@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.
- package/dist/adapter-L4Php1_S.d.mts +97 -0
- package/dist/browser/index.js +1069 -809
- package/dist/components/index.d.mts +4 -4
- package/dist/components/index.mjs +6 -6
- package/dist/{components-BI9xdoz5.mjs → components-D_yAxHwn.mjs} +433 -113
- package/dist/composables/index.d.mts +5 -4
- package/dist/composables/index.mjs +4 -4
- package/dist/constants/index.d.mts +1 -1
- package/dist/constants/index.mjs +3 -3
- package/dist/date/index.d.mts +124 -0
- package/dist/date/index.mjs +7514 -0
- package/dist/{globals-WKdFmgwy.mjs → globals-BhNI7no7.mjs} +1 -1
- package/dist/{index-Bby5ljat.d.mts → index-DknfL2GU.d.mts} +1 -1
- package/dist/{index-_y91DmIS.d.mts → index-OghXharF.d.mts} +721 -359
- package/dist/{index-DYSwiS9k.d.mts → index-ZW2YLa57.d.mts} +21 -2
- package/dist/{index-rcTqb9U3.d.mts → index-isYKpbs6.d.mts} +426 -266
- package/dist/{index-C8YcMooA.d.mts → index-kvJsAOSg.d.mts} +13 -9
- package/dist/index.d.mts +8 -7
- package/dist/index.mjs +7 -7
- package/dist/json/attributes.json +100 -0
- package/dist/json/importMap.json +64 -0
- package/dist/json/tags.json +45 -0
- package/dist/json/web-types.json +1303 -392
- package/dist/types/index.d.mts +2 -2
- package/dist/{useClickOutside-B47X8X6-.mjs → useClickOutside-w-Y2QxHh.mjs} +591 -657
- package/dist/utilities/index.d.mts +3 -3
- package/dist/utilities/index.mjs +2 -2
- package/dist/{utilities-9i1hJnMd.mjs → utilities-B58TiS_S.mjs} +41 -34
- package/package.json +3 -2
- /package/dist/{constants-3l8TGg5J.mjs → constants-DHKqjdjH.mjs} +0 -0
- /package/dist/{htmlElements-CXObxj0V.mjs → htmlElements-DO9n35bD.mjs} +0 -0
- /package/dist/{index-DMQJJUrv.d.mts → index-cPmI99rd.d.mts} +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { _ as
|
|
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-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
* <
|
|
1922
|
-
* <
|
|
1923
|
-
* </
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
3452
|
-
* const today = adapter.date() // Temporal.PlainDateTime
|
|
2885
|
+
* import { Vuetify0DateAdapter } from '@vuetify/v0/date'
|
|
3453
2886
|
*
|
|
3454
|
-
*
|
|
3455
|
-
* const
|
|
2887
|
+
* const { adapter } = createDate({ adapter: new Vuetify0DateAdapter() })
|
|
2888
|
+
* const today = adapter.date()
|
|
3456
2889
|
*
|
|
3457
|
-
* // With
|
|
3458
|
-
* const { adapter } = createDate({
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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
|
-
*
|
|
3545
|
-
* app.use(createDatePlugin())
|
|
2966
|
+
* import { Vuetify0DateAdapter } from '@vuetify/v0/date'
|
|
3546
2967
|
*
|
|
3547
|
-
*
|
|
3548
|
-
* app.use(createDatePlugin({
|
|
2968
|
+
* const app = createApp(App)
|
|
2969
|
+
* app.use(createDatePlugin({ adapter: new Vuetify0DateAdapter() }))
|
|
3549
2970
|
*
|
|
3550
|
-
* // With
|
|
3551
|
-
* app.use(createDatePlugin({
|
|
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
|
-
*
|
|
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
|
-
|
|
3591
|
-
|
|
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 =
|
|
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 || !
|
|
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(
|
|
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:
|
|
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(() =>
|
|
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 &&
|
|
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 || !
|
|
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(
|
|
5101
|
+
observer.value.observe(targetRef.value, { box: options.box || "content-box" });
|
|
5168
5102
|
if (options.immediate) {
|
|
5169
|
-
const rect =
|
|
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:
|
|
5111
|
+
target: targetRef.value
|
|
5178
5112
|
}]);
|
|
5179
5113
|
}
|
|
5180
5114
|
}
|
|
5181
|
-
watch(() =>
|
|
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 &&
|
|
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__ */
|
|
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 {
|
|
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 };
|