Skip to content

Commit 496385c

Browse files
committed
anchor point can be set stickily
A preference for where the anchor is set when there is space
1 parent 881bd85 commit 496385c

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

src/ui/popup.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import {extend, bindAll} from '../util/util.js';
44
import {Event, Evented} from '../util/evented.js';
5-
import {MapMouseEvent} from '../ui/events.js';
5+
import {MapMouseEvent} from './events.js';
66
import DOM from '../util/dom.js';
77
import LngLat from '../geo/lng_lat.js';
88
import Point from '@mapbox/point-geometry';
@@ -19,7 +19,8 @@ const defaultOptions = {
1919
closeOnClick: true,
2020
focusAfterOpen: true,
2121
className: '',
22-
maxWidth: "240px"
22+
maxWidth: "240px",
23+
stickyAnchor: 'bottom'
2324
};
2425

2526
export type Offset = number | PointLike | {[_: Anchor]: PointLike};
@@ -32,7 +33,8 @@ export type PopupOptions = {
3233
anchor?: Anchor,
3334
offset?: Offset,
3435
className?: string,
35-
maxWidth?: string
36+
maxWidth?: string,
37+
stickyAnchor: Anchor
3638
};
3739

3840
const focusQuerySelector = [
@@ -57,6 +59,9 @@ const focusQuerySelector = [
5759
* map moves.
5860
* @param {boolean} [options.focusAfterOpen=true] If `true`, the popup will try to focus the
5961
* first focusable element inside the popup.
62+
* @param {string} [options.stickyAnchor='bottom'] - A string to set the preference for where the anchor will be
63+
* dynamically set. Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`, `'top-right'`,
64+
* `'bottom-left'`, and `'bottom-right'`.
6065
* @param {string} [options.anchor] - A string indicating the part of the popup that should
6166
* be positioned closest to the coordinate, set via {@link Popup#setLngLat}.
6267
* Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`,
@@ -67,7 +72,7 @@ const focusQuerySelector = [
6772
* A pixel offset applied to the popup's location specified as:
6873
* - a single number specifying a distance from the popup's location
6974
* - a {@link PointLike} specifying a constant offset
70-
* - an object of {@link Point}s specifing an offset for each anchor position.
75+
* - an object of {@link Point}s specifying an offset for each anchor position.
7176
*
7277
* Negative offsets indicate left and up.
7378
* @param {string} [options.className] Space-separated CSS class names to add to popup container.
@@ -575,7 +580,7 @@ export default class Popup extends Evented {
575580
}
576581

577582
if (anchorComponents.length === 0) {
578-
return 'bottom';
583+
return this.options.stickyAnchor;
579584
}
580585
return ((anchorComponents.join('-'): any): Anchor);
581586

test/unit/ui/popup.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,30 @@ test('Popup automatically anchors to top if its bottom offset would push it off-
480480
t.end();
481481
});
482482

483+
test('Popup automatically anchors to its sticky position if no offset would push it off-screen', (t) => {
484+
const map = createMap(t);
485+
const point = new Point(containerWidth / 2, containerHeight / 2);
486+
const options = {offset: {
487+
'bottom': [0, 0],
488+
'top': [0, 0]
489+
}, stickyAnchor: 'left'};
490+
const popup = new Popup(options)
491+
.setLngLat([0, 0])
492+
.setText('Test')
493+
.addTo(map);
494+
map._domRenderTaskQueue.run();
495+
496+
Object.defineProperty(popup.getElement(), 'offsetWidth', {value: containerWidth / 2});
497+
Object.defineProperty(popup.getElement(), 'offsetHeight', {value: containerHeight / 2});
498+
499+
t.stub(map, 'project').returns(point);
500+
popup.setLngLat([0, 0]);
501+
map._domRenderTaskQueue.run();
502+
503+
t.ok(popup.getElement().classList.contains('mapboxgl-popup-anchor-left'));
504+
t.end();
505+
});
506+
483507
test('Popup is offset via a PointLike offset option', (t) => {
484508
const map = createMap(t);
485509
t.stub(map, 'project').returns(new Point(0, 0));

0 commit comments

Comments
 (0)