@zag-js/tooltip 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +4 -0
- package/dist/index.js +57 -12
- package/dist/index.mjs +575 -0
- package/package.json +11 -11
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,10 @@ declare type PublicContext = CommonProperties & {
|
|
|
54
54
|
* The user provided options used to position the popover content
|
|
55
55
|
*/
|
|
56
56
|
positioning: PositioningOptions;
|
|
57
|
+
/**
|
|
58
|
+
* Whether the tooltip is disabled
|
|
59
|
+
*/
|
|
60
|
+
disabled?: boolean;
|
|
57
61
|
};
|
|
58
62
|
declare type UserDefinedContext = RequiredBy<PublicContext, "id">;
|
|
59
63
|
declare type ComputedContext = Readonly<{
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
connect: () => connect,
|
|
24
|
+
machine: () => machine
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(src_exports);
|
|
27
|
+
|
|
28
|
+
// ../../utilities/dom/dist/index.mjs
|
|
2
29
|
var dataAttr = (guard) => {
|
|
3
30
|
return guard ? "" : void 0;
|
|
4
31
|
};
|
|
@@ -191,7 +218,7 @@ var visuallyHiddenStyle = {
|
|
|
191
218
|
};
|
|
192
219
|
|
|
193
220
|
// src/tooltip.connect.ts
|
|
194
|
-
|
|
221
|
+
var import_popper = require("@zag-js/popper");
|
|
195
222
|
|
|
196
223
|
// src/tooltip.dom.ts
|
|
197
224
|
var dom = defineDomHelpers({
|
|
@@ -220,8 +247,8 @@ var dom = defineDomHelpers({
|
|
|
220
247
|
});
|
|
221
248
|
|
|
222
249
|
// src/tooltip.store.ts
|
|
223
|
-
|
|
224
|
-
var store = proxy({
|
|
250
|
+
var import_core = require("@zag-js/core");
|
|
251
|
+
var store = (0, import_core.proxy)({
|
|
225
252
|
id: null,
|
|
226
253
|
prevId: null,
|
|
227
254
|
setId(val) {
|
|
@@ -237,7 +264,8 @@ function connect(state, send, normalize) {
|
|
|
237
264
|
const isOpen = state.hasTag("open");
|
|
238
265
|
const triggerId = dom.getTriggerId(state.context);
|
|
239
266
|
const contentId = dom.getContentId(state.context);
|
|
240
|
-
const
|
|
267
|
+
const isDisabled = state.context.disabled;
|
|
268
|
+
const popperStyles = (0, import_popper.getPlacementStyles)({
|
|
241
269
|
measured: !!state.context.isPlacementComplete,
|
|
242
270
|
placement: state.context.currentPlacement
|
|
243
271
|
});
|
|
@@ -272,17 +300,25 @@ function connect(state, send, normalize) {
|
|
|
272
300
|
}
|
|
273
301
|
},
|
|
274
302
|
onPointerDown() {
|
|
303
|
+
if (isDisabled)
|
|
304
|
+
return;
|
|
275
305
|
if (id === store.id) {
|
|
276
306
|
send("POINTER_DOWN");
|
|
277
307
|
}
|
|
278
308
|
},
|
|
279
309
|
onPointerMove() {
|
|
310
|
+
if (isDisabled)
|
|
311
|
+
return;
|
|
280
312
|
send("POINTER_ENTER");
|
|
281
313
|
},
|
|
282
314
|
onPointerLeave() {
|
|
315
|
+
if (isDisabled)
|
|
316
|
+
return;
|
|
283
317
|
send("POINTER_LEAVE");
|
|
284
318
|
},
|
|
285
319
|
onPointerCancel() {
|
|
320
|
+
if (isDisabled)
|
|
321
|
+
return;
|
|
286
322
|
send("POINTER_LEAVE");
|
|
287
323
|
}
|
|
288
324
|
}),
|
|
@@ -335,10 +371,10 @@ function connect(state, send, normalize) {
|
|
|
335
371
|
}
|
|
336
372
|
|
|
337
373
|
// src/tooltip.machine.ts
|
|
338
|
-
|
|
339
|
-
|
|
374
|
+
var import_core2 = require("@zag-js/core");
|
|
375
|
+
var import_popper2 = require("@zag-js/popper");
|
|
340
376
|
function machine(ctx) {
|
|
341
|
-
return createMachine(
|
|
377
|
+
return (0, import_core2.createMachine)(
|
|
342
378
|
{
|
|
343
379
|
id: "tooltip",
|
|
344
380
|
initial: "unknown",
|
|
@@ -358,6 +394,9 @@ function machine(ctx) {
|
|
|
358
394
|
computed: {
|
|
359
395
|
hasAriaLabel: (ctx2) => !!ctx2["aria-label"]
|
|
360
396
|
},
|
|
397
|
+
watch: {
|
|
398
|
+
disabled: ["closeIfDisabled"]
|
|
399
|
+
},
|
|
361
400
|
on: {
|
|
362
401
|
OPEN: "open",
|
|
363
402
|
CLOSE: "closed"
|
|
@@ -455,7 +494,7 @@ function machine(ctx) {
|
|
|
455
494
|
ctx2.currentPlacement = ctx2.positioning.placement;
|
|
456
495
|
let cleanup;
|
|
457
496
|
raf(() => {
|
|
458
|
-
cleanup = getPlacement(dom.getTriggerEl(ctx2), dom.getPositionerEl(ctx2), {
|
|
497
|
+
cleanup = (0, import_popper2.getPlacement)(dom.getTriggerEl(ctx2), dom.getPositionerEl(ctx2), {
|
|
459
498
|
...ctx2.positioning,
|
|
460
499
|
onComplete(data) {
|
|
461
500
|
ctx2.currentPlacement = data.placement;
|
|
@@ -487,7 +526,7 @@ function machine(ctx) {
|
|
|
487
526
|
};
|
|
488
527
|
},
|
|
489
528
|
trackStore(ctx2, _evt, { send }) {
|
|
490
|
-
return subscribe(store, () => {
|
|
529
|
+
return (0, import_core2.subscribe)(store, () => {
|
|
491
530
|
if (store.id !== ctx2.id) {
|
|
492
531
|
send("FORCE_CLOSE");
|
|
493
532
|
}
|
|
@@ -537,6 +576,11 @@ function machine(ctx) {
|
|
|
537
576
|
if (!omit.includes(evt.type)) {
|
|
538
577
|
(_a = ctx2.onClose) == null ? void 0 : _a.call(ctx2);
|
|
539
578
|
}
|
|
579
|
+
},
|
|
580
|
+
closeIfDisabled(ctx2, _evt, { send }) {
|
|
581
|
+
if (ctx2.disabled) {
|
|
582
|
+
send("CLOSE");
|
|
583
|
+
}
|
|
540
584
|
}
|
|
541
585
|
},
|
|
542
586
|
guards: {
|
|
@@ -552,7 +596,8 @@ function machine(ctx) {
|
|
|
552
596
|
}
|
|
553
597
|
);
|
|
554
598
|
}
|
|
555
|
-
export
|
|
599
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
600
|
+
0 && (module.exports = {
|
|
556
601
|
connect,
|
|
557
602
|
machine
|
|
558
|
-
};
|
|
603
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
// ../../utilities/dom/dist/index.mjs
|
|
2
|
+
var dataAttr = (guard) => {
|
|
3
|
+
return guard ? "" : void 0;
|
|
4
|
+
};
|
|
5
|
+
function getCache() {
|
|
6
|
+
const g = globalThis;
|
|
7
|
+
g.__styleCache = g.__styleCache || /* @__PURE__ */ new WeakMap();
|
|
8
|
+
return g.__styleCache;
|
|
9
|
+
}
|
|
10
|
+
function getComputedStyle(el) {
|
|
11
|
+
if (!el)
|
|
12
|
+
return {};
|
|
13
|
+
const cache = getCache();
|
|
14
|
+
let style = cache.get(el);
|
|
15
|
+
if (!style) {
|
|
16
|
+
const win = (el == null ? void 0 : el.ownerDocument.defaultView) ?? window;
|
|
17
|
+
style = win.getComputedStyle(el);
|
|
18
|
+
cache.set(el, style);
|
|
19
|
+
}
|
|
20
|
+
return style;
|
|
21
|
+
}
|
|
22
|
+
var runIfFn = (v, ...a) => {
|
|
23
|
+
const res = typeof v === "function" ? v(...a) : v;
|
|
24
|
+
return res ?? void 0;
|
|
25
|
+
};
|
|
26
|
+
var isArray = (v) => Array.isArray(v);
|
|
27
|
+
var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
|
|
28
|
+
var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
|
|
29
|
+
var isDom = () => typeof window !== "undefined";
|
|
30
|
+
function getPlatform() {
|
|
31
|
+
const agent = navigator.userAgentData;
|
|
32
|
+
return (agent == null ? void 0 : agent.platform) ?? navigator.platform;
|
|
33
|
+
}
|
|
34
|
+
var pt = (v) => isDom() && v.test(getPlatform());
|
|
35
|
+
var vn = (v) => isDom() && v.test(navigator.vendor);
|
|
36
|
+
var isSafari = () => isApple() && vn(/apple/i);
|
|
37
|
+
var isApple = () => pt(/mac|iphone|ipad|ipod/i);
|
|
38
|
+
function isDocument(el) {
|
|
39
|
+
return el.nodeType === Node.DOCUMENT_NODE;
|
|
40
|
+
}
|
|
41
|
+
function isWindow(value) {
|
|
42
|
+
return (value == null ? void 0 : value.toString()) === "[object Window]";
|
|
43
|
+
}
|
|
44
|
+
function getDocument(el) {
|
|
45
|
+
if (isWindow(el))
|
|
46
|
+
return el.document;
|
|
47
|
+
if (isDocument(el))
|
|
48
|
+
return el;
|
|
49
|
+
return (el == null ? void 0 : el.ownerDocument) ?? document;
|
|
50
|
+
}
|
|
51
|
+
function getWindow(el) {
|
|
52
|
+
return (el == null ? void 0 : el.ownerDocument.defaultView) ?? window;
|
|
53
|
+
}
|
|
54
|
+
function getNodeName(node) {
|
|
55
|
+
return isWindow(node) ? "" : (node == null ? void 0 : node.localName) ?? "";
|
|
56
|
+
}
|
|
57
|
+
function getParent(el) {
|
|
58
|
+
const doc = getDocument(el);
|
|
59
|
+
if (getNodeName(el) === "html")
|
|
60
|
+
return el;
|
|
61
|
+
return el.assignedSlot || el.parentElement || doc.documentElement;
|
|
62
|
+
}
|
|
63
|
+
function defineDomHelpers(helpers) {
|
|
64
|
+
const dom2 = {
|
|
65
|
+
getRootNode: (ctx) => {
|
|
66
|
+
var _a;
|
|
67
|
+
return ((_a = ctx.getRootNode) == null ? void 0 : _a.call(ctx)) ?? document;
|
|
68
|
+
},
|
|
69
|
+
getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
|
|
70
|
+
getWin: (ctx) => dom2.getDoc(ctx).defaultView ?? window,
|
|
71
|
+
getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
|
|
72
|
+
getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
...dom2,
|
|
76
|
+
...helpers
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function isHTMLElement(v) {
|
|
80
|
+
return typeof v === "object" && (v == null ? void 0 : v.nodeType) === Node.ELEMENT_NODE && typeof (v == null ? void 0 : v.nodeName) === "string";
|
|
81
|
+
}
|
|
82
|
+
var supportsPointerEvent = () => isDom() && window.onpointerdown === null;
|
|
83
|
+
var supportsTouchEvent = () => isDom() && window.ontouchstart === null;
|
|
84
|
+
var supportsMouseEvent = () => isDom() && window.onmousedown === null;
|
|
85
|
+
var isTouchEvent = (v) => isObject(v) && hasProp(v, "touches");
|
|
86
|
+
var isRef = (v) => hasProp(v, "current");
|
|
87
|
+
var fallback2 = { pageX: 0, pageY: 0, clientX: 0, clientY: 0 };
|
|
88
|
+
function extractInfo(event, type = "page") {
|
|
89
|
+
const point = isTouchEvent(event) ? event.touches[0] || event.changedTouches[0] || fallback2 : event;
|
|
90
|
+
return {
|
|
91
|
+
point: {
|
|
92
|
+
x: point[`${type}X`],
|
|
93
|
+
y: point[`${type}Y`]
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function addDomEvent(target, eventName, handler, options) {
|
|
98
|
+
const node = isRef(target) ? target.current : runIfFn(target);
|
|
99
|
+
node == null ? void 0 : node.addEventListener(eventName, handler, options);
|
|
100
|
+
return () => {
|
|
101
|
+
node == null ? void 0 : node.removeEventListener(eventName, handler, options);
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function addPointerEvent(target, event, listener, options) {
|
|
105
|
+
const type = getEventName(event) ?? event;
|
|
106
|
+
return addDomEvent(target, type, wrapHandler(listener, event === "pointerdown"), options);
|
|
107
|
+
}
|
|
108
|
+
function wrapHandler(fn, filter = false) {
|
|
109
|
+
const listener = (event) => {
|
|
110
|
+
fn(event, extractInfo(event));
|
|
111
|
+
};
|
|
112
|
+
return filter ? filterPrimaryPointer(listener) : listener;
|
|
113
|
+
}
|
|
114
|
+
function filterPrimaryPointer(fn) {
|
|
115
|
+
return (event) => {
|
|
116
|
+
const win = event.view ?? window;
|
|
117
|
+
const isMouseEvent2 = event instanceof win.MouseEvent;
|
|
118
|
+
const isPrimary = !isMouseEvent2 || isMouseEvent2 && event.button === 0;
|
|
119
|
+
if (isPrimary)
|
|
120
|
+
fn(event);
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
var mouseEventNames = {
|
|
124
|
+
pointerdown: "mousedown",
|
|
125
|
+
pointermove: "mousemove",
|
|
126
|
+
pointerup: "mouseup",
|
|
127
|
+
pointercancel: "mousecancel",
|
|
128
|
+
pointerover: "mouseover",
|
|
129
|
+
pointerout: "mouseout",
|
|
130
|
+
pointerenter: "mouseenter",
|
|
131
|
+
pointerleave: "mouseleave"
|
|
132
|
+
};
|
|
133
|
+
var touchEventNames = {
|
|
134
|
+
pointerdown: "touchstart",
|
|
135
|
+
pointermove: "touchmove",
|
|
136
|
+
pointerup: "touchend",
|
|
137
|
+
pointercancel: "touchcancel"
|
|
138
|
+
};
|
|
139
|
+
function getEventName(evt) {
|
|
140
|
+
if (supportsPointerEvent())
|
|
141
|
+
return evt;
|
|
142
|
+
if (supportsTouchEvent())
|
|
143
|
+
return touchEventNames[evt];
|
|
144
|
+
if (supportsMouseEvent())
|
|
145
|
+
return mouseEventNames[evt];
|
|
146
|
+
return evt;
|
|
147
|
+
}
|
|
148
|
+
function raf(fn) {
|
|
149
|
+
const id = globalThis.requestAnimationFrame(fn);
|
|
150
|
+
return function cleanup() {
|
|
151
|
+
globalThis.cancelAnimationFrame(id);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function addPointerlockChangeListener(doc, fn) {
|
|
155
|
+
return addDomEvent(doc, "pointerlockchange", fn, false);
|
|
156
|
+
}
|
|
157
|
+
function isScrollParent(el) {
|
|
158
|
+
const { overflow, overflowX, overflowY } = getComputedStyle(el);
|
|
159
|
+
return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
|
|
160
|
+
}
|
|
161
|
+
function getScrollParent(el) {
|
|
162
|
+
if (["html", "body", "#document"].includes(getNodeName(el))) {
|
|
163
|
+
return getDocument(el).body;
|
|
164
|
+
}
|
|
165
|
+
if (isHTMLElement(el) && isScrollParent(el)) {
|
|
166
|
+
return el;
|
|
167
|
+
}
|
|
168
|
+
return getScrollParent(getParent(el));
|
|
169
|
+
}
|
|
170
|
+
function getScrollParents(el, list = []) {
|
|
171
|
+
const scrollParent = getScrollParent(el);
|
|
172
|
+
const isBody = scrollParent === getDocument(el).body;
|
|
173
|
+
const win = getWindow(scrollParent);
|
|
174
|
+
const target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
|
|
175
|
+
const parents = list.concat(target);
|
|
176
|
+
if (isBody)
|
|
177
|
+
return parents;
|
|
178
|
+
return parents.concat(getScrollParents(getParent(target)));
|
|
179
|
+
}
|
|
180
|
+
var visuallyHiddenStyle = {
|
|
181
|
+
border: "0",
|
|
182
|
+
clip: "rect(0 0 0 0)",
|
|
183
|
+
height: "1px",
|
|
184
|
+
margin: "-1px",
|
|
185
|
+
overflow: "hidden",
|
|
186
|
+
padding: "0",
|
|
187
|
+
position: "absolute",
|
|
188
|
+
width: "1px",
|
|
189
|
+
whiteSpace: "nowrap",
|
|
190
|
+
wordWrap: "normal"
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// src/tooltip.connect.ts
|
|
194
|
+
import { getPlacementStyles } from "@zag-js/popper";
|
|
195
|
+
|
|
196
|
+
// src/tooltip.dom.ts
|
|
197
|
+
var dom = defineDomHelpers({
|
|
198
|
+
getTriggerId: (ctx) => {
|
|
199
|
+
var _a;
|
|
200
|
+
return ((_a = ctx.ids) == null ? void 0 : _a.trigger) ?? `tooltip:${ctx.id}:trigger`;
|
|
201
|
+
},
|
|
202
|
+
getContentId: (ctx) => {
|
|
203
|
+
var _a;
|
|
204
|
+
return ((_a = ctx.ids) == null ? void 0 : _a.content) ?? `tooltip:${ctx.id}:content`;
|
|
205
|
+
},
|
|
206
|
+
getArrowId: (ctx) => `tooltip:${ctx.id}:arrow`,
|
|
207
|
+
getPositionerId: (ctx) => `tooltip:${ctx.id}:popper`,
|
|
208
|
+
portalId: "tooltip-portal",
|
|
209
|
+
getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
|
|
210
|
+
getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
|
|
211
|
+
getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
|
|
212
|
+
getArrowEl: (ctx) => dom.getById(ctx, dom.getArrowId(ctx)),
|
|
213
|
+
getScrollParent: (ctx) => getScrollParent(dom.getTriggerEl(ctx)),
|
|
214
|
+
getPortalEl: (ctx) => dom.getDoc(ctx).getElementById(dom.portalId),
|
|
215
|
+
createPortalEl: (ctx) => {
|
|
216
|
+
const portal = dom.getDoc(ctx).createElement(dom.portalId);
|
|
217
|
+
portal.id = dom.portalId;
|
|
218
|
+
return portal;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// src/tooltip.store.ts
|
|
223
|
+
import { proxy } from "@zag-js/core";
|
|
224
|
+
var store = proxy({
|
|
225
|
+
id: null,
|
|
226
|
+
prevId: null,
|
|
227
|
+
setId(val) {
|
|
228
|
+
this.prevId = this.id;
|
|
229
|
+
this.id = val;
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// src/tooltip.connect.ts
|
|
234
|
+
function connect(state, send, normalize) {
|
|
235
|
+
const id = state.context.id;
|
|
236
|
+
const hasAriaLabel = state.context.hasAriaLabel;
|
|
237
|
+
const isOpen = state.hasTag("open");
|
|
238
|
+
const triggerId = dom.getTriggerId(state.context);
|
|
239
|
+
const contentId = dom.getContentId(state.context);
|
|
240
|
+
const isDisabled = state.context.disabled;
|
|
241
|
+
const popperStyles = getPlacementStyles({
|
|
242
|
+
measured: !!state.context.isPlacementComplete,
|
|
243
|
+
placement: state.context.currentPlacement
|
|
244
|
+
});
|
|
245
|
+
return {
|
|
246
|
+
isOpen,
|
|
247
|
+
open() {
|
|
248
|
+
send("OPEN");
|
|
249
|
+
},
|
|
250
|
+
close() {
|
|
251
|
+
send("CLOSE");
|
|
252
|
+
},
|
|
253
|
+
getAnimationState() {
|
|
254
|
+
return {
|
|
255
|
+
enter: store.prevId === null && id === store.id,
|
|
256
|
+
exit: store.id === null
|
|
257
|
+
};
|
|
258
|
+
},
|
|
259
|
+
triggerProps: normalize.button({
|
|
260
|
+
"data-part": "trigger",
|
|
261
|
+
id: triggerId,
|
|
262
|
+
"data-expanded": dataAttr(isOpen),
|
|
263
|
+
"aria-describedby": isOpen ? contentId : void 0,
|
|
264
|
+
onClick() {
|
|
265
|
+
send("CLICK");
|
|
266
|
+
},
|
|
267
|
+
onFocus() {
|
|
268
|
+
send("FOCUS");
|
|
269
|
+
},
|
|
270
|
+
onBlur() {
|
|
271
|
+
if (id === store.id) {
|
|
272
|
+
send("BLUR");
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
onPointerDown() {
|
|
276
|
+
if (isDisabled)
|
|
277
|
+
return;
|
|
278
|
+
if (id === store.id) {
|
|
279
|
+
send("POINTER_DOWN");
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
onPointerMove() {
|
|
283
|
+
if (isDisabled)
|
|
284
|
+
return;
|
|
285
|
+
send("POINTER_ENTER");
|
|
286
|
+
},
|
|
287
|
+
onPointerLeave() {
|
|
288
|
+
if (isDisabled)
|
|
289
|
+
return;
|
|
290
|
+
send("POINTER_LEAVE");
|
|
291
|
+
},
|
|
292
|
+
onPointerCancel() {
|
|
293
|
+
if (isDisabled)
|
|
294
|
+
return;
|
|
295
|
+
send("POINTER_LEAVE");
|
|
296
|
+
}
|
|
297
|
+
}),
|
|
298
|
+
arrowProps: normalize.element({
|
|
299
|
+
id: dom.getArrowId(state.context),
|
|
300
|
+
"data-part": "arrow",
|
|
301
|
+
style: popperStyles.arrow
|
|
302
|
+
}),
|
|
303
|
+
innerArrowProps: normalize.element({
|
|
304
|
+
"data-part": "arrow-inner",
|
|
305
|
+
style: popperStyles.innerArrow
|
|
306
|
+
}),
|
|
307
|
+
positionerProps: normalize.element({
|
|
308
|
+
id: dom.getPositionerId(state.context),
|
|
309
|
+
"data-part": "positioner",
|
|
310
|
+
style: popperStyles.floating
|
|
311
|
+
}),
|
|
312
|
+
contentProps: normalize.element({
|
|
313
|
+
"data-part": "content",
|
|
314
|
+
role: hasAriaLabel ? void 0 : "tooltip",
|
|
315
|
+
id: hasAriaLabel ? void 0 : contentId,
|
|
316
|
+
"data-placement": state.context.currentPlacement,
|
|
317
|
+
onPointerEnter() {
|
|
318
|
+
send("TOOLTIP_POINTER_ENTER");
|
|
319
|
+
},
|
|
320
|
+
onPointerLeave() {
|
|
321
|
+
send("TOOLTIP_POINTER_LEAVE");
|
|
322
|
+
},
|
|
323
|
+
style: {
|
|
324
|
+
pointerEvents: state.context.interactive ? "auto" : "none"
|
|
325
|
+
}
|
|
326
|
+
}),
|
|
327
|
+
labelProps: normalize.element({
|
|
328
|
+
"data-part": "label",
|
|
329
|
+
id: contentId,
|
|
330
|
+
role: "tooltip",
|
|
331
|
+
style: visuallyHiddenStyle,
|
|
332
|
+
children: state.context["aria-label"]
|
|
333
|
+
}),
|
|
334
|
+
createPortal() {
|
|
335
|
+
const doc = dom.getDoc(state.context);
|
|
336
|
+
const exist = dom.getPortalEl(state.context);
|
|
337
|
+
if (exist)
|
|
338
|
+
return exist;
|
|
339
|
+
const portal = dom.createPortalEl(state.context);
|
|
340
|
+
doc.body.appendChild(portal);
|
|
341
|
+
return portal;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// src/tooltip.machine.ts
|
|
347
|
+
import { createMachine, subscribe } from "@zag-js/core";
|
|
348
|
+
import { getPlacement } from "@zag-js/popper";
|
|
349
|
+
function machine(ctx) {
|
|
350
|
+
return createMachine(
|
|
351
|
+
{
|
|
352
|
+
id: "tooltip",
|
|
353
|
+
initial: "unknown",
|
|
354
|
+
context: {
|
|
355
|
+
openDelay: 1e3,
|
|
356
|
+
closeDelay: 500,
|
|
357
|
+
closeOnPointerDown: true,
|
|
358
|
+
closeOnEsc: true,
|
|
359
|
+
interactive: true,
|
|
360
|
+
currentPlacement: void 0,
|
|
361
|
+
...ctx,
|
|
362
|
+
positioning: {
|
|
363
|
+
placement: "bottom",
|
|
364
|
+
...ctx.positioning
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
computed: {
|
|
368
|
+
hasAriaLabel: (ctx2) => !!ctx2["aria-label"]
|
|
369
|
+
},
|
|
370
|
+
watch: {
|
|
371
|
+
disabled: ["closeIfDisabled"]
|
|
372
|
+
},
|
|
373
|
+
on: {
|
|
374
|
+
OPEN: "open",
|
|
375
|
+
CLOSE: "closed"
|
|
376
|
+
},
|
|
377
|
+
states: {
|
|
378
|
+
unknown: {
|
|
379
|
+
on: {
|
|
380
|
+
SETUP: "closed"
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
closed: {
|
|
384
|
+
tags: ["closed"],
|
|
385
|
+
entry: ["clearGlobalId", "invokeOnClose"],
|
|
386
|
+
on: {
|
|
387
|
+
FOCUS: "open",
|
|
388
|
+
POINTER_ENTER: [
|
|
389
|
+
{
|
|
390
|
+
guard: "noVisibleTooltip",
|
|
391
|
+
target: "opening"
|
|
392
|
+
},
|
|
393
|
+
{ target: "open" }
|
|
394
|
+
]
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
opening: {
|
|
398
|
+
tags: ["closed"],
|
|
399
|
+
activities: ["trackScroll", "trackPointerlockChange"],
|
|
400
|
+
after: {
|
|
401
|
+
OPEN_DELAY: "open"
|
|
402
|
+
},
|
|
403
|
+
on: {
|
|
404
|
+
POINTER_LEAVE: "closed",
|
|
405
|
+
BLUR: "closed",
|
|
406
|
+
SCROLL: "closed",
|
|
407
|
+
POINTER_LOCK_CHANGE: "closed",
|
|
408
|
+
POINTER_DOWN: {
|
|
409
|
+
guard: "closeOnPointerDown",
|
|
410
|
+
target: "closed"
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
open: {
|
|
415
|
+
tags: ["open"],
|
|
416
|
+
activities: [
|
|
417
|
+
"trackEscapeKey",
|
|
418
|
+
"trackDisabledTriggerOnSafari",
|
|
419
|
+
"trackScroll",
|
|
420
|
+
"trackPointerlockChange",
|
|
421
|
+
"computePlacement"
|
|
422
|
+
],
|
|
423
|
+
entry: ["setGlobalId", "invokeOnOpen"],
|
|
424
|
+
on: {
|
|
425
|
+
POINTER_LEAVE: [
|
|
426
|
+
{
|
|
427
|
+
guard: "isVisible",
|
|
428
|
+
target: "closing"
|
|
429
|
+
},
|
|
430
|
+
{ target: "closed" }
|
|
431
|
+
],
|
|
432
|
+
BLUR: "closed",
|
|
433
|
+
ESCAPE: "closed",
|
|
434
|
+
SCROLL: "closed",
|
|
435
|
+
POINTER_LOCK_CHANGE: "closed",
|
|
436
|
+
TOOLTIP_POINTER_LEAVE: {
|
|
437
|
+
guard: "isInteractive",
|
|
438
|
+
target: "closing"
|
|
439
|
+
},
|
|
440
|
+
POINTER_DOWN: {
|
|
441
|
+
guard: "closeOnPointerDown",
|
|
442
|
+
target: "closed"
|
|
443
|
+
},
|
|
444
|
+
CLICK: "closed"
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
closing: {
|
|
448
|
+
tags: ["open"],
|
|
449
|
+
activities: ["trackStore", "computePlacement"],
|
|
450
|
+
after: {
|
|
451
|
+
CLOSE_DELAY: "closed"
|
|
452
|
+
},
|
|
453
|
+
on: {
|
|
454
|
+
FORCE_CLOSE: "closed",
|
|
455
|
+
POINTER_ENTER: "open",
|
|
456
|
+
TOOLTIP_POINTER_ENTER: {
|
|
457
|
+
guard: "isInteractive",
|
|
458
|
+
target: "open"
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
activities: {
|
|
466
|
+
computePlacement(ctx2) {
|
|
467
|
+
ctx2.currentPlacement = ctx2.positioning.placement;
|
|
468
|
+
let cleanup;
|
|
469
|
+
raf(() => {
|
|
470
|
+
cleanup = getPlacement(dom.getTriggerEl(ctx2), dom.getPositionerEl(ctx2), {
|
|
471
|
+
...ctx2.positioning,
|
|
472
|
+
onComplete(data) {
|
|
473
|
+
ctx2.currentPlacement = data.placement;
|
|
474
|
+
ctx2.isPlacementComplete = true;
|
|
475
|
+
},
|
|
476
|
+
onCleanup() {
|
|
477
|
+
ctx2.currentPlacement = void 0;
|
|
478
|
+
ctx2.isPlacementComplete = false;
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
});
|
|
482
|
+
return cleanup;
|
|
483
|
+
},
|
|
484
|
+
trackPointerlockChange(ctx2, _evt, { send }) {
|
|
485
|
+
return addPointerlockChangeListener(dom.getDoc(ctx2), () => {
|
|
486
|
+
send("POINTER_LOCK_CHANGE");
|
|
487
|
+
});
|
|
488
|
+
},
|
|
489
|
+
trackScroll(ctx2, _evt, { send }) {
|
|
490
|
+
const trigger = dom.getTriggerEl(ctx2);
|
|
491
|
+
if (!trigger)
|
|
492
|
+
return;
|
|
493
|
+
const cleanups = getScrollParents(trigger).map((el) => {
|
|
494
|
+
const opts = { passive: true, capture: true };
|
|
495
|
+
return addDomEvent(el, "scroll", () => send("SCROLL"), opts);
|
|
496
|
+
});
|
|
497
|
+
return () => {
|
|
498
|
+
cleanups.forEach((fn) => fn == null ? void 0 : fn());
|
|
499
|
+
};
|
|
500
|
+
},
|
|
501
|
+
trackStore(ctx2, _evt, { send }) {
|
|
502
|
+
return subscribe(store, () => {
|
|
503
|
+
if (store.id !== ctx2.id) {
|
|
504
|
+
send("FORCE_CLOSE");
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
},
|
|
508
|
+
trackDisabledTriggerOnSafari(ctx2, _evt, { send }) {
|
|
509
|
+
if (!isSafari())
|
|
510
|
+
return;
|
|
511
|
+
const doc = dom.getDoc(ctx2);
|
|
512
|
+
return addPointerEvent(doc, "pointermove", (event) => {
|
|
513
|
+
const selector = "[data-part=trigger][data-expanded]";
|
|
514
|
+
if (isHTMLElement(event.target) && event.target.closest(selector))
|
|
515
|
+
return;
|
|
516
|
+
send("POINTER_LEAVE");
|
|
517
|
+
});
|
|
518
|
+
},
|
|
519
|
+
trackEscapeKey(ctx2, _evt, { send }) {
|
|
520
|
+
if (!ctx2.closeOnEsc)
|
|
521
|
+
return;
|
|
522
|
+
const doc = dom.getDoc(ctx2);
|
|
523
|
+
return addDomEvent(doc, "keydown", (event) => {
|
|
524
|
+
if (event.key === "Escape") {
|
|
525
|
+
send("ESCAPE");
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
},
|
|
530
|
+
actions: {
|
|
531
|
+
setGlobalId(ctx2) {
|
|
532
|
+
store.setId(ctx2.id);
|
|
533
|
+
},
|
|
534
|
+
clearGlobalId(ctx2) {
|
|
535
|
+
if (ctx2.id === store.id) {
|
|
536
|
+
store.setId(null);
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
invokeOnOpen(ctx2, evt) {
|
|
540
|
+
var _a;
|
|
541
|
+
const omit = ["TOOLTIP_POINTER_ENTER", "POINTER_ENTER"];
|
|
542
|
+
if (!omit.includes(evt.type)) {
|
|
543
|
+
(_a = ctx2.onOpen) == null ? void 0 : _a.call(ctx2);
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
invokeOnClose(ctx2, evt) {
|
|
547
|
+
var _a;
|
|
548
|
+
const omit = ["SETUP"];
|
|
549
|
+
if (!omit.includes(evt.type)) {
|
|
550
|
+
(_a = ctx2.onClose) == null ? void 0 : _a.call(ctx2);
|
|
551
|
+
}
|
|
552
|
+
},
|
|
553
|
+
closeIfDisabled(ctx2, _evt, { send }) {
|
|
554
|
+
if (ctx2.disabled) {
|
|
555
|
+
send("CLOSE");
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
guards: {
|
|
560
|
+
closeOnPointerDown: (ctx2) => ctx2.closeOnPointerDown,
|
|
561
|
+
noVisibleTooltip: () => store.id === null,
|
|
562
|
+
isVisible: (ctx2) => ctx2.id === store.id,
|
|
563
|
+
isInteractive: (ctx2) => ctx2.interactive
|
|
564
|
+
},
|
|
565
|
+
delays: {
|
|
566
|
+
OPEN_DELAY: (ctx2) => ctx2.openDelay,
|
|
567
|
+
CLOSE_DELAY: (ctx2) => ctx2.closeDelay
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
export {
|
|
573
|
+
connect,
|
|
574
|
+
machine
|
|
575
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"type": "module",
|
|
3
2
|
"name": "@zag-js/tooltip",
|
|
4
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
5
4
|
"description": "Core logic for the tooltip widget implemented as a state machine",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
6
8
|
"keywords": [
|
|
7
9
|
"js",
|
|
8
10
|
"machine",
|
|
@@ -15,8 +17,6 @@
|
|
|
15
17
|
"author": "Segun Adebayo <sage@adebayosegun.com>",
|
|
16
18
|
"homepage": "https://github.com/chakra-ui/zag#readme",
|
|
17
19
|
"license": "MIT",
|
|
18
|
-
"main": "dist/index.js",
|
|
19
|
-
"types": "dist/index.d.ts",
|
|
20
20
|
"repository": "https://github.com/chakra-ui/zag/tree/main/packages/tooltip",
|
|
21
21
|
"sideEffects": false,
|
|
22
22
|
"files": [
|
|
@@ -29,18 +29,18 @@
|
|
|
29
29
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@zag-js/core": "0.1.
|
|
33
|
-
"@zag-js/popper": "0.1.
|
|
34
|
-
"@zag-js/types": "0.2.
|
|
32
|
+
"@zag-js/core": "0.1.12",
|
|
33
|
+
"@zag-js/popper": "0.1.13",
|
|
34
|
+
"@zag-js/types": "0.2.7"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@zag-js/dom-utils": "0.1.
|
|
38
|
-
"@zag-js/utils": "0.1.
|
|
37
|
+
"@zag-js/dom-utils": "0.1.13",
|
|
38
|
+
"@zag-js/utils": "0.1.6"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
|
-
"build-fast": "tsup src/index.ts --format=esm",
|
|
41
|
+
"build-fast": "tsup src/index.ts --format=esm,cjs",
|
|
42
42
|
"start": "pnpm build --watch",
|
|
43
|
-
"build": "tsup src/index.ts --format=esm --dts",
|
|
43
|
+
"build": "tsup src/index.ts --format=esm,cjs --dts",
|
|
44
44
|
"test": "jest --config ../../../jest.config.js --rootDir . --passWithNoTests",
|
|
45
45
|
"lint": "eslint src --ext .ts,.tsx",
|
|
46
46
|
"test-ci": "pnpm test --ci --runInBand",
|