@vuetify/v0 0.1.5 → 0.1.6

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 (86) hide show
  1. package/dist/{adapter-Cmeg49W9.mjs → adapter-Bjs_Nx_J.mjs} +8 -10
  2. package/dist/{adapter-D2JoR-4d.d.mts → adapter-CLs-OrSN.d.mts} +4 -4
  3. package/dist/browser/index.js +1645 -273
  4. package/dist/components/index.d.mts +8 -8
  5. package/dist/components/index.mjs +28 -28
  6. package/dist/{components-BbbGkTcN.mjs → components-GiQh_RfQ.mjs} +1101 -110
  7. package/dist/composables/index.d.mts +7 -7
  8. package/dist/composables/index.mjs +27 -27
  9. package/dist/constants/index.mjs +1 -1
  10. package/dist/{createDataTable-cNf6DdHz.mjs → createDataTable-lSofI5rU.mjs} +5 -5
  11. package/dist/{createGroup-BrZPZudL.mjs → createGroup-CCb7Zfyw.mjs} +6 -5
  12. package/dist/{createPagination-Wc_vRGNQ.mjs → createPagination-lagznd8i.mjs} +2 -2
  13. package/dist/{createSelection-BURpoE3p.mjs → createSelection-Zo4RQpYe.mjs} +217 -61
  14. package/dist/{createSingle-BE1vHaZy.mjs → createSingle-BH9wNDrS.mjs} +2 -2
  15. package/dist/{createTokens-jwf8-iGn.mjs → createTokens-Cu1efg9Z.mjs} +21 -3
  16. package/dist/{createTrinity-DkwPrPRS.mjs → createTrinity-Cii8-B2r.mjs} +1 -1
  17. package/dist/data-table/adapters/client/index.d.mts +2 -2
  18. package/dist/data-table/adapters/client/index.mjs +7 -7
  19. package/dist/data-table/adapters/index.d.mts +4 -4
  20. package/dist/data-table/adapters/index.mjs +9 -9
  21. package/dist/data-table/adapters/server/index.d.mts +2 -2
  22. package/dist/data-table/adapters/server/index.mjs +5 -5
  23. package/dist/data-table/adapters/virtual/index.d.mts +2 -2
  24. package/dist/data-table/adapters/virtual/index.mjs +7 -7
  25. package/dist/data-table/index.d.mts +5 -5
  26. package/dist/data-table/index.mjs +19 -19
  27. package/dist/date/index.mjs +2 -2
  28. package/dist/features/adapters/posthog/index.mjs +2 -2
  29. package/dist/features/index.d.mts +6 -6
  30. package/dist/features/index.mjs +12 -12
  31. package/dist/{globals-vN-O052q.mjs → globals-D6FBsWDI.mjs} +1 -1
  32. package/dist/{index-DdWxDPX3.d.mts → index-DIK84tM4.d.mts} +1 -1
  33. package/dist/{index-BTMzRHep.d.mts → index-De0SQt1w.d.mts} +801 -50
  34. package/dist/{index-DRax9EgT.d.mts → index-DlUIZN-F.d.mts} +1125 -373
  35. package/dist/index.d.mts +8 -8
  36. package/dist/index.mjs +28 -28
  37. package/dist/json/attributes.json +196 -12
  38. package/dist/json/importMap.json +40 -0
  39. package/dist/json/tags.json +86 -0
  40. package/dist/json/web-types.json +605 -13
  41. package/dist/locale/adapters/index.mjs +3 -3
  42. package/dist/locale/adapters/v0/index.mjs +3 -3
  43. package/dist/locale/index.d.mts +6 -6
  44. package/dist/locale/index.mjs +12 -12
  45. package/dist/logger/adapters/index.mjs +4 -4
  46. package/dist/logger/adapters/pino/index.mjs +3 -3
  47. package/dist/logger/adapters/v0/index.mjs +3 -3
  48. package/dist/logger/index.d.mts +6 -6
  49. package/dist/logger/index.mjs +6 -6
  50. package/dist/permissions/adapters/index.d.mts +7 -7
  51. package/dist/permissions/adapters/index.mjs +3 -3
  52. package/dist/permissions/adapters/v0/index.d.mts +7 -7
  53. package/dist/permissions/adapters/v0/index.mjs +3 -3
  54. package/dist/permissions/index.d.mts +6 -6
  55. package/dist/permissions/index.mjs +10 -10
  56. package/dist/{pino-DFxkZLiu.mjs → pino-BD5PCzAF.mjs} +1 -1
  57. package/dist/{posthog-BOUoZTTf.mjs → posthog-BxaG8sYi.mjs} +1 -1
  58. package/dist/{server-B-HWxaTQ.d.mts → server-CGAeOGPC.d.mts} +1 -1
  59. package/dist/{server-C2R2POGE.mjs → server-DgOdFYMU.mjs} +1 -1
  60. package/dist/storage/index.d.mts +6 -6
  61. package/dist/storage/index.mjs +26 -26
  62. package/dist/theme/adapters/index.d.mts +6 -6
  63. package/dist/theme/adapters/index.mjs +3 -3
  64. package/dist/theme/adapters/v0/index.d.mts +6 -6
  65. package/dist/theme/adapters/v0/index.mjs +3 -3
  66. package/dist/theme/index.d.mts +6 -6
  67. package/dist/theme/index.mjs +11 -11
  68. package/dist/{toArray-VIn8vYt3.mjs → toArray-BBZH-G2X.mjs} +1 -1
  69. package/dist/{useClickOutside-DIi0kjN5.mjs → useClickOutside-Bm_3mbcT.mjs} +306 -98
  70. package/dist/{useFeatures-6O7EPJUS.mjs → useFeatures-BS4mit8z.mjs} +4 -4
  71. package/dist/{useLocale-DHjbekzS.mjs → useLocale-DJJmg-wv.mjs} +6 -6
  72. package/dist/{useLogger-BXqiUvt2.mjs → useLogger-C8G5jgNk.mjs} +4 -4
  73. package/dist/{usePermissions-DFacFVqO.mjs → usePermissions-C5Mkotol.mjs} +4 -4
  74. package/dist/{useTheme-D0_1mjTw.mjs → useTheme-BBnASLr3.mjs} +4 -4
  75. package/dist/utilities/index.mjs +2 -2
  76. package/dist/{utilities-Dx8wzGa5.mjs → utilities-CcJtp9Gx.mjs} +1 -1
  77. package/dist/{v0-CfSj99gF.mjs → v0-BWBSVkew.mjs} +2 -2
  78. package/dist/{v0-BNXo1ecc.d.mts → v0-Bh8d1j_p.d.mts} +1 -1
  79. package/dist/{v0-BPzPP8C5.d.mts → v0-CVr15VcY.d.mts} +1 -1
  80. package/dist/{v0-Dc5mcpQs.mjs → v0-CWUF_HqP.mjs} +2 -2
  81. package/dist/{v0-BYqmw3qM.mjs → v0-DtO_ICXr.mjs} +1 -1
  82. package/dist/{v0-Dwufx8ae.mjs → v0-DzvhDU1W.mjs} +2 -2
  83. package/dist/{v0-C8DBv9mh.mjs → v0-lua6ffdk.mjs} +2 -2
  84. package/dist/{virtual-BoTGK6HT.mjs → virtual-BEOqkQvm.mjs} +2 -2
  85. package/dist/{virtual-A4e1yrdn.d.mts → virtual-CVb9hRUU.d.mts} +1 -1
  86. package/package.json +1 -1
@@ -1,15 +1,15 @@
1
- import { a as SUPPORTS_OBSERVER, i as SUPPORTS_MUTATION_OBSERVER, n as SUPPORTS_INTERSECTION_OBSERVER, r as SUPPORTS_MATCH_MEDIA, t as IN_BROWSER } from "./globals-vN-O052q.mjs";
2
- import { a as isElement, c as isNull, g as mergeDeep, h as isUndefined, l as isNullOrUndefined, o as isFunction, p as isString, t as clamp, u as isNumber, v as useId$1, y as instanceExists } from "./utilities-Dx8wzGa5.mjs";
3
- import { i as useContext, n as createContext, t as createTrinity } from "./createTrinity-DkwPrPRS.mjs";
4
- import { a as createPlugin, i as useLogger, o as createPluginContext } from "./useLogger-BXqiUvt2.mjs";
5
- import { i as createRegistry } from "./createTokens-jwf8-iGn.mjs";
6
- import { t as createSelection } from "./createSelection-BURpoE3p.mjs";
7
- import { t as createSingle } from "./createSingle-BE1vHaZy.mjs";
8
- import { t as createGroup } from "./createGroup-BrZPZudL.mjs";
9
- import { t as toArray } from "./toArray-VIn8vYt3.mjs";
10
- import { a as useLocale } from "./useLocale-DHjbekzS.mjs";
1
+ import { a as SUPPORTS_OBSERVER, i as SUPPORTS_MUTATION_OBSERVER, n as SUPPORTS_INTERSECTION_OBSERVER, r as SUPPORTS_MATCH_MEDIA, t as IN_BROWSER } from "./globals-D6FBsWDI.mjs";
2
+ import { a as isElement, c as isNull, d as isObject, g as mergeDeep, h as isUndefined, l as isNullOrUndefined, o as isFunction, p as isString, t as clamp, u as isNumber, v as useId$1, y as instanceExists } from "./utilities-CcJtp9Gx.mjs";
3
+ import { i as useContext, n as createContext, t as createTrinity } from "./createTrinity-Cii8-B2r.mjs";
4
+ import { a as createPlugin, i as useLogger, o as createPluginContext } from "./useLogger-C8G5jgNk.mjs";
5
+ import { i as createRegistry } from "./createTokens-Cu1efg9Z.mjs";
6
+ import { i as createModel, t as createSelection } from "./createSelection-Zo4RQpYe.mjs";
7
+ import { t as createSingle } from "./createSingle-BH9wNDrS.mjs";
8
+ import { t as createGroup } from "./createGroup-CCb7Zfyw.mjs";
9
+ import { t as toArray } from "./toArray-BBZH-G2X.mjs";
10
+ import { a as useLocale } from "./useLocale-DJJmg-wv.mjs";
11
11
  import { t as MemoryAdapter } from "./memory-BsZGbGnG.mjs";
12
- import { computed, effectScope, isRef, nextTick, onScopeDispose, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toValue, unref, watch, watchEffect } from "vue";
12
+ import { computed, effectScope, isRef, nextTick, onScopeDispose, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, toRef, toValue, unref, watch, watchEffect } from "vue";
13
13
 
14
14
  //#region src/composables/createBreadcrumbs/index.ts
15
15
  /**
@@ -703,23 +703,22 @@ function useOverflow(namespace = "v0:overflow") {
703
703
  * @module useProxyModel
704
704
  *
705
705
  * @remarks
706
- * Proxy composable for bidirectional sync between selection registry and v-model.
706
+ * Proxy composable for bidirectional sync between a model context and v-model.
707
707
  *
708
708
  * Key features:
709
709
  * - Bidirectional synchronization
710
710
  * - Array and single-value modes
711
711
  * - Automatic cleanup on scope disposal
712
- * - Perfect for form controls with selection backing
712
+ * - Works with any ModelContext (Selection, Slider, etc.)
713
713
  *
714
- * Bridges the gap between selection composables and Vue's v-model.
714
+ * Bridges the gap between model composables and Vue's v-model.
715
715
  */
716
716
  /**
717
- * Syncs a ref with a selection registry bidirectionally.
717
+ * Syncs a ref with a model context bidirectionally.
718
718
  *
719
- * @param registry The selection registry to bind to.
719
+ * @param context The model context to bind to.
720
720
  * @param model The ref to sync.
721
721
  * @param options The options for the proxy model.
722
- * @template Z The type of the selection ticket.
723
722
  * @returns A function to stop the sync.
724
723
  *
725
724
  * @see https://0.vuetifyjs.com/composables/forms/use-proxy-model
@@ -738,8 +737,8 @@ function useOverflow(namespace = "v0:overflow") {
738
737
  * const stop = useProxyModel(registry, model)
739
738
  * ```
740
739
  */
741
- function useProxyModel(registry, model, options) {
742
- const multiple = options?.multiple ?? false;
740
+ function useProxyModel(context, model, options) {
741
+ const multiple = options?.multiple ?? context.multiple ?? false;
743
742
  const _transformIn = options?.transformIn;
744
743
  const _transformOut = options?.transformOut;
745
744
  function transformIn(val) {
@@ -750,39 +749,20 @@ function useProxyModel(registry, model, options) {
750
749
  if (/* @__PURE__ */ isFunction(_transformOut)) return _transformOut(val);
751
750
  return toValue(multiple) ? val : val[0];
752
751
  }
752
+ const applyOptions = toValue(multiple) === toValue(context.multiple ?? false) ? void 0 : { multiple: toValue(multiple) };
753
753
  const modelAsArray = transformIn(model);
754
754
  const pending = new Set(modelAsArray);
755
- for (const value of modelAsArray) {
756
- const ids = registry.browse(value);
757
- /* v8 ignore start -- edge case: value exists in registry at init */
758
- if (ids) {
759
- for (const id of ids) registry.select(id);
760
- pending.delete(value);
761
- }
762
- }
763
- const registryWatch = watch(registry.selectedValues, (val) => {
755
+ context.apply(modelAsArray, applyOptions);
756
+ for (const value of modelAsArray) if (Array.from(context.selectedValues.value).includes(value)) pending.delete(value);
757
+ const contextWatch = watch(context.selectedValues, (val) => {
764
758
  modelWatch.pause();
765
759
  model.value = transformOut(Array.from(toValue(val)));
766
760
  modelWatch.resume();
767
761
  }, { flush: "sync" });
768
762
  const modelWatch = watch(model, (val) => {
769
- registryWatch.pause();
770
- const currentIds = new Set(toValue(registry.selectedIds));
771
- const targetIds = /* @__PURE__ */ new Set();
772
- for (const value of transformIn(val)) {
773
- const ids = registry.browse(toRaw(value));
774
- if (ids) for (const id of ids) targetIds.add(id);
775
- }
776
- if (toValue(multiple)) {
777
- for (const id of currentIds.difference(targetIds)) registry.selectedIds.delete(id);
778
- for (const id of targetIds.difference(currentIds)) registry.selectedIds.add(id);
779
- } else {
780
- const next = targetIds.values().next().value;
781
- const last = currentIds.values().next().value;
782
- if (!/* @__PURE__ */ isUndefined(last)) registry.unselect(last);
783
- if (!/* @__PURE__ */ isUndefined(next)) registry.select(next);
784
- }
785
- registryWatch.resume();
763
+ contextWatch.pause();
764
+ context.apply(transformIn(val), applyOptions);
765
+ contextWatch.resume();
786
766
  }, {
787
767
  flush: "sync",
788
768
  deep: toValue(multiple)
@@ -790,18 +770,18 @@ function useProxyModel(registry, model, options) {
790
770
  function onRegister(data) {
791
771
  const ticket = data;
792
772
  if (!pending.has(ticket.value) || toValue(ticket.disabled)) return;
793
- registryWatch.pause();
773
+ contextWatch.pause();
794
774
  modelWatch.pause();
795
- registry.select(ticket.id);
775
+ context.select?.(ticket.id);
796
776
  pending.delete(ticket.value);
797
777
  modelWatch.resume();
798
- registryWatch.resume();
778
+ contextWatch.resume();
799
779
  }
800
- registry.on("register:ticket", onRegister);
780
+ context.on?.("register:ticket", onRegister);
801
781
  function stop() {
802
- registryWatch();
782
+ contextWatch();
803
783
  modelWatch();
804
- registry.off("register:ticket", onRegister);
784
+ context.off?.("register:ticket", onRegister);
805
785
  }
806
786
  onScopeDispose(stop, true);
807
787
  return stop;
@@ -1008,30 +988,42 @@ function createDefaultBreakpoints() {
1008
988
  * ```
1009
989
  */
1010
990
  function createBreakpoints(_options = {}) {
1011
- const { mobileBreakpoint, breakpoints } = /* @__PURE__ */ mergeDeep(createDefaultBreakpoints(), _options);
991
+ const { ssr, ...options } = _options;
992
+ const { mobileBreakpoint, breakpoints } = /* @__PURE__ */ mergeDeep(createDefaultBreakpoints(), options);
1012
993
  const sorted = Object.entries(breakpoints).toSorted((a, b) => a[1] - b[1]);
1013
994
  const names = sorted.map(([n]) => n);
1014
995
  const mb = /* @__PURE__ */ isNumber(mobileBreakpoint) ? mobileBreakpoint : breakpoints[mobileBreakpoint] ?? breakpoints.md;
1015
- const name = shallowRef("xs");
1016
- const width = shallowRef(0);
1017
- const height = shallowRef(0);
1018
- const isMobile = shallowRef(true);
1019
- const xs = shallowRef(true);
1020
- const sm = shallowRef(false);
1021
- const md = shallowRef(false);
1022
- const lg = shallowRef(false);
1023
- const xl = shallowRef(false);
1024
- const xxl = shallowRef(false);
1025
- const smAndUp = shallowRef(false);
1026
- const mdAndUp = shallowRef(false);
1027
- const lgAndUp = shallowRef(false);
1028
- const xlAndUp = shallowRef(false);
1029
- const xxlAndUp = shallowRef(false);
1030
- const smAndDown = shallowRef(true);
1031
- const mdAndDown = shallowRef(true);
1032
- const lgAndDown = shallowRef(true);
1033
- const xlAndDown = shallowRef(true);
1034
- const xxlAndDown = shallowRef(true);
996
+ const isSSR = !IN_BROWSER && !!ssr;
997
+ const initialWidth = isSSR ? ssr.clientWidth : 0;
998
+ const initialHeight = isSSR ? ssr.clientHeight ?? 0 : 0;
999
+ let initialName = "xs";
1000
+ if (isSSR) {
1001
+ for (let i = sorted.length - 1; i >= 0; i--) if (initialWidth >= sorted[i][1]) {
1002
+ initialName = sorted[i][0];
1003
+ break;
1004
+ }
1005
+ }
1006
+ const initialIndex = names.indexOf(initialName);
1007
+ const name = shallowRef(initialName);
1008
+ const width = shallowRef(initialWidth);
1009
+ const height = shallowRef(initialHeight);
1010
+ const isMobile = shallowRef(isSSR ? initialWidth < mb : true);
1011
+ const xs = shallowRef(initialIndex === 0);
1012
+ const sm = shallowRef(initialIndex === 1);
1013
+ const md = shallowRef(initialIndex === 2);
1014
+ const lg = shallowRef(initialIndex === 3);
1015
+ const xl = shallowRef(initialIndex === 4);
1016
+ const xxl = shallowRef(initialIndex === 5);
1017
+ const smAndUp = shallowRef(initialIndex >= 1);
1018
+ const mdAndUp = shallowRef(initialIndex >= 2);
1019
+ const lgAndUp = shallowRef(initialIndex >= 3);
1020
+ const xlAndUp = shallowRef(initialIndex >= 4);
1021
+ const xxlAndUp = shallowRef(initialIndex >= 5);
1022
+ const smAndDown = shallowRef(initialIndex <= 1);
1023
+ const mdAndDown = shallowRef(initialIndex <= 2);
1024
+ const lgAndDown = shallowRef(initialIndex <= 3);
1025
+ const xlAndDown = shallowRef(initialIndex <= 4);
1026
+ const xxlAndDown = shallowRef(initialIndex <= 5);
1035
1027
  function update() {
1036
1028
  if (!IN_BROWSER) return;
1037
1029
  width.value = window.innerWidth;
@@ -1083,10 +1075,12 @@ function createBreakpoints(_options = {}) {
1083
1075
  lgAndDown: readonly(lgAndDown),
1084
1076
  xlAndDown: readonly(xlAndDown),
1085
1077
  xxlAndDown: readonly(xxlAndDown),
1078
+ ssr: isSSR,
1086
1079
  update
1087
1080
  };
1088
1081
  }
1089
- function createBreakpointsFallback() {
1082
+ function createBreakpointsFallback(options = {}) {
1083
+ if (options.ssr) return createBreakpoints(options);
1090
1084
  return {
1091
1085
  breakpoints: createDefaultBreakpoints().breakpoints,
1092
1086
  name: readonly(shallowRef("xs")),
@@ -1109,12 +1103,14 @@ function createBreakpointsFallback() {
1109
1103
  lgAndDown: readonly(shallowRef(false)),
1110
1104
  xlAndDown: readonly(shallowRef(false)),
1111
1105
  xxlAndDown: readonly(shallowRef(false)),
1106
+ ssr: false,
1112
1107
  update: () => {}
1113
1108
  };
1114
1109
  }
1115
1110
  const [createBreakpointsContext, createBreakpointsPlugin, useBreakpoints] = createPluginContext("v0:breakpoints", (options) => createBreakpoints(options), {
1116
1111
  fallback: () => createBreakpointsFallback(),
1117
1112
  setup: (context, app, _options) => {
1113
+ if (IN_BROWSER) context.update();
1118
1114
  app.mixin({ mounted() {
1119
1115
  if (!/* @__PURE__ */ isNull(this.$parent)) return;
1120
1116
  const hydration = useHydration();
@@ -1591,6 +1587,9 @@ const keyAliasMap = {
1591
1587
  space: " ",
1592
1588
  return: "enter",
1593
1589
  del: "delete",
1590
+ plus: "+",
1591
+ slash: "/",
1592
+ underscore: "_",
1594
1593
  minus: "-",
1595
1594
  hyphen: "-"
1596
1595
  };
@@ -1636,7 +1635,7 @@ function splitKeyCombination(combination, isInternal = false) {
1636
1635
  "++",
1637
1636
  "//",
1638
1637
  "__"
1639
- ].some((v) => combination.startsWith(v)) || combination.includes("++") || combination.includes("__") || combination === "+" || combination === "_" || combination.length > 1 && (combination.endsWith("+") || combination.endsWith("_")) && combination.at(-2) !== combination.at(-1) || combination === "++" || combination === "--" || combination === "__") {
1638
+ ].some((v) => combination.startsWith(v)) || combination.includes("++") || combination.includes("//") || combination.includes("__") || combination === "+" || combination === "/" || combination === "_" || combination.length > 1 && (combination.endsWith("+") || combination.endsWith("/") || combination.endsWith("_")) && combination.at(-2) !== combination.at(-1) || combination === "++" || combination === "--" || combination === "__") {
1640
1639
  if (!isInternal) logger.warn(`Invalid hotkey combination: "${combination}" has invalid structure`);
1641
1640
  return emptyResult;
1642
1641
  }
@@ -1702,7 +1701,11 @@ function splitKeySequence(str) {
1702
1701
  logger.warn("Invalid hotkey sequence: empty string provided");
1703
1702
  return [];
1704
1703
  }
1705
- const hasInvalidStart = str.startsWith("-") && !["---", "--+"].includes(str);
1704
+ const hasInvalidStart = str.startsWith("-") && ![
1705
+ "-",
1706
+ "---",
1707
+ "--+"
1708
+ ].includes(str);
1706
1709
  const hasInvalidEnd = str.endsWith("-") && !str.endsWith("+-") && !str.endsWith("_-") && str !== "-" && str !== "---";
1707
1710
  if (hasInvalidStart || hasInvalidEnd) {
1708
1711
  logger.warn(`Invalid hotkey sequence: "${str}" contains invalid combinations`);
@@ -2928,10 +2931,15 @@ function createNested(_options = {}) {
2928
2931
  openedIds.clear();
2929
2932
  activeIds.clear();
2930
2933
  rootIds.clear();
2931
- group.reset();
2934
+ group.clear();
2932
2935
  }
2933
2936
  function reset() {
2934
- clear();
2937
+ children.clear();
2938
+ parents.clear();
2939
+ openedIds.clear();
2940
+ activeIds.clear();
2941
+ rootIds.clear();
2942
+ group.reset();
2935
2943
  }
2936
2944
  const context = {
2937
2945
  ...group,
@@ -3216,6 +3224,191 @@ function useQueue(namespace = "v0:queue") {
3216
3224
  return useContext(namespace);
3217
3225
  }
3218
3226
 
3227
+ //#endregion
3228
+ //#region src/composables/createSlider/index.ts
3229
+ /**
3230
+ * @module createSlider
3231
+ *
3232
+ * @see https://0.vuetifyjs.com/composables/forms/create-slider
3233
+ *
3234
+ * @remarks
3235
+ * Composable for managing slider state: value math, step snapping,
3236
+ * percentage conversion, and multi-thumb value operations.
3237
+ *
3238
+ * Extends createModel for useProxyModel compatibility:
3239
+ * - createRegistry → createModel → createSlider (ticket-per-thumb)
3240
+ *
3241
+ * Each thumb is a model ticket with a `shallowRef<number>` value.
3242
+ * Values are derived from ordered tickets, not a standalone ref.
3243
+ *
3244
+ * Designed for single-thumb, range, and multi-thumb sliders.
3245
+ * Also reusable for color picker tracks, media scrubbers,
3246
+ * gradient editors, and other 1D value-on-track controls.
3247
+ */
3248
+ /**
3249
+ * Creates slider state with value math, step snapping, and multi-thumb support.
3250
+ *
3251
+ * Extends createModel for useProxyModel compatibility. Each thumb is a model
3252
+ * ticket with a shallowRef<number> value. Values are derived from the ordered
3253
+ * tickets, enabling proper registration/unregistration lifecycle.
3254
+ *
3255
+ * @param options Slider configuration.
3256
+ * @returns Slider context with values, math functions, and thumb operations.
3257
+ *
3258
+ * @see https://0.vuetifyjs.com/composables/forms/create-slider
3259
+ * @see {@link createModel} for the base model composable.
3260
+ *
3261
+ * @example Single thumb
3262
+ * ```ts
3263
+ * import { createSlider } from '@vuetify/v0'
3264
+ *
3265
+ * const slider = createSlider({ min: 0, max: 100, step: 5 })
3266
+ * const ticket = slider.register({ value: 50 })
3267
+ * slider.up(0) // values: [55]
3268
+ * slider.fromValue(50) // 50
3269
+ * ```
3270
+ *
3271
+ * @example Range slider
3272
+ * ```ts
3273
+ * import { createSlider } from '@vuetify/v0'
3274
+ *
3275
+ * const slider = createSlider({ min: 0, max: 100, step: 1, range: true })
3276
+ * slider.register({ value: 25 })
3277
+ * slider.register({ value: 75 })
3278
+ * slider.set(0, 30) // values: [30, 75]
3279
+ * slider.set(1, 60) // values: [30, 60]
3280
+ * ```
3281
+ *
3282
+ * @example Custom pointer interaction (media scrubber)
3283
+ * ```ts
3284
+ * import { createSlider } from '@vuetify/v0'
3285
+ *
3286
+ * const slider = createSlider({ min: 0, max: 217, step: 0.1 })
3287
+ * slider.register({ value: 0 })
3288
+ *
3289
+ * // pointer → fromPercent → set → fromValue → UI
3290
+ * const percent = (clientX - rect.left) / rect.width * 100
3291
+ * slider.set(0, slider.fromPercent(percent))
3292
+ * const position = slider.fromValue(slider.values.value[0])
3293
+ * ```
3294
+ */
3295
+ function createSlider(options = {}) {
3296
+ const { min = 0, max = 100, step = 1, disabled: disabledProp = false, readonly: readonlyProp = false, orientation: orientationProp = "horizontal", inverted: invertedProp = false, minStepsBetweenThumbs = 0, crossover = false, range = false } = options;
3297
+ const model = createModel({
3298
+ disabled: disabledProp,
3299
+ multiple: true,
3300
+ events: true
3301
+ });
3302
+ const disabled = toRef(() => toValue(disabledProp));
3303
+ const readonly$1 = toRef(() => toValue(readonlyProp));
3304
+ const orientation = toRef(() => toValue(orientationProp));
3305
+ const inverted = toRef(() => toValue(invertedProp));
3306
+ const extent = max - min;
3307
+ let pending = null;
3308
+ const thumbs = computed(() => Array.from(model.selectedItems.value).toSorted((a, b) => a.index - b.index));
3309
+ const values = computed(() => thumbs.value.map((t) => toValue(t.value)));
3310
+ const selectedValues = computed(() => values.value);
3311
+ function snap(value) {
3312
+ if (step <= 0) return /* @__PURE__ */ clamp(value, min, max);
3313
+ const clamped = /* @__PURE__ */ clamp(value, min, max);
3314
+ return /* @__PURE__ */ clamp(min + Math.round((clamped - min) / step) * step, min, max);
3315
+ }
3316
+ function fromValue(value) {
3317
+ if (extent === 0) return 0;
3318
+ const p = (value - min) / extent * 100;
3319
+ return inverted.value ? 100 - p : p;
3320
+ }
3321
+ function fromPercent(p) {
3322
+ return snap(min + (inverted.value ? 100 - p : p) / 100 * extent);
3323
+ }
3324
+ function register(input) {
3325
+ const initialValue = /* @__PURE__ */ isObject(input) ? input.value : input;
3326
+ const thumbIndex = thumbs.value.length;
3327
+ const pendingValue = pending?.[thumbIndex];
3328
+ const val = /* @__PURE__ */ isUndefined(pendingValue) ? snap(initialValue ?? min) : snap(pendingValue);
3329
+ const ticket = model.register({ value: shallowRef(val) });
3330
+ if (!model.selectedIds.has(ticket.id)) model.selectedIds.add(ticket.id);
3331
+ if (pending && thumbs.value.length >= pending.length) pending = null;
3332
+ return ticket;
3333
+ }
3334
+ function apply(incoming, _options) {
3335
+ const snapped = incoming.map((v) => snap(Number(v)));
3336
+ if (thumbs.value.length === 0) {
3337
+ pending = snapped;
3338
+ return;
3339
+ }
3340
+ for (let index = 0; index < snapped.length; index++) {
3341
+ const ticket = thumbs.value[index];
3342
+ if (!ticket || !isRef(ticket.value)) continue;
3343
+ let constrained = snapped[index];
3344
+ if (!crossover) {
3345
+ const gap = minStepsBetweenThumbs * step;
3346
+ const prev = index > 0 ? snapped[index - 1] : void 0;
3347
+ const following = index < snapped.length - 1 ? snapped[index + 1] : void 0;
3348
+ if (!/* @__PURE__ */ isUndefined(prev)) constrained = Math.max(constrained, prev + gap);
3349
+ if (!/* @__PURE__ */ isUndefined(following)) constrained = Math.min(constrained, following - gap);
3350
+ }
3351
+ ticket.value.value = /* @__PURE__ */ clamp(constrained, min, max);
3352
+ }
3353
+ }
3354
+ function set(index, value) {
3355
+ if (readonly$1.value) return;
3356
+ const snapped = snap(value);
3357
+ const current = values.value;
3358
+ let constrained = snapped;
3359
+ if (!crossover) {
3360
+ const gap = minStepsBetweenThumbs * step;
3361
+ const prev = current[index - 1];
3362
+ const following = current[index + 1];
3363
+ if (index > 0 && !/* @__PURE__ */ isUndefined(prev)) constrained = Math.max(constrained, prev + gap);
3364
+ if (index < current.length - 1 && !/* @__PURE__ */ isUndefined(following)) constrained = Math.min(constrained, following - gap);
3365
+ }
3366
+ constrained = /* @__PURE__ */ clamp(constrained, min, max);
3367
+ const ticket = thumbs.value[index];
3368
+ if (ticket && isRef(ticket.value)) ticket.value.value = constrained;
3369
+ }
3370
+ function up(index, multiplier = 1) {
3371
+ set(index, (values.value[index] ?? min) + step * multiplier);
3372
+ }
3373
+ function down(index, multiplier = 1) {
3374
+ set(index, (values.value[index] ?? min) - step * multiplier);
3375
+ }
3376
+ function floor(index) {
3377
+ set(index, min);
3378
+ }
3379
+ function ceil(index) {
3380
+ set(index, max);
3381
+ }
3382
+ return {
3383
+ ...model,
3384
+ values,
3385
+ selectedValues,
3386
+ apply,
3387
+ range,
3388
+ min,
3389
+ max,
3390
+ step,
3391
+ minStepsBetweenThumbs,
3392
+ crossover,
3393
+ disabled,
3394
+ readonly: readonly$1,
3395
+ orientation,
3396
+ inverted,
3397
+ register,
3398
+ snap,
3399
+ fromValue,
3400
+ fromPercent,
3401
+ set,
3402
+ up,
3403
+ down,
3404
+ floor,
3405
+ ceil,
3406
+ get size() {
3407
+ return model.size;
3408
+ }
3409
+ };
3410
+ }
3411
+
3219
3412
  //#endregion
3220
3413
  //#region src/composables/useStack/index.ts
3221
3414
  /**
@@ -3689,31 +3882,50 @@ function createStorage(options = {}) {
3689
3882
  const { adapter = IN_BROWSER ? window.localStorage : new MemoryAdapter(), prefix = "v0:", serializer = {
3690
3883
  read: JSON.parse,
3691
3884
  write: JSON.stringify
3692
- } } = options;
3885
+ }, ttl } = options;
3693
3886
  const cache = /* @__PURE__ */ new Map();
3694
3887
  const watchers = /* @__PURE__ */ new Map();
3695
3888
  function has(key) {
3696
3889
  const prefixedKey = `${prefix}${key}`;
3697
3890
  return cache.has(prefixedKey);
3698
3891
  }
3699
- function get(key, defaultValue) {
3700
- const prefixedKey = `${prefix}${key}`;
3701
- if (cache.has(prefixedKey)) return cache.get(prefixedKey);
3702
- const storedValue = adapter?.getItem(prefixedKey);
3703
- let initialValue = defaultValue;
3704
- if (storedValue) try {
3705
- initialValue = serializer.read(storedValue);
3892
+ function readStored(prefixedKey) {
3893
+ const raw = adapter?.getItem(prefixedKey);
3894
+ if (!raw) return void 0;
3895
+ try {
3896
+ const parsed = serializer.read(raw);
3897
+ if (ttl && parsed && typeof parsed === "object" && "__ttl" in parsed && "__v" in parsed) {
3898
+ if (Date.now() - parsed.__t > ttl) {
3899
+ adapter?.removeItem(prefixedKey);
3900
+ return;
3901
+ }
3902
+ return parsed.__v;
3903
+ }
3904
+ return parsed;
3706
3905
  } catch (error) {
3707
3906
  console.error(`[v0:storage] Failed to parse stored value for key "${prefixedKey}":`, error);
3907
+ return;
3708
3908
  }
3709
- const valueRef = ref(initialValue);
3909
+ }
3910
+ function writeStored(prefixedKey, value) {
3911
+ const wrapped = ttl ? {
3912
+ __ttl: 1,
3913
+ __v: value,
3914
+ __t: Date.now()
3915
+ } : value;
3916
+ try {
3917
+ adapter?.setItem(prefixedKey, serializer.write(wrapped));
3918
+ } catch (error) {
3919
+ console.error(`[v0:storage] Failed to write key "${prefixedKey}":`, error);
3920
+ }
3921
+ }
3922
+ function get(key, defaultValue) {
3923
+ const prefixedKey = `${prefix}${key}`;
3924
+ if (cache.has(prefixedKey)) return cache.get(prefixedKey);
3925
+ const valueRef = ref(readStored(prefixedKey) ?? defaultValue);
3710
3926
  const stop = watch(valueRef, (newValue) => {
3711
3927
  if (/* @__PURE__ */ isNullOrUndefined(newValue)) adapter?.removeItem(prefixedKey);
3712
- else try {
3713
- adapter?.setItem(prefixedKey, serializer.write(newValue));
3714
- } catch (error) {
3715
- console.error(`[v0:storage] Failed to write key "${prefixedKey}":`, error);
3716
- }
3928
+ else writeStored(prefixedKey, newValue);
3717
3929
  }, { deep: true });
3718
3930
  watchers.set(prefixedKey, stop);
3719
3931
  cache.set(prefixedKey, valueRef);
@@ -3747,14 +3959,10 @@ function createStorage(options = {}) {
3747
3959
  const valueRef = cache.get(e.key);
3748
3960
  if (!valueRef) return;
3749
3961
  watchers.get(e.key)?.();
3750
- valueRef.value = e.newValue == null ? void 0 : serializer.read(e.newValue);
3962
+ valueRef.value = e.newValue == null ? void 0 : readStored(e.key);
3751
3963
  const stop = watch(valueRef, (newValue) => {
3752
3964
  if (/* @__PURE__ */ isNullOrUndefined(newValue)) adapter?.removeItem(e.key);
3753
- else try {
3754
- adapter?.setItem(e.key, serializer.write(newValue));
3755
- } catch (error) {
3756
- console.error(`[v0:storage] Failed to write key "${e.key}":`, error);
3757
- }
3965
+ else writeStored(e.key, newValue);
3758
3966
  }, { deep: true });
3759
3967
  watchers.set(e.key, stop);
3760
3968
  });
@@ -4713,4 +4921,4 @@ function useClickOutside(target, handler, options = {}) {
4713
4921
  }
4714
4922
 
4715
4923
  //#endregion
4716
- export { createOverflow as $, singleOpenStrategy as A, createForm as B, createQueue as C, createNestedContext as D, createNested as E, usePrefersReducedMotion as F, createDatePlugin as G, useForm as H, useLazy as I, createBreakpointsContext as J, useDate as K, useElementIntersection as L, useMediaQuery as M, usePrefersContrast as N, useNested as O, usePrefersDark as P, useProxyModel as Q, useIntersectionObserver as R, useStack as S, useQueue as T, createDate as U, createFormContext as V, createDateContext as W, useBreakpoints as X, createBreakpointsPlugin as Y, toReactive as Z, createStepContext as _, createVirtual as a, createFallbackHydration as at, createStackContext as b, useToggleScope as c, createHydrationPlugin as ct, useTimeline as d, createBreadcrumbsContext as dt, createOverflowContext as et, createStorage as f, useBreadcrumbs as ft, createStep as g, useStorage as h, useWindowEventListener as i, toElement as it, useMutationObserver as j, multipleOpenStrategy as k, createTimeline as l, useHydration as lt, createStoragePlugin as m, useDocumentEventListener as n, useElementSize as nt, createVirtualContext as o, createHydration as ot, createStorageContext as p, createBreakpoints as q, useEventListener as r, useResizeObserver as rt, useVirtual as s, createHydrationContext as st, useClickOutside as t, useOverflow as tt, createTimelineContext as u, createBreadcrumbs as ut, useStep as v, createQueueContext as w, createStackPlugin as x, createStack as y, useHotkey as z };
4924
+ export { useProxyModel as $, multipleOpenStrategy as A, useHotkey as B, createSlider as C, createNested as D, useQueue as E, usePrefersDark as F, createDateContext as G, createFormContext as H, usePrefersReducedMotion as I, createBreakpoints as J, createDatePlugin as K, useLazy as L, useMutationObserver as M, useMediaQuery as N, createNestedContext as O, usePrefersContrast as P, toReactive as Q, useElementIntersection as R, useStack as S, createQueueContext as T, useForm as U, createForm as V, createDate as W, createBreakpointsPlugin as X, createBreakpointsContext as Y, useBreakpoints as Z, createStepContext as _, createVirtual as a, toElement as at, createStackContext as b, useToggleScope as c, createHydrationContext as ct, useTimeline as d, createBreadcrumbs as dt, createOverflow as et, createStorage as f, createBreadcrumbsContext as ft, createStep as g, useStorage as h, useWindowEventListener as i, useResizeObserver as it, singleOpenStrategy as j, useNested as k, createTimeline as l, createHydrationPlugin as lt, createStoragePlugin as m, useDocumentEventListener as n, useOverflow as nt, createVirtualContext as o, createFallbackHydration as ot, createStorageContext as p, useBreadcrumbs as pt, useDate as q, useEventListener as r, useElementSize as rt, useVirtual as s, createHydration as st, useClickOutside as t, createOverflowContext as tt, createTimelineContext as u, useHydration as ut, useStep as v, createQueue as w, createStackPlugin as x, createStack as y, useIntersectionObserver as z };
@@ -1,7 +1,7 @@
1
- import { d as isObject, i as isBoolean, o as isFunction, r as isArray } from "./utilities-Dx8wzGa5.mjs";
2
- import { o as createPluginContext } from "./useLogger-BXqiUvt2.mjs";
3
- import { t as createTokens } from "./createTokens-jwf8-iGn.mjs";
4
- import { t as createGroup } from "./createGroup-BrZPZudL.mjs";
1
+ import { d as isObject, i as isBoolean, o as isFunction, r as isArray } from "./utilities-CcJtp9Gx.mjs";
2
+ import { o as createPluginContext } from "./useLogger-C8G5jgNk.mjs";
3
+ import { t as createTokens } from "./createTokens-Cu1efg9Z.mjs";
4
+ import { t as createGroup } from "./createGroup-CCb7Zfyw.mjs";
5
5
 
6
6
  //#region src/composables/useFeatures/adapters/generic/index.ts
7
7
  var FeaturesAdapter = class {};
@@ -1,9 +1,9 @@
1
- import { p as isString } from "./utilities-Dx8wzGa5.mjs";
2
- import { o as createPluginContext } from "./useLogger-BXqiUvt2.mjs";
3
- import { t as createTokens } from "./createTokens-jwf8-iGn.mjs";
4
- import { t as createSingle } from "./createSingle-BE1vHaZy.mjs";
5
- import { t as toArray } from "./toArray-VIn8vYt3.mjs";
6
- import { t as Vuetify0LocaleAdapter } from "./v0-CfSj99gF.mjs";
1
+ import { p as isString } from "./utilities-CcJtp9Gx.mjs";
2
+ import { o as createPluginContext } from "./useLogger-C8G5jgNk.mjs";
3
+ import { t as createTokens } from "./createTokens-Cu1efg9Z.mjs";
4
+ import { t as createSingle } from "./createSingle-BH9wNDrS.mjs";
5
+ import { t as toArray } from "./toArray-BBZH-G2X.mjs";
6
+ import { t as Vuetify0LocaleAdapter } from "./v0-BWBSVkew.mjs";
7
7
 
8
8
  //#region src/composables/useLocale/index.ts
9
9
  /**
@@ -1,7 +1,7 @@
1
- import { s as __LOGGER_ENABLED__, t as IN_BROWSER } from "./globals-vN-O052q.mjs";
2
- import { h as isUndefined } from "./utilities-Dx8wzGa5.mjs";
3
- import { i as useContext, n as createContext, t as createTrinity } from "./createTrinity-DkwPrPRS.mjs";
4
- import { t as Vuetify0LoggerAdapter } from "./v0-C8DBv9mh.mjs";
1
+ import { s as __LOGGER_ENABLED__, t as IN_BROWSER } from "./globals-D6FBsWDI.mjs";
2
+ import { h as isUndefined } from "./utilities-CcJtp9Gx.mjs";
3
+ import { i as useContext, n as createContext, t as createTrinity } from "./createTrinity-Cii8-B2r.mjs";
4
+ import { t as Vuetify0LoggerAdapter } from "./v0-lua6ffdk.mjs";
5
5
  import { hasInjectionContext } from "vue";
6
6
 
7
7
  //#region src/composables/createPlugin/index.ts
@@ -1,7 +1,7 @@
1
- import { o as createPluginContext } from "./useLogger-BXqiUvt2.mjs";
2
- import { t as createTokens } from "./createTokens-jwf8-iGn.mjs";
3
- import { t as toArray } from "./toArray-VIn8vYt3.mjs";
4
- import { t as Vuetify0PermissionAdapter } from "./v0-BYqmw3qM.mjs";
1
+ import { o as createPluginContext } from "./useLogger-C8G5jgNk.mjs";
2
+ import { t as createTokens } from "./createTokens-Cu1efg9Z.mjs";
3
+ import { t as toArray } from "./toArray-BBZH-G2X.mjs";
4
+ import { t as Vuetify0PermissionAdapter } from "./v0-DtO_ICXr.mjs";
5
5
 
6
6
  //#region src/composables/usePermissions/index.ts
7
7
  /**
@@ -1,7 +1,7 @@
1
- import { o as createPluginContext } from "./useLogger-BXqiUvt2.mjs";
2
- import { t as createTokens } from "./createTokens-jwf8-iGn.mjs";
3
- import { t as createSingle } from "./createSingle-BE1vHaZy.mjs";
4
- import { t as Vuetify0ThemeAdapter } from "./v0-Dwufx8ae.mjs";
1
+ import { o as createPluginContext } from "./useLogger-C8G5jgNk.mjs";
2
+ import { t as createTokens } from "./createTokens-Cu1efg9Z.mjs";
3
+ import { t as createSingle } from "./createSingle-BH9wNDrS.mjs";
4
+ import { t as Vuetify0ThemeAdapter } from "./v0-DzvhDU1W.mjs";
5
5
  import { computed, shallowRef, toRef } from "vue";
6
6
 
7
7
  //#region src/composables/useTheme/index.ts
@@ -1,4 +1,4 @@
1
- import "../globals-vN-O052q.mjs";
2
- import { _ as range, a as isElement, b as instanceName, c as isNull, d as isObject, f as isPrimitive, g as mergeDeep, h as isUndefined, i as isBoolean, l as isNullOrUndefined, m as isSymbol, n as debounce, o as isFunction, p as isString, r as isArray, s as isNaN, t as clamp, u as isNumber, v as useId, y as instanceExists } from "../utilities-Dx8wzGa5.mjs";
1
+ import "../globals-D6FBsWDI.mjs";
2
+ import { _ as range, a as isElement, b as instanceName, c as isNull, d as isObject, f as isPrimitive, g as mergeDeep, h as isUndefined, i as isBoolean, l as isNullOrUndefined, m as isSymbol, n as debounce, o as isFunction, p as isString, r as isArray, s as isNaN, t as clamp, u as isNumber, v as useId, y as instanceExists } from "../utilities-CcJtp9Gx.mjs";
3
3
 
4
4
  export { clamp, debounce, instanceExists, instanceName, isArray, isBoolean, isElement, isFunction, isNaN, isNull, isNullOrUndefined, isNumber, isObject, isPrimitive, isString, isSymbol, isUndefined, mergeDeep, range, useId };
@@ -1,4 +1,4 @@
1
- import { t as IN_BROWSER } from "./globals-vN-O052q.mjs";
1
+ import { t as IN_BROWSER } from "./globals-D6FBsWDI.mjs";
2
2
  import * as Vue from "vue";
3
3
  import { useId } from "vue";
4
4
 
@@ -1,5 +1,5 @@
1
- import { t as IN_BROWSER } from "./globals-vN-O052q.mjs";
2
- import { d as isObject, h as isUndefined } from "./utilities-Dx8wzGa5.mjs";
1
+ import { t as IN_BROWSER } from "./globals-D6FBsWDI.mjs";
2
+ import { d as isObject, h as isUndefined } from "./utilities-CcJtp9Gx.mjs";
3
3
 
4
4
  //#region src/composables/useLocale/adapters/v0.ts
5
5
  /**