@zag-js/tooltip 0.10.2 → 0.10.4

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.
@@ -1,8 +1,235 @@
1
- import {
2
- machine
3
- } from "./chunk-GUX4YLRO.mjs";
4
- import "./chunk-BML2QVAG.mjs";
5
- import "./chunk-GQYNO326.mjs";
6
- export {
7
- machine
8
- };
1
+ import { createMachine, subscribe } from '@zag-js/core';
2
+ import { addDomEvent } from '@zag-js/dom-event';
3
+ import { getScrollParents, isSafari, isHTMLElement } from '@zag-js/dom-query';
4
+ import { getPlacement } from '@zag-js/popper';
5
+ import { compact } from '@zag-js/utils';
6
+ import { dom } from './tooltip.dom.mjs';
7
+ import { store } from './tooltip.store.mjs';
8
+
9
+ function machine(userContext) {
10
+ const ctx = compact(userContext);
11
+ return createMachine(
12
+ {
13
+ id: "tooltip",
14
+ initial: "closed",
15
+ context: {
16
+ openDelay: 1e3,
17
+ closeDelay: 500,
18
+ closeOnPointerDown: true,
19
+ closeOnEsc: true,
20
+ interactive: true,
21
+ currentPlacement: void 0,
22
+ ...ctx,
23
+ positioning: {
24
+ placement: "bottom",
25
+ ...ctx.positioning
26
+ }
27
+ },
28
+ computed: {
29
+ hasAriaLabel: (ctx2) => !!ctx2["aria-label"]
30
+ },
31
+ watch: {
32
+ disabled: ["closeIfDisabled"],
33
+ open: ["toggleVisibility"]
34
+ },
35
+ on: {
36
+ OPEN: "open",
37
+ CLOSE: "closed"
38
+ },
39
+ states: {
40
+ closed: {
41
+ tags: ["closed"],
42
+ entry: ["clearGlobalId", "invokeOnClose"],
43
+ on: {
44
+ FOCUS: "open",
45
+ POINTER_ENTER: [
46
+ {
47
+ guard: "noVisibleTooltip",
48
+ target: "opening"
49
+ },
50
+ { target: "open" }
51
+ ]
52
+ }
53
+ },
54
+ opening: {
55
+ tags: ["closed"],
56
+ activities: ["trackScroll", "trackPointerlockChange"],
57
+ after: {
58
+ OPEN_DELAY: "open"
59
+ },
60
+ on: {
61
+ POINTER_LEAVE: "closed",
62
+ BLUR: "closed",
63
+ SCROLL: "closed",
64
+ POINTER_LOCK_CHANGE: "closed",
65
+ POINTER_DOWN: {
66
+ guard: "closeOnPointerDown",
67
+ target: "closed"
68
+ }
69
+ }
70
+ },
71
+ open: {
72
+ tags: ["open"],
73
+ activities: [
74
+ "trackEscapeKey",
75
+ "trackDisabledTriggerOnSafari",
76
+ "trackScroll",
77
+ "trackPointerlockChange",
78
+ "trackPositioning"
79
+ ],
80
+ entry: ["setGlobalId", "invokeOnOpen"],
81
+ on: {
82
+ POINTER_LEAVE: [
83
+ {
84
+ guard: "isVisible",
85
+ target: "closing"
86
+ },
87
+ { target: "closed" }
88
+ ],
89
+ BLUR: "closed",
90
+ ESCAPE: "closed",
91
+ SCROLL: "closed",
92
+ POINTER_LOCK_CHANGE: "closed",
93
+ TOOLTIP_POINTER_LEAVE: {
94
+ guard: "isInteractive",
95
+ target: "closing"
96
+ },
97
+ POINTER_DOWN: {
98
+ guard: "closeOnPointerDown",
99
+ target: "closed"
100
+ },
101
+ CLICK: "closed",
102
+ SET_POSITIONING: {
103
+ actions: "setPositioning"
104
+ }
105
+ }
106
+ },
107
+ closing: {
108
+ tags: ["open"],
109
+ activities: ["trackStore", "trackPositioning"],
110
+ after: {
111
+ CLOSE_DELAY: "closed"
112
+ },
113
+ on: {
114
+ FORCE_CLOSE: "closed",
115
+ POINTER_ENTER: "open",
116
+ TOOLTIP_POINTER_ENTER: {
117
+ guard: "isInteractive",
118
+ target: "open"
119
+ }
120
+ }
121
+ }
122
+ }
123
+ },
124
+ {
125
+ activities: {
126
+ trackPositioning(ctx2) {
127
+ ctx2.currentPlacement = ctx2.positioning.placement;
128
+ const getPositionerEl = () => dom.getPositionerEl(ctx2);
129
+ return getPlacement(dom.getTriggerEl(ctx2), getPositionerEl, {
130
+ ...ctx2.positioning,
131
+ defer: true,
132
+ onComplete(data) {
133
+ ctx2.currentPlacement = data.placement;
134
+ },
135
+ onCleanup() {
136
+ ctx2.currentPlacement = void 0;
137
+ }
138
+ });
139
+ },
140
+ trackPointerlockChange(ctx2, _evt, { send }) {
141
+ const onChange = () => send("POINTER_LOCK_CHANGE");
142
+ return addDomEvent(dom.getDoc(ctx2), "pointerlockchange", onChange, false);
143
+ },
144
+ trackScroll(ctx2, _evt, { send }) {
145
+ const trigger = dom.getTriggerEl(ctx2);
146
+ if (!trigger)
147
+ return;
148
+ const cleanups = getScrollParents(trigger).map((el) => {
149
+ const opts = { passive: true, capture: true };
150
+ return addDomEvent(el, "scroll", () => send("SCROLL"), opts);
151
+ });
152
+ return () => {
153
+ cleanups.forEach((fn) => fn?.());
154
+ };
155
+ },
156
+ trackStore(ctx2, _evt, { send }) {
157
+ return subscribe(store, () => {
158
+ if (store.id !== ctx2.id) {
159
+ send("FORCE_CLOSE");
160
+ }
161
+ });
162
+ },
163
+ trackDisabledTriggerOnSafari(ctx2, _evt, { send }) {
164
+ if (!isSafari())
165
+ return;
166
+ const doc = dom.getDoc(ctx2);
167
+ return addDomEvent(doc, "pointermove", (event) => {
168
+ const selector = "[data-part=trigger][data-expanded]";
169
+ if (isHTMLElement(event.target) && event.target.closest(selector))
170
+ return;
171
+ send("POINTER_LEAVE");
172
+ });
173
+ },
174
+ trackEscapeKey(ctx2, _evt, { send }) {
175
+ if (!ctx2.closeOnEsc)
176
+ return;
177
+ const doc = dom.getDoc(ctx2);
178
+ return addDomEvent(doc, "keydown", (event) => {
179
+ if (event.key === "Escape") {
180
+ send("ESCAPE");
181
+ }
182
+ });
183
+ }
184
+ },
185
+ actions: {
186
+ setGlobalId(ctx2) {
187
+ store.setId(ctx2.id);
188
+ },
189
+ clearGlobalId(ctx2) {
190
+ if (ctx2.id === store.id) {
191
+ store.setId(null);
192
+ }
193
+ },
194
+ invokeOnOpen(ctx2, evt) {
195
+ const omit = ["TOOLTIP_POINTER_ENTER", "POINTER_ENTER"];
196
+ if (!omit.includes(evt.type)) {
197
+ ctx2.onOpen?.();
198
+ }
199
+ },
200
+ invokeOnClose(ctx2) {
201
+ ctx2.onClose?.();
202
+ },
203
+ closeIfDisabled(ctx2, _evt, { send }) {
204
+ if (ctx2.disabled) {
205
+ send("CLOSE");
206
+ }
207
+ },
208
+ setPositioning(ctx2, evt) {
209
+ const getPositionerEl = () => dom.getPositionerEl(ctx2);
210
+ getPlacement(dom.getTriggerEl(ctx2), getPositionerEl, {
211
+ ...ctx2.positioning,
212
+ ...evt.options,
213
+ defer: true,
214
+ listeners: false
215
+ });
216
+ },
217
+ toggleVisibility(ctx2, _evt, { send }) {
218
+ send({ type: ctx2.open ? "OPEN" : "CLOSE", src: "controlled" });
219
+ }
220
+ },
221
+ guards: {
222
+ closeOnPointerDown: (ctx2) => ctx2.closeOnPointerDown,
223
+ noVisibleTooltip: () => store.id === null,
224
+ isVisible: (ctx2) => ctx2.id === store.id,
225
+ isInteractive: (ctx2) => ctx2.interactive
226
+ },
227
+ delays: {
228
+ OPEN_DELAY: (ctx2) => ctx2.openDelay,
229
+ CLOSE_DELAY: (ctx2) => ctx2.closeDelay
230
+ }
231
+ }
232
+ );
233
+ }
234
+
235
+ export { machine };
@@ -4,6 +4,5 @@ type Store = {
4
4
  prevId: Id;
5
5
  setId: (val: Id) => void;
6
6
  };
7
- declare const store: Store;
8
-
9
- export { store };
7
+ export declare const store: Store;
8
+ export {};
@@ -1,30 +1,10 @@
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);
1
+ 'use strict';
19
2
 
20
- // src/tooltip.store.ts
21
- var tooltip_store_exports = {};
22
- __export(tooltip_store_exports, {
23
- store: () => store
24
- });
25
- module.exports = __toCommonJS(tooltip_store_exports);
26
- var import_core = require("@zag-js/core");
27
- var store = (0, import_core.proxy)({
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const core = require('@zag-js/core');
6
+
7
+ const store = core.proxy({
28
8
  id: null,
29
9
  prevId: null,
30
10
  setId(val) {
@@ -32,7 +12,5 @@ var store = (0, import_core.proxy)({
32
12
  this.id = val;
33
13
  }
34
14
  });
35
- // Annotate the CommonJS export names for ESM import in node:
36
- 0 && (module.exports = {
37
- store
38
- });
15
+
16
+ exports.store = store;
@@ -1,6 +1,12 @@
1
- import {
2
- store
3
- } from "./chunk-GQYNO326.mjs";
4
- export {
5
- store
6
- };
1
+ import { proxy } from '@zag-js/core';
2
+
3
+ const store = proxy({
4
+ id: null,
5
+ prevId: null,
6
+ setId(val) {
7
+ this.prevId = this.id;
8
+ this.id = val;
9
+ }
10
+ });
11
+
12
+ export { store };
@@ -1,7 +1,6 @@
1
- import { StateMachine } from '@zag-js/core';
2
- import { PositioningOptions } from '@zag-js/popper';
3
- import { RequiredBy, CommonProperties, RootProperties } from '@zag-js/types';
4
-
1
+ import type { StateMachine as S } from "@zag-js/core";
2
+ import type { Placement, PositioningOptions } from "@zag-js/popper";
3
+ import type { CommonProperties, RequiredBy, RootProperties } from "@zag-js/types";
5
4
  type ElementIds = Partial<{
6
5
  trigger: string;
7
6
  content: string;
@@ -64,7 +63,7 @@ type PublicContext = CommonProperties & {
64
63
  */
65
64
  open?: boolean;
66
65
  };
67
- type UserDefinedContext = RequiredBy<PublicContext, "id">;
66
+ export type UserDefinedContext = RequiredBy<PublicContext, "id">;
68
67
  type ComputedContext = Readonly<{
69
68
  /**
70
69
  * @computed Whether an `aria-label` is set.
@@ -72,12 +71,11 @@ type ComputedContext = Readonly<{
72
71
  readonly hasAriaLabel: boolean;
73
72
  }>;
74
73
  type PrivateContext = RootProperties & {};
75
- type MachineContext = PublicContext & ComputedContext & PrivateContext;
76
- type MachineState = {
74
+ export type MachineContext = PublicContext & ComputedContext & PrivateContext;
75
+ export type MachineState = {
77
76
  value: "opening" | "open" | "closing" | "closed";
78
77
  tags: "open" | "closed";
79
78
  };
80
- type State = StateMachine.State<MachineContext, MachineState>;
81
- type Send = StateMachine.Send<StateMachine.AnyEventObject>;
82
-
83
- export { MachineContext, MachineState, Send, State, UserDefinedContext };
79
+ export type State = S.State<MachineContext, MachineState>;
80
+ export type Send = S.Send<S.AnyEventObject>;
81
+ export type { PositioningOptions, Placement };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/tooltip",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "Core logic for the tooltip widget implemented as a state machine",
5
5
  "keywords": [
6
6
  "js",
@@ -27,14 +27,14 @@
27
27
  "url": "https://github.com/chakra-ui/zag/issues"
28
28
  },
29
29
  "dependencies": {
30
- "@zag-js/anatomy": "0.10.2",
31
- "@zag-js/core": "0.10.2",
32
- "@zag-js/popper": "0.10.2",
33
- "@zag-js/dom-query": "0.10.2",
34
- "@zag-js/dom-event": "0.10.2",
35
- "@zag-js/utils": "0.10.2",
36
- "@zag-js/visually-hidden": "0.10.2",
37
- "@zag-js/types": "0.10.2"
30
+ "@zag-js/anatomy": "0.10.4",
31
+ "@zag-js/core": "0.10.4",
32
+ "@zag-js/popper": "0.10.4",
33
+ "@zag-js/dom-query": "0.10.4",
34
+ "@zag-js/dom-event": "0.10.4",
35
+ "@zag-js/utils": "0.10.4",
36
+ "@zag-js/visually-hidden": "0.10.4",
37
+ "@zag-js/types": "0.10.4"
38
38
  },
39
39
  "devDependencies": {
40
40
  "clean-package": "2.2.0"
@@ -52,13 +52,8 @@
52
52
  "./package.json": "./package.json"
53
53
  },
54
54
  "scripts": {
55
- "build-fast": "tsup src",
56
- "start": "pnpm build --watch",
57
- "build": "tsup src --dts",
58
- "test": "jest --config ../../../jest.config.js --rootDir . --passWithNoTests",
55
+ "build": "vite build -c ../../../vite.config.ts",
59
56
  "lint": "eslint src --ext .ts,.tsx",
60
- "test-ci": "pnpm test --ci --runInBand",
61
- "test-watch": "pnpm test --watch -u",
62
57
  "typecheck": "tsc --noEmit"
63
58
  }
64
59
  }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { anatomy } from "./tooltip.anatomy"
2
2
  export { connect } from "./tooltip.connect"
3
3
  export { machine } from "./tooltip.machine"
4
- export type { UserDefinedContext as Context } from "./tooltip.types"
4
+ export type { UserDefinedContext as Context, Placement, PositioningOptions } from "./tooltip.types"
@@ -93,3 +93,5 @@ export type MachineState = {
93
93
  export type State = S.State<MachineContext, MachineState>
94
94
 
95
95
  export type Send = S.Send<S.AnyEventObject>
96
+
97
+ export type { PositioningOptions, Placement }
@@ -1,17 +0,0 @@
1
- // src/tooltip.dom.ts
2
- import { createScope, getScrollParent } from "@zag-js/dom-query";
3
- var dom = createScope({
4
- getTriggerId: (ctx) => ctx.ids?.trigger ?? `tooltip:${ctx.id}:trigger`,
5
- getContentId: (ctx) => ctx.ids?.content ?? `tooltip:${ctx.id}:content`,
6
- getArrowId: (ctx) => ctx.ids?.arrow ?? `tooltip:${ctx.id}:arrow`,
7
- getPositionerId: (ctx) => ctx.ids?.positioner ?? `tooltip:${ctx.id}:popper`,
8
- getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
9
- getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
10
- getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
11
- getArrowEl: (ctx) => dom.getById(ctx, dom.getArrowId(ctx)),
12
- getScrollParent: (ctx) => getScrollParent(dom.getTriggerEl(ctx))
13
- });
14
-
15
- export {
16
- dom
17
- };
@@ -1,138 +0,0 @@
1
- import {
2
- parts
3
- } from "./chunk-RRQRIZBA.mjs";
4
- import {
5
- dom
6
- } from "./chunk-BML2QVAG.mjs";
7
- import {
8
- store
9
- } from "./chunk-GQYNO326.mjs";
10
-
11
- // src/tooltip.connect.ts
12
- import { dataAttr } from "@zag-js/dom-query";
13
- import { getPlacementStyles } from "@zag-js/popper";
14
- import { visuallyHiddenStyle } from "@zag-js/visually-hidden";
15
- function connect(state, send, normalize) {
16
- const id = state.context.id;
17
- const hasAriaLabel = state.context.hasAriaLabel;
18
- const isOpen = state.hasTag("open");
19
- const triggerId = dom.getTriggerId(state.context);
20
- const contentId = dom.getContentId(state.context);
21
- const isDisabled = state.context.disabled;
22
- const popperStyles = getPlacementStyles({
23
- placement: state.context.currentPlacement
24
- });
25
- return {
26
- /**
27
- * Whether the tooltip is open.
28
- */
29
- isOpen,
30
- /**
31
- * Function to open the tooltip.
32
- */
33
- open() {
34
- send("OPEN");
35
- },
36
- /**
37
- * Function to close the tooltip.
38
- */
39
- close() {
40
- send("CLOSE");
41
- },
42
- /**
43
- * Returns the animation state of the tooltip.
44
- */
45
- getAnimationState() {
46
- return {
47
- enter: store.prevId === null && id === store.id,
48
- exit: store.id === null
49
- };
50
- },
51
- /**
52
- * Function to reposition the popover
53
- */
54
- setPositioning(options = {}) {
55
- send({ type: "SET_POSITIONING", options });
56
- },
57
- triggerProps: normalize.button({
58
- ...parts.trigger.attrs,
59
- id: triggerId,
60
- "data-expanded": dataAttr(isOpen),
61
- "aria-describedby": isOpen ? contentId : void 0,
62
- onClick() {
63
- send("CLICK");
64
- },
65
- onFocus() {
66
- send("FOCUS");
67
- },
68
- onBlur() {
69
- if (id === store.id) {
70
- send("BLUR");
71
- }
72
- },
73
- onPointerDown() {
74
- if (isDisabled)
75
- return;
76
- if (id === store.id) {
77
- send("POINTER_DOWN");
78
- }
79
- },
80
- onPointerMove() {
81
- if (isDisabled)
82
- return;
83
- send("POINTER_ENTER");
84
- },
85
- onPointerLeave() {
86
- if (isDisabled)
87
- return;
88
- send("POINTER_LEAVE");
89
- },
90
- onPointerCancel() {
91
- if (isDisabled)
92
- return;
93
- send("POINTER_LEAVE");
94
- }
95
- }),
96
- arrowProps: normalize.element({
97
- id: dom.getArrowId(state.context),
98
- ...parts.arrow.attrs,
99
- style: popperStyles.arrow
100
- }),
101
- arrowTipProps: normalize.element({
102
- ...parts.arrowTip.attrs,
103
- style: popperStyles.arrowTip
104
- }),
105
- positionerProps: normalize.element({
106
- id: dom.getPositionerId(state.context),
107
- ...parts.positioner.attrs,
108
- style: popperStyles.floating
109
- }),
110
- contentProps: normalize.element({
111
- ...parts.content.attrs,
112
- hidden: !isOpen,
113
- role: hasAriaLabel ? void 0 : "tooltip",
114
- id: hasAriaLabel ? void 0 : contentId,
115
- "data-placement": state.context.currentPlacement,
116
- onPointerEnter() {
117
- send("TOOLTIP_POINTER_ENTER");
118
- },
119
- onPointerLeave() {
120
- send("TOOLTIP_POINTER_LEAVE");
121
- },
122
- style: {
123
- pointerEvents: state.context.interactive ? "auto" : "none"
124
- }
125
- }),
126
- labelProps: normalize.element({
127
- ...parts.label.attrs,
128
- id: contentId,
129
- role: "tooltip",
130
- style: visuallyHiddenStyle,
131
- children: state.context["aria-label"]
132
- })
133
- };
134
- }
135
-
136
- export {
137
- connect
138
- };
@@ -1,14 +0,0 @@
1
- // src/tooltip.store.ts
2
- import { proxy } from "@zag-js/core";
3
- var store = proxy({
4
- id: null,
5
- prevId: null,
6
- setId(val) {
7
- this.prevId = this.id;
8
- this.id = val;
9
- }
10
- });
11
-
12
- export {
13
- store
14
- };