@vuetify/v0 1.0.5 → 1.2.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/README.md +8 -0
- package/dist/{adapter-Butx_2UU.d.mts → adapter-BXunW_mw.d.mts} +1 -1
- package/dist/{createPagination-B5dfqY-a.mjs → adapter-BiQV5j8B.mjs} +98 -3
- package/dist/adapter-ClB-53_F.d.mts +62 -0
- package/dist/{adapter-hq9YlPOF.d.mts → adapter-CqS8xexO.d.mts} +2 -2
- package/dist/adapter-CrRJuxRk.mjs +21 -0
- package/dist/{adapter-_srNCBEi.d.mts → adapter-PDTe5nFT.d.mts} +6 -7
- package/dist/{adapter-lS_VpRow.mjs → adapter-TiGrumDi.mjs} +3 -1
- package/dist/browser/index.d.ts +17953 -15766
- package/dist/browser/index.js +16633 -14006
- package/dist/components/index.d.mts +2 -2
- package/dist/components/index.mjs +2 -2
- package/dist/{components-OCsY4P1f.mjs → components-DBhVg-t1.mjs} +4253 -2247
- package/dist/composables/index.d.mts +22 -20
- package/dist/composables/index.mjs +37 -34
- package/dist/{composables-xhcxXjuE.mjs → composables-ZGhVN2EJ.mjs} +47 -1066
- package/dist/{consola-BPGkJp_q.d.mts → consola-CdMU53rU.d.mts} +1 -1
- package/dist/constants/index.d.mts +1 -1
- package/dist/constants/index.mjs +1 -1
- package/dist/{createDataTable-D38H0Zbp.mjs → createDataTable-VmQEDn-7.mjs} +23 -7
- package/dist/{createGroup-CjUHFae5.mjs → createGroup-B_LL7xRr.mjs} +2 -2
- package/dist/createPlugin-Oo6t-vBw.mjs +157 -0
- package/dist/{createRegistry-B8VqA-QF.mjs → createRegistry-DVdvep0v.mjs} +1 -1
- package/dist/{createSelection-BXd5clS0.mjs → createSelection-BNdDz8oY.mjs} +1 -1
- package/dist/{createSingle-Bdkfht_B.mjs → createSingle-DHyIQ9Cj.mjs} +1 -1
- package/dist/{createTokens-vgyk_0vA.mjs → createTokens-DoISbwd7.mjs} +2 -2
- package/dist/data-table/adapters/client/index.d.mts +1 -1
- package/dist/data-table/adapters/client/index.mjs +1 -1
- package/dist/data-table/adapters/index.d.mts +4 -4
- package/dist/data-table/adapters/index.mjs +4 -4
- package/dist/data-table/adapters/server/index.d.mts +1 -1
- package/dist/data-table/adapters/server/index.mjs +1 -1
- package/dist/data-table/adapters/virtual/index.d.mts +1 -1
- package/dist/data-table/adapters/virtual/index.mjs +1 -1
- package/dist/data-table/index.d.mts +5 -5
- package/dist/data-table/index.mjs +5 -5
- package/dist/date/index.d.mts +1 -1
- package/dist/date/index.mjs +2 -2
- package/dist/features/adapters/flagsmith/index.d.mts +1 -1
- package/dist/features/adapters/flagsmith/index.mjs +1 -1
- package/dist/features/adapters/launchdarkly/index.d.mts +1 -1
- package/dist/features/adapters/launchdarkly/index.mjs +1 -1
- package/dist/features/adapters/posthog/index.d.mts +1 -1
- package/dist/features/adapters/posthog/index.mjs +2 -2
- package/dist/features/index.d.mts +2 -2
- package/dist/features/index.mjs +2 -2
- package/dist/{flagsmith-DA2GCyGv.d.mts → flagsmith-DcIDrI7_.d.mts} +1 -1
- package/dist/{globals-B7ejLnrz.mjs → globals-DaoKtIGF.mjs} +1 -1
- package/dist/{index-DY81ptHb.d.mts → index-Cm6CbqI6.d.mts} +7494 -5834
- package/dist/{index-CrAgM2EJ.d.mts → index-Cx0cWGlx.d.mts} +493 -132
- package/dist/{index-QnpcDsV7.d.mts → index-D0ub61GV.d.mts} +2 -2
- package/dist/{index-RGiSdjYt.d.mts → index-DSPkZ0ql.d.mts} +2 -2
- package/dist/{index-DCtHbY0a.d.mts → index-Di9e8sOm.d.mts} +24 -19
- package/dist/{index-DF0tMI2_.d.mts → index-DjRE4lLl.d.mts} +108 -2
- package/dist/index.d.mts +25 -24
- package/dist/index.mjs +40 -37
- package/dist/json/attributes.json +488 -0
- package/dist/json/importMap.json +92 -0
- package/dist/json/tags.json +234 -0
- package/dist/json/web-types.json +1540 -113
- package/dist/{launchdarkly-Bp8p9PMD.d.mts → launchdarkly-CUzunYol.d.mts} +1 -1
- package/dist/locale/adapters/index.d.mts +2 -2
- package/dist/locale/adapters/index.mjs +2 -2
- package/dist/locale/adapters/v0/index.d.mts +1 -1
- package/dist/locale/adapters/v0/index.mjs +1 -1
- package/dist/locale/adapters/vue-i18n/index.d.mts +1 -1
- package/dist/locale/adapters/vue-i18n/index.mjs +1 -1
- package/dist/locale/index.d.mts +3 -3
- package/dist/locale/index.mjs +3 -3
- package/dist/locale/messages/en/index.d.mts +5 -0
- package/dist/locale/messages/en/index.mjs +6 -1
- package/dist/logger/adapters/consola/index.d.mts +1 -1
- package/dist/logger/adapters/index.d.mts +4 -4
- package/dist/logger/adapters/index.mjs +1 -1
- package/dist/logger/adapters/pino/index.d.mts +1 -1
- package/dist/logger/adapters/v0/index.d.mts +1 -1
- package/dist/logger/adapters/v0/index.mjs +1 -1
- package/dist/logger/index.d.mts +5 -5
- package/dist/logger/index.mjs +2 -2
- package/dist/notifications/index.d.mts +1 -1
- package/dist/notifications/index.mjs +2 -2
- package/dist/palettes/ant/index.d.mts +1 -1
- package/dist/palettes/index.d.mts +3 -3
- package/dist/palettes/material/index.d.mts +1 -1
- package/dist/palettes/md1/index.d.mts +1 -1
- package/dist/palettes/md2/index.d.mts +1 -1
- package/dist/palettes/radix/index.d.mts +1 -1
- package/dist/palettes/tailwind/index.d.mts +1 -1
- package/dist/permissions/adapters/index.d.mts +1 -1
- package/dist/permissions/adapters/index.mjs +1 -1
- package/dist/permissions/adapters/v0/index.d.mts +1 -1
- package/dist/permissions/adapters/v0/index.mjs +1 -1
- package/dist/permissions/index.d.mts +1 -1
- package/dist/permissions/index.mjs +2 -2
- package/dist/{pino-B6BI1AOK.d.mts → pino-DjeWBFnj.d.mts} +1 -1
- package/dist/popover/adapters/floating-ui/index.d.mts +25 -0
- package/dist/popover/adapters/floating-ui/index.mjs +98 -0
- package/dist/popover/index.d.mts +3 -0
- package/dist/popover/index.mjs +3 -0
- package/dist/{posthog-sFqk0bGy.d.mts → posthog-CJAYssdr.d.mts} +1 -1
- package/dist/rules/index.d.mts +1 -1
- package/dist/rules/index.mjs +1 -1
- package/dist/{server-DbtTGb67.d.mts → server-5vbJ7GGs.d.mts} +2 -2
- package/dist/{server-D5BJBjB0.mjs → server-m7iD1vOr.mjs} +1 -2
- package/dist/storage/adapters/index.d.mts +2 -2
- package/dist/storage/adapters/index.mjs +1 -1
- package/dist/storage/adapters/memory/index.d.mts +1 -1
- package/dist/storage/adapters/memory/index.mjs +1 -1
- package/dist/storage/index.d.mts +3 -3
- package/dist/storage/index.mjs +2 -2
- package/dist/theme/adapters/index.d.mts +1 -1
- package/dist/theme/adapters/index.mjs +3 -3
- package/dist/theme/adapters/unhead/index.d.mts +1 -1
- package/dist/theme/adapters/unhead/index.mjs +1 -1
- package/dist/theme/adapters/v0/index.d.mts +1 -1
- package/dist/theme/adapters/v0/index.mjs +1 -1
- package/dist/theme/index.d.mts +2 -2
- package/dist/theme/index.mjs +4 -4
- package/dist/types/index.d.mts +1 -1
- package/dist/{unhead-DxiB3P5p.mjs → unhead-C8zbWr45.mjs} +2 -2
- package/dist/{useEventListener-BjWJPfYS.mjs → useEventListener-2eAMwUdw.mjs} +2 -2
- package/dist/useFeatures-DLafCOWt.mjs +221 -0
- package/dist/{useLocale-B2BAEieU.mjs → useLocale-K_45ulPt.mjs} +4 -4
- package/dist/{useLogger-CXKIZhks.mjs → useLogger-YyWuYvrH.mjs} +5 -159
- package/dist/{useNotifications-Czgbh8Ns.mjs → useNotifications-Kh_KvM7j.mjs} +57 -154
- package/dist/{usePermissions-BkndJNpk.mjs → usePermissions-BCGwsOES.mjs} +4 -4
- package/dist/usePopover-BTo0AGIQ.mjs +420 -0
- package/dist/{useRovingFocus-Cn96TXRw.mjs → useRovingFocus-CkRnVmJ1.mjs} +1122 -531
- package/dist/{useRules-NzJChxfk.mjs → useRules-BuE5ffOJ.mjs} +3 -2
- package/dist/{useStorage-D6xihSHv.mjs → useStorage-BT8-mjVs.mjs} +5 -4
- package/dist/useTheme-DkK6tPqY.mjs +445 -0
- package/dist/useTimer-CGVXk397.mjs +151 -0
- package/dist/utilities/index.d.mts +2 -2
- package/dist/utilities/index.mjs +181 -2
- package/dist/{v0-BFMaRqAx.mjs → v0-B_53w7Fu.mjs} +2 -2
- package/dist/{v0-BnUwMaOv.d.mts → v0-CDW1Ktk-.d.mts} +1 -1
- package/dist/{v0-gU93DxmF.mjs → v0-D0Exc2bO.mjs} +2 -2
- package/dist/{v0-rSxMW8FJ.d.mts → v0-DfFK-p4X.d.mts} +1 -1
- package/dist/{v0-DotXXGXU.d.mts → v0-GI9U-rPA.d.mts} +2 -2
- package/dist/{v0-eZcJPyii.mjs → v0-SuxTihEe.mjs} +1 -1
- package/dist/{v0-A4GLojAr.mjs → v0-yZ2ZUtVF.mjs} +1 -2
- package/dist/{virtual-DFvOoeG6.mjs → virtual-Bbu26O_h.mjs} +1 -2
- package/dist/{virtual-C-NsLue0.d.mts → virtual-JIdFLpTQ.d.mts} +2 -2
- package/package.json +8 -1
- package/dist/adapter-CVoWg0sw.mjs +0 -99
- package/dist/useFeatures-DcgU66KC.mjs +0 -124
- package/dist/useTheme-BuXEQdPz.mjs +0 -162
- /package/dist/{adapter-CTsckKAR.mjs → adapter-8UADsA3-.mjs} +0 -0
- /package/dist/{adapter-BCtceV3b.mjs → adapter-BuSfpxur.mjs} +0 -0
- /package/dist/{adapter-Bc0yPSfo.d.mts → adapter-D5nT3bLw.d.mts} +0 -0
- /package/dist/{adapter-bwZo7b5p.mjs → adapter-D8zizQVP.mjs} +0 -0
- /package/dist/{adapter-BYzU4Ey5.d.mts → adapter-ryk5H6YZ.d.mts} +0 -0
- /package/dist/{index-CROz1VSV.d.mts → index-CX869wwk.d.mts} +0 -0
- /package/dist/{index-FtE8MXJ_.d.mts → index-CsuikFeJ.d.mts} +0 -0
- /package/dist/{index-DidZKN6S.d.mts → index-Djhiy3nS.d.mts} +0 -0
- /package/dist/{index-CyNk9FpR.d.mts → index-DtiaWx5U.d.mts} +0 -0
- /package/dist/{index-DXMlYoiQ.d.mts → index-H_hl6-4b.d.mts} +0 -0
- /package/dist/{index-BgCkepP_.d.mts → index-u_qSc2xS.d.mts} +0 -0
- /package/dist/{memory-DbyZeNjg.d.mts → memory-B7z1RR9r.d.mts} +0 -0
- /package/dist/{memory-BJjkQzxs.mjs → memory-CR6zvuaP.mjs} +0 -0
- /package/dist/{toArray-C89ZaEuF.mjs → toArray-MY9Kb1Qy.mjs} +0 -0
- /package/dist/{v0-UNyykD27.mjs → v0-Ch0yBKEj.mjs} +0 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { t as IN_BROWSER } from "./globals-DaoKtIGF.mjs";
|
|
2
|
+
import { isNullOrUndefined, useId as useId$1 } from "./utilities/index.mjs";
|
|
3
|
+
import { n as createPluginContext } from "./createPlugin-Oo6t-vBw.mjs";
|
|
4
|
+
import { n as useEventListener } from "./useEventListener-2eAMwUdw.mjs";
|
|
5
|
+
import { t as useTimer } from "./useTimer-CGVXk397.mjs";
|
|
6
|
+
import { t as PopoverAdapter } from "./adapter-CrRJuxRk.mjs";
|
|
7
|
+
import { computed, onScopeDispose, shallowReadonly, shallowRef, toRef, toValue, watch } from "vue";
|
|
8
|
+
//#region src/composables/useDelay/index.ts
|
|
9
|
+
/**
|
|
10
|
+
* @module useDelay
|
|
11
|
+
*
|
|
12
|
+
* @see https://0.vuetifyjs.com/composables/system/use-delay
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* Schedule open and close transitions with configurable delays.
|
|
16
|
+
*
|
|
17
|
+
* Composes `useTimer` for the underlying lifecycle (start / stop / pause / resume,
|
|
18
|
+
* plus reactive `isActive`, `isPaused`, `remaining`) and adds direction tracking
|
|
19
|
+
* (`isOpening`) and promise-based resolution.
|
|
20
|
+
*
|
|
21
|
+
* Key features:
|
|
22
|
+
* - Reactive `openDelay` and `closeDelay` via `MaybeRefOrGetter`
|
|
23
|
+
* - `start(isOpening)` returns a `Promise<boolean>` that resolves once the delay elapses
|
|
24
|
+
* - Per-call `minDelay` floor enforces a minimum delay
|
|
25
|
+
* - Automatic cleanup on scope disposal (timer cleared, pending promise settled with current direction)
|
|
26
|
+
* - SSR-safe
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import { useDelay } from '@vuetify/v0'
|
|
31
|
+
*
|
|
32
|
+
* const delay = useDelay(isOpening => isVisible.value = isOpening, {
|
|
33
|
+
* openDelay: 300,
|
|
34
|
+
* closeDelay: 200,
|
|
35
|
+
* })
|
|
36
|
+
*
|
|
37
|
+
* delay.start(true)
|
|
38
|
+
* delay.start(false, { minDelay: 500 })
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Schedule open and close transitions with configurable delays.
|
|
43
|
+
*
|
|
44
|
+
* Composes `useTimer` for the lifecycle (`start` / `stop` / `pause` / `resume` plus
|
|
45
|
+
* reactive `isActive`, `isPaused`, `remaining`) and adds direction tracking
|
|
46
|
+
* (`isOpening`) and promise-based resolution.
|
|
47
|
+
*
|
|
48
|
+
* @param callback Optional callback invoked once a started delay elapses; receives the resolved direction.
|
|
49
|
+
* @param options Reactive delay settings.
|
|
50
|
+
* @returns Lifecycle controls and reactive state.
|
|
51
|
+
*
|
|
52
|
+
* @see https://0.vuetifyjs.com/composables/system/use-delay
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* const delay = useDelay(isOpening => isVisible.value = isOpening, {
|
|
57
|
+
* openDelay: 300,
|
|
58
|
+
* closeDelay: 200,
|
|
59
|
+
* })
|
|
60
|
+
*
|
|
61
|
+
* delay.start(true)
|
|
62
|
+
* delay.start(false, { minDelay: 500 })
|
|
63
|
+
* delay.pause()
|
|
64
|
+
* delay.resume()
|
|
65
|
+
* delay.stop()
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
function useDelay(callback, options = {}) {
|
|
69
|
+
const { openDelay, closeDelay } = options;
|
|
70
|
+
const isOpening = shallowRef(false);
|
|
71
|
+
let minDelay = 0;
|
|
72
|
+
let resolver;
|
|
73
|
+
function fire() {
|
|
74
|
+
const direction = isOpening.value;
|
|
75
|
+
const resolve = resolver;
|
|
76
|
+
resolver = void 0;
|
|
77
|
+
resolve?.(direction);
|
|
78
|
+
callback?.(direction);
|
|
79
|
+
}
|
|
80
|
+
function duration() {
|
|
81
|
+
const raw = isOpening.value ? toValue(openDelay) : toValue(closeDelay);
|
|
82
|
+
return Math.max(minDelay, raw ?? 0);
|
|
83
|
+
}
|
|
84
|
+
const timer = useTimer(fire, { duration });
|
|
85
|
+
function start(direction, options = {}) {
|
|
86
|
+
const previous = resolver;
|
|
87
|
+
resolver = void 0;
|
|
88
|
+
isOpening.value = direction;
|
|
89
|
+
minDelay = options.minDelay ?? 0;
|
|
90
|
+
previous?.(direction);
|
|
91
|
+
const ms = duration();
|
|
92
|
+
return new Promise((resolve) => {
|
|
93
|
+
resolver = resolve;
|
|
94
|
+
if (ms <= 0) {
|
|
95
|
+
timer.stop();
|
|
96
|
+
fire();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
timer.start();
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function stop() {
|
|
103
|
+
const resolve = resolver;
|
|
104
|
+
resolver = void 0;
|
|
105
|
+
timer.stop();
|
|
106
|
+
resolve?.(isOpening.value);
|
|
107
|
+
}
|
|
108
|
+
onScopeDispose(() => {
|
|
109
|
+
const resolve = resolver;
|
|
110
|
+
resolver = void 0;
|
|
111
|
+
resolve?.(isOpening.value);
|
|
112
|
+
}, true);
|
|
113
|
+
return {
|
|
114
|
+
start,
|
|
115
|
+
stop,
|
|
116
|
+
pause: timer.pause,
|
|
117
|
+
resume: timer.resume,
|
|
118
|
+
isActive: shallowReadonly(timer.isActive),
|
|
119
|
+
isPaused: shallowReadonly(timer.isPaused),
|
|
120
|
+
remaining: shallowReadonly(timer.remaining),
|
|
121
|
+
isOpening: shallowReadonly(isOpening)
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/composables/usePopover/adapters/v0.ts
|
|
126
|
+
/**
|
|
127
|
+
* Default positioning adapter. Emits CSS anchor positioning
|
|
128
|
+
* (`position-area` / `position-try-fallbacks`) - no JS measurement, no
|
|
129
|
+
* runtime dependency, works with the native popover API's own layout.
|
|
130
|
+
*/
|
|
131
|
+
var V0PopoverAdapter = class extends PopoverAdapter {
|
|
132
|
+
setup(context) {
|
|
133
|
+
return toRef(() => ({
|
|
134
|
+
"position": "fixed",
|
|
135
|
+
"margin": "unset",
|
|
136
|
+
"inset-area": context.placement.value.raw,
|
|
137
|
+
"position-area": context.placement.value.raw,
|
|
138
|
+
"position-anchor": context.anchorName,
|
|
139
|
+
"position-try-fallbacks": context.positionTry.value
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/composables/usePopover/adapters/placement.ts
|
|
145
|
+
const SIDE_KEYWORDS = {
|
|
146
|
+
"top": "top",
|
|
147
|
+
"bottom": "bottom",
|
|
148
|
+
"left": "left",
|
|
149
|
+
"right": "right",
|
|
150
|
+
"block-start": "top",
|
|
151
|
+
"block-end": "bottom",
|
|
152
|
+
"inline-start": "left",
|
|
153
|
+
"inline-end": "right"
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Best-effort normalization of a CSS `position-area` value into an
|
|
157
|
+
* engine-neutral `{ side, align }` descriptor. Covers the common single- and
|
|
158
|
+
* two-token forms (`'bottom'`, `'top span-left'`, `'bottom span-right'`,
|
|
159
|
+
* logical `block-start`/`block-end`/`inline-start`/`inline-end`); anything
|
|
160
|
+
* else falls back to `bottom`/`center`. `raw` always carries the original
|
|
161
|
+
* value verbatim, so no expressiveness is lost even when the normalization
|
|
162
|
+
* doesn't recognize it.
|
|
163
|
+
*/
|
|
164
|
+
function toPlacement(positionArea) {
|
|
165
|
+
const tokens = positionArea.trim().split(/\s+/);
|
|
166
|
+
const side = SIDE_KEYWORDS[tokens[0] ?? "bottom"] ?? "bottom";
|
|
167
|
+
let align = "center";
|
|
168
|
+
const second = tokens[1];
|
|
169
|
+
if (second === "span-left" || second === "span-start" || second === "left") align = "start";
|
|
170
|
+
else if (second === "span-right" || second === "span-end" || second === "right") align = "end";
|
|
171
|
+
return {
|
|
172
|
+
side,
|
|
173
|
+
align,
|
|
174
|
+
raw: positionArea
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region src/composables/usePopover/index.ts
|
|
179
|
+
/**
|
|
180
|
+
* @module usePopover
|
|
181
|
+
*
|
|
182
|
+
* @see https://0.vuetifyjs.com/composables/system/use-popover
|
|
183
|
+
*
|
|
184
|
+
* @remarks
|
|
185
|
+
* Composable for native popover API behavior with CSS anchor positioning.
|
|
186
|
+
* Manages open/close state, anchor styles, content attributes, bidirectional
|
|
187
|
+
* sync between reactive state and native popover events, and configurable
|
|
188
|
+
* open / close delays via `useDelay`.
|
|
189
|
+
*
|
|
190
|
+
* Key features:
|
|
191
|
+
* - Native popover API (showPopover/hidePopover)
|
|
192
|
+
* - CSS anchor positioning (position-area, position-try-fallbacks) by default,
|
|
193
|
+
* via a pluggable `PopoverAdapter` seam for JS positioning engines
|
|
194
|
+
* - Reactive open/close delays via `useDelay`
|
|
195
|
+
* - Toggle event sync for native state changes
|
|
196
|
+
* - SSR-safe (no DOM ops outside browser)
|
|
197
|
+
* - Optional external isOpen ref for v-model integration
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```ts
|
|
201
|
+
* import { usePopover } from '@vuetify/v0'
|
|
202
|
+
*
|
|
203
|
+
* const popover = usePopover({ openDelay: 200, closeDelay: 100 })
|
|
204
|
+
* popover.open()
|
|
205
|
+
* popover.toggle()
|
|
206
|
+
* ```
|
|
207
|
+
*
|
|
208
|
+
* @example Bring your own positioning engine
|
|
209
|
+
* ```ts
|
|
210
|
+
* import { PopoverAdapter, usePopover } from '@vuetify/v0'
|
|
211
|
+
*
|
|
212
|
+
* class MyAdapter extends PopoverAdapter {
|
|
213
|
+
* setup (context) {
|
|
214
|
+
* // read context.anchorEl / context.contentEl / context.isOpen /
|
|
215
|
+
* // context.placement, return a Ref<Record<string, string>> of styles
|
|
216
|
+
* }
|
|
217
|
+
* }
|
|
218
|
+
*
|
|
219
|
+
* const popover = usePopover({ adapter: new MyAdapter() })
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* @example App-wide adapter via createPopoverPlugin
|
|
223
|
+
* ```ts
|
|
224
|
+
* import { createPopoverPlugin } from '@vuetify/v0'
|
|
225
|
+
* import { FloatingUIPopoverAdapter } from '@vuetify/v0/popover/adapters/floating-ui'
|
|
226
|
+
*
|
|
227
|
+
* app.use(createPopoverPlugin({ adapter: new FloatingUIPopoverAdapter() }))
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
function createPopover(options = {}) {
|
|
231
|
+
return { adapter: options.adapter };
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Synthesized fallback used when `usePopover()` is called without
|
|
235
|
+
* `app.use(createPopoverPlugin())`. Returns `{ adapter: undefined }` so
|
|
236
|
+
* resolution falls through to `V0PopoverAdapter`.
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```ts
|
|
240
|
+
* import { createPopoverFallback } from '@vuetify/v0'
|
|
241
|
+
*
|
|
242
|
+
* const plugin = createPopoverFallback()
|
|
243
|
+
* plugin.adapter // undefined
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
function createPopoverFallback() {
|
|
247
|
+
return { adapter: void 0 };
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Creates a scoped popover plugin context (the first member of the plugin trinity).
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```ts
|
|
254
|
+
* import { createPopoverContext } from '@vuetify/v0'
|
|
255
|
+
* import { FloatingUIPopoverAdapter } from '@vuetify/v0/popover/adapters/floating-ui'
|
|
256
|
+
*
|
|
257
|
+
* export const [useAppPopover, provideAppPopover, appPopover] = createPopoverContext({
|
|
258
|
+
* namespace: 'app:popover-plugin',
|
|
259
|
+
* adapter: new FloatingUIPopoverAdapter(),
|
|
260
|
+
* })
|
|
261
|
+
* ```
|
|
262
|
+
*
|
|
263
|
+
* Plugin trinity for an app-wide popover positioning adapter.
|
|
264
|
+
*
|
|
265
|
+
* Namespace is `v0:popover-plugin` — not `v0:popover`, which `Popover.Root`
|
|
266
|
+
* already owns for compound context. The generated consumer is module-private;
|
|
267
|
+
* `usePopover()` consults it internally. Fallback is `{ adapter: undefined }`,
|
|
268
|
+
* so zero-config matches today's `V0PopoverAdapter` default.
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```ts
|
|
272
|
+
* import { createPopoverPlugin } from '@vuetify/v0'
|
|
273
|
+
* import { FloatingUIPopoverAdapter } from '@vuetify/v0/popover/adapters/floating-ui'
|
|
274
|
+
*
|
|
275
|
+
* app.use(createPopoverPlugin({ adapter: new FloatingUIPopoverAdapter() }))
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
278
|
+
const [createPopoverContext, createPopoverPlugin, usePopoverPlugin] = createPluginContext("v0:popover-plugin", createPopover, { fallback: () => createPopoverFallback() });
|
|
279
|
+
function bindOption(source, fallback) {
|
|
280
|
+
const override = shallowRef();
|
|
281
|
+
return computed({
|
|
282
|
+
get: () => override.value ?? toValue(source) ?? fallback,
|
|
283
|
+
set: (value) => {
|
|
284
|
+
override.value = value;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
function usePopover(options = {}) {
|
|
289
|
+
const plugin = usePopoverPlugin();
|
|
290
|
+
const { id: _id, openDelay, closeDelay } = options;
|
|
291
|
+
const adapter = options.adapter ?? plugin.adapter ?? new V0PopoverAdapter();
|
|
292
|
+
const id = _id ?? /* @__PURE__ */ useId$1();
|
|
293
|
+
const anchor = `--${String(id).replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
294
|
+
const isOpen = options.isOpen ?? shallowRef(false);
|
|
295
|
+
const positionArea = bindOption(options.positionArea, "bottom");
|
|
296
|
+
const positionTry = bindOption(options.positionTry, "most-width bottom");
|
|
297
|
+
const delay = useDelay((direction) => {
|
|
298
|
+
isOpen.value = direction;
|
|
299
|
+
}, {
|
|
300
|
+
openDelay,
|
|
301
|
+
closeDelay
|
|
302
|
+
});
|
|
303
|
+
function open() {
|
|
304
|
+
delay.start(true);
|
|
305
|
+
}
|
|
306
|
+
function close() {
|
|
307
|
+
delay.start(false);
|
|
308
|
+
}
|
|
309
|
+
function toggle() {
|
|
310
|
+
if (isOpen.value) close();
|
|
311
|
+
else open();
|
|
312
|
+
}
|
|
313
|
+
function cancel() {
|
|
314
|
+
delay.stop();
|
|
315
|
+
}
|
|
316
|
+
const anchorStyles = toRef(() => ({ anchorName: anchor }));
|
|
317
|
+
const contentAttrs = toRef(() => ({
|
|
318
|
+
id,
|
|
319
|
+
popover: ""
|
|
320
|
+
}));
|
|
321
|
+
const anchorEl = shallowRef();
|
|
322
|
+
const contentEl = shallowRef();
|
|
323
|
+
const placement = toRef(() => toPlacement(positionArea.value));
|
|
324
|
+
const contentStyles = adapter.setup({
|
|
325
|
+
anchorName: anchor,
|
|
326
|
+
anchorEl,
|
|
327
|
+
contentEl,
|
|
328
|
+
isOpen,
|
|
329
|
+
placement,
|
|
330
|
+
positionTry
|
|
331
|
+
});
|
|
332
|
+
onScopeDispose(() => adapter.dispose?.(), true);
|
|
333
|
+
let stopAnchor;
|
|
334
|
+
let stopContent;
|
|
335
|
+
function attachAnchor(el) {
|
|
336
|
+
stopAnchor?.();
|
|
337
|
+
const handle = watch(() => toValue(el), (value) => {
|
|
338
|
+
anchorEl.value = value;
|
|
339
|
+
}, { immediate: true });
|
|
340
|
+
function stop() {
|
|
341
|
+
handle();
|
|
342
|
+
if (stopAnchor !== stop) return;
|
|
343
|
+
stopAnchor = void 0;
|
|
344
|
+
anchorEl.value = null;
|
|
345
|
+
}
|
|
346
|
+
stopAnchor = stop;
|
|
347
|
+
onScopeDispose(stop, true);
|
|
348
|
+
}
|
|
349
|
+
function attach(el) {
|
|
350
|
+
stopContent?.();
|
|
351
|
+
const handle = watch(() => toValue(el), (value) => {
|
|
352
|
+
contentEl.value = value;
|
|
353
|
+
}, { immediate: true });
|
|
354
|
+
const events = attachContentEvents(el);
|
|
355
|
+
function stop() {
|
|
356
|
+
handle();
|
|
357
|
+
events();
|
|
358
|
+
if (stopContent !== stop) return;
|
|
359
|
+
stopContent = void 0;
|
|
360
|
+
contentEl.value = null;
|
|
361
|
+
}
|
|
362
|
+
stopContent = stop;
|
|
363
|
+
onScopeDispose(stop, true);
|
|
364
|
+
}
|
|
365
|
+
function attachContentEvents(el) {
|
|
366
|
+
let current;
|
|
367
|
+
function hide(element) {
|
|
368
|
+
if (!IN_BROWSER || /* @__PURE__ */ isNullOrUndefined(element)) return;
|
|
369
|
+
try {
|
|
370
|
+
if (element.matches?.(":popover-open") === false) return;
|
|
371
|
+
element.hidePopover?.();
|
|
372
|
+
} catch {}
|
|
373
|
+
}
|
|
374
|
+
function sync() {
|
|
375
|
+
if (!IN_BROWSER) return;
|
|
376
|
+
const element = toValue(el);
|
|
377
|
+
if (!/* @__PURE__ */ isNullOrUndefined(current) && current !== element) hide(current);
|
|
378
|
+
current = /* @__PURE__ */ isNullOrUndefined(element) ? void 0 : element;
|
|
379
|
+
if (/* @__PURE__ */ isNullOrUndefined(element)) return;
|
|
380
|
+
if (!isOpen.value) {
|
|
381
|
+
hide(element);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (!element.isConnected) return;
|
|
385
|
+
if (element.matches?.(":popover-open")) return;
|
|
386
|
+
element.showPopover?.();
|
|
387
|
+
}
|
|
388
|
+
const handle = watch([isOpen, () => toValue(el)], sync, {
|
|
389
|
+
immediate: true,
|
|
390
|
+
flush: "post"
|
|
391
|
+
});
|
|
392
|
+
const listener = useEventListener(el, "toggle", (e) => {
|
|
393
|
+
if (!toValue(el)?.isConnected) return;
|
|
394
|
+
isOpen.value = e.newState === "open";
|
|
395
|
+
});
|
|
396
|
+
function stop() {
|
|
397
|
+
handle();
|
|
398
|
+
listener();
|
|
399
|
+
hide(toValue(el) ?? current);
|
|
400
|
+
}
|
|
401
|
+
return stop;
|
|
402
|
+
}
|
|
403
|
+
return {
|
|
404
|
+
isOpen,
|
|
405
|
+
id,
|
|
406
|
+
open,
|
|
407
|
+
close,
|
|
408
|
+
toggle,
|
|
409
|
+
cancel,
|
|
410
|
+
anchorStyles,
|
|
411
|
+
contentAttrs,
|
|
412
|
+
contentStyles,
|
|
413
|
+
positionArea,
|
|
414
|
+
positionTry,
|
|
415
|
+
attach,
|
|
416
|
+
attachAnchor
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
//#endregion
|
|
420
|
+
export { toPlacement as a, usePopover as i, createPopoverFallback as n, V0PopoverAdapter as o, createPopoverPlugin as r, useDelay as s, createPopoverContext as t };
|