@zag-js/tooltip 1.34.0 → 1.35.0

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.mjs CHANGED
@@ -1,530 +1,10 @@
1
- import { createAnatomy } from '@zag-js/anatomy';
2
- import { addDomEvent, getOverflowAncestors, isComposingEvent, dataAttr, isLeftClick } from '@zag-js/dom-query';
3
- import { trackFocusVisible, isFocusVisible } from '@zag-js/focus-visible';
4
- import { getPlacement, getPlacementStyles } from '@zag-js/popper';
5
- import { createStore, ensureProps, createSplitProps } from '@zag-js/utils';
6
- import { createGuards, createMachine } from '@zag-js/core';
7
- import { createProps } from '@zag-js/types';
8
-
9
- // src/tooltip.anatomy.ts
10
- var anatomy = createAnatomy("tooltip").parts("trigger", "arrow", "arrowTip", "positioner", "content");
11
- var parts = anatomy.build();
12
-
13
- // src/tooltip.dom.ts
14
- var getTriggerId = (scope) => scope.ids?.trigger ?? `tooltip:${scope.id}:trigger`;
15
- var getContentId = (scope) => scope.ids?.content ?? `tooltip:${scope.id}:content`;
16
- var getArrowId = (scope) => scope.ids?.arrow ?? `tooltip:${scope.id}:arrow`;
17
- var getPositionerId = (scope) => scope.ids?.positioner ?? `tooltip:${scope.id}:popper`;
18
- var getTriggerEl = (scope) => scope.getById(getTriggerId(scope));
19
- var getPositionerEl = (scope) => scope.getById(getPositionerId(scope));
20
- var store = createStore({
21
- id: null,
22
- prevId: null,
23
- instant: false
24
- });
25
-
26
- // src/tooltip.connect.ts
27
- function connect(service, normalize) {
28
- const { state, context, send, scope, prop, event: _event } = service;
29
- const id = prop("id");
30
- const hasAriaLabel = !!prop("aria-label");
31
- const open = state.matches("open", "closing");
32
- const triggerId = getTriggerId(scope);
33
- const contentId = getContentId(scope);
34
- const disabled = prop("disabled");
35
- const popperStyles = getPlacementStyles({
36
- ...prop("positioning"),
37
- placement: context.get("currentPlacement")
38
- });
39
- return {
40
- open,
41
- setOpen(nextOpen) {
42
- const open2 = state.matches("open", "closing");
43
- if (open2 === nextOpen) return;
44
- send({ type: nextOpen ? "open" : "close" });
45
- },
46
- reposition(options = {}) {
47
- send({ type: "positioning.set", options });
48
- },
49
- getTriggerProps() {
50
- return normalize.button({
51
- ...parts.trigger.attrs,
52
- id: triggerId,
53
- dir: prop("dir"),
54
- "data-expanded": dataAttr(open),
55
- "data-state": open ? "open" : "closed",
56
- "aria-describedby": open ? contentId : void 0,
57
- onClick(event) {
58
- if (event.defaultPrevented) return;
59
- if (disabled) return;
60
- if (!prop("closeOnClick")) return;
61
- send({ type: "close", src: "trigger.click" });
62
- },
63
- onFocus(event) {
64
- queueMicrotask(() => {
65
- if (event.defaultPrevented) return;
66
- if (disabled) return;
67
- if (_event.src === "trigger.pointerdown") return;
68
- if (!isFocusVisible()) return;
69
- send({ type: "open", src: "trigger.focus" });
70
- });
71
- },
72
- onBlur(event) {
73
- if (event.defaultPrevented) return;
74
- if (disabled) return;
75
- if (id === store.get("id")) {
76
- send({ type: "close", src: "trigger.blur" });
77
- }
78
- },
79
- onPointerDown(event) {
80
- if (event.defaultPrevented) return;
81
- if (disabled) return;
82
- if (!isLeftClick(event)) return;
83
- if (!prop("closeOnPointerDown")) return;
84
- if (id === store.get("id")) {
85
- send({ type: "close", src: "trigger.pointerdown" });
86
- }
87
- },
88
- onPointerMove(event) {
89
- if (event.defaultPrevented) return;
90
- if (disabled) return;
91
- if (event.pointerType === "touch") return;
92
- send({ type: "pointer.move" });
93
- },
94
- onPointerOver(event) {
95
- if (event.defaultPrevented) return;
96
- if (disabled) return;
97
- if (event.pointerType === "touch") return;
98
- send({ type: "pointer.move" });
99
- },
100
- onPointerLeave() {
101
- if (disabled) return;
102
- send({ type: "pointer.leave" });
103
- },
104
- onPointerCancel() {
105
- if (disabled) return;
106
- send({ type: "pointer.leave" });
107
- }
108
- });
109
- },
110
- getArrowProps() {
111
- return normalize.element({
112
- id: getArrowId(scope),
113
- ...parts.arrow.attrs,
114
- dir: prop("dir"),
115
- style: popperStyles.arrow
116
- });
117
- },
118
- getArrowTipProps() {
119
- return normalize.element({
120
- ...parts.arrowTip.attrs,
121
- dir: prop("dir"),
122
- style: popperStyles.arrowTip
123
- });
124
- },
125
- getPositionerProps() {
126
- return normalize.element({
127
- id: getPositionerId(scope),
128
- ...parts.positioner.attrs,
129
- dir: prop("dir"),
130
- style: popperStyles.floating
131
- });
132
- },
133
- getContentProps() {
134
- const isCurrentTooltip = store.get("id") === id;
135
- const isPrevTooltip = store.get("prevId") === id;
136
- const instant = store.get("instant") && (open && isCurrentTooltip || isPrevTooltip);
137
- return normalize.element({
138
- ...parts.content.attrs,
139
- dir: prop("dir"),
140
- hidden: !open,
141
- "data-state": open ? "open" : "closed",
142
- "data-instant": dataAttr(instant),
143
- role: hasAriaLabel ? void 0 : "tooltip",
144
- id: hasAriaLabel ? void 0 : contentId,
145
- "data-placement": context.get("currentPlacement"),
146
- onPointerEnter() {
147
- send({ type: "content.pointer.move" });
148
- },
149
- onPointerLeave() {
150
- send({ type: "content.pointer.leave" });
151
- },
152
- style: {
153
- pointerEvents: prop("interactive") ? "auto" : "none"
154
- }
155
- });
156
- }
157
- };
158
- }
159
- var { and, not } = createGuards();
160
- var machine = createMachine({
161
- initialState: ({ prop }) => {
162
- const open = prop("open") || prop("defaultOpen");
163
- return open ? "open" : "closed";
164
- },
165
- props({ props: props2 }) {
166
- ensureProps(props2, ["id"]);
167
- const closeOnClick = props2.closeOnClick ?? true;
168
- const closeOnPointerDown = props2.closeOnPointerDown ?? closeOnClick;
169
- return {
170
- openDelay: 400,
171
- closeDelay: 150,
172
- closeOnEscape: true,
173
- interactive: false,
174
- closeOnScroll: true,
175
- disabled: false,
176
- ...props2,
177
- closeOnPointerDown,
178
- closeOnClick,
179
- positioning: {
180
- placement: "bottom",
181
- ...props2.positioning
182
- }
183
- };
184
- },
185
- effects: ["trackFocusVisible", "trackStore"],
186
- context: ({ bindable }) => ({
187
- currentPlacement: bindable(() => ({ defaultValue: void 0 })),
188
- hasPointerMoveOpened: bindable(() => ({ defaultValue: false }))
189
- }),
190
- watch({ track, action, prop }) {
191
- track([() => prop("disabled")], () => {
192
- action(["closeIfDisabled"]);
193
- });
194
- track([() => prop("open")], () => {
195
- action(["toggleVisibility"]);
196
- });
197
- },
198
- states: {
199
- closed: {
200
- entry: ["clearGlobalId"],
201
- on: {
202
- "controlled.open": {
203
- target: "open"
204
- },
205
- open: [
206
- {
207
- guard: "isOpenControlled",
208
- actions: ["invokeOnOpen"]
209
- },
210
- {
211
- target: "open",
212
- actions: ["invokeOnOpen"]
213
- }
214
- ],
215
- "pointer.leave": {
216
- actions: ["clearPointerMoveOpened"]
217
- },
218
- "pointer.move": [
219
- {
220
- guard: and("noVisibleTooltip", not("hasPointerMoveOpened")),
221
- target: "opening"
222
- },
223
- {
224
- guard: not("hasPointerMoveOpened"),
225
- target: "open",
226
- actions: ["setPointerMoveOpened", "invokeOnOpen"]
227
- }
228
- ]
229
- }
230
- },
231
- opening: {
232
- effects: ["trackScroll", "trackPointerlockChange", "waitForOpenDelay"],
233
- on: {
234
- "after.openDelay": [
235
- {
236
- guard: "isOpenControlled",
237
- actions: ["setPointerMoveOpened", "invokeOnOpen"]
238
- },
239
- {
240
- target: "open",
241
- actions: ["setPointerMoveOpened", "invokeOnOpen"]
242
- }
243
- ],
244
- "controlled.open": {
245
- target: "open"
246
- },
247
- "controlled.close": {
248
- target: "closed"
249
- },
250
- open: [
251
- {
252
- guard: "isOpenControlled",
253
- actions: ["invokeOnOpen"]
254
- },
255
- {
256
- target: "open",
257
- actions: ["invokeOnOpen"]
258
- }
259
- ],
260
- "pointer.leave": [
261
- {
262
- guard: "isOpenControlled",
263
- // We trigger toggleVisibility manually since the `ctx.open` has not changed yet (at this point)
264
- actions: ["clearPointerMoveOpened", "invokeOnClose", "toggleVisibility"]
265
- },
266
- {
267
- target: "closed",
268
- actions: ["clearPointerMoveOpened", "invokeOnClose"]
269
- }
270
- ],
271
- close: [
272
- {
273
- guard: "isOpenControlled",
274
- // We trigger toggleVisibility manually since the `ctx.open` has not changed yet (at this point)
275
- actions: ["invokeOnClose", "toggleVisibility"]
276
- },
277
- {
278
- target: "closed",
279
- actions: ["invokeOnClose"]
280
- }
281
- ]
282
- }
283
- },
284
- open: {
285
- effects: ["trackEscapeKey", "trackScroll", "trackPointerlockChange", "trackPositioning"],
286
- entry: ["setGlobalId"],
287
- on: {
288
- "controlled.close": {
289
- target: "closed"
290
- },
291
- close: [
292
- {
293
- guard: "isOpenControlled",
294
- actions: ["invokeOnClose"]
295
- },
296
- {
297
- target: "closed",
298
- actions: ["invokeOnClose"]
299
- }
300
- ],
301
- "pointer.leave": [
302
- {
303
- guard: "isVisible",
304
- target: "closing",
305
- actions: ["clearPointerMoveOpened"]
306
- },
307
- // == group ==
308
- {
309
- guard: "isOpenControlled",
310
- actions: ["clearPointerMoveOpened", "invokeOnClose"]
311
- },
312
- {
313
- target: "closed",
314
- actions: ["clearPointerMoveOpened", "invokeOnClose"]
315
- }
316
- ],
317
- "content.pointer.leave": {
318
- guard: "isInteractive",
319
- target: "closing"
320
- },
321
- "positioning.set": {
322
- actions: ["reposition"]
323
- }
324
- }
325
- },
326
- closing: {
327
- effects: ["trackPositioning", "waitForCloseDelay"],
328
- on: {
329
- "after.closeDelay": [
330
- {
331
- guard: "isOpenControlled",
332
- actions: ["invokeOnClose"]
333
- },
334
- {
335
- target: "closed",
336
- actions: ["invokeOnClose"]
337
- }
338
- ],
339
- "controlled.close": {
340
- target: "closed"
341
- },
342
- "controlled.open": {
343
- target: "open"
344
- },
345
- close: [
346
- {
347
- guard: "isOpenControlled",
348
- actions: ["invokeOnClose"]
349
- },
350
- {
351
- target: "closed",
352
- actions: ["invokeOnClose"]
353
- }
354
- ],
355
- "pointer.move": [
356
- {
357
- guard: "isOpenControlled",
358
- // We trigger toggleVisibility manually since the `ctx.open` has not changed yet (at this point)
359
- actions: ["setPointerMoveOpened", "invokeOnOpen", "toggleVisibility"]
360
- },
361
- {
362
- target: "open",
363
- actions: ["setPointerMoveOpened", "invokeOnOpen"]
364
- }
365
- ],
366
- "content.pointer.move": {
367
- guard: "isInteractive",
368
- target: "open"
369
- },
370
- "positioning.set": {
371
- actions: ["reposition"]
372
- }
373
- }
374
- }
375
- },
376
- implementations: {
377
- guards: {
378
- noVisibleTooltip: () => store.get("id") === null,
379
- isVisible: ({ prop }) => prop("id") === store.get("id"),
380
- isInteractive: ({ prop }) => !!prop("interactive"),
381
- hasPointerMoveOpened: ({ context }) => context.get("hasPointerMoveOpened"),
382
- isOpenControlled: ({ prop }) => prop("open") !== void 0
383
- },
384
- actions: {
385
- setGlobalId: ({ prop }) => {
386
- const prevId = store.get("id");
387
- const isInstant = prevId !== null && prevId !== prop("id");
388
- store.update({ id: prop("id"), prevId: isInstant ? prevId : null, instant: isInstant });
389
- },
390
- clearGlobalId: ({ prop }) => {
391
- if (prop("id") === store.get("id")) {
392
- store.update({ id: null, prevId: null, instant: false });
393
- }
394
- },
395
- invokeOnOpen: ({ prop }) => {
396
- prop("onOpenChange")?.({ open: true });
397
- },
398
- invokeOnClose: ({ prop }) => {
399
- prop("onOpenChange")?.({ open: false });
400
- },
401
- closeIfDisabled: ({ prop, send }) => {
402
- if (!prop("disabled")) return;
403
- send({ type: "close", src: "disabled.change" });
404
- },
405
- reposition: ({ context, event, prop, scope }) => {
406
- if (event.type !== "positioning.set") return;
407
- const getPositionerEl2 = () => getPositionerEl(scope);
408
- return getPlacement(getTriggerEl(scope), getPositionerEl2, {
409
- ...prop("positioning"),
410
- ...event.options,
411
- defer: true,
412
- listeners: false,
413
- onComplete(data) {
414
- context.set("currentPlacement", data.placement);
415
- }
416
- });
417
- },
418
- toggleVisibility: ({ prop, event, send }) => {
419
- queueMicrotask(() => {
420
- send({
421
- type: prop("open") ? "controlled.open" : "controlled.close",
422
- previousEvent: event
423
- });
424
- });
425
- },
426
- setPointerMoveOpened: ({ context }) => {
427
- context.set("hasPointerMoveOpened", true);
428
- },
429
- clearPointerMoveOpened: ({ context }) => {
430
- context.set("hasPointerMoveOpened", false);
431
- }
432
- },
433
- effects: {
434
- trackFocusVisible: ({ scope }) => {
435
- return trackFocusVisible({ root: scope.getRootNode?.() });
436
- },
437
- trackPositioning: ({ context, prop, scope }) => {
438
- if (!context.get("currentPlacement")) {
439
- context.set("currentPlacement", prop("positioning").placement);
440
- }
441
- const getPositionerEl2 = () => getPositionerEl(scope);
442
- return getPlacement(getTriggerEl(scope), getPositionerEl2, {
443
- ...prop("positioning"),
444
- defer: true,
445
- onComplete(data) {
446
- context.set("currentPlacement", data.placement);
447
- }
448
- });
449
- },
450
- trackPointerlockChange: ({ send, scope }) => {
451
- const doc = scope.getDoc();
452
- const onChange = () => send({ type: "close", src: "pointerlock:change" });
453
- return addDomEvent(doc, "pointerlockchange", onChange, false);
454
- },
455
- trackScroll: ({ send, prop, scope }) => {
456
- if (!prop("closeOnScroll")) return;
457
- const triggerEl = getTriggerEl(scope);
458
- if (!triggerEl) return;
459
- const overflowParents = getOverflowAncestors(triggerEl);
460
- const cleanups = overflowParents.map((overflowParent) => {
461
- const onScroll = () => {
462
- send({ type: "close", src: "scroll" });
463
- };
464
- return addDomEvent(overflowParent, "scroll", onScroll, {
465
- passive: true,
466
- capture: true
467
- });
468
- });
469
- return () => {
470
- cleanups.forEach((fn) => fn?.());
471
- };
472
- },
473
- trackStore: ({ prop, send }) => {
474
- let cleanup;
475
- queueMicrotask(() => {
476
- cleanup = store.subscribe(() => {
477
- if (store.get("id") !== prop("id")) {
478
- send({ type: "close", src: "id.change" });
479
- }
480
- });
481
- });
482
- return () => cleanup?.();
483
- },
484
- trackEscapeKey: ({ send, prop }) => {
485
- if (!prop("closeOnEscape")) return;
486
- const onKeyDown = (event) => {
487
- if (isComposingEvent(event)) return;
488
- if (event.key !== "Escape") return;
489
- event.stopPropagation();
490
- send({ type: "close", src: "keydown.escape" });
491
- };
492
- return addDomEvent(document, "keydown", onKeyDown, true);
493
- },
494
- waitForOpenDelay: ({ send, prop }) => {
495
- const id = setTimeout(() => {
496
- send({ type: "after.openDelay" });
497
- }, prop("openDelay"));
498
- return () => clearTimeout(id);
499
- },
500
- waitForCloseDelay: ({ send, prop }) => {
501
- const id = setTimeout(() => {
502
- send({ type: "after.closeDelay" });
503
- }, prop("closeDelay"));
504
- return () => clearTimeout(id);
505
- }
506
- }
507
- }
508
- });
509
- var props = createProps()([
510
- "aria-label",
511
- "closeDelay",
512
- "closeOnEscape",
513
- "closeOnPointerDown",
514
- "closeOnScroll",
515
- "closeOnClick",
516
- "dir",
517
- "disabled",
518
- "getRootNode",
519
- "id",
520
- "ids",
521
- "interactive",
522
- "onOpenChange",
523
- "defaultOpen",
524
- "open",
525
- "openDelay",
526
- "positioning"
527
- ]);
528
- var splitProps = createSplitProps(props);
529
-
530
- export { anatomy, connect, machine, props, splitProps };
1
+ // src/index.ts
2
+ import { anatomy } from "./tooltip.anatomy.mjs";
3
+ import { connect } from "./tooltip.connect.mjs";
4
+ import { machine } from "./tooltip.machine.mjs";
5
+ export * from "./tooltip.props.mjs";
6
+ export {
7
+ anatomy,
8
+ connect,
9
+ machine
10
+ };
@@ -0,0 +1,6 @@
1
+ import * as _zag_js_anatomy from '@zag-js/anatomy';
2
+
3
+ declare const anatomy: _zag_js_anatomy.AnatomyInstance<"trigger" | "arrow" | "arrowTip" | "positioner" | "content">;
4
+ declare const parts: Record<"trigger" | "arrow" | "arrowTip" | "positioner" | "content", _zag_js_anatomy.AnatomyPart>;
5
+
6
+ export { anatomy, parts };
@@ -0,0 +1,6 @@
1
+ import * as _zag_js_anatomy from '@zag-js/anatomy';
2
+
3
+ declare const anatomy: _zag_js_anatomy.AnatomyInstance<"trigger" | "arrow" | "arrowTip" | "positioner" | "content">;
4
+ declare const parts: Record<"trigger" | "arrow" | "arrowTip" | "positioner" | "content", _zag_js_anatomy.AnatomyPart>;
5
+
6
+ export { anatomy, parts };
@@ -0,0 +1,34 @@
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/tooltip.anatomy.ts
21
+ var tooltip_anatomy_exports = {};
22
+ __export(tooltip_anatomy_exports, {
23
+ anatomy: () => anatomy,
24
+ parts: () => parts
25
+ });
26
+ module.exports = __toCommonJS(tooltip_anatomy_exports);
27
+ var import_anatomy = require("@zag-js/anatomy");
28
+ var anatomy = (0, import_anatomy.createAnatomy)("tooltip").parts("trigger", "arrow", "arrowTip", "positioner", "content");
29
+ var parts = anatomy.build();
30
+ // Annotate the CommonJS export names for ESM import in node:
31
+ 0 && (module.exports = {
32
+ anatomy,
33
+ parts
34
+ });
@@ -0,0 +1,8 @@
1
+ // src/tooltip.anatomy.ts
2
+ import { createAnatomy } from "@zag-js/anatomy";
3
+ var anatomy = createAnatomy("tooltip").parts("trigger", "arrow", "arrowTip", "positioner", "content");
4
+ var parts = anatomy.build();
5
+ export {
6
+ anatomy,
7
+ parts
8
+ };
@@ -0,0 +1,8 @@
1
+ import { Service } from '@zag-js/core';
2
+ import { PropTypes, NormalizeProps } from '@zag-js/types';
3
+ import { TooltipSchema, TooltipApi } from './tooltip.types.mjs';
4
+ import '@zag-js/popper';
5
+
6
+ declare function connect<P extends PropTypes>(service: Service<TooltipSchema>, normalize: NormalizeProps<P>): TooltipApi<P>;
7
+
8
+ export { connect };
@@ -0,0 +1,8 @@
1
+ import { Service } from '@zag-js/core';
2
+ import { PropTypes, NormalizeProps } from '@zag-js/types';
3
+ import { TooltipSchema, TooltipApi } from './tooltip.types.js';
4
+ import '@zag-js/popper';
5
+
6
+ declare function connect<P extends PropTypes>(service: Service<TooltipSchema>, normalize: NormalizeProps<P>): TooltipApi<P>;
7
+
8
+ export { connect };