@vuetify/v0 0.0.18 → 0.0.20

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,25 +1,10 @@
1
- import { a as isBoolean, c as isNull, d as isObject, g as mergeDeep, h as isUndefined, l as isNullOrUndefined, o as isFunction, p as isString, r as genId, t as clamp, u as isNumber } from "./utilities-JxCe-nF2.mjs";
2
- import { C as useResizeObserver, J as createTrinity, O as useHydration, P as toArray, Y as createContext, Z as useContext, k as createGroup, p as createSingle, q as createPlugin, u as createTokens, z as useRegistry } from "./useStep-DC_JvZpy.mjs";
3
- import { i as SUPPORTS_MUTATION_OBSERVER, n as SUPPORTS_INTERSECTION_OBSERVER, t as IN_BROWSER } from "./globals-BGVqrlN7.mjs";
4
- import { computed, effectScope, isRef, onScopeDispose, reactive, readonly, ref, shallowReadonly, shallowRef, toRef, toValue, unref, watch } from "vue";
1
+ import { a as isBoolean, c as isNull, d as isObject, g as mergeDeep, h as isUndefined, l as isNullOrUndefined, o as isFunction, p as isString, r as genId, t as clamp, u as isNumber } from "./utilities-BrFKLHFS.mjs";
2
+ import { J as createTrinity, P as toArray, S as createTokens, T as createSingle, Y as createContext, Z as useContext, d as useResizeObserver, g as useHydration, k as createGroup, q as createPlugin, z as useRegistry } from "./useStep-Dw7XloDM.mjs";
3
+ import { i as SUPPORTS_MUTATION_OBSERVER, n as SUPPORTS_INTERSECTION_OBSERVER, t as IN_BROWSER } from "./globals-exvZ8fiO.mjs";
4
+ import { computed, effectScope, isRef, onScopeDispose, reactive, readonly, ref, shallowReadonly, shallowRef, toRef, toValue, unref, watch, watchEffect } from "vue";
5
5
 
6
6
  //#region src/composables/toReactive/index.ts
7
7
  /**
8
- * @module toReactive
9
- *
10
- * @remarks
11
- * Utility function to convert values and refs into reactive proxies with ref unwrapping.
12
- *
13
- * Key features:
14
- * - Automatic ref unwrapping
15
- * - Deep reactive proxying
16
- * - Map and Set support with ref unwrapping
17
- * - Nested object/array reactivity
18
- * - Type preservation
19
- *
20
- * Perfect for creating reactive versions of plain objects while automatically unwrapping refs.
21
- */
22
- /**
23
8
  * Converts a `MaybeRef` to a `UnwrapNestedRefs`.
24
9
  *
25
10
  * @param objectRef The object to convert.
@@ -140,21 +125,6 @@ function toReactive(objectRef) {
140
125
  //#endregion
141
126
  //#region src/composables/useEventListener/index.ts
142
127
  /**
143
- * @module useEventListener
144
- *
145
- * @remarks
146
- * Event listener composable with automatic cleanup on scope disposal.
147
- *
148
- * Key features:
149
- * - Supports Window, Document, and HTMLElement targets
150
- * - Reactive targets, events, and listeners
151
- * - Event options support (capture, passive, once)
152
- * - Automatic removeEventListener on unmount
153
- * - Multiple overloads for type safety
154
- *
155
- * Perfect for safely managing event listeners in Vue components.
156
- */
157
- /**
158
128
  * Attaches an event listener to a target.
159
129
  *
160
130
  * @param target The target to attach the event listener to.
@@ -209,7 +179,7 @@ function useEventListener(target, event, listener, options) {
209
179
  * @see https://0.vuetifyjs.com/composables/system/use-event-listener
210
180
  */
211
181
  function useWindowEventListener(event, listener, options) {
212
- return useEventListener(window, event, listener, options);
182
+ return IN_BROWSER ? useEventListener(window, event, listener, options) : () => {};
213
183
  }
214
184
  /**
215
185
  * Attaches an event listener to the document.
@@ -223,30 +193,12 @@ function useWindowEventListener(event, listener, options) {
223
193
  * @see https://0.vuetifyjs.com/composables/system/use-event-listener
224
194
  */
225
195
  function useDocumentEventListener(event, listener, options) {
226
- return useEventListener(document, event, listener, options);
196
+ return IN_BROWSER ? useEventListener(document, event, listener, options) : () => {};
227
197
  }
228
198
 
229
199
  //#endregion
230
200
  //#region src/composables/useBreakpoints/index.ts
231
201
  /**
232
- * @module useBreakpoints
233
- *
234
- * @see https://0.vuetifyjs.com/composables/plugins/use-breakpoints
235
- *
236
- * @remarks
237
- * Responsive breakpoint detection composable with window resize handling.
238
- *
239
- * Key features:
240
- * - Window matchMedia integration
241
- * - Six built-in breakpoints (xs, sm, md, lg, xl, xxl)
242
- * - Automatic resize listener with cleanup
243
- * - SSR-safe (checks IN_BROWSER)
244
- * - Hydration-aware
245
- * - Custom breakpoint configuration
246
- *
247
- * Perfect for responsive layouts and conditional rendering based on screen size.
248
- */
249
- /**
250
202
  * Creates default breakpoint configuration.
251
203
  *
252
204
  * @returns The default breakpoint configuration object.
@@ -492,25 +444,217 @@ function useBreakpoints(namespace = "v0:breakpoints") {
492
444
  }
493
445
 
494
446
  //#endregion
495
- //#region src/composables/useFeatures/index.ts
447
+ //#region src/composables/useClickOutside/index.ts
496
448
  /**
497
- * @module useFeatures
449
+ * Detects clicks outside of the specified element(s).
498
450
  *
499
- * @see https://0.vuetifyjs.com/composables/plugins/use-features
451
+ * Uses two-phase detection (pointerdown → pointerup) to prevent false positives
452
+ * when users drag from inside to outside an element.
453
+ *
454
+ * @param target Element ref(s) to detect clicks outside of. Accepts a single ref/getter or array of refs/getters.
455
+ * @param handler Callback invoked when a click outside is detected.
456
+ * @param options Configuration options.
457
+ * @returns An object with methods to control the listener.
500
458
  *
501
- * @remarks
502
- * Feature flag system with boolean and token-based features.
459
+ * @see https://0.vuetifyjs.com/composables/system/use-click-outside
503
460
  *
504
- * Key features:
505
- * - Boolean features (true/false activation)
506
- * - Token features with $variation support
507
- * - Auto-selection of enabled features
508
- * - Multi-select support for feature combinations
509
- * - Perfect for A/B testing, progressive rollout, feature toggles
461
+ * @example Native element ref
462
+ * ```ts
463
+ * const menuRef = useTemplateRef<HTMLElement>('menu')
464
+ *
465
+ * useClickOutside(menuRef, () => { isOpen.value = false })
466
+ * ```
510
467
  *
511
- * Inheritance chain: useRegistry createSelection → createGroup → createFeatures
512
- * Integrates with useTokens for token-based features.
468
+ * @example Component ref (e.g., Atom)
469
+ * ```ts
470
+ * const atomRef = useTemplateRef<AtomExpose>('atom')
471
+ *
472
+ * // Pass the exposed element TemplateRef via getter
473
+ * useClickOutside(
474
+ * () => atomRef.value?.element,
475
+ * () => { isOpen.value = false }
476
+ * )
477
+ * ```
478
+ *
479
+ * @example Multiple targets
480
+ * ```ts
481
+ * const popoverRef = useTemplateRef<AtomExpose>('popover')
482
+ * const anchorRef = useTemplateRef<HTMLElement>('anchor')
483
+ *
484
+ * useClickOutside(
485
+ * [() => popoverRef.value?.element, anchorRef],
486
+ * () => { isOpen.value = false }
487
+ * )
488
+ * ```
489
+ *
490
+ * @example Ignoring elements (CSS selectors or refs)
491
+ * ```ts
492
+ * useClickOutside(
493
+ * () => navRef.value?.element,
494
+ * () => { isOpen.value = false },
495
+ * { ignore: ['[data-app-bar]'] }
496
+ * )
497
+ * ```
513
498
  */
499
+ function useClickOutside(target, handler, options = {}) {
500
+ const { capture = true, touchScrollThreshold = 30, detectIframe = false, ignore = [] } = options;
501
+ const isPaused = shallowRef(false);
502
+ const isActive = toRef(() => !isPaused.value);
503
+ let initialTarget = null;
504
+ let startPosition = {
505
+ x: 0,
506
+ y: 0
507
+ };
508
+ let cleanupPointerDown;
509
+ let cleanupPointerUp;
510
+ let cleanupBlur;
511
+ /**
512
+ * Resolve target(s) to an array of HTMLElements.
513
+ */
514
+ function getTargets() {
515
+ return (Array.isArray(target) ? target : [target]).map((source) => toValue(source)).filter((el) => !/* @__PURE__ */ isNullOrUndefined(el));
516
+ }
517
+ /**
518
+ * Resolve ignore targets to a tuple of [selectors, elements].
519
+ * Called once per event to avoid repeated toValue() calls in hot path.
520
+ */
521
+ function resolveIgnoreTargets() {
522
+ const ignoreTargets = toValue(ignore);
523
+ if (ignoreTargets.length === 0) return [[], []];
524
+ const selectors = [];
525
+ const elements = [];
526
+ for (const ignoreTarget of ignoreTargets) if (/* @__PURE__ */ isString(ignoreTarget)) selectors.push(ignoreTarget);
527
+ else {
528
+ const ignoreEl = toValue(ignoreTarget);
529
+ if (ignoreEl) elements.push(ignoreEl);
530
+ }
531
+ return [selectors, elements];
532
+ }
533
+ /**
534
+ * Check if an element matches resolved ignore targets.
535
+ */
536
+ function isIgnored(el, selectors, elements) {
537
+ if (!el) return false;
538
+ for (const selector of selectors) try {
539
+ if (el.matches(selector) || !/* @__PURE__ */ isNull(el.closest(selector))) return true;
540
+ } catch {}
541
+ for (const ignoreEl of elements) if (ignoreEl === el || ignoreEl.contains(el)) return true;
542
+ return false;
543
+ }
544
+ /**
545
+ * Check if any element in the event path should be ignored.
546
+ */
547
+ function shouldIgnore(path) {
548
+ const [selectors, elements] = resolveIgnoreTargets();
549
+ if (selectors.length === 0 && elements.length === 0) return false;
550
+ return path.some((node) => node instanceof Element && isIgnored(node, selectors, elements));
551
+ }
552
+ /**
553
+ * Check if the event target is outside all target elements.
554
+ */
555
+ function isOutside(eventTarget) {
556
+ if (!eventTarget) return false;
557
+ if (!(eventTarget instanceof Node)) return false;
558
+ const targets = getTargets();
559
+ if (targets.length === 0) return false;
560
+ return targets.every((el) => {
561
+ return el !== eventTarget && !el.contains(eventTarget);
562
+ });
563
+ }
564
+ /**
565
+ * Validate that the target is still in the DOM.
566
+ */
567
+ function isValidTarget(eventTarget) {
568
+ if (!(eventTarget instanceof Element)) return false;
569
+ if (!eventTarget.isConnected) return false;
570
+ return true;
571
+ }
572
+ /**
573
+ * Handle pointerdown - store initial target and position.
574
+ */
575
+ function onPointerDown(event) {
576
+ if (isPaused.value) return;
577
+ if (event.defaultPrevented) return;
578
+ initialTarget = event.composedPath()[0] ?? event.target;
579
+ startPosition = {
580
+ x: event.clientX,
581
+ y: event.clientY
582
+ };
583
+ }
584
+ /**
585
+ * Handle pointerup - check if it's an outside click.
586
+ */
587
+ function onPointerUp(event) {
588
+ if (isPaused.value) return;
589
+ if (event.defaultPrevented) return;
590
+ if (!initialTarget) return;
591
+ const pointerdownTarget = initialTarget;
592
+ initialTarget = null;
593
+ if (!isValidTarget(pointerdownTarget)) return;
594
+ const path = event.composedPath();
595
+ const pointerupTarget = path[0] ?? event.target;
596
+ if (event.pointerType === "touch") {
597
+ const dx = Math.abs(event.clientX - startPosition.x);
598
+ const dy = Math.abs(event.clientY - startPosition.y);
599
+ if (dx >= touchScrollThreshold || dy >= touchScrollThreshold) return;
600
+ }
601
+ if (isOutside(pointerdownTarget) && isOutside(pointerupTarget) && !shouldIgnore(path)) handler(event);
602
+ }
603
+ /**
604
+ * Handle window blur - detect focus moving to iframe.
605
+ */
606
+ function onBlur(event) {
607
+ if (isPaused.value) return;
608
+ if (event.defaultPrevented) return;
609
+ if (document.activeElement instanceof HTMLIFrameElement) {
610
+ const iframeIsOutside = getTargets().every((el) => !el.contains(document.activeElement));
611
+ const [selectors, elements] = resolveIgnoreTargets();
612
+ if (iframeIsOutside && !isIgnored(document.activeElement, selectors, elements)) handler(event);
613
+ }
614
+ }
615
+ function setup() {
616
+ cleanupPointerDown = useDocumentEventListener("pointerdown", onPointerDown, capture);
617
+ cleanupPointerUp = useDocumentEventListener("pointerup", onPointerUp, capture);
618
+ if (!detectIframe) return;
619
+ cleanupBlur = useWindowEventListener("blur", onBlur, capture);
620
+ }
621
+ function cleanup() {
622
+ cleanupPointerDown?.();
623
+ cleanupPointerUp?.();
624
+ cleanupBlur?.();
625
+ cleanupPointerDown = void 0;
626
+ cleanupPointerUp = void 0;
627
+ cleanupBlur = void 0;
628
+ }
629
+ function pause() {
630
+ if (isPaused.value) return;
631
+ isPaused.value = true;
632
+ initialTarget = null;
633
+ cleanup();
634
+ }
635
+ function resume() {
636
+ if (!isPaused.value) return;
637
+ isPaused.value = false;
638
+ setup();
639
+ }
640
+ function stop() {
641
+ isPaused.value = true;
642
+ initialTarget = null;
643
+ cleanup();
644
+ }
645
+ setup();
646
+ onScopeDispose(stop, true);
647
+ return {
648
+ isActive: shallowReadonly(isActive),
649
+ isPaused: shallowReadonly(isPaused),
650
+ pause,
651
+ resume,
652
+ stop
653
+ };
654
+ }
655
+
656
+ //#endregion
657
+ //#region src/composables/useFeatures/index.ts
514
658
  /**
515
659
  * Creates a new features instance.
516
660
  *
@@ -671,22 +815,6 @@ function useFeatures(namespace = "v0:features") {
671
815
 
672
816
  //#endregion
673
817
  //#region src/composables/useFilter/index.ts
674
- /**
675
- * @module useFilter
676
- *
677
- * @remarks
678
- * Reactive array filtering composable with multiple filter modes.
679
- *
680
- * Key features:
681
- * - Four filter modes: some, every, union, intersection
682
- * - Case-insensitive filtering
683
- * - Custom filter functions
684
- * - Reactive updates
685
- * - Context-based DI support
686
- * - Perfect for search, multi-criteria filtering
687
- *
688
- * Filters arrays based on query strings with configurable matching strategies.
689
- */
690
818
  function defaultFilter(query, item, keys, mode = "some") {
691
819
  const queries = Array.isArray(query) ? query.map((q) => String(q).toLowerCase()) : [String(query).toLowerCase()];
692
820
  function match(value, q) {
@@ -840,22 +968,6 @@ function useFilterContext(namespace = "v0:filter") {
840
968
  //#endregion
841
969
  //#region src/composables/useForm/index.ts
842
970
  /**
843
- * @module useForm
844
- *
845
- * @remarks
846
- * Form validation composable with async rule support and multiple validation modes.
847
- *
848
- * Key features:
849
- * - Sync and async validation rules
850
- * - Multiple validation modes (submit, change, combined)
851
- * - Tri-state isValid (null/true/false)
852
- * - isPristine tracking
853
- * - Silent validation mode
854
- * - Form-level validation and reset
855
- *
856
- * Each field is registered with validation rules and tracks its own state independently.
857
- */
858
- /**
859
971
  * Creates a new form instance.
860
972
  *
861
973
  * @param options The options for the form instance.
@@ -1061,22 +1173,6 @@ function useForm(namespace = "v0:form") {
1061
1173
  //#endregion
1062
1174
  //#region src/composables/useIntersectionObserver/index.ts
1063
1175
  /**
1064
- * @module useIntersectionObserver
1065
- *
1066
- * @remarks
1067
- * IntersectionObserver composable with lifecycle management.
1068
- *
1069
- * Key features:
1070
- * - IntersectionObserver API wrapper
1071
- * - Pause/resume/stop functionality
1072
- * - Automatic cleanup on unmount
1073
- * - SSR-safe (checks SUPPORTS_INTERSECTION_OBSERVER)
1074
- * - Hydration-aware
1075
- * - Immediate callback option
1076
- *
1077
- * Perfect for lazy loading, infinite scroll, and visibility detection.
1078
- */
1079
- /**
1080
1176
  * A composable that uses the Intersection Observer API to detect when an element
1081
1177
  * is visible in the viewport.
1082
1178
  *
@@ -1117,12 +1213,14 @@ function useForm(namespace = "v0:form") {
1117
1213
  */
1118
1214
  function useIntersectionObserver(target, callback, options = {}) {
1119
1215
  const { isHydrated } = useHydration();
1216
+ const targetRef = isRef(target) ? target : shallowRef(target);
1120
1217
  const observer = shallowRef();
1121
1218
  const isPaused = shallowRef(false);
1122
1219
  const isIntersecting = shallowRef(false);
1123
1220
  const isActive = toRef(() => !!observer.value);
1124
1221
  function setup() {
1125
- if (!isHydrated.value || !SUPPORTS_INTERSECTION_OBSERVER || !target.value || isPaused.value) return;
1222
+ if (observer.value === null) return;
1223
+ if (!isHydrated.value || !SUPPORTS_INTERSECTION_OBSERVER || !targetRef.value || isPaused.value) return;
1126
1224
  observer.value = new IntersectionObserver((entries) => {
1127
1225
  const transformedEntries = entries.map((entry) => ({
1128
1226
  boundingClientRect: entry.boundingClientRect,
@@ -1136,26 +1234,29 @@ function useIntersectionObserver(target, callback, options = {}) {
1136
1234
  const latestEntry = transformedEntries.at(-1);
1137
1235
  if (latestEntry) isIntersecting.value = latestEntry.isIntersecting;
1138
1236
  callback(transformedEntries);
1237
+ if (options.once && latestEntry?.isIntersecting) stop();
1139
1238
  }, {
1140
1239
  root: options.root || null,
1141
1240
  rootMargin: options.rootMargin || "0px",
1142
1241
  threshold: options.threshold || 0
1143
1242
  });
1144
- observer.value.observe(target.value);
1243
+ observer.value.observe(targetRef.value);
1145
1244
  if (options.immediate) callback([{
1146
- boundingClientRect: target.value.getBoundingClientRect(),
1245
+ boundingClientRect: targetRef.value.getBoundingClientRect(),
1147
1246
  intersectionRatio: 0,
1148
1247
  intersectionRect: new DOMRect(0, 0, 0, 0),
1149
1248
  isIntersecting: false,
1150
1249
  rootBounds: null,
1151
- target: target.value,
1250
+ target: targetRef.value,
1152
1251
  time: performance.now()
1153
1252
  }]);
1154
1253
  }
1155
- watch([isHydrated, target], () => {
1254
+ watchEffect(() => {
1255
+ const hydrated = isHydrated.value;
1256
+ const target$1 = targetRef.value;
1156
1257
  cleanup();
1157
- setup();
1158
- }, { immediate: true });
1258
+ if (hydrated && target$1) setup();
1259
+ });
1159
1260
  function cleanup() {
1160
1261
  if (observer.value) {
1161
1262
  observer.value.disconnect();
@@ -1173,6 +1274,7 @@ function useIntersectionObserver(target, callback, options = {}) {
1173
1274
  }
1174
1275
  function stop() {
1175
1276
  cleanup();
1277
+ observer.value = null;
1176
1278
  }
1177
1279
  onScopeDispose(stop, true);
1178
1280
  return {
@@ -1244,20 +1346,6 @@ function useElementIntersection(target, options = {}) {
1244
1346
  //#endregion
1245
1347
  //#region src/composables/useKeydown/index.ts
1246
1348
  /**
1247
- * @module useKeydown
1248
- *
1249
- * @remarks
1250
- * Keydown event listener composable with key filtering.
1251
- *
1252
- * Key features:
1253
- * - Key-specific event handling
1254
- * - preventDefault and stopPropagation options
1255
- * - Automatic cleanup on scope disposal
1256
- * - Built on useEventListener for consistent event handling
1257
- *
1258
- * Simplified wrapper around useEventListener for keyboard interactions.
1259
- */
1260
- /**
1261
1349
  * A composable that adds a keydown event listener to the document.
1262
1350
  *
1263
1351
  * @param handlers The key handlers to add.
@@ -1269,6 +1357,10 @@ function useElementIntersection(target, options = {}) {
1269
1357
  * ```ts
1270
1358
  * import { useKeydown } from '@vuetify/v0'
1271
1359
  *
1360
+ * // Single handler
1361
+ * useKeydown({ key: 'Escape', handler: () => console.log('Escape pressed') })
1362
+ *
1363
+ * // Multiple handlers
1272
1364
  * const { isActive, start, stop } = useKeydown([
1273
1365
  * { key: 'Enter', handler: () => console.log('Enter pressed') },
1274
1366
  * { key: 'Escape', handler: () => console.log('Escape pressed'), preventDefault: true },
@@ -1313,22 +1405,6 @@ function useKeydown(handlers) {
1313
1405
  //#endregion
1314
1406
  //#region src/composables/useMutationObserver/index.ts
1315
1407
  /**
1316
- * @module useMutationObserver
1317
- *
1318
- * @remarks
1319
- * MutationObserver composable with lifecycle management.
1320
- *
1321
- * Key features:
1322
- * - MutationObserver API wrapper
1323
- * - Pause/resume/stop functionality
1324
- * - Automatic cleanup on unmount
1325
- * - SSR-safe (checks SUPPORTS_MUTATION_OBSERVER)
1326
- * - Hydration-aware
1327
- * - Configurable observation options (childList, attributes, characterData, etc.)
1328
- *
1329
- * Perfect for detecting DOM changes and responding to mutations.
1330
- */
1331
- /**
1332
1408
  * A composable that uses the Mutation Observer API to detect changes in the DOM.
1333
1409
  *
1334
1410
  * @param target The element to observe.
@@ -1375,7 +1451,7 @@ function useMutationObserver(target, callback, options = {}) {
1375
1451
  const { isHydrated } = useHydration();
1376
1452
  const observer = shallowRef();
1377
1453
  const isPaused = shallowRef(false);
1378
- const isActive = computed(() => !!observer.value);
1454
+ const isActive = toRef(() => !!observer.value);
1379
1455
  const observerOptions = {
1380
1456
  childList: options.childList ?? true,
1381
1457
  attributes: options.attributes ?? false,
@@ -1386,6 +1462,7 @@ function useMutationObserver(target, callback, options = {}) {
1386
1462
  attributeFilter: options.attributeFilter
1387
1463
  };
1388
1464
  function setup() {
1465
+ if (observer.value === null) return;
1389
1466
  if (!isHydrated.value || !SUPPORTS_MUTATION_OBSERVER || !target.value || isPaused.value) return;
1390
1467
  observer.value = new MutationObserver((mutations) => {
1391
1468
  callback(mutations.map((mutation) => ({
@@ -1399,6 +1476,7 @@ function useMutationObserver(target, callback, options = {}) {
1399
1476
  attributeNamespace: mutation.attributeNamespace,
1400
1477
  oldValue: mutation.oldValue
1401
1478
  })));
1479
+ if (options.once) stop();
1402
1480
  });
1403
1481
  observer.value.observe(target.value, observerOptions);
1404
1482
  if (options.immediate) {
@@ -1419,12 +1497,15 @@ function useMutationObserver(target, callback, options = {}) {
1419
1497
  attributeNamespace: null,
1420
1498
  oldValue: null
1421
1499
  }]);
1500
+ if (options.once) stop();
1422
1501
  }
1423
1502
  }
1424
- watch([isHydrated, target], () => {
1503
+ watchEffect(() => {
1504
+ const hydrated = isHydrated.value;
1505
+ const el = target.value;
1425
1506
  cleanup();
1426
- setup();
1427
- }, { immediate: true });
1507
+ if (hydrated && el) setup();
1508
+ });
1428
1509
  function cleanup() {
1429
1510
  if (observer.value) {
1430
1511
  observer.value.disconnect();
@@ -1441,6 +1522,7 @@ function useMutationObserver(target, callback, options = {}) {
1441
1522
  }
1442
1523
  function stop() {
1443
1524
  cleanup();
1525
+ observer.value = null;
1444
1526
  }
1445
1527
  onScopeDispose(stop, true);
1446
1528
  return {
@@ -1473,23 +1555,6 @@ var Vuetify0PermissionAdapter = class extends PermissionAdapter {
1473
1555
  //#endregion
1474
1556
  //#region src/composables/usePermissions/index.ts
1475
1557
  /**
1476
- * @module usePermissions
1477
- *
1478
- * @see https://0.vuetifyjs.com/composables/plugins/use-permissions
1479
- *
1480
- * @remarks
1481
- * Permission management composable with support for RBAC and ABAC patterns.
1482
- *
1483
- * Key features:
1484
- * - Role-Based Access Control (RBAC) support
1485
- * - Attribute-Based Access Control (ABAC) with context
1486
- * - Functional permission conditions
1487
- * - Token-based permission storage
1488
- * - Adapter pattern for custom permission systems
1489
- *
1490
- * Built on useTokens for flexible permission configuration.
1491
- */
1492
- /**
1493
1558
  * Creates a new permissions instance.
1494
1559
  *
1495
1560
  * @param options The options for the permissions instance.
@@ -1636,21 +1701,6 @@ function usePermissions(namespace = "v0:permissions") {
1636
1701
  //#endregion
1637
1702
  //#region src/composables/useQueue/index.ts
1638
1703
  /**
1639
- * @module useQueue
1640
- *
1641
- * @remarks
1642
- * A queue composable for managing time-based collections with:
1643
- * - Automatic timeout-based removal
1644
- * - Pause/resume functionality
1645
- * - FIFO (First In, First Out) ordering
1646
- * - Manual dismissal support
1647
- * - Queue progression management
1648
- *
1649
- * Built on top of useRegistry, the queue automatically manages timeouts for tickets,
1650
- * ensuring only the first ticket in the queue is active at any time. When an ticket
1651
- * expires or is removed, the next ticket in the queue automatically becomes active.
1652
- */
1653
- /**
1654
1704
  * Creates a new queue instance
1655
1705
  *
1656
1706
  * @param options The options for the queue instance
@@ -1852,21 +1902,6 @@ var MemoryAdapter = class {
1852
1902
  //#endregion
1853
1903
  //#region src/composables/useStorage/index.ts
1854
1904
  /**
1855
- * @module useStorage
1856
- *
1857
- * @remarks
1858
- * Reactive storage composable with adapter pattern for localStorage, sessionStorage, or memory.
1859
- *
1860
- * Key features:
1861
- * - Reactive refs that sync with storage
1862
- * - localStorage, sessionStorage, and memory adapters
1863
- * - Custom serialization support
1864
- * - SSR fallback to memory adapter
1865
- * - Automatic cleanup on remove/clear
1866
- *
1867
- * Uses adapter pattern to abstract storage implementation details.
1868
- */
1869
- /**
1870
1905
  * Creates a new storage instance.
1871
1906
  *
1872
1907
  * @param options The options for the storage instance.
@@ -2103,24 +2138,6 @@ var Vuetify0ThemeAdapter = class extends ThemeAdapter {
2103
2138
  //#endregion
2104
2139
  //#region src/composables/useTheme/index.ts
2105
2140
  /**
2106
- * @module useTheme
2107
- *
2108
- * @see https://0.vuetifyjs.com/composables/plugins/use-theme
2109
- *
2110
- * @remarks
2111
- * Theme management composable with token resolution and CSS variable injection.
2112
- *
2113
- * Key features:
2114
- * - Single-selection theme switching (extends createSingle)
2115
- * - Token alias resolution via useTokens
2116
- * - Lazy theme loading (compute colors only when selected)
2117
- * - CSS variable generation via adapter pattern
2118
- * - SSR support with head integration
2119
- * - Theme cycling
2120
- *
2121
- * Integrates with createSingle for selection and useTokens for color resolution.
2122
- */
2123
- /**
2124
2141
  * Creates a new theme instance.
2125
2142
  *
2126
2143
  * @param options The options for the theme instance.
@@ -2341,21 +2358,6 @@ function useTheme(namespace = "v0:theme") {
2341
2358
  //#endregion
2342
2359
  //#region src/composables/useTimeline/index.ts
2343
2360
  /**
2344
- * @module useTimeline
2345
- *
2346
- * @remarks
2347
- * Bounded undo/redo system with overflow management.
2348
- *
2349
- * Key features:
2350
- * - Fixed-size history (default: 10 items)
2351
- * - Undo/redo stack management
2352
- * - Overflow queue (preserves oldest items)
2353
- * - Automatic reindexing after operations
2354
- * - Perfect for command pattern, history tracking
2355
- *
2356
- * Extends useRegistry with temporal navigation capabilities.
2357
- */
2358
- /**
2359
2361
  * Creates a new timeline instance.
2360
2362
  *
2361
2363
  * @param _options The options for the timeline instance.
@@ -2490,24 +2492,6 @@ function useTimeline(namespace = "v0:timeline") {
2490
2492
  //#endregion
2491
2493
  //#region src/composables/useToggleScope/index.ts
2492
2494
  /**
2493
- * @module useToggleScope
2494
- *
2495
- * @remarks
2496
- * Conditionally manages an effect scope based on a reactive boolean condition.
2497
- * When the source becomes true, creates and runs an effect scope. When false, stops the scope.
2498
- * All reactive effects created within the scoped function are automatically cleaned up on deactivation.
2499
- *
2500
- * Key features:
2501
- * - Uses Vue's effectScope for efficient reactive effect lifecycle management
2502
- * - Automatic cleanup when condition becomes false
2503
- * - Supports optional reset callback for scope restart capability
2504
- * - Handles rapid toggling and parent scope disposal safely
2505
- * - SSR-safe (effectScope is part of Vue core)
2506
- *
2507
- * Perfect for conditional side effects, feature flags, and performance optimization
2508
- * by only running reactive effects when needed.
2509
- */
2510
- /**
2511
2495
  * Conditionally manages an effect scope based on a reactive boolean source.
2512
2496
  *
2513
2497
  * @param source A reactive boolean value or getter that controls the scope lifecycle
@@ -2589,24 +2573,6 @@ function useToggleScope(source, fn) {
2589
2573
  //#endregion
2590
2574
  //#region src/composables/useVirtual/index.ts
2591
2575
  /**
2592
- * @module useVirtual
2593
- *
2594
- * @remarks
2595
- * Virtual scrolling composable for efficiently rendering large lists.
2596
- *
2597
- * Key features:
2598
- * - Renders only visible items (viewport + overscan)
2599
- * - Dynamic or fixed item heights
2600
- * - SSR-safe (checks IN_BROWSER)
2601
- * - Bidirectional scrolling (forward/reverse for chat apps)
2602
- * - Scroll anchoring (maintains position across data changes)
2603
- * - Edge detection for infinite scroll
2604
- * - iOS momentum and elastic scrolling
2605
- * - Configurable overscan (extra items rendered for smooth scrolling)
2606
- *
2607
- * Perfect for large data sets, chat apps, and infinite scroll implementations.
2608
- */
2609
- /**
2610
2576
  * Virtual scrolling composable for efficiently rendering large lists
2611
2577
  *
2612
2578
  * @param items Reactive array of items to virtualize
@@ -2847,7 +2813,7 @@ function useVirtual(items, _options = {}) {
2847
2813
  cancelAnimationFrame(raf);
2848
2814
  cancelAnimationFrame(rebuildRaf);
2849
2815
  cancelAnimationFrame(edgeRaf);
2850
- });
2816
+ }, true);
2851
2817
  return {
2852
2818
  element,
2853
2819
  items: computedItems,
@@ -2863,4 +2829,4 @@ function useVirtual(items, _options = {}) {
2863
2829
  }
2864
2830
 
2865
2831
  //#endregion
2866
- export { useForm as A, createBreakpointsContext as B, PermissionAdapter as C, useIntersectionObserver as D, useElementIntersection as E, createFeatures as F, useWindowEventListener as G, useBreakpoints as H, createFeaturesContext as I, toReactive as K, createFeaturesPlugin as L, createFilterContext as M, useFilter as N, createForm as O, useFilterContext as P, useFeatures as R, usePermissions as S, useKeydown as T, useDocumentEventListener as U, createBreakpointsPlugin as V, useEventListener as W, createQueueContext as _, useTimeline as a, createPermissionsContext as b, createThemePlugin as c, createStorage as d, createStorageContext as f, createQueue as g, MemoryAdapter as h, createTimelineContext as i, createFilter as j, createFormContext as k, useTheme as l, useStorage as m, useToggleScope as n, createTheme as o, createStoragePlugin as p, createTimeline as r, createThemeContext as s, useVirtual as t, Vuetify0ThemeAdapter as u, useQueue as v, useMutationObserver as w, createPermissionsPlugin as x, createPermissions as y, createBreakpoints as z };
2832
+ export { useForm as A, createBreakpoints as B, PermissionAdapter as C, useIntersectionObserver as D, useElementIntersection as E, createFeatures as F, useEventListener as G, createBreakpointsPlugin as H, createFeaturesContext as I, useWindowEventListener as K, createFeaturesPlugin as L, createFilterContext as M, useFilter as N, createForm as O, useFilterContext as P, useFeatures as R, usePermissions as S, useKeydown as T, useBreakpoints as U, createBreakpointsContext as V, useDocumentEventListener as W, createQueueContext as _, useTimeline as a, createPermissionsContext as b, createThemePlugin as c, createStorage as d, createStorageContext as f, createQueue as g, MemoryAdapter as h, createTimelineContext as i, createFilter as j, createFormContext as k, useTheme as l, useStorage as m, useToggleScope as n, createTheme as o, createStoragePlugin as p, toReactive as q, createTimeline as r, createThemeContext as s, useVirtual as t, Vuetify0ThemeAdapter as u, useQueue as v, useMutationObserver as w, createPermissionsPlugin as x, createPermissions as y, useClickOutside as z };