@vuetify/v0 0.0.2 → 0.0.3

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.
@@ -120,21 +120,35 @@ var Atom_default = Atom_vue_vue_type_script_setup_true_lang_default;
120
120
  * A simple wrapper for tapping into a v0 namespace
121
121
  * @param key The provided string or InjectionKey
122
122
  * @template Z The type values for the context.
123
- * @returns A function that retrieves context
123
+ * @returns The injected context
124
124
  * @throws Error if namespace is not found.
125
125
  *
126
126
  * @see https://vuejs.org/api/composition-api-dependency-injection.html#inject
127
+ * @see https://0.vuetifyjs.com/composables/foundation/create-context
127
128
  */
128
129
  function useContext(key) {
129
- return function(namespace) {
130
- const context = inject(namespace || key, void 0);
131
- if (context === void 0) throw new Error(`Context "${String(key)}" not found. Ensure it's provided by an ancestor.`);
132
- return context;
133
- };
130
+ const context = inject(key, void 0);
131
+ if (context === void 0) throw new Error(`Context "${String(key)}" not found. Ensure it's provided by an ancestor.`);
132
+ return context;
133
+ }
134
+ /**
135
+ * A simple wrapper for providing Vue context.
136
+ *
137
+ * @param key The provided string or InjectionKey
138
+ * @param context The context value to provide
139
+ * @param app Optional Vue app instance for global provide
140
+ * @returns The provided context
141
+ *
142
+ * @see https://vuejs.org/api/composition-api-dependency-injection.html#provide
143
+ * @see https://0.vuetifyjs.com/composables/foundation/create-context
144
+ */
145
+ function provideContext(key, context, app) {
146
+ app?.provide(key, context) ?? provide(key, context);
147
+ return context;
134
148
  }
135
149
  /**
136
150
  * A simple wrapper for Vues provide & inject systems
137
- * to create context for managing application state
151
+ *
138
152
  * @param key The provided string or InjectionKey
139
153
  * @template Z The type values for the context.
140
154
  * @returns A tuple containing provide/inject
@@ -142,12 +156,14 @@ function useContext(key) {
142
156
  * @see https://vuejs.org/api/composition-api-dependency-injection.html#provide
143
157
  * @see https://0.vuetifyjs.com/composables/foundation/create-context
144
158
  */
145
- function createContext(key) {
146
- function provideContext(context, app) {
147
- app?.provide(key, context) ?? provide(key, context);
148
- return context;
159
+ function createContext(_key) {
160
+ function _provideContext(context, app) {
161
+ return provideContext(_key, context, app);
162
+ }
163
+ function _useContext(key = _key) {
164
+ return useContext(key);
149
165
  }
150
- return [useContext(key), provideContext];
166
+ return [_useContext, _provideContext];
151
167
  }
152
168
 
153
169
  //#endregion
@@ -157,6 +173,7 @@ function createContext(key) {
157
173
  * @param options Configurable object with namespace and provide/setup methods
158
174
  * @returns A Vue plugin object with install method that runs app w/ context
159
175
  *
176
+ * @see https://vuejs.org/guide/reusability/plugins
160
177
  * @see https://vuejs.org/api/application.html#app-runwithcontext
161
178
  * @see https://0.vuetifyjs.com/factories/create-plugin
162
179
  */
@@ -282,7 +299,7 @@ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && "matchMedia" in window && typeof wind
282
299
  const SUPPORTS_OBSERVER = IN_BROWSER && "ResizeObserver" in window;
283
300
  const SUPPORTS_INTERSECTION_OBSERVER = IN_BROWSER && "IntersectionObserver" in window;
284
301
  const SUPPORTS_MUTATION_OBSERVER = IN_BROWSER && "MutationObserver" in window;
285
- const version = "0.0.2";
302
+ const version = "0.0.3";
286
303
  const __LOGGER_ENABLED__ = false;
287
304
 
288
305
  //#endregion
@@ -328,58 +345,54 @@ function createBreakpoints(options = {}) {
328
345
  const sorted = Object.entries(breakpoints).sort((a, b) => a[1] - b[1]);
329
346
  const names = sorted.map(([n]) => n);
330
347
  const mb = typeof mobileBreakpoint === "number" ? mobileBreakpoint : breakpoints[mobileBreakpoint] ?? breakpoints.md;
331
- const state = shallowReactive({
332
- breakpoints,
333
- name: "xs",
334
- width: 0,
335
- height: 0,
336
- isMobile: true,
337
- xs: true,
338
- sm: false,
339
- md: false,
340
- lg: false,
341
- xl: false,
342
- xxl: false,
343
- smAndUp: false,
344
- mdAndUp: false,
345
- lgAndUp: false,
346
- xlAndUp: false,
347
- xxlAndUp: false,
348
- smAndDown: true,
349
- mdAndDown: true,
350
- lgAndDown: true,
351
- xlAndDown: true,
352
- xxlAndDown: true,
353
- update
354
- });
348
+ const name = shallowRef("xs");
349
+ const width = shallowRef(0);
350
+ const height = shallowRef(0);
351
+ const isMobile = shallowRef(true);
352
+ const xs = shallowRef(true);
353
+ const sm = shallowRef(false);
354
+ const md = shallowRef(false);
355
+ const lg = shallowRef(false);
356
+ const xl = shallowRef(false);
357
+ const xxl = shallowRef(false);
358
+ const smAndUp = shallowRef(false);
359
+ const mdAndUp = shallowRef(false);
360
+ const lgAndUp = shallowRef(false);
361
+ const xlAndUp = shallowRef(false);
362
+ const xxlAndUp = shallowRef(false);
363
+ const smAndDown = shallowRef(true);
364
+ const mdAndDown = shallowRef(true);
365
+ const lgAndDown = shallowRef(true);
366
+ const xlAndDown = shallowRef(true);
367
+ const xxlAndDown = shallowRef(true);
355
368
  function update() {
356
369
  if (!IN_BROWSER) return;
357
- state.width = window.innerWidth;
358
- state.height = window.innerHeight;
370
+ width.value = window.innerWidth;
371
+ height.value = window.innerHeight;
359
372
  let current = "xs";
360
- for (let i = sorted.length - 1; i >= 0; i--) if (state.width >= sorted[i][1]) {
373
+ for (let i = sorted.length - 1; i >= 0; i--) if (width.value >= sorted[i][1]) {
361
374
  current = sorted[i][0];
362
375
  break;
363
376
  }
364
- state.name = current;
377
+ name.value = current;
365
378
  const index = names.indexOf(current);
366
- state.isMobile = state.width < mb;
367
- state.xs = index === 0;
368
- state.sm = index === 1;
369
- state.md = index === 2;
370
- state.lg = index === 3;
371
- state.xl = index === 4;
372
- state.xxl = index === 5;
373
- state.smAndUp = index >= 1;
374
- state.mdAndUp = index >= 2;
375
- state.lgAndUp = index >= 3;
376
- state.xlAndUp = index >= 4;
377
- state.xxlAndUp = index >= 5;
378
- state.smAndDown = index <= 1;
379
- state.mdAndDown = index <= 2;
380
- state.lgAndDown = index <= 3;
381
- state.xlAndDown = index <= 4;
382
- state.xxlAndDown = index <= 5;
379
+ isMobile.value = width.value < mb;
380
+ xs.value = index === 0;
381
+ sm.value = index === 1;
382
+ md.value = index === 2;
383
+ lg.value = index === 3;
384
+ xl.value = index === 4;
385
+ xxl.value = index === 5;
386
+ smAndUp.value = index >= 1;
387
+ mdAndUp.value = index >= 2;
388
+ lgAndUp.value = index >= 3;
389
+ xlAndUp.value = index >= 4;
390
+ xxlAndUp.value = index >= 5;
391
+ smAndDown.value = index <= 1;
392
+ mdAndDown.value = index <= 2;
393
+ lgAndDown.value = index <= 3;
394
+ xlAndDown.value = index <= 4;
395
+ xxlAndDown.value = index <= 5;
383
396
  }
384
397
  if (getCurrentInstance()) onMounted(() => {
385
398
  const { isHydrated } = useHydration();
@@ -395,7 +408,30 @@ function createBreakpoints(options = {}) {
395
408
  window.addEventListener("resize", listener, { passive: true });
396
409
  if (getCurrentInstance()) onScopeDispose(() => window.removeEventListener("resize", listener));
397
410
  }
398
- return state;
411
+ return {
412
+ breakpoints,
413
+ name: readonly(name),
414
+ width: readonly(width),
415
+ height: readonly(height),
416
+ isMobile: readonly(isMobile),
417
+ xs: readonly(xs),
418
+ sm: readonly(sm),
419
+ md: readonly(md),
420
+ lg: readonly(lg),
421
+ xl: readonly(xl),
422
+ xxl: readonly(xxl),
423
+ smAndUp: readonly(smAndUp),
424
+ mdAndUp: readonly(mdAndUp),
425
+ lgAndUp: readonly(lgAndUp),
426
+ xlAndUp: readonly(xlAndUp),
427
+ xxlAndUp: readonly(xxlAndUp),
428
+ smAndDown: readonly(smAndDown),
429
+ mdAndDown: readonly(mdAndDown),
430
+ lgAndDown: readonly(lgAndDown),
431
+ xlAndDown: readonly(xlAndDown),
432
+ xxlAndDown: readonly(xxlAndDown),
433
+ update
434
+ };
399
435
  }
400
436
  /**
401
437
  * Creates a Vue plugin for managing responsive breakpoints with automatic updates.
@@ -447,8 +483,7 @@ var BreakpointsRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
447
483
  breakpoints: {}
448
484
  },
449
485
  setup(__props) {
450
- const props = __props;
451
- const breakpointsContext = createBreakpoints(props);
486
+ const breakpointsContext = createBreakpoints(__props);
452
487
  provideBreakpointsContext(breakpointsContext);
453
488
  return (_ctx, _cache) => {
454
489
  return renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(breakpointsContext))));
@@ -504,8 +539,8 @@ var ContextRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
504
539
  value: {}
505
540
  },
506
541
  setup(__props) {
507
- const [, provideContext] = createContext(__props.contextKey);
508
- provideContext(__props.value);
542
+ const [, provideContext$1] = createContext(__props.contextKey);
543
+ provideContext$1(__props.value);
509
544
  return (_ctx, _cache) => {
510
545
  return renderSlot(_ctx.$slots, "default");
511
546
  };
@@ -523,6 +558,212 @@ const Context = {
523
558
  Root: ContextRoot_default
524
559
  };
525
560
 
561
+ //#endregion
562
+ //#region src/components/Hydration/Hydration.vue?vue&type=script&setup=true&lang.ts
563
+ var Hydration_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
564
+ name: "Hydration",
565
+ __name: "Hydration",
566
+ setup(__props) {
567
+ const hydrationContext = useHydration();
568
+ return (_ctx, _cache) => {
569
+ return renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(hydrationContext))));
570
+ };
571
+ }
572
+ });
573
+
574
+ //#endregion
575
+ //#region src/components/Hydration/Hydration.vue
576
+ var Hydration_default = Hydration_vue_vue_type_script_setup_true_lang_default;
577
+
578
+ //#endregion
579
+ //#region src/components/Hydration/HydrationRoot.vue?vue&type=script&setup=true&lang.ts
580
+ var HydrationRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
581
+ name: "HydrationRoot",
582
+ __name: "HydrationRoot",
583
+ setup(__props) {
584
+ const hydrationContext = createHydration();
585
+ provideHydrationContext(hydrationContext);
586
+ return (_ctx, _cache) => {
587
+ return renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(hydrationContext))));
588
+ };
589
+ }
590
+ });
591
+
592
+ //#endregion
593
+ //#region src/components/Hydration/HydrationRoot.vue
594
+ var HydrationRoot_default = HydrationRoot_vue_vue_type_script_setup_true_lang_default;
595
+
596
+ //#endregion
597
+ //#region src/components/Popover/PopoverRoot.vue?vue&type=script&setup=true&lang.ts
598
+ const [usePopoverContext, providePopoverContext] = createContext("Popover");
599
+ var PopoverRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
600
+ name: "PopoverRoot",
601
+ __name: "PopoverRoot",
602
+ props: /* @__PURE__ */ mergeModels({
603
+ id: {},
604
+ as: { default: null },
605
+ renderless: { type: Boolean }
606
+ }, {
607
+ "modelValue": {
608
+ type: Boolean,
609
+ default: false
610
+ },
611
+ "modelModifiers": {}
612
+ }),
613
+ emits: ["update:modelValue"],
614
+ setup(__props) {
615
+ const props = createPropsRestProxy(__props, ["as"]);
616
+ const isSelected = useModel(__props, "modelValue");
617
+ const id = toRef(() => props.id ?? useId());
618
+ function toggle() {
619
+ isSelected.value = !isSelected.value;
620
+ }
621
+ const bindableProps = toRef(() => ({
622
+ id,
623
+ isSelected,
624
+ toggle
625
+ }));
626
+ providePopoverContext({
627
+ isSelected,
628
+ toggle,
629
+ id: id.value
630
+ });
631
+ return (_ctx, _cache) => {
632
+ return openBlock(), createBlock(unref(Atom_default), mergeProps({
633
+ as: _ctx.as,
634
+ renderless: _ctx.renderless
635
+ }, bindableProps.value), {
636
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(bindableProps.value)))]),
637
+ _: 3
638
+ }, 16, ["as", "renderless"]);
639
+ };
640
+ }
641
+ });
642
+
643
+ //#endregion
644
+ //#region src/components/Popover/PopoverRoot.vue
645
+ var PopoverRoot_default = PopoverRoot_vue_vue_type_script_setup_true_lang_default;
646
+
647
+ //#endregion
648
+ //#region src/components/Popover/PopoverAnchor.vue?vue&type=script&setup=true&lang.ts
649
+ var PopoverAnchor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
650
+ name: "PopoverAnchor",
651
+ __name: "PopoverAnchor",
652
+ props: {
653
+ target: {},
654
+ as: { default: "button" },
655
+ renderless: { type: Boolean }
656
+ },
657
+ setup(__props) {
658
+ const props = createPropsRestProxy(__props, ["as"]);
659
+ const context = usePopoverContext();
660
+ const popovertarget = toRef(() => props.target ?? context.id);
661
+ const style = toRef(() => ({ anchorName: `--${popovertarget.value}` }));
662
+ return (_ctx, _cache) => {
663
+ return openBlock(), createBlock(unref(Atom_default), {
664
+ as: _ctx.as,
665
+ "data-popover-open": unref(context).isSelected.value ? "" : void 0,
666
+ popovertarget: popovertarget.value,
667
+ style: normalizeStyle(style.value),
668
+ type: _ctx.as === "button" ? "button" : void 0
669
+ }, {
670
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
671
+ _: 3
672
+ }, 8, [
673
+ "as",
674
+ "data-popover-open",
675
+ "popovertarget",
676
+ "style",
677
+ "type"
678
+ ]);
679
+ };
680
+ }
681
+ });
682
+
683
+ //#endregion
684
+ //#region src/components/Popover/PopoverAnchor.vue
685
+ var PopoverAnchor_default = PopoverAnchor_vue_vue_type_script_setup_true_lang_default;
686
+
687
+ //#endregion
688
+ //#region src/components/Popover/PopoverContent.vue?vue&type=script&setup=true&lang.ts
689
+ var PopoverContent_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
690
+ name: "PopoverContent",
691
+ __name: "PopoverContent",
692
+ props: {
693
+ id: {},
694
+ positionArea: { default: "bottom" },
695
+ positionTry: { default: "most-width bottom" },
696
+ as: {},
697
+ renderless: { type: Boolean }
698
+ },
699
+ emits: ["beforetoggle"],
700
+ setup(__props, { emit: __emit }) {
701
+ const props = createPropsRestProxy(__props, ["positionArea", "positionTry"]);
702
+ const emit = __emit;
703
+ const context = usePopoverContext();
704
+ const ref$1 = useTemplateRef("ref");
705
+ const id = toRef(() => props.id ?? context.id);
706
+ const style = toRef(() => ({
707
+ positionArea: __props.positionArea,
708
+ positionAnchor: `--${id.value}`,
709
+ positionTry: __props.positionTry
710
+ }));
711
+ onMounted(() => {
712
+ if (context.isSelected.value) ref$1.value?.element?.showPopover();
713
+ });
714
+ function onBeforeToggle(e) {
715
+ context.isSelected.value = e.newState === "open";
716
+ emit("beforetoggle", e);
717
+ }
718
+ return (_ctx, _cache) => {
719
+ return openBlock(), createBlock(unref(Atom_default), {
720
+ id: id.value,
721
+ ref_key: "ref",
722
+ ref: ref$1,
723
+ popover: "",
724
+ style: normalizeStyle(style.value),
725
+ onBeforetoggle: onBeforeToggle
726
+ }, {
727
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
728
+ _: 3
729
+ }, 8, ["id", "style"]);
730
+ };
731
+ }
732
+ });
733
+
734
+ //#endregion
735
+ //#region src/components/Popover/PopoverContent.vue
736
+ var PopoverContent_default = PopoverContent_vue_vue_type_script_setup_true_lang_default;
737
+
738
+ //#endregion
739
+ //#region src/components/Popover/index.ts
740
+ const Popover = {
741
+ Root: PopoverRoot_default,
742
+ Anchor: PopoverAnchor_default,
743
+ Content: PopoverContent_default
744
+ };
745
+
746
+ //#endregion
747
+ //#region src/factories/createTrinity/index.ts
748
+ /**
749
+ * A tuple containing Vue's provide/inject and a context object
750
+ * @param createContext The function that creates the context
751
+ * @param provideContext The function that provides context
752
+ * @param context The underlying context object singleton
753
+ * @template Z The type parameter for the context value
754
+ * @template E The vmodel type for the context state.
755
+ * @returns [createContext, provideContext, context]
756
+ *
757
+ * @see https://0.vuetifyjs.com/composables/foundation/create-trinity
758
+ */
759
+ function createTrinity(createContext$1, provideContext$1, context) {
760
+ return [
761
+ createContext$1,
762
+ (_context = context, app) => provideContext$1(_context, app),
763
+ context
764
+ ];
765
+ }
766
+
526
767
  //#endregion
527
768
  //#region src/composables/useLogger/adapters/consola.ts
528
769
  var ConsolaLoggerAdapter = class {
@@ -638,21 +879,19 @@ var Vuetify0LoggerAdapter = class {
638
879
  format(level, message, ...args) {
639
880
  const timestamp = this.timestamps ? this.timestamp() : "";
640
881
  const prefixTag = `[${this.prefix} ${level.toLowerCase()}]`;
641
- const formattedMessage = [
882
+ return [[
642
883
  timestamp,
643
884
  prefixTag,
644
885
  message
645
- ].filter(Boolean).join(" ");
646
- return [formattedMessage, ...args];
886
+ ].filter(Boolean).join(" "), ...args];
647
887
  }
648
888
  timestamp() {
649
889
  if (!IN_BROWSER) return (/* @__PURE__ */ new Date()).toISOString();
650
- const now = /* @__PURE__ */ new Date();
651
- return now.toTimeString().split(" ")[0];
890
+ return (/* @__PURE__ */ new Date()).toTimeString().split(" ")[0] ?? "";
652
891
  }
653
892
  style(level) {
654
893
  if (!this.colors || !IN_BROWSER) return "";
655
- const styles = {
894
+ return {
656
895
  trace: "color: #64748b",
657
896
  debug: "color: #3b82f6",
658
897
  info: "color: #10b981",
@@ -660,8 +899,7 @@ var Vuetify0LoggerAdapter = class {
660
899
  error: "color: #ef4444",
661
900
  fatal: "color: #dc2626; font-weight: bold",
662
901
  silent: ""
663
- };
664
- return styles[level] || "";
902
+ }[level] || "";
665
903
  }
666
904
  log(level, method, message, ...args) {
667
905
  const [formattedMessage, ...restArgs] = this.format(level, message, ...args);
@@ -687,7 +925,7 @@ function createLogger(options = {}) {
687
925
  const currentLevel = shallowRef(initialLevel);
688
926
  const isEnabled = shallowRef(initialEnabled);
689
927
  function value(level$1) {
690
- const levels = {
928
+ return {
691
929
  trace: 0,
692
930
  debug: 1,
693
931
  info: 2,
@@ -695,8 +933,7 @@ function createLogger(options = {}) {
695
933
  error: 4,
696
934
  fatal: 5,
697
935
  silent: 6
698
- };
699
- return levels[level$1] ?? 2;
936
+ }[level$1] ?? 2;
700
937
  }
701
938
  function can(level$1) {
702
939
  if (!isEnabled.value) return false;
@@ -787,27 +1024,6 @@ function createLoggerPlugin(options = {}) {
787
1024
  });
788
1025
  }
789
1026
 
790
- //#endregion
791
- //#region src/factories/createTrinity/index.ts
792
- /**
793
- * A tuple containing Vue's provide/inject and a context object
794
- * @param createContext The function that creates the context
795
- * @param provideContext The function that provides context
796
- * @param context The underlying context object singleton
797
- * @template Z The type parameter for the context value
798
- * @template E The vmodel type for the context state.
799
- * @returns [createContext, provideContext, context]
800
- *
801
- * @see https://0.vuetifyjs.com/composables/foundation/create-trinity
802
- */
803
- function createTrinity(createContext$1, provideContext, context) {
804
- return [
805
- createContext$1,
806
- (_context = context, app) => provideContext(_context, app),
807
- context
808
- ];
809
- }
810
-
811
1027
  //#endregion
812
1028
  //#region src/composables/useRegistry/index.ts
813
1029
  /**
@@ -819,6 +1035,8 @@ function createTrinity(createContext$1, provideContext, context) {
819
1035
  * @template Z The type of items managed by the registry.
820
1036
  * @template E The type of the registry context.
821
1037
  * @returns The registry context object.
1038
+ *
1039
+ * @see https://0.vuetifyjs.com/composables/registration/use-registry
822
1040
  */
823
1041
  function useRegistry(options) {
824
1042
  const logger = useLogger();
@@ -1070,13 +1288,16 @@ function useSelection(options) {
1070
1288
  if (selectedIds.has(id)) unselect(id);
1071
1289
  else select(id);
1072
1290
  }
1291
+ function selected(id) {
1292
+ return selectedIds.has(id);
1293
+ }
1073
1294
  function register(registration = {}) {
1074
1295
  const id = registration.id ?? genId();
1075
1296
  const item = {
1076
1297
  disabled: false,
1077
1298
  ...registration,
1078
1299
  id,
1079
- isActive: toRef(() => selectedIds.has(id)),
1300
+ isSelected: toRef(() => selectedIds.has(id)),
1080
1301
  select: () => select(id),
1081
1302
  unselect: () => unselect(id),
1082
1303
  toggle: () => toggle(id)
@@ -1106,439 +1327,29 @@ function useSelection(options) {
1106
1327
  mandate,
1107
1328
  select,
1108
1329
  unselect,
1109
- toggle
1330
+ toggle,
1331
+ selected
1110
1332
  };
1111
1333
  }
1334
+ /**
1335
+ * Creates a selection registry context with full injection/provision control.
1336
+ * Returns the complete trinity for advanced usage scenarios.
1337
+ *
1338
+ * @param namespace The namespace for the selection registry context
1339
+ * @param options Optional configuration for selection behavior.
1340
+ * @template Z The structure of the registry selection items.
1341
+ * @template E The available methods for the selection's context.
1342
+ * @returns A tuple containing the inject function, provide function, and the selection context.
1343
+ */
1344
+ function createSelectionContext(namespace, options) {
1345
+ const [useSelectionContext, _provideSelectionContext] = createContext(namespace);
1346
+ const context = useSelection(options);
1347
+ function provideSelectionContext(_context = context, app) {
1348
+ return _provideSelectionContext(_context, app);
1349
+ }
1350
+ return createTrinity(useSelectionContext, provideSelectionContext, context);
1351
+ }
1112
1352
 
1113
- //#endregion
1114
- //#region src/utilities/benchmark.ts
1115
- async function run(name, fn, samples = 100) {
1116
- fn();
1117
- return {
1118
- name,
1119
- duration: 0,
1120
- ops: Infinity
1121
- };
1122
- }
1123
-
1124
- //#endregion
1125
- //#region src/transformers/toArray/index.ts
1126
- /* @__NO_SIDE_EFFECTS__ */
1127
- function toArray(value) {
1128
- return isNullOrUndefined(value) ? [] : Array.isArray(value) ? value : [value];
1129
- }
1130
-
1131
- //#endregion
1132
- //#region src/transformers/toReactive/index.ts
1133
- /**
1134
- * Converts an object to a reactive reference using Vue's reactivity system.
1135
- * This function creates a reactive version of the provided object,
1136
- * making its properties automatically track dependencies and trigger re-renders
1137
- * when they change.
1138
- *
1139
- * @param objectRef - A reference to an object that should be made reactive.
1140
- * @template Z The type of the object that extends object.
1141
- * @returns A reactive reference to the object.
1142
- */
1143
- function toReactive(objectRef) {
1144
- if (!isRef(objectRef)) return reactive(objectRef);
1145
- const target = objectRef.value;
1146
- if (target instanceof Map) {
1147
- const mapProxy = new Proxy(/* @__PURE__ */ new Map(), { get(_, p) {
1148
- const map = objectRef.value;
1149
- if (p === "get") return (key) => unref(map.get(key));
1150
- if (p === "set") return (key, value) => {
1151
- const existingValue = map.get(key);
1152
- if (isRef(existingValue)) existingValue.value = unref(value);
1153
- else map.set(key, value);
1154
- return mapProxy;
1155
- };
1156
- if (p === "has") return (key) => map.has(key);
1157
- if (p === "delete") return (key) => map.delete(key);
1158
- if (p === "clear") return () => map.clear();
1159
- if (p === "size") return map.size;
1160
- if (p === "keys") return () => map.keys();
1161
- if (p === "values") return function* () {
1162
- for (const value of map.values()) yield unref(value);
1163
- };
1164
- if (p === "entries") return function* () {
1165
- for (const [key, value] of map.entries()) yield [key, unref(value)];
1166
- };
1167
- if (p === "forEach") return (callback, thisArg) => {
1168
- for (const [key, value] of map.entries()) callback.call(thisArg, unref(value), key, mapProxy);
1169
- };
1170
- if (p === Symbol.iterator) return function* () {
1171
- for (const [key, value] of map.entries()) yield [key, unref(value)];
1172
- };
1173
- return Reflect.get(map, p);
1174
- } });
1175
- return reactive(mapProxy);
1176
- }
1177
- if (target instanceof Set) {
1178
- const setProxy = new Proxy(/* @__PURE__ */ new Set(), { get(_, p) {
1179
- const set = objectRef.value;
1180
- if (p === "add") return (value) => {
1181
- set.add(value);
1182
- return setProxy;
1183
- };
1184
- if (p === "has") return (value) => set.has(value);
1185
- if (p === "delete") return (value) => set.delete(value);
1186
- if (p === "clear") return () => set.clear();
1187
- if (p === "size") return set.size;
1188
- if (p === "keys" || p === "values") return function* () {
1189
- for (const value of set.values()) yield unref(value);
1190
- };
1191
- if (p === "entries") return function* () {
1192
- for (const value of set.values()) {
1193
- const unreffedValue = unref(value);
1194
- yield [unreffedValue, unreffedValue];
1195
- }
1196
- };
1197
- if (p === "forEach") return (callback, thisArg) => {
1198
- for (const value of set) {
1199
- const unreffedValue = unref(value);
1200
- callback.call(thisArg, unreffedValue, unreffedValue, setProxy);
1201
- }
1202
- };
1203
- if (p === Symbol.iterator) return function* () {
1204
- for (const value of set.values()) yield unref(value);
1205
- };
1206
- return Reflect.get(set, p);
1207
- } });
1208
- return reactive(setProxy);
1209
- }
1210
- const proxy = new Proxy({}, {
1211
- get(_, p, receiver) {
1212
- return unref(Reflect.get(objectRef.value, p, receiver));
1213
- },
1214
- set(_, p, value) {
1215
- const currentTarget = objectRef.value;
1216
- currentTarget[p] = value;
1217
- return true;
1218
- },
1219
- deleteProperty(_, p) {
1220
- return Reflect.deleteProperty(objectRef.value, p);
1221
- },
1222
- has(_, p) {
1223
- return Reflect.has(objectRef.value, p);
1224
- },
1225
- ownKeys() {
1226
- return Object.keys(objectRef.value);
1227
- },
1228
- getOwnPropertyDescriptor(_, p) {
1229
- const desc = Reflect.getOwnPropertyDescriptor(objectRef.value, p);
1230
- if (!desc) return void 0;
1231
- const newDesc = {
1232
- ...desc,
1233
- configurable: true
1234
- };
1235
- if ("value" in newDesc) newDesc.value = unref(newDesc.value);
1236
- return newDesc;
1237
- }
1238
- });
1239
- return reactive(proxy);
1240
- }
1241
-
1242
- //#endregion
1243
- //#region src/composables/useGroup/index.ts
1244
- /**
1245
- * Creates a group selection context for managing collections of items where multiple selections can be made.
1246
- * This function extends the selection functionality with group selection capabilities.
1247
- *
1248
- * @param options Optional configuration for group selection behavior.
1249
- * @template Z The type of items managed by the group selection.
1250
- * @template E The type of the group selection context.
1251
- * @returns The group selection context object.
1252
- */
1253
- function useGroup(options) {
1254
- const registry = useSelection(options);
1255
- const selectedIndexes = computed(() => {
1256
- return new Set(Array.from(registry.selectedItems.value).map((item) => item?.index));
1257
- });
1258
- function select(ids) {
1259
- for (const id of toArray(ids)) registry.select(id);
1260
- }
1261
- function unselect(ids) {
1262
- for (const id of toArray(ids)) registry.unselect(id);
1263
- }
1264
- function toggle(ids) {
1265
- for (const id of toArray(ids)) registry.toggle(id);
1266
- }
1267
- return {
1268
- ...registry,
1269
- select,
1270
- unselect,
1271
- toggle,
1272
- selectedIndexes
1273
- };
1274
- }
1275
-
1276
- //#endregion
1277
- //#region src/components/Group/GroupItem.vue?vue&type=script&setup=true&lang.ts
1278
- var GroupItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1279
- name: "GroupItem",
1280
- __name: "GroupItem",
1281
- props: {
1282
- id: { default: () => useId() },
1283
- value: {},
1284
- disabled: { type: Boolean },
1285
- namespace: { default: "group" }
1286
- },
1287
- setup(__props) {
1288
- const [useGroupContext] = useGroup(__props.namespace);
1289
- const group = useGroupContext();
1290
- if (!group) throw new Error(`Failed to get group context at namespace "${__props.namespace}"`);
1291
- const { isActive, toggle, index } = group.register({
1292
- id: __props.id,
1293
- value: __props.value,
1294
- disabled: __props.disabled
1295
- });
1296
- onUnmounted(() => {
1297
- group.unregister(__props.id);
1298
- });
1299
- return (_ctx, _cache) => {
1300
- return renderSlot(_ctx.$slots, "default", {
1301
- index: unref(index),
1302
- isActive: unref(isActive),
1303
- toggle: unref(toggle)
1304
- });
1305
- };
1306
- }
1307
- });
1308
-
1309
- //#endregion
1310
- //#region src/components/Group/GroupItem.vue
1311
- var GroupItem_default = GroupItem_vue_vue_type_script_setup_true_lang_default;
1312
-
1313
- //#endregion
1314
- //#region src/components/Group/GroupRoot.vue?vue&type=script&setup=true&lang.ts
1315
- var GroupRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1316
- name: "GroupRoot",
1317
- __name: "GroupRoot",
1318
- props: /* @__PURE__ */ mergeModels({
1319
- namespace: { default: "group" },
1320
- enroll: { type: Boolean },
1321
- mandatory: { type: [Boolean, String] },
1322
- events: { type: Boolean }
1323
- }, {
1324
- "modelValue": {},
1325
- "modelModifiers": {}
1326
- }),
1327
- emits: ["update:modelValue"],
1328
- setup(__props) {
1329
- const props = createPropsRestProxy(__props, ["namespace"]);
1330
- const model = useModel(__props, "modelValue");
1331
- const [, provideGroupContext] = useGroup(__props.namespace, props);
1332
- const { register, unregister, reset, mandate, select } = provideGroupContext(model);
1333
- return (_ctx, _cache) => {
1334
- return renderSlot(_ctx.$slots, "default", {
1335
- mandate: unref(mandate),
1336
- model: model.value,
1337
- register: unref(register),
1338
- reset: unref(reset),
1339
- select: unref(select),
1340
- unregister: unref(unregister)
1341
- });
1342
- };
1343
- }
1344
- });
1345
-
1346
- //#endregion
1347
- //#region src/components/Group/GroupRoot.vue
1348
- var GroupRoot_default = GroupRoot_vue_vue_type_script_setup_true_lang_default;
1349
-
1350
- //#endregion
1351
- //#region src/components/Group/index.ts
1352
- const Group = {
1353
- Item: GroupItem_default,
1354
- Root: GroupRoot_default
1355
- };
1356
-
1357
- //#endregion
1358
- //#region src/components/Hydration/Hydration.vue?vue&type=script&setup=true&lang.ts
1359
- var Hydration_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1360
- name: "Hydration",
1361
- __name: "Hydration",
1362
- setup(__props) {
1363
- const hydrationContext = useHydration();
1364
- return (_ctx, _cache) => {
1365
- return renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(hydrationContext))));
1366
- };
1367
- }
1368
- });
1369
-
1370
- //#endregion
1371
- //#region src/components/Hydration/Hydration.vue
1372
- var Hydration_default = Hydration_vue_vue_type_script_setup_true_lang_default;
1373
-
1374
- //#endregion
1375
- //#region src/components/Hydration/HydrationRoot.vue?vue&type=script&setup=true&lang.ts
1376
- var HydrationRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1377
- name: "HydrationRoot",
1378
- __name: "HydrationRoot",
1379
- setup(__props) {
1380
- const hydrationContext = createHydration();
1381
- provideHydrationContext(hydrationContext);
1382
- return (_ctx, _cache) => {
1383
- return renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(hydrationContext))));
1384
- };
1385
- }
1386
- });
1387
-
1388
- //#endregion
1389
- //#region src/components/Hydration/HydrationRoot.vue
1390
- var HydrationRoot_default = HydrationRoot_vue_vue_type_script_setup_true_lang_default;
1391
-
1392
- //#endregion
1393
- //#region src/components/Popover/PopoverRoot.vue?vue&type=script&setup=true&lang.ts
1394
- const [usePopoverContext, providePopoverContext] = createContext("Popover");
1395
- var PopoverRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1396
- name: "PopoverRoot",
1397
- __name: "PopoverRoot",
1398
- props: /* @__PURE__ */ mergeModels({
1399
- id: {},
1400
- as: { default: null },
1401
- renderless: { type: Boolean }
1402
- }, {
1403
- "modelValue": {
1404
- type: Boolean,
1405
- default: false
1406
- },
1407
- "modelModifiers": {}
1408
- }),
1409
- emits: ["update:modelValue"],
1410
- setup(__props) {
1411
- const props = createPropsRestProxy(__props, ["as"]);
1412
- const isActive = useModel(__props, "modelValue");
1413
- const id = toRef(() => props.id ?? useId());
1414
- function toggle() {
1415
- isActive.value = !isActive.value;
1416
- }
1417
- const bindableProps = toRef(() => ({
1418
- id,
1419
- isActive,
1420
- toggle
1421
- }));
1422
- providePopoverContext({
1423
- isActive,
1424
- toggle,
1425
- id: id.value
1426
- });
1427
- return (_ctx, _cache) => {
1428
- return openBlock(), createBlock(unref(Atom_default), mergeProps({
1429
- as: _ctx.as,
1430
- renderless: _ctx.renderless
1431
- }, bindableProps.value), {
1432
- default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(bindableProps.value)))]),
1433
- _: 3
1434
- }, 16, ["as", "renderless"]);
1435
- };
1436
- }
1437
- });
1438
-
1439
- //#endregion
1440
- //#region src/components/Popover/PopoverRoot.vue
1441
- var PopoverRoot_default = PopoverRoot_vue_vue_type_script_setup_true_lang_default;
1442
-
1443
- //#endregion
1444
- //#region src/components/Popover/PopoverAnchor.vue?vue&type=script&setup=true&lang.ts
1445
- var PopoverAnchor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1446
- name: "PopoverAnchor",
1447
- __name: "PopoverAnchor",
1448
- props: {
1449
- target: {},
1450
- as: { default: "button" },
1451
- renderless: { type: Boolean }
1452
- },
1453
- setup(__props) {
1454
- const props = createPropsRestProxy(__props, ["as"]);
1455
- const context = usePopoverContext();
1456
- const popovertarget = toRef(() => props.target ?? context.id);
1457
- const style = toRef(() => ({ anchorName: `--${popovertarget.value}` }));
1458
- return (_ctx, _cache) => {
1459
- return openBlock(), createBlock(unref(Atom_default), {
1460
- as: _ctx.as,
1461
- "data-popover-open": unref(context).isActive.value ? "" : void 0,
1462
- popovertarget: popovertarget.value,
1463
- style: normalizeStyle(style.value),
1464
- type: _ctx.as === "button" ? "button" : void 0
1465
- }, {
1466
- default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
1467
- _: 3
1468
- }, 8, [
1469
- "as",
1470
- "data-popover-open",
1471
- "popovertarget",
1472
- "style",
1473
- "type"
1474
- ]);
1475
- };
1476
- }
1477
- });
1478
-
1479
- //#endregion
1480
- //#region src/components/Popover/PopoverAnchor.vue
1481
- var PopoverAnchor_default = PopoverAnchor_vue_vue_type_script_setup_true_lang_default;
1482
-
1483
- //#endregion
1484
- //#region src/components/Popover/PopoverContent.vue?vue&type=script&setup=true&lang.ts
1485
- var PopoverContent_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1486
- name: "PopoverContent",
1487
- __name: "PopoverContent",
1488
- props: {
1489
- id: {},
1490
- positionArea: { default: "bottom" },
1491
- positionTry: { default: "most-width bottom" },
1492
- as: {},
1493
- renderless: { type: Boolean }
1494
- },
1495
- emits: ["beforetoggle"],
1496
- setup(__props, { emit: __emit }) {
1497
- const props = createPropsRestProxy(__props, ["positionArea", "positionTry"]);
1498
- const emit = __emit;
1499
- const context = usePopoverContext();
1500
- const ref$1 = useTemplateRef("ref");
1501
- const id = toRef(() => props.id ?? context.id);
1502
- const style = toRef(() => ({
1503
- positionArea: __props.positionArea,
1504
- positionAnchor: `--${id.value}`,
1505
- positionTry: __props.positionTry
1506
- }));
1507
- onMounted(() => {
1508
- if (context.isActive.value) ref$1.value?.element?.showPopover();
1509
- });
1510
- function onBeforeToggle(e) {
1511
- context.isActive.value = e.newState === "open";
1512
- emit("beforetoggle", e);
1513
- }
1514
- return (_ctx, _cache) => {
1515
- return openBlock(), createBlock(unref(Atom_default), {
1516
- id: id.value,
1517
- ref_key: "ref",
1518
- ref: ref$1,
1519
- popover: "",
1520
- style: normalizeStyle(style.value),
1521
- onBeforetoggle: onBeforeToggle
1522
- }, {
1523
- default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
1524
- _: 3
1525
- }, 8, ["id", "style"]);
1526
- };
1527
- }
1528
- });
1529
-
1530
- //#endregion
1531
- //#region src/components/Popover/PopoverContent.vue
1532
- var PopoverContent_default = PopoverContent_vue_vue_type_script_setup_true_lang_default;
1533
-
1534
- //#endregion
1535
- //#region src/components/Popover/index.ts
1536
- const Popover = {
1537
- Root: PopoverRoot_default,
1538
- Anchor: PopoverAnchor_default,
1539
- Content: PopoverContent_default
1540
- };
1541
-
1542
1353
  //#endregion
1543
1354
  //#region src/composables/useSingle/index.ts
1544
1355
  /**
@@ -1552,7 +1363,7 @@ const Popover = {
1552
1363
  */
1553
1364
  function useSingle(options) {
1554
1365
  const registry = useSelection(options);
1555
- const mandatory = options?.mandatory ?? true;
1366
+ const mandatory = options?.mandatory ?? false;
1556
1367
  const selectedId = computed(() => registry.selectedIds.values().next().value);
1557
1368
  const selectedItem = computed(() => registry.selectedItems.value.values().next().value);
1558
1369
  const selectedIndex = computed(() => selectedItem.value?.index ?? -1);
@@ -1561,7 +1372,7 @@ function useSingle(options) {
1561
1372
  const item = registry.get(id);
1562
1373
  if (!item || item.disabled) return;
1563
1374
  registry.selectedIds.clear();
1564
- registry.selectedIds.add(id);
1375
+ registry.select(id);
1565
1376
  }
1566
1377
  function unselect(id) {
1567
1378
  if (mandatory && registry.selectedIds.size === 1) return;
@@ -1582,151 +1393,35 @@ function useSingle(options) {
1582
1393
  toggle
1583
1394
  };
1584
1395
  }
1585
-
1586
- //#endregion
1587
- //#region src/composables/useStep/index.ts
1588
1396
  /**
1589
- * Creates a step selection context for managing collections where users can navigate through items sequentially.
1590
- * This function extends the single selection functionality with stepping navigation.
1397
+ * Creates a single selection registry context with full injection/provision control.
1398
+ * Returns the complete trinity for advanced usage scenarios.
1591
1399
  *
1592
- * @param options Optional configuration for step behavior.
1593
- * @template Z The type of items managed by the step selection.
1594
- * @template E The type of the step selection context.
1595
- * @returns The step selection context object.
1400
+ * @param namespace The namespace for the single selection registry context
1401
+ * @param options Optional configuration for single selection behavior.
1402
+ * @template Z The structure of the registry single selection items.
1403
+ * @template E The available methods for the single's context.
1404
+ * @returns A tuple containing the inject function, provide function, and the single selection context.
1596
1405
  */
1597
- function useStep(options) {
1598
- const registry = useSingle(options);
1599
- function first() {
1600
- if (registry.size === 0) return;
1601
- registry.selectedIds.clear();
1602
- registry.select(registry.lookup(0));
1603
- }
1604
- function last() {
1605
- const size = registry.size;
1606
- if (size === 0) return;
1607
- registry.selectedIds.clear();
1608
- registry.select(registry.lookup(size - 1));
1609
- }
1610
- function next() {
1611
- step(1);
1612
- }
1613
- function prev() {
1614
- step(-1);
1615
- }
1616
- function wrapped(length, index) {
1617
- return (index + length) % length;
1618
- }
1619
- function step(count = 1) {
1620
- const length = registry.size;
1621
- if (!length) return;
1622
- const direction = Math.sign(count || 1);
1623
- let hops = 0;
1624
- let index = wrapped(length, registry.selectedIndex.value + count);
1625
- let id = registry.lookup(index);
1626
- while (id !== void 0 && registry.get(id)?.disabled && hops < length) {
1627
- index = wrapped(length, index + direction);
1628
- id = registry.lookup(index);
1629
- hops++;
1630
- }
1631
- if (id === void 0 || hops === length) return;
1632
- registry.selectedIds.clear();
1633
- registry.select(id);
1406
+ function createSingleContext(namespace, options) {
1407
+ const [useSingleContext, _provideSingleContext] = createContext(namespace);
1408
+ const context = useSingle(options);
1409
+ function provideSingleContext(_context = context, app) {
1410
+ return _provideSingleContext(_context, app);
1634
1411
  }
1635
- return {
1636
- ...registry,
1637
- first,
1638
- last,
1639
- next,
1640
- prev,
1641
- step
1642
- };
1412
+ return createTrinity(useSingleContext, provideSingleContext, context);
1643
1413
  }
1644
1414
 
1645
1415
  //#endregion
1646
- //#region src/components/Step/StepItem.vue?vue&type=script&setup=true&lang.ts
1647
- var StepItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1648
- name: "StepItem",
1649
- __name: "StepItem",
1650
- props: {
1651
- id: { default: () => useId() },
1652
- value: {},
1653
- disabled: { type: Boolean },
1654
- namespace: { default: "step" }
1655
- },
1656
- setup(__props) {
1657
- const [useStepContext] = useStep(__props.namespace);
1658
- const step = useStepContext();
1659
- if (!step) throw new Error(`Failed to get step context at namespace "${__props.namespace}"`);
1660
- const { index, isActive, toggle } = step.register({
1661
- id: __props.id,
1662
- value: __props.value,
1663
- disabled: __props.disabled
1664
- });
1665
- onUnmounted(() => {
1666
- step.unregister(__props.id);
1667
- });
1668
- return (_ctx, _cache) => {
1669
- return renderSlot(_ctx.$slots, "default", {
1670
- index: unref(index),
1671
- isActive: unref(isActive),
1672
- toggle: unref(toggle)
1673
- });
1674
- };
1675
- }
1676
- });
1677
-
1678
- //#endregion
1679
- //#region src/components/Step/StepItem.vue
1680
- var StepItem_default = StepItem_vue_vue_type_script_setup_true_lang_default;
1681
-
1682
- //#endregion
1683
- //#region src/components/Step/StepRoot.vue?vue&type=script&setup=true&lang.ts
1684
- var StepRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1685
- name: "StepRoot",
1686
- __name: "StepRoot",
1687
- props: /* @__PURE__ */ mergeModels({
1688
- namespace: { default: "step" },
1689
- enroll: { type: Boolean },
1690
- mandatory: { type: [Boolean, String] },
1691
- events: { type: Boolean }
1692
- }, {
1693
- "modelValue": {},
1694
- "modelModifiers": {}
1695
- }),
1696
- emits: ["update:modelValue"],
1697
- setup(__props) {
1698
- const props = createPropsRestProxy(__props, ["namespace"]);
1699
- const model = useModel(__props, "modelValue");
1700
- const [, provideStepContext] = useStep(__props.namespace, props);
1701
- const { register, unregister, reset, mandate, select, first, last, next, prev, step } = provideStepContext(model);
1702
- return (_ctx, _cache) => {
1703
- return renderSlot(_ctx.$slots, "default", {
1704
- first: unref(first),
1705
- last: unref(last),
1706
- mandate: unref(mandate),
1707
- model: model.value,
1708
- next: unref(next),
1709
- prev: unref(prev),
1710
- register: unref(register),
1711
- reset: unref(reset),
1712
- select: unref(select),
1713
- step: unref(step),
1714
- unregister: unref(unregister)
1715
- });
1716
- };
1717
- }
1718
- });
1719
-
1720
- //#endregion
1721
- //#region src/components/Step/StepRoot.vue
1722
- var StepRoot_default = StepRoot_vue_vue_type_script_setup_true_lang_default;
1723
-
1724
- //#endregion
1725
- //#region src/components/Step/index.ts
1726
- const Step = {
1727
- Item: StepItem_default,
1728
- Root: StepRoot_default
1729
- };
1416
+ //#region src/utilities/benchmark.ts
1417
+ async function run(name, fn, samples = 100) {
1418
+ fn();
1419
+ return {
1420
+ name,
1421
+ duration: 0,
1422
+ ops: Infinity
1423
+ };
1424
+ }
1730
1425
 
1731
1426
  //#endregion
1732
1427
  //#region src/composables/useTokens/index.ts
@@ -1738,13 +1433,15 @@ const Step = {
1738
1433
  * @template Z The structure of the registry token items.
1739
1434
  * @template E The available methods for the token's context.
1740
1435
  * @returns The token context object.
1436
+ *
1437
+ * @see https://0.vuetifyjs.com/composables/registration/use-tokens
1741
1438
  * @see https://www.designtokens.org/tr/drafts/format/
1742
1439
  */
1743
- function useTokens(tokens = {}) {
1440
+ function useTokens(tokens = {}, options = {}) {
1744
1441
  const logger = useLogger();
1745
1442
  const registry = useRegistry();
1746
1443
  const cache = /* @__PURE__ */ new Map();
1747
- registry.onboard(flatten(tokens));
1444
+ registry.onboard(flatten(tokens, options.prefix, !!options.flat));
1748
1445
  function isAlias(token) {
1749
1446
  return isString(token) && token.length > 2 && token[0] === "{" && token.at(-1) === "}";
1750
1447
  }
@@ -1775,7 +1472,7 @@ function useTokens(tokens = {}) {
1775
1472
  if (found?.value === void 0) {
1776
1473
  logger.warn(`Alias not found for "${String(reference)}"`);
1777
1474
  cache.set(cacheKey, void 0);
1778
- return void 0;
1475
+ return;
1779
1476
  }
1780
1477
  let result;
1781
1478
  let current = found.value;
@@ -1792,7 +1489,7 @@ function useTokens(tokens = {}) {
1792
1489
  if (current === void 0) {
1793
1490
  logger.warn(`Path not found inside "${clean}": ${segments.join(".")}`);
1794
1491
  cache.set(cacheKey, void 0);
1795
- return void 0;
1492
+ return;
1796
1493
  }
1797
1494
  result = current;
1798
1495
  } else if (isTokenAlias(current)) {
@@ -1806,7 +1503,8 @@ function useTokens(tokens = {}) {
1806
1503
  }
1807
1504
  return {
1808
1505
  ...registry,
1809
- resolve
1506
+ resolve,
1507
+ isAlias
1810
1508
  };
1811
1509
  }
1812
1510
  /**
@@ -1834,14 +1532,15 @@ function createTokensContext(namespace, tokens = {}) {
1834
1532
  * @param prefix An optional prefix to prepend to each token ID.
1835
1533
  * @returns An array of flattened tokens, each with an ID and value.
1836
1534
  */
1837
- function flatten(tokens, prefix = "") {
1535
+ function flatten(tokens, prefix = "", flat = false) {
1838
1536
  const flattened = [];
1839
1537
  const stack = [{
1840
1538
  tokens,
1841
- prefix
1539
+ prefix,
1540
+ flat
1842
1541
  }];
1843
1542
  while (stack.length > 0) {
1844
- const { tokens: currentTokens, prefix: currentPrefix } = stack.pop();
1543
+ const { tokens: currentTokens, prefix: currentPrefix, flat: flat$1 } = stack.pop();
1845
1544
  const meta = {};
1846
1545
  for (const k in currentTokens) if (k.startsWith("$")) meta[k] = currentTokens[k];
1847
1546
  if (Object.keys(meta).length > 0 && currentPrefix) flattened.push({
@@ -1865,7 +1564,7 @@ function flatten(tokens, prefix = "") {
1865
1564
  value
1866
1565
  });
1867
1566
  const inner = value.$value;
1868
- if (isObject(inner)) for (const innerKey in inner) {
1567
+ if (isObject(inner) && !flat$1) for (const innerKey in inner) {
1869
1568
  if (innerKey.startsWith("$")) continue;
1870
1569
  const child = inner[innerKey];
1871
1570
  const childId = `${id}.${innerKey}`;
@@ -1879,14 +1578,23 @@ function flatten(tokens, prefix = "") {
1879
1578
  });
1880
1579
  else stack.push({
1881
1580
  tokens: child,
1882
- prefix: childId
1581
+ prefix: childId,
1582
+ flat: flat$1
1883
1583
  });
1884
1584
  }
1885
1585
  continue;
1886
1586
  }
1587
+ if (flat$1) {
1588
+ flattened.push({
1589
+ id,
1590
+ value
1591
+ });
1592
+ continue;
1593
+ }
1887
1594
  stack.push({
1888
1595
  tokens: value,
1889
- prefix: id
1596
+ prefix: id,
1597
+ flat: flat$1
1890
1598
  });
1891
1599
  }
1892
1600
  }
@@ -1955,17 +1663,23 @@ var Vuetify0ThemeAdapter = class extends ThemeAdapter {
1955
1663
  * @template Z The type of theme context.
1956
1664
  * @template E The type of theme items managed by the registry.
1957
1665
  * @returns A tuple containing inject, provide functions and the theme context.
1666
+ *
1667
+ * @see https://0.vuetifyjs.com/composables/plugins/use-theme
1958
1668
  */
1959
1669
  function createTheme(namespace = "v0:theme", options = {}) {
1960
1670
  const { themes = {}, palette = {} } = options;
1961
1671
  const [useThemeContext, _provideThemeContext] = createContext(namespace);
1672
+ const tokens = useTokens({
1673
+ palette,
1674
+ ...themes
1675
+ }, { flat: true });
1962
1676
  const registry = useSingle();
1963
1677
  for (const id in themes) {
1678
+ const { colors: value,...theme } = themes[id];
1964
1679
  register({
1965
1680
  id,
1966
- value: themes[id].colors,
1967
- dark: themes[id].dark ?? false,
1968
- lazy: themes[id].lazy ?? false
1681
+ value,
1682
+ ...theme
1969
1683
  });
1970
1684
  if (id === options.default && !registry.selectedId.value) registry.select(id);
1971
1685
  }
@@ -1974,7 +1688,7 @@ function createTheme(namespace = "v0:theme", options = {}) {
1974
1688
  const resolved = {};
1975
1689
  for (const theme of registry.values()) {
1976
1690
  if (theme.lazy && theme.id !== registry.selectedId.value) continue;
1977
- resolved[String(theme.id)] = resolve(theme.id, theme.value);
1691
+ resolved[theme.id] = resolve(theme.value);
1978
1692
  }
1979
1693
  return resolved;
1980
1694
  });
@@ -1983,26 +1697,11 @@ function createTheme(namespace = "v0:theme", options = {}) {
1983
1697
  const next = current === -1 ? 0 : (current + 1) % themes$1.length;
1984
1698
  registry.select(themes$1[next]);
1985
1699
  }
1986
- function resolve(themeId, colors$1) {
1700
+ function resolve(colors$1) {
1987
1701
  const resolved = {};
1988
- for (const [key, value] of Object.entries(colors$1)) resolved[key] = resolveTokenReference(themeId, value);
1702
+ for (const [key, value] of Object.entries(colors$1)) resolved[key] = tokens.isAlias(value) ? tokens.resolve(value) : value;
1989
1703
  return resolved;
1990
1704
  }
1991
- function resolveTokenReference(themeId, value) {
1992
- return value.replace(/{([a-zA-Z0-9.-_]+)}/g, (match, tokenKey) => {
1993
- if (palette[tokenKey]) return isString(palette[tokenKey]) ? palette[tokenKey] : match;
1994
- const [targetTheme, ...colorPath] = tokenKey.split(".");
1995
- const colorKey = colorPath.join(".");
1996
- if (targetTheme && colorKey) {
1997
- const targetColors = themes[targetTheme];
1998
- const resolved$1 = targetColors?.[colorKey];
1999
- return isString(resolved$1) ? resolveTokenReference(targetTheme, resolved$1) : match;
2000
- }
2001
- const currentColors = themes[themeId];
2002
- const resolved = currentColors?.[tokenKey];
2003
- return isString(resolved) ? resolveTokenReference(themeId, resolved) : match;
2004
- });
2005
- }
2006
1705
  function register(registration = {}) {
2007
1706
  const item = {
2008
1707
  lazy: false,
@@ -2026,9 +1725,11 @@ function createTheme(namespace = "v0:theme", options = {}) {
2026
1725
  * Simple hook to access the theme context.
2027
1726
  *
2028
1727
  * @returns The theme context containing current theme state and utilities.
1728
+ *
1729
+ * @see https://0.vuetifyjs.com/composables/plugins/use-theme
2029
1730
  */
2030
1731
  function useTheme() {
2031
- return useContext("v0:theme")();
1732
+ return useContext("v0:theme");
2032
1733
  }
2033
1734
  /**
2034
1735
  * Creates a Vue plugin for theme management with automatic color system updates.
@@ -2038,16 +1739,12 @@ function useTheme() {
2038
1739
  * @param options Configuration for themes, palette, and adapter.
2039
1740
  * @template Z The type of theme context.
2040
1741
  * @template E The type of theme items.
2041
- * @template R The type of token context.
2042
- * @template O The type of token items.
2043
1742
  * @returns A Vue plugin object with install method.
1743
+ *
1744
+ * @see https://0.vuetifyjs.com/composables/plugins/use-theme
2044
1745
  */
2045
1746
  function createThemePlugin(_options = {}) {
2046
1747
  const { adapter = new Vuetify0ThemeAdapter(), palette = {}, themes = {},...options } = _options;
2047
- const [, provideThemeTokenContext, tokensContext] = createTokensContext("v0:theme:tokens", {
2048
- palette,
2049
- ...themes
2050
- });
2051
1748
  const [, provideThemeContext, themeContext] = createTheme("v0:theme", {
2052
1749
  ...options,
2053
1750
  themes,
@@ -2060,7 +1757,6 @@ function createThemePlugin(_options = {}) {
2060
1757
  namespace: "v0:theme",
2061
1758
  provide: (app) => {
2062
1759
  provideThemeContext(themeContext, app);
2063
- provideThemeTokenContext(tokensContext, app);
2064
1760
  },
2065
1761
  setup: () => {
2066
1762
  if (IN_BROWSER) watch(themeContext.colors, update, {
@@ -2094,16 +1790,11 @@ var ThemeItem_default = ThemeItem_vue_vue_type_script_setup_true_lang_default;
2094
1790
  var ThemeRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2095
1791
  name: "ThemeRoot",
2096
1792
  __name: "ThemeRoot",
2097
- props: /* @__PURE__ */ mergeModels({
1793
+ props: {
2098
1794
  namespace: { default: "v0:theme" },
2099
1795
  themes: { default: () => [] }
2100
- }, {
2101
- "modelValue": { default: "default" },
2102
- "modelModifiers": {}
2103
- }),
2104
- emits: ["update:modelValue"],
1796
+ },
2105
1797
  setup(__props) {
2106
- useModel(__props, "modelValue");
2107
1798
  const [provideThemeContext] = createTheme(__props.namespace);
2108
1799
  const themeContext = provideThemeContext();
2109
1800
  for (const theme of __props.themes) themeContext.register(theme);
@@ -2124,6 +1815,124 @@ const Theme = {
2124
1815
  Root: ThemeRoot_default
2125
1816
  };
2126
1817
 
1818
+ //#endregion
1819
+ //#region src/transformers/toArray/index.ts
1820
+ /* @__NO_SIDE_EFFECTS__ */
1821
+ function toArray(value) {
1822
+ return isNullOrUndefined(value) ? [] : Array.isArray(value) ? value : [value];
1823
+ }
1824
+
1825
+ //#endregion
1826
+ //#region src/transformers/toReactive/index.ts
1827
+ /**
1828
+ * Converts an object to a reactive reference using Vue's reactivity system.
1829
+ * This function creates a reactive version of the provided object,
1830
+ * making its properties automatically track dependencies and trigger re-renders
1831
+ * when they change.
1832
+ *
1833
+ * @param objectRef - A reference to an object that should be made reactive.
1834
+ * @template Z The type of the object that extends object.
1835
+ * @returns A reactive reference to the object.
1836
+ */
1837
+ function toReactive(objectRef) {
1838
+ if (!isRef(objectRef)) return reactive(objectRef);
1839
+ const target = objectRef.value;
1840
+ if (target instanceof Map) {
1841
+ const mapProxy = new Proxy(/* @__PURE__ */ new Map(), { get(_, p) {
1842
+ const map = objectRef.value;
1843
+ if (p === "get") return (key) => unref(map.get(key));
1844
+ if (p === "set") return (key, value) => {
1845
+ const existingValue = map.get(key);
1846
+ if (isRef(existingValue)) existingValue.value = unref(value);
1847
+ else map.set(key, value);
1848
+ return mapProxy;
1849
+ };
1850
+ if (p === "has") return (key) => map.has(key);
1851
+ if (p === "delete") return (key) => map.delete(key);
1852
+ if (p === "clear") return () => map.clear();
1853
+ if (p === "size") return map.size;
1854
+ if (p === "keys") return () => map.keys();
1855
+ if (p === "values") return function* () {
1856
+ for (const value of map.values()) yield unref(value);
1857
+ };
1858
+ if (p === "entries") return function* () {
1859
+ for (const [key, value] of map.entries()) yield [key, unref(value)];
1860
+ };
1861
+ if (p === "forEach") return (callback, thisArg) => {
1862
+ for (const [key, value] of map.entries()) callback.call(thisArg, unref(value), key, mapProxy);
1863
+ };
1864
+ if (p === Symbol.iterator) return function* () {
1865
+ for (const [key, value] of map.entries()) yield [key, unref(value)];
1866
+ };
1867
+ return Reflect.get(map, p);
1868
+ } });
1869
+ return reactive(mapProxy);
1870
+ }
1871
+ if (target instanceof Set) {
1872
+ const setProxy = new Proxy(/* @__PURE__ */ new Set(), { get(_, p) {
1873
+ const set = objectRef.value;
1874
+ if (p === "add") return (value) => {
1875
+ set.add(value);
1876
+ return setProxy;
1877
+ };
1878
+ if (p === "has") return (value) => set.has(value);
1879
+ if (p === "delete") return (value) => set.delete(value);
1880
+ if (p === "clear") return () => set.clear();
1881
+ if (p === "size") return set.size;
1882
+ if (p === "keys" || p === "values") return function* () {
1883
+ for (const value of set.values()) yield unref(value);
1884
+ };
1885
+ if (p === "entries") return function* () {
1886
+ for (const value of set.values()) {
1887
+ const unreffedValue = unref(value);
1888
+ yield [unreffedValue, unreffedValue];
1889
+ }
1890
+ };
1891
+ if (p === "forEach") return (callback, thisArg) => {
1892
+ for (const value of set) {
1893
+ const unreffedValue = unref(value);
1894
+ callback.call(thisArg, unreffedValue, unreffedValue, setProxy);
1895
+ }
1896
+ };
1897
+ if (p === Symbol.iterator) return function* () {
1898
+ for (const value of set.values()) yield unref(value);
1899
+ };
1900
+ return Reflect.get(set, p);
1901
+ } });
1902
+ return reactive(setProxy);
1903
+ }
1904
+ const proxy = new Proxy({}, {
1905
+ get(_, p, receiver) {
1906
+ return unref(Reflect.get(objectRef.value, p, receiver));
1907
+ },
1908
+ set(_, p, value) {
1909
+ const currentTarget = objectRef.value;
1910
+ currentTarget[p] = value;
1911
+ return true;
1912
+ },
1913
+ deleteProperty(_, p) {
1914
+ return Reflect.deleteProperty(objectRef.value, p);
1915
+ },
1916
+ has(_, p) {
1917
+ return Reflect.has(objectRef.value, p);
1918
+ },
1919
+ ownKeys() {
1920
+ return Object.keys(objectRef.value);
1921
+ },
1922
+ getOwnPropertyDescriptor(_, p) {
1923
+ const desc = Reflect.getOwnPropertyDescriptor(objectRef.value, p);
1924
+ if (!desc) return;
1925
+ const newDesc = {
1926
+ ...desc,
1927
+ configurable: true
1928
+ };
1929
+ if ("value" in newDesc) newDesc.value = unref(newDesc.value);
1930
+ return newDesc;
1931
+ }
1932
+ });
1933
+ return reactive(proxy);
1934
+ }
1935
+
2127
1936
  //#endregion
2128
1937
  //#region src/composables/useEventListener/index.ts
2129
1938
  function useEventListener(target, event, listener, options) {
@@ -2132,10 +1941,10 @@ function useEventListener(target, event, listener, options) {
2132
1941
  for (const fn of cleanups) fn();
2133
1942
  cleanups.length = 0;
2134
1943
  }
2135
- const register = (el, event$1, listener$1, options$1) => {
1944
+ function register(el, event$1, listener$1, options$1) {
2136
1945
  el.addEventListener(event$1, listener$1, options$1);
2137
1946
  return () => el.removeEventListener(event$1, listener$1, options$1);
2138
- };
1947
+ }
2139
1948
  const stopWatcher = watch(() => [
2140
1949
  toValue(target),
2141
1950
  toValue(event),
@@ -2185,6 +1994,132 @@ function useDocumentEventListener(event, listener, options) {
2185
1994
  return useEventListener(document, event, listener, options);
2186
1995
  }
2187
1996
 
1997
+ //#endregion
1998
+ //#region src/composables/useGroup/index.ts
1999
+ /**
2000
+ * Creates a group selection context for managing collections of items where multiple selections can be made.
2001
+ * This function extends the selection functionality with group selection capabilities.
2002
+ *
2003
+ * @param options Optional configuration for group selection behavior.
2004
+ * @template Z The type of items managed by the group selection.
2005
+ * @template E The type of the group selection context.
2006
+ * @returns The group selection context object.
2007
+ */
2008
+ function useGroup(options) {
2009
+ const registry = useSelection(options);
2010
+ const selectedIndexes = computed(() => {
2011
+ return new Set(Array.from(registry.selectedItems.value).map((item) => item?.index));
2012
+ });
2013
+ function select(ids) {
2014
+ for (const id of toArray(ids)) registry.select(id);
2015
+ }
2016
+ function unselect(ids) {
2017
+ for (const id of toArray(ids)) registry.unselect(id);
2018
+ }
2019
+ function toggle(ids) {
2020
+ for (const id of toArray(ids)) registry.toggle(id);
2021
+ }
2022
+ return {
2023
+ ...registry,
2024
+ select,
2025
+ unselect,
2026
+ toggle,
2027
+ selectedIndexes
2028
+ };
2029
+ }
2030
+ /**
2031
+ * Creates a group selection registry context with full injection/provision control.
2032
+ * Returns the complete trinity for advanced usage scenarios.
2033
+ *
2034
+ * @param namespace The namespace for the group selection registry context
2035
+ * @param options Optional configuration for group selection behavior.
2036
+ * @template Z The structure of the registry group selection items.
2037
+ * @template E The available methods for the group's context.
2038
+ * @returns A tuple containing the inject function, provide function, and the group selection context.
2039
+ */
2040
+ function createGroupContext(namespace, options) {
2041
+ const [useGroupContext, _provideGroupContext] = createContext(namespace);
2042
+ const context = useGroup(options);
2043
+ function provideGroupContext(_context = context, app) {
2044
+ return _provideGroupContext(_context, app);
2045
+ }
2046
+ return createTrinity(useGroupContext, provideGroupContext, context);
2047
+ }
2048
+
2049
+ //#endregion
2050
+ //#region src/composables/useFeatures/index.ts
2051
+ /**
2052
+ *
2053
+ * @param namespace The namespace for the feature context
2054
+ * @param options Configure initial features to register
2055
+ * @template Z The type of feature ticket
2056
+ * @template E The type of feature context
2057
+ * @returns A context trinity for the features context
2058
+ *
2059
+ * @see https://0.vuetifyjs.com/composables/plugins/create-features
2060
+ */
2061
+ function createFeatures(namespace = "v0:features", options = {}) {
2062
+ const [useFeaturesContext, _provideFeaturesContext] = createContext(namespace);
2063
+ const tokens = useTokens(options.features, { flat: true });
2064
+ const registry = useGroup();
2065
+ for (const [id, { value }] of tokens.entries()) register({
2066
+ id,
2067
+ value
2068
+ });
2069
+ function variation(id, fallback = null) {
2070
+ const ticket = registry.get(id);
2071
+ if (!ticket) return fallback;
2072
+ return isObject(ticket.value) ? ticket.value.$variation ?? fallback : fallback;
2073
+ }
2074
+ function register(registration = {}) {
2075
+ const item = {
2076
+ value: false,
2077
+ ...registration
2078
+ };
2079
+ const ticket = registry.register(item);
2080
+ if (isBoolean(ticket.value) || isObject(ticket.value) && isBoolean(ticket.value.$value) && ticket.value.$value === true) registry.select(ticket.id);
2081
+ return ticket;
2082
+ }
2083
+ const context = {
2084
+ ...registry,
2085
+ variation,
2086
+ register
2087
+ };
2088
+ function provideFeaturesContext(_context = context, app) {
2089
+ return _provideFeaturesContext(_context, app);
2090
+ }
2091
+ return createTrinity(useFeaturesContext, provideFeaturesContext, context);
2092
+ }
2093
+ /**
2094
+ * Simple hook to access the theme context.
2095
+ *
2096
+ * @returns The features context containing current theme state and utilities.
2097
+ *
2098
+ * @see https://0.vuetifyjs.com/composables/plugins/create-features
2099
+ */
2100
+ function useFeatures() {
2101
+ return useContext("v0:features");
2102
+ }
2103
+ /**
2104
+ * Creates a Vue plugin for feature management with variation support.
2105
+ *
2106
+ * @param options Configuration for initial features to register.
2107
+ * @template Z The type of feature ticket.
2108
+ * @template E The type of feature context.
2109
+ * @returns A Vue plugin object with install method.
2110
+ *
2111
+ * @see https://0.vuetifyjs.com/composables/plugins/create-features
2112
+ */
2113
+ function createFeaturesPlugin(options = {}) {
2114
+ const [, provideFeaturesContext, context] = createFeatures("v0:features", options);
2115
+ return createPlugin({
2116
+ namespace: "v0:features",
2117
+ provide: (app) => {
2118
+ provideFeaturesContext(context, app);
2119
+ }
2120
+ });
2121
+ }
2122
+
2188
2123
  //#endregion
2189
2124
  //#region src/composables/useFilter/index.ts
2190
2125
  function defaultFilter(query, item, keys, mode = "some") {
@@ -2192,8 +2127,7 @@ function defaultFilter(query, item, keys, mode = "some") {
2192
2127
  function match(value, q) {
2193
2128
  return String(value).toLowerCase().includes(q);
2194
2129
  }
2195
- const values = typeof item === "object" && item !== null ? keys?.length ? keys.map((k) => item[k]) : Object.values(item) : [item];
2196
- const stringValues = values.map((v) => String(v).toLowerCase());
2130
+ const stringValues = (typeof item === "object" && item !== null ? keys?.length ? keys.map((k) => item[k]) : Object.values(item) : [item]).map((v) => String(v).toLowerCase());
2197
2131
  if (mode === "some") return stringValues.some((val) => match(val, queries[0]));
2198
2132
  if (mode === "every") return stringValues.every((val) => match(val, queries[0]));
2199
2133
  if (mode === "union") return queries.some((q) => stringValues.some((val) => match(val, q)));
@@ -2219,14 +2153,13 @@ function useFilter(query, items, options = {}) {
2219
2153
  const filterFunction = customFilter ?? ((q, i) => defaultFilter(q, i, keys, mode));
2220
2154
  const itemsRef = isRef(items) ? items : toRef(() => items);
2221
2155
  const queryRef = toRefOrGetter(query);
2222
- const filteredItems = computed(() => {
2156
+ return { items: computed(() => {
2223
2157
  const q = toValue(queryRef);
2224
2158
  const queries = (Array.isArray(q) ? q : [q]).filter((q$1) => String(q$1).trim());
2225
2159
  if (queries.length === 0) return itemsRef.value;
2226
2160
  const queryParam = queries.length === 1 ? queries[0] : queries;
2227
2161
  return itemsRef.value.filter((item) => filterFunction(queryParam, item));
2228
- });
2229
- return { items: filteredItems };
2162
+ }) };
2230
2163
  }
2231
2164
 
2232
2165
  //#endregion
@@ -2261,12 +2194,8 @@ function useForm(options) {
2261
2194
  }
2262
2195
  async function validate(id) {
2263
2196
  const validating = toArray(id);
2264
- if (validatesOn("submit")) {
2265
- const results = await Promise.all(validating.map(async (id$1) => await registry.get(id$1)?.validate() ?? true));
2266
- return results.every(Boolean);
2267
- }
2268
- const tickets = validating.map((id$1) => registry.get(id$1)).filter(Boolean);
2269
- return tickets.every((ticket) => ticket.isValid.value === true);
2197
+ if (validatesOn("submit")) return (await Promise.all(validating.map(async (id$1) => await registry.get(id$1)?.validate() ?? true))).every(Boolean);
2198
+ return validating.map((id$1) => registry.get(id$1)).filter(Boolean).every((ticket) => ticket.isValid.value === true);
2270
2199
  }
2271
2200
  function register(registration) {
2272
2201
  const model = shallowRef(registration.value == null ? "" : toValue(registration.value));
@@ -2290,8 +2219,7 @@ function useForm(options) {
2290
2219
  if (rules.length === 0) return true;
2291
2220
  isValidating$1.value = true;
2292
2221
  try {
2293
- const results = await Promise.all(rules.map((rule) => rule(model.value)));
2294
- const errorMessages = results.filter((result) => typeof result === "string");
2222
+ const errorMessages = (await Promise.all(rules.map((rule) => rule(model.value)))).filter((result) => typeof result === "string");
2295
2223
  if (!silent) {
2296
2224
  errors.value = errorMessages;
2297
2225
  isValid$1.value = errorMessages.length === 0;
@@ -2381,9 +2309,8 @@ function useIntersectionObserver(target, callback, options = {}) {
2381
2309
  });
2382
2310
  observer.value.observe(el);
2383
2311
  if (options.immediate) {
2384
- const rect = el.getBoundingClientRect();
2385
2312
  const syntheticEntry = {
2386
- boundingClientRect: rect,
2313
+ boundingClientRect: el.getBoundingClientRect(),
2387
2314
  intersectionRatio: 0,
2388
2315
  intersectionRect: new DOMRect(0, 0, 0, 0),
2389
2316
  isIntersecting: false,
@@ -2416,9 +2343,8 @@ function useIntersectionObserver(target, callback, options = {}) {
2416
2343
  });
2417
2344
  observer.value.observe(target.value);
2418
2345
  if (options.immediate) {
2419
- const rect = target.value.getBoundingClientRect();
2420
2346
  const syntheticEntry = {
2421
- boundingClientRect: rect,
2347
+ boundingClientRect: target.value.getBoundingClientRect(),
2422
2348
  intersectionRatio: 0,
2423
2349
  intersectionRect: new DOMRect(0, 0, 0, 0),
2424
2350
  isIntersecting: false,
@@ -2515,72 +2441,6 @@ function useKeydown(handlers) {
2515
2441
  };
2516
2442
  }
2517
2443
 
2518
- //#endregion
2519
- //#region src/composables/useLayout/index.ts
2520
- function useLayout(_options = {}) {
2521
- const { enroll = true, events = true,...options } = _options;
2522
- const registry = useGroup({
2523
- enroll,
2524
- events,
2525
- ...options
2526
- });
2527
- const sizes = shallowReactive(/* @__PURE__ */ new Map());
2528
- const height = shallowRef(0);
2529
- const width = shallowRef(0);
2530
- const bounds = {
2531
- top: computed(() => sum("top")),
2532
- bottom: computed(() => sum("bottom")),
2533
- left: computed(() => sum("left")),
2534
- right: computed(() => sum("right"))
2535
- };
2536
- const main = {
2537
- x: computed(() => bounds.left.value),
2538
- y: computed(() => bounds.top.value),
2539
- width: computed(() => width.value - bounds.left.value - bounds.right.value),
2540
- height: computed(() => height.value - bounds.top.value - bounds.bottom.value)
2541
- };
2542
- function sum(position) {
2543
- let total = 0;
2544
- for (const item of registry.values()) if (item.position === position && item.isActive.value) total += sizes.get(item.id) ?? item.value ?? 0;
2545
- return total;
2546
- }
2547
- function register(registration) {
2548
- const item = {
2549
- position: registration.position,
2550
- order: registration.order ?? 0,
2551
- ...registration
2552
- };
2553
- const ticket = registry.register(item);
2554
- sizes.set(ticket.id, ticket.value);
2555
- return ticket;
2556
- }
2557
- if (IN_BROWSER && getCurrentInstance()) {
2558
- function resize() {
2559
- height.value = window.innerHeight;
2560
- width.value = window.innerWidth;
2561
- }
2562
- onMounted(() => {
2563
- resize();
2564
- window.addEventListener("resize", resize);
2565
- });
2566
- onUnmounted(() => {
2567
- window.removeEventListener("resize", resize);
2568
- });
2569
- }
2570
- registry.on("unregister", (item) => {
2571
- sizes.delete(item.id);
2572
- });
2573
- return {
2574
- ...registry,
2575
- register,
2576
- bounds,
2577
- main,
2578
- sizes,
2579
- height,
2580
- width
2581
- };
2582
- }
2583
-
2584
2444
  //#endregion
2585
2445
  //#region src/composables/useLocale/adapters/v0.ts
2586
2446
  /**
@@ -2673,7 +2533,7 @@ function createLocale(namespace = "v0:locale", options = {}) {
2673
2533
  * @returns The locale context containing translation and formatting functions.
2674
2534
  */
2675
2535
  function useLocale() {
2676
- return useContext("v0:locale")();
2536
+ return useContext("v0:locale");
2677
2537
  }
2678
2538
  /**
2679
2539
  * Creates a Vue plugin for internationalization with locale management and translation support.
@@ -2752,7 +2612,7 @@ function useMutationObserver(target, callback, options = {}) {
2752
2612
  forEach: () => {},
2753
2613
  *[Symbol.iterator]() {}
2754
2614
  };
2755
- const syntheticEntry = {
2615
+ callback([{
2756
2616
  type: "childList",
2757
2617
  target: el,
2758
2618
  addedNodes: emptyNodeList,
@@ -2762,8 +2622,7 @@ function useMutationObserver(target, callback, options = {}) {
2762
2622
  attributeName: null,
2763
2623
  attributeNamespace: null,
2764
2624
  oldValue: null
2765
- };
2766
- callback([syntheticEntry]);
2625
+ }]);
2767
2626
  }
2768
2627
  }, { immediate: true });
2769
2628
  function setup() {
@@ -2830,6 +2689,91 @@ function useMutationObserver(target, callback, options = {}) {
2830
2689
  };
2831
2690
  }
2832
2691
 
2692
+ //#endregion
2693
+ //#region src/composables/usePermissions/adapters/adapter.ts
2694
+ var PermissionAdapter = class {};
2695
+
2696
+ //#endregion
2697
+ //#region src/composables/usePermissions/adapters/v0.ts
2698
+ var Vuetify0PermissionAdapter = class extends PermissionAdapter {
2699
+ constructor() {
2700
+ super();
2701
+ }
2702
+ can(role, action, subject, context, permissions) {
2703
+ const access = `${role}.${action}.${subject}`;
2704
+ const ticket = permissions.get(access);
2705
+ if (!ticket || !ticket.value) return false;
2706
+ return isFunction(ticket.value) ? ticket.value(context) : ticket.value;
2707
+ }
2708
+ };
2709
+
2710
+ //#endregion
2711
+ //#region src/composables/usePermissions/index.ts
2712
+ /**
2713
+ *
2714
+ * @param namespace The namespace for the permissions context
2715
+ * @param options Configure initial permissions and adapter
2716
+ * @template Z The type of permission ticket
2717
+ * @template E The type of permission context
2718
+ * @returns A context trinity for the permissions context
2719
+ *
2720
+ * @see https://0.vuetifyjs.com/composables/plugins/create-permissions
2721
+ */
2722
+ function createPermissions(namespace = "v0:permissions", options = {}) {
2723
+ const { adapter = new Vuetify0PermissionAdapter(), permissions = {} } = options;
2724
+ const [usePermissionsContext, _providePermissionsContext] = createContext(namespace);
2725
+ const record = {};
2726
+ for (const role in permissions) {
2727
+ if (!record[role]) record[role] = {};
2728
+ for (const [actions, subjects, condition = true] of permissions[role]) for (const action of toArray(actions)) for (const subject of toArray(subjects)) {
2729
+ if (!record[role][action]) record[role][action] = {};
2730
+ record[role][action][subject] = condition;
2731
+ }
2732
+ }
2733
+ const tokens = useTokens(record);
2734
+ function can(id, action, subject, context$1 = {}) {
2735
+ return adapter.can(id, action, subject, context$1, tokens);
2736
+ }
2737
+ const context = {
2738
+ ...tokens,
2739
+ can
2740
+ };
2741
+ function providePermissionsContext(_context = context, app) {
2742
+ return _providePermissionsContext(_context, app);
2743
+ }
2744
+ return createTrinity(usePermissionsContext, providePermissionsContext, context);
2745
+ }
2746
+ /**
2747
+ * Simple hook to access the permissions context
2748
+ *
2749
+ * @returns The permissions context
2750
+ * @template Z The type of permission ticket
2751
+ *
2752
+ * @see https://0.vuetifyjs.com/composables/plugins/use-permissions
2753
+ */
2754
+ function usePermissions() {
2755
+ return useContext("v0:permissions");
2756
+ }
2757
+ /**
2758
+ * Factory function to create a permissions plugin
2759
+ *
2760
+ * @param options Configuration options for the permissions plugin
2761
+ * @template Z The type of permission ticket
2762
+ * @template E The type of permission context
2763
+ * @returns A Vue plugin object for permissions management
2764
+ *
2765
+ * @see https://0.vuetifyjs.com/composables/plugins/use-permissions
2766
+ */
2767
+ function createPermissionsPlugin(options = {}) {
2768
+ const [, providePermissionContext, context] = createPermissions("v0:permissions", options);
2769
+ return createPlugin({
2770
+ namespace: "v0:permissions",
2771
+ provide: (app) => {
2772
+ providePermissionContext(context, app);
2773
+ }
2774
+ });
2775
+ }
2776
+
2833
2777
  //#endregion
2834
2778
  //#region src/composables/useProxyModel/index.ts
2835
2779
  /**
@@ -2842,8 +2786,7 @@ function useMutationObserver(target, callback, options = {}) {
2842
2786
  */
2843
2787
  function useProxyModel(registry, initial, options, _transformIn, _transformOut) {
2844
2788
  const logger = useLogger();
2845
- const reactivity = options?.deep ? ref : shallowRef;
2846
- const internal = reactivity(initial ? toArray(initial) : []);
2789
+ const internal = (options?.deep ? ref : shallowRef)(initial ? toArray(initial) : []);
2847
2790
  const isModelArray = isArray(initial);
2848
2791
  function transformIn(val) {
2849
2792
  if (isFunction(_transformIn)) return _transformIn(val);
@@ -2873,8 +2816,9 @@ function useProxyModel(registry, initial, options, _transformIn, _transformOut)
2873
2816
  const currentIds = new Set(toValue(registry.selectedIds));
2874
2817
  const targetIds = /* @__PURE__ */ new Set();
2875
2818
  for (const value of toArray(val)) {
2876
- const id = registry.browse(value);
2877
- if (id) targetIds.add(id);
2819
+ const ids = registry.browse(value);
2820
+ if (isArray(ids)) for (const single of ids) targetIds.add(single);
2821
+ else if (ids) targetIds.add(ids);
2878
2822
  else logger.warn("Unable to find id for value", value);
2879
2823
  }
2880
2824
  watcher.pause();
@@ -3012,6 +2956,83 @@ function useElementSize(target) {
3012
2956
  };
3013
2957
  }
3014
2958
 
2959
+ //#endregion
2960
+ //#region src/composables/useStep/index.ts
2961
+ /**
2962
+ * Creates a step selection context for managing collections where users can navigate through items sequentially.
2963
+ * This function extends the single selection functionality with stepping navigation.
2964
+ *
2965
+ * @param options Optional configuration for step behavior.
2966
+ * @template Z The type of items managed by the step selection.
2967
+ * @template E The type of the step selection context.
2968
+ * @returns The step selection context object.
2969
+ */
2970
+ function useStep(options) {
2971
+ const registry = useSingle(options);
2972
+ function first() {
2973
+ if (registry.size === 0) return;
2974
+ registry.selectedIds.clear();
2975
+ registry.select(registry.lookup(0));
2976
+ }
2977
+ function last() {
2978
+ const size = registry.size;
2979
+ if (size === 0) return;
2980
+ registry.selectedIds.clear();
2981
+ registry.select(registry.lookup(size - 1));
2982
+ }
2983
+ function next() {
2984
+ step(1);
2985
+ }
2986
+ function prev() {
2987
+ step(-1);
2988
+ }
2989
+ function wrapped(length, index) {
2990
+ return (index + length) % length;
2991
+ }
2992
+ function step(count = 1) {
2993
+ const length = registry.size;
2994
+ if (!length) return;
2995
+ const direction = Math.sign(count || 1);
2996
+ let hops = 0;
2997
+ let index = wrapped(length, registry.selectedIndex.value + count);
2998
+ let id = registry.lookup(index);
2999
+ while (id !== void 0 && registry.get(id)?.disabled && hops < length) {
3000
+ index = wrapped(length, index + direction);
3001
+ id = registry.lookup(index);
3002
+ hops++;
3003
+ }
3004
+ if (id === void 0 || hops === length) return;
3005
+ registry.selectedIds.clear();
3006
+ registry.select(id);
3007
+ }
3008
+ return {
3009
+ ...registry,
3010
+ first,
3011
+ last,
3012
+ next,
3013
+ prev,
3014
+ step
3015
+ };
3016
+ }
3017
+ /**
3018
+ * Creates a step selection registry context with full injection/provision control.
3019
+ * Returns the complete trinity for advanced usage scenarios.
3020
+ *
3021
+ * @param namespace The namespace for the step selection registry context
3022
+ * @param options Optional configuration for step selection behavior.
3023
+ * @template Z The structure of the registry step selection items.
3024
+ * @template E The available methods for the step's context.
3025
+ * @returns A tuple containing the inject function, provide function, and the step selection context.
3026
+ */
3027
+ function createStepContext(namespace, options) {
3028
+ const [useStepContext, _provideStepContext] = createContext(namespace);
3029
+ const context = useStep(options);
3030
+ function provideStepContext(_context = context, app) {
3031
+ return _provideStepContext(_context, app);
3032
+ }
3033
+ return createTrinity(useStepContext, provideStepContext, context);
3034
+ }
3035
+
3015
3036
  //#endregion
3016
3037
  //#region src/composables/useStorage/adapters/memory.ts
3017
3038
  /**
@@ -3034,7 +3055,7 @@ var MemoryAdapter = class {
3034
3055
  this.store.delete(key);
3035
3056
  }
3036
3057
  key(index) {
3037
- return Array.from(this.store.keys())[index];
3058
+ return String(Array.from(this.store.keys())[index] ?? "");
3038
3059
  }
3039
3060
  };
3040
3061
 
@@ -3120,4 +3141,59 @@ function createStoragePlugin(options = {}) {
3120
3141
  }
3121
3142
 
3122
3143
  //#endregion
3123
- export { Atom_default as Atom, Breakpoints, COMMON_ELEMENTS, ConsolaLoggerAdapter, Context, Group, Hydration_default as Hydration, HydrationRoot_default as HydrationRoot, IN_BROWSER, PinoLoggerAdapter, Popover, SELF_CLOSING_TAGS, SUPPORTS_INTERSECTION_OBSERVER, SUPPORTS_MATCH_MEDIA, SUPPORTS_MUTATION_OBSERVER, SUPPORTS_OBSERVER, SUPPORTS_TOUCH, Step, Theme, Vuetify0LoggerAdapter, __LOGGER_ENABLED__, createBreakpoints, createBreakpointsPlugin, createContext, createHydration, createHydrationPlugin, createLocale, createLocalePlugin, createLogger, createLoggerPlugin, createPlugin, createRegistryContext, createStorage, createStoragePlugin, createTheme, createThemePlugin, createTokensContext, createTrinity, genId, isArray, isBoolean, isFunction, isNullOrUndefined, isNumber, isObject, isPrimitive, isSelfClosingTag, isString, mergeDeep, provideBreakpointsContext, provideHydrationContext, providePopoverContext, provideStorageContext, run, toArray, toReactive, useBreakpoints, useBreakpointsContext, useContext, useDocumentEventListener, useElementIntersection, useElementSize, useEventListener, useFilter, useForm, useGroup, useHydration, useHydrationContext, useIntersectionObserver, useKeydown, useLayout, useLocale, useLogger, useMutationObserver, usePopoverContext, useProxyModel, useRegistry, useResizeObserver, useSelection, useSingle, useStep, useStorage, useStorageContext, useTheme, useTokens, useWindowEventListener, version };
3144
+ //#region src/composables/useTimeline/index.ts
3145
+ /**
3146
+ * Creates a registry with timeline capabilities (undo/redo)
3147
+ *
3148
+ * @param _options Optional configuration for timeline
3149
+ * @template Z The type of ticket to be stored in the timeline
3150
+ * @template E The type of the timeline context
3151
+ * @returns The timeline context object
3152
+ *
3153
+ * @see https://0.vuetifyjs.com/composables/registration/use-timeline
3154
+ */
3155
+ function useTimeline(_options = {}) {
3156
+ const { size = 10,...options } = _options;
3157
+ const registry = useRegistry(options);
3158
+ const undoTimeline = [];
3159
+ const redoTimeline = [];
3160
+ function register(item) {
3161
+ if (registry.size < size) return registry.register({ ...item });
3162
+ const id = registry.lookup(0);
3163
+ const removing = registry.get(id);
3164
+ if (redoTimeline.length === size) redoTimeline.shift();
3165
+ redoTimeline.push(removing);
3166
+ registry.unregister(id);
3167
+ const ticket = registry.register({ ...item });
3168
+ registry.reindex();
3169
+ return ticket;
3170
+ }
3171
+ function redo() {
3172
+ if (undoTimeline.length === 0) return;
3173
+ registry.register(undoTimeline.pop());
3174
+ registry.reindex();
3175
+ }
3176
+ function undo() {
3177
+ const id = registry.lookup(registry.size - 1);
3178
+ if (!id) return;
3179
+ undoTimeline.push(registry.get(id));
3180
+ registry.unregister(id);
3181
+ restore();
3182
+ }
3183
+ function restore() {
3184
+ const value = redoTimeline.pop();
3185
+ const restored = value ? [value, ...registry.values()] : [...registry.values()];
3186
+ registry.clear();
3187
+ registry.onboard(restored);
3188
+ registry.reindex();
3189
+ }
3190
+ return {
3191
+ ...registry,
3192
+ register,
3193
+ undo,
3194
+ redo
3195
+ };
3196
+ }
3197
+
3198
+ //#endregion
3199
+ export { Atom_default as Atom, Breakpoints, COMMON_ELEMENTS, ConsolaLoggerAdapter, Context, Hydration_default as Hydration, HydrationRoot_default as HydrationRoot, IN_BROWSER, PinoLoggerAdapter, Popover, SELF_CLOSING_TAGS, SUPPORTS_INTERSECTION_OBSERVER, SUPPORTS_MATCH_MEDIA, SUPPORTS_MUTATION_OBSERVER, SUPPORTS_OBSERVER, SUPPORTS_TOUCH, Theme, Vuetify0LoggerAdapter, __LOGGER_ENABLED__, createBreakpoints, createBreakpointsPlugin, createContext, createFeatures, createFeaturesPlugin, createGroupContext, createHydration, createHydrationPlugin, createLocale, createLocalePlugin, createLogger, createLoggerPlugin, createPermissions, createPermissionsPlugin, createPlugin, createRegistryContext, createSelectionContext, createSingleContext, createStepContext, createStorage, createStoragePlugin, createTheme, createThemePlugin, createTokensContext, createTrinity, genId, isArray, isBoolean, isFunction, isNullOrUndefined, isNumber, isObject, isPrimitive, isSelfClosingTag, isString, mergeDeep, provideBreakpointsContext, provideContext, provideHydrationContext, providePopoverContext, provideStorageContext, run, toArray, toReactive, useBreakpoints, useBreakpointsContext, useContext, useDocumentEventListener, useElementIntersection, useElementSize, useEventListener, useFeatures, useFilter, useForm, useGroup, useHydration, useHydrationContext, useIntersectionObserver, useKeydown, useLocale, useLogger, useMutationObserver, usePermissions, usePopoverContext, useProxyModel, useRegistry, useResizeObserver, useSelection, useSingle, useStep, useStorage, useStorageContext, useTheme, useTimeline, useTokens, useWindowEventListener, version };