Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[v4] create collapsed option #222

Merged
merged 10 commits into from
Mar 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ A geocoder component using Mapbox Geocoding API
properties. Search results closer to this point will be given
higher priority.
- `options.trackProximity` **[Boolean][23]** If true, the geocoder proximity will automatically update based on the map view. (optional, default `true`)
- `options.collapsed` **[Boolean][23]** If true, the geocoder control will collapse until hovered or in focus. (optional, default `false`)
- `options.bbox` **[Array][24]?** a bounding box argument: this is
a bounding box given as an array in the format [minX, minY, maxX, maxY].
Search results will be limited to the bounding box.
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Remove hardcoded IDs in bounding box exception list
- Fix duplicate event bug
- Fix trapped focus [#220](https://github.com/mapbox/mapbox-gl-geocoder/issues/220)
- Add `collapsed` option to collapse the geocoder controller into a button until hovered or focused [#222](https://github.com/mapbox/mapbox-gl-geocoder/issues/222)

## v3.1.6
- Resolve npm publish failure
Expand Down
31 changes: 26 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ var geocoderService;
* @param {String} options.accessToken Required.
* @param {String} options.origin Use to set a custom API origin. Defaults to https://api.mapbox.com.
* @param {Number} [options.zoom=16] On geocoded result what zoom level should the map animate to when a `bbox` isn't found in the response. If a `bbox` is found the map will fit to the `bbox`.
* @param {Boolean|Object} [options.flyTo] If false, animating the map to a selected result is disabled. If true, animating the map will use the default animation parameters. If an object, the object will be passed to the flyTo map method to specify a custom animation.
* @param {Boolean|Object} [options.flyTo] If false, animating the map to a selected result is disabled. If true, animating the map will use the default animation parameters. If an object, the object will be passed to the flyTo map method to specify a custom animation.
* @param {String} [options.placeholder="Search"] Override the default placeholder attribute value.
* @param {Object} [options.proximity] a proximity argument: this is
* a geographical point given as an object with latitude and longitude
* properties. Search results closer to this point will be given
* higher priority.
* @param {Boolean} [options.trackProximity=true] If true, the geocoder proximity will automatically update based on the map view.
* @param {Boolean} [options.collapsed=false] If true, the geocoder control will collapse until hovered or in focus.
* @param {Array} [options.bbox] a bounding box argument: this is
* a bounding box given as an array in the format [minX, minY, maxX, maxY].
* Search results will be limited to the bounding box.
Expand All @@ -43,7 +44,7 @@ var geocoderService;
* @param {'distance'|'score'} [options.reverseMode='distance'] - Set the factors that are used to sort nearby results.
* @param {boolean} [options.reverseGeocode] Enable reverse geocoding. Defaults to false. Expects coordinates to be lat, lon.
* @param {Function} [options.render] A function that specifies how the results should be rendered in the dropdown menu
* @param {Function} [options.getItemValue] A function that specifies how the selected result should be rendered in the search bar
* @param {Function} [options.getItemValue] A function that specifies how the selected result should be rendered in the search bar
* @example
* var geocoder = new MapboxGeocoder({ accessToken: mapboxgl.accessToken });
* map.addControl(geocoder);
Expand All @@ -68,7 +69,8 @@ MapboxGeocoder.prototype = {
reverseGeocode: false,
limit: 5,
origin: 'https://api.mapbox.com',
getItemValue: function(item) {
collapsed: false,
getItemValue: function(item) {
return item.place_name
}
},
Expand All @@ -92,6 +94,8 @@ MapboxGeocoder.prototype = {
this._onQueryResult = this._onQueryResult.bind(this);
this._clear = this._clear.bind(this);
this._updateProximity = this._updateProximity.bind(this);
this._collapse = this._collapse.bind(this);
this._unCollapse = this._unCollapse.bind(this);

var el = (this.container = document.createElement('div'));
el.className = 'mapboxgl-ctrl-geocoder mapboxgl-ctrl';
Expand All @@ -103,6 +107,14 @@ MapboxGeocoder.prototype = {
this._inputEl.type = 'text';
this._inputEl.placeholder = this._getPlaceholderText();

if (this.options.collapsed) {
this._collapse();
this.container.addEventListener('mouseenter', this._unCollapse);
this.container.addEventListener('mouseleave', this._collapse);
this._inputEl.addEventListener('focus', this._unCollapse);
this._inputEl.addEventListener('blur', this._collapse);
}

this._inputEl.addEventListener('keydown', debounce(this._onKeyDown, 200));
this._inputEl.addEventListener('change', this._onChange);

Expand Down Expand Up @@ -361,6 +373,15 @@ MapboxGeocoder.prototype = {
}
},

_collapse: function() {
// do not collapse if input is in focus
if (!this._inputEl.value && this._inputEl !== document.activeElement) this.container.classList.add('geocoder-collapsed');
},

_unCollapse: function() {
this.container.classList.remove('geocoder-collapsed');
},

/**
* Set & query the input
* @param {string} searchInput location name or other search input
Expand Down Expand Up @@ -417,13 +438,13 @@ MapboxGeocoder.prototype = {

/**
* Get the function used to render the results dropdown
*
*
* @returns {Function} the render function
*/
getRenderFunction: function(){
return this._typeahead.render;
},

/**
* Get the language to use in UI elements and when making search requests
*
Expand Down
19 changes: 13 additions & 6 deletions lib/mapbox-gl-geocoder.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@
max-width:360px;
z-index:1;
border-radius:3px;
transition: width .25s, min-width .25s;
}

.mapboxgl-ctrl-geocoder input[type='text'] {
font-size:12px;
width:100%;
border:0;
background-color:transparent;
height:40px;
margin:0;
color:rgba(0,0,0,.5);
padding:10px 10px 10px 40px;
padding:10px 10px 10px 35px;
text-overflow:ellipsis;
white-space:nowrap;
overflow:hidden;
Expand All @@ -40,8 +40,8 @@

.mapboxgl-ctrl-geocoder .geocoder-icon-search {
position:absolute;
top:10px;
left:10px;
top: 7px;
left: 5px;
}
.mapboxgl-ctrl-geocoder button {
padding:0;
Expand All @@ -54,8 +54,8 @@
background-color:#fff;
z-index:2;
position:absolute;
right:10px;
top:10px;
right: 5px;
top: 7px;
display:none;
}

Expand All @@ -64,6 +64,13 @@
box-shadow: 0 0 0 2px rgba(0,0,0,0.1);
}

/* Collapsed */
.geocoder-collapsed {
width: 30px;
min-width: 30px;
transition: width .25s, min-width .25s;
}

/* Suggestions */
.mapboxgl-ctrl-geocoder ul {
background-color:#fff;
Expand Down
4 changes: 2 additions & 2 deletions test/test.geocoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ test('geocoder', function(tt) {
once(function(e) {
t.equal(e.features.length, 1, 'One result returned');
t.ok(
e.features[0].place_name.indexOf('Tanzania') > -1,
e.features[0].place_name.indexOf('Tanzania') > -1,
'returns expected result'
);
t.ok(
e.features[0].place_name.indexOf('Singida') > -1,
e.features[0].place_name.indexOf('Singida') > -1,
'returns expected result'
);
t.equal(e.config.limit, 1, 'sets limit to 1 for reverse geocodes');
Expand Down
49 changes: 49 additions & 0 deletions test/test.ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,5 +158,54 @@ test('Geocoder#inputControl', function(tt) {
t.end();
});

tt.test('options.collapsed=true', function(t) {
t.plan(1);
setup({
collapsed: true
});
var wrapper = container.querySelector('.mapboxgl-ctrl-geocoder');
t.equal(wrapper.classList.contains('geocoder-collapsed'), true, 'mapboxgl-ctrl-geocoder has `geocoder-collapsed` class');
t.end();
});

tt.test('options.collapsed=true, focus', function(t) {
t.plan(1);
setup({
collapsed: true
});
var wrapper = container.querySelector('.mapboxgl-ctrl-geocoder');
var inputEl = container.querySelector('.mapboxgl-ctrl-geocoder input');
// focus input, remove geocoder-collapsed
var focusEvent = document.createEvent('Event');
focusEvent.initEvent("focus", true, true);
inputEl.dispatchEvent(focusEvent);
t.equal(wrapper.classList.contains('geocoder-collapsed'), false, 'mapboxgl-ctrl-geocoder does not have `geocoder-collapsed` class when inputEl in focus');
t.end();
});

tt.test('options.collapsed=true, hover', function(t) {
t.plan(1);
setup({
collapsed: true
});
var wrapper = container.querySelector('.mapboxgl-ctrl-geocoder');
// hover input, remove geocoder-collapsed
var hoverEvent = document.createEvent('Event');
hoverEvent.initEvent("mouseenter", true, true);
wrapper.dispatchEvent(hoverEvent);
t.equal(wrapper.classList.contains('geocoder-collapsed'), false, 'mapboxgl-ctrl-geocoder does not have `geocoder-collapsed` class when wrapper hovered');
t.end();
});

tt.test('options.collapsed=false', function(t) {
t.plan(1);
setup({
collapsed: false
});
var wrapper = container.querySelector('.mapboxgl-ctrl-geocoder');
t.equal(wrapper.classList.contains('geocoder-collapsed'), false, 'mapboxgl-ctrl-geocoder does not have `geocoder-collapsed` class');
t.end();
});

tt.end();
});