Skip to content

Commit

Permalink
Add pointerOffsetX and pointerOffsetY options for popup view an…
Browse files Browse the repository at this point in the history
…d `view.tooltip`
  • Loading branch information
lahmatiy committed Mar 14, 2024
1 parent 9f85fea commit 10a86af
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## next

- Added `positionMode` option for `popup` view. When set to "natural", the popup attempts to position itself at the bottom right side if dimensions allow, instead of positioning towards the larger available space by default (value "safe" for the option)
- Added `pointerOffsetX` and `pointerOffsetY` options for `popup` view and `view.tooltip`
- Enabled `positionMode: natural` for tooltips by default, can be changed via tooltip options
- Exposed type checking helpers `isArray()`, `isSet()` and `isRegExp()`
- Fixed `badge` view options when it receives an array as data
Expand Down
13 changes: 13 additions & 0 deletions src/core/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ function createTooltip(host) {
let [config, data, context] = tooltipEls.get(triggerEl) || [];
let position = 'pointer';
let positionMode = 'natural';
let pointerOffsetX = 3;
let pointerOffsetY = 3;
let content = config;

if (classNames !== null) {
Expand All @@ -275,11 +277,22 @@ function createTooltip(host) {

position = config.position || position;
positionMode = config.positionMode || positionMode;

if (Number.isFinite(config.pointerOffsetX)) {
pointerOffsetX = config.pointerOffsetX;
}

if (Number.isFinite(config.pointerOffsetY)) {
pointerOffsetY = config.pointerOffsetY;
}

content = config.content;
}

popup.position = position;
popup.positionMode = positionMode;
popup.pointerOffsetX = pointerOffsetX;
popup.pointerOffsetY = pointerOffsetY;

if (content) {
return host.view.render(el, content, data, context);
Expand Down
2 changes: 2 additions & 0 deletions src/pages/views-showcase.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ A canonical form for a tooltip setup is an object with fields (all are optional,
className: 'string', // additional class names for tooltip's element
position: 'pointer', // 'trigger' or 'pointer'
positionMode: 'natural', // 'safe' or 'natural'
pointerOffsetX: 3, // tooltip offset from the pointer
pointerOffsetY: 3, // tooltip offset from the pointer
showDelay: true, // true (300ms), false (0ms), a number, or a function which takes a triggerEl and returns showDelay value
content: 'a view config' // view config for tooltip's content
}
Expand Down
11 changes: 9 additions & 2 deletions src/views/layout/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const defaultShowDelay = 300;
const defaultOptions = {
position: 'trigger',
positionMode: 'safe', // 'safe' – choose side with more space, 'natural' – choose right/bottom when enough space
pointerOffsetX: 3,
pointerOffsetY: 3,
showDelay: false, // false = 0, true = defaultShowDelay
hoverTriggers: null, // null or string (a list of css selectors)
hoverPin: false, // see hoverPinModes
Expand Down Expand Up @@ -78,6 +80,10 @@ function appendIfNeeded(parent, child) {
}
}

function ensureNumber(value, fallback = 0) {
return Number.isFinite(value) ? value : fallback;
}

export default function(host) {
const hoverTriggerInstances = [];
const inspectorLockedInstances = new Set();
Expand Down Expand Up @@ -204,6 +210,8 @@ export default function(host) {
this.render = options.render;
this.position = options.position;
this.positionMode = options.positionMode;
this.pointerOffsetX = ensureNumber(options.pointerOffsetX);
this.pointerOffsetY = ensureNumber(options.pointerOffsetY);
this.hoverTriggers = options.hoverTriggers;
this.hoverPin = options.hoverPin;
this.hideIfEventOutsideDisabled = !options.hideIfEventOutside;
Expand Down Expand Up @@ -322,8 +330,7 @@ export default function(host) {
const offsetParent = getOffsetParent(hostEl.firstChild);
const viewport = getViewportRect(window, offsetParent);
const { x: pointerX, y: pointerY } = pointerXY.value;
const pointerOffsetX = 3;
const pointerOffsetY = 3;
const { pointerOffsetX, pointerOffsetY } = this;
const box = !pointerPosition
? getBoundingRect(this.lastTriggerEl, hostEl)
: {
Expand Down

0 comments on commit 10a86af

Please sign in to comment.