@destyler/hover-card 0.0.6 → 0.0.7-beta.1

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,10 +1,335 @@
1
- export { HoverCardArrow, HoverCardContent, HoverCardPortal, HoverCardRoot, HoverCardTrigger, hoverCardArrowProps, hoverCardContentProps, hoverCardPortalProps, hoverCardRootProps, hoverCardTriggerProps } from './component.mjs';
2
- import 'vue';
3
- import '@destyler/primitive';
4
- import '@destyler/composition';
5
- import '@destyler/popper';
6
- import '@destyler/presence';
7
- import '@destyler/dismissable-layer';
8
- import '@destyler/dismissable-layer/component';
9
- import '@destyler/shared';
10
- import '@destyler/teleport';
1
+ import { createAnatomy } from '@zag-js/anatomy';
2
+ import { getPlacementStyles, getPlacement } from '@zag-js/popper';
3
+ import { createScope } from '@zag-js/dom-query';
4
+ import { createMachine, guards } from '@zag-js/core';
5
+ import { trackDismissableElement } from '@zag-js/dismissable';
6
+ import { compact, createSplitProps } from '@zag-js/utils';
7
+ import { createProps } from '@zag-js/types';
8
+
9
+ const anatomy = createAnatomy("hoverCard").parts("arrow", "arrowTip", "trigger", "positioner", "content");
10
+ const parts = anatomy.build();
11
+
12
+ const dom = createScope({
13
+ getTriggerId: (ctx) => ctx.ids?.trigger ?? `hover-card:${ctx.id}:trigger`,
14
+ getContentId: (ctx) => ctx.ids?.content ?? `hover-card:${ctx.id}:content`,
15
+ getPositionerId: (ctx) => ctx.ids?.positioner ?? `hover-card:${ctx.id}:popper`,
16
+ getArrowId: (ctx) => ctx.ids?.arrow ?? `hover-card:${ctx.id}:arrow`,
17
+ getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
18
+ getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
19
+ getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx))
20
+ });
21
+
22
+ function connect(state, send, normalize) {
23
+ const open = state.hasTag("open");
24
+ const popperStyles = getPlacementStyles({
25
+ ...state.context.positioning,
26
+ placement: state.context.currentPlacement
27
+ });
28
+ return {
29
+ open,
30
+ setOpen(nextOpen) {
31
+ if (nextOpen === open)
32
+ return;
33
+ send(nextOpen ? "OPEN" : "CLOSE");
34
+ },
35
+ reposition(options = {}) {
36
+ send({ type: "POSITIONING.SET", options });
37
+ },
38
+ getArrowProps() {
39
+ return normalize.element({
40
+ id: dom.getArrowId(state.context),
41
+ ...parts.arrow.attrs,
42
+ dir: state.context.dir,
43
+ style: popperStyles.arrow
44
+ });
45
+ },
46
+ getArrowTipProps() {
47
+ return normalize.element({
48
+ ...parts.arrowTip.attrs,
49
+ dir: state.context.dir,
50
+ style: popperStyles.arrowTip
51
+ });
52
+ },
53
+ getTriggerProps() {
54
+ return normalize.element({
55
+ ...parts.trigger.attrs,
56
+ "dir": state.context.dir,
57
+ "data-placement": state.context.currentPlacement,
58
+ "id": dom.getTriggerId(state.context),
59
+ "data-state": open ? "open" : "closed",
60
+ onPointerEnter(event) {
61
+ if (event.pointerType === "touch")
62
+ return;
63
+ send({ type: "POINTER_ENTER", src: "trigger" });
64
+ },
65
+ onPointerLeave(event) {
66
+ if (event.pointerType === "touch")
67
+ return;
68
+ send({ type: "POINTER_LEAVE", src: "trigger" });
69
+ },
70
+ onFocus() {
71
+ send("TRIGGER_FOCUS");
72
+ },
73
+ onBlur() {
74
+ send("TRIGGER_BLUR");
75
+ }
76
+ });
77
+ },
78
+ getPositionerProps() {
79
+ return normalize.element({
80
+ id: dom.getPositionerId(state.context),
81
+ ...parts.positioner.attrs,
82
+ dir: state.context.dir,
83
+ style: popperStyles.floating
84
+ });
85
+ },
86
+ getContentProps() {
87
+ return normalize.element({
88
+ ...parts.content.attrs,
89
+ "dir": state.context.dir,
90
+ "id": dom.getContentId(state.context),
91
+ "hidden": !open,
92
+ "data-state": open ? "open" : "closed",
93
+ "data-placement": state.context.currentPlacement,
94
+ onPointerEnter(event) {
95
+ if (event.pointerType === "touch")
96
+ return;
97
+ send({ type: "POINTER_ENTER", src: "content" });
98
+ },
99
+ onPointerLeave(event) {
100
+ if (event.pointerType === "touch")
101
+ return;
102
+ send({ type: "POINTER_LEAVE", src: "content" });
103
+ }
104
+ });
105
+ }
106
+ };
107
+ }
108
+
109
+ const { not, and } = guards;
110
+ function machine(userContext) {
111
+ const ctx = compact(userContext);
112
+ return createMachine(
113
+ {
114
+ id: "hover-card",
115
+ initial: ctx.open ? "open" : "closed",
116
+ context: {
117
+ openDelay: 700,
118
+ closeDelay: 300,
119
+ currentPlacement: void 0,
120
+ ...ctx,
121
+ positioning: {
122
+ placement: "bottom",
123
+ ...ctx.positioning
124
+ }
125
+ },
126
+ watch: {
127
+ open: ["toggleVisibility"]
128
+ },
129
+ states: {
130
+ closed: {
131
+ tags: ["closed"],
132
+ entry: ["clearIsPointer"],
133
+ on: {
134
+ "CONTROLLED.OPEN": "open",
135
+ "POINTER_ENTER": {
136
+ target: "opening",
137
+ actions: ["setIsPointer"]
138
+ },
139
+ "TRIGGER_FOCUS": "opening",
140
+ "OPEN": "opening"
141
+ }
142
+ },
143
+ opening: {
144
+ tags: ["closed"],
145
+ after: {
146
+ OPEN_DELAY: [
147
+ {
148
+ guard: "isOpenControlled",
149
+ actions: ["invokeOnOpen"]
150
+ },
151
+ {
152
+ target: "open",
153
+ actions: ["invokeOnOpen"]
154
+ }
155
+ ]
156
+ },
157
+ on: {
158
+ "CONTROLLED.OPEN": "open",
159
+ "POINTER_LEAVE": [
160
+ {
161
+ guard: "isOpenControlled",
162
+ actions: ["invokeOnClose"]
163
+ },
164
+ {
165
+ target: "closed",
166
+ actions: ["invokeOnClose"]
167
+ }
168
+ ],
169
+ "TRIGGER_BLUR": [
170
+ {
171
+ guard: and("isOpenControlled", not("isPointer")),
172
+ actions: ["invokeOnClose"]
173
+ },
174
+ {
175
+ guard: not("isPointer"),
176
+ target: "closed",
177
+ actions: ["invokeOnClose"]
178
+ }
179
+ ],
180
+ "CLOSE": [
181
+ {
182
+ guard: "isOpenControlled",
183
+ actions: ["invokeOnClose"]
184
+ },
185
+ {
186
+ target: "closed",
187
+ actions: ["invokeOnClose"]
188
+ }
189
+ ]
190
+ }
191
+ },
192
+ open: {
193
+ tags: ["open"],
194
+ activities: ["trackDismissableElement", "trackPositioning"],
195
+ on: {
196
+ "CONTROLLED.CLOSE": "closed",
197
+ "POINTER_ENTER": {
198
+ actions: ["setIsPointer"]
199
+ },
200
+ "POINTER_LEAVE": "closing",
201
+ "CLOSE": [
202
+ {
203
+ guard: "isOpenControlled",
204
+ actions: ["invokeOnClose"]
205
+ },
206
+ {
207
+ target: "closed",
208
+ actions: ["invokeOnClose"]
209
+ }
210
+ ],
211
+ "TRIGGER_BLUR": [
212
+ {
213
+ guard: and("isOpenControlled", not("isPointer")),
214
+ actions: ["invokeOnClose"]
215
+ },
216
+ {
217
+ guard: not("isPointer"),
218
+ target: "closed",
219
+ actions: ["invokeOnClose"]
220
+ }
221
+ ],
222
+ "POSITIONING.SET": {
223
+ actions: "reposition"
224
+ }
225
+ }
226
+ },
227
+ closing: {
228
+ tags: ["open"],
229
+ activities: ["trackPositioning"],
230
+ after: {
231
+ CLOSE_DELAY: [
232
+ {
233
+ guard: "isOpenControlled",
234
+ actions: ["invokeOnClose"]
235
+ },
236
+ {
237
+ target: "closed",
238
+ actions: ["invokeOnClose"]
239
+ }
240
+ ]
241
+ },
242
+ on: {
243
+ "CONTROLLED.CLOSE": "closed",
244
+ "POINTER_ENTER": {
245
+ target: "open",
246
+ // no need to invokeOnOpen here because it's still open (but about to close)
247
+ actions: ["setIsPointer"]
248
+ }
249
+ }
250
+ }
251
+ }
252
+ },
253
+ {
254
+ guards: {
255
+ isPointer: (ctx2) => !!ctx2.isPointer,
256
+ isOpenControlled: (ctx2) => !!ctx2["open.controlled"]
257
+ },
258
+ activities: {
259
+ trackPositioning(ctx2) {
260
+ ctx2.currentPlacement = ctx2.positioning.placement;
261
+ const getPositionerEl = () => dom.getPositionerEl(ctx2);
262
+ return getPlacement(dom.getTriggerEl(ctx2), getPositionerEl, {
263
+ ...ctx2.positioning,
264
+ defer: true,
265
+ onComplete(data) {
266
+ ctx2.currentPlacement = data.placement;
267
+ }
268
+ });
269
+ },
270
+ trackDismissableElement(ctx2, _evt, { send }) {
271
+ const getContentEl = () => dom.getContentEl(ctx2);
272
+ return trackDismissableElement(getContentEl, {
273
+ defer: true,
274
+ exclude: [dom.getTriggerEl(ctx2)],
275
+ onDismiss() {
276
+ send({ type: "CLOSE", src: "interact-outside" });
277
+ },
278
+ onFocusOutside(event) {
279
+ event.preventDefault();
280
+ }
281
+ });
282
+ }
283
+ },
284
+ actions: {
285
+ invokeOnClose(ctx2) {
286
+ ctx2.onOpenChange?.({ open: false });
287
+ },
288
+ invokeOnOpen(ctx2) {
289
+ ctx2.onOpenChange?.({ open: true });
290
+ },
291
+ setIsPointer(ctx2) {
292
+ ctx2.isPointer = true;
293
+ },
294
+ clearIsPointer(ctx2) {
295
+ ctx2.isPointer = false;
296
+ },
297
+ reposition(ctx2, evt) {
298
+ const getPositionerEl = () => dom.getPositionerEl(ctx2);
299
+ getPlacement(dom.getTriggerEl(ctx2), getPositionerEl, {
300
+ ...ctx2.positioning,
301
+ ...evt.options,
302
+ defer: true,
303
+ listeners: false,
304
+ onComplete(data) {
305
+ ctx2.currentPlacement = data.placement;
306
+ }
307
+ });
308
+ },
309
+ toggleVisibility(ctx2, evt, { send }) {
310
+ send({ type: ctx2.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: evt });
311
+ }
312
+ },
313
+ delays: {
314
+ OPEN_DELAY: (ctx2) => ctx2.openDelay,
315
+ CLOSE_DELAY: (ctx2) => ctx2.closeDelay
316
+ }
317
+ }
318
+ );
319
+ }
320
+
321
+ const props = createProps()([
322
+ "closeDelay",
323
+ "dir",
324
+ "getRootNode",
325
+ "id",
326
+ "ids",
327
+ "onOpenChange",
328
+ "open.controlled",
329
+ "open",
330
+ "openDelay",
331
+ "positioning"
332
+ ]);
333
+ const splitProps = createSplitProps(props);
334
+
335
+ export { anatomy, connect, machine, props, splitProps };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@destyler/hover-card",
3
3
  "type": "module",
4
- "version": "0.0.6",
4
+ "version": "0.0.7-beta.1",
5
5
  "description": "for sighted users to preview content available behind a link.",
6
6
  "author": "Elone Hoo <elonehoo@gmail.com>",
7
7
  "license": "MIT",
@@ -10,14 +10,6 @@
10
10
  "types": "./dist/index.d.mts",
11
11
  "default": "./dist/index.mjs"
12
12
  },
13
- "./resolver": {
14
- "types": "./dist/resolver.d.mts",
15
- "default": "./dist/resolver.mjs"
16
- },
17
- "./component": {
18
- "types": "./dist/component.d.mts",
19
- "default": "./dist/component.mjs"
20
- },
21
13
  "./*": "./*"
22
14
  },
23
15
  "main": "dist/index.cjs",
@@ -27,20 +19,18 @@
27
19
  "*.d.ts",
28
20
  "dist"
29
21
  ],
30
- "peerDependencies": {
31
- "vue": ">=3.4.21"
32
- },
33
22
  "dependencies": {
34
- "@destyler/composition": "0.0.6",
35
- "@destyler/dismissable-layer": "0.0.6",
36
- "@destyler/popper": "0.0.6",
37
- "@destyler/presence": "0.0.6",
38
- "@destyler/primitive": "0.0.6",
39
- "@destyler/shared": "0.0.6",
40
- "@destyler/teleport": "0.0.6"
23
+ "@zag-js/anatomy": "^0.80.0",
24
+ "@zag-js/core": "^0.80.0",
25
+ "@zag-js/dismissable": "^0.80.0",
26
+ "@zag-js/dom-query": "^0.80.0",
27
+ "@zag-js/popper": "^0.80.0",
28
+ "@zag-js/types": "^0.80.0",
29
+ "@zag-js/utils": "^0.80.0"
41
30
  },
42
31
  "scripts": {
43
32
  "clear": "rimraf ./dist",
33
+ "clear:node_modules": "rimraf ./node_modules",
44
34
  "build": "pnpm run clear && unbuild",
45
35
  "stub": "unbuild --stub"
46
36
  }
package/README.md DELETED
@@ -1,7 +0,0 @@
1
- # @destyler/hover-card
2
-
3
- [![NPM version](https://img.shields.io/npm/v/@destyler/hover-card?color=a1b858&label=)](https://www.npmjs.com/package/@destyler/hover-card)
4
-
5
- > for sighted users to preview content available behind a link.
6
-
7
- [GitHub](https://github.com/destyler/destyler) | [Documentation](https://destyler-dev.zeabur.app/)