@vuetify/v0 0.1.8 → 0.1.10

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.
Files changed (119) hide show
  1. package/SKILL.md +95 -0
  2. package/dist/adapter-D3dUnE__.d.mts +17 -0
  3. package/dist/{adapter-DIx4Rntl.d.mts → adapter-hDuQ9aNN.d.mts} +4 -4
  4. package/dist/browser/index.js +2029 -704
  5. package/dist/components/index.d.mts +2 -2
  6. package/dist/components/index.mjs +23 -23
  7. package/dist/{components-BbxKYAXs.mjs → components-TiigKVsl.mjs} +816 -237
  8. package/dist/composables/index.d.mts +16 -15
  9. package/dist/composables/index.mjs +22 -22
  10. package/dist/{consola-BVzYzeLH.d.mts → consola-C1OjyZVf.d.mts} +1 -1
  11. package/dist/constants/index.d.mts +1 -1
  12. package/dist/constants/index.mjs +1 -1
  13. package/dist/{createDataTable-DZouEhvH.mjs → createDataTable-DoqbfLt0.mjs} +5 -5
  14. package/dist/{createGroup-BpJFi41X.mjs → createGroup-DpbGTwFy.mjs} +1 -1
  15. package/dist/{createPagination-Bu8vE0JW.mjs → createPagination-DZSJ8aO5.mjs} +5 -5
  16. package/dist/{createSelection-8MX0OHXR.mjs → createSelection-B6bQNyuF.mjs} +1 -1
  17. package/dist/{createSingle-CbuOBb-E.mjs → createSingle-fWHREEJO.mjs} +6 -6
  18. package/dist/{createTokens-CXlT0Vc6.mjs → createTokens-N8QIWw_D.mjs} +26 -5
  19. package/dist/data-table/adapters/client/index.d.mts +1 -1
  20. package/dist/data-table/adapters/client/index.mjs +3 -3
  21. package/dist/data-table/adapters/index.d.mts +4 -4
  22. package/dist/data-table/adapters/index.mjs +5 -5
  23. package/dist/data-table/adapters/server/index.d.mts +1 -1
  24. package/dist/data-table/adapters/server/index.mjs +3 -3
  25. package/dist/data-table/adapters/virtual/index.d.mts +1 -1
  26. package/dist/data-table/adapters/virtual/index.mjs +3 -3
  27. package/dist/data-table/index.d.mts +5 -5
  28. package/dist/data-table/index.mjs +14 -14
  29. package/dist/date/index.mjs +1 -1
  30. package/dist/features/adapters/posthog/index.mjs +2 -2
  31. package/dist/features/index.d.mts +1 -1
  32. package/dist/features/index.mjs +8 -8
  33. package/dist/{globals-ClSU6mqC.mjs → globals-F7fiJVG1.mjs} +1 -1
  34. package/dist/{index-CmCMrlt3.d.mts → index-CLDBngUs.d.mts} +1 -1
  35. package/dist/{index-MHkcqY_y.d.mts → index-Cv1XUHyA.d.mts} +1 -21
  36. package/dist/{index-B5NU2uB7.d.mts → index-DXdQb5BV.d.mts} +1057 -217
  37. package/dist/{index-63-0oJS8.d.mts → index-Dfa5Wb4T.d.mts} +430 -186
  38. package/dist/{index-CxW4itj1.d.mts → index-YyqYAay2.d.mts} +10 -2
  39. package/dist/index.d.mts +19 -18
  40. package/dist/index.mjs +24 -24
  41. package/dist/json/attributes.json +196 -0
  42. package/dist/json/importMap.json +52 -0
  43. package/dist/json/tags.json +104 -0
  44. package/dist/json/web-types.json +617 -1
  45. package/dist/locale/adapters/index.d.mts +3 -2
  46. package/dist/locale/adapters/index.mjs +2 -2
  47. package/dist/locale/adapters/v0/index.d.mts +1 -1
  48. package/dist/locale/adapters/v0/index.mjs +2 -2
  49. package/dist/locale/adapters/vue-i18n/index.d.mts +22 -0
  50. package/dist/locale/adapters/vue-i18n/index.mjs +26 -0
  51. package/dist/locale/index.d.mts +4 -3
  52. package/dist/locale/index.mjs +8 -9
  53. package/dist/logger/adapters/consola/index.d.mts +1 -1
  54. package/dist/logger/adapters/index.d.mts +4 -4
  55. package/dist/logger/adapters/index.mjs +2 -2
  56. package/dist/logger/adapters/pino/index.d.mts +1 -1
  57. package/dist/logger/adapters/pino/index.mjs +1 -1
  58. package/dist/logger/adapters/v0/index.d.mts +1 -1
  59. package/dist/logger/adapters/v0/index.mjs +2 -2
  60. package/dist/logger/index.d.mts +5 -5
  61. package/dist/logger/index.mjs +3 -3
  62. package/dist/notifications/index.d.mts +78 -0
  63. package/dist/notifications/index.mjs +215 -0
  64. package/dist/palettes/ant/index.d.mts +1 -1
  65. package/dist/palettes/index.d.mts +2 -2
  66. package/dist/palettes/material/index.d.mts +1 -1
  67. package/dist/palettes/md1/index.d.mts +1 -1
  68. package/dist/palettes/md2/index.d.mts +1 -1
  69. package/dist/palettes/radix/index.d.mts +1 -1
  70. package/dist/palettes/tailwind/index.d.mts +1 -1
  71. package/dist/permissions/adapters/index.d.mts +2 -2
  72. package/dist/permissions/adapters/index.mjs +1 -1
  73. package/dist/permissions/adapters/v0/index.d.mts +1 -1
  74. package/dist/permissions/adapters/v0/index.mjs +1 -1
  75. package/dist/permissions/index.d.mts +1 -1
  76. package/dist/permissions/index.mjs +5 -5
  77. package/dist/{pino-Bzighnkd.d.mts → pino-CM1iLXmi.d.mts} +1 -1
  78. package/dist/{posthog-BE7-t7cV.mjs → posthog-CdcdfMYS.mjs} +1 -1
  79. package/dist/rules/index.d.mts +1 -1
  80. package/dist/rules/index.mjs +9 -10
  81. package/dist/{server-Ch9J86tb.d.mts → server-Ct-h4-OA.d.mts} +1 -1
  82. package/dist/{server-CZ6ahbEH.mjs → server-DHET3KNW.mjs} +1 -1
  83. package/dist/storage/adapters/index.d.mts +2 -2
  84. package/dist/storage/adapters/memory/index.d.mts +1 -1
  85. package/dist/storage/index.d.mts +3 -3
  86. package/dist/storage/index.mjs +21 -21
  87. package/dist/theme/adapters/index.d.mts +1 -1
  88. package/dist/theme/adapters/index.mjs +2 -2
  89. package/dist/theme/adapters/v0/index.d.mts +1 -1
  90. package/dist/theme/adapters/v0/index.mjs +2 -2
  91. package/dist/theme/index.d.mts +1 -1
  92. package/dist/theme/index.mjs +8 -8
  93. package/dist/{useClickOutside-W0Sur1rC.mjs → useClickOutside-DNuJQ9EG.mjs} +860 -126
  94. package/dist/{useFeatures-CUicSI-E.mjs → useFeatures-CWNXTIXk.mjs} +3 -3
  95. package/dist/useLocale-Dzl6lCCF.mjs +75 -0
  96. package/dist/{useLogger-DY1Hbcy1.mjs → useLogger-Bw836Jbg.mjs} +2 -2
  97. package/dist/{usePermissions-BSW59R4q.mjs → usePermissions-DrRVDeVy.mjs} +2 -2
  98. package/dist/{useRules-BbA6_gvs.mjs → useRules-TMGuA8al.mjs} +2 -2
  99. package/dist/{useTheme-Bdx2Lj5c.mjs → useTheme-qMpg3Ti6.mjs} +9 -6
  100. package/dist/utilities/index.d.mts +2 -2
  101. package/dist/utilities/index.mjs +3 -32
  102. package/dist/v0-3zDdS4II.d.mts +19 -0
  103. package/dist/{v0-BZINNGoC.d.mts → v0-BBRwZ3at.d.mts} +1 -1
  104. package/dist/{v0-YAqbXudL.mjs → v0-BoWQ8RK0.mjs} +1 -1
  105. package/dist/{v0-BFseIsBi.mjs → v0-BsuBuBSa.mjs} +1 -1
  106. package/dist/{v0-2G2476h-.mjs → v0-CIEQpOK2.mjs} +1 -1
  107. package/dist/{v0-CdUL2eOn.d.mts → v0-CMeh39LQ.d.mts} +1 -1
  108. package/dist/v0-DgaVf3xM.mjs +62 -0
  109. package/dist/{v0-1xxC39wf.d.mts → v0-JPf99NKg.d.mts} +1 -1
  110. package/dist/{virtual-DwBiFA25.d.mts → virtual-B1lRbO7Q.d.mts} +1 -1
  111. package/dist/{virtual-eDNVH1fz.mjs → virtual-D0_D5gkh.mjs} +1 -1
  112. package/package.json +11 -4
  113. package/dist/useLocale-cQlPxbpV.mjs +0 -87
  114. package/dist/v0-CAKa6tzG.d.mts +0 -22
  115. package/dist/v0-CHBrvw49.mjs +0 -35
  116. /package/dist/{adapter-JTFG3Jn8.d.mts → adapter-CJQav2JB.d.mts} +0 -0
  117. /package/dist/{index-B5ZDDkXv.d.mts → index-BvTD7kU8.d.mts} +0 -0
  118. /package/dist/{index-NsE5nARK.d.mts → index-DSao7i57.d.mts} +0 -0
  119. /package/dist/{memory-BTtRdnNn.d.mts → memory-DyBabFV1.d.mts} +0 -0
@@ -1,14 +1,14 @@
1
- import { a as SUPPORTS_OBSERVER, i as SUPPORTS_MUTATION_OBSERVER, n as SUPPORTS_INTERSECTION_OBSERVER, r as SUPPORTS_MATCH_MEDIA, t as IN_BROWSER } from "./globals-ClSU6mqC.mjs";
1
+ import { a as SUPPORTS_OBSERVER, i as SUPPORTS_MUTATION_OBSERVER, n as SUPPORTS_INTERSECTION_OBSERVER, r as SUPPORTS_MATCH_MEDIA, t as IN_BROWSER } from "./globals-F7fiJVG1.mjs";
2
2
  import { clamp, instanceExists, isElement, isFunction, isNull, isNullOrUndefined, isNumber, isObject, isString, isUndefined, mergeDeep, useId as useId$1 } from "./utilities/index.mjs";
3
3
  import { i as useContext, n as createContext, t as createTrinity } from "./createTrinity-C_c8eedz.mjs";
4
- import { a as createPlugin, i as useLogger, o as createPluginContext } from "./useLogger-DY1Hbcy1.mjs";
5
- import { i as createRegistry } from "./createTokens-CXlT0Vc6.mjs";
6
- import { i as createModel, t as createSelection } from "./createSelection-8MX0OHXR.mjs";
7
- import { t as createSingle } from "./createSingle-CbuOBb-E.mjs";
8
- import { t as createGroup } from "./createGroup-BpJFi41X.mjs";
4
+ import { a as createPlugin, i as useLogger, o as createPluginContext } from "./useLogger-Bw836Jbg.mjs";
5
+ import { a as createRegistry } from "./createTokens-N8QIWw_D.mjs";
6
+ import { i as createModel, t as createSelection } from "./createSelection-B6bQNyuF.mjs";
7
+ import { t as createSingle } from "./createSingle-fWHREEJO.mjs";
8
+ import { t as createGroup } from "./createGroup-DpbGTwFy.mjs";
9
9
  import { t as toArray } from "./toArray-VdROPpy-.mjs";
10
- import { a as useLocale } from "./useLocale-cQlPxbpV.mjs";
11
- import { a as useRules, o as isStandardSchema } from "./useRules-BbA6_gvs.mjs";
10
+ import { a as useLocale } from "./useLocale-Dzl6lCCF.mjs";
11
+ import { a as useRules, o as isStandardSchema } from "./useRules-TMGuA8al.mjs";
12
12
  import { t as MemoryAdapter } from "./memory-XCMtkld1.mjs";
13
13
  import { computed, effectScope, isRef, nextTick, onMounted, onScopeDispose, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, toRef, toValue, unref, watch, watchEffect } from "vue";
14
14
  //#region src/composables/createBreadcrumbs/index.ts
@@ -747,7 +747,8 @@ function useProxyModel(context, model, options) {
747
747
  const modelAsArray = transformIn(model);
748
748
  const pending = new Set(modelAsArray);
749
749
  context.apply(modelAsArray, applyOptions);
750
- for (const value of modelAsArray) if (Array.from(context.selectedValues.value).includes(value)) pending.delete(value);
750
+ const selected = new Set(context.selectedValues.value);
751
+ for (const value of modelAsArray) if (selected.has(value)) pending.delete(value);
751
752
  const contextWatch = watch(context.selectedValues, (val) => {
752
753
  modelWatch.pause();
753
754
  model.value = transformOut(Array.from(toValue(val)));
@@ -781,6 +782,132 @@ function useProxyModel(context, model, options) {
781
782
  return stop;
782
783
  }
783
784
  //#endregion
785
+ //#region src/composables/useTimer/index.ts
786
+ /**
787
+ * @module useTimer
788
+ *
789
+ * @remarks
790
+ * A reactive timer composable with pause/resume support.
791
+ *
792
+ * Key features:
793
+ * - Start/stop/pause/resume controls
794
+ * - Reactive remaining time tracking
795
+ * - One-shot (default) or repeating mode
796
+ * - Automatic cleanup on scope disposal
797
+ * - SSR-safe
798
+ */
799
+ /**
800
+ * Creates a reactive timer with pause/resume support.
801
+ *
802
+ * @param handler Callback invoked when the timer fires.
803
+ * @param options Timer configuration.
804
+ * @returns Timer controls and reactive state.
805
+ *
806
+ * @see https://0.vuetifyjs.com/composables/system/use-timer
807
+ *
808
+ * @example
809
+ * ```ts
810
+ * const timer = useTimer(() => console.log('fired'), { duration: 5000 })
811
+ *
812
+ * timer.start()
813
+ * timer.pause()
814
+ * timer.resume()
815
+ * timer.stop()
816
+ * ```
817
+ */
818
+ function useTimer(handler, options = {}) {
819
+ const { duration = 1e3, repeat = false } = options;
820
+ const remaining = shallowRef(duration);
821
+ const isActive = shallowRef(false);
822
+ const isPaused = shallowRef(false);
823
+ let timeoutId;
824
+ let trackingId;
825
+ let startedAt = 0;
826
+ let budget = duration;
827
+ function clearTimer() {
828
+ if (!/* @__PURE__ */ isUndefined(timeoutId)) {
829
+ globalThis.clearTimeout(timeoutId);
830
+ timeoutId = void 0;
831
+ }
832
+ }
833
+ function startTracking() {
834
+ stopTracking();
835
+ if (!IN_BROWSER) return;
836
+ trackingId = globalThis.setInterval(() => {
837
+ if (!isActive.value || isPaused.value) return;
838
+ const elapsed = Date.now() - startedAt;
839
+ remaining.value = Math.max(0, budget - elapsed);
840
+ }, 100);
841
+ }
842
+ function stopTracking() {
843
+ if (!/* @__PURE__ */ isUndefined(trackingId)) {
844
+ globalThis.clearInterval(trackingId);
845
+ trackingId = void 0;
846
+ }
847
+ }
848
+ function fire() {
849
+ clearTimer();
850
+ stopTracking();
851
+ handler();
852
+ if (repeat) begin(duration);
853
+ else {
854
+ isActive.value = false;
855
+ remaining.value = 0;
856
+ }
857
+ }
858
+ function begin(ms) {
859
+ clearTimer();
860
+ stopTracking();
861
+ budget = ms;
862
+ startedAt = Date.now();
863
+ remaining.value = ms;
864
+ isActive.value = true;
865
+ isPaused.value = false;
866
+ timeoutId = globalThis.setTimeout(fire, ms);
867
+ startTracking();
868
+ }
869
+ function start() {
870
+ if (duration < 0) return;
871
+ begin(duration);
872
+ }
873
+ function stop() {
874
+ clearTimer();
875
+ stopTracking();
876
+ isActive.value = false;
877
+ isPaused.value = false;
878
+ remaining.value = duration;
879
+ }
880
+ function pause() {
881
+ if (!isActive.value || isPaused.value) return;
882
+ const elapsed = Date.now() - startedAt;
883
+ budget = Math.max(0, budget - elapsed);
884
+ remaining.value = budget;
885
+ clearTimer();
886
+ stopTracking();
887
+ isPaused.value = true;
888
+ }
889
+ function resume() {
890
+ if (!isPaused.value) return;
891
+ isPaused.value = false;
892
+ startedAt = Date.now();
893
+ timeoutId = globalThis.setTimeout(fire, budget);
894
+ startTracking();
895
+ }
896
+ onScopeDispose(() => {
897
+ clearTimer();
898
+ stopTracking();
899
+ }, true);
900
+ return {
901
+ start,
902
+ stop,
903
+ pause,
904
+ resume,
905
+ remaining,
906
+ isActive,
907
+ isPaused
908
+ };
909
+ }
910
+ //#endregion
784
911
  //#region src/composables/toReactive/index.ts
785
912
  /**
786
913
  * @module toReactive
@@ -1010,24 +1137,22 @@ function createBreakpoints(_options = {}) {
1010
1137
  const mdAndUp = shallowRef(initialIndex >= 2);
1011
1138
  const lgAndUp = shallowRef(initialIndex >= 3);
1012
1139
  const xlAndUp = shallowRef(initialIndex >= 4);
1013
- const xxlAndUp = shallowRef(initialIndex >= 5);
1014
1140
  const smAndDown = shallowRef(initialIndex <= 1);
1015
1141
  const mdAndDown = shallowRef(initialIndex <= 2);
1016
1142
  const lgAndDown = shallowRef(initialIndex <= 3);
1017
1143
  const xlAndDown = shallowRef(initialIndex <= 4);
1018
- const xxlAndDown = shallowRef(initialIndex <= 5);
1019
1144
  function update() {
1020
1145
  if (!IN_BROWSER) return;
1021
1146
  width.value = window.innerWidth;
1022
1147
  height.value = window.innerHeight;
1023
1148
  let current = "xs";
1024
- for (let i = sorted.length - 1; i >= 0; i--) if (width.value >= sorted[i][1]) {
1149
+ for (let i = sorted.length - 1; i >= 0; i--) if (window.matchMedia(`(min-width: ${sorted[i][1]}px)`).matches) {
1025
1150
  current = sorted[i][0];
1026
1151
  break;
1027
1152
  }
1028
1153
  name.value = current;
1029
1154
  const index = names.indexOf(current);
1030
- isMobile.value = width.value < mb;
1155
+ isMobile.value = /* @__PURE__ */ isNumber(mb) ? !window.matchMedia(`(min-width: ${mb}px)`).matches : index < names.indexOf(mobileBreakpoint);
1031
1156
  xs.value = index === 0;
1032
1157
  sm.value = index === 1;
1033
1158
  md.value = index === 2;
@@ -1038,12 +1163,10 @@ function createBreakpoints(_options = {}) {
1038
1163
  mdAndUp.value = index >= 2;
1039
1164
  lgAndUp.value = index >= 3;
1040
1165
  xlAndUp.value = index >= 4;
1041
- xxlAndUp.value = index >= 5;
1042
1166
  smAndDown.value = index <= 1;
1043
1167
  mdAndDown.value = index <= 2;
1044
1168
  lgAndDown.value = index <= 3;
1045
1169
  xlAndDown.value = index <= 4;
1046
- xxlAndDown.value = index <= 5;
1047
1170
  }
1048
1171
  return {
1049
1172
  breakpoints,
@@ -1062,12 +1185,10 @@ function createBreakpoints(_options = {}) {
1062
1185
  mdAndUp: readonly(mdAndUp),
1063
1186
  lgAndUp: readonly(lgAndUp),
1064
1187
  xlAndUp: readonly(xlAndUp),
1065
- xxlAndUp: readonly(xxlAndUp),
1066
1188
  smAndDown: readonly(smAndDown),
1067
1189
  mdAndDown: readonly(mdAndDown),
1068
1190
  lgAndDown: readonly(lgAndDown),
1069
1191
  xlAndDown: readonly(xlAndDown),
1070
- xxlAndDown: readonly(xxlAndDown),
1071
1192
  ssr: isSSR,
1072
1193
  update
1073
1194
  };
@@ -1081,8 +1202,8 @@ function createBreakpointsFallback(options = {}) {
1081
1202
  name: readonly(shallowRef("xs")),
1082
1203
  width: readonly(shallowRef(0)),
1083
1204
  height: readonly(shallowRef(0)),
1084
- isMobile: readonly(shallowRef(false)),
1085
- xs: readonly(shallowRef(false)),
1205
+ isMobile: readonly(shallowRef(true)),
1206
+ xs: readonly(shallowRef(true)),
1086
1207
  sm: readonly(shallowRef(false)),
1087
1208
  md: readonly(shallowRef(false)),
1088
1209
  lg: readonly(shallowRef(false)),
@@ -1092,12 +1213,10 @@ function createBreakpointsFallback(options = {}) {
1092
1213
  mdAndUp: readonly(shallowRef(false)),
1093
1214
  lgAndUp: readonly(shallowRef(false)),
1094
1215
  xlAndUp: readonly(shallowRef(false)),
1095
- xxlAndUp: readonly(shallowRef(false)),
1096
- smAndDown: readonly(shallowRef(false)),
1097
- mdAndDown: readonly(shallowRef(false)),
1098
- lgAndDown: readonly(shallowRef(false)),
1099
- xlAndDown: readonly(shallowRef(false)),
1100
- xxlAndDown: readonly(shallowRef(false)),
1216
+ smAndDown: readonly(shallowRef(true)),
1217
+ mdAndDown: readonly(shallowRef(true)),
1218
+ lgAndDown: readonly(shallowRef(true)),
1219
+ xlAndDown: readonly(shallowRef(true)),
1101
1220
  ssr: false,
1102
1221
  update: () => {}
1103
1222
  };
@@ -2078,11 +2197,16 @@ function useElementIntersection(target, options = {}) {
2078
2197
  * ```
2079
2198
  */
2080
2199
  function useLazy(active, options = {}) {
2081
- const { eager = false } = options;
2200
+ const { eager = false, delay = 0 } = options;
2082
2201
  const isBooted = shallowRef(false);
2083
2202
  const hasContent = toRef(() => isBooted.value || toValue(eager) || toValue(active));
2203
+ const timer = delay > 0 ? useTimer(() => {
2204
+ isBooted.value = true;
2205
+ }, { duration: delay }) : void 0;
2084
2206
  const stop = watch(() => toValue(active), (value) => {
2085
- if (value) isBooted.value = true;
2207
+ if (value) if (timer) timer.start();
2208
+ else isBooted.value = true;
2209
+ else timer?.stop();
2086
2210
  }, { immediate: true });
2087
2211
  function reset() {
2088
2212
  isBooted.value = false;
@@ -2143,7 +2267,7 @@ function useLazy(active, options = {}) {
2143
2267
  function useMediaQuery(query) {
2144
2268
  const matches = shallowRef(false);
2145
2269
  const mediaQueryList = shallowRef(null);
2146
- const resolvedQuery = computed(() => toValue(query));
2270
+ const resolvedQuery = toRef(() => toValue(query));
2147
2271
  const hydration = useHydration();
2148
2272
  let cleanup = null;
2149
2273
  function update() {
@@ -2935,83 +3059,6 @@ function useNested(namespace = "v0:nested") {
2935
3059
  return useContext(namespace);
2936
3060
  }
2937
3061
  //#endregion
2938
- //#region src/composables/usePopover/index.ts
2939
- /**
2940
- * @module usePopover
2941
- *
2942
- * @remarks
2943
- * Composable for native popover API behavior with CSS anchor positioning.
2944
- * Manages open/close state, anchor styles, content attributes, and
2945
- * bidirectional sync between reactive state and native popover events.
2946
- *
2947
- * Key features:
2948
- * - Native popover API (showPopover/hidePopover)
2949
- * - CSS anchor positioning (position-area, position-try-fallbacks)
2950
- * - Toggle event sync for native state changes
2951
- * - SSR-safe (no DOM ops outside browser)
2952
- * - Optional external isOpen ref for v-model integration
2953
- *
2954
- * Perfect for building select, combobox, tooltip, and menu components
2955
- * without wrapping the Popover compound component.
2956
- */
2957
- function usePopover(options = {}) {
2958
- const { id: _id, positionArea = "bottom", positionTry = "most-width bottom" } = options;
2959
- const id = _id ?? /* @__PURE__ */ useId$1();
2960
- const isOpen = options.isOpen ?? shallowRef(false);
2961
- function open() {
2962
- isOpen.value = true;
2963
- }
2964
- function close() {
2965
- isOpen.value = false;
2966
- }
2967
- function toggle() {
2968
- isOpen.value = !isOpen.value;
2969
- }
2970
- const anchorStyles = toRef(() => ({ anchorName: `--${id}` }));
2971
- const contentAttrs = toRef(() => ({
2972
- id,
2973
- popover: ""
2974
- }));
2975
- const contentStyles = toRef(() => ({
2976
- "position": "fixed",
2977
- "margin": "unset",
2978
- "inset-area": positionArea,
2979
- "position-area": positionArea,
2980
- "position-anchor": `--${id}`,
2981
- "position-try-fallbacks": positionTry
2982
- }));
2983
- /* v8 ignore start -- browser popover API */
2984
- function attach(el) {
2985
- onMounted(() => {
2986
- const element = toValue(el);
2987
- if (isOpen.value) element?.showPopover();
2988
- });
2989
- watch(isOpen, (value) => {
2990
- const element = toValue(el);
2991
- if (!element?.isConnected) return;
2992
- if (value === element.matches?.(":popover-open")) return;
2993
- if (value) element.showPopover?.();
2994
- else element.hidePopover?.();
2995
- });
2996
- useEventListener(el, "toggle", (e) => {
2997
- if (!toValue(el)?.isConnected) return;
2998
- isOpen.value = e.newState === "open";
2999
- });
3000
- }
3001
- /* v8 ignore stop */
3002
- return {
3003
- isOpen,
3004
- id,
3005
- open,
3006
- close,
3007
- toggle,
3008
- anchorStyles,
3009
- contentAttrs,
3010
- contentStyles,
3011
- attach
3012
- };
3013
- }
3014
- //#endregion
3015
3062
  //#region src/composables/createQueue/index.ts
3016
3063
  /**
3017
3064
  * @module createQueue
@@ -3065,21 +3112,22 @@ function createQueue(_options = {}) {
3065
3112
  ...options,
3066
3113
  events: true
3067
3114
  });
3068
- const timeouts = /* @__PURE__ */ new Map();
3069
- function startTimeout(ticket) {
3115
+ const timers = /* @__PURE__ */ new Map();
3116
+ function createTicketTimer(ticket) {
3070
3117
  if (/* @__PURE__ */ isUndefined(ticket.timeout) || ticket.timeout < 0 || ticket.isPaused) return;
3071
- const timeout = setTimeout(() => {
3072
- timeouts.delete(ticket.id);
3118
+ const timer = useTimer(() => {
3119
+ timers.delete(ticket.id);
3073
3120
  registry.unregister(ticket.id);
3074
3121
  resume();
3075
- }, ticket.timeout);
3076
- timeouts.set(ticket.id, timeout);
3077
- }
3078
- function clearTimeout(id) {
3079
- const timeout = timeouts.get(id);
3080
- if (timeout) {
3081
- globalThis.clearTimeout(timeout);
3082
- timeouts.delete(id);
3122
+ }, { duration: ticket.timeout });
3123
+ timers.set(ticket.id, timer);
3124
+ timer.start();
3125
+ }
3126
+ function stopTimer(id) {
3127
+ const timer = timers.get(id);
3128
+ if (timer) {
3129
+ timer.stop();
3130
+ timers.delete(id);
3083
3131
  }
3084
3132
  }
3085
3133
  function register(registration = {}) {
@@ -3093,14 +3141,14 @@ function createQueue(_options = {}) {
3093
3141
  dismiss: () => unregister(id)
3094
3142
  };
3095
3143
  const registered = registry.register(ticket);
3096
- startTimeout(registered);
3144
+ createTicketTimer(registered);
3097
3145
  return registered;
3098
3146
  }
3099
3147
  function unregister(id) {
3100
3148
  const ticket = /* @__PURE__ */ isUndefined(id) ? registry.seek("first") : registry.get(id);
3101
3149
  if (!ticket) return void 0;
3102
3150
  const wasFirst = ticket.index === 0;
3103
- clearTimeout(ticket.id);
3151
+ stopTimer(ticket.id);
3104
3152
  registry.unregister(ticket.id);
3105
3153
  if (wasFirst) resume();
3106
3154
  return ticket;
@@ -3111,7 +3159,7 @@ function createQueue(_options = {}) {
3111
3159
  const ticket = registry.get(id);
3112
3160
  if (!ticket) continue;
3113
3161
  if (ticket.index === 0) hadFirst = true;
3114
- clearTimeout(ticket.id);
3162
+ stopTimer(ticket.id);
3115
3163
  }
3116
3164
  registry.offboard(ids);
3117
3165
  if (hadFirst) resume();
@@ -3119,18 +3167,21 @@ function createQueue(_options = {}) {
3119
3167
  function pause() {
3120
3168
  const ticket = registry.seek("first");
3121
3169
  if (!ticket || ticket.isPaused) return void 0;
3122
- clearTimeout(ticket.id);
3170
+ timers.get(ticket.id)?.pause();
3123
3171
  return registry.upsert(ticket.id, { isPaused: true });
3124
3172
  }
3125
3173
  function resume() {
3126
3174
  const ticket = registry.seek("first");
3127
3175
  if (!ticket || ticket.index !== 0 || !ticket.isPaused) return void 0;
3128
3176
  const updated = registry.upsert(ticket.id, { isPaused: false });
3129
- startTimeout(updated);
3177
+ const timer = timers.get(updated.id);
3178
+ if (timer) timer.start();
3179
+ else createTicketTimer(updated);
3130
3180
  return updated;
3131
3181
  }
3132
3182
  function clear() {
3133
- for (const id of timeouts.keys()) clearTimeout(id);
3183
+ for (const timer of timers.values()) timer.stop();
3184
+ timers.clear();
3134
3185
  registry.clear();
3135
3186
  }
3136
3187
  function dispose() {
@@ -3205,6 +3256,679 @@ function useQueue(namespace = "v0:queue") {
3205
3256
  return useContext(namespace);
3206
3257
  }
3207
3258
  //#endregion
3259
+ //#region src/composables/useNotifications/index.ts
3260
+ /**
3261
+ * @module useNotifications
3262
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications
3263
+ *
3264
+ * @remarks
3265
+ * Notification management composable built on createRegistry and createQueue.
3266
+ * Registry stores the full notification lifecycle (permanent record).
3267
+ * Queue manages the display surface (toasts) with FIFO ordering and auto-dismiss.
3268
+ *
3269
+ * Supports:
3270
+ * - Push notifications with severity levels and configurable timeouts
3271
+ * - State mutations: read, seen, archived, snoozed
3272
+ * - Bulk operations: readAll, archiveAll, clear
3273
+ * - Toast queue with pause/resume and auto-dismiss
3274
+ * - Adapter integration via event system
3275
+ * - Plugin installation via createNotificationsPlugin
3276
+ */
3277
+ function createNotifications(options = {}) {
3278
+ const { timeout = 3e3, ...registryOptions } = options;
3279
+ const registry = createRegistry({
3280
+ ...registryOptions,
3281
+ events: true,
3282
+ reactive: true
3283
+ });
3284
+ const queue = createQueue({
3285
+ timeout,
3286
+ events: true,
3287
+ reactive: true
3288
+ });
3289
+ registry.on("unregister:ticket", (ticket) => {
3290
+ if (queue.has(ticket.id)) queue.unregister(ticket.id);
3291
+ });
3292
+ /**
3293
+ * Build a full {@link NotificationTicket} from raw input
3294
+ *
3295
+ * @param input The notification input to hydrate.
3296
+ * @returns A partial ticket with timestamps, lifecycle methods, and an ID.
3297
+ * @internal Used by {@link send}, {@link register}, and {@link onboard}.
3298
+ */
3299
+ function hydrate(input) {
3300
+ const id = input.id ?? /* @__PURE__ */ useId$1();
3301
+ const now = /* @__PURE__ */ new Date();
3302
+ return {
3303
+ ...input,
3304
+ id,
3305
+ createdAt: now,
3306
+ readAt: null,
3307
+ seenAt: null,
3308
+ archivedAt: null,
3309
+ snoozedUntil: null,
3310
+ read: () => read(id),
3311
+ unread: () => unread(id),
3312
+ seen: () => seen(id),
3313
+ archive: () => archive(id),
3314
+ unarchive: () => unarchive(id),
3315
+ snooze: (until) => snooze(id, until),
3316
+ wake: () => wake(id),
3317
+ dismiss: () => queue.unregister(id)
3318
+ };
3319
+ }
3320
+ /**
3321
+ * Create a notification and enqueue it for toast display
3322
+ *
3323
+ * @param input The notification input to create.
3324
+ * @returns The hydrated notification ticket.
3325
+ * @remarks Hydrates the input with timestamps and lifecycle methods, registers
3326
+ * it in the registry, adds it to the display queue, and emits
3327
+ * `notification:received`. The ticket auto-dismisses after the configured
3328
+ * timeout unless paused.
3329
+ *
3330
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#send
3331
+ *
3332
+ * @example
3333
+ * ```ts
3334
+ * import { useNotifications } from '@vuetify/v0'
3335
+ *
3336
+ * const notifications = useNotifications()
3337
+ *
3338
+ * // Basic toast
3339
+ * notifications.send({ subject: 'Changes saved', severity: 'success' })
3340
+ *
3341
+ * // With custom timeout
3342
+ * const ticket = notifications.send({ subject: 'Connection lost', severity: 'error', timeout: 10000 })
3343
+ *
3344
+ * console.log(ticket.id) // 'generated-id'
3345
+ * console.log(ticket.createdAt) // Date
3346
+ * console.log(ticket.readAt) // null
3347
+ *
3348
+ * // Ticket convenience methods
3349
+ * ticket.read() // marks as read
3350
+ * ticket.dismiss() // removes from toast queue, keeps in registry
3351
+ * ```
3352
+ */
3353
+ function send(input) {
3354
+ const ticket = registry.register(hydrate(input));
3355
+ queue.register(/* @__PURE__ */ isUndefined(input.timeout) ? { id: ticket.id } : {
3356
+ id: ticket.id,
3357
+ timeout: input.timeout
3358
+ });
3359
+ registry.emit("notification:received", ticket);
3360
+ return ticket;
3361
+ }
3362
+ /**
3363
+ * Register a notification in the registry without adding it to the toast queue
3364
+ *
3365
+ * @param input The notification input to register.
3366
+ * @returns The hydrated notification ticket.
3367
+ * @remarks Overrides the base registry `register` to hydrate the input with
3368
+ * timestamps and lifecycle methods. Use for historical or pre-existing items
3369
+ * that should appear in an inbox but not pop up as toasts.
3370
+ *
3371
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#register
3372
+ *
3373
+ * @example
3374
+ * ```ts
3375
+ * import { useNotifications } from '@vuetify/v0'
3376
+ *
3377
+ * const notifications = useNotifications()
3378
+ *
3379
+ * // Register a historical item (appears in inbox, not as toast)
3380
+ * const ticket = notifications.register({ id: 'old-1', subject: 'Deployed v2.1' })
3381
+ *
3382
+ * console.log(ticket.createdAt) // Date
3383
+ * console.log(ticket.readAt) // null
3384
+ *
3385
+ * // Lifecycle methods work the same as send()
3386
+ * ticket.read()
3387
+ * ticket.archive()
3388
+ * ```
3389
+ */
3390
+ function register(input) {
3391
+ return registry.register(hydrate(input));
3392
+ }
3393
+ /**
3394
+ * Bulk version of {@link register}
3395
+ *
3396
+ * @param inputs Array of notification inputs to register.
3397
+ * @returns Array of hydrated notification tickets.
3398
+ * @remarks Registers multiple notifications into the registry without toast
3399
+ * display. Wraps all registrations in a single `registry.batch()` call so
3400
+ * reactive updates are deferred until the entire batch completes.
3401
+ *
3402
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#onboard
3403
+ *
3404
+ * @example
3405
+ * ```ts
3406
+ * import { useNotifications } from '@vuetify/v0'
3407
+ *
3408
+ * const notifications = useNotifications()
3409
+ *
3410
+ * // Load historical items on mount
3411
+ * const tickets = notifications.onboard([
3412
+ * { id: 'n1', subject: 'Welcome to the team' },
3413
+ * { id: 'n2', subject: 'Setup complete', severity: 'success' },
3414
+ * ])
3415
+ *
3416
+ * console.log(tickets.length) // 2
3417
+ * console.log(notifications.queue.values()) // [] (no toasts)
3418
+ * console.log(notifications.values().length) // 2 (in registry)
3419
+ * ```
3420
+ */
3421
+ function onboard(inputs) {
3422
+ return registry.batch(() => inputs.map((input) => register(input)));
3423
+ }
3424
+ /**
3425
+ * Mark a notification as read
3426
+ *
3427
+ * @param id The ID of the notification to mark as read.
3428
+ * @remarks Sets `readAt` to the current time and emits `notification:read`.
3429
+ * Adapters listen to this event for outbound sync.
3430
+ *
3431
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#read
3432
+ *
3433
+ * @example
3434
+ * ```ts
3435
+ * import { useNotifications } from '@vuetify/v0'
3436
+ *
3437
+ * const notifications = useNotifications()
3438
+ *
3439
+ * const ticket = notifications.send({ subject: 'New message' })
3440
+ *
3441
+ * notifications.read(ticket.id)
3442
+ * console.log(ticket.readAt) // Date
3443
+ *
3444
+ * // Or via ticket convenience method
3445
+ * ticket.read()
3446
+ * ```
3447
+ */
3448
+ function read(id) {
3449
+ registry.upsert(id, { readAt: /* @__PURE__ */ new Date() }, "notification:read");
3450
+ }
3451
+ /**
3452
+ * Mark a notification as unread
3453
+ *
3454
+ * @param id The ID of the notification to mark as unread.
3455
+ * @remarks Clears `readAt` and emits `notification:unread`.
3456
+ *
3457
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#unread
3458
+ *
3459
+ * @example
3460
+ * ```ts
3461
+ * import { useNotifications } from '@vuetify/v0'
3462
+ *
3463
+ * const notifications = useNotifications()
3464
+ *
3465
+ * notifications.unread('notif-1')
3466
+ * ```
3467
+ */
3468
+ function unread(id) {
3469
+ registry.upsert(id, { readAt: null }, "notification:unread");
3470
+ }
3471
+ /**
3472
+ * Mark a notification as seen
3473
+ *
3474
+ * @param id The ID of the notification to mark as seen.
3475
+ * @remarks Sets `seenAt` to the current time and emits `notification:seen`.
3476
+ * Distinct from read — seen tracks whether the notification appeared in the
3477
+ * user's viewport, while read indicates the user actively engaged with it.
3478
+ *
3479
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#seen
3480
+ *
3481
+ * @example
3482
+ * ```ts
3483
+ * import { useNotifications } from '@vuetify/v0'
3484
+ *
3485
+ * const notifications = useNotifications()
3486
+ *
3487
+ * // Mark as seen when visible in inbox viewport
3488
+ * notifications.seen('notif-1')
3489
+ * ```
3490
+ */
3491
+ function seen(id) {
3492
+ registry.upsert(id, { seenAt: /* @__PURE__ */ new Date() }, "notification:seen");
3493
+ }
3494
+ /**
3495
+ * Archive a notification
3496
+ *
3497
+ * @param id The ID of the notification to archive.
3498
+ * @remarks Sets `archivedAt` to the current time and emits `notification:archived`.
3499
+ *
3500
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#archive
3501
+ *
3502
+ * @example
3503
+ * ```ts
3504
+ * import { useNotifications } from '@vuetify/v0'
3505
+ *
3506
+ * const notifications = useNotifications()
3507
+ *
3508
+ * notifications.archive('notif-1')
3509
+ * ```
3510
+ */
3511
+ function archive(id) {
3512
+ registry.upsert(id, { archivedAt: /* @__PURE__ */ new Date() }, "notification:archived");
3513
+ }
3514
+ /**
3515
+ * Restore an archived notification
3516
+ *
3517
+ * @param id The ID of the notification to unarchive.
3518
+ * @remarks Clears `archivedAt` and emits `notification:unarchived`.
3519
+ *
3520
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#unarchive
3521
+ *
3522
+ * @example
3523
+ * ```ts
3524
+ * import { useNotifications } from '@vuetify/v0'
3525
+ *
3526
+ * const notifications = useNotifications()
3527
+ *
3528
+ * notifications.unarchive('notif-1')
3529
+ * ```
3530
+ */
3531
+ function unarchive(id) {
3532
+ registry.upsert(id, { archivedAt: null }, "notification:unarchived");
3533
+ }
3534
+ /**
3535
+ * Snooze a notification until a given time
3536
+ *
3537
+ * @param id The ID of the notification to snooze.
3538
+ * @param until The time at which the snooze expires.
3539
+ * @remarks Sets `snoozedUntil` and emits `notification:snoozed`. The composable
3540
+ * does not auto-wake — consumers are responsible for calling {@link wake} when
3541
+ * the snooze expires (e.g., via a timer or server push).
3542
+ *
3543
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#snooze
3544
+ *
3545
+ * @example
3546
+ * ```ts
3547
+ * import { useNotifications } from '@vuetify/v0'
3548
+ *
3549
+ * const notifications = useNotifications()
3550
+ *
3551
+ * const tomorrow = new Date(Date.now() + 86_400_000)
3552
+ * notifications.snooze('notif-1', tomorrow)
3553
+ * ```
3554
+ */
3555
+ function snooze(id, until) {
3556
+ registry.upsert(id, { snoozedUntil: until }, "notification:snoozed");
3557
+ }
3558
+ /**
3559
+ * Cancel a snooze
3560
+ *
3561
+ * @param id The ID of the notification to wake.
3562
+ * @remarks Clears `snoozedUntil` and emits `notification:unsnoozed`.
3563
+ *
3564
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#wake
3565
+ *
3566
+ * @example
3567
+ * ```ts
3568
+ * import { useNotifications } from '@vuetify/v0'
3569
+ *
3570
+ * const notifications = useNotifications()
3571
+ *
3572
+ * notifications.wake('notif-1')
3573
+ * ```
3574
+ */
3575
+ function wake(id) {
3576
+ registry.upsert(id, { snoozedUntil: null }, "notification:unsnoozed");
3577
+ }
3578
+ /**
3579
+ * Mark all unread notifications as read
3580
+ *
3581
+ * @remarks Iterates all notifications and marks unread ones as read in a single
3582
+ * batch. Skips already-read notifications to preserve their original `readAt`
3583
+ * timestamp. Emits `notification:read` for each affected notification.
3584
+ *
3585
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#readall
3586
+ *
3587
+ * @example
3588
+ * ```ts
3589
+ * import { useNotifications } from '@vuetify/v0'
3590
+ *
3591
+ * const notifications = useNotifications()
3592
+ *
3593
+ * notifications.send({ subject: 'Message 1' })
3594
+ * notifications.send({ subject: 'Message 2' })
3595
+ *
3596
+ * notifications.readAll()
3597
+ *
3598
+ * console.log(notifications.values().every(t => t.readAt !== null)) // true
3599
+ * ```
3600
+ */
3601
+ function readAll() {
3602
+ const now = /* @__PURE__ */ new Date();
3603
+ registry.batch(() => {
3604
+ for (const ticket of registry.values()) if (/* @__PURE__ */ isNull(ticket.readAt)) registry.upsert(ticket.id, { readAt: now }, "notification:read");
3605
+ });
3606
+ }
3607
+ /**
3608
+ * Archive all unarchived notifications
3609
+ *
3610
+ * @remarks Iterates all notifications and archives unarchived ones in a single
3611
+ * batch. Skips already-archived notifications to preserve their original
3612
+ * `archivedAt` timestamp. Emits `notification:archived` for each affected notification.
3613
+ *
3614
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications#archiveall
3615
+ *
3616
+ * @example
3617
+ * ```ts
3618
+ * import { useNotifications } from '@vuetify/v0'
3619
+ *
3620
+ * const notifications = useNotifications()
3621
+ *
3622
+ * notifications.send({ subject: 'Alert 1' })
3623
+ * notifications.send({ subject: 'Alert 2' })
3624
+ *
3625
+ * notifications.archiveAll()
3626
+ *
3627
+ * console.log(notifications.values().every(t => t.archivedAt !== null)) // true
3628
+ * ```
3629
+ */
3630
+ function archiveAll() {
3631
+ const now = /* @__PURE__ */ new Date();
3632
+ registry.batch(() => {
3633
+ for (const ticket of registry.values()) if (/* @__PURE__ */ isNull(ticket.archivedAt)) registry.upsert(ticket.id, { archivedAt: now }, "notification:archived");
3634
+ });
3635
+ }
3636
+ return {
3637
+ ...registry,
3638
+ send,
3639
+ register,
3640
+ onboard,
3641
+ queue,
3642
+ read,
3643
+ unread,
3644
+ seen,
3645
+ archive,
3646
+ unarchive,
3647
+ snooze,
3648
+ wake,
3649
+ readAll,
3650
+ archiveAll,
3651
+ get size() {
3652
+ return registry.size;
3653
+ }
3654
+ };
3655
+ }
3656
+ function noop() {}
3657
+ const EMPTY = [];
3658
+ function createNotificationsFallback() {
3659
+ const stub = {
3660
+ id: "",
3661
+ index: 0,
3662
+ value: 0,
3663
+ valueIsIndex: true,
3664
+ createdAt: /* @__PURE__ */ new Date(0),
3665
+ readAt: null,
3666
+ seenAt: null,
3667
+ archivedAt: null,
3668
+ snoozedUntil: null,
3669
+ read: noop,
3670
+ unread: noop,
3671
+ seen: noop,
3672
+ archive: noop,
3673
+ unarchive: noop,
3674
+ snooze: noop,
3675
+ wake: noop,
3676
+ dismiss: noop,
3677
+ unregister: noop
3678
+ };
3679
+ return {
3680
+ collection: /* @__PURE__ */ new Map(),
3681
+ size: 0,
3682
+ send: () => stub,
3683
+ queue: {
3684
+ collection: /* @__PURE__ */ new Map(),
3685
+ size: 0,
3686
+ register: () => ({}),
3687
+ unregister: () => void 0,
3688
+ has: () => false,
3689
+ get: () => void 0,
3690
+ keys: () => EMPTY,
3691
+ values: () => EMPTY,
3692
+ entries: () => EMPTY,
3693
+ browse: () => void 0,
3694
+ lookup: () => void 0,
3695
+ upsert: () => ({}),
3696
+ seek: () => void 0,
3697
+ move: () => void 0,
3698
+ on: noop,
3699
+ off: noop,
3700
+ emit: noop,
3701
+ dispose: noop,
3702
+ clear: noop,
3703
+ reindex: noop,
3704
+ batch: (fn) => fn(),
3705
+ onboard: () => EMPTY,
3706
+ offboard: noop,
3707
+ pause: () => void 0,
3708
+ resume: () => void 0
3709
+ },
3710
+ read: noop,
3711
+ unread: noop,
3712
+ seen: noop,
3713
+ archive: noop,
3714
+ unarchive: noop,
3715
+ snooze: noop,
3716
+ wake: noop,
3717
+ readAll: noop,
3718
+ archiveAll: noop,
3719
+ clear: noop,
3720
+ has: () => false,
3721
+ get: () => void 0,
3722
+ keys: () => EMPTY,
3723
+ values: () => EMPTY,
3724
+ entries: () => EMPTY,
3725
+ browse: () => void 0,
3726
+ lookup: () => void 0,
3727
+ upsert: () => stub,
3728
+ register: () => stub,
3729
+ unregister: noop,
3730
+ reindex: noop,
3731
+ move: () => void 0,
3732
+ seek: () => void 0,
3733
+ on: noop,
3734
+ off: noop,
3735
+ emit: noop,
3736
+ dispose: noop,
3737
+ batch: (fn) => fn(),
3738
+ onboard: () => EMPTY,
3739
+ offboard: noop
3740
+ };
3741
+ }
3742
+ /**
3743
+ * Notification management with registry, event system, and optional adapters.
3744
+ *
3745
+ * @see https://0.vuetifyjs.com/composables/plugins/use-notifications
3746
+ *
3747
+ * @example
3748
+ * ```ts
3749
+ * import { createNotificationsPlugin, useNotifications } from '@vuetify/v0'
3750
+ *
3751
+ * // Install as plugin
3752
+ * app.use(createNotificationsPlugin())
3753
+ *
3754
+ * // Use in components
3755
+ * const notifications = useNotifications()
3756
+ * notifications.send({ subject: 'Saved', severity: 'success' })
3757
+ * ```
3758
+ */
3759
+ const [createNotificationsContext, createNotificationsPlugin, useNotifications] = createPluginContext("v0:notifications", (options) => createNotifications(options), {
3760
+ fallback: () => createNotificationsFallback(),
3761
+ setup: (context, app, options) => {
3762
+ app.onUnmount(() => {
3763
+ context.dispose();
3764
+ context.queue.dispose();
3765
+ });
3766
+ const { adapter } = options;
3767
+ if (!adapter) return;
3768
+ adapter.setup({
3769
+ send: context.send,
3770
+ register: context.register,
3771
+ on: context.on,
3772
+ off: context.off
3773
+ });
3774
+ if (/* @__PURE__ */ isFunction(adapter.dispose)) app.onUnmount(() => adapter.dispose());
3775
+ }
3776
+ });
3777
+ //#endregion
3778
+ //#region src/composables/usePopover/index.ts
3779
+ /**
3780
+ * @module usePopover
3781
+ *
3782
+ * @remarks
3783
+ * Composable for native popover API behavior with CSS anchor positioning.
3784
+ * Manages open/close state, anchor styles, content attributes, and
3785
+ * bidirectional sync between reactive state and native popover events.
3786
+ *
3787
+ * Key features:
3788
+ * - Native popover API (showPopover/hidePopover)
3789
+ * - CSS anchor positioning (position-area, position-try-fallbacks)
3790
+ * - Toggle event sync for native state changes
3791
+ * - SSR-safe (no DOM ops outside browser)
3792
+ * - Optional external isOpen ref for v-model integration
3793
+ *
3794
+ * Perfect for building select, combobox, tooltip, and menu components
3795
+ * without wrapping the Popover compound component.
3796
+ */
3797
+ function usePopover(options = {}) {
3798
+ const { id: _id, positionArea = "bottom", positionTry = "most-width bottom", showDelay = 0, hideDelay = 0 } = options;
3799
+ const id = _id ?? /* @__PURE__ */ useId$1();
3800
+ const isOpen = options.isOpen ?? shallowRef(false);
3801
+ const showTimer = showDelay > 0 ? useTimer(() => {
3802
+ isOpen.value = true;
3803
+ }, { duration: showDelay }) : void 0;
3804
+ const hideTimer = hideDelay > 0 ? useTimer(() => {
3805
+ isOpen.value = false;
3806
+ }, { duration: hideDelay }) : void 0;
3807
+ function open() {
3808
+ hideTimer?.stop();
3809
+ if (showTimer) showTimer.start();
3810
+ else isOpen.value = true;
3811
+ }
3812
+ function close() {
3813
+ showTimer?.stop();
3814
+ if (hideTimer) hideTimer.start();
3815
+ else isOpen.value = false;
3816
+ }
3817
+ function toggle() {
3818
+ if (isOpen.value) close();
3819
+ else open();
3820
+ }
3821
+ const anchorStyles = toRef(() => ({ anchorName: `--${id}` }));
3822
+ const contentAttrs = toRef(() => ({
3823
+ id,
3824
+ popover: ""
3825
+ }));
3826
+ const contentStyles = toRef(() => ({
3827
+ "position": "fixed",
3828
+ "margin": "unset",
3829
+ "inset-area": positionArea,
3830
+ "position-area": positionArea,
3831
+ "position-anchor": `--${id}`,
3832
+ "position-try-fallbacks": positionTry
3833
+ }));
3834
+ /* v8 ignore start -- browser popover API */
3835
+ function attach(el) {
3836
+ onMounted(() => {
3837
+ const element = toValue(el);
3838
+ if (isOpen.value) element?.showPopover();
3839
+ });
3840
+ watch(isOpen, (value) => {
3841
+ const element = toValue(el);
3842
+ if (!element?.isConnected) return;
3843
+ if (value === element.matches?.(":popover-open")) return;
3844
+ if (value) element.showPopover?.();
3845
+ else element.hidePopover?.();
3846
+ });
3847
+ useEventListener(el, "toggle", (e) => {
3848
+ if (!toValue(el)?.isConnected) return;
3849
+ isOpen.value = e.newState === "open";
3850
+ });
3851
+ }
3852
+ /* v8 ignore stop */
3853
+ return {
3854
+ isOpen,
3855
+ id,
3856
+ open,
3857
+ close,
3858
+ toggle,
3859
+ anchorStyles,
3860
+ contentAttrs,
3861
+ contentStyles,
3862
+ attach
3863
+ };
3864
+ }
3865
+ //#endregion
3866
+ //#region src/composables/useRaf/index.ts
3867
+ /**
3868
+ * @module useRaf
3869
+ *
3870
+ * @see https://0.vuetifyjs.com/composables/system/use-raf
3871
+ *
3872
+ * @remarks
3873
+ * Scope-disposed safe requestAnimationFrame composable.
3874
+ *
3875
+ * Key features:
3876
+ * - Cancel-then-request pattern (deduplicates rapid calls)
3877
+ * - Automatic cleanup on scope disposal
3878
+ * - SSR-safe (no-op in non-browser environments)
3879
+ * - Callable function with cancel method
3880
+ *
3881
+ * Perfect for throttling updates to the next animation frame.
3882
+ */
3883
+ /**
3884
+ * Scope-disposed safe requestAnimationFrame.
3885
+ *
3886
+ * @param callback Function to call on animation frame.
3887
+ * @returns Callable that requests frame (canceling pending), with cancel method.
3888
+ *
3889
+ * @see https://0.vuetifyjs.com/composables/system/use-raf
3890
+ *
3891
+ * @example
3892
+ * ```ts
3893
+ * // Basic usage
3894
+ * const update = useRaf((timestamp) => {
3895
+ * // Runs on next animation frame
3896
+ * })
3897
+ *
3898
+ * update() // Request frame
3899
+ * update() // Cancels previous, requests new (deduplicated)
3900
+ *
3901
+ * // Manual cancel
3902
+ * update.cancel()
3903
+ *
3904
+ * // Check if pending
3905
+ * if (update.isActive.value) { ... }
3906
+ * ```
3907
+ */
3908
+ function useRaf(callback) {
3909
+ const id = shallowRef();
3910
+ const isActive = toRef(() => !/* @__PURE__ */ isUndefined(id.value));
3911
+ function cancel() {
3912
+ if (!/* @__PURE__ */ isUndefined(id.value)) {
3913
+ cancelAnimationFrame(id.value);
3914
+ id.value = void 0;
3915
+ }
3916
+ }
3917
+ function request() {
3918
+ if (!IN_BROWSER) return;
3919
+ cancel();
3920
+ id.value = requestAnimationFrame((timestamp) => {
3921
+ id.value = void 0;
3922
+ callback(timestamp);
3923
+ });
3924
+ }
3925
+ onScopeDispose(cancel, true);
3926
+ return Object.assign(request, {
3927
+ cancel,
3928
+ isActive
3929
+ });
3930
+ }
3931
+ //#endregion
3208
3932
  //#region src/composables/createFocusTraversal/index.ts
3209
3933
  /**
3210
3934
  * @module createFocusTraversal
@@ -3653,6 +4377,9 @@ function createSlider(options = {}) {
3653
4377
  function ceil(index) {
3654
4378
  set(index, max);
3655
4379
  }
4380
+ function onboard(registrations) {
4381
+ return model.batch(() => registrations.map((r) => register(r)));
4382
+ }
3656
4383
  return {
3657
4384
  ...model,
3658
4385
  values,
@@ -3669,6 +4396,7 @@ function createSlider(options = {}) {
3669
4396
  orientation,
3670
4397
  inverted,
3671
4398
  register,
4399
+ onboard,
3672
4400
  snap,
3673
4401
  fromValue,
3674
4402
  fromPercent,
@@ -3748,12 +4476,12 @@ function createStack(_options = {}) {
3748
4476
  const id = input.id ?? /* @__PURE__ */ useId$1();
3749
4477
  const blocking = input.blocking ?? false;
3750
4478
  const onDismiss = input.onDismiss;
3751
- const zIndex = computed(() => {
4479
+ const zIndex = toRef(() => {
3752
4480
  const position = ids().indexOf(id);
3753
4481
  if (position === -1) return baseZIndex;
3754
4482
  return baseZIndex + position * increment;
3755
4483
  });
3756
- const globalTop = computed(() => {
4484
+ const globalTop = toRef(() => {
3757
4485
  const list = ids();
3758
4486
  if (list.length === 0) return false;
3759
4487
  return list.at(-1) === id;
@@ -4326,6 +5054,12 @@ function createTimeline(_options = {}) {
4326
5054
  function redo() {
4327
5055
  if (stack.length === 0) return void 0;
4328
5056
  const item = stack.pop();
5057
+ if (registry.size >= size) {
5058
+ const oldest = registry.seek("first");
5059
+ if (overflow.length === size) overflow.shift();
5060
+ overflow.push(oldest);
5061
+ registry.unregister(oldest.id);
5062
+ }
4329
5063
  const ticket = registry.register(item);
4330
5064
  registry.reindex();
4331
5065
  return ticket;
@@ -5381,4 +6115,4 @@ function useClickOutside(target, handler, options = {}) {
5381
6115
  };
5382
6116
  }
5383
6117
  //#endregion
5384
- export { useForm as $, useRtl as A, multipleOpenStrategy as B, createStackPlugin as C, useBreadcrumbs as Ct, createRtlContext as D, createRtl as E, useQueue as F, usePrefersDark as G, useMutationObserver as H, usePopover as I, useElementIntersection as J, usePrefersReducedMotion as K, createNested as L, useRovingFocus as M, createQueue as N, createRtlFallback as O, createQueueContext as P, createFormContext as Q, createNestedContext as R, createStackContext as S, createBreadcrumbsContext as St, createSlider as T, useMediaQuery as U, singleOpenStrategy as V, usePrefersContrast as W, useHotkey as X, useIntersectionObserver as Y, createForm as Z, useStorage as _, createHydration as _t, useVirtualFocus as a, createBreakpointsContext as at, useStep as b, useHydration as bt, useVirtual as c, toReactive as ct, createTimeline as d, createOverflowContext as dt, createDate as et, createTimelineContext as f, useOverflow as ft, createStoragePlugin as g, createFallbackHydration as gt, createStorageContext as h, toElement as ht, useWindowEventListener as i, createBreakpoints as it, Vuetify0RtlAdapter as j, createRtlPlugin as k, useToggleScope as l, useProxyModel as lt, createStorage as m, useResizeObserver as mt, useDocumentEventListener as n, createDatePlugin as nt, createVirtual as o, createBreakpointsPlugin as ot, useTimeline as p, useElementSize as pt, useLazy as q, useEventListener as r, useDate as rt, createVirtualContext as s, useBreakpoints as st, useClickOutside as t, createDateContext as tt, createValidation as u, createOverflow as ut, createStep as v, createHydrationContext as vt, useStack as w, createStack as x, createBreadcrumbs as xt, createStepContext as y, createHydrationPlugin as yt, useNested as z };
6118
+ export { useElementIntersection as $, useRtl as A, createQueueContext as B, createStackPlugin as C, createHydration as Ct, createRtlContext as D, createBreadcrumbs as Dt, createRtl as E, useHydration as Et, createNotifications as F, multipleOpenStrategy as G, createNested as H, createNotificationsContext as I, useMediaQuery as J, singleOpenStrategy as K, createNotificationsPlugin as L, useRovingFocus as M, useRaf as N, createRtlFallback as O, createBreadcrumbsContext as Ot, usePopover as P, useLazy as Q, useNotifications as R, createStackContext as S, createFallbackHydration as St, createSlider as T, createHydrationPlugin as Tt, createNestedContext as U, useQueue as V, useNested as W, usePrefersDark as X, usePrefersContrast as Y, usePrefersReducedMotion as Z, useStorage as _, createOverflowContext as _t, useVirtualFocus as a, createDate as at, useStep as b, useResizeObserver as bt, useVirtual as c, useDate as ct, createTimeline as d, createBreakpointsPlugin as dt, useIntersectionObserver as et, createTimelineContext as f, useBreakpoints as ft, createStoragePlugin as g, createOverflow as gt, createStorageContext as h, useProxyModel as ht, useWindowEventListener as i, useForm as it, Vuetify0RtlAdapter as j, createRtlPlugin as k, useBreadcrumbs as kt, useToggleScope as l, createBreakpoints as lt, createStorage as m, useTimer as mt, useDocumentEventListener as n, createForm as nt, createVirtual as o, createDateContext as ot, useTimeline as p, toReactive as pt, useMutationObserver as q, useEventListener as r, createFormContext as rt, createVirtualContext as s, createDatePlugin as st, useClickOutside as t, useHotkey as tt, createValidation as u, createBreakpointsContext as ut, createStep as v, useOverflow as vt, useStack as w, createHydrationContext as wt, createStack as x, toElement as xt, createStepContext as y, useElementSize as yt, createQueue as z };