@vuetify/v0 0.0.16 → 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.
Files changed (30) hide show
  1. package/README.md +125 -47
  2. package/dist/browser/index.js +1801 -1604
  3. package/dist/components/index.d.mts +4 -4
  4. package/dist/components/index.mjs +6 -6
  5. package/dist/{components-Dk00OFL2.mjs → components-D590hSY0.mjs} +151 -54
  6. package/dist/composables/index.d.mts +4 -4
  7. package/dist/composables/index.mjs +5 -5
  8. package/dist/{composables-YOUVfUsn.mjs → composables-FE6B8JUW.mjs} +370 -303
  9. package/dist/constants/index.d.mts +1 -1
  10. package/dist/constants/index.mjs +3 -3
  11. package/dist/{globals-Rnihe4SF.mjs → globals-exvZ8fiO.mjs} +1 -1
  12. package/dist/index-4jSy8KIt.d.mts +73 -0
  13. package/dist/{index-BzW68rBC.d.mts → index-BYyEPh1S.d.mts} +227 -17
  14. package/dist/index-CjzlIAtF.d.mts +296 -0
  15. package/dist/{index-BeJMYhId.d.mts → index-DahjxaTj.d.mts} +899 -136
  16. package/dist/{index-BulceeMA.d.mts → index-Gr6XPRWt.d.mts} +50 -18
  17. package/dist/index.d.mts +7 -7
  18. package/dist/index.mjs +8 -8
  19. package/dist/types/index.d.mts +1 -1
  20. package/dist/{useStep-Bqhi_DDs.mjs → useStep-Dw7XloDM.mjs} +1067 -1258
  21. package/dist/utilities/index.d.mts +2 -2
  22. package/dist/utilities/index.mjs +1 -1
  23. package/dist/utilities-BrFKLHFS.mjs +363 -0
  24. package/package.json +3 -3
  25. package/dist/index-BXN7M6o_.d.mts +0 -71
  26. package/dist/index-Bd3J4RNS.d.mts +0 -11
  27. package/dist/utilities-DQWf_4V_.mjs +0 -139
  28. /package/dist/{constants-BWV0uYsM.mjs → constants-DypzAkYp.mjs} +0 -0
  29. /package/dist/{htmlElements-BYo-fMlZ.mjs → htmlElements-CXObxj0V.mjs} +0 -0
  30. /package/dist/{index-B6lIRI3i.d.mts → index-B9mKi4pr.d.mts} +0 -0
@@ -1,25 +1,9 @@
1
- import { _ as range, d as isObject, h as isUndefined, i as isArray, l as isNullOrUndefined, m as isSymbol, o as isFunction, p as isString, r as genId, s as isNaN } from "./utilities-DQWf_4V_.mjs";
2
- import { a as SUPPORTS_OBSERVER, s as __LOGGER_ENABLED__, t as IN_BROWSER } from "./globals-Rnihe4SF.mjs";
3
- import { computed, getCurrentInstance, inject, isRef, onScopeDispose, provide, reactive, shallowReactive, shallowReadonly, shallowRef, toRef, toValue, watch } from "vue";
1
+ import { _ as range, d as isObject, h as isUndefined, l as isNullOrUndefined, m as isSymbol, o as isFunction, p as isString, r as genId, s as isNaN } from "./utilities-BrFKLHFS.mjs";
2
+ import { a as SUPPORTS_OBSERVER, s as __LOGGER_ENABLED__, t as IN_BROWSER } from "./globals-exvZ8fiO.mjs";
3
+ import { computed, getCurrentInstance, inject, isRef, onScopeDispose, provide, reactive, shallowReactive, shallowReadonly, shallowRef, toRef, toValue, watch, watchEffect } from "vue";
4
4
 
5
5
  //#region src/composables/createContext/index.ts
6
6
  /**
7
- * @module createContext
8
- *
9
- * @see https://0.vuetifyjs.com/composables/foundation/create-context
10
- *
11
- * @remarks
12
- * Factory for creating type-safe Vue dependency injection contexts.
13
- *
14
- * Provides a wrapper around Vue's provide/inject that throws errors when context is not found,
15
- * eliminating silent failures and improving developer experience. Supports both app-level and
16
- * component-level provision.
17
- *
18
- * Supports two modes:
19
- * - **Static key**: `createContext('my-key')` - key is fixed at creation time
20
- * - **Dynamic key**: `createContext()` or `createContext({ suffix: 'item' })` - key provided at runtime
21
- */
22
- /**
23
7
  * Injects a context provided by an ancestor component.
24
8
  *
25
9
  * @param key The key of the context to inject.
@@ -441,12 +425,12 @@ function createFallbackLogger(namespace = "v0:logger") {
441
425
  return `[${namespace} ${type}] ${message}`;
442
426
  }
443
427
  return {
444
- debug: (message, ...args) => console.log(format(message, "debug"), ...args),
445
- info: (message, ...args) => console.log(format(message, "info"), ...args),
446
- warn: (message, ...args) => console.log(format(message, "warn"), ...args),
447
- error: (message, ...args) => console.log(format(message, "error"), ...args),
448
- trace: (message, ...args) => console.log(format(message, "trace"), ...args),
449
- fatal: (message, ...args) => console.log(format(message, "fatal"), ...args),
428
+ debug: (message, ...args) => console.debug(format(message, "debug"), ...args),
429
+ info: (message, ...args) => console.info(format(message, "info"), ...args),
430
+ warn: (message, ...args) => console.warn(format(message, "warn"), ...args),
431
+ error: (message, ...args) => console.error(format(message, "error"), ...args),
432
+ trace: (message, ...args) => console.trace(format(message, "trace"), ...args),
433
+ fatal: (message, ...args) => console.error(format(message, "fatal"), ...args),
450
434
  level: () => {},
451
435
  current: () => "info",
452
436
  enabled: () => true,
@@ -474,7 +458,7 @@ function createFallbackLogger(namespace = "v0:logger") {
474
458
  * ```
475
459
  */
476
460
  function createLoggerContext(_options = {}) {
477
- const { namespace = "v0:logger",...options } = _options;
461
+ const { namespace = "v0:logger", ...options } = _options;
478
462
  const [useLoggerContext, _provideLoggerContext] = createContext(namespace);
479
463
  const context = createLogger(options);
480
464
  function provideLoggerContext(_context = context, app) {
@@ -509,7 +493,7 @@ function createLoggerContext(_options = {}) {
509
493
  * ```
510
494
  */
511
495
  function createLoggerPlugin(_options = {}) {
512
- const { namespace = "v0:logger",...options } = _options;
496
+ const { namespace = "v0:logger", ...options } = _options;
513
497
  const [, provideLoggerContext, context] = createLoggerContext({
514
498
  ...options,
515
499
  namespace
@@ -558,21 +542,6 @@ function useLogger(namespace = "v0:logger") {
558
542
  //#endregion
559
543
  //#region src/composables/useRegistry/index.ts
560
544
  /**
561
- * @module useRegistry
562
- *
563
- * @remarks
564
- * A foundational composable for managing collections of items (tickets) with:
565
- * - Unique ID-based access
566
- * - Index-based ordering
567
- * - Value-based reverse lookup
568
- * - Automatic reindexing
569
- * - Optional event emission
570
- * - Performance-optimized caching
571
- *
572
- * The registry serves as the base for many other composables in the system,
573
- * including useSelection, useForm, useTimeline, and more.
574
- */
575
- /**
576
545
  * Creates a new registry instance.
577
546
  *
578
547
  * @param options The options for the registry instance.
@@ -606,6 +575,8 @@ function useRegistry(options) {
606
575
  let indexDependentCount = 0;
607
576
  let needsReindex = false;
608
577
  let minDirtyIndex = Infinity;
578
+ let batching = false;
579
+ let pendingEmits = [];
609
580
  function emit(event, data = void 0) {
610
581
  if (!events) return;
611
582
  const cbs = listeners.get(event);
@@ -614,17 +585,21 @@ function useRegistry(options) {
614
585
  }
615
586
  function on(event, cb) {
616
587
  if (!events) {
617
- logger.warn(`Attempted to register event listener for "${event}" but events are disabled.`);
588
+ logger.warn(`Events are disabled. Initialize with \`useRegistry({ events: true })\` to enable.`);
618
589
  return;
619
590
  }
620
591
  if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
621
592
  listeners.get(event).add(cb);
622
593
  }
623
594
  function off(event, cb) {
595
+ if (!events) {
596
+ logger.warn(`Events are disabled. Initialize with \`useRegistry({ events: true })\` to enable.`);
597
+ return;
598
+ }
624
599
  listeners.get(event)?.delete(cb);
625
600
  }
626
601
  function dispose() {
627
- if (listeners.size > 0) listeners.clear();
602
+ listeners.clear();
628
603
  clear();
629
604
  }
630
605
  function get(id) {
@@ -681,24 +656,19 @@ function useRegistry(options) {
681
656
  function assign(value, id) {
682
657
  const bucket = catalog.get(value);
683
658
  if (bucket) {
684
- if (/* @__PURE__ */ isArray(bucket)) {
685
- if (!bucket.includes(id)) bucket.push(id);
686
- } else if (bucket !== id) catalog.set(value, [bucket, id]);
687
- } else catalog.set(value, id);
659
+ if (!bucket.includes(id)) bucket.push(id);
660
+ } else catalog.set(value, [id]);
688
661
  }
689
662
  function unassign(value, id) {
690
663
  const bucket = catalog.get(value);
691
664
  if (!bucket) return;
692
- if (/* @__PURE__ */ isArray(bucket)) {
693
- const next = bucket.filter((v) => v !== id);
694
- if (next.length === 0) catalog.delete(value);
695
- else if (next.length === 1) catalog.set(value, next[0]);
696
- else catalog.set(value, next);
697
- } else if (bucket === id) catalog.delete(value);
665
+ const next = bucket.filter((v) => v !== id);
666
+ if (next.length === 0) catalog.delete(value);
667
+ else catalog.set(value, next);
698
668
  }
699
669
  function keys() {
700
670
  const cached = cache.get("keys");
701
- if (cached != void 0) return cached;
671
+ if (!/* @__PURE__ */ isUndefined(cached)) return cached;
702
672
  const keys$1 = Array.from(collection.keys());
703
673
  cache.set("keys", keys$1);
704
674
  return keys$1;
@@ -718,9 +688,9 @@ function useRegistry(options) {
718
688
  return entries$1;
719
689
  }
720
690
  function clear() {
721
- if (collection.size > 0) collection.clear();
722
- if (catalog.size > 0) catalog.clear();
723
- if (directory.size > 0) directory.clear();
691
+ collection.clear();
692
+ catalog.clear();
693
+ directory.clear();
724
694
  invalidate();
725
695
  indexDependentCount = 0;
726
696
  needsReindex = false;
@@ -728,13 +698,35 @@ function useRegistry(options) {
728
698
  emit("clear:registry");
729
699
  }
730
700
  function invalidate() {
731
- if (cache.size > 0) cache.clear();
701
+ if (batching) return;
702
+ cache.clear();
703
+ }
704
+ function queueEmit(event, data) {
705
+ if (batching) pendingEmits.push({
706
+ event,
707
+ data
708
+ });
709
+ else emit(event, data);
710
+ }
711
+ function batch(fn) {
712
+ if (batching) return fn();
713
+ batching = true;
714
+ pendingEmits = [];
715
+ try {
716
+ const result = fn();
717
+ cache.clear();
718
+ for (const { event, data } of pendingEmits) emit(event, data);
719
+ return result;
720
+ } finally {
721
+ batching = false;
722
+ pendingEmits = [];
723
+ }
732
724
  }
733
725
  function reindex() {
734
726
  const startIndex = minDirtyIndex === Infinity ? 0 : minDirtyIndex;
735
727
  if (startIndex === 0) {
736
- if (catalog.size > 0) catalog.clear();
737
- if (directory.size > 0) directory.clear();
728
+ catalog.clear();
729
+ directory.clear();
738
730
  }
739
731
  invalidate();
740
732
  let index = 0;
@@ -761,7 +753,7 @@ function useRegistry(options) {
761
753
  const size = collection.size;
762
754
  const id = registration.id ?? /* @__PURE__ */ genId();
763
755
  if (has(id)) {
764
- logger.warn(`Ticket with id "${id}" already exists in the registry. Skipping registration.`);
756
+ logger.warn(`Ticket "${id}" already exists. Use \`upsert()\` to update or check \`has()\` before registering.`);
765
757
  return get(id);
766
758
  }
767
759
  const valueIsUndefined = /* @__PURE__ */ isUndefined(registration.value);
@@ -780,7 +772,7 @@ function useRegistry(options) {
780
772
  directory.set(ticket.index, ticket.id);
781
773
  assign(ticket.value, ticket.id);
782
774
  invalidate();
783
- emit("register:ticket", ticket);
775
+ queueEmit("register:ticket", ticket);
784
776
  return ticket;
785
777
  }
786
778
  function unregister(id) {
@@ -790,15 +782,12 @@ function useRegistry(options) {
790
782
  collection.delete(ticket.id);
791
783
  directory.delete(ticket.index);
792
784
  unassign(ticket.value, ticket.id);
793
- invalidate();
785
+ const willReindex = indexDependentCount > 0 && ticket.index < collection.size;
786
+ if (!willReindex) invalidate();
794
787
  emit("unregister:ticket", ticket);
795
- if (indexDependentCount > 0 && ticket.index < collection.size) {
796
- minDirtyIndex = Math.min(minDirtyIndex, ticket.index);
797
- reindex();
798
- } else {
799
- minDirtyIndex = Math.min(minDirtyIndex, ticket.index);
800
- needsReindex = true;
801
- }
788
+ minDirtyIndex = Math.min(minDirtyIndex, ticket.index);
789
+ if (willReindex) reindex();
790
+ else needsReindex = true;
802
791
  }
803
792
  function offboard(ids) {
804
793
  const removed = [];
@@ -814,12 +803,16 @@ function useRegistry(options) {
814
803
  }
815
804
  if (removed.length === 0) return;
816
805
  invalidate();
817
- if (events) for (const ticket of removed) emit("unregister:ticket", ticket);
806
+ for (const ticket of removed) queueEmit("unregister:ticket", ticket);
818
807
  needsReindex = true;
819
808
  }
820
809
  function seek(direction = "first", from, predicate) {
821
810
  if (collection.size === 0) return void 0;
822
811
  if (needsReindex) reindex();
812
+ if (!predicate && /* @__PURE__ */ isUndefined(from)) {
813
+ const tickets$1 = values();
814
+ return direction === "first" ? tickets$1[0] : tickets$1.at(-1);
815
+ }
823
816
  const tickets = values();
824
817
  const index = /* @__PURE__ */ isUndefined(from) ? void 0 : Math.max(0, Math.min(from, tickets.length - 1));
825
818
  if (direction === "last") {
@@ -855,8 +848,9 @@ function useRegistry(options) {
855
848
  unregister,
856
849
  reindex,
857
850
  seek,
851
+ batch,
858
852
  onboard(registrations) {
859
- return registrations.map((registration) => register(registration));
853
+ return batch(() => registrations.map((registration) => register(registration)));
860
854
  },
861
855
  offboard,
862
856
  get size() {
@@ -867,8 +861,7 @@ function useRegistry(options) {
867
861
  /**
868
862
  * Creates a new registry context.
869
863
  *
870
- * @param namespace The namespace for the registry context.
871
- * @param options The options for the registry context.
864
+ * @param options The options for the registry context, including `namespace` (defaults to `'v0:registry'`) and `events`.
872
865
  * @template Z The type of registry ticket that extends RegistryTicket. Use this to add custom properties to tickets.
873
866
  * @template E The type of registry context that extends RegistryContext<Z>. Use this when extending the registry with additional methods.
874
867
  * @returns A new registry context.
@@ -894,7 +887,7 @@ function useRegistry(options) {
894
887
  * ```
895
888
  */
896
889
  function createRegistryContext(_options = {}) {
897
- const { namespace = "v0:registry",...options } = _options;
890
+ const { namespace = "v0:registry", ...options } = _options;
898
891
  const [useRegistryContext, _provideRegistryContext] = createContext(namespace);
899
892
  const context = useRegistry(options);
900
893
  function provideRegistryContext(_context = context, app) {
@@ -906,21 +899,6 @@ function createRegistryContext(_options = {}) {
906
899
  //#endregion
907
900
  //#region src/composables/useSelection/index.ts
908
901
  /**
909
- * @module useSelection
910
- *
911
- * @remarks
912
- * Base composable for managing selected items in a collection with Set-based tracking.
913
- *
914
- * Key features:
915
- * - Set-based selectedIds for O(1) selection checks
916
- * - Mandatory selection mode (prevents deselecting last item)
917
- * - Auto-enrollment option (selects non-disabled items on register)
918
- * - Disabled item filtering
919
- * - Computed selectedItems and selectedValues Sets
920
- *
921
- * Extends useRegistry and serves as the base for useSingle, useGroup, useStep, and useFeatures.
922
- */
923
- /**
924
902
  * Creates a new selection instance for managing multiple selected items.
925
903
  *
926
904
  * Extends `useRegistry` with selection tracking via a reactive `Set` of selected IDs.
@@ -967,14 +945,14 @@ function createRegistryContext(_options = {}) {
967
945
  * ```
968
946
  */
969
947
  function createSelection(_options = {}) {
970
- const { disabled = false, enroll = false, mandatory = false, multiple = false,...options } = _options;
948
+ const { disabled = false, enroll = false, mandatory = false, multiple = false, ...options } = _options;
971
949
  const registry = useRegistry(options);
972
950
  const selectedIds = shallowReactive(/* @__PURE__ */ new Set());
973
951
  const selectedItems = computed(() => {
974
- return new Set(Array.from(selectedIds).map((id) => registry.get(id)));
952
+ return new Set(Array.from(selectedIds).map((id) => registry.get(id)).filter((item) => !/* @__PURE__ */ isUndefined(item)));
975
953
  });
976
954
  const selectedValues = computed(() => {
977
- return new Set(Array.from(selectedItems.value).map((item) => item?.value));
955
+ return new Set(Array.from(selectedItems.value).map((item) => item.value));
978
956
  });
979
957
  function seek(direction = "first", from) {
980
958
  return registry.seek(direction, from, (ticket) => !toValue(ticket.disabled));
@@ -985,16 +963,19 @@ function createSelection(_options = {}) {
985
963
  if (ticket) select(ticket.id);
986
964
  }
987
965
  function select(id) {
966
+ if (toValue(disabled)) return;
988
967
  const item = registry.get(id);
989
968
  if (!item || toValue(item.disabled)) return;
990
969
  if (!multiple) selectedIds.clear();
991
970
  selectedIds.add(id);
992
971
  }
993
972
  function unselect(id) {
973
+ if (toValue(disabled)) return;
994
974
  if (mandatory && selectedIds.size === 1) return;
995
975
  selectedIds.delete(id);
996
976
  }
997
977
  function toggle(id) {
978
+ if (toValue(disabled)) return;
998
979
  if (selected(id)) unselect(id);
999
980
  else select(id);
1000
981
  }
@@ -1013,7 +994,7 @@ function createSelection(_options = {}) {
1013
994
  id
1014
995
  };
1015
996
  const ticket = registry.register(item);
1016
- if (enroll && !toValue(item.disabled)) selectedIds.add(ticket.id);
997
+ if (enroll && !toValue(disabled) && !toValue(item.disabled)) selectedIds.add(ticket.id);
1017
998
  if (mandatory === "force") mandate();
1018
999
  return ticket;
1019
1000
  }
@@ -1084,7 +1065,7 @@ function createSelection(_options = {}) {
1084
1065
  * ```
1085
1066
  */
1086
1067
  function createSelectionContext(_options = {}) {
1087
- const { namespace = "v0:selection",...options } = _options;
1068
+ const { namespace = "v0:selection", ...options } = _options;
1088
1069
  const [useSelectionContext, _provideSelectionContext] = createContext(namespace);
1089
1070
  const context = createSelection(options);
1090
1071
  function provideSelectionContext(_context = context, app) {
@@ -1157,20 +1138,6 @@ function toArray(value) {
1157
1138
  //#endregion
1158
1139
  //#region src/composables/useProxyModel/index.ts
1159
1140
  /**
1160
- * @module useProxyModel
1161
- *
1162
- * @remarks
1163
- * Proxy composable for bidirectional sync between selection registry and v-model.
1164
- *
1165
- * Key features:
1166
- * - Bidirectional synchronization
1167
- * - Array and single-value modes
1168
- * - Automatic cleanup on scope disposal
1169
- * - Perfect for form controls with selection backing
1170
- *
1171
- * Bridges the gap between selection composables and Vue's v-model.
1172
- */
1173
- /**
1174
1141
  * Syncs a ref with a selection registry bidirectionally.
1175
1142
  *
1176
1143
  * @param registry The selection registry to bind to.
@@ -1211,12 +1178,9 @@ function useProxyModel(registry, model, options) {
1211
1178
  const pending = new Set(modelAsArray);
1212
1179
  for (const value of modelAsArray) {
1213
1180
  const ids = registry.browse(value);
1214
- if (/* @__PURE__ */ isArray(ids)) {
1181
+ if (ids) {
1215
1182
  for (const id of ids) registry.select(id);
1216
1183
  pending.delete(value);
1217
- } else if (ids) {
1218
- registry.select(ids);
1219
- pending.delete(value);
1220
1184
  }
1221
1185
  }
1222
1186
  const registryWatch = watch(registry.selectedValues, (val) => {
@@ -1230,8 +1194,7 @@ function useProxyModel(registry, model, options) {
1230
1194
  const targetIds = /* @__PURE__ */ new Set();
1231
1195
  for (const value of transformIn(val)) {
1232
1196
  const ids = registry.browse(value);
1233
- if (/* @__PURE__ */ isArray(ids)) for (const single of ids) targetIds.add(single);
1234
- else if (ids) targetIds.add(ids);
1197
+ if (ids) for (const id of ids) targetIds.add(id);
1235
1198
  }
1236
1199
  if (multiple) {
1237
1200
  for (const id of currentIds.difference(targetIds)) registry.selectedIds.delete(id);
@@ -1247,7 +1210,8 @@ function useProxyModel(registry, model, options) {
1247
1210
  flush: "sync",
1248
1211
  deep: multiple
1249
1212
  });
1250
- function onRegister(ticket) {
1213
+ function onRegister(data) {
1214
+ const ticket = data;
1251
1215
  if (!pending.has(ticket.value) || ticket.disabled) return;
1252
1216
  registryWatch.pause();
1253
1217
  modelWatch.pause();
@@ -1269,21 +1233,6 @@ function useProxyModel(registry, model, options) {
1269
1233
  //#endregion
1270
1234
  //#region src/composables/useProxyRegistry/index.ts
1271
1235
  /**
1272
- * @module useProxyRegistry
1273
- *
1274
- * @remarks
1275
- * Proxy composable for reactive registry keys, values, entries, and size.
1276
- *
1277
- * Key features:
1278
- * - Reactive proxy for registry data
1279
- * - Deep or shallow reactivity options
1280
- * - Event-based updates
1281
- * - Automatic cleanup on scope disposal
1282
- * - Transforms Map-based registry into reactive refs
1283
- *
1284
- * Perfect for exposing registry data as reactive computed properties.
1285
- */
1286
- /**
1287
1236
  * Creates a proxy registry that provides reactive objects for registry data.
1288
1237
  *
1289
1238
  * @param registry The registry instance to proxy.
@@ -1333,26 +1282,6 @@ function useProxyRegistry(registry, options) {
1333
1282
  //#endregion
1334
1283
  //#region src/composables/useGroup/index.ts
1335
1284
  /**
1336
- * @module useGroup
1337
- *
1338
- * @remarks
1339
- * Multi-selection composable that extends useSelection with batch operations and tri-state support.
1340
- *
1341
- * Key features:
1342
- * - Batch operations (select/unselect/toggle accept ID | ID[])
1343
- * - Tri-state support via mixed/indeterminate state (mix/unmix)
1344
- * - selectedIndexes computed Set for position-based tracking
1345
- * - Perfect for checkbox trees, multi-select dropdowns, filter panels
1346
- *
1347
- * Tri-state behavior:
1348
- * - Items can be selected, mixed (indeterminate), or unselected
1349
- * - select() clears mixed state, mix() clears selected state (mutually exclusive)
1350
- * - toggle() on a mixed item selects it (resolves positively)
1351
- *
1352
- * Inheritance chain: useRegistry → useSelection → useGroup
1353
- * Extended by: useFeatures
1354
- */
1355
- /**
1356
1285
  * Creates a new group instance with batch selection and tri-state support.
1357
1286
  *
1358
1287
  * Extends `createSelection` to support selecting, unselecting, and toggling multiple items
@@ -1426,7 +1355,7 @@ function useProxyRegistry(registry, options) {
1426
1355
  * ```
1427
1356
  */
1428
1357
  function createGroup(_options = {}) {
1429
- const { mandatory = false, multiple = true,...options } = _options;
1358
+ const { mandatory = false, multiple = true, ...options } = _options;
1430
1359
  const selection = createSelection({
1431
1360
  ...options,
1432
1361
  mandatory,
@@ -1436,10 +1365,10 @@ function createGroup(_options = {}) {
1436
1365
  const proxy = useProxyRegistry(selection);
1437
1366
  const mixedIds = shallowReactive(/* @__PURE__ */ new Set());
1438
1367
  const selectedIndexes = computed(() => {
1439
- return new Set(Array.from(selection.selectedItems.value).map((item) => item?.index));
1368
+ return new Set(Array.from(selection.selectedItems.value).map((item) => item?.index).filter((index) => !/* @__PURE__ */ isUndefined(index)));
1440
1369
  });
1441
1370
  const mixedItems = computed(() => {
1442
- return new Set(Array.from(mixedIds).map((id) => selection.get(id)));
1371
+ return new Set(Array.from(mixedIds).map((id) => selection.get(id)).filter((item) => !/* @__PURE__ */ isUndefined(item)));
1443
1372
  });
1444
1373
  function mixed(id) {
1445
1374
  return mixedIds.has(id);
@@ -1506,10 +1435,10 @@ function createGroup(_options = {}) {
1506
1435
  if (items.length === 0) return false;
1507
1436
  return items.every((item) => selection.selectedIds.has(item.id));
1508
1437
  });
1509
- const isMixed = toRef(() => {
1438
+ const isNoneSelected = computed(() => selection.selectedIds.size === 0);
1439
+ const isMixed = computed(() => {
1510
1440
  return mixedIds.size > 0 || !isNoneSelected.value && !isAllSelected.value;
1511
1441
  });
1512
- const isNoneSelected = toRef(() => selection.selectedIds.size === 0);
1513
1442
  function selectAll() {
1514
1443
  for (const item of selectableItems.value) {
1515
1444
  mixedIds.delete(item.id);
@@ -1581,7 +1510,7 @@ function createGroup(_options = {}) {
1581
1510
  * ```
1582
1511
  */
1583
1512
  function createGroupContext(_options = {}) {
1584
- const { namespace = "v0:group",...options } = _options;
1513
+ const { namespace = "v0:group", ...options } = _options;
1585
1514
  const [useGroupContext, _provideGroupContext] = createContext(namespace);
1586
1515
  const context = createGroup(options);
1587
1516
  function provideGroupContext(_context = context, app) {
@@ -1617,1364 +1546,1244 @@ function useGroup(namespace = "v0:group") {
1617
1546
  }
1618
1547
 
1619
1548
  //#endregion
1620
- //#region src/composables/useHydration/index.ts
1549
+ //#region src/composables/useLocale/adapters/v0.ts
1621
1550
  /**
1622
- * @module useHydration
1551
+ * Vuetify0.x locale adapter implementation
1623
1552
  *
1624
- * @see https://0.vuetifyjs.com/composables/plugins/use-hydration
1553
+ * This adapter provides translation and number formatting
1554
+ * capabilities using the Intl API and supports both
1555
+ * numbered ({0}, {1}) and named ({name}) variables in translation strings.
1556
+ */
1557
+ var Vuetify0LocaleAdapter = class {
1558
+ t(message, ...params) {
1559
+ let resolvedMessage = message;
1560
+ if (params.length > 0 && /* @__PURE__ */ isObject(params[0])) {
1561
+ const variables = params[0];
1562
+ resolvedMessage = resolvedMessage.replace(/{([a-zA-Z][a-zA-Z0-9_]*)}/g, (match, name) => {
1563
+ return /* @__PURE__ */ isUndefined(variables[name]) ? match : String(variables[name]);
1564
+ });
1565
+ params = params.slice(1);
1566
+ }
1567
+ resolvedMessage = resolvedMessage.replace(/\{(\d+)\}/g, (match, index) => {
1568
+ const idx = Number.parseInt(index, 10);
1569
+ if (!/* @__PURE__ */ isUndefined(params[idx])) return String(params[idx]);
1570
+ return match;
1571
+ });
1572
+ return resolvedMessage;
1573
+ }
1574
+ n(value, locale, ...params) {
1575
+ if (!IN_BROWSER || !locale) return value.toString();
1576
+ const options = params[0];
1577
+ return new Intl.NumberFormat(String(locale), options).format(value);
1578
+ }
1579
+ };
1580
+
1581
+ //#endregion
1582
+ //#region src/composables/useSingle/index.ts
1583
+ /**
1584
+ * Creates a new single selection instance that enforces only one selected item at a time.
1625
1585
  *
1626
- * @remarks
1627
- * SSR hydration state management composable.
1586
+ * Extends `createSelection` by automatically clearing previous selections when a new item is selected.
1587
+ * Adds computed singular properties: `selectedId`, `selectedItem`, `selectedIndex`, `selectedValue`.
1628
1588
  *
1629
- * Key features:
1630
- * - Hydration state detection (browser vs SSR)
1631
- * - Root component detection
1632
- * - Readonly hydration state refs
1633
- * - Plugin installation support
1634
- * - Perfect for hydration-safe rendering
1589
+ * @param options The options for the single selection instance.
1590
+ * @template Z The type of the single selection ticket.
1591
+ * @template E The type of the single selection context.
1592
+ * @returns A new single selection instance with single-selection enforcement.
1635
1593
  *
1636
- * Essential for composables that need to behave differently during SSR vs client-side.
1637
- */
1638
- /**
1639
- * Creates a new hydration instance.
1594
+ * @remarks
1595
+ * **Key Differences from `createSelection`:**
1596
+ * - Automatically clears `selectedIds` before selecting a new item (enforces single selection)
1597
+ * - Provides singular computed properties instead of plural sets
1598
+ * - Perfect for tabs, radio buttons, theme selectors, and other single-choice UI components
1640
1599
  *
1641
- * @returns A new hydration instance.
1600
+ * **Computed Properties:**
1601
+ * - `selectedId`: The ID of the selected item (undefined if none selected)
1602
+ * - `selectedItem`: The selected ticket object (undefined if none selected)
1603
+ * - `selectedIndex`: The index of the selected item (-1 if none selected)
1604
+ * - `selectedValue`: The value of the selected item (undefined if none selected)
1642
1605
  *
1643
- * @see https://0.vuetifyjs.com/composables/plugins/use-hydration
1606
+ * **Inheritance Chain:**
1607
+ * `useRegistry` → `createSelection` → `createSingle` → `createStep`
1608
+ *
1609
+ * @see https://0.vuetifyjs.com/composables/selection/use-single
1644
1610
  *
1645
1611
  * @example
1646
1612
  * ```ts
1647
- * import { createHydration } from '@vuetify/v0'
1613
+ * import { createSingle } from '@vuetify/v0'
1648
1614
  *
1649
- * const hydration = createHydration()
1650
- * console.log(hydration.isHydrated.value) // false
1651
- * hydration.hydrate()
1652
- * console.log(hydration.isHydrated.value) // true
1653
- * ```
1654
- */
1655
- function createHydration() {
1656
- const isHydrated = shallowRef(false);
1657
- function hydrate() {
1658
- isHydrated.value = true;
1659
- }
1660
- return {
1661
- isHydrated: shallowReadonly(isHydrated),
1662
- hydrate
1663
- };
1664
- }
1665
- function createFallbackHydration() {
1666
- return {
1667
- isHydrated: shallowReadonly(shallowRef(true)),
1668
- hydrate: () => {}
1669
- };
1670
- }
1671
- /**
1672
- * Creates a new hydration context trinity.
1615
+ * const tabs = createSingle({ mandatory: true })
1673
1616
  *
1674
- * @param options Options for creating the hydration context.
1675
- * @template E The type of the hydration context.
1676
- * @returns A new hydration context trinity.
1617
+ * tabs.onboard([
1618
+ * { id: 'home', value: 'Home' },
1619
+ * { id: 'about', value: 'About' },
1620
+ * { id: 'contact', value: 'Contact' },
1621
+ * ])
1677
1622
  *
1678
- * @see https://0.vuetifyjs.com/composables/plugins/use-hydration
1623
+ * tabs.first() // Select first tab
1679
1624
  *
1680
- * @example
1681
- * ```ts
1682
- * import { createHydrationContext } from '@vuetify/v0'
1625
+ * console.log(tabs.selectedId.value) // 'home'
1626
+ * console.log(tabs.selectedIndex.value) // 0
1683
1627
  *
1684
- * export const [useHydrationContext, provideHydrationContext, context] = createHydrationContext({
1685
- * namespace: 'app:hydration',
1686
- * })
1628
+ * tabs.select('about') // Switch to about tab
1629
+ * console.log(tabs.selectedId.value) // 'about'
1630
+ * console.log(tabs.selectedIds.size) // 1 (always enforces single selection)
1687
1631
  * ```
1688
1632
  */
1689
- function createHydrationContext(_options = {}) {
1690
- const { namespace = "v0:hydration" } = _options;
1691
- const [useHydrationContext, _provideHydrationContext] = createContext(namespace);
1692
- const context = createHydration();
1693
- function provideHydrationContext(_context = context, app) {
1694
- return _provideHydrationContext(_context, app);
1633
+ function createSingle(_options = {}) {
1634
+ const { mandatory = false, multiple = false, ...options } = _options;
1635
+ const registry = createSelection({
1636
+ ...options,
1637
+ mandatory,
1638
+ multiple
1639
+ });
1640
+ const selectedId = computed(() => registry.selectedIds.values().next().value);
1641
+ const selectedItem = computed(() => registry.selectedItems.value.values().next().value);
1642
+ const selectedIndex = computed(() => selectedItem.value?.index ?? -1);
1643
+ const selectedValue = computed(() => selectedItem.value?.value);
1644
+ function unselect(id) {
1645
+ if (mandatory && registry.selectedIds.size === 1) return;
1646
+ registry.selectedIds.delete(id);
1695
1647
  }
1696
- return createTrinity(useHydrationContext, provideHydrationContext, context);
1648
+ function toggle(id) {
1649
+ if (registry.selectedIds.has(id)) unselect(id);
1650
+ else registry.select(id);
1651
+ }
1652
+ return {
1653
+ ...registry,
1654
+ selectedId,
1655
+ selectedItem,
1656
+ selectedIndex,
1657
+ selectedValue,
1658
+ unselect,
1659
+ toggle,
1660
+ get size() {
1661
+ return registry.size;
1662
+ }
1663
+ };
1697
1664
  }
1698
1665
  /**
1699
- * Creates a new hydration plugin.
1666
+ * Creates a new single selection context.
1700
1667
  *
1701
- * @param options The options for the hydration plugin.
1702
- * @template E The type of the hydration context.
1703
- * @returns A new hydration plugin.
1668
+ * @param options The options for the single selection context.
1669
+ * @template Z The type of the single selection ticket.
1670
+ * @template E The type of the single selection context.
1671
+ * @returns A new single selection context.
1704
1672
  *
1705
- * @see https://0.vuetifyjs.com/composables/plugins/use-hydration
1673
+ * @see https://0.vuetifyjs.com/composables/selection/use-single
1706
1674
  *
1707
1675
  * @example
1708
1676
  * ```ts
1709
- * import { createApp } from 'vue'
1710
- * import { createHydrationPlugin } from '@vuetify/v0'
1711
- * import App from './App.vue'
1677
+ * import { createSingleContext } from '@vuetify/v0'
1712
1678
  *
1713
- * const app = createApp(App)
1679
+ * // With default namespace 'v0:single'
1680
+ * export const [useSingle, provideSingle, context] = createSingleContext()
1714
1681
  *
1715
- * app.use(createHydrationPlugin())
1682
+ * // In a parent component:
1683
+ * provideSingle()
1716
1684
  *
1717
- * app.mount('#app')
1685
+ * // In a child component:
1686
+ * const single = useSingle()
1687
+ * single.select('tab-1')
1718
1688
  * ```
1719
1689
  */
1720
- function createHydrationPlugin(_options = {}) {
1721
- const { namespace = "v0:hydration",...options } = _options;
1722
- const [, provideHydrationContext, context] = createHydrationContext({
1723
- ...options,
1724
- namespace
1725
- });
1726
- return createPlugin({
1727
- namespace,
1728
- provide: (app) => {
1729
- provideHydrationContext(context, app);
1730
- },
1731
- setup: (app) => {
1732
- app.mixin({ mounted() {
1733
- if (this.$parent !== null) return;
1734
- context.hydrate();
1735
- } });
1736
- }
1737
- });
1690
+ function createSingleContext(_options = {}) {
1691
+ const { namespace = "v0:single", ...options } = _options;
1692
+ const [useSingleContext, _provideSingleContext] = createContext(namespace);
1693
+ const context = createSingle(options);
1694
+ function provideSingleContext(_context = context, app) {
1695
+ return _provideSingleContext(_context, app);
1696
+ }
1697
+ return createTrinity(useSingleContext, provideSingleContext, context);
1738
1698
  }
1739
1699
  /**
1740
- * Returns the current hydration instance.
1700
+ * Returns the current single selection instance.
1741
1701
  *
1742
- * @param namespace The namespace for the hydration context. Defaults to `v0:hydration`.
1743
- * @returns The current hydration instance.
1702
+ * @param namespace The namespace for the single selection context. Defaults to `'v0:single'`.
1703
+ * @returns The current single selection instance.
1744
1704
  *
1745
- * @see https://0.vuetifyjs.com/composables/plugins/use-hydration
1705
+ * @see https://0.vuetifyjs.com/composables/selection/use-single
1746
1706
  *
1747
1707
  * @example
1748
1708
  * ```vue
1749
1709
  * <script setup lang="ts">
1750
- * import { useHydration } from '@vuetify/v0'
1710
+ * import { useSingle } from '@vuetify/v0'
1751
1711
  *
1752
- * const hydration = useHydration()
1712
+ * const tabs = useSingle()
1753
1713
  * <\/script>
1754
1714
  *
1755
1715
  * <template>
1756
1716
  * <div>
1757
- * <p>Is hydrated: {{ hydration.isHydrated.value }}</p>
1717
+ * <p>Selected: {{ tabs.selectedId }}</p>
1758
1718
  * </div>
1759
1719
  * </template>
1760
1720
  * ```
1761
1721
  */
1762
- function useHydration(namespace = "v0:hydration") {
1763
- const fallback = createFallbackHydration();
1764
- if (!getCurrentInstance()) return fallback;
1765
- try {
1766
- return useContext(namespace, fallback);
1767
- } catch {
1768
- return fallback;
1769
- }
1722
+ function useSingle(namespace = "v0:single") {
1723
+ return useContext(namespace);
1770
1724
  }
1771
1725
 
1772
1726
  //#endregion
1773
- //#region src/composables/useResizeObserver/index.ts
1774
- /**
1775
- * @module useResizeObserver
1776
- *
1777
- * @remarks
1778
- * ResizeObserver composable with lifecycle management.
1779
- *
1780
- * Key features:
1781
- * - ResizeObserver API wrapper
1782
- * - Pause/resume/stop functionality
1783
- * - Automatic cleanup on unmount
1784
- * - SSR-safe (checks SUPPORTS_OBSERVER)
1785
- * - Hydration-aware
1786
- * - Box model options (content-box/border-box)
1787
- *
1788
- * Perfect for responsive components and size-based rendering.
1789
- */
1727
+ //#region src/composables/useTokens/index.ts
1790
1728
  /**
1791
- * A composable that uses the Resize Observer API to detect when an element's
1792
- * size changes.
1729
+ * Creates a new token instance.
1793
1730
  *
1794
- * @param target The element to observe.
1795
- * @param callback The callback to execute when the element's size changes.
1796
- * @param options The options for the Resize Observer.
1797
- * @returns An object with methods to control the observer.
1731
+ * @param tokens The tokens to use.
1732
+ * @param options The options for the token instance.
1733
+ * @template Z The type of the token ticket.
1734
+ * @template E The type of the token context.
1735
+ * @returns A new token instance.
1798
1736
  *
1799
- * @see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
1800
- * @see https://0.vuetifyjs.com/composables/system/use-resize-observer
1737
+ * @see https://www.designtokens.org/tr/drafts/format/
1738
+ * @see https://0.vuetifyjs.com/composables/registration/use-tokens
1801
1739
  *
1802
1740
  * @example
1803
1741
  * ```ts
1804
- * import { ref } from 'vue'
1805
- * import { useResizeObserver } from '@vuetify/v0'
1806
- *
1807
- * const el = ref<HTMLElement>()
1808
- * const width = ref(0)
1809
- * const height = ref(0)
1742
+ * import { useTokens } from '@vuetify/v0'
1810
1743
  *
1811
- * const { pause, resume, isPaused } = useResizeObserver(
1812
- * el,
1813
- * (entries) => {
1814
- * const entry = entries[0]
1815
- * if (entry) {
1816
- * width.value = entry.contentRect.width
1817
- * height.value = entry.contentRect.height
1818
- * console.log('Size changed:', width.value, 'x', height.value)
1819
- * }
1744
+ * const tokens = useTokens({
1745
+ * colors: {
1746
+ * primary: '#3b82f6',
1747
+ * secondary: '{colors.primary}', // Alias reference
1820
1748
  * },
1821
- * { immediate: true }
1822
- * )
1823
- *
1824
- * // Pause observation
1825
- * pause()
1749
+ * })
1826
1750
  *
1827
- * // Resume observation
1828
- * resume()
1751
+ * console.log(tokens.resolve('{colors.primary}')) // '#3b82f6'
1752
+ * console.log(tokens.resolve('{colors.secondary}')) // '#3b82f6'
1829
1753
  * ```
1830
1754
  */
1831
- function useResizeObserver(target, callback, options = {}) {
1832
- const { isHydrated } = useHydration();
1833
- const observer = shallowRef();
1834
- const isPaused = shallowRef(false);
1835
- const isActive = toRef(() => !!observer.value);
1836
- function setup() {
1837
- if (!isHydrated.value || !SUPPORTS_OBSERVER || !target.value || isPaused.value) return;
1838
- observer.value = new ResizeObserver((entries) => {
1839
- callback(entries.map((entry) => ({
1840
- contentRect: {
1841
- width: entry.contentRect.width,
1842
- height: entry.contentRect.height,
1843
- top: entry.contentRect.top,
1844
- left: entry.contentRect.left
1845
- },
1846
- target: entry.target
1847
- })));
1848
- });
1849
- observer.value.observe(target.value, { box: options.box || "content-box" });
1850
- if (options.immediate) {
1851
- const rect = target.value.getBoundingClientRect();
1852
- callback([{
1853
- contentRect: {
1854
- width: rect.width,
1855
- height: rect.height,
1856
- top: rect.top,
1857
- left: rect.left
1858
- },
1859
- target: target.value
1860
- }]);
1861
- }
1862
- }
1863
- watch([isHydrated, target], () => {
1864
- cleanup();
1865
- setup();
1866
- }, { immediate: true });
1867
- function cleanup() {
1868
- if (observer.value) {
1869
- observer.value.disconnect();
1870
- observer.value = void 0;
1871
- }
1872
- }
1873
- function pause() {
1874
- isPaused.value = true;
1875
- observer.value?.disconnect();
1755
+ function createTokens(tokens = {}, options = {}) {
1756
+ const logger = useLogger();
1757
+ const registry = useRegistry(options);
1758
+ const cache = /* @__PURE__ */ new Map();
1759
+ registry.onboard(flatten(tokens, options.prefix, !!options.flat));
1760
+ function isAlias(token) {
1761
+ return /* @__PURE__ */ isString(token) && token.length > 2 && token[0] === "{" && token.at(-1) === "}";
1876
1762
  }
1877
- function resume() {
1878
- isPaused.value = false;
1879
- setup();
1763
+ function isTokenAlias(value) {
1764
+ return /* @__PURE__ */ isObject(value) && "$value" in value;
1880
1765
  }
1881
- function stop() {
1882
- cleanup();
1766
+ function resolve(token, visited = /* @__PURE__ */ new Set()) {
1767
+ const cacheKey = /* @__PURE__ */ isString(token) ? token : JSON.stringify(token);
1768
+ const cached = cache.get(cacheKey);
1769
+ if (!/* @__PURE__ */ isUndefined(cached)) return cached;
1770
+ const reference = isTokenAlias(token) ? token.$value : token;
1771
+ const isAliasReference = /* @__PURE__ */ isString(reference) && isAlias(reference);
1772
+ const clean = isAliasReference ? reference.slice(1, -1) : String(reference);
1773
+ if (visited.has(clean)) {
1774
+ logger.warn(`Circular alias detected for "${clean}"`);
1775
+ cache.set(cacheKey, void 0);
1776
+ return;
1777
+ }
1778
+ visited.add(clean);
1779
+ let found = registry.get(clean);
1780
+ let segments = [];
1781
+ if (!found && clean.includes(".")) {
1782
+ const parts = clean.split(".");
1783
+ for (let i = parts.length - 1; i > 0; i--) {
1784
+ const prefix = parts.slice(0, i).join(".");
1785
+ const suffix = parts.slice(i);
1786
+ const candidate = registry.get(prefix);
1787
+ if (!/* @__PURE__ */ isUndefined(candidate?.value)) {
1788
+ found = candidate;
1789
+ segments = suffix;
1790
+ break;
1791
+ }
1792
+ }
1793
+ }
1794
+ if (/* @__PURE__ */ isUndefined(found?.value)) {
1795
+ if (isAliasReference) logger.warn(`Alias not found for "${String(reference)}"`);
1796
+ cache.set(cacheKey, void 0);
1797
+ return;
1798
+ }
1799
+ let result;
1800
+ let current = found.value;
1801
+ if (segments.length > 0) {
1802
+ if (isTokenAlias(current)) current = current.$value;
1803
+ for (const segment of segments) {
1804
+ if (!/* @__PURE__ */ isObject(current) || !(segment in current)) {
1805
+ current = void 0;
1806
+ break;
1807
+ }
1808
+ current = current[segment];
1809
+ if (isTokenAlias(current)) current = current.$value;
1810
+ }
1811
+ if (/* @__PURE__ */ isUndefined(current)) {
1812
+ logger.warn(`Path not found inside "${clean}": ${segments.join(".")}`);
1813
+ cache.set(cacheKey, void 0);
1814
+ return;
1815
+ }
1816
+ result = current;
1817
+ } else if (isTokenAlias(current)) {
1818
+ const inner = current.$value;
1819
+ if (/* @__PURE__ */ isString(inner) && isAlias(inner)) return resolve(inner, visited);
1820
+ result = inner;
1821
+ } else if (/* @__PURE__ */ isString(current) && isAlias(current)) return resolve(current, visited);
1822
+ else result = current;
1823
+ cache.set(cacheKey, result);
1824
+ return result;
1883
1825
  }
1884
- onScopeDispose(stop, true);
1885
1826
  return {
1886
- isActive: shallowReadonly(isActive),
1887
- isPaused: shallowReadonly(isPaused),
1888
- pause,
1889
- resume,
1890
- stop
1827
+ ...registry,
1828
+ resolve,
1829
+ isAlias,
1830
+ get size() {
1831
+ return registry.size;
1832
+ }
1891
1833
  };
1892
1834
  }
1893
1835
  /**
1894
- * A convenience composable that uses the Resize Observer API to track an
1895
- * element's size.
1836
+ * Creates a new token context.
1896
1837
  *
1897
- * @param target The element to observe.
1898
- * @returns An object with the element's width and height.
1838
+ * @param namespace The namespace for the token context.
1839
+ * @param tokens The tokens to use.
1840
+ * @template Z The type of the token ticket.
1841
+ * @template E The type of the token context.
1842
+ * @returns A new token context.
1899
1843
  *
1900
- * @see https://0.vuetifyjs.com/composables/system/use-resize-observer#use-element-size
1844
+ * @see https://0.vuetifyjs.com/composables/registration/use-tokens
1901
1845
  *
1902
1846
  * @example
1903
1847
  * ```ts
1904
- * import { ref, watchEffect } from 'vue'
1905
- * import { useElementSize } from '@vuetify/v0'
1906
- *
1907
- * const box = ref<HTMLElement>()
1908
- * const { width, height } = useElementSize(box)
1848
+ * import { createTokensContext } from '@vuetify/v0'
1909
1849
  *
1910
- * // Width and height are reactive refs
1911
- * watchEffect(() => {
1912
- * console.log('Box size:', width.value, 'x', height.value)
1850
+ * export const [useTokens, provideTokens, context] = createTokensContext({
1851
+ * namespace: 'v0:tokens',
1852
+ * tokens: {
1853
+ * colors: {
1854
+ * primary: '#3b82f6',
1855
+ * secondary: '{colors.primary}', // Alias reference
1856
+ * },
1857
+ * },
1913
1858
  * })
1914
1859
  * ```
1915
1860
  */
1916
- function useElementSize(target) {
1917
- const width = shallowRef(0);
1918
- const height = shallowRef(0);
1919
- const { pause: _pause, resume, stop, isActive, isPaused } = useResizeObserver(target, (entries) => {
1920
- const entry = entries[0];
1921
- if (entry) {
1922
- width.value = entry.contentRect.width;
1923
- height.value = entry.contentRect.height;
1924
- }
1925
- }, { immediate: true });
1926
- function pause() {
1927
- width.value = 0;
1928
- height.value = 0;
1929
- _pause();
1861
+ function createTokensContext(_options) {
1862
+ const { namespace = "v0:tokens", tokens = {}, ...options } = _options;
1863
+ const [useTokensContext, _provideTokensContext] = createContext(namespace);
1864
+ const context = createTokens(tokens, options);
1865
+ function provideTokensContext(_context = context, app) {
1866
+ return _provideTokensContext(_context, app);
1930
1867
  }
1931
- return {
1932
- width,
1933
- height,
1934
- isActive,
1935
- isPaused,
1936
- pause,
1937
- resume,
1938
- stop
1939
- };
1868
+ return createTrinity(useTokensContext, provideTokensContext, context);
1940
1869
  }
1941
-
1942
- //#endregion
1943
- //#region src/composables/useOverflow/index.ts
1944
1870
  /**
1945
- * @module useOverflow
1946
- *
1947
- * @remarks
1948
- * Composable for computing how many items fit in a container based on available width.
1949
- * Enables responsive truncation logic for Pagination, Breadcrumbs, and similar components.
1871
+ * Returns the current tokens instance.
1950
1872
  *
1951
- * Key features:
1952
- * - Container width tracking via ResizeObserver
1953
- * - Two modes: variable-width (per-item) or uniform-width (sample-based)
1954
- * - Computes capacity (how many items fit)
1955
- * - SSR-safe with Infinity fallback
1956
- * - Supports reserved space for nav buttons, ellipsis, etc.
1957
- *
1958
- * Use variable mode (default) for items with different widths like Breadcrumbs.
1959
- * Use uniform mode (itemWidth option) for same-width items like Pagination buttons.
1960
- */
1961
- /**
1962
- * Creates a new overflow context for computing how many items fit in a container.
1873
+ * @param namespace The namespace for the tokens context. Defaults to `'v0:tokens'`.
1874
+ * @returns The current tokens instance.
1963
1875
  *
1964
- * @param options Configuration options
1965
- * @returns Overflow context with container ref, capacity, and measurement functions
1876
+ * @see https://0.vuetifyjs.com/composables/registration/use-tokens
1966
1877
  *
1967
- * @example Variable-width mode (Breadcrumbs)
1878
+ * @example
1968
1879
  * ```vue
1969
- * <script lang="ts" setup>
1970
- * import { useTemplateRef } from 'vue'
1971
- * import { createOverflow } from '@vuetify/v0'
1880
+ * <script setup lang="ts">
1881
+ * import { useTokens } from '@vuetify/v0'
1972
1882
  *
1973
- * const containerRef = useTemplateRef('container')
1974
- * const overflow = createOverflow({
1975
- * container: containerRef,
1976
- * gap: 8,
1977
- * reserved: 40,
1978
- * })
1883
+ * const tokens = useTokens()
1979
1884
  * <\/script>
1980
- *
1981
- * <template>
1982
- * <div ref="container">
1983
- * <span
1984
- * v-for="(item, i) in items.slice(0, overflow.capacity.value)"
1985
- * :key="i"
1986
- * :ref="el => overflow.measure(i, el)"
1987
- * >
1988
- * {{ item }}
1989
- * </span>
1990
- * <span v-if="overflow.isOverflowing.value">...</span>
1991
- * </div>
1992
- * </template>
1993
- * ```
1994
- *
1995
- * @example Uniform-width mode (Pagination)
1996
- * ```ts
1997
- * const overflow = createOverflow({
1998
- * container: () => atom.value?.element,
1999
- * itemWidth: buttonWidth,
2000
- * reserved: () => buttonWidth.value * 4,
2001
- * })
2002
1885
  * ```
2003
1886
  */
2004
- function createOverflow(options = {}) {
2005
- const { container: _container, gap = 0, reserved = 0, itemWidth, reverse } = options;
2006
- const container = /* @__PURE__ */ isUndefined(_container) ? shallowRef() : toRef(_container);
2007
- const widths = shallowRef(/* @__PURE__ */ new Map());
2008
- const { width } = useElementSize(container);
2009
- function measure(index, el) {
2010
- if (!el) {
2011
- if (widths.value.has(index)) {
2012
- const next = new Map(widths.value);
2013
- next.delete(index);
2014
- widths.value = next;
1887
+ function useTokens(namespace = "v0:tokens") {
1888
+ return useContext(namespace);
1889
+ }
1890
+ /**
1891
+ * Flattens a nested collection of tokens into a flat array of tokens.
1892
+ * Each token is represented by an object containing its ID & value.
1893
+ * @param tokens The collection of tokens to flatten.
1894
+ * @param prefix An optional prefix to prepend to each token ID.
1895
+ * @returns An array of flattened tokens, each with an ID and value.
1896
+ */
1897
+ function flatten(tokens, prefix = "", flat = false) {
1898
+ const flattened = [];
1899
+ const stack = [{
1900
+ tokens,
1901
+ prefix,
1902
+ flat
1903
+ }];
1904
+ while (stack.length > 0) {
1905
+ const { tokens: currentTokens, prefix: currentPrefix, flat: flat$1 } = stack.pop();
1906
+ const meta = {};
1907
+ for (const k in currentTokens) if (k.startsWith("$")) meta[k] = currentTokens[k];
1908
+ if (Object.keys(meta).length > 0 && currentPrefix) flattened.push({
1909
+ id: currentPrefix,
1910
+ value: meta
1911
+ });
1912
+ for (const key in currentTokens) {
1913
+ if (key.startsWith("$")) continue;
1914
+ const value = currentTokens[key];
1915
+ const id = currentPrefix ? `${currentPrefix}.${key}` : key;
1916
+ if (!/* @__PURE__ */ isObject(value)) {
1917
+ flattened.push({
1918
+ id,
1919
+ value
1920
+ });
1921
+ continue;
2015
1922
  }
2016
- return;
1923
+ if ("$value" in value) {
1924
+ flattened.push({
1925
+ id,
1926
+ value
1927
+ });
1928
+ const inner = value.$value;
1929
+ if (/* @__PURE__ */ isObject(inner) && !flat$1) for (const innerKey in inner) {
1930
+ if (innerKey.startsWith("$")) continue;
1931
+ const child = inner[innerKey];
1932
+ const childId = `${id}.${innerKey}`;
1933
+ if (!/* @__PURE__ */ isObject(child)) flattened.push({
1934
+ id: childId,
1935
+ value: child
1936
+ });
1937
+ else if ("$value" in child) flattened.push({
1938
+ id: childId,
1939
+ value: child
1940
+ });
1941
+ else stack.push({
1942
+ tokens: child,
1943
+ prefix: childId,
1944
+ flat: flat$1
1945
+ });
1946
+ }
1947
+ continue;
1948
+ }
1949
+ if (flat$1) {
1950
+ flattened.push({
1951
+ id,
1952
+ value
1953
+ });
1954
+ continue;
1955
+ }
1956
+ stack.push({
1957
+ tokens: value,
1958
+ prefix: id,
1959
+ flat: flat$1
1960
+ });
2017
1961
  }
2018
- const style = getComputedStyle(el);
2019
- const marginX = Number.parseFloat(style.marginLeft) + Number.parseFloat(style.marginRight);
2020
- const w = el.offsetWidth + marginX;
2021
- if (widths.value.get(index) !== w) widths.value = new Map(widths.value).set(index, w);
2022
1962
  }
2023
- function reset() {
2024
- widths.value = /* @__PURE__ */ new Map();
1963
+ return flattened;
1964
+ }
1965
+
1966
+ //#endregion
1967
+ //#region src/composables/useLocale/index.ts
1968
+ /**
1969
+ * Creates a new locale instance.
1970
+ *
1971
+ * @param options The options for the locale instance.
1972
+ * @template Z The type of the locale ticket.
1973
+ * @template E The type of the locale context.
1974
+ * @returns A new locale instance.
1975
+ *
1976
+ * @see https://0.vuetifyjs.com/composables/plugins/use-locale
1977
+ */
1978
+ function createLocale(_options = {}) {
1979
+ const { adapter = new Vuetify0LocaleAdapter(), messages = {}, ...options } = _options;
1980
+ const tokens = createTokens(messages);
1981
+ const registry = createSingle(options);
1982
+ for (const id in messages) {
1983
+ registry.register({ id });
1984
+ if (id === options.default && !registry.selectedId.value) registry.select(id);
2025
1985
  }
2026
- const total = computed(() => {
2027
- const g = toValue(gap);
2028
- let sum = 0;
2029
- let count = 0;
2030
- for (const w of widths.value.values()) {
2031
- sum += w + (count > 0 ? g : 0);
2032
- count++;
1986
+ function t(key, params, fallback) {
1987
+ const locale = registry.selectedId.value;
1988
+ const args = toArray(params);
1989
+ if (!locale) return adapter.t(fallback ?? key, ...args);
1990
+ const path = `${locale}.${key}`;
1991
+ const message = tokens.get(path)?.value;
1992
+ const template = /* @__PURE__ */ isString(message) ? resolve(locale, message) : fallback ?? key;
1993
+ return adapter.t(template, ...args);
1994
+ }
1995
+ function n(value, ...params) {
1996
+ return adapter.n(value, registry.selectedId.value, ...params);
1997
+ }
1998
+ function resolve(locale, str) {
1999
+ return str.replace(/{([a-zA-Z0-9.-_]+)}/g, (match, key) => {
2000
+ const [prefix, ...rest] = key.split(".");
2001
+ const target = registry.has(prefix) ? prefix : locale;
2002
+ const path = `${target}.${registry.has(prefix) ? rest.join(".") : key}`;
2003
+ const resolved = tokens.get(path)?.value;
2004
+ if (/* @__PURE__ */ isString(resolved)) return resolve(target, resolved);
2005
+ return match;
2006
+ });
2007
+ }
2008
+ return {
2009
+ ...registry,
2010
+ t,
2011
+ n,
2012
+ get size() {
2013
+ return registry.size;
2033
2014
  }
2034
- return sum;
2035
- });
2015
+ };
2016
+ }
2017
+ function createLocaleFallback() {
2036
2018
  return {
2037
- container,
2038
- width,
2039
- capacity: computed(() => {
2040
- const available = width.value - toValue(reserved);
2041
- if (width.value === 0) return Infinity;
2042
- if (available <= 0) return 0;
2043
- const g = toValue(gap);
2044
- const uniformWidth = toValue(itemWidth);
2045
- if (uniformWidth && uniformWidth > 0) {
2046
- const first = uniformWidth;
2047
- const subsequent = uniformWidth + g;
2048
- if (available < first) return 0;
2049
- return Math.max(1, Math.floor((available - first) / subsequent) + 1);
2050
- }
2051
- const entries = [...widths.value.entries()].toSorted((a, b) => a[0] - b[0]);
2052
- if (toValue(reverse)) entries.reverse();
2053
- let sum = 0;
2054
- let count = 0;
2055
- for (const [, w] of entries) {
2056
- const next = sum + w + (count > 0 ? g : 0);
2057
- if (next > available) break;
2058
- sum = next;
2059
- count++;
2060
- }
2061
- return count;
2062
- }),
2063
- total,
2064
- isOverflowing: toRef(() => {
2065
- return total.value > width.value - toValue(reserved);
2066
- }),
2067
- measure,
2068
- reset
2019
+ size: 0,
2020
+ t: (key, _params, fallback) => fallback ?? key,
2021
+ n: String
2069
2022
  };
2070
2023
  }
2071
2024
  /**
2072
- * Creates an overflow context with dependency injection support.
2025
+ * Creates a new locale context.
2073
2026
  *
2074
- * @param options Configuration options including namespace
2075
- * @returns Trinity tuple: [useContext, provideContext, defaultContext]
2027
+ * @param options The options for the locale context.
2028
+ * @template Z The type of the locale ticket.
2029
+ * @template E The type of the locale context.
2030
+ * @returns A new locale context.
2031
+ *
2032
+ * @see https://0.vuetifyjs.com/composables/plugins/use-locale
2076
2033
  *
2077
2034
  * @example
2078
2035
  * ```ts
2079
- * // Create injectable context
2080
- * const [useOverflow, provideOverflow, overflow] = createOverflowContext({
2081
- * namespace: 'my-overflow',
2082
- * gap: 8,
2083
- * reserved: 160,
2036
+ * import { createLocaleContext } from '@vuetify/v0'
2037
+ *
2038
+ * export const [useAppLocale, provideAppLocale, appLocale] = createLocaleContext({
2039
+ * namespace: 'app:locale',
2040
+ * messages: {
2041
+ * en: { hello: 'Hello' },
2042
+ * es: { hello: 'Hola' },
2043
+ * },
2084
2044
  * })
2085
2045
  *
2086
- * // In parent component
2087
- * provideOverflow()
2046
+ * // In a parent component:
2047
+ * provideAppLocale()
2088
2048
  *
2089
- * // In child component
2090
- * const overflow = useOverflow()
2049
+ * // In a child component:
2050
+ * const locale = useAppLocale()
2051
+ * locale.select('es')
2091
2052
  * ```
2092
2053
  */
2093
- function createOverflowContext(_options = {}) {
2094
- const { namespace = "v0:overflow",...options } = _options;
2095
- const [useOverflowContext, _provideOverflowContext] = createContext(namespace);
2096
- const context = createOverflow(options);
2097
- function provideOverflowContext(_context = context, app) {
2098
- return _provideOverflowContext(_context, app);
2054
+ function createLocaleContext(_options = {}) {
2055
+ const { namespace = "v0:locale", ...options } = _options;
2056
+ const [useLocaleContext, _provideLocaleContext] = createContext(namespace);
2057
+ const context = createLocale(options);
2058
+ function provideLocaleContext(_context = context, app) {
2059
+ return _provideLocaleContext(_context, app);
2099
2060
  }
2100
- return createTrinity(useOverflowContext, provideOverflowContext, context);
2061
+ return createTrinity(useLocaleContext, provideLocaleContext, context);
2101
2062
  }
2102
2063
  /**
2103
- * Returns the current overflow context from dependency injection.
2104
- *
2105
- * @param namespace The namespace for the overflow context. Defaults to `v0:overflow`.
2106
- * @returns The current overflow context.
2107
- *
2108
- * @example
2109
- * ```vue
2110
- * <script lang="ts" setup>
2111
- * import { useOverflow } from '@vuetify/v0'
2064
+ * Creates a new locale plugin.
2112
2065
  *
2113
- * // Inject overflow context provided by parent
2114
- * const overflow = useOverflow()
2115
- * <\/script>
2066
+ * @param options The options for the locale plugin.
2067
+ * @template Z The type of the locale ticket.
2068
+ * @template E The type of the locale context.
2069
+ * @template R The type of the token ticket.
2070
+ * @template O The type of the token context.
2071
+ * @returns A new locale plugin.
2116
2072
  *
2117
- * <template>
2118
- * <div>
2119
- * <p>Capacity: {{ overflow.capacity.value }}</p>
2120
- * </div>
2121
- * </template>
2122
- * ```
2073
+ * @see https://0.vuetifyjs.com/composables/plugins/use-locale
2123
2074
  */
2124
- function useOverflow(namespace = "v0:overflow") {
2125
- return useContext(namespace);
2075
+ function createLocalePlugin(_options = {}) {
2076
+ const { namespace = "v0:locale", adapter = new Vuetify0LocaleAdapter(), messages = {}, ...options } = _options;
2077
+ const [, provideLocaleContext, context] = createLocaleContext({
2078
+ ...options,
2079
+ namespace,
2080
+ adapter,
2081
+ messages
2082
+ });
2083
+ return createPlugin({
2084
+ namespace,
2085
+ provide: (app) => {
2086
+ provideLocaleContext(context, app);
2087
+ }
2088
+ });
2126
2089
  }
2127
-
2128
- //#endregion
2129
- //#region src/composables/usePagination/index.ts
2130
- /**
2131
- * @module usePagination
2132
- *
2133
- * @remarks
2134
- * Lightweight pagination composable for navigating through pages.
2135
- *
2136
- * Key features:
2137
- * - No registry overhead - just a bounded integer
2138
- * - Direct ref support for v-model compatibility
2139
- * - Navigation methods: next, prev, first, last
2140
- * - Computed visible items with ellipsis
2141
- * - Trinity pattern for dependency injection
2142
- *
2143
- * Unlike registry-based composables, pagination tracks a single number
2144
- * within a range, making it efficient for large page counts.
2145
- */
2146
2090
  /**
2147
- * Creates a pagination instance.
2148
- *
2149
- * @param options The options for the pagination instance.
2150
- * @returns A pagination context with navigation methods.
2151
- *
2152
- * @example
2153
- * ```ts
2154
- * import { createPagination } from '@vuetify/v0'
2091
+ * Returns the current locale instance.
2155
2092
  *
2156
- * // Basic usage
2157
- * const pagination = createPagination({ size: 100 })
2158
- * pagination.next()
2159
- * pagination.items.value // [{ type: 'page', value: 1 }, { type: 'page', value: 2 }, ...]
2093
+ * @returns The current locale instance.
2160
2094
  *
2161
- * // With v-model (pass a ref)
2162
- * const page = ref(1)
2163
- * const pagination = createPagination({ page, size: 100 })
2164
- * // Mutating pagination.page or the passed ref syncs both
2165
- * ```
2095
+ * @see https://0.vuetifyjs.com/composables/plugins/use-locale
2166
2096
  */
2167
- function createPagination(_options = {}) {
2168
- const { page: _page = 1, itemsPerPage: _itemsPerPage = 10, size: _size = 0, visible: _visible = 7, ellipsis = "..." } = _options;
2169
- const page = isRef(_page) ? _page : shallowRef(_page);
2170
- const pages = computed(() => {
2171
- const size = toValue(_size);
2172
- const perPage = toValue(_itemsPerPage);
2173
- if (size <= 0 || /* @__PURE__ */ isNaN(size)) return 0;
2174
- return Math.ceil(size / perPage);
2175
- });
2176
- function first() {
2177
- page.value = 1;
2178
- }
2179
- function last() {
2180
- page.value = Math.max(1, pages.value);
2181
- }
2182
- function next() {
2183
- if (page.value < pages.value) page.value++;
2184
- }
2185
- function prev() {
2186
- if (page.value > 1) page.value--;
2187
- }
2188
- function select(value) {
2189
- if (value < 1) page.value = 1;
2190
- else if (value > pages.value) page.value = Math.max(1, pages.value);
2191
- else page.value = value;
2192
- }
2193
- const isFirst = computed(() => page.value <= 1);
2194
- const isLast = computed(() => page.value >= pages.value);
2195
- const pageStart = computed(() => (page.value - 1) * toValue(_itemsPerPage));
2196
- const pageStop = computed(() => Math.min(pageStart.value + toValue(_itemsPerPage), toValue(_size)));
2197
- function toPage(value) {
2198
- return {
2199
- type: "page",
2200
- value
2201
- };
2202
- }
2203
- function toEllipsis() {
2204
- return ellipsis === false ? false : {
2205
- type: "ellipsis",
2206
- value: ellipsis
2207
- };
2208
- }
2209
- function filter(array) {
2210
- return array.filter(Boolean);
2097
+ function useLocale(namespace = "v0:locale") {
2098
+ const fallback = createLocaleFallback();
2099
+ if (!getCurrentInstance()) return fallback;
2100
+ try {
2101
+ return useContext(namespace, fallback);
2102
+ } catch {
2103
+ return fallback;
2211
2104
  }
2212
- return {
2213
- page,
2214
- ellipsis,
2215
- items: computed(() => {
2216
- const pageCount = pages.value;
2217
- const visible = toValue(_visible);
2218
- const current = page.value;
2219
- if (pageCount <= 0 || /* @__PURE__ */ isNaN(pageCount) || pageCount > Number.MAX_SAFE_INTEGER) return [];
2220
- if (visible <= 0) return [];
2221
- if (visible <= 2) return [toPage(current)];
2222
- if (pageCount <= visible) return (/* @__PURE__ */ range(pageCount, 1)).map(toPage);
2223
- if (visible === 3) {
2224
- const mid = current <= 1 ? 2 : current >= pageCount ? pageCount - 1 : current;
2225
- return [
2226
- toPage(1),
2227
- toPage(mid),
2228
- toPage(pageCount)
2229
- ];
2230
- }
2231
- const boundary = visible - 2;
2232
- const middle = visible - 4;
2233
- if (middle <= 0) {
2234
- if (current <= boundary) return filter([
2235
- ...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
2236
- toEllipsis(),
2237
- toPage(pageCount)
2238
- ]);
2239
- if (current > pageCount - boundary) return filter([
2240
- toPage(1),
2241
- toEllipsis(),
2242
- ...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
2243
- ]);
2244
- return current <= Math.ceil(pageCount / 2) ? filter([
2245
- toPage(1),
2246
- toPage(current),
2247
- toEllipsis(),
2248
- toPage(pageCount)
2249
- ]) : filter([
2250
- toPage(1),
2251
- toEllipsis(),
2252
- toPage(current),
2253
- toPage(pageCount)
2254
- ]);
2255
- }
2256
- const leftThreshold = boundary - 1;
2257
- const rightThreshold = pageCount - boundary + 2;
2258
- if (current <= leftThreshold) return filter([
2259
- ...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
2260
- toEllipsis(),
2261
- toPage(pageCount)
2262
- ]);
2263
- else if (current >= rightThreshold) return filter([
2264
- toPage(1),
2265
- toEllipsis(),
2266
- ...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
2267
- ]);
2268
- else {
2269
- const start = current - Math.floor(middle / 2);
2270
- return filter([
2271
- toPage(1),
2272
- toEllipsis(),
2273
- ...(/* @__PURE__ */ range(middle, start)).map(toPage),
2274
- toEllipsis(),
2275
- toPage(pageCount)
2276
- ]);
2277
- }
2278
- }),
2279
- pageStart,
2280
- pageStop,
2281
- isFirst,
2282
- isLast,
2283
- first,
2284
- last,
2285
- next,
2286
- prev,
2287
- select,
2288
- get itemsPerPage() {
2289
- return toValue(_itemsPerPage);
2290
- },
2291
- get size() {
2292
- return toValue(_size);
2293
- },
2294
- get pages() {
2295
- return pages.value;
2296
- }
2105
+ }
2106
+
2107
+ //#endregion
2108
+ //#region src/composables/useHydration/index.ts
2109
+ /**
2110
+ * Creates a new hydration instance.
2111
+ *
2112
+ * @returns A new hydration instance.
2113
+ *
2114
+ * @see https://0.vuetifyjs.com/composables/plugins/use-hydration
2115
+ *
2116
+ * @example
2117
+ * ```ts
2118
+ * import { createHydration } from '@vuetify/v0'
2119
+ *
2120
+ * const hydration = createHydration()
2121
+ * console.log(hydration.isHydrated.value) // false
2122
+ * hydration.hydrate()
2123
+ * console.log(hydration.isHydrated.value) // true
2124
+ * ```
2125
+ */
2126
+ function createHydration() {
2127
+ const isHydrated = shallowRef(false);
2128
+ function hydrate() {
2129
+ isHydrated.value = true;
2130
+ }
2131
+ return {
2132
+ isHydrated: shallowReadonly(isHydrated),
2133
+ hydrate
2134
+ };
2135
+ }
2136
+ function createFallbackHydration() {
2137
+ return {
2138
+ isHydrated: shallowReadonly(shallowRef(true)),
2139
+ hydrate: () => {}
2297
2140
  };
2298
2141
  }
2299
2142
  /**
2300
- * Creates a pagination context for dependency injection.
2143
+ * Creates a new hydration context trinity.
2301
2144
  *
2302
- * @param options The options including namespace.
2303
- * @returns A trinity: [usePagination, providePagination, defaultContext]
2145
+ * @param options Options for creating the hydration context.
2146
+ * @template E The type of the hydration context.
2147
+ * @returns A new hydration context trinity.
2148
+ *
2149
+ * @see https://0.vuetifyjs.com/composables/plugins/use-hydration
2304
2150
  *
2305
2151
  * @example
2306
2152
  * ```ts
2307
- * // With default namespace 'v0:pagination'
2308
- * const [usePagination, providePaginationContext] = createPaginationContext({ size: 50 })
2153
+ * import { createHydrationContext } from '@vuetify/v0'
2309
2154
  *
2310
- * // Or with custom namespace
2311
- * const [usePagination, providePaginationContext] = createPaginationContext({
2312
- * namespace: 'my-pagination',
2313
- * size: 50,
2155
+ * export const [useHydrationContext, provideHydrationContext, context] = createHydrationContext({
2156
+ * namespace: 'app:hydration',
2314
2157
  * })
2158
+ * ```
2159
+ */
2160
+ function createHydrationContext(_options = {}) {
2161
+ const { namespace = "v0:hydration" } = _options;
2162
+ const [useHydrationContext, _provideHydrationContext] = createContext(namespace);
2163
+ const context = createHydration();
2164
+ function provideHydrationContext(_context = context, app) {
2165
+ return _provideHydrationContext(_context, app);
2166
+ }
2167
+ return createTrinity(useHydrationContext, provideHydrationContext, context);
2168
+ }
2169
+ /**
2170
+ * Creates a new hydration plugin.
2315
2171
  *
2316
- * // Parent component
2317
- * providePaginationContext()
2172
+ * @param options The options for the hydration plugin.
2173
+ * @template E The type of the hydration context.
2174
+ * @returns A new hydration plugin.
2318
2175
  *
2319
- * // Child component
2320
- * const pagination = usePagination()
2321
- * pagination.next()
2176
+ * @see https://0.vuetifyjs.com/composables/plugins/use-hydration
2177
+ *
2178
+ * @example
2179
+ * ```ts
2180
+ * import { createApp } from 'vue'
2181
+ * import { createHydrationPlugin } from '@vuetify/v0'
2182
+ * import App from './App.vue'
2183
+ *
2184
+ * const app = createApp(App)
2185
+ *
2186
+ * app.use(createHydrationPlugin())
2187
+ *
2188
+ * app.mount('#app')
2322
2189
  * ```
2323
2190
  */
2324
- function createPaginationContext(_options = {}) {
2325
- const { namespace = "v0:pagination",...options } = _options;
2326
- const [usePaginationContext, _providePaginationContext] = createContext(namespace);
2327
- const context = createPagination(options);
2328
- function providePaginationContext(_context = context, app) {
2329
- return _providePaginationContext(_context, app);
2330
- }
2331
- return createTrinity(usePaginationContext, providePaginationContext, context);
2191
+ function createHydrationPlugin(_options = {}) {
2192
+ const { namespace = "v0:hydration", ...options } = _options;
2193
+ const [, provideHydrationContext, context] = createHydrationContext({
2194
+ ...options,
2195
+ namespace
2196
+ });
2197
+ return createPlugin({
2198
+ namespace,
2199
+ provide: (app) => {
2200
+ provideHydrationContext(context, app);
2201
+ },
2202
+ setup: (app) => {
2203
+ app.mixin({ mounted() {
2204
+ if (this.$parent !== null) return;
2205
+ context.hydrate();
2206
+ } });
2207
+ }
2208
+ });
2332
2209
  }
2333
2210
  /**
2334
- * Returns the current pagination instance from context.
2211
+ * Returns the current hydration instance.
2335
2212
  *
2336
- * @param namespace The namespace. @default 'v0:pagination'
2337
- * @returns The pagination context.
2213
+ * @param namespace The namespace for the hydration context. Defaults to `v0:hydration`.
2214
+ * @returns The current hydration instance.
2215
+ *
2216
+ * @see https://0.vuetifyjs.com/composables/plugins/use-hydration
2338
2217
  *
2339
2218
  * @example
2340
2219
  * ```vue
2341
- * <script setup>
2342
- * import { usePagination } from '@vuetify/v0'
2220
+ * <script setup lang="ts">
2221
+ * import { useHydration } from '@vuetify/v0'
2343
2222
  *
2344
- * const pagination = usePagination()
2223
+ * const hydration = useHydration()
2345
2224
  * <\/script>
2346
2225
  *
2347
2226
  * <template>
2348
- * <button @click="pagination.prev()" :disabled="pagination.isFirst.value">Prev</button>
2349
- * <button @click="pagination.next()" :disabled="pagination.isLast.value">Next</button>
2227
+ * <div>
2228
+ * <p>Is hydrated: {{ hydration.isHydrated.value }}</p>
2229
+ * </div>
2350
2230
  * </template>
2351
2231
  * ```
2352
2232
  */
2353
- function usePagination(namespace = "v0:pagination") {
2354
- return useContext(namespace);
2233
+ function useHydration(namespace = "v0:hydration") {
2234
+ const fallback = createFallbackHydration();
2235
+ if (!getCurrentInstance()) return fallback;
2236
+ try {
2237
+ return useContext(namespace, fallback);
2238
+ } catch {
2239
+ return fallback;
2240
+ }
2355
2241
  }
2356
2242
 
2357
2243
  //#endregion
2358
- //#region src/composables/useSingle/index.ts
2359
- /**
2360
- * @module useSingle
2361
- *
2362
- * @remarks
2363
- * Single-selection composable that extends useSelection to enforce only one selected item.
2364
- *
2365
- * Key features:
2366
- * - Auto-clears previous selection when selecting new item
2367
- * - Singular computed properties (selectedId, selectedItem, selectedIndex, selectedValue)
2368
- * - Perfect for tabs, radio buttons, theme selectors
2369
- *
2370
- * Inheritance chain: useRegistry → useSelection → useSingle
2371
- */
2244
+ //#region src/composables/useResizeObserver/index.ts
2372
2245
  /**
2373
- * Creates a new single selection instance that enforces only one selected item at a time.
2374
- *
2375
- * Extends `createSelection` by automatically clearing previous selections when a new item is selected.
2376
- * Adds computed singular properties: `selectedId`, `selectedItem`, `selectedIndex`, `selectedValue`.
2377
- *
2378
- * @param options The options for the single selection instance.
2379
- * @template Z The type of the single selection ticket.
2380
- * @template E The type of the single selection context.
2381
- * @returns A new single selection instance with single-selection enforcement.
2382
- *
2383
- * @remarks
2384
- * **Key Differences from `createSelection`:**
2385
- * - Automatically clears `selectedIds` before selecting a new item (enforces single selection)
2386
- * - Provides singular computed properties instead of plural sets
2387
- * - Perfect for tabs, radio buttons, theme selectors, and other single-choice UI components
2388
- *
2389
- * **Computed Properties:**
2390
- * - `selectedId`: The ID of the selected item (undefined if none selected)
2391
- * - `selectedItem`: The selected ticket object (undefined if none selected)
2392
- * - `selectedIndex`: The index of the selected item (-1 if none selected)
2393
- * - `selectedValue`: The value of the selected item (undefined if none selected)
2246
+ * A composable that uses the Resize Observer API to detect when an element's
2247
+ * size changes.
2394
2248
  *
2395
- * **Inheritance Chain:**
2396
- * `useRegistry` `createSelection` `createSingle` `createStep`
2249
+ * @param target The element to observe.
2250
+ * @param callback The callback to execute when the element's size changes.
2251
+ * @param options The options for the Resize Observer.
2252
+ * @returns An object with methods to control the observer.
2397
2253
  *
2398
- * @see https://0.vuetifyjs.com/composables/selection/use-single
2254
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
2255
+ * @see https://0.vuetifyjs.com/composables/system/use-resize-observer
2399
2256
  *
2400
2257
  * @example
2401
2258
  * ```ts
2402
- * import { createSingle } from '@vuetify/v0'
2403
- *
2404
- * const tabs = createSingle({ mandatory: true })
2259
+ * import { ref } from 'vue'
2260
+ * import { useResizeObserver } from '@vuetify/v0'
2405
2261
  *
2406
- * tabs.onboard([
2407
- * { id: 'home', value: 'Home' },
2408
- * { id: 'about', value: 'About' },
2409
- * { id: 'contact', value: 'Contact' },
2410
- * ])
2262
+ * const el = ref<HTMLElement>()
2263
+ * const width = ref(0)
2264
+ * const height = ref(0)
2411
2265
  *
2412
- * tabs.first() // Select first tab
2266
+ * const { pause, resume, isPaused } = useResizeObserver(
2267
+ * el,
2268
+ * (entries) => {
2269
+ * const entry = entries[0]
2270
+ * if (entry) {
2271
+ * width.value = entry.contentRect.width
2272
+ * height.value = entry.contentRect.height
2273
+ * console.log('Size changed:', width.value, 'x', height.value)
2274
+ * }
2275
+ * },
2276
+ * { immediate: true }
2277
+ * )
2413
2278
  *
2414
- * console.log(tabs.selectedId.value) // 'home'
2415
- * console.log(tabs.selectedIndex.value) // 0
2279
+ * // Pause observation
2280
+ * pause()
2416
2281
  *
2417
- * tabs.select('about') // Switch to about tab
2418
- * console.log(tabs.selectedId.value) // 'about'
2419
- * console.log(tabs.selectedIds.size) // 1 (always enforces single selection)
2282
+ * // Resume observation
2283
+ * resume()
2420
2284
  * ```
2421
2285
  */
2422
- function createSingle(_options = {}) {
2423
- const { mandatory = false, multiple = false,...options } = _options;
2424
- const registry = createSelection({
2425
- ...options,
2426
- mandatory,
2427
- multiple
2286
+ function useResizeObserver(target, callback, options = {}) {
2287
+ const { isHydrated } = useHydration();
2288
+ const observer = shallowRef();
2289
+ const isPaused = shallowRef(false);
2290
+ const isActive = toRef(() => !!observer.value);
2291
+ function setup() {
2292
+ if (observer.value === null) return;
2293
+ if (!isHydrated.value || !SUPPORTS_OBSERVER || !target.value || isPaused.value) return;
2294
+ observer.value = new ResizeObserver((entries) => {
2295
+ callback(entries.map((entry) => ({
2296
+ contentRect: {
2297
+ width: entry.contentRect.width,
2298
+ height: entry.contentRect.height,
2299
+ top: entry.contentRect.top,
2300
+ left: entry.contentRect.left
2301
+ },
2302
+ target: entry.target
2303
+ })));
2304
+ if (options.once) stop();
2305
+ });
2306
+ observer.value.observe(target.value, { box: options.box || "content-box" });
2307
+ if (options.immediate) {
2308
+ const rect = target.value.getBoundingClientRect();
2309
+ callback([{
2310
+ contentRect: {
2311
+ width: rect.width,
2312
+ height: rect.height,
2313
+ top: rect.top,
2314
+ left: rect.left
2315
+ },
2316
+ target: target.value
2317
+ }]);
2318
+ }
2319
+ }
2320
+ watchEffect(() => {
2321
+ const hydrated = isHydrated.value;
2322
+ const el = target.value;
2323
+ cleanup();
2324
+ if (hydrated && el) setup();
2428
2325
  });
2429
- const selectedId = computed(() => registry.selectedIds.values().next().value);
2430
- const selectedItem = computed(() => registry.selectedItems.value.values().next().value);
2431
- const selectedIndex = computed(() => selectedItem.value?.index ?? -1);
2432
- const selectedValue = computed(() => selectedItem.value?.value);
2433
- function unselect(id) {
2434
- if (mandatory && registry.selectedIds.size === 1) return;
2435
- registry.selectedIds.delete(id);
2326
+ function cleanup() {
2327
+ if (observer.value) {
2328
+ observer.value.disconnect();
2329
+ observer.value = void 0;
2330
+ }
2436
2331
  }
2437
- function toggle(id) {
2438
- if (registry.selectedIds.has(id)) unselect(id);
2439
- else registry.select(id);
2332
+ function pause() {
2333
+ isPaused.value = true;
2334
+ observer.value?.disconnect();
2335
+ }
2336
+ function resume() {
2337
+ isPaused.value = false;
2338
+ setup();
2339
+ }
2340
+ function stop() {
2341
+ cleanup();
2342
+ observer.value = null;
2440
2343
  }
2344
+ onScopeDispose(stop, true);
2441
2345
  return {
2442
- ...registry,
2443
- selectedId,
2444
- selectedItem,
2445
- selectedIndex,
2446
- selectedValue,
2447
- unselect,
2448
- toggle,
2449
- get size() {
2450
- return registry.size;
2451
- }
2346
+ isActive: shallowReadonly(isActive),
2347
+ isPaused: shallowReadonly(isPaused),
2348
+ pause,
2349
+ resume,
2350
+ stop
2452
2351
  };
2453
2352
  }
2454
2353
  /**
2455
- * Creates a new single selection context.
2354
+ * A convenience composable that uses the Resize Observer API to track an
2355
+ * element's size.
2456
2356
  *
2457
- * @param options The options for the single selection context.
2458
- * @template Z The type of the single selection ticket.
2459
- * @template E The type of the single selection context.
2460
- * @returns A new single selection context.
2357
+ * @param target The element to observe.
2358
+ * @returns An object with the element's width and height.
2461
2359
  *
2462
- * @see https://0.vuetifyjs.com/composables/selection/use-single
2360
+ * @see https://0.vuetifyjs.com/composables/system/use-resize-observer#use-element-size
2463
2361
  *
2464
2362
  * @example
2465
2363
  * ```ts
2466
- * import { createSingleContext } from '@vuetify/v0'
2467
- *
2468
- * // With default namespace 'v0:single'
2469
- * export const [useSingle, provideSingle, context] = createSingleContext()
2364
+ * import { ref, watchEffect } from 'vue'
2365
+ * import { useElementSize } from '@vuetify/v0'
2470
2366
  *
2471
- * // In a parent component:
2472
- * provideSingle()
2367
+ * const box = ref<HTMLElement>()
2368
+ * const { width, height } = useElementSize(box)
2473
2369
  *
2474
- * // In a child component:
2475
- * const single = useSingle()
2476
- * single.select('tab-1')
2370
+ * // Width and height are reactive refs
2371
+ * watchEffect(() => {
2372
+ * console.log('Box size:', width.value, 'x', height.value)
2373
+ * })
2477
2374
  * ```
2478
2375
  */
2479
- function createSingleContext(_options = {}) {
2480
- const { namespace = "v0:single",...options } = _options;
2481
- const [useSingleContext, _provideSingleContext] = createContext(namespace);
2482
- const context = createSingle(options);
2483
- function provideSingleContext(_context = context, app) {
2484
- return _provideSingleContext(_context, app);
2376
+ function useElementSize(target) {
2377
+ const width = shallowRef(0);
2378
+ const height = shallowRef(0);
2379
+ const { pause: _pause, resume, stop, isActive, isPaused } = useResizeObserver(target, (entries) => {
2380
+ const entry = entries[0];
2381
+ if (entry) {
2382
+ width.value = entry.contentRect.width;
2383
+ height.value = entry.contentRect.height;
2384
+ }
2385
+ }, { immediate: true });
2386
+ function pause() {
2387
+ width.value = 0;
2388
+ height.value = 0;
2389
+ _pause();
2485
2390
  }
2486
- return createTrinity(useSingleContext, provideSingleContext, context);
2391
+ return {
2392
+ width,
2393
+ height,
2394
+ isActive,
2395
+ isPaused,
2396
+ pause,
2397
+ resume,
2398
+ stop
2399
+ };
2487
2400
  }
2401
+
2402
+ //#endregion
2403
+ //#region src/composables/useOverflow/index.ts
2488
2404
  /**
2489
- * Returns the current single selection instance.
2490
- *
2491
- * @param namespace The namespace for the single selection context. Defaults to `'v0:single'`.
2492
- * @returns The current single selection instance.
2405
+ * Creates a new overflow context for computing how many items fit in a container.
2493
2406
  *
2494
- * @see https://0.vuetifyjs.com/composables/selection/use-single
2407
+ * @param options Configuration options
2408
+ * @returns Overflow context with container ref, capacity, and measurement functions
2495
2409
  *
2496
- * @example
2410
+ * @example Variable-width mode (Breadcrumbs)
2497
2411
  * ```vue
2498
- * <script setup lang="ts">
2499
- * import { useSingle } from '@vuetify/v0'
2412
+ * <script lang="ts" setup>
2413
+ * import { useTemplateRef } from 'vue'
2414
+ * import { createOverflow } from '@vuetify/v0'
2500
2415
  *
2501
- * const tabs = useSingle()
2416
+ * const containerRef = useTemplateRef('container')
2417
+ * const overflow = createOverflow({
2418
+ * container: containerRef,
2419
+ * gap: 8,
2420
+ * reserved: 40,
2421
+ * })
2502
2422
  * <\/script>
2503
2423
  *
2504
2424
  * <template>
2505
- * <div>
2506
- * <p>Selected: {{ tabs.selectedId }}</p>
2425
+ * <div ref="container">
2426
+ * <span
2427
+ * v-for="(item, i) in items.slice(0, overflow.capacity.value)"
2428
+ * :key="i"
2429
+ * :ref="el => overflow.measure(i, el)"
2430
+ * >
2431
+ * {{ item }}
2432
+ * </span>
2433
+ * <span v-if="overflow.isOverflowing.value">...</span>
2507
2434
  * </div>
2508
2435
  * </template>
2509
2436
  * ```
2510
- */
2511
- function useSingle(namespace = "v0:single") {
2512
- return useContext(namespace);
2513
- }
2514
-
2515
- //#endregion
2516
- //#region src/composables/useTokens/index.ts
2517
- /**
2518
- * @module useTokens
2519
- *
2520
- * @see https://0.vuetifyjs.com/composables/registration/use-tokens
2521
- *
2522
- * @remarks
2523
- * Design token registry with alias resolution and W3C Design Tokens format support.
2524
- *
2525
- * Key features:
2526
- * - Alias resolution with circular reference detection
2527
- * - Nested token flattening with dot notation
2528
- * - W3C Design Tokens format ($value, $type, $description, $extensions)
2529
- * - Path-based resolution (e.g., {colors}.blue.500)
2530
- * - Resolution caching for performance (~28,590 ops/sec)
2531
- *
2532
- * Used by useTheme, useLocale, and useFeatures for token-based configuration.
2533
- */
2534
- /**
2535
- * Creates a new token instance.
2536
2437
  *
2537
- * @param tokens The tokens to use.
2538
- * @param options The options for the token instance.
2539
- * @template Z The type of the token ticket.
2540
- * @template E The type of the token context.
2541
- * @returns A new token instance.
2542
- *
2543
- * @see https://www.designtokens.org/tr/drafts/format/
2544
- * @see https://0.vuetifyjs.com/composables/registration/use-tokens
2545
- *
2546
- * @example
2438
+ * @example Uniform-width mode (Pagination)
2547
2439
  * ```ts
2548
- * import { useTokens } from '@vuetify/v0'
2549
- *
2550
- * const tokens = useTokens({
2551
- * colors: {
2552
- * primary: '#3b82f6',
2553
- * secondary: '{colors.primary}', // Alias reference
2554
- * },
2440
+ * const overflow = createOverflow({
2441
+ * container: () => atom.value?.element,
2442
+ * itemWidth: buttonWidth,
2443
+ * reserved: () => buttonWidth.value * 4,
2555
2444
  * })
2556
- *
2557
- * console.log(tokens.resolve('{colors.primary}')) // '#3b82f6'
2558
- * console.log(tokens.resolve('{colors.secondary}')) // '#3b82f6'
2559
2445
  * ```
2560
2446
  */
2561
- function createTokens(tokens = {}, options = {}) {
2562
- const logger = useLogger();
2563
- const registry = useRegistry(options);
2564
- const cache = /* @__PURE__ */ new Map();
2565
- registry.onboard(flatten(tokens, options.prefix, !!options.flat));
2566
- function isAlias(token) {
2567
- return /* @__PURE__ */ isString(token) && token.length > 2 && token[0] === "{" && token.at(-1) === "}";
2568
- }
2569
- function isTokenAlias(value) {
2570
- return /* @__PURE__ */ isObject(value) && "$value" in value;
2571
- }
2572
- function resolve(token, visited = /* @__PURE__ */ new Set()) {
2573
- const cacheKey = /* @__PURE__ */ isString(token) ? token : JSON.stringify(token);
2574
- const cached = cache.get(cacheKey);
2575
- if (!/* @__PURE__ */ isUndefined(cached)) return cached;
2576
- const reference = isTokenAlias(token) ? token.$value : token;
2577
- const isAliasReference = /* @__PURE__ */ isString(reference) && isAlias(reference);
2578
- const clean = isAliasReference ? reference.slice(1, -1) : String(reference);
2579
- if (visited.has(clean)) {
2580
- logger.warn(`Circular alias detected for "${clean}"`);
2581
- cache.set(cacheKey, void 0);
2582
- return;
2583
- }
2584
- visited.add(clean);
2585
- let found = registry.get(clean);
2586
- let segments = [];
2587
- if (!found && clean.includes(".")) {
2588
- const parts = clean.split(".");
2589
- for (let i = parts.length - 1; i > 0; i--) {
2590
- const prefix = parts.slice(0, i).join(".");
2591
- const suffix = parts.slice(i);
2592
- const candidate = registry.get(prefix);
2593
- if (!/* @__PURE__ */ isUndefined(candidate?.value)) {
2594
- found = candidate;
2595
- segments = suffix;
2596
- break;
2597
- }
2447
+ function createOverflow(options = {}) {
2448
+ const { container: _container, gap = 0, reserved = 0, itemWidth, reverse } = options;
2449
+ const container = /* @__PURE__ */ isUndefined(_container) ? shallowRef() : toRef(_container);
2450
+ const widths = shallowRef(/* @__PURE__ */ new Map());
2451
+ const { width } = useElementSize(container);
2452
+ function measure(index, el) {
2453
+ if (!el) {
2454
+ if (widths.value.has(index)) {
2455
+ const next = new Map(widths.value);
2456
+ next.delete(index);
2457
+ widths.value = next;
2598
2458
  }
2599
- }
2600
- if (/* @__PURE__ */ isUndefined(found?.value)) {
2601
- if (isAliasReference) logger.warn(`Alias not found for "${String(reference)}"`);
2602
- cache.set(cacheKey, void 0);
2603
2459
  return;
2604
2460
  }
2605
- let result;
2606
- let current = found.value;
2607
- if (segments.length > 0) {
2608
- if (isTokenAlias(current)) current = current.$value;
2609
- for (const segment of segments) {
2610
- if (!/* @__PURE__ */ isObject(current) || !(segment in current)) {
2611
- current = void 0;
2612
- break;
2613
- }
2614
- current = current[segment];
2615
- if (isTokenAlias(current)) current = current.$value;
2461
+ const style = getComputedStyle(el);
2462
+ const marginX = Number.parseFloat(style.marginLeft) + Number.parseFloat(style.marginRight);
2463
+ const w = el.offsetWidth + marginX;
2464
+ if (widths.value.get(index) !== w) widths.value = new Map(widths.value).set(index, w);
2465
+ }
2466
+ function reset() {
2467
+ widths.value = /* @__PURE__ */ new Map();
2468
+ }
2469
+ const total = computed(() => {
2470
+ const g = toValue(gap);
2471
+ let sum = 0;
2472
+ let count = 0;
2473
+ for (const w of widths.value.values()) {
2474
+ sum += w + (count > 0 ? g : 0);
2475
+ count++;
2476
+ }
2477
+ return sum;
2478
+ });
2479
+ return {
2480
+ container,
2481
+ width,
2482
+ capacity: computed(() => {
2483
+ const available = width.value - toValue(reserved);
2484
+ if (width.value === 0) return Infinity;
2485
+ if (available <= 0) return 0;
2486
+ const g = toValue(gap);
2487
+ const uniformWidth = toValue(itemWidth);
2488
+ if (uniformWidth && uniformWidth > 0) {
2489
+ const first = uniformWidth;
2490
+ const subsequent = uniformWidth + g;
2491
+ if (available < first) return 0;
2492
+ return Math.max(1, Math.floor((available - first) / subsequent) + 1);
2616
2493
  }
2617
- if (/* @__PURE__ */ isUndefined(current)) {
2618
- logger.warn(`Path not found inside "${clean}": ${segments.join(".")}`);
2619
- cache.set(cacheKey, void 0);
2620
- return;
2494
+ const entries = [...widths.value.entries()].toSorted((a, b) => a[0] - b[0]);
2495
+ if (toValue(reverse)) entries.reverse();
2496
+ let sum = 0;
2497
+ let count = 0;
2498
+ for (const [, w] of entries) {
2499
+ const next = sum + w + (count > 0 ? g : 0);
2500
+ if (next > available) break;
2501
+ sum = next;
2502
+ count++;
2621
2503
  }
2622
- result = current;
2623
- } else if (isTokenAlias(current)) {
2624
- const inner = current.$value;
2625
- if (/* @__PURE__ */ isString(inner) && isAlias(inner)) return resolve(inner, visited);
2626
- result = inner;
2627
- } else if (/* @__PURE__ */ isString(current) && isAlias(current)) return resolve(current, visited);
2628
- else result = current;
2629
- cache.set(cacheKey, result);
2630
- return result;
2631
- }
2632
- return {
2633
- ...registry,
2634
- resolve,
2635
- isAlias,
2636
- get size() {
2637
- return registry.size;
2638
- }
2504
+ return count;
2505
+ }),
2506
+ total,
2507
+ isOverflowing: toRef(() => {
2508
+ return total.value > width.value - toValue(reserved);
2509
+ }),
2510
+ measure,
2511
+ reset
2639
2512
  };
2640
2513
  }
2641
2514
  /**
2642
- * Creates a new token context.
2643
- *
2644
- * @param namespace The namespace for the token context.
2645
- * @param tokens The tokens to use.
2646
- * @template Z The type of the token ticket.
2647
- * @template E The type of the token context.
2648
- * @returns A new token context.
2515
+ * Creates an overflow context with dependency injection support.
2649
2516
  *
2650
- * @see https://0.vuetifyjs.com/composables/registration/use-tokens
2517
+ * @param options Configuration options including namespace
2518
+ * @returns Trinity tuple: [useContext, provideContext, defaultContext]
2651
2519
  *
2652
2520
  * @example
2653
2521
  * ```ts
2654
- * import { createTokensContext } from '@vuetify/v0'
2655
- *
2656
- * export const [useTokens, provideTokens, context] = createTokensContext({
2657
- * namespace: 'v0:tokens',
2658
- * tokens: {
2659
- * colors: {
2660
- * primary: '#3b82f6',
2661
- * secondary: '{colors.primary}', // Alias reference
2662
- * },
2663
- * },
2522
+ * // Create injectable context
2523
+ * const [useOverflow, provideOverflow, overflow] = createOverflowContext({
2524
+ * namespace: 'my-overflow',
2525
+ * gap: 8,
2526
+ * reserved: 160,
2664
2527
  * })
2528
+ *
2529
+ * // In parent component
2530
+ * provideOverflow()
2531
+ *
2532
+ * // In child component
2533
+ * const overflow = useOverflow()
2665
2534
  * ```
2666
2535
  */
2667
- function createTokensContext(_options) {
2668
- const { namespace = "v0:tokens", tokens = {},...options } = _options;
2669
- const [useTokensContext, _provideTokensContext] = createContext(namespace);
2670
- const context = createTokens(tokens, options);
2671
- function provideTokensContext(_context = context, app) {
2672
- return _provideTokensContext(_context, app);
2536
+ function createOverflowContext(_options = {}) {
2537
+ const { namespace = "v0:overflow", ...options } = _options;
2538
+ const [useOverflowContext, _provideOverflowContext] = createContext(namespace);
2539
+ const context = createOverflow(options);
2540
+ function provideOverflowContext(_context = context, app) {
2541
+ return _provideOverflowContext(_context, app);
2673
2542
  }
2674
- return createTrinity(useTokensContext, provideTokensContext, context);
2543
+ return createTrinity(useOverflowContext, provideOverflowContext, context);
2675
2544
  }
2676
2545
  /**
2677
- * Returns the current tokens instance.
2678
- *
2679
- * @param namespace The namespace for the tokens context. Defaults to `'v0:tokens'`.
2680
- * @returns The current tokens instance.
2546
+ * Returns the current overflow context from dependency injection.
2681
2547
  *
2682
- * @see https://0.vuetifyjs.com/composables/registration/use-tokens
2548
+ * @param namespace The namespace for the overflow context. Defaults to `v0:overflow`.
2549
+ * @returns The current overflow context.
2683
2550
  *
2684
2551
  * @example
2685
2552
  * ```vue
2686
- * <script setup lang="ts">
2687
- * import { useTokens } from '@vuetify/v0'
2553
+ * <script lang="ts" setup>
2554
+ * import { useOverflow } from '@vuetify/v0'
2688
2555
  *
2689
- * const tokens = useTokens()
2556
+ * // Inject overflow context provided by parent
2557
+ * const overflow = useOverflow()
2690
2558
  * <\/script>
2559
+ *
2560
+ * <template>
2561
+ * <div>
2562
+ * <p>Capacity: {{ overflow.capacity.value }}</p>
2563
+ * </div>
2564
+ * </template>
2691
2565
  * ```
2692
2566
  */
2693
- function useTokens(namespace = "v0:tokens") {
2567
+ function useOverflow(namespace = "v0:overflow") {
2694
2568
  return useContext(namespace);
2695
2569
  }
2696
- /**
2697
- * Flattens a nested collection of tokens into a flat array of tokens.
2698
- * Each token is represented by an object containing its ID & value.
2699
- * @param tokens The collection of tokens to flatten.
2700
- * @param prefix An optional prefix to prepend to each token ID.
2701
- * @returns An array of flattened tokens, each with an ID and value.
2702
- */
2703
- function flatten(tokens, prefix = "", flat = false) {
2704
- const flattened = [];
2705
- const stack = [{
2706
- tokens,
2707
- prefix,
2708
- flat
2709
- }];
2710
- while (stack.length > 0) {
2711
- const { tokens: currentTokens, prefix: currentPrefix, flat: flat$1 } = stack.pop();
2712
- const meta = {};
2713
- for (const k in currentTokens) if (k.startsWith("$")) meta[k] = currentTokens[k];
2714
- if (Object.keys(meta).length > 0 && currentPrefix) flattened.push({
2715
- id: currentPrefix,
2716
- value: meta
2717
- });
2718
- for (const key in currentTokens) {
2719
- if (key.startsWith("$")) continue;
2720
- const value = currentTokens[key];
2721
- const id = currentPrefix ? `${currentPrefix}.${key}` : key;
2722
- if (!/* @__PURE__ */ isObject(value)) {
2723
- flattened.push({
2724
- id,
2725
- value
2726
- });
2727
- continue;
2728
- }
2729
- if ("$value" in value) {
2730
- flattened.push({
2731
- id,
2732
- value
2733
- });
2734
- const inner = value.$value;
2735
- if (/* @__PURE__ */ isObject(inner) && !flat$1) for (const innerKey in inner) {
2736
- if (innerKey.startsWith("$")) continue;
2737
- const child = inner[innerKey];
2738
- const childId = `${id}.${innerKey}`;
2739
- if (!/* @__PURE__ */ isObject(child)) flattened.push({
2740
- id: childId,
2741
- value: child
2742
- });
2743
- else if ("$value" in child) flattened.push({
2744
- id: childId,
2745
- value: child
2746
- });
2747
- else stack.push({
2748
- tokens: child,
2749
- prefix: childId,
2750
- flat: flat$1
2751
- });
2752
- }
2753
- continue;
2754
- }
2755
- if (flat$1) {
2756
- flattened.push({
2757
- id,
2758
- value
2759
- });
2760
- continue;
2761
- }
2762
- stack.push({
2763
- tokens: value,
2764
- prefix: id,
2765
- flat: flat$1
2766
- });
2767
- }
2768
- }
2769
- return flattened;
2770
- }
2771
-
2772
- //#endregion
2773
- //#region src/composables/useLocale/adapters/v0.ts
2774
- /**
2775
- * Vuetify0.x locale adapter implementation
2776
- *
2777
- * This adapter provides translation and number formatting
2778
- * capabilities using the Intl API and supports both
2779
- * numbered ({0}, {1}) and named ({name}) variables in translation strings.
2780
- */
2781
- var Vuetify0LocaleAdapter = class {
2782
- t(message, ...params) {
2783
- let resolvedMessage = message;
2784
- if (params.length > 0 && /* @__PURE__ */ isObject(params[0])) {
2785
- const variables = params[0];
2786
- resolvedMessage = resolvedMessage.replace(/{([a-zA-Z][a-zA-Z0-9_]*)}/g, (match, name) => {
2787
- return /* @__PURE__ */ isUndefined(variables[name]) ? match : String(variables[name]);
2788
- });
2789
- params = params.slice(1);
2790
- }
2791
- resolvedMessage = resolvedMessage.replace(/\{(\d+)\}/g, (match, index) => {
2792
- const idx = Number.parseInt(index, 10);
2793
- if (!/* @__PURE__ */ isUndefined(params[idx])) return String(params[idx]);
2794
- return match;
2795
- });
2796
- return resolvedMessage;
2797
- }
2798
- n(value, locale, ...params) {
2799
- if (!IN_BROWSER || !locale) return value.toString();
2800
- const options = params[0];
2801
- return new Intl.NumberFormat(String(locale), options).format(value);
2802
- }
2803
- };
2804
2570
 
2805
2571
  //#endregion
2806
- //#region src/composables/useLocale/index.ts
2572
+ //#region src/composables/usePagination/index.ts
2807
2573
  /**
2808
- * @module useLocale
2809
- *
2810
- * @remarks
2811
- * Internationalization (i18n) composable with adapter pattern for message translation.
2574
+ * Creates a pagination instance.
2812
2575
  *
2813
- * Key features:
2814
- * - Locale selection with createSingle
2815
- * - Token-based message storage with useTokens
2816
- * - Numbered and named placeholder support ({0}, {name})
2817
- * - Number formatting with Intl.NumberFormat
2818
- * - Adapter pattern for integration with i18n providers
2576
+ * @param options The options for the pagination instance.
2577
+ * @returns A pagination context with navigation methods.
2819
2578
  *
2820
- * Integrates with createSingle for locale selection and useTokens for message resolution.
2821
- */
2822
- /**
2823
- * Creates a new locale instance.
2579
+ * @example
2580
+ * ```ts
2581
+ * import { createPagination } from '@vuetify/v0'
2824
2582
  *
2825
- * @param options The options for the locale instance.
2826
- * @template Z The type of the locale ticket.
2827
- * @template E The type of the locale context.
2828
- * @returns A new locale instance.
2583
+ * // Basic usage
2584
+ * const pagination = createPagination({ size: 100 })
2585
+ * pagination.next()
2586
+ * pagination.items.value // [{ type: 'page', value: 1 }, { type: 'page', value: 2 }, ...]
2829
2587
  *
2830
- * @see https://0.vuetifyjs.com/composables/plugins/use-locale
2831
- */
2832
- function createLocale(_options = {}) {
2833
- const { adapter = new Vuetify0LocaleAdapter(), messages = {},...options } = _options;
2834
- const tokens = createTokens(messages);
2835
- const registry = createSingle(options);
2836
- for (const id in messages) {
2837
- registry.register({ id });
2838
- if (id === options.default && !registry.selectedId.value) registry.select(id);
2588
+ * // With v-model (pass a ref)
2589
+ * const page = ref(1)
2590
+ * const pagination = createPagination({ page, size: 100 })
2591
+ * // Mutating pagination.page or the passed ref syncs both
2592
+ * ```
2593
+ */
2594
+ function createPagination(_options = {}) {
2595
+ const { page: _page = 1, itemsPerPage: _itemsPerPage = 10, size: _size = 0, visible: _visible = 7, ellipsis = "..." } = _options;
2596
+ const page = isRef(_page) ? _page : shallowRef(_page);
2597
+ const pages = computed(() => {
2598
+ const size = toValue(_size);
2599
+ const perPage = toValue(_itemsPerPage);
2600
+ if (size <= 0 || /* @__PURE__ */ isNaN(size)) return 0;
2601
+ return Math.ceil(size / perPage);
2602
+ });
2603
+ function first() {
2604
+ page.value = 1;
2839
2605
  }
2840
- function t(key, params, fallback) {
2841
- const locale = registry.selectedId.value;
2842
- const args = toArray(params);
2843
- if (!locale) return adapter.t(fallback ?? key, ...args);
2844
- const path = `${locale}.${key}`;
2845
- const message = tokens.get(path)?.value;
2846
- const template = /* @__PURE__ */ isString(message) ? resolve(locale, message) : fallback ?? key;
2847
- return adapter.t(template, ...args);
2606
+ function last() {
2607
+ page.value = Math.max(1, pages.value);
2848
2608
  }
2849
- function n(value, ...params) {
2850
- return adapter.n(value, registry.selectedId.value, ...params);
2609
+ function next() {
2610
+ if (page.value < pages.value) page.value++;
2851
2611
  }
2852
- function resolve(locale, str) {
2853
- return str.replace(/{([a-zA-Z0-9.-_]+)}/g, (match, key) => {
2854
- const [prefix, ...rest] = key.split(".");
2855
- const target = registry.has(prefix) ? prefix : locale;
2856
- const path = `${target}.${registry.has(prefix) ? rest.join(".") : key}`;
2857
- const resolved = tokens.get(path)?.value;
2858
- if (/* @__PURE__ */ isString(resolved)) return resolve(target, resolved);
2859
- return match;
2860
- });
2612
+ function prev() {
2613
+ if (page.value > 1) page.value--;
2614
+ }
2615
+ function select(value) {
2616
+ if (value < 1) page.value = 1;
2617
+ else if (value > pages.value) page.value = Math.max(1, pages.value);
2618
+ else page.value = value;
2619
+ }
2620
+ const isFirst = computed(() => page.value <= 1);
2621
+ const isLast = computed(() => page.value >= pages.value);
2622
+ const pageStart = computed(() => (page.value - 1) * toValue(_itemsPerPage));
2623
+ const pageStop = computed(() => Math.min(pageStart.value + toValue(_itemsPerPage), toValue(_size)));
2624
+ function toPage(value) {
2625
+ return {
2626
+ type: "page",
2627
+ value
2628
+ };
2629
+ }
2630
+ function toEllipsis() {
2631
+ return ellipsis === false ? false : {
2632
+ type: "ellipsis",
2633
+ value: ellipsis
2634
+ };
2635
+ }
2636
+ function filter(array) {
2637
+ return array.filter((item) => item !== false);
2861
2638
  }
2862
2639
  return {
2863
- ...registry,
2864
- t,
2865
- n,
2640
+ page,
2641
+ ellipsis,
2642
+ items: computed(() => {
2643
+ const pageCount = pages.value;
2644
+ const visible = toValue(_visible);
2645
+ const current = page.value;
2646
+ if (pageCount <= 0 || /* @__PURE__ */ isNaN(pageCount) || pageCount > Number.MAX_SAFE_INTEGER) return [];
2647
+ if (visible <= 0) return [];
2648
+ if (visible <= 2) return [toPage(current)];
2649
+ if (pageCount <= visible) return (/* @__PURE__ */ range(pageCount, 1)).map(toPage);
2650
+ if (visible === 3) {
2651
+ const mid = current <= 1 ? 2 : current >= pageCount ? pageCount - 1 : current;
2652
+ return [
2653
+ toPage(1),
2654
+ toPage(mid),
2655
+ toPage(pageCount)
2656
+ ];
2657
+ }
2658
+ const boundary = visible - 2;
2659
+ const middle = visible - 4;
2660
+ if (middle <= 0) {
2661
+ if (current <= boundary) return filter([
2662
+ ...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
2663
+ toEllipsis(),
2664
+ toPage(pageCount)
2665
+ ]);
2666
+ if (current > pageCount - boundary) return filter([
2667
+ toPage(1),
2668
+ toEllipsis(),
2669
+ ...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
2670
+ ]);
2671
+ return current <= Math.ceil(pageCount / 2) ? filter([
2672
+ toPage(1),
2673
+ toPage(current),
2674
+ toEllipsis(),
2675
+ toPage(pageCount)
2676
+ ]) : filter([
2677
+ toPage(1),
2678
+ toEllipsis(),
2679
+ toPage(current),
2680
+ toPage(pageCount)
2681
+ ]);
2682
+ }
2683
+ const leftThreshold = boundary - 1;
2684
+ const rightThreshold = pageCount - boundary + 2;
2685
+ if (current <= leftThreshold) return filter([
2686
+ ...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
2687
+ toEllipsis(),
2688
+ toPage(pageCount)
2689
+ ]);
2690
+ else if (current >= rightThreshold) return filter([
2691
+ toPage(1),
2692
+ toEllipsis(),
2693
+ ...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
2694
+ ]);
2695
+ else {
2696
+ const start = current - Math.floor(middle / 2);
2697
+ return filter([
2698
+ toPage(1),
2699
+ toEllipsis(),
2700
+ ...(/* @__PURE__ */ range(middle, start)).map(toPage),
2701
+ toEllipsis(),
2702
+ toPage(pageCount)
2703
+ ]);
2704
+ }
2705
+ }),
2706
+ pageStart,
2707
+ pageStop,
2708
+ isFirst,
2709
+ isLast,
2710
+ first,
2711
+ last,
2712
+ next,
2713
+ prev,
2714
+ select,
2715
+ get itemsPerPage() {
2716
+ return toValue(_itemsPerPage);
2717
+ },
2866
2718
  get size() {
2867
- return registry.size;
2719
+ return toValue(_size);
2720
+ },
2721
+ get pages() {
2722
+ return pages.value;
2868
2723
  }
2869
2724
  };
2870
2725
  }
2871
- function createLocaleFallback() {
2872
- return {
2873
- size: 0,
2874
- t: (key, _params, fallback) => fallback ?? key,
2875
- n: String
2876
- };
2877
- }
2878
2726
  /**
2879
- * Creates a new locale context.
2880
- *
2881
- * @param options The options for the locale context.
2882
- * @template Z The type of the locale ticket.
2883
- * @template E The type of the locale context.
2884
- * @returns A new locale context.
2727
+ * Creates a pagination context for dependency injection.
2885
2728
  *
2886
- * @see https://0.vuetifyjs.com/composables/plugins/use-locale
2729
+ * @param options The options including namespace.
2730
+ * @returns A trinity: [usePagination, providePagination, defaultContext]
2887
2731
  *
2888
2732
  * @example
2889
2733
  * ```ts
2890
- * import { createLocaleContext } from '@vuetify/v0'
2734
+ * // With default namespace 'v0:pagination'
2735
+ * const [usePagination, providePaginationContext] = createPaginationContext({ size: 50 })
2891
2736
  *
2892
- * export const [useAppLocale, provideAppLocale, appLocale] = createLocaleContext({
2893
- * namespace: 'app:locale',
2894
- * messages: {
2895
- * en: { hello: 'Hello' },
2896
- * es: { hello: 'Hola' },
2897
- * },
2737
+ * // Or with custom namespace
2738
+ * const [usePagination, providePaginationContext] = createPaginationContext({
2739
+ * namespace: 'my-pagination',
2740
+ * size: 50,
2898
2741
  * })
2899
2742
  *
2900
- * // In a parent component:
2901
- * provideAppLocale()
2743
+ * // Parent component
2744
+ * providePaginationContext()
2902
2745
  *
2903
- * // In a child component:
2904
- * const locale = useAppLocale()
2905
- * locale.select('es')
2746
+ * // Child component
2747
+ * const pagination = usePagination()
2748
+ * pagination.next()
2906
2749
  * ```
2907
2750
  */
2908
- function createLocaleContext(_options = {}) {
2909
- const { namespace = "v0:locale",...options } = _options;
2910
- const [useLocaleContext, _provideLocaleContext] = createContext(namespace);
2911
- const context = createLocale(options);
2912
- function provideLocaleContext(_context = context, app) {
2913
- return _provideLocaleContext(_context, app);
2751
+ function createPaginationContext(_options = {}) {
2752
+ const { namespace = "v0:pagination", ...options } = _options;
2753
+ const [usePaginationContext, _providePaginationContext] = createContext(namespace);
2754
+ const context = createPagination(options);
2755
+ function providePaginationContext(_context = context, app) {
2756
+ return _providePaginationContext(_context, app);
2914
2757
  }
2915
- return createTrinity(useLocaleContext, provideLocaleContext, context);
2758
+ return createTrinity(usePaginationContext, providePaginationContext, context);
2916
2759
  }
2917
2760
  /**
2918
- * Creates a new locale plugin.
2761
+ * Returns the current pagination instance from context.
2919
2762
  *
2920
- * @param options The options for the locale plugin.
2921
- * @template Z The type of the locale ticket.
2922
- * @template E The type of the locale context.
2923
- * @template R The type of the token ticket.
2924
- * @template O The type of the token context.
2925
- * @returns A new locale plugin.
2763
+ * @param namespace The namespace. @default 'v0:pagination'
2764
+ * @returns The pagination context.
2926
2765
  *
2927
- * @see https://0.vuetifyjs.com/composables/plugins/use-locale
2928
- */
2929
- function createLocalePlugin(_options = {}) {
2930
- const { namespace = "v0:locale", adapter = new Vuetify0LocaleAdapter(), messages = {},...options } = _options;
2931
- const [, provideLocaleContext, context] = createLocaleContext({
2932
- ...options,
2933
- namespace,
2934
- adapter,
2935
- messages
2936
- });
2937
- return createPlugin({
2938
- namespace,
2939
- provide: (app) => {
2940
- provideLocaleContext(context, app);
2941
- }
2942
- });
2943
- }
2944
- /**
2945
- * Returns the current locale instance.
2766
+ * @example
2767
+ * ```vue
2768
+ * <script setup lang="ts">
2769
+ * import { usePagination } from '@vuetify/v0'
2946
2770
  *
2947
- * @returns The current locale instance.
2771
+ * const pagination = usePagination()
2772
+ * <\/script>
2948
2773
  *
2949
- * @see https://0.vuetifyjs.com/composables/plugins/use-locale
2774
+ * <template>
2775
+ * <button @click="pagination.prev()" :disabled="pagination.isFirst.value">Prev</button>
2776
+ * <button @click="pagination.next()" :disabled="pagination.isLast.value">Next</button>
2777
+ * </template>
2778
+ * ```
2950
2779
  */
2951
- function useLocale(namespace = "v0:locale") {
2952
- const fallback = createLocaleFallback();
2953
- if (!getCurrentInstance()) return fallback;
2954
- try {
2955
- return useContext(namespace, fallback);
2956
- } catch {
2957
- return fallback;
2958
- }
2780
+ function usePagination(namespace = "v0:pagination") {
2781
+ return useContext(namespace);
2959
2782
  }
2960
2783
 
2961
2784
  //#endregion
2962
2785
  //#region src/composables/useStep/index.ts
2963
2786
  /**
2964
- * @module useStep
2965
- *
2966
- * @remarks
2967
- * Navigation composable that extends useSingle with first/last/next/prev/step methods.
2968
- *
2969
- * Key features:
2970
- * - Configurable circular or bounded navigation
2971
- * - Automatic disabled item skipping
2972
- * - Arbitrary step counts (positive/negative)
2973
- * - Perfect for wizards, carousels, pagination, onboarding flows
2974
- *
2975
- * Inheritance chain: useRegistry → useSelection → useSingle → useStep
2976
- */
2977
- /**
2978
2787
  * Creates a new step instance with navigation through items.
2979
2788
  *
2980
2789
  * Extends `createSingle` with `first()`, `last()`, `next()`, `prev()`, and `step(count)` methods
@@ -3043,7 +2852,7 @@ function useLocale(namespace = "v0:locale") {
3043
2852
  * ```
3044
2853
  */
3045
2854
  function createStep(_options = {}) {
3046
- const { circular = false,...options } = _options;
2855
+ const { circular = false, ...options } = _options;
3047
2856
  const registry = createSingle(options);
3048
2857
  function first() {
3049
2858
  const ticket = registry.seek("first");
@@ -3119,7 +2928,7 @@ function createStep(_options = {}) {
3119
2928
  * ```
3120
2929
  */
3121
2930
  function createStepContext(_options = {}) {
3122
- const { namespace = "v0:step",...options } = _options;
2931
+ const { namespace = "v0:step", ...options } = _options;
3123
2932
  const [useStepContext, _provideStepContext] = createContext(namespace);
3124
2933
  const context = createStep(options);
3125
2934
  function provideStepContext(_context = context, app) {
@@ -3156,4 +2965,4 @@ function useStep(namespace = "v0:step") {
3156
2965
  }
3157
2966
 
3158
2967
  //#endregion
3159
- export { createGroupContext as A, createLogger as B, useResizeObserver as C, createHydrationPlugin as D, createHydrationContext as E, createSelection as F, PinoLoggerAdapter as G, createLoggerPlugin as H, createSelectionContext as I, createTrinity as J, ConsolaLoggerAdapter as K, useSelection as L, useProxyRegistry as M, useProxyModel as N, useHydration as O, toArray as P, createRegistryContext as R, useElementSize as S, createHydration as T, useLogger as U, createLoggerContext as V, Vuetify0LoggerAdapter as W, provideContext as X, createContext as Y, useContext as Z, createPaginationContext as _, createLocaleContext as a, createOverflowContext as b, useLocale as c, createTokensContext as d, useTokens as f, createPagination as g, useSingle as h, createLocale as i, useGroup as j, createGroup as k, Vuetify0LocaleAdapter as l, createSingleContext as m, createStepContext as n, createLocaleFallback as o, createSingle as p, createPlugin as q, useStep as r, createLocalePlugin as s, createStep as t, createTokens as u, usePagination as v, createFallbackHydration as w, useOverflow as x, createOverflow as y, useRegistry as z };
2968
+ export { createGroupContext as A, createLogger as B, createTokensContext as C, useSingle as D, createSingleContext as E, createSelection as F, PinoLoggerAdapter as G, createLoggerPlugin as H, createSelectionContext as I, createTrinity as J, ConsolaLoggerAdapter as K, useSelection as L, useProxyRegistry as M, useProxyModel as N, Vuetify0LocaleAdapter as O, toArray as P, createRegistryContext as R, createTokens as S, createSingle as T, useLogger as U, createLoggerContext as V, Vuetify0LoggerAdapter as W, provideContext as X, createContext as Y, useContext as Z, createLocale as _, createPaginationContext as a, createLocalePlugin as b, createOverflowContext as c, useResizeObserver as d, createFallbackHydration as f, useHydration as g, createHydrationPlugin as h, createPagination as i, useGroup as j, createGroup as k, useOverflow as l, createHydrationContext as m, createStepContext as n, usePagination as o, createHydration as p, createPlugin as q, useStep as r, createOverflow as s, createStep as t, useElementSize as u, createLocaleContext as v, useTokens as w, useLocale as x, createLocaleFallback as y, useRegistry as z };