@vuetify/v0 0.0.23 → 0.0.24

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 (32) hide show
  1. package/dist/adapter-L4Php1_S.d.mts +97 -0
  2. package/dist/browser/index.js +1069 -809
  3. package/dist/components/index.d.mts +4 -4
  4. package/dist/components/index.mjs +6 -6
  5. package/dist/{components-BI9xdoz5.mjs → components-D_yAxHwn.mjs} +433 -113
  6. package/dist/composables/index.d.mts +5 -4
  7. package/dist/composables/index.mjs +4 -4
  8. package/dist/constants/index.d.mts +1 -1
  9. package/dist/constants/index.mjs +3 -3
  10. package/dist/date/index.d.mts +124 -0
  11. package/dist/date/index.mjs +7514 -0
  12. package/dist/{globals-WKdFmgwy.mjs → globals-BhNI7no7.mjs} +1 -1
  13. package/dist/{index-Bby5ljat.d.mts → index-DknfL2GU.d.mts} +1 -1
  14. package/dist/{index-_y91DmIS.d.mts → index-OghXharF.d.mts} +721 -359
  15. package/dist/{index-DYSwiS9k.d.mts → index-ZW2YLa57.d.mts} +21 -2
  16. package/dist/{index-rcTqb9U3.d.mts → index-isYKpbs6.d.mts} +426 -266
  17. package/dist/{index-C8YcMooA.d.mts → index-kvJsAOSg.d.mts} +13 -9
  18. package/dist/index.d.mts +8 -7
  19. package/dist/index.mjs +7 -7
  20. package/dist/json/attributes.json +100 -0
  21. package/dist/json/importMap.json +64 -0
  22. package/dist/json/tags.json +45 -0
  23. package/dist/json/web-types.json +1303 -392
  24. package/dist/types/index.d.mts +2 -2
  25. package/dist/{useClickOutside-B47X8X6-.mjs → useClickOutside-w-Y2QxHh.mjs} +591 -657
  26. package/dist/utilities/index.d.mts +3 -3
  27. package/dist/utilities/index.mjs +2 -2
  28. package/dist/{utilities-9i1hJnMd.mjs → utilities-B58TiS_S.mjs} +41 -34
  29. package/package.json +3 -2
  30. /package/dist/{constants-3l8TGg5J.mjs → constants-DHKqjdjH.mjs} +0 -0
  31. /package/dist/{htmlElements-CXObxj0V.mjs → htmlElements-DO9n35bD.mjs} +0 -0
  32. /package/dist/{index-DMQJJUrv.d.mts → index-cPmI99rd.d.mts} +0 -0
@@ -1,7 +1,6 @@
1
- import { _ as isUndefined, a as genId, c as isFunction, d as isNullOrUndefined, f as isNumber, g as isSymbol, h as isString, l as isNaN, o as isArray, p as isObject, r as clamp, s as isBoolean, t as instanceExists, u as isNull, v as mergeDeep, y as range } from "./utilities-9i1hJnMd.mjs";
2
- import { a as SUPPORTS_OBSERVER, i as SUPPORTS_MUTATION_OBSERVER, n as SUPPORTS_INTERSECTION_OBSERVER, r as SUPPORTS_MATCH_MEDIA, s as __LOGGER_ENABLED__, t as IN_BROWSER } from "./globals-WKdFmgwy.mjs";
3
- import { computed, effectScope, inject, isRef, onScopeDispose, provide, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, toRef, toValue, unref, watch, watchEffect } from "vue";
4
- import { Temporal } from "@js-temporal/polyfill";
1
+ import { _ as useId$1, a as isFunction, c as isNullOrUndefined, f as isString, g as range, h as mergeDeep, i as isBoolean, l as isNumber, m as isUndefined, o as isNaN, p as isSymbol, r as isArray, s as isNull, t as clamp, u as isObject, v as instanceExists } from "./utilities-B58TiS_S.mjs";
2
+ import { a as SUPPORTS_OBSERVER, i as SUPPORTS_MUTATION_OBSERVER, n as SUPPORTS_INTERSECTION_OBSERVER, r as SUPPORTS_MATCH_MEDIA, s as __LOGGER_ENABLED__, t as IN_BROWSER } from "./globals-BhNI7no7.mjs";
3
+ import { computed, effectScope, inject, isRef, nextTick, onScopeDispose, provide, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, toRef, toValue, unref, watch, watchEffect } from "vue";
5
4
 
6
5
  //#region src/composables/createContext/index.ts
7
6
  /**
@@ -787,7 +786,7 @@ function createRegistry(options) {
787
786
  }
788
787
  function register(registration = {}) {
789
788
  const size = collection.size;
790
- const id = registration.id ?? /* @__PURE__ */ genId();
789
+ const id = registration.id ?? /* @__PURE__ */ useId$1();
791
790
  if (has(id)) {
792
791
  logger$1.warn(`Ticket "${id}" already exists. Use \`upsert()\` to update or check \`has()\` before registering.`);
793
792
  return get(id);
@@ -1034,7 +1033,7 @@ function createSelection(_options = {}) {
1034
1033
  return selectedIds.has(id);
1035
1034
  }
1036
1035
  function register(registration = {}) {
1037
- const id = registration.id ?? /* @__PURE__ */ genId();
1036
+ const id = registration.id ?? /* @__PURE__ */ useId$1();
1038
1037
  const item = {
1039
1038
  disabled: false,
1040
1039
  select: () => select(id),
@@ -1388,7 +1387,7 @@ function createGroup(_options = {}) {
1388
1387
  else selection.toggle(id);
1389
1388
  }
1390
1389
  function register(registration = {}) {
1391
- const id = registration.id ?? /* @__PURE__ */ genId();
1390
+ const id = registration.id ?? /* @__PURE__ */ useId$1();
1392
1391
  const item = {
1393
1392
  ...registration,
1394
1393
  id,
@@ -1819,18 +1818,26 @@ function toReactive(objectRef) {
1819
1818
  */
1820
1819
  function createHydration() {
1821
1820
  const isHydrated = shallowRef(false);
1821
+ const isSettled = shallowRef(false);
1822
1822
  function hydrate() {
1823
1823
  isHydrated.value = true;
1824
1824
  }
1825
+ function settle() {
1826
+ isSettled.value = true;
1827
+ }
1825
1828
  return {
1826
1829
  isHydrated: shallowReadonly(isHydrated),
1827
- hydrate
1830
+ isSettled: shallowReadonly(isSettled),
1831
+ hydrate,
1832
+ settle
1828
1833
  };
1829
1834
  }
1830
1835
  function createFallbackHydration() {
1831
1836
  return {
1832
1837
  isHydrated: shallowReadonly(shallowRef(true)),
1833
- hydrate: () => {}
1838
+ isSettled: shallowReadonly(shallowRef(true)),
1839
+ hydrate: () => {},
1840
+ settle: () => {}
1834
1841
  };
1835
1842
  }
1836
1843
  /**
@@ -1894,9 +1901,11 @@ function createHydrationPlugin(_options = {}) {
1894
1901
  provideHydrationContext(context, app);
1895
1902
  },
1896
1903
  setup: (app) => {
1897
- app.mixin({ mounted() {
1904
+ app.mixin({ async mounted() {
1898
1905
  if (!/* @__PURE__ */ isNull(this.$parent)) return;
1899
1906
  context.hydrate();
1907
+ await nextTick();
1908
+ context.settle();
1900
1909
  } });
1901
1910
  }
1902
1911
  });
@@ -1914,13 +1923,16 @@ function createHydrationPlugin(_options = {}) {
1914
1923
  * <script setup lang="ts">
1915
1924
  * import { useHydration } from '@vuetify/v0'
1916
1925
  *
1917
- * const hydration = useHydration()
1926
+ * const { isHydrated, isSettled } = useHydration()
1927
+ *
1928
+ * // Use isSettled to gate animations after state restoration
1929
+ * const transition = computed(() => isSettled.value ? 'fade' : undefined)
1918
1930
  * <\/script>
1919
1931
  *
1920
1932
  * <template>
1921
- * <div>
1922
- * <p>Is hydrated: {{ hydration.isHydrated.value }}</p>
1923
- * </div>
1933
+ * <Transition :name="transition">
1934
+ * <div v-if="show">Animates only after hydration settles</div>
1935
+ * </Transition>
1924
1936
  * </template>
1925
1937
  * ```
1926
1938
  */
@@ -2803,585 +2815,6 @@ function useLocale(namespace = "v0:locale") {
2803
2815
  }
2804
2816
  }
2805
2817
 
2806
- //#endregion
2807
- //#region src/composables/useDate/adapters/v0.ts
2808
- /**
2809
- * @module Vuetify0DateAdapter
2810
- *
2811
- * @remarks
2812
- * Default DateAdapter for v0, built on the Temporal API.
2813
- * Uses Temporal.PlainDateTime as the primary date type.
2814
- *
2815
- * Implements the full date-io IUtils interface for industry compatibility.
2816
- *
2817
- * Requires native Temporal support or @js-temporal/polyfill.
2818
- *
2819
- * @see https://tc39.es/proposal-temporal/docs/
2820
- * @see https://github.com/dmtrKovalenko/date-io
2821
- */
2822
- /** Single regex for token replacement in formatByString */
2823
- const FORMAT_TOKEN_REGEX = /YYYY|YY|MMMM|MMM|MM|M|dddd|ddd|DD|D|HH|H|hh|h|mm|m|ss|s|A|a/g;
2824
- /** Maximum cache size to prevent memory leaks */
2825
- const MAX_CACHE_SIZE = 50;
2826
- var Vuetify0DateAdapter = class {
2827
- _locale;
2828
- /** Cache for Intl.DateTimeFormat instances, keyed by locale + options */
2829
- formatCache = /* @__PURE__ */ new Map();
2830
- /** Cache for Intl.NumberFormat instances, keyed by locale */
2831
- numberFormatCache = /* @__PURE__ */ new Map();
2832
- constructor(locale = "en-US") {
2833
- this._locale = locale;
2834
- }
2835
- /** Current locale. Setting a new locale clears format caches. */
2836
- get locale() {
2837
- return this._locale;
2838
- }
2839
- set locale(value) {
2840
- if (this._locale !== value) {
2841
- this._locale = value;
2842
- this.formatCache.clear();
2843
- this.numberFormatCache.clear();
2844
- }
2845
- }
2846
- /**
2847
- * Create a date from various input types.
2848
- *
2849
- * @param value - Date value (PlainDateTime, PlainDate, ZonedDateTime, Date, ISO string, timestamp)
2850
- * @returns PlainDateTime or null if invalid
2851
- *
2852
- * @remarks
2853
- * **SSR Safety:** When called without arguments:
2854
- * - Browser: Returns current time via `Temporal.Now.plainDateTimeISO()`
2855
- * - Server: Returns epoch (1970-01-01T00:00:00) for deterministic rendering
2856
- *
2857
- * For SSR apps needing current time, pass `Date.now()` explicitly and handle
2858
- * hydration via `<ClientOnly>` (Nuxt) or `v-if` + `onMounted` pattern.
2859
- */
2860
- date(value) {
2861
- if (/* @__PURE__ */ isNullOrUndefined(value)) return IN_BROWSER ? Temporal.Now.plainDateTimeISO() : Temporal.PlainDateTime.from({
2862
- year: 1970,
2863
- month: 1,
2864
- day: 1,
2865
- hour: 0,
2866
- minute: 0,
2867
- second: 0
2868
- });
2869
- if (value instanceof Temporal.PlainDateTime) return value;
2870
- if (value instanceof Temporal.PlainDate) return value.toPlainDateTime();
2871
- if (value instanceof Temporal.ZonedDateTime) return value.toPlainDateTime();
2872
- if (value instanceof Date) return Temporal.PlainDateTime.from({
2873
- year: value.getFullYear(),
2874
- month: value.getMonth() + 1,
2875
- day: value.getDate(),
2876
- hour: value.getHours(),
2877
- minute: value.getMinutes(),
2878
- second: value.getSeconds(),
2879
- millisecond: value.getMilliseconds()
2880
- });
2881
- if (/* @__PURE__ */ isString(value)) try {
2882
- return Temporal.PlainDateTime.from(value);
2883
- } catch {
2884
- try {
2885
- return this.parseISO(value);
2886
- } catch {
2887
- return null;
2888
- }
2889
- }
2890
- if (/* @__PURE__ */ isNumber(value)) {
2891
- const date = new Date(value);
2892
- return Temporal.PlainDateTime.from({
2893
- year: date.getFullYear(),
2894
- month: date.getMonth() + 1,
2895
- day: date.getDate(),
2896
- hour: date.getHours(),
2897
- minute: date.getMinutes(),
2898
- second: date.getSeconds(),
2899
- millisecond: date.getMilliseconds()
2900
- });
2901
- }
2902
- return null;
2903
- }
2904
- toJsDate(value) {
2905
- return new Date(value.year, value.month - 1, value.day, value.hour, value.minute, value.second, value.millisecond);
2906
- }
2907
- parseISO(dateString) {
2908
- if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) return Temporal.PlainDate.from(dateString).toPlainDateTime();
2909
- if (dateString.includes("Z") || /[+-]\d{2}:\d{2}$/.test(dateString)) return Temporal.Instant.from(dateString).toZonedDateTimeISO("UTC").toPlainDateTime();
2910
- return Temporal.PlainDateTime.from(dateString);
2911
- }
2912
- toISO(date) {
2913
- return date.toString();
2914
- }
2915
- /**
2916
- * Parses a date string into a PlainDateTime.
2917
- *
2918
- * **Known limitation**: The `format` parameter is currently ignored.
2919
- * Temporal API doesn't provide built-in format parsing, and implementing
2920
- * full format string parsing (e.g., 'MM/DD/YYYY') would require a
2921
- * substantial custom parser. This method delegates to `date()` which
2922
- * handles ISO 8601 strings and common formats.
2923
- *
2924
- * For custom format parsing, consider using a library like date-fns or
2925
- * luxon with a custom adapter.
2926
- *
2927
- * @param value - The date string to parse
2928
- * @param _format - Format hint (currently ignored)
2929
- * @returns Parsed PlainDateTime or null if invalid
2930
- */
2931
- parse(value, _format) {
2932
- try {
2933
- return this.date(value);
2934
- } catch {
2935
- return null;
2936
- }
2937
- }
2938
- isValid(date) {
2939
- if (/* @__PURE__ */ isNullOrUndefined(date)) return false;
2940
- if (date instanceof Temporal.PlainDateTime) return true;
2941
- if (date instanceof Temporal.PlainDate) return true;
2942
- if (date instanceof Temporal.ZonedDateTime) return true;
2943
- if (date instanceof Date) return !Number.isNaN(date.getTime());
2944
- if (/* @__PURE__ */ isString(date)) try {
2945
- Temporal.PlainDateTime.from(date);
2946
- return true;
2947
- } catch {
2948
- try {
2949
- Temporal.PlainDate.from(date);
2950
- return true;
2951
- } catch {
2952
- return false;
2953
- }
2954
- }
2955
- return false;
2956
- }
2957
- isNull(value) {
2958
- return /* @__PURE__ */ isNullOrUndefined(value);
2959
- }
2960
- getCurrentLocaleCode() {
2961
- return this.locale;
2962
- }
2963
- is12HourCycleInCurrentLocale() {
2964
- return new Intl.DateTimeFormat(this.locale, { hour: "numeric" }).resolvedOptions().hour12 ?? false;
2965
- }
2966
- format(date, formatString) {
2967
- const jsDate = this.toJsDate(date);
2968
- const options = {
2969
- fullDate: { dateStyle: "full" },
2970
- fullDateWithWeekday: {
2971
- weekday: "long",
2972
- year: "numeric",
2973
- month: "long",
2974
- day: "numeric"
2975
- },
2976
- normalDate: { dateStyle: "medium" },
2977
- shortDate: { dateStyle: "short" },
2978
- year: { year: "numeric" },
2979
- month: { month: "long" },
2980
- monthShort: { month: "short" },
2981
- monthAndYear: {
2982
- year: "numeric",
2983
- month: "long"
2984
- },
2985
- monthAndDate: {
2986
- month: "long",
2987
- day: "numeric"
2988
- },
2989
- weekday: { weekday: "long" },
2990
- weekdayShort: { weekday: "short" },
2991
- dayOfMonth: { day: "numeric" },
2992
- hours12h: {
2993
- hour: "numeric",
2994
- hour12: true
2995
- },
2996
- hours24h: {
2997
- hour: "numeric",
2998
- hour12: false
2999
- },
3000
- minutes: { minute: "numeric" },
3001
- seconds: { second: "numeric" },
3002
- fullTime: { timeStyle: "medium" },
3003
- fullTime12h: {
3004
- hour: "numeric",
3005
- minute: "numeric",
3006
- second: "numeric",
3007
- hour12: true
3008
- },
3009
- fullTime24h: {
3010
- hour: "numeric",
3011
- minute: "numeric",
3012
- second: "numeric",
3013
- hour12: false
3014
- },
3015
- fullDateTime: {
3016
- dateStyle: "full",
3017
- timeStyle: "short"
3018
- },
3019
- fullDateTime12h: {
3020
- dateStyle: "full",
3021
- hour: "numeric",
3022
- minute: "numeric",
3023
- hour12: true
3024
- },
3025
- fullDateTime24h: {
3026
- dateStyle: "full",
3027
- hour: "numeric",
3028
- minute: "numeric",
3029
- hour12: false
3030
- },
3031
- keyboardDate: {
3032
- year: "numeric",
3033
- month: "2-digit",
3034
- day: "2-digit"
3035
- },
3036
- keyboardDateTime: {
3037
- year: "numeric",
3038
- month: "2-digit",
3039
- day: "2-digit",
3040
- hour: "numeric",
3041
- minute: "numeric"
3042
- },
3043
- keyboardDateTime12h: {
3044
- year: "numeric",
3045
- month: "2-digit",
3046
- day: "2-digit",
3047
- hour: "numeric",
3048
- minute: "numeric",
3049
- hour12: true
3050
- },
3051
- keyboardDateTime24h: {
3052
- year: "numeric",
3053
- month: "2-digit",
3054
- day: "2-digit",
3055
- hour: "numeric",
3056
- minute: "numeric",
3057
- hour12: false
3058
- }
3059
- }[formatString];
3060
- if (options) return this.getFormatter(options).format(jsDate);
3061
- return this.getFormatter({}).format(jsDate);
3062
- }
3063
- formatByString(date, formatString) {
3064
- const jsDate = this.toJsDate(date);
3065
- const getTokenValue = (token) => {
3066
- switch (token) {
3067
- case "YYYY": return String(date.year);
3068
- case "YY": return String(date.year).slice(-2);
3069
- case "MM": return String(date.month).padStart(2, "0");
3070
- case "M": return String(date.month);
3071
- case "DD": return String(date.day).padStart(2, "0");
3072
- case "D": return String(date.day);
3073
- case "HH": return String(date.hour).padStart(2, "0");
3074
- case "H": return String(date.hour);
3075
- case "hh": return String(date.hour % 12 || 12).padStart(2, "0");
3076
- case "h": return String(date.hour % 12 || 12);
3077
- case "mm": return String(date.minute).padStart(2, "0");
3078
- case "m": return String(date.minute);
3079
- case "ss": return String(date.second).padStart(2, "0");
3080
- case "s": return String(date.second);
3081
- case "A": return date.hour < 12 ? "AM" : "PM";
3082
- case "a": return date.hour < 12 ? "am" : "pm";
3083
- case "MMMM": return this.getFormatter({ month: "long" }).format(jsDate);
3084
- case "MMM": return this.getFormatter({ month: "short" }).format(jsDate);
3085
- case "dddd": return this.getFormatter({ weekday: "long" }).format(jsDate);
3086
- case "ddd": return this.getFormatter({ weekday: "short" }).format(jsDate);
3087
- default: return token;
3088
- }
3089
- };
3090
- return formatString.replace(FORMAT_TOKEN_REGEX, (match) => getTokenValue(match));
3091
- }
3092
- getFormatHelperText(format) {
3093
- return {
3094
- keyboardDate: "mm/dd/yyyy",
3095
- keyboardDateTime: "mm/dd/yyyy hh:mm",
3096
- keyboardDateTime12h: "mm/dd/yyyy hh:mm am/pm",
3097
- keyboardDateTime24h: "mm/dd/yyyy hh:mm"
3098
- }[format] ?? format.replace(/YYYY/g, "yyyy").replace(/MM/g, "mm").replace(/DD/g, "dd").replace(/HH/g, "hh").replace(/mm/g, "mm").replace(/ss/g, "ss");
3099
- }
3100
- formatNumber(numberToFormat) {
3101
- return this.getNumberFormatter().format(Number(numberToFormat));
3102
- }
3103
- getMeridiemText(ampm) {
3104
- const date = ampm === "am" ? new Date(2020, 0, 1, 9, 0) : new Date(2020, 0, 1, 15, 0);
3105
- const match = this.getFormatter({
3106
- hour: "numeric",
3107
- hour12: true
3108
- }).format(date).match(/[AP]M|[ap]m|午前|午後|上午|下午/i);
3109
- return match ? match[0] : ampm.toUpperCase();
3110
- }
3111
- startOfDay(date) {
3112
- return date.with({
3113
- hour: 0,
3114
- minute: 0,
3115
- second: 0,
3116
- millisecond: 0,
3117
- microsecond: 0,
3118
- nanosecond: 0
3119
- });
3120
- }
3121
- endOfDay(date) {
3122
- return date.with({
3123
- hour: 23,
3124
- minute: 59,
3125
- second: 59,
3126
- millisecond: 999,
3127
- microsecond: 999,
3128
- nanosecond: 999
3129
- });
3130
- }
3131
- startOfWeek(date, firstDayOfWeek = 0) {
3132
- const diff = (date.dayOfWeek % 7 - firstDayOfWeek + 7) % 7;
3133
- return this.startOfDay(date.subtract({ days: diff }));
3134
- }
3135
- endOfWeek(date, firstDayOfWeek = 0) {
3136
- const start = this.startOfWeek(date, firstDayOfWeek);
3137
- return this.endOfDay(start.add({ days: 6 }));
3138
- }
3139
- startOfMonth(date) {
3140
- return this.startOfDay(date.with({ day: 1 }));
3141
- }
3142
- endOfMonth(date) {
3143
- return this.endOfDay(date.with({ day: date.daysInMonth }));
3144
- }
3145
- startOfYear(date) {
3146
- return this.startOfDay(date.with({
3147
- month: 1,
3148
- day: 1
3149
- }));
3150
- }
3151
- endOfYear(date) {
3152
- return this.endOfDay(date.with({
3153
- month: 12,
3154
- day: 31
3155
- }));
3156
- }
3157
- addSeconds(date, amount) {
3158
- return date.add({ seconds: amount });
3159
- }
3160
- addMinutes(date, amount) {
3161
- return date.add({ minutes: amount });
3162
- }
3163
- addHours(date, amount) {
3164
- return date.add({ hours: amount });
3165
- }
3166
- addDays(date, amount) {
3167
- return date.add({ days: amount });
3168
- }
3169
- addWeeks(date, amount) {
3170
- return date.add({ weeks: amount });
3171
- }
3172
- addMonths(date, amount) {
3173
- return date.add({ months: amount });
3174
- }
3175
- addYears(date, amount) {
3176
- return date.add({ years: amount });
3177
- }
3178
- isAfter(date, comparing) {
3179
- return Temporal.PlainDateTime.compare(date, comparing) > 0;
3180
- }
3181
- isAfterDay(date, comparing) {
3182
- return Temporal.PlainDate.compare(date.toPlainDate(), comparing.toPlainDate()) > 0;
3183
- }
3184
- isAfterMonth(date, comparing) {
3185
- if (date.year !== comparing.year) return date.year > comparing.year;
3186
- return date.month > comparing.month;
3187
- }
3188
- isAfterYear(date, comparing) {
3189
- return date.year > comparing.year;
3190
- }
3191
- isBefore(date, comparing) {
3192
- return Temporal.PlainDateTime.compare(date, comparing) < 0;
3193
- }
3194
- isBeforeDay(date, comparing) {
3195
- return Temporal.PlainDate.compare(date.toPlainDate(), comparing.toPlainDate()) < 0;
3196
- }
3197
- isBeforeMonth(date, comparing) {
3198
- if (date.year !== comparing.year) return date.year < comparing.year;
3199
- return date.month < comparing.month;
3200
- }
3201
- isBeforeYear(date, comparing) {
3202
- return date.year < comparing.year;
3203
- }
3204
- isEqual(date, comparing) {
3205
- return Temporal.PlainDateTime.compare(date, comparing) === 0;
3206
- }
3207
- isSameDay(date, comparing) {
3208
- return Temporal.PlainDate.compare(date.toPlainDate(), comparing.toPlainDate()) === 0;
3209
- }
3210
- isSameMonth(date, comparing) {
3211
- return date.year === comparing.year && date.month === comparing.month;
3212
- }
3213
- isSameYear(date, comparing) {
3214
- return date.year === comparing.year;
3215
- }
3216
- isSameHour(date, comparing) {
3217
- return date.year === comparing.year && date.month === comparing.month && date.day === comparing.day && date.hour === comparing.hour;
3218
- }
3219
- isWithinRange(date, [start, end]) {
3220
- return Temporal.PlainDateTime.compare(date, start) >= 0 && Temporal.PlainDateTime.compare(date, end) <= 0;
3221
- }
3222
- getYear(date) {
3223
- return date.year;
3224
- }
3225
- getMonth(date) {
3226
- return date.month - 1;
3227
- }
3228
- getDate(date) {
3229
- return date.day;
3230
- }
3231
- getHours(date) {
3232
- return date.hour;
3233
- }
3234
- getMinutes(date) {
3235
- return date.minute;
3236
- }
3237
- getSeconds(date) {
3238
- return date.second;
3239
- }
3240
- getDiff(date, comparing, unit) {
3241
- const unitKey = unit ?? "days";
3242
- const comp = /* @__PURE__ */ isString(comparing) ? this.date(comparing) : comparing;
3243
- if (/* @__PURE__ */ isNull(comp)) return 0;
3244
- const duration = date.since(comp, { largestUnit: unitKey });
3245
- switch (unitKey) {
3246
- case "years": return duration.years;
3247
- case "months": return duration.months + duration.years * 12;
3248
- case "weeks": return duration.weeks + Math.floor(duration.days / 7);
3249
- case "days": return duration.days + duration.weeks * 7;
3250
- case "hours": return Math.round(duration.total({ unit: "hours" }));
3251
- case "minutes": return Math.round(duration.total({ unit: "minutes" }));
3252
- case "seconds": return Math.round(duration.total({ unit: "seconds" }));
3253
- default: return duration.days;
3254
- }
3255
- }
3256
- getWeek(date, firstDayOfWeek = 0, minimalDays = 1) {
3257
- const startOfYear = this.startOfYear(date);
3258
- const startOfFirstWeek = this.startOfWeek(startOfYear, firstDayOfWeek);
3259
- let firstWeekStart = startOfFirstWeek;
3260
- if (startOfYear.day - startOfFirstWeek.day < minimalDays) firstWeekStart = startOfFirstWeek.add({ weeks: 1 });
3261
- const startOfCurrentWeek = this.startOfWeek(date, firstDayOfWeek);
3262
- const diff = this.getDiff(startOfCurrentWeek, firstWeekStart, "weeks");
3263
- return Math.max(1, diff + 1);
3264
- }
3265
- getDaysInMonth(date) {
3266
- return date.daysInMonth;
3267
- }
3268
- setYear(date, year) {
3269
- return date.with({ year });
3270
- }
3271
- setMonth(date, month) {
3272
- return date.with({ month: month + 1 });
3273
- }
3274
- setDate(date, day) {
3275
- return date.with({ day });
3276
- }
3277
- setHours(date, hours) {
3278
- return date.with({ hour: hours });
3279
- }
3280
- setMinutes(date, minutes) {
3281
- return date.with({ minute: minutes });
3282
- }
3283
- setSeconds(date, seconds) {
3284
- return date.with({ second: seconds });
3285
- }
3286
- getWeekdays(firstDayOfWeek = 0, format = "short") {
3287
- const weekdays = [];
3288
- const refDate = Temporal.PlainDate.from("2015-01-04");
3289
- const formatter = this.getFormatter({ weekday: format });
3290
- for (let i = 0; i < 7; i++) {
3291
- const day = refDate.add({ days: (i + firstDayOfWeek) % 7 });
3292
- const jsDate = new Date(day.year, day.month - 1, day.day);
3293
- weekdays.push(formatter.format(jsDate));
3294
- }
3295
- return weekdays;
3296
- }
3297
- getWeekArray(date, firstDayOfWeek = 0) {
3298
- const weeks = [];
3299
- const monthStart = this.startOfMonth(date);
3300
- const monthEnd = this.endOfMonth(date);
3301
- let current = this.startOfWeek(monthStart, firstDayOfWeek);
3302
- const end = this.endOfWeek(monthEnd);
3303
- while (Temporal.PlainDateTime.compare(current, end) <= 0) {
3304
- const week = [];
3305
- for (let i = 0; i < 7; i++) {
3306
- week.push(current);
3307
- current = current.add({ days: 1 });
3308
- }
3309
- weeks.push(week);
3310
- }
3311
- return weeks;
3312
- }
3313
- getMonthArray(date) {
3314
- const year = date.year;
3315
- const months = [];
3316
- for (let month = 1; month <= 12; month++) months.push(Temporal.PlainDateTime.from({
3317
- year,
3318
- month,
3319
- day: 1
3320
- }));
3321
- return months;
3322
- }
3323
- getYearRange(start, end) {
3324
- const years = [];
3325
- let current = start.year;
3326
- while (current <= end.year) {
3327
- years.push(Temporal.PlainDateTime.from({
3328
- year: current,
3329
- month: 1,
3330
- day: 1
3331
- }));
3332
- current++;
3333
- }
3334
- return years;
3335
- }
3336
- getNextMonth(date) {
3337
- return this.startOfMonth(date.add({ months: 1 }));
3338
- }
3339
- getPreviousMonth(date) {
3340
- return this.startOfMonth(date.subtract({ months: 1 }));
3341
- }
3342
- mergeDateAndTime(date, time) {
3343
- return date.with({
3344
- hour: time.hour,
3345
- minute: time.minute,
3346
- second: time.second,
3347
- millisecond: time.millisecond
3348
- });
3349
- }
3350
- /**
3351
- * Gets a cached Intl.DateTimeFormat instance or creates one if not cached.
3352
- * Cache is limited to MAX_CACHE_SIZE entries to prevent memory leaks.
3353
- */
3354
- getFormatter(options) {
3355
- const key = `${this.locale}:${JSON.stringify(options)}`;
3356
- let formatter = this.formatCache.get(key);
3357
- if (!formatter) {
3358
- if (this.formatCache.size >= MAX_CACHE_SIZE) {
3359
- const firstKey = this.formatCache.keys().next().value;
3360
- if (firstKey) this.formatCache.delete(firstKey);
3361
- }
3362
- formatter = new Intl.DateTimeFormat(this.locale, options);
3363
- this.formatCache.set(key, formatter);
3364
- }
3365
- return formatter;
3366
- }
3367
- /**
3368
- * Gets a cached Intl.NumberFormat instance or creates one if not cached.
3369
- * Cache is limited to MAX_CACHE_SIZE entries to prevent memory leaks.
3370
- */
3371
- getNumberFormatter() {
3372
- let formatter = this.numberFormatCache.get(this.locale);
3373
- if (!formatter) {
3374
- if (this.numberFormatCache.size >= MAX_CACHE_SIZE) {
3375
- const firstKey = this.numberFormatCache.keys().next().value;
3376
- if (firstKey) this.numberFormatCache.delete(firstKey);
3377
- }
3378
- formatter = new Intl.NumberFormat(this.locale);
3379
- this.numberFormatCache.set(this.locale, formatter);
3380
- }
3381
- return formatter;
3382
- }
3383
- };
3384
-
3385
2818
  //#endregion
3386
2819
  //#region src/composables/useDate/index.ts
3387
2820
  /**
@@ -3392,16 +2825,16 @@ var Vuetify0DateAdapter = class {
3392
2825
  *
3393
2826
  * Key features:
3394
2827
  * - Adapter pattern for date library abstraction
3395
- * - Temporal API as default adapter (modern, immutable dates)
3396
2828
  * - Locale-aware formatting via Intl.DateTimeFormat
3397
2829
  * - Integration with useLocale for automatic locale sync
3398
2830
  *
3399
- * @example
2831
+ * @example Using the built-in Temporal adapter
3400
2832
  * ```ts
2833
+ * import { Vuetify0DateAdapter } from '@vuetify/v0/date'
3401
2834
  * import { createDatePlugin } from '@vuetify/v0'
3402
2835
  *
3403
2836
  * const app = createApp(App)
3404
- * app.use(createDatePlugin())
2837
+ * app.use(createDatePlugin({ adapter: new Vuetify0DateAdapter() }))
3405
2838
  *
3406
2839
  * // In a component:
3407
2840
  * const { adapter } = useDate()
@@ -3417,7 +2850,7 @@ var Vuetify0DateAdapter = class {
3417
2850
  * // ... implementation
3418
2851
  * }
3419
2852
  *
3420
- * const context = createDate({ adapter: new DateFnsAdapter() })
2853
+ * app.use(createDatePlugin({ adapter: new DateFnsAdapter() }))
3421
2854
  * ```
3422
2855
  */
3423
2856
  /**
@@ -3440,7 +2873,8 @@ const defaultLocales = {
3440
2873
  /**
3441
2874
  * Creates a new date context.
3442
2875
  *
3443
- * @param options Optional adapter and locale configuration.
2876
+ * @param options Adapter and locale configuration.
2877
+ * @template Z The date type used by the adapter.
3444
2878
  * @template E The date context type.
3445
2879
  * @returns A date context.
3446
2880
  *
@@ -3448,18 +2882,20 @@ const defaultLocales = {
3448
2882
  *
3449
2883
  * @example
3450
2884
  * ```ts
3451
- * const { adapter } = createDate()
3452
- * const today = adapter.date() // Temporal.PlainDateTime
2885
+ * import { Vuetify0DateAdapter } from '@vuetify/v0/date'
3453
2886
  *
3454
- * // With locale options
3455
- * const { adapter: deAdapter } = createDate({ locale: 'de-DE' })
2887
+ * const { adapter } = createDate({ adapter: new Vuetify0DateAdapter() })
2888
+ * const today = adapter.date()
3456
2889
  *
3457
- * // With custom adapter
3458
- * const { adapter } = createDate({ adapter: new DateFnsAdapter() })
2890
+ * // With locale options
2891
+ * const { adapter } = createDate({
2892
+ * adapter: new Vuetify0DateAdapter(),
2893
+ * locale: 'de-DE',
2894
+ * })
3459
2895
  * ```
3460
2896
  */
3461
- function createDate(options = {}) {
3462
- const { locales = defaultLocales, adapter = new Vuetify0DateAdapter(), locale: initialLocale } = options;
2897
+ function createDate(options) {
2898
+ const { locales = defaultLocales, adapter, locale: initialLocale } = options;
3463
2899
  let selectedId;
3464
2900
  try {
3465
2901
  if (instanceExists()) selectedId = useLocale().selectedId;
@@ -3487,22 +2923,10 @@ function createDate(options = {}) {
3487
2923
  };
3488
2924
  }
3489
2925
  /**
3490
- * Creates a fallback date context for when useDate is called outside of a Vue component.
3491
- *
3492
- * @returns A fallback date context with Vuetify0DateAdapter.
3493
- * @internal
3494
- */
3495
- function createDateFallback() {
3496
- const adapter = new Vuetify0DateAdapter();
3497
- return {
3498
- adapter,
3499
- locale: computed(() => adapter.locale ?? "en-US")
3500
- };
3501
- }
3502
- /**
3503
2926
  * Creates a new date context trinity.
3504
2927
  *
3505
- * @param options Optional adapter, locale, and namespace configuration.
2928
+ * @param options Adapter, locale, and namespace configuration.
2929
+ * @template Z The date type used by the adapter.
3506
2930
  * @template E The date context type.
3507
2931
  * @returns A trinity [useContext, provideContext, defaultContext].
3508
2932
  *
@@ -3510,18 +2934,15 @@ function createDateFallback() {
3510
2934
  *
3511
2935
  * @example
3512
2936
  * ```ts
3513
- * const [useAppDate, provideAppDate] = createDateContext({
3514
- * namespace: 'app:date',
3515
- * })
2937
+ * import { Vuetify0DateAdapter } from '@vuetify/v0/date'
3516
2938
  *
3517
- * // With custom adapter
3518
2939
  * const [useAppDate, provideAppDate] = createDateContext({
3519
- * adapter: new DateFnsAdapter(),
2940
+ * adapter: new Vuetify0DateAdapter(),
3520
2941
  * namespace: 'app:date',
3521
2942
  * })
3522
2943
  * ```
3523
2944
  */
3524
- function createDateContext(options = {}) {
2945
+ function createDateContext(options) {
3525
2946
  const { namespace = "v0:date", ...dateOptions } = options;
3526
2947
  const [useDateContext, _provideDateContext] = createContext(namespace);
3527
2948
  const context = createDate(dateOptions);
@@ -3533,7 +2954,8 @@ function createDateContext(options = {}) {
3533
2954
  /**
3534
2955
  * Creates a new date plugin.
3535
2956
  *
3536
- * @param options Optional adapter, locale, and namespace configuration.
2957
+ * @param options Adapter, locale, and namespace configuration.
2958
+ * @template Z The date type used by the adapter.
3537
2959
  * @template E The date context type.
3538
2960
  * @returns A Vue plugin.
3539
2961
  *
@@ -3541,17 +2963,19 @@ function createDateContext(options = {}) {
3541
2963
  *
3542
2964
  * @example
3543
2965
  * ```ts
3544
- * const app = createApp(App)
3545
- * app.use(createDatePlugin())
2966
+ * import { Vuetify0DateAdapter } from '@vuetify/v0/date'
3546
2967
  *
3547
- * // With options
3548
- * app.use(createDatePlugin({ locale: 'de-DE' }))
2968
+ * const app = createApp(App)
2969
+ * app.use(createDatePlugin({ adapter: new Vuetify0DateAdapter() }))
3549
2970
  *
3550
- * // With custom adapter
3551
- * app.use(createDatePlugin({ adapter: new DateFnsAdapter() }))
2971
+ * // With locale options
2972
+ * app.use(createDatePlugin({
2973
+ * adapter: new Vuetify0DateAdapter(),
2974
+ * locale: 'de-DE',
2975
+ * }))
3552
2976
  * ```
3553
2977
  */
3554
- function createDatePlugin(options = {}) {
2978
+ function createDatePlugin(options) {
3555
2979
  const { namespace = "v0:date", ...dateOptions } = options;
3556
2980
  const [, provideDateContext, context] = createDateContext({
3557
2981
  namespace,
@@ -3567,16 +2991,26 @@ function createDatePlugin(options = {}) {
3567
2991
  /**
3568
2992
  * Returns the current date context.
3569
2993
  *
3570
- * When called inside a component with a provided date context (via plugin or provider),
3571
- * returns that context. Otherwise, returns a fallback context with Vuetify0DateAdapter.
2994
+ * Requires `createDatePlugin` to be installed with an adapter.
3572
2995
  *
3573
2996
  * @param namespace The namespace to look up (defaults to 'v0:date').
2997
+ * @template Z The date type used by the adapter.
3574
2998
  * @template E The date context type.
3575
2999
  * @returns The current date context.
3000
+ * @throws If called outside a component or without a date plugin installed.
3576
3001
  *
3577
3002
  * @see https://0.vuetifyjs.com/composables/plugins/use-date
3578
3003
  *
3579
3004
  * @example
3005
+ * ```ts
3006
+ * // main.ts
3007
+ * import { Vuetify0DateAdapter } from '@vuetify/v0/date'
3008
+ * import { createDatePlugin } from '@vuetify/v0'
3009
+ *
3010
+ * app.use(createDatePlugin({ adapter: new Vuetify0DateAdapter() }))
3011
+ * ```
3012
+ *
3013
+ * @example
3580
3014
  * ```vue
3581
3015
  * <script setup lang="ts">
3582
3016
  * import { useDate } from '@vuetify/v0'
@@ -3587,13 +3021,8 @@ function createDatePlugin(options = {}) {
3587
3021
  * ```
3588
3022
  */
3589
3023
  function useDate(namespace = "v0:date") {
3590
- const fallback = createDateFallback();
3591
- if (!instanceExists()) return fallback;
3592
- try {
3593
- return useContext(namespace, fallback);
3594
- } catch {
3595
- return fallback;
3596
- }
3024
+ if (!instanceExists()) throw new Error("[v0] useDate() must be called inside a Vue component with createDatePlugin installed.\n\nExample:\n import { Vuetify0DateAdapter } from '@vuetify/v0/date'\n import { createDatePlugin } from '@vuetify/v0'\n\n app.use(createDatePlugin({ adapter: new Vuetify0DateAdapter() }))");
3025
+ return useContext(namespace);
3597
3026
  }
3598
3027
 
3599
3028
  //#endregion
@@ -4593,7 +4022,7 @@ function matchesKeyGroup(e, group, platformIsMac) {
4593
4022
  */
4594
4023
  function useIntersectionObserver(target, callback, options = {}) {
4595
4024
  const { isHydrated } = useHydration();
4596
- const targetRef = isRef(target) ? target : shallowRef(target);
4025
+ const targetRef = toRef(target);
4597
4026
  const observer = shallowRef();
4598
4027
  const isPaused = shallowRef(false);
4599
4028
  const isIntersecting = shallowRef(false);
@@ -4994,6 +4423,7 @@ function usePrefersContrast() {
4994
4423
  */
4995
4424
  function useMutationObserver(target, callback, options = {}) {
4996
4425
  const { isHydrated } = useHydration();
4426
+ const targetRef = toRef(target);
4997
4427
  const observer = shallowRef();
4998
4428
  const isPaused = shallowRef(false);
4999
4429
  const isActive = toRef(() => !!observer.value);
@@ -5008,7 +4438,7 @@ function useMutationObserver(target, callback, options = {}) {
5008
4438
  };
5009
4439
  function setup() {
5010
4440
  if (/* @__PURE__ */ isNull(observer.value)) return;
5011
- if (!isHydrated.value || !SUPPORTS_MUTATION_OBSERVER || !target.value || isPaused.value) return;
4441
+ if (!isHydrated.value || !SUPPORTS_MUTATION_OBSERVER || !targetRef.value || isPaused.value) return;
5012
4442
  observer.value = new MutationObserver((mutations) => {
5013
4443
  callback(mutations.map((mutation) => ({
5014
4444
  type: mutation.type,
@@ -5023,7 +4453,7 @@ function useMutationObserver(target, callback, options = {}) {
5023
4453
  })));
5024
4454
  if (options.once) stop();
5025
4455
  });
5026
- observer.value.observe(target.value, observerOptions);
4456
+ observer.value.observe(targetRef.value, observerOptions);
5027
4457
  if (options.immediate) {
5028
4458
  const emptyNodeList = {
5029
4459
  length: 0,
@@ -5033,7 +4463,7 @@ function useMutationObserver(target, callback, options = {}) {
5033
4463
  };
5034
4464
  callback([{
5035
4465
  type: "childList",
5036
- target: target.value,
4466
+ target: targetRef.value,
5037
4467
  addedNodes: emptyNodeList,
5038
4468
  removedNodes: emptyNodeList,
5039
4469
  previousSibling: null,
@@ -5045,13 +4475,13 @@ function useMutationObserver(target, callback, options = {}) {
5045
4475
  if (options.once) stop();
5046
4476
  }
5047
4477
  }
5048
- watch(() => target.value, (el, oldEl) => {
4478
+ watch(() => targetRef.value, (el, oldEl) => {
5049
4479
  if (oldEl) cleanup();
5050
4480
  if (isHydrated.value && el) setup();
5051
4481
  }, { immediate: true });
5052
4482
  if (!isHydrated.value) {
5053
4483
  const stopHydrationWatch = watch(() => isHydrated.value, (hydrated) => {
5054
- if (hydrated && target.value && !observer.value) {
4484
+ if (hydrated && targetRef.value && !observer.value) {
5055
4485
  setup();
5056
4486
  stopHydrationWatch();
5057
4487
  }
@@ -5085,6 +4515,509 @@ function useMutationObserver(target, callback, options = {}) {
5085
4515
  };
5086
4516
  }
5087
4517
 
4518
+ //#endregion
4519
+ //#region src/composables/createNested/strategies.ts
4520
+ /**
4521
+ * Multiple open strategy: allows multiple nodes to be open simultaneously.
4522
+ *
4523
+ * @remarks
4524
+ * Perfect for tree views, file explorers, and nested menus where users expect
4525
+ * to keep multiple sections expanded at once.
4526
+ *
4527
+ * @example
4528
+ * ```ts
4529
+ * const tree = createNested({ openStrategy: multipleOpenStrategy })
4530
+ * tree.open('node-1')
4531
+ * tree.open('node-2')
4532
+ * // Both nodes are now open
4533
+ * ```
4534
+ */
4535
+ const multipleOpenStrategy = {
4536
+ onOpen: void 0,
4537
+ onClose: void 0
4538
+ };
4539
+ /**
4540
+ * Single open strategy: only one node can be open at a time (accordion behavior).
4541
+ *
4542
+ * @remarks
4543
+ * Perfect for accordions, single-select navigation, and contexts where only
4544
+ * one section should be visible at a time.
4545
+ *
4546
+ * @example
4547
+ * ```ts
4548
+ * const tree = createNested({ openStrategy: singleOpenStrategy })
4549
+ * tree.open('node-1') // node-1 opens
4550
+ * tree.open('node-2') // node-1 closes, node-2 opens
4551
+ * ```
4552
+ */
4553
+ const singleOpenStrategy = {
4554
+ onOpen: (id, context) => {
4555
+ for (const openedId of context.openedIds) if (openedId !== id) context.openedIds.delete(openedId);
4556
+ },
4557
+ onClose: void 0
4558
+ };
4559
+
4560
+ //#endregion
4561
+ //#region src/composables/createNested/index.ts
4562
+ /**
4563
+ * @module createNested
4564
+ *
4565
+ * @remarks
4566
+ * Hierarchical tree management composable extending createGroup with:
4567
+ * - Parent-child relationship tracking (children/parents Maps)
4568
+ * - Open/close state management
4569
+ * - Tree traversal utilities (getPath, getDescendants, etc.)
4570
+ * - Pluggable open strategies
4571
+ *
4572
+ * Inheritance chain: createSelection → createGroup → createNested
4573
+ */
4574
+ /**
4575
+ * Resolves open mode to an OpenStrategy.
4576
+ */
4577
+ function resolveOpenStrategy(open = "multiple") {
4578
+ return open === "single" ? singleOpenStrategy : multipleOpenStrategy;
4579
+ }
4580
+ /**
4581
+ * Creates a new nested tree instance with hierarchical management.
4582
+ *
4583
+ * Extends `createGroup` to support parent-child relationships, tree traversal,
4584
+ * and open/close state management. Perfect for tree views, nested navigation,
4585
+ * and hierarchical data structures.
4586
+ *
4587
+ * @param options The options for the nested instance.
4588
+ * @template Z The type of the nested ticket.
4589
+ * @template E The type of the nested context.
4590
+ * @returns A new nested instance with tree management capabilities.
4591
+ *
4592
+ * @remarks
4593
+ * **Key Differences from `createGroup`:**
4594
+ * - `register()` accepts `parentId` for establishing parent-child relationships
4595
+ * - `unregister()` accepts optional `cascade` parameter for cascading deletions
4596
+ * - Adds tree traversal methods: `getPath()`, `getAncestors()`, `getDescendants()`
4597
+ * - Adds computed properties: `roots`, `leaves`, `isLeaf()`, `getDepth()`
4598
+ * - Adds open state management: `open()`, `close()`, `flip()`, `opened()`
4599
+ *
4600
+ * @see https://0.vuetifyjs.com/composables/selection/use-nested
4601
+ *
4602
+ * @example
4603
+ * ```ts
4604
+ * import { createNested } from '@vuetify/v0'
4605
+ *
4606
+ * const tree = createNested()
4607
+ *
4608
+ * const root = tree.register({ id: 'root', value: 'Root' })
4609
+ * const child1 = tree.register({ id: 'child-1', value: 'Child 1', parentId: 'root' })
4610
+ * const child2 = tree.register({ id: 'child-2', value: 'Child 2', parentId: 'root' })
4611
+ *
4612
+ * console.log(tree.getPath('child-1')) // ['root', 'child-1']
4613
+ * console.log(tree.getDescendants('root')) // ['child-1', 'child-2']
4614
+ * console.log(tree.isLeaf('child-2')) // true
4615
+ *
4616
+ * tree.open('root')
4617
+ * console.log(tree.opened('root')) // true
4618
+ * ```
4619
+ */
4620
+ function createNested(_options = {}) {
4621
+ const { open: openMode = "multiple", openAll = false, reveal: revealOnOpen = false, selection: selectionMode = "cascade", openStrategy, ...options } = _options;
4622
+ const resolvedOpenStrategy = openStrategy ?? resolveOpenStrategy(openMode);
4623
+ const group = createGroup(options);
4624
+ const logger$1 = useLogger();
4625
+ const children = shallowReactive(/* @__PURE__ */ new Map());
4626
+ const parents = shallowReactive(/* @__PURE__ */ new Map());
4627
+ const openedIds = shallowReactive(/* @__PURE__ */ new Set());
4628
+ const openedItems = computed(() => {
4629
+ return new Set(Array.from(openedIds).map((id) => group.get(id)).filter((item) => !/* @__PURE__ */ isUndefined(item)));
4630
+ });
4631
+ const roots = computed(() => {
4632
+ return group.values().filter((item) => /* @__PURE__ */ isUndefined(parents.get(item.id)));
4633
+ });
4634
+ const leaves = computed(() => {
4635
+ return group.values().filter((item) => {
4636
+ const childList = children.get(item.id);
4637
+ return /* @__PURE__ */ isUndefined(childList) || childList.length === 0;
4638
+ });
4639
+ });
4640
+ function opened(id) {
4641
+ return openedIds.has(id);
4642
+ }
4643
+ function open(ids) {
4644
+ for (const id of toArray(ids)) {
4645
+ if (!group.has(id)) continue;
4646
+ if (revealOnOpen) {
4647
+ let parentId = parents.get(id);
4648
+ while (!/* @__PURE__ */ isUndefined(parentId)) {
4649
+ openedIds.add(parentId);
4650
+ parentId = parents.get(parentId);
4651
+ }
4652
+ }
4653
+ openedIds.add(id);
4654
+ resolvedOpenStrategy.onOpen?.(id, context);
4655
+ }
4656
+ }
4657
+ function close(ids) {
4658
+ for (const id of toArray(ids)) {
4659
+ if (!group.has(id)) continue;
4660
+ openedIds.delete(id);
4661
+ resolvedOpenStrategy.onClose?.(id, context);
4662
+ }
4663
+ }
4664
+ function flip(ids) {
4665
+ for (const id of toArray(ids)) {
4666
+ if (!group.has(id)) continue;
4667
+ if (opened(id)) close(id);
4668
+ else open(id);
4669
+ }
4670
+ }
4671
+ /**
4672
+ * Open node(s) and their immediate non-leaf children.
4673
+ * Useful for expanding a section with its immediate subcategories.
4674
+ */
4675
+ function unfold(ids) {
4676
+ for (const id of toArray(ids)) {
4677
+ if (!group.has(id)) continue;
4678
+ open(id);
4679
+ const childIds = children.get(id) ?? [];
4680
+ for (const childId of childIds) if (!isLeaf(childId)) open(childId);
4681
+ }
4682
+ }
4683
+ /**
4684
+ * Reveal a node by opening all its ancestors.
4685
+ * Makes the node visible in a collapsed tree without opening the node itself.
4686
+ */
4687
+ function reveal(ids) {
4688
+ for (const id of toArray(ids)) {
4689
+ if (!group.has(id)) continue;
4690
+ const ancestorIds = getAncestors(id);
4691
+ if (ancestorIds.length > 0) open(ancestorIds);
4692
+ }
4693
+ }
4694
+ /**
4695
+ * Fully expand a node and all its non-leaf descendants.
4696
+ * Opens the entire subtree rooted at the given node.
4697
+ */
4698
+ function expand(ids) {
4699
+ for (const id of toArray(ids)) {
4700
+ if (!group.has(id)) continue;
4701
+ if (!isLeaf(id)) open(id);
4702
+ for (const descendantId of getDescendants(id)) if (!isLeaf(descendantId)) open(descendantId);
4703
+ }
4704
+ }
4705
+ function expandAll() {
4706
+ for (const id of group.keys()) if (!isLeaf(id)) openedIds.add(id);
4707
+ }
4708
+ function collapseAll() {
4709
+ openedIds.clear();
4710
+ }
4711
+ function getPath(id) {
4712
+ const path = [];
4713
+ let currentId = id;
4714
+ while (!/* @__PURE__ */ isUndefined(currentId)) {
4715
+ path.unshift(currentId);
4716
+ currentId = parents.get(currentId);
4717
+ }
4718
+ return path;
4719
+ }
4720
+ function getAncestors(id) {
4721
+ return getPath(id).slice(0, -1);
4722
+ }
4723
+ function getDescendants(id) {
4724
+ const descendants = [];
4725
+ const queue = [...children.get(id) ?? []];
4726
+ let index = 0;
4727
+ while (index < queue.length) {
4728
+ const currentId = queue[index++];
4729
+ descendants.push(currentId);
4730
+ queue.push(...children.get(currentId) ?? []);
4731
+ }
4732
+ return descendants;
4733
+ }
4734
+ function isLeaf(id) {
4735
+ const childList = children.get(id);
4736
+ return /* @__PURE__ */ isUndefined(childList) || childList.length === 0;
4737
+ }
4738
+ function getDepth(id) {
4739
+ return getAncestors(id).length;
4740
+ }
4741
+ /**
4742
+ * Check if `ancestorId` is an ancestor of `descendantId`.
4743
+ * Returns false if either ID doesn't exist in the tree.
4744
+ */
4745
+ function isAncestorOf(ancestorId, descendantId) {
4746
+ if (!group.has(ancestorId) || !group.has(descendantId)) return false;
4747
+ if (ancestorId === descendantId) return false;
4748
+ let currentId = parents.get(descendantId);
4749
+ while (!/* @__PURE__ */ isUndefined(currentId)) {
4750
+ if (currentId === ancestorId) return true;
4751
+ currentId = parents.get(currentId);
4752
+ }
4753
+ return false;
4754
+ }
4755
+ /**
4756
+ * Check if `id` has `ancestorId` as an ancestor.
4757
+ * Semantic alias for isAncestorOf(ancestorId, id).
4758
+ */
4759
+ function hasAncestor(id, ancestorId) {
4760
+ return isAncestorOf(ancestorId, id);
4761
+ }
4762
+ /**
4763
+ * Get siblings of a node (including self).
4764
+ * For root nodes, returns all root IDs.
4765
+ */
4766
+ function siblings(id) {
4767
+ if (!group.has(id)) return [];
4768
+ const parentId = parents.get(id);
4769
+ if (/* @__PURE__ */ isUndefined(parentId)) return group.values().filter((item) => /* @__PURE__ */ isUndefined(parents.get(item.id))).map((item) => item.id);
4770
+ return children.get(parentId) ?? [];
4771
+ }
4772
+ /**
4773
+ * Get 1-indexed position among siblings (for aria-posinset).
4774
+ * Returns 0 if node not found.
4775
+ */
4776
+ function position(id) {
4777
+ const index = siblings(id).indexOf(id);
4778
+ return index === -1 ? 0 : index + 1;
4779
+ }
4780
+ function updateAncestors(id) {
4781
+ const ancestorIds = getAncestors(id).toReversed();
4782
+ for (const aid of ancestorIds) {
4783
+ const childIds = children.get(aid) ?? [];
4784
+ if (childIds.length === 0) continue;
4785
+ const allSelected = childIds.every((cid) => group.selected(cid));
4786
+ const someSelected = childIds.some((cid) => group.selected(cid) || group.mixed(cid));
4787
+ if (allSelected) {
4788
+ group.unmix(aid);
4789
+ group.select(aid);
4790
+ } else if (someSelected) {
4791
+ group.unselect(aid);
4792
+ group.mix(aid);
4793
+ } else {
4794
+ group.unmix(aid);
4795
+ group.unselect(aid);
4796
+ }
4797
+ }
4798
+ }
4799
+ function getLeafDescendants(id) {
4800
+ return getDescendants(id).filter((did) => isLeaf(did));
4801
+ }
4802
+ function select(ids) {
4803
+ for (const id of toArray(ids)) {
4804
+ if (!group.has(id)) continue;
4805
+ if (selectionMode === "independent") group.select(id);
4806
+ else if (selectionMode === "leaf") if (isLeaf(id)) group.select(id);
4807
+ else for (const lid of getLeafDescendants(id)) group.select(lid);
4808
+ else {
4809
+ group.unmix(id);
4810
+ group.select(id);
4811
+ for (const did of getDescendants(id)) {
4812
+ group.unmix(did);
4813
+ group.select(did);
4814
+ }
4815
+ updateAncestors(id);
4816
+ }
4817
+ }
4818
+ }
4819
+ function unselect(ids) {
4820
+ for (const id of toArray(ids)) {
4821
+ if (!group.has(id)) continue;
4822
+ if (selectionMode === "independent") group.unselect(id);
4823
+ else if (selectionMode === "leaf") if (isLeaf(id)) group.unselect(id);
4824
+ else for (const lid of getLeafDescendants(id)) group.unselect(lid);
4825
+ else {
4826
+ group.unmix(id);
4827
+ group.unselect(id);
4828
+ for (const did of getDescendants(id)) {
4829
+ group.unmix(did);
4830
+ group.unselect(did);
4831
+ }
4832
+ updateAncestors(id);
4833
+ }
4834
+ }
4835
+ }
4836
+ function toggle(ids) {
4837
+ for (const id of toArray(ids)) if (selectionMode === "independent") group.toggle(id);
4838
+ else if (selectionMode === "leaf") if (isLeaf(id)) group.toggle(id);
4839
+ else {
4840
+ const leafIds = getLeafDescendants(id);
4841
+ if (leafIds.every((lid) => group.selected(lid))) for (const lid of leafIds) group.unselect(lid);
4842
+ else for (const lid of leafIds) group.select(lid);
4843
+ }
4844
+ else if (group.selected(id) || group.mixed(id)) unselect(id);
4845
+ else select(id);
4846
+ }
4847
+ /**
4848
+ * Converts the tree to a flat array with parentId references.
4849
+ * Useful for serialization or sending to APIs/AI systems.
4850
+ */
4851
+ function toFlat() {
4852
+ return group.values().map((item) => ({
4853
+ id: item.id,
4854
+ parentId: parents.get(item.id),
4855
+ value: item.value
4856
+ }));
4857
+ }
4858
+ function register(registration = {}) {
4859
+ const id = registration.id ?? /* @__PURE__ */ useId$1();
4860
+ const parentId = registration.parentId;
4861
+ const nested = registration.children;
4862
+ if (!/* @__PURE__ */ isUndefined(parentId) && !group.has(parentId)) logger$1.warn(`Parent with id "${parentId}" does not exist. Registering "${id}" without parent.`);
4863
+ if (!/* @__PURE__ */ isUndefined(parentId) && group.has(parentId)) {
4864
+ parents.set(id, parentId);
4865
+ const list = children.get(parentId);
4866
+ if (list) list.push(id);
4867
+ else children.set(parentId, [id]);
4868
+ if (openAll) openedIds.add(parentId);
4869
+ } else parents.set(id, void 0);
4870
+ const { children: _, ...rest } = registration;
4871
+ const item = {
4872
+ ...rest,
4873
+ id,
4874
+ parentId: parents.get(id),
4875
+ isOpen: toRef(() => opened(id)),
4876
+ isLeaf: toRef(() => isLeaf(id)),
4877
+ depth: toRef(() => getDepth(id)),
4878
+ open: () => open(id),
4879
+ close: () => close(id),
4880
+ flip: () => flip(id),
4881
+ reveal: () => reveal(id),
4882
+ getPath: () => getPath(id),
4883
+ getAncestors: () => getAncestors(id),
4884
+ getDescendants: () => getDescendants(id),
4885
+ isAncestorOf: (descendantId) => isAncestorOf(id, descendantId),
4886
+ hasAncestor: (ancestorId) => hasAncestor(id, ancestorId),
4887
+ siblings: () => siblings(id),
4888
+ position: () => position(id)
4889
+ };
4890
+ const ticket = group.register(item);
4891
+ if (nested?.length) for (const child of nested) register({
4892
+ ...child,
4893
+ parentId: id
4894
+ });
4895
+ return ticket;
4896
+ }
4897
+ function unregister(id, cascade = false) {
4898
+ if (!group.has(id)) return;
4899
+ const parentId = parents.get(id);
4900
+ if (!/* @__PURE__ */ isUndefined(parentId)) {
4901
+ const siblings$1 = children.get(parentId);
4902
+ if (siblings$1) {
4903
+ const filtered = siblings$1.filter((sid) => sid !== id);
4904
+ if (filtered.length === 0) children.delete(parentId);
4905
+ else children.set(parentId, filtered);
4906
+ }
4907
+ }
4908
+ const list = children.get(id);
4909
+ if (list?.length) if (cascade) for (const did of getDescendants(id)) {
4910
+ parents.delete(did);
4911
+ children.delete(did);
4912
+ openedIds.delete(did);
4913
+ group.unregister(did);
4914
+ }
4915
+ else {
4916
+ for (const did of getDescendants(id)) openedIds.delete(did);
4917
+ for (const cid of list) parents.set(cid, void 0);
4918
+ }
4919
+ parents.delete(id);
4920
+ children.delete(id);
4921
+ openedIds.delete(id);
4922
+ group.unregister(id);
4923
+ }
4924
+ function offboard(ids, cascade = false) {
4925
+ for (const id of ids) unregister(id, cascade);
4926
+ }
4927
+ function onboard(registrations) {
4928
+ return registrations.map((registration) => register(registration));
4929
+ }
4930
+ function clear() {
4931
+ children.clear();
4932
+ parents.clear();
4933
+ openedIds.clear();
4934
+ group.reset();
4935
+ }
4936
+ function reset() {
4937
+ clear();
4938
+ }
4939
+ const context = {
4940
+ ...group,
4941
+ children,
4942
+ parents,
4943
+ openedIds,
4944
+ openedItems,
4945
+ roots,
4946
+ leaves,
4947
+ getPath,
4948
+ getAncestors,
4949
+ getDescendants,
4950
+ isLeaf,
4951
+ getDepth,
4952
+ isAncestorOf,
4953
+ hasAncestor,
4954
+ siblings,
4955
+ position,
4956
+ open,
4957
+ close,
4958
+ flip,
4959
+ opened,
4960
+ unfold,
4961
+ reveal,
4962
+ expand,
4963
+ expandAll,
4964
+ collapseAll,
4965
+ toFlat,
4966
+ openStrategy: resolvedOpenStrategy,
4967
+ select,
4968
+ unselect,
4969
+ toggle,
4970
+ register,
4971
+ unregister,
4972
+ offboard,
4973
+ onboard,
4974
+ clear,
4975
+ reset,
4976
+ get size() {
4977
+ return group.size;
4978
+ }
4979
+ };
4980
+ return context;
4981
+ }
4982
+ /**
4983
+ * Creates a new nested context with provide/inject pattern.
4984
+ *
4985
+ * @param options The options for the nested context.
4986
+ * @returns A trinity tuple [useNested, provideNested, defaultNested]
4987
+ *
4988
+ * @see https://0.vuetifyjs.com/composables/selection/use-nested
4989
+ *
4990
+ * @example
4991
+ * ```ts
4992
+ * import { createNestedContext } from '@vuetify/v0'
4993
+ *
4994
+ * export const [useTree, provideTree, tree] = createNestedContext()
4995
+ *
4996
+ * // In parent: provideTree()
4997
+ * // In child: const tree = useTree()
4998
+ * ```
4999
+ */
5000
+ function createNestedContext(_options = {}) {
5001
+ const { namespace = "v0:nested", ...options } = _options;
5002
+ const [useNestedContext, _provideNestedContext] = createContext(namespace);
5003
+ const context = createNested(options);
5004
+ function provideNestedContext(_context = context, app) {
5005
+ return _provideNestedContext(_context, app);
5006
+ }
5007
+ return createTrinity(useNestedContext, provideNestedContext, context);
5008
+ }
5009
+ /**
5010
+ * Returns the current nested instance from context.
5011
+ *
5012
+ * @param namespace The namespace for the nested context. Defaults to `'v0:nested'`.
5013
+ * @returns The current nested instance.
5014
+ *
5015
+ * @see https://0.vuetifyjs.com/composables/selection/use-nested
5016
+ */
5017
+ function useNested(namespace = "v0:nested") {
5018
+ return useContext(namespace);
5019
+ }
5020
+
5088
5021
  //#endregion
5089
5022
  //#region src/composables/useResizeObserver/index.ts
5090
5023
  /**
@@ -5146,12 +5079,13 @@ function useMutationObserver(target, callback, options = {}) {
5146
5079
  */
5147
5080
  function useResizeObserver(target, callback, options = {}) {
5148
5081
  const { isHydrated } = useHydration();
5082
+ const targetRef = toRef(target);
5149
5083
  const observer = shallowRef();
5150
5084
  const isPaused = shallowRef(false);
5151
5085
  const isActive = toRef(() => !!observer.value);
5152
5086
  function setup() {
5153
5087
  if (/* @__PURE__ */ isNull(observer.value)) return;
5154
- if (!isHydrated.value || !SUPPORTS_OBSERVER || !target.value || isPaused.value) return;
5088
+ if (!isHydrated.value || !SUPPORTS_OBSERVER || !targetRef.value || isPaused.value) return;
5155
5089
  observer.value = new ResizeObserver((entries) => {
5156
5090
  callback(entries.map((entry) => ({
5157
5091
  contentRect: {
@@ -5164,9 +5098,9 @@ function useResizeObserver(target, callback, options = {}) {
5164
5098
  })));
5165
5099
  if (options.once) stop();
5166
5100
  });
5167
- observer.value.observe(target.value, { box: options.box || "content-box" });
5101
+ observer.value.observe(targetRef.value, { box: options.box || "content-box" });
5168
5102
  if (options.immediate) {
5169
- const rect = target.value.getBoundingClientRect();
5103
+ const rect = targetRef.value.getBoundingClientRect();
5170
5104
  callback([{
5171
5105
  contentRect: {
5172
5106
  width: rect.width,
@@ -5174,17 +5108,17 @@ function useResizeObserver(target, callback, options = {}) {
5174
5108
  top: rect.top,
5175
5109
  left: rect.left
5176
5110
  },
5177
- target: target.value
5111
+ target: targetRef.value
5178
5112
  }]);
5179
5113
  }
5180
5114
  }
5181
- watch(() => target.value, (el, oldEl) => {
5115
+ watch(() => targetRef.value, (el, oldEl) => {
5182
5116
  if (oldEl) cleanup();
5183
5117
  if (isHydrated.value && el) setup();
5184
5118
  }, { immediate: true });
5185
5119
  if (!isHydrated.value) {
5186
5120
  const stopHydrationWatch = watch(() => isHydrated.value, (hydrated) => {
5187
- if (hydrated && target.value && !observer.value) {
5121
+ if (hydrated && targetRef.value && !observer.value) {
5188
5122
  setup();
5189
5123
  stopHydrationWatch();
5190
5124
  }
@@ -5941,7 +5875,7 @@ function createQueue(_options = {}) {
5941
5875
  }
5942
5876
  }
5943
5877
  function register(registration = {}) {
5944
- const id = registration.id ?? /* @__PURE__ */ genId();
5878
+ const id = registration.id ?? /* @__PURE__ */ useId$1();
5945
5879
  const timeout = Object.prototype.hasOwnProperty.call(registration, "timeout") ? registration.timeout : _timeout;
5946
5880
  const ticket = {
5947
5881
  ...registration,
@@ -7653,4 +7587,4 @@ function useClickOutside(target, handler, options = {}) {
7653
7587
  }
7654
7588
 
7655
7589
  //#endregion
7656
- export { useFilter as $, createContext as $t, PermissionAdapter as A, createHydrationPlugin as At, useMediaQuery as B, createSelectionContext as Bt, createQueue as C, createBreakpoints as Ct, createPermissionsContext as D, createFallbackHydration as Dt, createPermissions as E, useBreakpoints as Et, createOverflowContext as F, createGroupContext as Ft, useElementIntersection as G, createLoggerContext as Gt, usePrefersDark as H, createRegistry as Ht, useOverflow as I, useGroup as It, createForm as J, Vuetify0LoggerAdapter as Jt, useIntersectionObserver as K, createLoggerPlugin as Kt, useElementSize as L, toArray as Lt, createPaginationContext as M, toReactive as Mt, usePagination as N, useProxyModel as Nt, createPermissionsPlugin as O, createHydration as Ot, createOverflow as P, createGroup as Pt, createFilterContext as Q, createTrinity as Qt, useResizeObserver as R, useProxyRegistry as Rt, useStep as S, useSingle as St, useQueue as T, createBreakpointsPlugin as Tt, usePrefersReducedMotion as U, createRegistryContext as Ut, usePrefersContrast as V, useSelection as Vt, useLazy as W, createLogger as Wt, useForm as X, ConsolaLoggerAdapter as Xt, createFormContext as Y, PinoLoggerAdapter as Yt, createFilter as Z, createPlugin as Zt, createStoragePlugin as _, createTokens as _t, useVirtual as a, createDate as at, createStep as b, createSingle as bt, createTimelineContext as c, createDatePlugin as ct, createThemeContext as d, createLocale as dt, provideContext as en, useFilterContext as et, createThemePlugin as f, createLocaleContext as ft, createStorageContext as g, Vuetify0LocaleAdapter as gt, createStorage as h, useLocale as ht, useWindowEventListener as i, useFeatures as it, createPagination as j, useHydration as jt, usePermissions as k, createHydrationContext as kt, useTimeline as l, useDate as lt, Vuetify0ThemeAdapter as m, createLocalePlugin as mt, useDocumentEventListener as n, createFeaturesContext as nt, useToggleScope as o, createDateContext as ot, useTheme as p, createLocaleFallback as pt, useHotkey as q, useLogger as qt, useEventListener as r, createFeaturesPlugin as rt, createTimeline as s, createDateFallback as st, useClickOutside as t, useContext as tn, createFeatures as tt, createTheme as u, Vuetify0DateAdapter as ut, useStorage as v, createTokensContext as vt, createQueueContext as w, createBreakpointsContext as wt, createStepContext as x, createSingleContext as xt, MemoryAdapter as y, useTokens as yt, useMutationObserver as z, createSelection as zt };
7590
+ export { createForm as $, ConsolaLoggerAdapter as $t, PermissionAdapter as A, createFallbackHydration as At, createNestedContext as B, toArray as Bt, createQueue as C, createSingle as Ct, createPermissionsContext as D, createBreakpointsContext as Dt, createPermissions as E, createBreakpoints as Et, createOverflowContext as F, toReactive as Ft, useMediaQuery as G, createRegistry as Gt, multipleOpenStrategy as H, createSelection as Ht, useOverflow as I, useProxyModel as It, usePrefersReducedMotion as J, createLoggerContext as Jt, usePrefersContrast as K, createRegistryContext as Kt, useElementSize as L, createGroup as Lt, createPaginationContext as M, createHydrationContext as Mt, usePagination as N, createHydrationPlugin as Nt, createPermissionsPlugin as O, createBreakpointsPlugin as Ot, createOverflow as P, useHydration as Pt, useHotkey as Q, PinoLoggerAdapter as Qt, useResizeObserver as R, createGroupContext as Rt, useStep as S, useTokens as St, useQueue as T, useSingle as Tt, singleOpenStrategy as U, createSelectionContext as Ut, useNested as V, useProxyRegistry as Vt, useMutationObserver as W, useSelection as Wt, useElementIntersection as X, useLogger as Xt, useLazy as Y, createLoggerPlugin as Yt, useIntersectionObserver as Z, Vuetify0LoggerAdapter as Zt, createStoragePlugin as _, createLocalePlugin as _t, useVirtual as a, useFilterContext as at, createStep as b, createTokens as bt, createTimelineContext as c, createFeaturesPlugin as ct, createThemeContext as d, createDateContext as dt, createPlugin as en, createFormContext as et, createThemePlugin as f, createDatePlugin as ft, createStorageContext as g, createLocaleFallback as gt, createStorage as h, createLocaleContext as ht, useWindowEventListener as i, useContext as in, useFilter as it, createPagination as j, createHydration as jt, usePermissions as k, useBreakpoints as kt, useTimeline as l, useFeatures as lt, Vuetify0ThemeAdapter as m, createLocale as mt, useDocumentEventListener as n, createContext as nn, createFilter as nt, useToggleScope as o, createFeatures as ot, useTheme as p, useDate as pt, usePrefersDark as q, createLogger as qt, useEventListener as r, provideContext as rn, createFilterContext as rt, createTimeline as s, createFeaturesContext as st, useClickOutside as t, createTrinity as tn, useForm as tt, createTheme as u, createDate as ut, useStorage as v, useLocale as vt, createQueueContext as w, createSingleContext as wt, createStepContext as x, createTokensContext as xt, MemoryAdapter as y, Vuetify0LocaleAdapter as yt, createNested as z, useGroup as zt };