@vuetify/v0 0.0.13 → 0.0.15
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/browser/index.js +2439 -820
- package/dist/components/index.d.mts +3 -3
- package/dist/components/index.mjs +5 -5
- package/dist/{components-z-JwOlZj.mjs → components-Cf1h368z.mjs} +570 -44
- package/dist/composables/index.d.mts +2 -3
- package/dist/composables/index.mjs +4 -4
- package/dist/{composables-BbLwk7s2.mjs → composables-CrW3IMUM.mjs} +1813 -792
- package/dist/constants/index.d.mts +1 -1
- package/dist/constants/index.mjs +1 -1
- package/dist/{globals-Dh0BVnN0.mjs → globals-CqryJ9G3.mjs} +1 -1
- package/dist/index-BPAr2atm.d.mts +70 -0
- package/dist/index-CQcSUYj_.d.mts +1120 -0
- package/dist/{index-CQjOW_w5.d.mts → index-CkmnMjE3.d.mts} +1754 -162
- package/dist/index.d.mts +5 -6
- package/dist/index.mjs +5 -5
- package/dist/utilities/index.d.mts +2 -2
- package/dist/utilities/index.mjs +2 -2
- package/dist/utilities-C6o-keMm.mjs +135 -0
- package/package.json +11 -13
- package/dist/index-CHMeCyP_.d.mts +0 -815
- package/dist/index-CSdGoUCI.d.mts +0 -17
- package/dist/index-D-EP6KrS.d.mts +0 -812
- package/dist/utilities-C26nB74O.mjs +0 -63
- /package/dist/{index-8AIxAM2d.d.mts → index-BmxOG13-.d.mts} +0 -0
package/dist/browser/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, createBlock, createCommentVNode, createPropsRestProxy, defineComponent,
|
|
1
|
+
import { computed, createBlock, createCommentVNode, createPropsRestProxy, createTextVNode, defineComponent, effectScope, getCurrentInstance, guardReactiveProps, inject, isRef, mergeModels, mergeProps, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, openBlock, provide, reactive, readonly, ref, renderSlot, resolveDynamicComponent, shallowReactive, shallowReadonly, shallowRef, toDisplayString, toRef, toValue, unref, useAttrs, useId, useModel, useTemplateRef, vShow, watch, withCtx, withDirectives } from "vue";
|
|
2
2
|
|
|
3
3
|
//#region src/constants/htmlElements.ts
|
|
4
4
|
const selfClosingTags = [
|
|
@@ -119,6 +119,10 @@ function isPrimitive(item) {
|
|
|
119
119
|
return typeof item === "string" || typeof item === "number" || typeof item === "boolean";
|
|
120
120
|
}
|
|
121
121
|
/* @__NO_SIDE_EFFECTS__ */
|
|
122
|
+
function isNaN(item) {
|
|
123
|
+
return /* @__PURE__ */ isNumber(item) && Number.isNaN(item);
|
|
124
|
+
}
|
|
125
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
122
126
|
function mergeDeep(target, ...sources) {
|
|
123
127
|
if (sources.length === 0) return target;
|
|
124
128
|
const source = sources.shift();
|
|
@@ -137,10 +141,78 @@ function mergeDeep(target, ...sources) {
|
|
|
137
141
|
function genId() {
|
|
138
142
|
return Math.random().toString(36).slice(2, 9);
|
|
139
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Clamps a value between a minimum and maximum
|
|
146
|
+
*
|
|
147
|
+
* @param value The value to clamp
|
|
148
|
+
* @param min The minimum value (default: 0)
|
|
149
|
+
* @param max The maximum value (default: 1)
|
|
150
|
+
* @returns The clamped value
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* clamp(5, 0, 10) // 5
|
|
155
|
+
* clamp(-5, 0, 10) // 0
|
|
156
|
+
* clamp(15, 0, 10) // 10
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
160
|
+
function clamp(value, min = 0, max = 1) {
|
|
161
|
+
return Math.max(min, Math.min(max, value));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Creates an array of sequential numbers
|
|
165
|
+
*
|
|
166
|
+
* @param length The length of the array to create
|
|
167
|
+
* @param start The starting index (default: 0)
|
|
168
|
+
* @returns An array of sequential numbers
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* range(3) // [0, 1, 2]
|
|
173
|
+
* range(3, 1) // [1, 2, 3]
|
|
174
|
+
* range(5, 10) // [10, 11, 12, 13, 14]
|
|
175
|
+
* range(0) // []
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
179
|
+
function range(length, start = 0) {
|
|
180
|
+
return Array.from({ length }, (_, index) => start + index);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Debounces a function call by the specified delay
|
|
184
|
+
*
|
|
185
|
+
* @param fn The function to debounce
|
|
186
|
+
* @param delay The delay in milliseconds
|
|
187
|
+
* @returns A debounced function with clear and immediate methods
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* const debouncedFn = debounce(() => console.log('called'), 500)
|
|
192
|
+
* debouncedFn() // Will call after 500ms
|
|
193
|
+
* debouncedFn.clear() // Cancel pending call
|
|
194
|
+
* debouncedFn.immediate() // Call immediately
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
function debounce(fn, delay) {
|
|
198
|
+
let timeoutId;
|
|
199
|
+
function debounced(...args) {
|
|
200
|
+
if (!/* @__PURE__ */ isUndefined(timeoutId)) clearTimeout(timeoutId);
|
|
201
|
+
timeoutId = setTimeout(() => fn(...args), delay);
|
|
202
|
+
}
|
|
203
|
+
debounced.clear = () => {
|
|
204
|
+
if (!/* @__PURE__ */ isUndefined(timeoutId)) clearTimeout(timeoutId);
|
|
205
|
+
};
|
|
206
|
+
debounced.immediate = (...args) => {
|
|
207
|
+
debounced.clear();
|
|
208
|
+
fn(...args);
|
|
209
|
+
};
|
|
210
|
+
return debounced;
|
|
211
|
+
}
|
|
140
212
|
|
|
141
213
|
//#endregion
|
|
142
214
|
//#region src/components/Atom/Atom.vue
|
|
143
|
-
const _sfc_main$
|
|
215
|
+
const _sfc_main$25 = /* @__PURE__ */ defineComponent({
|
|
144
216
|
name: "Atom",
|
|
145
217
|
__name: "Atom",
|
|
146
218
|
props: {
|
|
@@ -171,7 +243,7 @@ const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
|
171
243
|
};
|
|
172
244
|
}
|
|
173
245
|
});
|
|
174
|
-
var Atom_default = _sfc_main$
|
|
246
|
+
var Atom_default = _sfc_main$25;
|
|
175
247
|
|
|
176
248
|
//#endregion
|
|
177
249
|
//#region src/composables/createContext/index.ts
|
|
@@ -210,7 +282,7 @@ var Atom_default = _sfc_main$18;
|
|
|
210
282
|
*/
|
|
211
283
|
function useContext(key, defaultValue) {
|
|
212
284
|
const context = inject(key, defaultValue);
|
|
213
|
-
if (
|
|
285
|
+
if (/* @__PURE__ */ isUndefined(context)) throw new Error(`Context "${String(key)}" not found. Ensure it's provided by an ancestor.`);
|
|
214
286
|
return context;
|
|
215
287
|
}
|
|
216
288
|
/**
|
|
@@ -528,6 +600,95 @@ function toReactive(objectRef) {
|
|
|
528
600
|
}));
|
|
529
601
|
}
|
|
530
602
|
|
|
603
|
+
//#endregion
|
|
604
|
+
//#region src/composables/useEventListener/index.ts
|
|
605
|
+
/**
|
|
606
|
+
* @module useEventListener
|
|
607
|
+
*
|
|
608
|
+
* @remarks
|
|
609
|
+
* Event listener composable with automatic cleanup on scope disposal.
|
|
610
|
+
*
|
|
611
|
+
* Key features:
|
|
612
|
+
* - Supports Window, Document, and HTMLElement targets
|
|
613
|
+
* - Reactive targets, events, and listeners
|
|
614
|
+
* - Event options support (capture, passive, once)
|
|
615
|
+
* - Automatic removeEventListener on unmount
|
|
616
|
+
* - Multiple overloads for type safety
|
|
617
|
+
*
|
|
618
|
+
* Perfect for safely managing event listeners in Vue components.
|
|
619
|
+
*/
|
|
620
|
+
/**
|
|
621
|
+
* Attaches an event listener to a target.
|
|
622
|
+
*
|
|
623
|
+
* @param target The target to attach the event listener to.
|
|
624
|
+
* @param event The event to listen for.
|
|
625
|
+
* @param listener The event listener.
|
|
626
|
+
* @param options The event listener options.
|
|
627
|
+
* @returns A function to remove the event listener.
|
|
628
|
+
*
|
|
629
|
+
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
630
|
+
*/
|
|
631
|
+
function useEventListener(target, event, listener, options) {
|
|
632
|
+
const cleanups = [];
|
|
633
|
+
function cleanup() {
|
|
634
|
+
for (const fn of cleanups) fn();
|
|
635
|
+
cleanups.length = 0;
|
|
636
|
+
}
|
|
637
|
+
function register(el, event$1, listener$1, options$1) {
|
|
638
|
+
el.addEventListener(event$1, listener$1, options$1);
|
|
639
|
+
return () => el.removeEventListener(event$1, listener$1, options$1);
|
|
640
|
+
}
|
|
641
|
+
const stopWatcher = watch(() => [
|
|
642
|
+
toValue(target),
|
|
643
|
+
toValue(event),
|
|
644
|
+
unref(listener),
|
|
645
|
+
toValue(options)
|
|
646
|
+
], ([el, events, listeners, opts]) => {
|
|
647
|
+
cleanup();
|
|
648
|
+
if (!el) return;
|
|
649
|
+
const eventList = toArray(events);
|
|
650
|
+
const listenerList = toArray(listeners);
|
|
651
|
+
for (const event$1 of eventList) for (const listenerFn of listenerList) cleanups.push(register(el, event$1, listenerFn, opts));
|
|
652
|
+
}, {
|
|
653
|
+
immediate: true,
|
|
654
|
+
flush: "post"
|
|
655
|
+
});
|
|
656
|
+
function stop() {
|
|
657
|
+
stopWatcher();
|
|
658
|
+
cleanup();
|
|
659
|
+
}
|
|
660
|
+
onScopeDispose(stop, true);
|
|
661
|
+
return stop;
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Attaches an event listener to the window.
|
|
665
|
+
*
|
|
666
|
+
* @param event The event to listen for.
|
|
667
|
+
* @param listener The event listener.
|
|
668
|
+
* @param options The event listener options.
|
|
669
|
+
* @template E The event type.
|
|
670
|
+
* @returns A function to remove the event listener.
|
|
671
|
+
*
|
|
672
|
+
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
673
|
+
*/
|
|
674
|
+
function useWindowEventListener(event, listener, options) {
|
|
675
|
+
return useEventListener(window, event, listener, options);
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Attaches an event listener to the document.
|
|
679
|
+
*
|
|
680
|
+
* @param event The event to listen for.
|
|
681
|
+
* @param listener The event listener.
|
|
682
|
+
* @param options The event listener options.
|
|
683
|
+
* @template E The event type.
|
|
684
|
+
* @returns A function to remove the event listener.
|
|
685
|
+
*
|
|
686
|
+
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
687
|
+
*/
|
|
688
|
+
function useDocumentEventListener(event, listener, options) {
|
|
689
|
+
return useEventListener(document, event, listener, options);
|
|
690
|
+
}
|
|
691
|
+
|
|
531
692
|
//#endregion
|
|
532
693
|
//#region src/composables/useHydration/index.ts
|
|
533
694
|
/**
|
|
@@ -574,6 +735,12 @@ function createHydration() {
|
|
|
574
735
|
hydrate
|
|
575
736
|
};
|
|
576
737
|
}
|
|
738
|
+
function createFallbackHydration() {
|
|
739
|
+
return {
|
|
740
|
+
isHydrated: shallowReadonly(shallowRef(true)),
|
|
741
|
+
hydrate: () => {}
|
|
742
|
+
};
|
|
743
|
+
}
|
|
577
744
|
/**
|
|
578
745
|
* Creates a new hydration context trinity.
|
|
579
746
|
*
|
|
@@ -666,7 +833,13 @@ function createHydrationPlugin(_options = {}) {
|
|
|
666
833
|
* ```
|
|
667
834
|
*/
|
|
668
835
|
function useHydration(namespace = "v0:hydration") {
|
|
669
|
-
|
|
836
|
+
const fallback = createFallbackHydration();
|
|
837
|
+
if (!getCurrentInstance()) return fallback;
|
|
838
|
+
try {
|
|
839
|
+
return useContext(namespace, fallback);
|
|
840
|
+
} catch {
|
|
841
|
+
return fallback;
|
|
842
|
+
}
|
|
670
843
|
}
|
|
671
844
|
|
|
672
845
|
//#endregion
|
|
@@ -677,7 +850,7 @@ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && "matchMedia" in window && typeof wind
|
|
|
677
850
|
const SUPPORTS_OBSERVER = IN_BROWSER && "ResizeObserver" in window;
|
|
678
851
|
const SUPPORTS_INTERSECTION_OBSERVER = IN_BROWSER && "IntersectionObserver" in window;
|
|
679
852
|
const SUPPORTS_MUTATION_OBSERVER = IN_BROWSER && "MutationObserver" in window;
|
|
680
|
-
const version = "0.0.
|
|
853
|
+
const version = "0.0.15";
|
|
681
854
|
const __LOGGER_ENABLED__ = false;
|
|
682
855
|
|
|
683
856
|
//#endregion
|
|
@@ -908,9 +1081,9 @@ function createBreakpointsPlugin(_options = {}) {
|
|
|
908
1081
|
const unwatch = watch(hydration.isHydrated, (hydrated) => {
|
|
909
1082
|
if (hydrated) listener();
|
|
910
1083
|
}, { immediate: true });
|
|
911
|
-
|
|
1084
|
+
const cleanup = useWindowEventListener("resize", listener, { passive: true });
|
|
912
1085
|
onScopeDispose(() => {
|
|
913
|
-
|
|
1086
|
+
cleanup();
|
|
914
1087
|
unwatch();
|
|
915
1088
|
}, true);
|
|
916
1089
|
} });
|
|
@@ -945,95 +1118,6 @@ function useBreakpoints(namespace = "v0:breakpoints") {
|
|
|
945
1118
|
return useContext(namespace);
|
|
946
1119
|
}
|
|
947
1120
|
|
|
948
|
-
//#endregion
|
|
949
|
-
//#region src/composables/useEventListener/index.ts
|
|
950
|
-
/**
|
|
951
|
-
* @module useEventListener
|
|
952
|
-
*
|
|
953
|
-
* @remarks
|
|
954
|
-
* Event listener composable with automatic cleanup on scope disposal.
|
|
955
|
-
*
|
|
956
|
-
* Key features:
|
|
957
|
-
* - Supports Window, Document, and HTMLElement targets
|
|
958
|
-
* - Reactive targets, events, and listeners
|
|
959
|
-
* - Event options support (capture, passive, once)
|
|
960
|
-
* - Automatic removeEventListener on unmount
|
|
961
|
-
* - Multiple overloads for type safety
|
|
962
|
-
*
|
|
963
|
-
* Perfect for safely managing event listeners in Vue components.
|
|
964
|
-
*/
|
|
965
|
-
/**
|
|
966
|
-
* Attaches an event listener to a target.
|
|
967
|
-
*
|
|
968
|
-
* @param target The target to attach the event listener to.
|
|
969
|
-
* @param event The event to listen for.
|
|
970
|
-
* @param listener The event listener.
|
|
971
|
-
* @param options The event listener options.
|
|
972
|
-
* @returns A function to remove the event listener.
|
|
973
|
-
*
|
|
974
|
-
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
975
|
-
*/
|
|
976
|
-
function useEventListener(target, event, listener, options) {
|
|
977
|
-
const cleanups = [];
|
|
978
|
-
function cleanup() {
|
|
979
|
-
for (const fn of cleanups) fn();
|
|
980
|
-
cleanups.length = 0;
|
|
981
|
-
}
|
|
982
|
-
function register(el, event$1, listener$1, options$1) {
|
|
983
|
-
el.addEventListener(event$1, listener$1, options$1);
|
|
984
|
-
return () => el.removeEventListener(event$1, listener$1, options$1);
|
|
985
|
-
}
|
|
986
|
-
const stopWatcher = watch(() => [
|
|
987
|
-
toValue(target),
|
|
988
|
-
toValue(event),
|
|
989
|
-
unref(listener),
|
|
990
|
-
toValue(options)
|
|
991
|
-
], ([el, events, listeners, opts]) => {
|
|
992
|
-
cleanup();
|
|
993
|
-
if (!el) return;
|
|
994
|
-
const eventList = toArray(events);
|
|
995
|
-
const listenerList = toArray(listeners);
|
|
996
|
-
for (const event$1 of eventList) for (const listenerFn of listenerList) cleanups.push(register(el, event$1, listenerFn, opts));
|
|
997
|
-
}, {
|
|
998
|
-
immediate: true,
|
|
999
|
-
flush: "post"
|
|
1000
|
-
});
|
|
1001
|
-
function stop() {
|
|
1002
|
-
stopWatcher();
|
|
1003
|
-
cleanup();
|
|
1004
|
-
}
|
|
1005
|
-
onScopeDispose(stop, true);
|
|
1006
|
-
return stop;
|
|
1007
|
-
}
|
|
1008
|
-
/**
|
|
1009
|
-
* Attaches an event listener to the window.
|
|
1010
|
-
*
|
|
1011
|
-
* @param event The event to listen for.
|
|
1012
|
-
* @param listener The event listener.
|
|
1013
|
-
* @param options The event listener options.
|
|
1014
|
-
* @template E The event type.
|
|
1015
|
-
* @returns A function to remove the event listener.
|
|
1016
|
-
*
|
|
1017
|
-
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
1018
|
-
*/
|
|
1019
|
-
function useWindowEventListener(event, listener, options) {
|
|
1020
|
-
return useEventListener(window, event, listener, options);
|
|
1021
|
-
}
|
|
1022
|
-
/**
|
|
1023
|
-
* Attaches an event listener to the document.
|
|
1024
|
-
*
|
|
1025
|
-
* @param event The event to listen for.
|
|
1026
|
-
* @param listener The event listener.
|
|
1027
|
-
* @param options The event listener options.
|
|
1028
|
-
* @template E The event type.
|
|
1029
|
-
* @returns A function to remove the event listener.
|
|
1030
|
-
*
|
|
1031
|
-
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
1032
|
-
*/
|
|
1033
|
-
function useDocumentEventListener(event, listener, options) {
|
|
1034
|
-
return useEventListener(document, event, listener, options);
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
1121
|
//#endregion
|
|
1038
1122
|
//#region src/composables/useLogger/adapters/consola.ts
|
|
1039
1123
|
var ConsolaLoggerAdapter = class {
|
|
@@ -1454,6 +1538,9 @@ function useRegistry(options) {
|
|
|
1454
1538
|
const cache = /* @__PURE__ */ new Map();
|
|
1455
1539
|
const listeners = /* @__PURE__ */ new Map();
|
|
1456
1540
|
const events = options?.events ?? false;
|
|
1541
|
+
let indexDependentCount = 0;
|
|
1542
|
+
let needsReindex = false;
|
|
1543
|
+
let minDirtyIndex = Infinity;
|
|
1457
1544
|
function emit(event, data = void 0) {
|
|
1458
1545
|
if (!events) return;
|
|
1459
1546
|
const cbs = listeners.get(event);
|
|
@@ -1488,13 +1575,15 @@ function useRegistry(options) {
|
|
|
1488
1575
|
let value = existing.value;
|
|
1489
1576
|
let valueIsIndex = existing.valueIsIndex;
|
|
1490
1577
|
if (hasValue) {
|
|
1491
|
-
if (patch.value
|
|
1578
|
+
if (/* @__PURE__ */ isUndefined(patch.value)) {
|
|
1492
1579
|
value = existing.index;
|
|
1493
1580
|
valueIsIndex = true;
|
|
1494
1581
|
} else {
|
|
1495
1582
|
value = patch.value;
|
|
1496
1583
|
valueIsIndex = false;
|
|
1497
1584
|
}
|
|
1585
|
+
if (valueIsIndex !== existing.valueIsIndex) if (valueIsIndex) indexDependentCount++;
|
|
1586
|
+
else indexDependentCount--;
|
|
1498
1587
|
if (!Object.is(value, existing.value)) {
|
|
1499
1588
|
unassign(existing.value, id);
|
|
1500
1589
|
assign(value, id);
|
|
@@ -1514,9 +1603,11 @@ function useRegistry(options) {
|
|
|
1514
1603
|
return updated;
|
|
1515
1604
|
}
|
|
1516
1605
|
function browse(value) {
|
|
1606
|
+
if (indexDependentCount > 0 && needsReindex) reindex();
|
|
1517
1607
|
return catalog.get(value);
|
|
1518
1608
|
}
|
|
1519
1609
|
function lookup(index) {
|
|
1610
|
+
if (needsReindex) reindex();
|
|
1520
1611
|
return directory.get(index);
|
|
1521
1612
|
}
|
|
1522
1613
|
function has(id) {
|
|
@@ -1566,25 +1657,39 @@ function useRegistry(options) {
|
|
|
1566
1657
|
if (catalog.size > 0) catalog.clear();
|
|
1567
1658
|
if (directory.size > 0) directory.clear();
|
|
1568
1659
|
invalidate();
|
|
1660
|
+
indexDependentCount = 0;
|
|
1661
|
+
needsReindex = false;
|
|
1662
|
+
minDirtyIndex = Infinity;
|
|
1569
1663
|
emit("clear:registry");
|
|
1570
1664
|
}
|
|
1571
1665
|
function invalidate() {
|
|
1572
1666
|
if (cache.size > 0) cache.clear();
|
|
1573
1667
|
}
|
|
1574
1668
|
function reindex() {
|
|
1575
|
-
|
|
1576
|
-
if (
|
|
1669
|
+
const startIndex = minDirtyIndex === Infinity ? 0 : minDirtyIndex;
|
|
1670
|
+
if (startIndex === 0) {
|
|
1671
|
+
if (catalog.size > 0) catalog.clear();
|
|
1672
|
+
if (directory.size > 0) directory.clear();
|
|
1673
|
+
}
|
|
1577
1674
|
invalidate();
|
|
1578
1675
|
let index = 0;
|
|
1579
|
-
for (const ticket of values()) {
|
|
1580
|
-
if (
|
|
1581
|
-
|
|
1582
|
-
|
|
1676
|
+
for (const ticket of collection.values()) {
|
|
1677
|
+
if (index < startIndex) {
|
|
1678
|
+
index++;
|
|
1679
|
+
continue;
|
|
1583
1680
|
}
|
|
1681
|
+
if (startIndex > 0) directory.delete(ticket.index);
|
|
1682
|
+
if (ticket.valueIsIndex) {
|
|
1683
|
+
if (startIndex > 0) unassign(ticket.value, ticket.id);
|
|
1684
|
+
ticket.value = index;
|
|
1685
|
+
assign(ticket.value, ticket.id);
|
|
1686
|
+
} else if (startIndex === 0) assign(ticket.value, ticket.id);
|
|
1687
|
+
ticket.index = index;
|
|
1584
1688
|
directory.set(index, ticket.id);
|
|
1585
|
-
assign(ticket.value, ticket.id);
|
|
1586
1689
|
index++;
|
|
1587
1690
|
}
|
|
1691
|
+
needsReindex = false;
|
|
1692
|
+
minDirtyIndex = Infinity;
|
|
1588
1693
|
emit("reindex:registry");
|
|
1589
1694
|
}
|
|
1590
1695
|
function register(registration = {}) {
|
|
@@ -1598,6 +1703,7 @@ function useRegistry(options) {
|
|
|
1598
1703
|
const index = registration.index ?? size;
|
|
1599
1704
|
const value = valueIsUndefined ? index : registration.value;
|
|
1600
1705
|
const valueIsIndex = valueIsUndefined;
|
|
1706
|
+
if (valueIsIndex) indexDependentCount++;
|
|
1601
1707
|
const ticket = {
|
|
1602
1708
|
...registration,
|
|
1603
1709
|
id,
|
|
@@ -1615,15 +1721,40 @@ function useRegistry(options) {
|
|
|
1615
1721
|
function unregister(id) {
|
|
1616
1722
|
const ticket = collection.get(id);
|
|
1617
1723
|
if (!ticket) return;
|
|
1724
|
+
if (ticket.valueIsIndex) indexDependentCount--;
|
|
1618
1725
|
collection.delete(ticket.id);
|
|
1619
1726
|
directory.delete(ticket.index);
|
|
1620
1727
|
unassign(ticket.value, ticket.id);
|
|
1621
1728
|
invalidate();
|
|
1622
1729
|
emit("unregister:ticket", ticket);
|
|
1623
|
-
|
|
1730
|
+
if (indexDependentCount > 0 && ticket.index < collection.size) {
|
|
1731
|
+
minDirtyIndex = Math.min(minDirtyIndex, ticket.index);
|
|
1732
|
+
reindex();
|
|
1733
|
+
} else {
|
|
1734
|
+
minDirtyIndex = Math.min(minDirtyIndex, ticket.index);
|
|
1735
|
+
needsReindex = true;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
function offboard(ids) {
|
|
1739
|
+
const removed = [];
|
|
1740
|
+
for (const id of ids) {
|
|
1741
|
+
const ticket = collection.get(id);
|
|
1742
|
+
if (!ticket) continue;
|
|
1743
|
+
if (ticket.valueIsIndex) indexDependentCount--;
|
|
1744
|
+
minDirtyIndex = Math.min(minDirtyIndex, ticket.index);
|
|
1745
|
+
collection.delete(ticket.id);
|
|
1746
|
+
directory.delete(ticket.index);
|
|
1747
|
+
unassign(ticket.value, ticket.id);
|
|
1748
|
+
removed.push(ticket);
|
|
1749
|
+
}
|
|
1750
|
+
if (removed.length === 0) return;
|
|
1751
|
+
invalidate();
|
|
1752
|
+
if (events) for (const ticket of removed) emit("unregister:ticket", ticket);
|
|
1753
|
+
needsReindex = true;
|
|
1624
1754
|
}
|
|
1625
1755
|
function seek(direction = "first", from, predicate) {
|
|
1626
1756
|
if (collection.size === 0) return void 0;
|
|
1757
|
+
if (needsReindex) reindex();
|
|
1627
1758
|
const tickets = values();
|
|
1628
1759
|
const index = /* @__PURE__ */ isUndefined(from) ? void 0 : Math.max(0, Math.min(from, tickets.length - 1));
|
|
1629
1760
|
if (direction === "last") {
|
|
@@ -1660,8 +1791,9 @@ function useRegistry(options) {
|
|
|
1660
1791
|
reindex,
|
|
1661
1792
|
seek,
|
|
1662
1793
|
onboard(registrations) {
|
|
1663
|
-
return registrations.map((registration) =>
|
|
1794
|
+
return registrations.map((registration) => register(registration));
|
|
1664
1795
|
},
|
|
1796
|
+
offboard,
|
|
1665
1797
|
get size() {
|
|
1666
1798
|
return collection.size;
|
|
1667
1799
|
}
|
|
@@ -1682,7 +1814,11 @@ function useRegistry(options) {
|
|
|
1682
1814
|
* ```ts
|
|
1683
1815
|
* import { createRegistryContext } from '@vuetify/v0'
|
|
1684
1816
|
*
|
|
1685
|
-
*
|
|
1817
|
+
* // With default namespace 'v0:registry'
|
|
1818
|
+
* export const [useItems, provideItems, items] = createRegistryContext()
|
|
1819
|
+
*
|
|
1820
|
+
* // Or with custom namespace
|
|
1821
|
+
* export const [useItems, provideItems, items] = createRegistryContext({ namespace: 'my-items' })
|
|
1686
1822
|
*
|
|
1687
1823
|
* // In a parent component:
|
|
1688
1824
|
* provideItems()
|
|
@@ -1692,8 +1828,8 @@ function useRegistry(options) {
|
|
|
1692
1828
|
* items.register({ id: 'item-1', value: 'Value 1' })
|
|
1693
1829
|
* ```
|
|
1694
1830
|
*/
|
|
1695
|
-
function createRegistryContext(_options) {
|
|
1696
|
-
const { namespace,...options } = _options;
|
|
1831
|
+
function createRegistryContext(_options = {}) {
|
|
1832
|
+
const { namespace = "v0:registry",...options } = _options;
|
|
1697
1833
|
const [useRegistryContext, _provideRegistryContext] = createContext(namespace);
|
|
1698
1834
|
const context = useRegistry(options);
|
|
1699
1835
|
function provideRegistryContext(_context = context, app) {
|
|
@@ -1804,12 +1940,12 @@ function createSelection(_options = {}) {
|
|
|
1804
1940
|
const id = registration.id ?? /* @__PURE__ */ genId();
|
|
1805
1941
|
const item = {
|
|
1806
1942
|
disabled: false,
|
|
1807
|
-
...registration,
|
|
1808
|
-
id,
|
|
1809
|
-
isSelected: toRef(() => selected(id)),
|
|
1810
1943
|
select: () => select(id),
|
|
1811
1944
|
unselect: () => unselect(id),
|
|
1812
|
-
toggle: () => toggle(id)
|
|
1945
|
+
toggle: () => toggle(id),
|
|
1946
|
+
isSelected: toRef(() => selected(id)),
|
|
1947
|
+
...registration,
|
|
1948
|
+
id
|
|
1813
1949
|
};
|
|
1814
1950
|
const ticket = registry.register(item);
|
|
1815
1951
|
if (enroll && !toValue(item.disabled)) selectedIds.add(ticket.id);
|
|
@@ -1820,6 +1956,13 @@ function createSelection(_options = {}) {
|
|
|
1820
1956
|
selectedIds.delete(id);
|
|
1821
1957
|
registry.unregister(id);
|
|
1822
1958
|
}
|
|
1959
|
+
function offboard(ids) {
|
|
1960
|
+
for (const id of ids) selectedIds.delete(id);
|
|
1961
|
+
registry.offboard(ids);
|
|
1962
|
+
}
|
|
1963
|
+
function onboard(registrations) {
|
|
1964
|
+
return registrations.map((registration) => register(registration));
|
|
1965
|
+
}
|
|
1823
1966
|
function reset() {
|
|
1824
1967
|
registry.clear();
|
|
1825
1968
|
selectedIds.clear();
|
|
@@ -1833,6 +1976,8 @@ function createSelection(_options = {}) {
|
|
|
1833
1976
|
selectedValues,
|
|
1834
1977
|
register,
|
|
1835
1978
|
unregister,
|
|
1979
|
+
onboard,
|
|
1980
|
+
offboard,
|
|
1836
1981
|
reset,
|
|
1837
1982
|
mandate,
|
|
1838
1983
|
seek,
|
|
@@ -1848,7 +1993,6 @@ function createSelection(_options = {}) {
|
|
|
1848
1993
|
/**
|
|
1849
1994
|
* Creates a new selection context.
|
|
1850
1995
|
*
|
|
1851
|
-
* @param namespace The namespace for the selection context.
|
|
1852
1996
|
* @param options The options for the selection context.
|
|
1853
1997
|
* @template Z The type of the selection ticket.
|
|
1854
1998
|
* @template E The type of the selection context.
|
|
@@ -1860,7 +2004,11 @@ function createSelection(_options = {}) {
|
|
|
1860
2004
|
* ```ts
|
|
1861
2005
|
* import { createSelectionContext } from '@vuetify/v0'
|
|
1862
2006
|
*
|
|
1863
|
-
*
|
|
2007
|
+
* // With default namespace 'v0:selection'
|
|
2008
|
+
* export const [useCheckboxes, provideCheckboxes, checkboxes] = createSelectionContext()
|
|
2009
|
+
*
|
|
2010
|
+
* // Or with custom namespace
|
|
2011
|
+
* export const [useCheckboxes, provideCheckboxes, checkboxes] = createSelectionContext({ namespace: 'checkboxes' })
|
|
1864
2012
|
*
|
|
1865
2013
|
* // In a parent component:
|
|
1866
2014
|
* provideCheckboxes()
|
|
@@ -1870,8 +2018,8 @@ function createSelection(_options = {}) {
|
|
|
1870
2018
|
* checkboxes.select('checkbox-1')
|
|
1871
2019
|
* ```
|
|
1872
2020
|
*/
|
|
1873
|
-
function createSelectionContext(_options) {
|
|
1874
|
-
const { namespace,...options } = _options;
|
|
2021
|
+
function createSelectionContext(_options = {}) {
|
|
2022
|
+
const { namespace = "v0:selection",...options } = _options;
|
|
1875
2023
|
const [useSelectionContext, _provideSelectionContext] = createContext(namespace);
|
|
1876
2024
|
const context = createSelection(options);
|
|
1877
2025
|
function provideSelectionContext(_context = context, app) {
|
|
@@ -1907,31 +2055,102 @@ function useSelection(namespace = "v0:selection") {
|
|
|
1907
2055
|
}
|
|
1908
2056
|
|
|
1909
2057
|
//#endregion
|
|
1910
|
-
//#region src/composables/
|
|
2058
|
+
//#region src/composables/useProxyRegistry/index.ts
|
|
1911
2059
|
/**
|
|
1912
|
-
* @module
|
|
2060
|
+
* @module useProxyRegistry
|
|
1913
2061
|
*
|
|
1914
2062
|
* @remarks
|
|
1915
|
-
*
|
|
2063
|
+
* Proxy composable for reactive registry keys, values, entries, and size.
|
|
1916
2064
|
*
|
|
1917
2065
|
* Key features:
|
|
1918
|
-
* -
|
|
1919
|
-
* -
|
|
1920
|
-
* -
|
|
2066
|
+
* - Reactive proxy for registry data
|
|
2067
|
+
* - Deep or shallow reactivity options
|
|
2068
|
+
* - Event-based updates
|
|
2069
|
+
* - Automatic cleanup on scope disposal
|
|
2070
|
+
* - Transforms Map-based registry into reactive refs
|
|
1921
2071
|
*
|
|
1922
|
-
*
|
|
1923
|
-
* Extended by: useFeatures
|
|
2072
|
+
* Perfect for exposing registry data as reactive computed properties.
|
|
1924
2073
|
*/
|
|
1925
2074
|
/**
|
|
1926
|
-
* Creates a
|
|
2075
|
+
* Creates a proxy registry that provides reactive objects for registry data.
|
|
2076
|
+
*
|
|
2077
|
+
* @param registry The registry instance to proxy.
|
|
2078
|
+
* @param options The options for the proxy registry.
|
|
2079
|
+
* @template Z The type of the registry ticket.
|
|
2080
|
+
* @returns A proxy registry with reactive objects.
|
|
2081
|
+
*
|
|
2082
|
+
* @see https://0.vuetifyjs.com/composables/registration/use-proxy-registry
|
|
2083
|
+
*
|
|
2084
|
+
* @example
|
|
2085
|
+
* ```ts
|
|
2086
|
+
* import { useRegistry, useProxyRegistry } from '@vuetify/v0'
|
|
2087
|
+
*
|
|
2088
|
+
* const registry = useRegistry({ events: true })
|
|
2089
|
+
* const proxy = useProxyRegistry(registry)
|
|
2090
|
+
*
|
|
2091
|
+
* registry.register({ value: 'Item 1' })
|
|
2092
|
+
* console.log(proxy.size) // 1
|
|
2093
|
+
* ```
|
|
2094
|
+
*/
|
|
2095
|
+
function useProxyRegistry(registry, options) {
|
|
2096
|
+
const state = (options?.deep ? reactive : shallowReactive)({
|
|
2097
|
+
keys: registry.keys(),
|
|
2098
|
+
values: registry.values(),
|
|
2099
|
+
entries: registry.entries(),
|
|
2100
|
+
size: registry.size
|
|
2101
|
+
});
|
|
2102
|
+
function update() {
|
|
2103
|
+
state.keys = registry.keys();
|
|
2104
|
+
state.values = registry.values();
|
|
2105
|
+
state.entries = registry.entries();
|
|
2106
|
+
state.size = registry.size;
|
|
2107
|
+
}
|
|
2108
|
+
registry.on("register:ticket", update);
|
|
2109
|
+
registry.on("unregister:ticket", update);
|
|
2110
|
+
registry.on("update:ticket", update);
|
|
2111
|
+
registry.on("clear:registry", update);
|
|
2112
|
+
onScopeDispose(() => {
|
|
2113
|
+
registry.off("register:ticket", update);
|
|
2114
|
+
registry.off("unregister:ticket", update);
|
|
2115
|
+
registry.off("update:ticket", update);
|
|
2116
|
+
registry.off("clear:registry", update);
|
|
2117
|
+
}, true);
|
|
2118
|
+
return state;
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
//#endregion
|
|
2122
|
+
//#region src/composables/useGroup/index.ts
|
|
2123
|
+
/**
|
|
2124
|
+
* @module useGroup
|
|
2125
|
+
*
|
|
2126
|
+
* @remarks
|
|
2127
|
+
* Multi-selection composable that extends useSelection with batch operations and tri-state support.
|
|
2128
|
+
*
|
|
2129
|
+
* Key features:
|
|
2130
|
+
* - Batch operations (select/unselect/toggle accept ID | ID[])
|
|
2131
|
+
* - Tri-state support via mixed/indeterminate state (mix/unmix)
|
|
2132
|
+
* - selectedIndexes computed Set for position-based tracking
|
|
2133
|
+
* - Perfect for checkbox trees, multi-select dropdowns, filter panels
|
|
2134
|
+
*
|
|
2135
|
+
* Tri-state behavior:
|
|
2136
|
+
* - Items can be selected, mixed (indeterminate), or unselected
|
|
2137
|
+
* - select() clears mixed state, mix() clears selected state (mutually exclusive)
|
|
2138
|
+
* - toggle() on a mixed item selects it (resolves positively)
|
|
2139
|
+
*
|
|
2140
|
+
* Inheritance chain: useRegistry → useSelection → useGroup
|
|
2141
|
+
* Extended by: useFeatures
|
|
2142
|
+
*/
|
|
2143
|
+
/**
|
|
2144
|
+
* Creates a new group instance with batch selection and tri-state support.
|
|
1927
2145
|
*
|
|
1928
2146
|
* Extends `createSelection` to support selecting, unselecting, and toggling multiple items
|
|
1929
|
-
* at once by passing an array of IDs. Adds
|
|
2147
|
+
* at once by passing an array of IDs. Adds tri-state (mixed/indeterminate) support for
|
|
2148
|
+
* checkbox trees and similar use cases.
|
|
1930
2149
|
*
|
|
1931
2150
|
* @param options The options for the group instance.
|
|
1932
2151
|
* @template Z The type of the group ticket.
|
|
1933
2152
|
* @template E The type of the group context.
|
|
1934
|
-
* @returns A new group instance with batch selection support.
|
|
2153
|
+
* @returns A new group instance with batch selection and tri-state support.
|
|
1935
2154
|
*
|
|
1936
2155
|
* @remarks
|
|
1937
2156
|
* **Key Differences from `createSelection`:**
|
|
@@ -1939,13 +2158,22 @@ function useSelection(namespace = "v0:selection") {
|
|
|
1939
2158
|
* - `unselect()` accepts `ID | ID[]` for batch operations
|
|
1940
2159
|
* - `toggle()` accepts `ID | ID[]` for batch operations
|
|
1941
2160
|
* - Adds `selectedIndexes` computed Set for getting selected item indexes
|
|
1942
|
-
* -
|
|
2161
|
+
* - Adds tri-state support via `mix()`, `unmix()`, `mixed()`, `mixedIds`, `mixedItems`
|
|
2162
|
+
* - Perfect for checkbox trees, multi-select dropdowns, and bulk operations
|
|
2163
|
+
*
|
|
2164
|
+
* **Tri-State Support:**
|
|
2165
|
+
* - Items can be in one of three states: selected, mixed (indeterminate), or unselected
|
|
2166
|
+
* - `mix(id)` sets item to mixed state (clears selected if set)
|
|
2167
|
+
* - `unmix(id)` clears mixed state
|
|
2168
|
+
* - `select(id)` clears mixed state before selecting
|
|
2169
|
+
* - `toggle(id)` on a mixed item selects it (resolves the indeterminate state positively)
|
|
2170
|
+
* - Mixed state works on disabled items (it's a computed state, not user action)
|
|
1943
2171
|
*
|
|
1944
2172
|
* **Batch Operations:**
|
|
1945
2173
|
* - Single ID: `group.select('item-1')`
|
|
1946
2174
|
* - Array of IDs: `group.select(['item-1', 'item-2', 'item-3'])`
|
|
1947
2175
|
* - Uses `toArray()` utility internally to normalize input
|
|
1948
|
-
* - Disabled items are automatically skipped in
|
|
2176
|
+
* - Disabled items are automatically skipped in select operations
|
|
1949
2177
|
* - Non-existent IDs are silently ignored
|
|
1950
2178
|
*
|
|
1951
2179
|
* **Inheritance Chain:**
|
|
@@ -1974,45 +2202,148 @@ function useSelection(namespace = "v0:selection") {
|
|
|
1974
2202
|
* console.log(checkboxes.selectedIds) // Set { 'option-a', 'option-c' }
|
|
1975
2203
|
* console.log(Array.from(checkboxes.selectedIndexes.value)) // [0, 2]
|
|
1976
2204
|
*
|
|
1977
|
-
* //
|
|
1978
|
-
* checkboxes.
|
|
1979
|
-
* console.log(checkboxes.
|
|
2205
|
+
* // Set item to mixed/indeterminate state
|
|
2206
|
+
* checkboxes.mix('option-a')
|
|
2207
|
+
* console.log(checkboxes.mixedIds) // Set { 'option-a' }
|
|
2208
|
+
* console.log(checkboxes.selectedIds) // Set { 'option-c' } (option-a removed)
|
|
2209
|
+
*
|
|
2210
|
+
* // Toggle a mixed item selects it
|
|
2211
|
+
* checkboxes.toggle('option-a')
|
|
2212
|
+
* console.log(checkboxes.selectedIds) // Set { 'option-a', 'option-c' }
|
|
2213
|
+
* console.log(checkboxes.mixedIds) // Set {} (cleared)
|
|
1980
2214
|
* ```
|
|
1981
2215
|
*/
|
|
1982
2216
|
function createGroup(_options = {}) {
|
|
1983
2217
|
const { mandatory = false, multiple = true,...options } = _options;
|
|
1984
|
-
const
|
|
2218
|
+
const selection = createSelection({
|
|
1985
2219
|
...options,
|
|
1986
2220
|
mandatory,
|
|
1987
|
-
multiple
|
|
2221
|
+
multiple,
|
|
2222
|
+
events: true
|
|
1988
2223
|
});
|
|
2224
|
+
const proxy = useProxyRegistry(selection);
|
|
2225
|
+
const mixedIds = shallowReactive(/* @__PURE__ */ new Set());
|
|
1989
2226
|
const selectedIndexes = computed(() => {
|
|
1990
|
-
return new Set(Array.from(
|
|
2227
|
+
return new Set(Array.from(selection.selectedItems.value).map((item) => item?.index));
|
|
2228
|
+
});
|
|
2229
|
+
const mixedItems = computed(() => {
|
|
2230
|
+
return new Set(Array.from(mixedIds).map((id) => selection.get(id)));
|
|
1991
2231
|
});
|
|
2232
|
+
function mixed(id) {
|
|
2233
|
+
return mixedIds.has(id);
|
|
2234
|
+
}
|
|
2235
|
+
function mix(ids) {
|
|
2236
|
+
for (const id of toArray(ids)) {
|
|
2237
|
+
if (!selection.has(id)) continue;
|
|
2238
|
+
selection.selectedIds.delete(id);
|
|
2239
|
+
mixedIds.add(id);
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
function unmix(ids) {
|
|
2243
|
+
for (const id of toArray(ids)) mixedIds.delete(id);
|
|
2244
|
+
}
|
|
1992
2245
|
function select(ids) {
|
|
1993
|
-
for (const id of toArray(ids))
|
|
2246
|
+
for (const id of toArray(ids)) {
|
|
2247
|
+
mixedIds.delete(id);
|
|
2248
|
+
selection.select(id);
|
|
2249
|
+
}
|
|
1994
2250
|
}
|
|
1995
2251
|
function unselect(ids) {
|
|
1996
|
-
for (const id of toArray(ids))
|
|
2252
|
+
for (const id of toArray(ids)) selection.unselect(id);
|
|
1997
2253
|
}
|
|
1998
2254
|
function toggle(ids) {
|
|
1999
|
-
for (const id of toArray(ids))
|
|
2255
|
+
for (const id of toArray(ids)) if (mixed(id)) select(id);
|
|
2256
|
+
else selection.toggle(id);
|
|
2257
|
+
}
|
|
2258
|
+
function register(registration = {}) {
|
|
2259
|
+
const id = registration.id ?? /* @__PURE__ */ genId();
|
|
2260
|
+
const item = {
|
|
2261
|
+
...registration,
|
|
2262
|
+
id,
|
|
2263
|
+
isMixed: toRef(() => mixed(id)),
|
|
2264
|
+
select: () => select(id),
|
|
2265
|
+
unselect: () => unselect(id),
|
|
2266
|
+
toggle: () => toggle(id),
|
|
2267
|
+
mix: () => mix(id),
|
|
2268
|
+
unmix: () => unmix(id)
|
|
2269
|
+
};
|
|
2270
|
+
const ticket = selection.register(item);
|
|
2271
|
+
if (toValue(registration.indeterminate)) mix(id);
|
|
2272
|
+
return ticket;
|
|
2273
|
+
}
|
|
2274
|
+
function unregister(id) {
|
|
2275
|
+
mixedIds.delete(id);
|
|
2276
|
+
selection.unregister(id);
|
|
2277
|
+
}
|
|
2278
|
+
function offboard(ids) {
|
|
2279
|
+
for (const id of ids) mixedIds.delete(id);
|
|
2280
|
+
selection.offboard(ids);
|
|
2281
|
+
}
|
|
2282
|
+
function onboard(registrations) {
|
|
2283
|
+
return registrations.map((registration) => register(registration));
|
|
2284
|
+
}
|
|
2285
|
+
function reset() {
|
|
2286
|
+
mixedIds.clear();
|
|
2287
|
+
selection.reset();
|
|
2288
|
+
}
|
|
2289
|
+
const selectableItems = computed(() => {
|
|
2290
|
+
return proxy.values.filter((item) => !toValue(item.disabled));
|
|
2291
|
+
});
|
|
2292
|
+
const isAllSelected = computed(() => {
|
|
2293
|
+
const items = selectableItems.value;
|
|
2294
|
+
if (items.length === 0) return false;
|
|
2295
|
+
return items.every((item) => selection.selectedIds.has(item.id));
|
|
2296
|
+
});
|
|
2297
|
+
const isMixed = toRef(() => {
|
|
2298
|
+
return mixedIds.size > 0 || !isNoneSelected.value && !isAllSelected.value;
|
|
2299
|
+
});
|
|
2300
|
+
const isNoneSelected = toRef(() => selection.selectedIds.size === 0);
|
|
2301
|
+
function selectAll() {
|
|
2302
|
+
for (const item of selectableItems.value) {
|
|
2303
|
+
mixedIds.delete(item.id);
|
|
2304
|
+
selection.select(item.id);
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
function unselectAll() {
|
|
2308
|
+
const first = selection.selectedIds.values().next().value;
|
|
2309
|
+
selection.selectedIds.clear();
|
|
2310
|
+
if (!mandatory || !first) return;
|
|
2311
|
+
selection.select(first);
|
|
2312
|
+
}
|
|
2313
|
+
function toggleAll() {
|
|
2314
|
+
if (isAllSelected.value) unselectAll();
|
|
2315
|
+
else selectAll();
|
|
2000
2316
|
}
|
|
2001
2317
|
return {
|
|
2002
|
-
...
|
|
2318
|
+
...selection,
|
|
2319
|
+
mixed,
|
|
2320
|
+
mix,
|
|
2321
|
+
unmix,
|
|
2003
2322
|
select,
|
|
2004
2323
|
unselect,
|
|
2005
2324
|
toggle,
|
|
2325
|
+
register,
|
|
2326
|
+
unregister,
|
|
2327
|
+
offboard,
|
|
2328
|
+
onboard,
|
|
2329
|
+
reset,
|
|
2330
|
+
selectAll,
|
|
2331
|
+
unselectAll,
|
|
2332
|
+
toggleAll,
|
|
2333
|
+
mixedIds,
|
|
2334
|
+
mixedItems,
|
|
2006
2335
|
selectedIndexes,
|
|
2336
|
+
isNoneSelected,
|
|
2337
|
+
isAllSelected,
|
|
2338
|
+
isMixed,
|
|
2007
2339
|
get size() {
|
|
2008
|
-
return
|
|
2340
|
+
return selection.size;
|
|
2009
2341
|
}
|
|
2010
2342
|
};
|
|
2011
2343
|
}
|
|
2012
2344
|
/**
|
|
2013
2345
|
* Creates a new group context.
|
|
2014
2346
|
*
|
|
2015
|
-
* @param namespace The namespace for the group context.
|
|
2016
2347
|
* @param options The options for the group context.
|
|
2017
2348
|
* @template Z The type of the group ticket.
|
|
2018
2349
|
* @template E The type of the group context.
|
|
@@ -2024,7 +2355,11 @@ function createGroup(_options = {}) {
|
|
|
2024
2355
|
* ```ts
|
|
2025
2356
|
* import { createGroupContext } from '@vuetify/v0'
|
|
2026
2357
|
*
|
|
2027
|
-
*
|
|
2358
|
+
* // With default namespace 'v0:group'
|
|
2359
|
+
* export const [useMyGroup, provideMyGroup, myGroup] = createGroupContext()
|
|
2360
|
+
*
|
|
2361
|
+
* // Or with custom namespace
|
|
2362
|
+
* export const [useMyGroup, provideMyGroup, myGroup] = createGroupContext({ namespace: 'my-group' })
|
|
2028
2363
|
*
|
|
2029
2364
|
* // In a parent component:
|
|
2030
2365
|
* provideMyGroup()
|
|
@@ -2033,8 +2368,8 @@ function createGroup(_options = {}) {
|
|
|
2033
2368
|
* const group = useMyGroup()
|
|
2034
2369
|
* ```
|
|
2035
2370
|
*/
|
|
2036
|
-
function createGroupContext(_options) {
|
|
2037
|
-
const { namespace,...options } = _options;
|
|
2371
|
+
function createGroupContext(_options = {}) {
|
|
2372
|
+
const { namespace = "v0:group",...options } = _options;
|
|
2038
2373
|
const [useGroupContext, _provideGroupContext] = createContext(namespace);
|
|
2039
2374
|
const context = createGroup(options);
|
|
2040
2375
|
function provideGroupContext(_context = context, app) {
|
|
@@ -2065,7 +2400,7 @@ function createGroupContext(_options) {
|
|
|
2065
2400
|
* </template>
|
|
2066
2401
|
* ```
|
|
2067
2402
|
*/
|
|
2068
|
-
function useGroup(namespace) {
|
|
2403
|
+
function useGroup(namespace = "v0:group") {
|
|
2069
2404
|
return useContext(namespace);
|
|
2070
2405
|
}
|
|
2071
2406
|
|
|
@@ -2129,9 +2464,10 @@ function createTokens(tokens = {}, options = {}) {
|
|
|
2129
2464
|
function resolve(token, visited = /* @__PURE__ */ new Set()) {
|
|
2130
2465
|
const cacheKey = /* @__PURE__ */ isString(token) ? token : JSON.stringify(token);
|
|
2131
2466
|
const cached = cache.get(cacheKey);
|
|
2132
|
-
if (
|
|
2467
|
+
if (!/* @__PURE__ */ isUndefined(cached)) return cached;
|
|
2133
2468
|
const reference = isTokenAlias(token) ? token.$value : token;
|
|
2134
|
-
const
|
|
2469
|
+
const isAliasReference = /* @__PURE__ */ isString(reference) && isAlias(reference);
|
|
2470
|
+
const clean = isAliasReference ? reference.slice(1, -1) : String(reference);
|
|
2135
2471
|
if (visited.has(clean)) {
|
|
2136
2472
|
logger.warn(`Circular alias detected for "${clean}"`);
|
|
2137
2473
|
cache.set(cacheKey, void 0);
|
|
@@ -2146,15 +2482,15 @@ function createTokens(tokens = {}, options = {}) {
|
|
|
2146
2482
|
const prefix = parts.slice(0, i).join(".");
|
|
2147
2483
|
const suffix = parts.slice(i);
|
|
2148
2484
|
const candidate = registry.get(prefix);
|
|
2149
|
-
if (candidate?.value
|
|
2485
|
+
if (!/* @__PURE__ */ isUndefined(candidate?.value)) {
|
|
2150
2486
|
found = candidate;
|
|
2151
2487
|
segments = suffix;
|
|
2152
2488
|
break;
|
|
2153
2489
|
}
|
|
2154
2490
|
}
|
|
2155
2491
|
}
|
|
2156
|
-
if (found?.value
|
|
2157
|
-
logger.warn(`Alias not found for "${String(reference)}"`);
|
|
2492
|
+
if (/* @__PURE__ */ isUndefined(found?.value)) {
|
|
2493
|
+
if (isAliasReference) logger.warn(`Alias not found for "${String(reference)}"`);
|
|
2158
2494
|
cache.set(cacheKey, void 0);
|
|
2159
2495
|
return;
|
|
2160
2496
|
}
|
|
@@ -2170,7 +2506,7 @@ function createTokens(tokens = {}, options = {}) {
|
|
|
2170
2506
|
current = current[segment];
|
|
2171
2507
|
if (isTokenAlias(current)) current = current.$value;
|
|
2172
2508
|
}
|
|
2173
|
-
if (
|
|
2509
|
+
if (/* @__PURE__ */ isUndefined(current)) {
|
|
2174
2510
|
logger.warn(`Path not found inside "${clean}": ${segments.join(".")}`);
|
|
2175
2511
|
cache.set(cacheKey, void 0);
|
|
2176
2512
|
return;
|
|
@@ -2221,7 +2557,7 @@ function createTokens(tokens = {}, options = {}) {
|
|
|
2221
2557
|
* ```
|
|
2222
2558
|
*/
|
|
2223
2559
|
function createTokensContext(_options) {
|
|
2224
|
-
const { namespace, tokens = {},...options } = _options;
|
|
2560
|
+
const { namespace = "v0:tokens", tokens = {},...options } = _options;
|
|
2225
2561
|
const [useTokensContext, _provideTokensContext] = createContext(namespace);
|
|
2226
2562
|
const context = createTokens(tokens, options);
|
|
2227
2563
|
function provideTokensContext(_context = context, app) {
|
|
@@ -2541,7 +2877,7 @@ function defaultFilter(query, item, keys, mode = "some") {
|
|
|
2541
2877
|
* @template Z The type of the items.
|
|
2542
2878
|
* @returns The filtered items.
|
|
2543
2879
|
*
|
|
2544
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
2880
|
+
* @see https://0.vuetifyjs.com/composables/utilities/use-filter
|
|
2545
2881
|
*
|
|
2546
2882
|
* @example
|
|
2547
2883
|
* ```ts
|
|
@@ -2641,7 +2977,7 @@ function createForm(options) {
|
|
|
2641
2977
|
if (ticket.isValid.value === false) return false;
|
|
2642
2978
|
if (ticket.isValid.value === null) return null;
|
|
2643
2979
|
}
|
|
2644
|
-
return hasFields
|
|
2980
|
+
return hasFields ? true : null;
|
|
2645
2981
|
});
|
|
2646
2982
|
function reset() {
|
|
2647
2983
|
for (const ticket of registry.values()) ticket.reset();
|
|
@@ -2731,7 +3067,6 @@ function createForm(options) {
|
|
|
2731
3067
|
/**
|
|
2732
3068
|
* Creates a new form context.
|
|
2733
3069
|
*
|
|
2734
|
-
* @param namespace The namespace for the form context.
|
|
2735
3070
|
* @param options The options for the form context.
|
|
2736
3071
|
* @template Z The type of the form ticket.
|
|
2737
3072
|
* @template E The type of the form context.
|
|
@@ -2743,7 +3078,12 @@ function createForm(options) {
|
|
|
2743
3078
|
* ```ts
|
|
2744
3079
|
* import { createFormContext } from '@vuetify/v0'
|
|
2745
3080
|
*
|
|
2746
|
-
*
|
|
3081
|
+
* // With default namespace 'v0:form'
|
|
3082
|
+
* export const [useMyForm, provideMyForm, myForm] = createFormContext({ validateOn: 'change' })
|
|
3083
|
+
*
|
|
3084
|
+
* // Or with custom namespace
|
|
3085
|
+
* export const [useMyForm, provideMyForm, myForm] = createFormContext({
|
|
3086
|
+
* namespace: 'my-form',
|
|
2747
3087
|
* validateOn: 'change',
|
|
2748
3088
|
* })
|
|
2749
3089
|
*
|
|
@@ -2755,8 +3095,8 @@ function createForm(options) {
|
|
|
2755
3095
|
* form.register({ id: 'field', value: ref(''), rules: [...] })
|
|
2756
3096
|
* ```
|
|
2757
3097
|
*/
|
|
2758
|
-
function createFormContext(_options) {
|
|
2759
|
-
const { namespace,...options } = _options;
|
|
3098
|
+
function createFormContext(_options = {}) {
|
|
3099
|
+
const { namespace = "v0:form",...options } = _options;
|
|
2760
3100
|
const [useFormContext, _provideFormContext] = createContext(namespace);
|
|
2761
3101
|
const context = createForm(options);
|
|
2762
3102
|
function provideFormContext(_context = context, app) {
|
|
@@ -2853,6 +3193,7 @@ function useIntersectionObserver(target, callback, options = {}) {
|
|
|
2853
3193
|
const observer = shallowRef();
|
|
2854
3194
|
const isPaused = shallowRef(false);
|
|
2855
3195
|
const isIntersecting = shallowRef(false);
|
|
3196
|
+
const isActive = toRef(() => !!observer.value);
|
|
2856
3197
|
function setup() {
|
|
2857
3198
|
if (!isHydrated.value || !SUPPORTS_INTERSECTION_OBSERVER || !target.value || isPaused.value) return;
|
|
2858
3199
|
observer.value = new IntersectionObserver((entries) => {
|
|
@@ -2906,10 +3247,11 @@ function useIntersectionObserver(target, callback, options = {}) {
|
|
|
2906
3247
|
function stop() {
|
|
2907
3248
|
cleanup();
|
|
2908
3249
|
}
|
|
2909
|
-
|
|
3250
|
+
onScopeDispose(stop, true);
|
|
2910
3251
|
return {
|
|
2911
|
-
|
|
2912
|
-
|
|
3252
|
+
isActive: shallowReadonly(isActive),
|
|
3253
|
+
isIntersecting: shallowReadonly(isIntersecting),
|
|
3254
|
+
isPaused: shallowReadonly(isPaused),
|
|
2913
3255
|
pause,
|
|
2914
3256
|
resume,
|
|
2915
3257
|
stop
|
|
@@ -2946,7 +3288,7 @@ function useIntersectionObserver(target, callback, options = {}) {
|
|
|
2946
3288
|
function useElementIntersection(target, options = {}) {
|
|
2947
3289
|
const isIntersecting = shallowRef(false);
|
|
2948
3290
|
const intersectionRatio = shallowRef(0);
|
|
2949
|
-
const { pause: _pause, resume, stop, isPaused } = useIntersectionObserver(target, (entries) => {
|
|
3291
|
+
const { pause: _pause, resume, stop, isActive, isPaused } = useIntersectionObserver(target, (entries) => {
|
|
2950
3292
|
const entry = entries.at(-1);
|
|
2951
3293
|
if (entry) {
|
|
2952
3294
|
isIntersecting.value = entry.isIntersecting;
|
|
@@ -2962,8 +3304,9 @@ function useElementIntersection(target, options = {}) {
|
|
|
2962
3304
|
_pause();
|
|
2963
3305
|
}
|
|
2964
3306
|
return {
|
|
2965
|
-
isIntersecting:
|
|
2966
|
-
intersectionRatio:
|
|
3307
|
+
isIntersecting: shallowReadonly(isIntersecting),
|
|
3308
|
+
intersectionRatio: shallowReadonly(intersectionRatio),
|
|
3309
|
+
isActive,
|
|
2967
3310
|
isPaused,
|
|
2968
3311
|
pause,
|
|
2969
3312
|
resume,
|
|
@@ -2983,7 +3326,7 @@ function useElementIntersection(target, options = {}) {
|
|
|
2983
3326
|
* - Key-specific event handling
|
|
2984
3327
|
* - preventDefault and stopPropagation options
|
|
2985
3328
|
* - Automatic cleanup on scope disposal
|
|
2986
|
-
* -
|
|
3329
|
+
* - Built on useEventListener for consistent event handling
|
|
2987
3330
|
*
|
|
2988
3331
|
* Simplified wrapper around useEventListener for keyboard interactions.
|
|
2989
3332
|
*/
|
|
@@ -2999,36 +3342,44 @@ function useElementIntersection(target, options = {}) {
|
|
|
2999
3342
|
* ```ts
|
|
3000
3343
|
* import { useKeydown } from '@vuetify/v0'
|
|
3001
3344
|
*
|
|
3002
|
-
* const {
|
|
3345
|
+
* const { isActive, start, stop } = useKeydown([
|
|
3003
3346
|
* { key: 'Enter', handler: () => console.log('Enter pressed') },
|
|
3004
3347
|
* { key: 'Escape', handler: () => console.log('Escape pressed'), preventDefault: true },
|
|
3005
3348
|
* ])
|
|
3006
3349
|
*
|
|
3007
|
-
*
|
|
3008
|
-
*
|
|
3350
|
+
* // Listener is automatically active when called in component setup
|
|
3351
|
+
* // Manually control if needed:
|
|
3352
|
+
* stop()
|
|
3353
|
+
* start()
|
|
3009
3354
|
* ```
|
|
3010
3355
|
*/
|
|
3011
3356
|
function useKeydown(handlers) {
|
|
3012
|
-
|
|
3357
|
+
let cleanup = null;
|
|
3358
|
+
const isActive = toRef(() => !!cleanup);
|
|
3013
3359
|
function onKeydown(event) {
|
|
3014
|
-
const
|
|
3360
|
+
const handlerList = toValue(handlers);
|
|
3361
|
+
const handler = (Array.isArray(handlerList) ? handlerList : [handlerList]).find((h) => h.key === event.key);
|
|
3015
3362
|
if (handler) {
|
|
3016
3363
|
if (handler.preventDefault) event.preventDefault();
|
|
3017
3364
|
if (handler.stopPropagation) event.stopPropagation();
|
|
3018
3365
|
handler.handler(event);
|
|
3019
3366
|
}
|
|
3020
3367
|
}
|
|
3021
|
-
function
|
|
3022
|
-
|
|
3368
|
+
function start() {
|
|
3369
|
+
if (cleanup) return;
|
|
3370
|
+
cleanup = useDocumentEventListener("keydown", onKeydown);
|
|
3023
3371
|
}
|
|
3024
|
-
function
|
|
3025
|
-
|
|
3372
|
+
function stop() {
|
|
3373
|
+
if (!cleanup) return;
|
|
3374
|
+
cleanup();
|
|
3375
|
+
cleanup = null;
|
|
3026
3376
|
}
|
|
3027
|
-
|
|
3028
|
-
onScopeDispose(
|
|
3377
|
+
cleanup = useDocumentEventListener("keydown", onKeydown);
|
|
3378
|
+
onScopeDispose(stop);
|
|
3029
3379
|
return {
|
|
3030
|
-
|
|
3031
|
-
|
|
3380
|
+
isActive,
|
|
3381
|
+
start,
|
|
3382
|
+
stop
|
|
3032
3383
|
};
|
|
3033
3384
|
}
|
|
3034
3385
|
|
|
@@ -3132,7 +3483,6 @@ function createSingle(_options = {}) {
|
|
|
3132
3483
|
/**
|
|
3133
3484
|
* Creates a new single selection context.
|
|
3134
3485
|
*
|
|
3135
|
-
* @param namespace The namespace for the single selection context.
|
|
3136
3486
|
* @param options The options for the single selection context.
|
|
3137
3487
|
* @template Z The type of the single selection ticket.
|
|
3138
3488
|
* @template E The type of the single selection context.
|
|
@@ -3144,18 +3494,19 @@ function createSingle(_options = {}) {
|
|
|
3144
3494
|
* ```ts
|
|
3145
3495
|
* import { createSingleContext } from '@vuetify/v0'
|
|
3146
3496
|
*
|
|
3147
|
-
*
|
|
3497
|
+
* // With default namespace 'v0:single'
|
|
3498
|
+
* export const [useSingle, provideSingle, context] = createSingleContext()
|
|
3148
3499
|
*
|
|
3149
3500
|
* // In a parent component:
|
|
3150
|
-
*
|
|
3501
|
+
* provideSingle()
|
|
3151
3502
|
*
|
|
3152
3503
|
* // In a child component:
|
|
3153
|
-
* const
|
|
3154
|
-
*
|
|
3504
|
+
* const single = useSingle()
|
|
3505
|
+
* single.select('tab-1')
|
|
3155
3506
|
* ```
|
|
3156
3507
|
*/
|
|
3157
|
-
function createSingleContext(_options) {
|
|
3158
|
-
const { namespace,...options } = _options;
|
|
3508
|
+
function createSingleContext(_options = {}) {
|
|
3509
|
+
const { namespace = "v0:single",...options } = _options;
|
|
3159
3510
|
const [useSingleContext, _provideSingleContext] = createContext(namespace);
|
|
3160
3511
|
const context = createSingle(options);
|
|
3161
3512
|
function provideSingleContext(_context = context, app) {
|
|
@@ -3197,7 +3548,7 @@ function useSingle(namespace = "v0:single") {
|
|
|
3197
3548
|
*
|
|
3198
3549
|
* This adapter provides translation and number formatting
|
|
3199
3550
|
* capabilities using the Intl API and supports both
|
|
3200
|
-
* numbered and named variables in translation strings.
|
|
3551
|
+
* numbered ({0}, {1}) and named ({name}) variables in translation strings.
|
|
3201
3552
|
*/
|
|
3202
3553
|
var Vuetify0LocaleAdapter = class {
|
|
3203
3554
|
t(message, ...params) {
|
|
@@ -3205,13 +3556,13 @@ var Vuetify0LocaleAdapter = class {
|
|
|
3205
3556
|
if (params.length > 0 && /* @__PURE__ */ isObject(params[0])) {
|
|
3206
3557
|
const variables = params[0];
|
|
3207
3558
|
resolvedMessage = resolvedMessage.replace(/{([a-zA-Z][a-zA-Z0-9_]*)}/g, (match, name) => {
|
|
3208
|
-
return variables[name]
|
|
3559
|
+
return /* @__PURE__ */ isUndefined(variables[name]) ? match : String(variables[name]);
|
|
3209
3560
|
});
|
|
3210
3561
|
params = params.slice(1);
|
|
3211
3562
|
}
|
|
3212
3563
|
resolvedMessage = resolvedMessage.replace(/\{(\d+)\}/g, (match, index) => {
|
|
3213
3564
|
const idx = Number.parseInt(index, 10);
|
|
3214
|
-
if (params[idx]
|
|
3565
|
+
if (!/* @__PURE__ */ isUndefined(params[idx])) return String(params[idx]);
|
|
3215
3566
|
return match;
|
|
3216
3567
|
});
|
|
3217
3568
|
return resolvedMessage;
|
|
@@ -3252,21 +3603,20 @@ var Vuetify0LocaleAdapter = class {
|
|
|
3252
3603
|
*/
|
|
3253
3604
|
function createLocale(_options = {}) {
|
|
3254
3605
|
const { adapter = new Vuetify0LocaleAdapter(), messages = {},...options } = _options;
|
|
3255
|
-
const tokens = createTokens(messages
|
|
3606
|
+
const tokens = createTokens(messages);
|
|
3256
3607
|
const registry = createSingle(options);
|
|
3257
3608
|
for (const id in messages) {
|
|
3258
|
-
registry.register({
|
|
3259
|
-
id,
|
|
3260
|
-
value: messages[id]
|
|
3261
|
-
});
|
|
3609
|
+
registry.register({ id });
|
|
3262
3610
|
if (id === options.default && !registry.selectedId.value) registry.select(id);
|
|
3263
3611
|
}
|
|
3264
|
-
function t(key,
|
|
3612
|
+
function t(key, params, fallback) {
|
|
3265
3613
|
const locale = registry.selectedId.value;
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
const
|
|
3269
|
-
|
|
3614
|
+
const args = toArray(params);
|
|
3615
|
+
if (!locale) return adapter.t(fallback ?? key, ...args);
|
|
3616
|
+
const path = `${locale}.${key}`;
|
|
3617
|
+
const message = tokens.get(path)?.value;
|
|
3618
|
+
const template = /* @__PURE__ */ isString(message) ? resolve(locale, message) : fallback ?? key;
|
|
3619
|
+
return adapter.t(template, ...args);
|
|
3270
3620
|
}
|
|
3271
3621
|
function n(value, ...params) {
|
|
3272
3622
|
return adapter.n(value, registry.selectedId.value, ...params);
|
|
@@ -3274,17 +3624,10 @@ function createLocale(_options = {}) {
|
|
|
3274
3624
|
function resolve(locale, str) {
|
|
3275
3625
|
return str.replace(/{([a-zA-Z0-9.-_]+)}/g, (match, key) => {
|
|
3276
3626
|
const [prefix, ...rest] = key.split(".");
|
|
3277
|
-
const
|
|
3278
|
-
const
|
|
3279
|
-
const
|
|
3280
|
-
const name = prefixTicket ? path : key;
|
|
3281
|
-
const resolved = (registry.get(target)?.value)?.[name];
|
|
3627
|
+
const target = registry.has(prefix) ? prefix : locale;
|
|
3628
|
+
const path = `${target}.${registry.has(prefix) ? rest.join(".") : key}`;
|
|
3629
|
+
const resolved = tokens.get(path)?.value;
|
|
3282
3630
|
if (/* @__PURE__ */ isString(resolved)) return resolve(target, resolved);
|
|
3283
|
-
const alias = `{${key}}`;
|
|
3284
|
-
if (tokens.isAlias(alias)) {
|
|
3285
|
-
const result = tokens.resolve(alias);
|
|
3286
|
-
return /* @__PURE__ */ isString(result) ? result : match;
|
|
3287
|
-
}
|
|
3288
3631
|
return match;
|
|
3289
3632
|
});
|
|
3290
3633
|
}
|
|
@@ -3297,6 +3640,13 @@ function createLocale(_options = {}) {
|
|
|
3297
3640
|
}
|
|
3298
3641
|
};
|
|
3299
3642
|
}
|
|
3643
|
+
function createLocaleFallback() {
|
|
3644
|
+
return {
|
|
3645
|
+
size: 0,
|
|
3646
|
+
t: (key, _params, fallback) => fallback ?? key,
|
|
3647
|
+
n: String
|
|
3648
|
+
};
|
|
3649
|
+
}
|
|
3300
3650
|
/**
|
|
3301
3651
|
* Creates a new locale context.
|
|
3302
3652
|
*
|
|
@@ -3371,7 +3721,13 @@ function createLocalePlugin(_options = {}) {
|
|
|
3371
3721
|
* @see https://0.vuetifyjs.com/composables/plugins/use-locale
|
|
3372
3722
|
*/
|
|
3373
3723
|
function useLocale(namespace = "v0:locale") {
|
|
3374
|
-
|
|
3724
|
+
const fallback = createLocaleFallback();
|
|
3725
|
+
if (!getCurrentInstance()) return fallback;
|
|
3726
|
+
try {
|
|
3727
|
+
return useContext(namespace, fallback);
|
|
3728
|
+
} catch {
|
|
3729
|
+
return fallback;
|
|
3730
|
+
}
|
|
3375
3731
|
}
|
|
3376
3732
|
|
|
3377
3733
|
//#endregion
|
|
@@ -3439,6 +3795,7 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
3439
3795
|
const { isHydrated } = useHydration();
|
|
3440
3796
|
const observer = shallowRef();
|
|
3441
3797
|
const isPaused = shallowRef(false);
|
|
3798
|
+
const isActive = computed(() => !!observer.value);
|
|
3442
3799
|
const observerOptions = {
|
|
3443
3800
|
childList: options.childList ?? true,
|
|
3444
3801
|
attributes: options.attributes ?? false,
|
|
@@ -3505,9 +3862,10 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
3505
3862
|
function stop() {
|
|
3506
3863
|
cleanup();
|
|
3507
3864
|
}
|
|
3508
|
-
|
|
3865
|
+
onScopeDispose(stop, true);
|
|
3509
3866
|
return {
|
|
3510
|
-
|
|
3867
|
+
isActive: shallowReadonly(isActive),
|
|
3868
|
+
isPaused: shallowReadonly(isPaused),
|
|
3511
3869
|
pause,
|
|
3512
3870
|
resume,
|
|
3513
3871
|
stop
|
|
@@ -3515,360 +3873,881 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
3515
3873
|
}
|
|
3516
3874
|
|
|
3517
3875
|
//#endregion
|
|
3518
|
-
//#region src/composables/
|
|
3519
|
-
var PermissionAdapter = class {};
|
|
3520
|
-
|
|
3521
|
-
//#endregion
|
|
3522
|
-
//#region src/composables/usePermissions/adapters/v0.ts
|
|
3523
|
-
var Vuetify0PermissionAdapter = class extends PermissionAdapter {
|
|
3524
|
-
constructor() {
|
|
3525
|
-
super();
|
|
3526
|
-
}
|
|
3527
|
-
can(role, action, subject, context, permissions) {
|
|
3528
|
-
const access = `${role}.${action}.${subject}`;
|
|
3529
|
-
const ticket = permissions.get(access);
|
|
3530
|
-
if (!ticket || !ticket.value) return false;
|
|
3531
|
-
return /* @__PURE__ */ isFunction(ticket.value) ? ticket.value(context) : ticket.value;
|
|
3532
|
-
}
|
|
3533
|
-
};
|
|
3534
|
-
|
|
3535
|
-
//#endregion
|
|
3536
|
-
//#region src/composables/usePermissions/index.ts
|
|
3876
|
+
//#region src/composables/useResizeObserver/index.ts
|
|
3537
3877
|
/**
|
|
3538
|
-
* @module
|
|
3539
|
-
*
|
|
3540
|
-
* @see https://0.vuetifyjs.com/composables/plugins/use-permissions
|
|
3878
|
+
* @module useResizeObserver
|
|
3541
3879
|
*
|
|
3542
3880
|
* @remarks
|
|
3543
|
-
*
|
|
3881
|
+
* ResizeObserver composable with lifecycle management.
|
|
3544
3882
|
*
|
|
3545
3883
|
* Key features:
|
|
3546
|
-
* -
|
|
3547
|
-
* -
|
|
3548
|
-
* -
|
|
3549
|
-
* -
|
|
3550
|
-
* -
|
|
3884
|
+
* - ResizeObserver API wrapper
|
|
3885
|
+
* - Pause/resume/stop functionality
|
|
3886
|
+
* - Automatic cleanup on unmount
|
|
3887
|
+
* - SSR-safe (checks SUPPORTS_OBSERVER)
|
|
3888
|
+
* - Hydration-aware
|
|
3889
|
+
* - Box model options (content-box/border-box)
|
|
3551
3890
|
*
|
|
3552
|
-
*
|
|
3891
|
+
* Perfect for responsive components and size-based rendering.
|
|
3553
3892
|
*/
|
|
3554
3893
|
/**
|
|
3555
|
-
*
|
|
3894
|
+
* A composable that uses the Resize Observer API to detect when an element's
|
|
3895
|
+
* size changes.
|
|
3556
3896
|
*
|
|
3557
|
-
* @param
|
|
3558
|
-
* @
|
|
3559
|
-
* @
|
|
3560
|
-
* @returns
|
|
3897
|
+
* @param target The element to observe.
|
|
3898
|
+
* @param callback The callback to execute when the element's size changes.
|
|
3899
|
+
* @param options The options for the Resize Observer.
|
|
3900
|
+
* @returns An object with methods to control the observer.
|
|
3561
3901
|
*
|
|
3562
|
-
* @see https://
|
|
3902
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
|
|
3903
|
+
* @see https://0.vuetifyjs.com/composables/system/use-resize-observer
|
|
3563
3904
|
*
|
|
3564
3905
|
* @example
|
|
3565
3906
|
* ```ts
|
|
3566
|
-
* import {
|
|
3907
|
+
* import { ref } from 'vue'
|
|
3908
|
+
* import { useResizeObserver } from '@vuetify/v0'
|
|
3567
3909
|
*
|
|
3568
|
-
* const
|
|
3569
|
-
*
|
|
3570
|
-
*
|
|
3571
|
-
*
|
|
3572
|
-
*
|
|
3910
|
+
* const el = ref<HTMLElement>()
|
|
3911
|
+
* const width = ref(0)
|
|
3912
|
+
* const height = ref(0)
|
|
3913
|
+
*
|
|
3914
|
+
* const { pause, resume, isPaused } = useResizeObserver(
|
|
3915
|
+
* el,
|
|
3916
|
+
* (entries) => {
|
|
3917
|
+
* const entry = entries[0]
|
|
3918
|
+
* if (entry) {
|
|
3919
|
+
* width.value = entry.contentRect.width
|
|
3920
|
+
* height.value = entry.contentRect.height
|
|
3921
|
+
* console.log('Size changed:', width.value, 'x', height.value)
|
|
3922
|
+
* }
|
|
3573
3923
|
* },
|
|
3574
|
-
* }
|
|
3924
|
+
* { immediate: true }
|
|
3925
|
+
* )
|
|
3926
|
+
*
|
|
3927
|
+
* // Pause observation
|
|
3928
|
+
* pause()
|
|
3929
|
+
*
|
|
3930
|
+
* // Resume observation
|
|
3931
|
+
* resume()
|
|
3575
3932
|
* ```
|
|
3576
3933
|
*/
|
|
3577
|
-
function
|
|
3578
|
-
const {
|
|
3579
|
-
const
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3934
|
+
function useResizeObserver(target, callback, options = {}) {
|
|
3935
|
+
const { isHydrated } = useHydration();
|
|
3936
|
+
const observer = shallowRef();
|
|
3937
|
+
const isPaused = shallowRef(false);
|
|
3938
|
+
const isActive = toRef(() => !!observer.value);
|
|
3939
|
+
function setup() {
|
|
3940
|
+
if (!isHydrated.value || !SUPPORTS_OBSERVER || !target.value || isPaused.value) return;
|
|
3941
|
+
observer.value = new ResizeObserver((entries) => {
|
|
3942
|
+
callback(entries.map((entry) => ({
|
|
3943
|
+
contentRect: {
|
|
3944
|
+
width: entry.contentRect.width,
|
|
3945
|
+
height: entry.contentRect.height,
|
|
3946
|
+
top: entry.contentRect.top,
|
|
3947
|
+
left: entry.contentRect.left
|
|
3948
|
+
},
|
|
3949
|
+
target: entry.target
|
|
3950
|
+
})));
|
|
3951
|
+
});
|
|
3952
|
+
observer.value.observe(target.value, { box: options.box || "content-box" });
|
|
3953
|
+
if (options.immediate) {
|
|
3954
|
+
const rect = target.value.getBoundingClientRect();
|
|
3955
|
+
callback([{
|
|
3956
|
+
contentRect: {
|
|
3957
|
+
width: rect.width,
|
|
3958
|
+
height: rect.height,
|
|
3959
|
+
top: rect.top,
|
|
3960
|
+
left: rect.left
|
|
3961
|
+
},
|
|
3962
|
+
target: target.value
|
|
3963
|
+
}]);
|
|
3585
3964
|
}
|
|
3586
3965
|
}
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3966
|
+
watch([isHydrated, target], () => {
|
|
3967
|
+
cleanup();
|
|
3968
|
+
setup();
|
|
3969
|
+
}, { immediate: true });
|
|
3970
|
+
function cleanup() {
|
|
3971
|
+
if (observer.value) {
|
|
3972
|
+
observer.value.disconnect();
|
|
3973
|
+
observer.value = void 0;
|
|
3974
|
+
}
|
|
3590
3975
|
}
|
|
3976
|
+
function pause() {
|
|
3977
|
+
isPaused.value = true;
|
|
3978
|
+
observer.value?.disconnect();
|
|
3979
|
+
}
|
|
3980
|
+
function resume() {
|
|
3981
|
+
isPaused.value = false;
|
|
3982
|
+
setup();
|
|
3983
|
+
}
|
|
3984
|
+
function stop() {
|
|
3985
|
+
cleanup();
|
|
3986
|
+
}
|
|
3987
|
+
onScopeDispose(stop, true);
|
|
3591
3988
|
return {
|
|
3592
|
-
|
|
3593
|
-
|
|
3989
|
+
isActive: shallowReadonly(isActive),
|
|
3990
|
+
isPaused: shallowReadonly(isPaused),
|
|
3991
|
+
pause,
|
|
3992
|
+
resume,
|
|
3993
|
+
stop
|
|
3594
3994
|
};
|
|
3595
3995
|
}
|
|
3596
3996
|
/**
|
|
3597
|
-
*
|
|
3997
|
+
* A convenience composable that uses the Resize Observer API to track an
|
|
3998
|
+
* element's size.
|
|
3598
3999
|
*
|
|
3599
|
-
* @param
|
|
3600
|
-
* @
|
|
3601
|
-
* @template E The type of the permission context.
|
|
3602
|
-
* @returns A new permissions context.
|
|
4000
|
+
* @param target The element to observe.
|
|
4001
|
+
* @returns An object with the element's width and height.
|
|
3603
4002
|
*
|
|
3604
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
4003
|
+
* @see https://0.vuetifyjs.com/composables/system/use-resize-observer#use-element-size
|
|
3605
4004
|
*
|
|
3606
4005
|
* @example
|
|
3607
4006
|
* ```ts
|
|
3608
|
-
* import {
|
|
4007
|
+
* import { ref, watchEffect } from 'vue'
|
|
4008
|
+
* import { useElementSize } from '@vuetify/v0'
|
|
3609
4009
|
*
|
|
3610
|
-
*
|
|
3611
|
-
*
|
|
3612
|
-
*
|
|
3613
|
-
*
|
|
3614
|
-
*
|
|
3615
|
-
*
|
|
4010
|
+
* const box = ref<HTMLElement>()
|
|
4011
|
+
* const { width, height } = useElementSize(box)
|
|
4012
|
+
*
|
|
4013
|
+
* // Width and height are reactive refs
|
|
4014
|
+
* watchEffect(() => {
|
|
4015
|
+
* console.log('Box size:', width.value, 'x', height.value)
|
|
3616
4016
|
* })
|
|
3617
4017
|
* ```
|
|
3618
4018
|
*/
|
|
3619
|
-
function
|
|
3620
|
-
const
|
|
3621
|
-
const
|
|
3622
|
-
const
|
|
3623
|
-
|
|
3624
|
-
|
|
4019
|
+
function useElementSize(target) {
|
|
4020
|
+
const width = shallowRef(0);
|
|
4021
|
+
const height = shallowRef(0);
|
|
4022
|
+
const { pause: _pause, resume, stop, isActive, isPaused } = useResizeObserver(target, (entries) => {
|
|
4023
|
+
const entry = entries[0];
|
|
4024
|
+
if (entry) {
|
|
4025
|
+
width.value = entry.contentRect.width;
|
|
4026
|
+
height.value = entry.contentRect.height;
|
|
4027
|
+
}
|
|
4028
|
+
}, { immediate: true });
|
|
4029
|
+
function pause() {
|
|
4030
|
+
width.value = 0;
|
|
4031
|
+
height.value = 0;
|
|
4032
|
+
_pause();
|
|
3625
4033
|
}
|
|
3626
|
-
return
|
|
4034
|
+
return {
|
|
4035
|
+
width,
|
|
4036
|
+
height,
|
|
4037
|
+
isActive,
|
|
4038
|
+
isPaused,
|
|
4039
|
+
pause,
|
|
4040
|
+
resume,
|
|
4041
|
+
stop
|
|
4042
|
+
};
|
|
3627
4043
|
}
|
|
4044
|
+
|
|
4045
|
+
//#endregion
|
|
4046
|
+
//#region src/composables/useOverflow/index.ts
|
|
3628
4047
|
/**
|
|
3629
|
-
*
|
|
3630
|
-
*
|
|
3631
|
-
* @param options The options for the permissions plugin.
|
|
3632
|
-
* @template Z The type of the permission ticket.
|
|
3633
|
-
* @template E The type of the permission context.
|
|
3634
|
-
* @returns A new permissions plugin.
|
|
4048
|
+
* @module useOverflow
|
|
3635
4049
|
*
|
|
3636
|
-
* @
|
|
4050
|
+
* @remarks
|
|
4051
|
+
* Composable for computing how many items fit in a container based on available width.
|
|
4052
|
+
* Enables responsive truncation logic for Pagination, Breadcrumbs, and similar components.
|
|
3637
4053
|
*
|
|
3638
|
-
*
|
|
3639
|
-
*
|
|
3640
|
-
*
|
|
3641
|
-
*
|
|
3642
|
-
*
|
|
4054
|
+
* Key features:
|
|
4055
|
+
* - Container width tracking via ResizeObserver
|
|
4056
|
+
* - Two modes: variable-width (per-item) or uniform-width (sample-based)
|
|
4057
|
+
* - Computes capacity (how many items fit)
|
|
4058
|
+
* - SSR-safe with Infinity fallback
|
|
4059
|
+
* - Supports reserved space for nav buttons, ellipsis, etc.
|
|
4060
|
+
*
|
|
4061
|
+
* Use variable mode (default) for items with different widths like Breadcrumbs.
|
|
4062
|
+
* Use uniform mode (itemWidth option) for same-width items like Pagination buttons.
|
|
4063
|
+
*/
|
|
4064
|
+
/**
|
|
4065
|
+
* Creates a new overflow context for computing how many items fit in a container.
|
|
3643
4066
|
*
|
|
3644
|
-
*
|
|
4067
|
+
* @param options Configuration options
|
|
4068
|
+
* @returns Overflow context with container ref, capacity, and measurement functions
|
|
3645
4069
|
*
|
|
3646
|
-
*
|
|
3647
|
-
*
|
|
3648
|
-
*
|
|
3649
|
-
*
|
|
3650
|
-
*
|
|
3651
|
-
*
|
|
4070
|
+
* @example Variable-width mode (Breadcrumbs)
|
|
4071
|
+
* ```vue
|
|
4072
|
+
* <script lang="ts" setup>
|
|
4073
|
+
* import { useTemplateRef } from 'vue'
|
|
4074
|
+
* import { createOverflow } from '@vuetify/v0'
|
|
4075
|
+
*
|
|
4076
|
+
* const containerRef = useTemplateRef('container')
|
|
4077
|
+
* const overflow = createOverflow({
|
|
4078
|
+
* container: containerRef,
|
|
4079
|
+
* gap: 8,
|
|
4080
|
+
* reserved: 40,
|
|
3652
4081
|
* })
|
|
3653
|
-
*
|
|
4082
|
+
* <\/script>
|
|
3654
4083
|
*
|
|
3655
|
-
*
|
|
4084
|
+
* <template>
|
|
4085
|
+
* <div ref="container">
|
|
4086
|
+
* <span
|
|
4087
|
+
* v-for="(item, i) in items.slice(0, overflow.capacity.value)"
|
|
4088
|
+
* :key="i"
|
|
4089
|
+
* :ref="el => overflow.measure(i, el)"
|
|
4090
|
+
* >
|
|
4091
|
+
* {{ item }}
|
|
4092
|
+
* </span>
|
|
4093
|
+
* <span v-if="overflow.isOverflowing.value">...</span>
|
|
4094
|
+
* </div>
|
|
4095
|
+
* </template>
|
|
4096
|
+
* ```
|
|
4097
|
+
*
|
|
4098
|
+
* @example Uniform-width mode (Pagination)
|
|
4099
|
+
* ```ts
|
|
4100
|
+
* const overflow = createOverflow({
|
|
4101
|
+
* container: () => atom.value?.element,
|
|
4102
|
+
* itemWidth: buttonWidth,
|
|
4103
|
+
* reserved: () => buttonWidth.value * 4,
|
|
4104
|
+
* })
|
|
3656
4105
|
* ```
|
|
3657
4106
|
*/
|
|
3658
|
-
function
|
|
3659
|
-
const {
|
|
3660
|
-
const
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
4107
|
+
function createOverflow(options = {}) {
|
|
4108
|
+
const { container: _container, gap = 0, reserved = 0, itemWidth, reverse } = options;
|
|
4109
|
+
const container = /* @__PURE__ */ isUndefined(_container) ? shallowRef() : toRef(_container);
|
|
4110
|
+
const widths = shallowRef(/* @__PURE__ */ new Map());
|
|
4111
|
+
const { width } = useElementSize(container);
|
|
4112
|
+
function measure(index, el) {
|
|
4113
|
+
if (!el) {
|
|
4114
|
+
if (widths.value.has(index)) {
|
|
4115
|
+
const next = new Map(widths.value);
|
|
4116
|
+
next.delete(index);
|
|
4117
|
+
widths.value = next;
|
|
4118
|
+
}
|
|
4119
|
+
return;
|
|
4120
|
+
}
|
|
4121
|
+
const style = getComputedStyle(el);
|
|
4122
|
+
const marginX = Number.parseFloat(style.marginLeft) + Number.parseFloat(style.marginRight);
|
|
4123
|
+
const w = el.offsetWidth + marginX;
|
|
4124
|
+
if (widths.value.get(index) !== w) widths.value = new Map(widths.value).set(index, w);
|
|
4125
|
+
}
|
|
4126
|
+
function reset() {
|
|
4127
|
+
widths.value = /* @__PURE__ */ new Map();
|
|
4128
|
+
}
|
|
4129
|
+
const total = computed(() => {
|
|
4130
|
+
const g = toValue(gap);
|
|
4131
|
+
let sum = 0;
|
|
4132
|
+
let count = 0;
|
|
4133
|
+
for (const w of widths.value.values()) {
|
|
4134
|
+
sum += w + (count > 0 ? g : 0);
|
|
4135
|
+
count++;
|
|
3668
4136
|
}
|
|
4137
|
+
return sum;
|
|
3669
4138
|
});
|
|
4139
|
+
return {
|
|
4140
|
+
container,
|
|
4141
|
+
width,
|
|
4142
|
+
capacity: computed(() => {
|
|
4143
|
+
const available = width.value - toValue(reserved);
|
|
4144
|
+
if (width.value === 0) return Infinity;
|
|
4145
|
+
if (available <= 0) return 0;
|
|
4146
|
+
const g = toValue(gap);
|
|
4147
|
+
const uniformWidth = toValue(itemWidth);
|
|
4148
|
+
if (uniformWidth && uniformWidth > 0) {
|
|
4149
|
+
const first = uniformWidth;
|
|
4150
|
+
const subsequent = uniformWidth + g;
|
|
4151
|
+
if (available < first) return 0;
|
|
4152
|
+
return Math.max(1, Math.floor((available - first) / subsequent) + 1);
|
|
4153
|
+
}
|
|
4154
|
+
const entries = [...widths.value.entries()].toSorted((a, b) => a[0] - b[0]);
|
|
4155
|
+
if (toValue(reverse)) entries.reverse();
|
|
4156
|
+
let sum = 0;
|
|
4157
|
+
let count = 0;
|
|
4158
|
+
for (const [, w] of entries) {
|
|
4159
|
+
const next = sum + w + (count > 0 ? g : 0);
|
|
4160
|
+
if (next > available) break;
|
|
4161
|
+
sum = next;
|
|
4162
|
+
count++;
|
|
4163
|
+
}
|
|
4164
|
+
return count;
|
|
4165
|
+
}),
|
|
4166
|
+
total,
|
|
4167
|
+
isOverflowing: toRef(() => {
|
|
4168
|
+
return total.value > width.value - toValue(reserved);
|
|
4169
|
+
}),
|
|
4170
|
+
measure,
|
|
4171
|
+
reset
|
|
4172
|
+
};
|
|
3670
4173
|
}
|
|
3671
4174
|
/**
|
|
3672
|
-
*
|
|
4175
|
+
* Creates an overflow context with dependency injection support.
|
|
3673
4176
|
*
|
|
3674
|
-
* @
|
|
3675
|
-
* @returns
|
|
4177
|
+
* @param options Configuration options including namespace
|
|
4178
|
+
* @returns Trinity tuple: [useContext, provideContext, defaultContext]
|
|
3676
4179
|
*
|
|
3677
|
-
* @
|
|
4180
|
+
* @example
|
|
4181
|
+
* ```ts
|
|
4182
|
+
* // Create injectable context
|
|
4183
|
+
* const [useOverflow, provideOverflow, overflow] = createOverflowContext({
|
|
4184
|
+
* namespace: 'my-overflow',
|
|
4185
|
+
* gap: 8,
|
|
4186
|
+
* reserved: 160,
|
|
4187
|
+
* })
|
|
4188
|
+
*
|
|
4189
|
+
* // In parent component
|
|
4190
|
+
* provideOverflow()
|
|
4191
|
+
*
|
|
4192
|
+
* // In child component
|
|
4193
|
+
* const overflow = useOverflow()
|
|
4194
|
+
* ```
|
|
4195
|
+
*/
|
|
4196
|
+
function createOverflowContext(_options = {}) {
|
|
4197
|
+
const { namespace = "v0:overflow",...options } = _options;
|
|
4198
|
+
const [useOverflowContext, _provideOverflowContext] = createContext(namespace);
|
|
4199
|
+
const context = createOverflow(options);
|
|
4200
|
+
function provideOverflowContext(_context = context, app) {
|
|
4201
|
+
return _provideOverflowContext(_context, app);
|
|
4202
|
+
}
|
|
4203
|
+
return createTrinity(useOverflowContext, provideOverflowContext, context);
|
|
4204
|
+
}
|
|
4205
|
+
/**
|
|
4206
|
+
* Returns the current overflow context from dependency injection.
|
|
4207
|
+
*
|
|
4208
|
+
* @param namespace The namespace for the overflow context. Defaults to `v0:overflow`.
|
|
4209
|
+
* @returns The current overflow context.
|
|
3678
4210
|
*
|
|
3679
4211
|
* @example
|
|
3680
4212
|
* ```vue
|
|
3681
|
-
* <script
|
|
3682
|
-
* import {
|
|
4213
|
+
* <script lang="ts" setup>
|
|
4214
|
+
* import { useOverflow } from '@vuetify/v0'
|
|
3683
4215
|
*
|
|
3684
|
-
*
|
|
4216
|
+
* // Inject overflow context provided by parent
|
|
4217
|
+
* const overflow = useOverflow()
|
|
3685
4218
|
* <\/script>
|
|
3686
4219
|
*
|
|
3687
4220
|
* <template>
|
|
3688
4221
|
* <div>
|
|
3689
|
-
* <p
|
|
4222
|
+
* <p>Capacity: {{ overflow.capacity.value }}</p>
|
|
3690
4223
|
* </div>
|
|
3691
4224
|
* </template>
|
|
3692
4225
|
* ```
|
|
3693
4226
|
*/
|
|
3694
|
-
function
|
|
4227
|
+
function useOverflow(namespace = "v0:overflow") {
|
|
3695
4228
|
return useContext(namespace);
|
|
3696
4229
|
}
|
|
3697
4230
|
|
|
3698
4231
|
//#endregion
|
|
3699
|
-
//#region src/composables/
|
|
4232
|
+
//#region src/composables/usePagination/index.ts
|
|
3700
4233
|
/**
|
|
3701
|
-
* @module
|
|
4234
|
+
* @module usePagination
|
|
3702
4235
|
*
|
|
3703
4236
|
* @remarks
|
|
3704
|
-
*
|
|
4237
|
+
* Lightweight pagination composable for navigating through pages.
|
|
3705
4238
|
*
|
|
3706
4239
|
* Key features:
|
|
3707
|
-
* -
|
|
3708
|
-
* -
|
|
3709
|
-
* -
|
|
3710
|
-
* -
|
|
3711
|
-
*
|
|
3712
|
-
*
|
|
4240
|
+
* - No registry overhead - just a bounded integer
|
|
4241
|
+
* - Direct ref support for v-model compatibility
|
|
4242
|
+
* - Navigation methods: next, prev, first, last
|
|
4243
|
+
* - Computed visible items with ellipsis
|
|
4244
|
+
* - Trinity pattern for dependency injection
|
|
4245
|
+
*
|
|
4246
|
+
* Unlike registry-based composables, pagination tracks a single number
|
|
4247
|
+
* within a range, making it efficient for large page counts.
|
|
3713
4248
|
*/
|
|
3714
4249
|
/**
|
|
3715
|
-
*
|
|
3716
|
-
*
|
|
3717
|
-
* @param registry The selection registry to bind to.
|
|
3718
|
-
* @param model The ref to sync.
|
|
3719
|
-
* @param options The options for the proxy model.
|
|
3720
|
-
* @template Z The type of the selection ticket.
|
|
3721
|
-
* @returns A function to stop the sync.
|
|
4250
|
+
* Creates a pagination instance.
|
|
3722
4251
|
*
|
|
3723
|
-
* @
|
|
4252
|
+
* @param options The options for the pagination instance.
|
|
4253
|
+
* @returns A pagination context with navigation methods.
|
|
3724
4254
|
*
|
|
3725
4255
|
* @example
|
|
3726
4256
|
* ```ts
|
|
3727
|
-
* import {
|
|
4257
|
+
* import { createPagination } from '@vuetify/v0'
|
|
3728
4258
|
*
|
|
3729
|
-
*
|
|
3730
|
-
* const
|
|
3731
|
-
*
|
|
3732
|
-
*
|
|
3733
|
-
* { id: 'item-2', value: 'Item 2' },
|
|
3734
|
-
* ])
|
|
4259
|
+
* // Basic usage
|
|
4260
|
+
* const pagination = createPagination({ size: 100 })
|
|
4261
|
+
* pagination.next()
|
|
4262
|
+
* pagination.items.value // [{ type: 'page', value: 1 }, { type: 'page', value: 2 }, ...]
|
|
3735
4263
|
*
|
|
3736
|
-
*
|
|
4264
|
+
* // With v-model (pass a ref)
|
|
4265
|
+
* const page = ref(1)
|
|
4266
|
+
* const pagination = createPagination({ page, size: 100 })
|
|
4267
|
+
* // Mutating pagination.page or the passed ref syncs both
|
|
3737
4268
|
* ```
|
|
3738
4269
|
*/
|
|
3739
|
-
function
|
|
3740
|
-
const
|
|
3741
|
-
const
|
|
3742
|
-
const
|
|
3743
|
-
|
|
3744
|
-
const
|
|
3745
|
-
|
|
4270
|
+
function createPagination(_options = {}) {
|
|
4271
|
+
const { page: _page = 1, itemsPerPage: _itemsPerPage = 10, size: _size = 0, visible: _visible = 7, ellipsis = "..." } = _options;
|
|
4272
|
+
const page = isRef(_page) ? _page : shallowRef(_page);
|
|
4273
|
+
const pages = computed(() => {
|
|
4274
|
+
const size = toValue(_size);
|
|
4275
|
+
const perPage = toValue(_itemsPerPage);
|
|
4276
|
+
if (size <= 0 || /* @__PURE__ */ isNaN(size)) return 0;
|
|
4277
|
+
return Math.ceil(size / perPage);
|
|
4278
|
+
});
|
|
4279
|
+
function first() {
|
|
4280
|
+
page.value = 1;
|
|
3746
4281
|
}
|
|
3747
|
-
function
|
|
3748
|
-
|
|
3749
|
-
return multiple ? val : val[0];
|
|
4282
|
+
function last() {
|
|
4283
|
+
page.value = pages.value;
|
|
3750
4284
|
}
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
for (const value of modelAsArray) {
|
|
3754
|
-
const ids = registry.browse(value);
|
|
3755
|
-
if (/* @__PURE__ */ isArray(ids)) {
|
|
3756
|
-
for (const id of ids) registry.select(id);
|
|
3757
|
-
pending.delete(value);
|
|
3758
|
-
} else if (ids) {
|
|
3759
|
-
registry.select(ids);
|
|
3760
|
-
pending.delete(value);
|
|
3761
|
-
}
|
|
4285
|
+
function next() {
|
|
4286
|
+
if (page.value < pages.value) page.value++;
|
|
3762
4287
|
}
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
} else {
|
|
3781
|
-
const next = targetIds.values().next().value;
|
|
3782
|
-
const last = currentIds.values().next().value;
|
|
3783
|
-
if (last !== void 0) registry.unselect(last);
|
|
3784
|
-
if (next !== void 0) registry.select(next);
|
|
3785
|
-
}
|
|
3786
|
-
registryWatch.resume();
|
|
3787
|
-
}, {
|
|
3788
|
-
flush: "sync",
|
|
3789
|
-
deep: multiple
|
|
3790
|
-
});
|
|
3791
|
-
function onRegister(ticket) {
|
|
3792
|
-
if (!pending.has(ticket.value) || ticket.disabled) return;
|
|
3793
|
-
registryWatch.pause();
|
|
3794
|
-
modelWatch.pause();
|
|
3795
|
-
registry.select(ticket.id);
|
|
3796
|
-
pending.delete(ticket.value);
|
|
3797
|
-
modelWatch.resume();
|
|
3798
|
-
registryWatch.resume();
|
|
4288
|
+
function prev() {
|
|
4289
|
+
if (page.value > 1) page.value--;
|
|
4290
|
+
}
|
|
4291
|
+
function select(value) {
|
|
4292
|
+
if (value < 1) page.value = 1;
|
|
4293
|
+
else if (value > pages.value) page.value = pages.value;
|
|
4294
|
+
else page.value = value;
|
|
4295
|
+
}
|
|
4296
|
+
const isFirst = computed(() => page.value <= 1);
|
|
4297
|
+
const isLast = computed(() => page.value >= pages.value);
|
|
4298
|
+
const pageStart = computed(() => (page.value - 1) * toValue(_itemsPerPage));
|
|
4299
|
+
const pageStop = computed(() => Math.min(pageStart.value + toValue(_itemsPerPage), toValue(_size)));
|
|
4300
|
+
function toPage(value) {
|
|
4301
|
+
return {
|
|
4302
|
+
type: "page",
|
|
4303
|
+
value
|
|
4304
|
+
};
|
|
3799
4305
|
}
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
4306
|
+
function toEllipsis() {
|
|
4307
|
+
return ellipsis === false ? false : {
|
|
4308
|
+
type: "ellipsis",
|
|
4309
|
+
value: ellipsis
|
|
4310
|
+
};
|
|
3805
4311
|
}
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
}
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
4312
|
+
function filter(array) {
|
|
4313
|
+
return array.filter(Boolean);
|
|
4314
|
+
}
|
|
4315
|
+
return {
|
|
4316
|
+
page,
|
|
4317
|
+
ellipsis,
|
|
4318
|
+
items: computed(() => {
|
|
4319
|
+
const pageCount = pages.value;
|
|
4320
|
+
const visible = toValue(_visible);
|
|
4321
|
+
const current = page.value;
|
|
4322
|
+
if (pageCount <= 0 || /* @__PURE__ */ isNaN(pageCount) || pageCount > Number.MAX_SAFE_INTEGER) return [];
|
|
4323
|
+
if (visible <= 0) return [];
|
|
4324
|
+
if (visible <= 2) return [toPage(current)];
|
|
4325
|
+
if (pageCount <= visible) return (/* @__PURE__ */ range(pageCount, 1)).map(toPage);
|
|
4326
|
+
if (visible === 3) {
|
|
4327
|
+
const mid = current <= 1 ? 2 : current >= pageCount ? pageCount - 1 : current;
|
|
4328
|
+
return [
|
|
4329
|
+
toPage(1),
|
|
4330
|
+
toPage(mid),
|
|
4331
|
+
toPage(pageCount)
|
|
4332
|
+
];
|
|
4333
|
+
}
|
|
4334
|
+
const boundary = visible - 2;
|
|
4335
|
+
const middle = visible - 4;
|
|
4336
|
+
if (middle <= 0) {
|
|
4337
|
+
if (current <= boundary) return filter([
|
|
4338
|
+
...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
|
|
4339
|
+
toEllipsis(),
|
|
4340
|
+
toPage(pageCount)
|
|
4341
|
+
]);
|
|
4342
|
+
if (current > pageCount - boundary) return filter([
|
|
4343
|
+
toPage(1),
|
|
4344
|
+
toEllipsis(),
|
|
4345
|
+
...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
|
|
4346
|
+
]);
|
|
4347
|
+
return current <= Math.ceil(pageCount / 2) ? filter([
|
|
4348
|
+
toPage(1),
|
|
4349
|
+
toPage(current),
|
|
4350
|
+
toEllipsis(),
|
|
4351
|
+
toPage(pageCount)
|
|
4352
|
+
]) : filter([
|
|
4353
|
+
toPage(1),
|
|
4354
|
+
toEllipsis(),
|
|
4355
|
+
toPage(current),
|
|
4356
|
+
toPage(pageCount)
|
|
4357
|
+
]);
|
|
4358
|
+
}
|
|
4359
|
+
const leftThreshold = boundary - 1;
|
|
4360
|
+
const rightThreshold = pageCount - boundary + 2;
|
|
4361
|
+
if (current <= leftThreshold) return filter([
|
|
4362
|
+
...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
|
|
4363
|
+
toEllipsis(),
|
|
4364
|
+
toPage(pageCount)
|
|
4365
|
+
]);
|
|
4366
|
+
else if (current >= rightThreshold) return filter([
|
|
4367
|
+
toPage(1),
|
|
4368
|
+
toEllipsis(),
|
|
4369
|
+
...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
|
|
4370
|
+
]);
|
|
4371
|
+
else {
|
|
4372
|
+
const start = current - Math.floor(middle / 2);
|
|
4373
|
+
return filter([
|
|
4374
|
+
toPage(1),
|
|
4375
|
+
toEllipsis(),
|
|
4376
|
+
...(/* @__PURE__ */ range(middle, start)).map(toPage),
|
|
4377
|
+
toEllipsis(),
|
|
4378
|
+
toPage(pageCount)
|
|
4379
|
+
]);
|
|
4380
|
+
}
|
|
4381
|
+
}),
|
|
4382
|
+
pageStart,
|
|
4383
|
+
pageStop,
|
|
4384
|
+
isFirst,
|
|
4385
|
+
isLast,
|
|
4386
|
+
first,
|
|
4387
|
+
last,
|
|
4388
|
+
next,
|
|
4389
|
+
prev,
|
|
4390
|
+
select,
|
|
4391
|
+
get itemsPerPage() {
|
|
4392
|
+
return toValue(_itemsPerPage);
|
|
4393
|
+
},
|
|
4394
|
+
get size() {
|
|
4395
|
+
return toValue(_size);
|
|
4396
|
+
},
|
|
4397
|
+
get pages() {
|
|
4398
|
+
return pages.value;
|
|
4399
|
+
}
|
|
4400
|
+
};
|
|
4401
|
+
}
|
|
4402
|
+
/**
|
|
4403
|
+
* Creates a pagination context for dependency injection.
|
|
3824
4404
|
*
|
|
3825
|
-
*
|
|
4405
|
+
* @param options The options including namespace.
|
|
4406
|
+
* @returns A trinity: [usePagination, providePagination, defaultContext]
|
|
4407
|
+
*
|
|
4408
|
+
* @example
|
|
4409
|
+
* ```ts
|
|
4410
|
+
* // With default namespace 'v0:pagination'
|
|
4411
|
+
* const [usePagination, providePaginationContext] = createPaginationContext({ size: 50 })
|
|
4412
|
+
*
|
|
4413
|
+
* // Or with custom namespace
|
|
4414
|
+
* const [usePagination, providePaginationContext] = createPaginationContext({
|
|
4415
|
+
* namespace: 'my-pagination',
|
|
4416
|
+
* size: 50,
|
|
4417
|
+
* })
|
|
4418
|
+
*
|
|
4419
|
+
* // Parent component
|
|
4420
|
+
* providePaginationContext()
|
|
4421
|
+
*
|
|
4422
|
+
* // Child component
|
|
4423
|
+
* const pagination = usePagination()
|
|
4424
|
+
* pagination.next()
|
|
4425
|
+
* ```
|
|
3826
4426
|
*/
|
|
4427
|
+
function createPaginationContext(_options = {}) {
|
|
4428
|
+
const { namespace = "v0:pagination",...options } = _options;
|
|
4429
|
+
const [usePaginationContext, _providePaginationContext] = createContext(namespace);
|
|
4430
|
+
const context = createPagination(options);
|
|
4431
|
+
function providePaginationContext(_context = context, app) {
|
|
4432
|
+
return _providePaginationContext(_context, app);
|
|
4433
|
+
}
|
|
4434
|
+
return createTrinity(usePaginationContext, providePaginationContext, context);
|
|
4435
|
+
}
|
|
3827
4436
|
/**
|
|
3828
|
-
*
|
|
4437
|
+
* Returns the current pagination instance from context.
|
|
3829
4438
|
*
|
|
3830
|
-
* @param
|
|
3831
|
-
* @
|
|
3832
|
-
* @template Z The type of the registry ticket.
|
|
3833
|
-
* @returns A proxy registry with reactive objects.
|
|
4439
|
+
* @param namespace The namespace. @default 'v0:pagination'
|
|
4440
|
+
* @returns The pagination context.
|
|
3834
4441
|
*
|
|
3835
|
-
* @
|
|
4442
|
+
* @example
|
|
4443
|
+
* ```vue
|
|
4444
|
+
* <script setup>
|
|
4445
|
+
* import { usePagination } from '@vuetify/v0'
|
|
4446
|
+
*
|
|
4447
|
+
* const pagination = usePagination()
|
|
4448
|
+
* <\/script>
|
|
4449
|
+
*
|
|
4450
|
+
* <template>
|
|
4451
|
+
* <button @click="pagination.prev()" :disabled="pagination.isFirst.value">Prev</button>
|
|
4452
|
+
* <button @click="pagination.next()" :disabled="pagination.isLast.value">Next</button>
|
|
4453
|
+
* </template>
|
|
4454
|
+
* ```
|
|
4455
|
+
*/
|
|
4456
|
+
function usePagination(namespace = "v0:pagination") {
|
|
4457
|
+
return useContext(namespace);
|
|
4458
|
+
}
|
|
4459
|
+
|
|
4460
|
+
//#endregion
|
|
4461
|
+
//#region src/composables/usePermissions/adapters/adapter.ts
|
|
4462
|
+
var PermissionAdapter = class {};
|
|
4463
|
+
|
|
4464
|
+
//#endregion
|
|
4465
|
+
//#region src/composables/usePermissions/adapters/v0.ts
|
|
4466
|
+
var Vuetify0PermissionAdapter = class extends PermissionAdapter {
|
|
4467
|
+
constructor() {
|
|
4468
|
+
super();
|
|
4469
|
+
}
|
|
4470
|
+
can(role, action, subject, context, permissions) {
|
|
4471
|
+
const access = `${role}.${action}.${subject}`;
|
|
4472
|
+
const ticket = permissions.get(access);
|
|
4473
|
+
if (!ticket || !ticket.value) return false;
|
|
4474
|
+
return /* @__PURE__ */ isFunction(ticket.value) ? ticket.value(context) : ticket.value;
|
|
4475
|
+
}
|
|
4476
|
+
};
|
|
4477
|
+
|
|
4478
|
+
//#endregion
|
|
4479
|
+
//#region src/composables/usePermissions/index.ts
|
|
4480
|
+
/**
|
|
4481
|
+
* @module usePermissions
|
|
4482
|
+
*
|
|
4483
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-permissions
|
|
4484
|
+
*
|
|
4485
|
+
* @remarks
|
|
4486
|
+
* Permission management composable with support for RBAC and ABAC patterns.
|
|
4487
|
+
*
|
|
4488
|
+
* Key features:
|
|
4489
|
+
* - Role-Based Access Control (RBAC) support
|
|
4490
|
+
* - Attribute-Based Access Control (ABAC) with context
|
|
4491
|
+
* - Functional permission conditions
|
|
4492
|
+
* - Token-based permission storage
|
|
4493
|
+
* - Adapter pattern for custom permission systems
|
|
4494
|
+
*
|
|
4495
|
+
* Built on useTokens for flexible permission configuration.
|
|
4496
|
+
*/
|
|
4497
|
+
/**
|
|
4498
|
+
* Creates a new permissions instance.
|
|
4499
|
+
*
|
|
4500
|
+
* @param options The options for the permissions instance.
|
|
4501
|
+
* @template Z The type of the permission ticket.
|
|
4502
|
+
* @template E The type of the permission context.
|
|
4503
|
+
* @returns A new permissions instance.
|
|
4504
|
+
*
|
|
4505
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-permissions
|
|
3836
4506
|
*
|
|
3837
4507
|
* @example
|
|
3838
4508
|
* ```ts
|
|
3839
|
-
* import {
|
|
4509
|
+
* import { createPermissions } from '@vuetify/v0'
|
|
3840
4510
|
*
|
|
3841
|
-
* const
|
|
3842
|
-
*
|
|
4511
|
+
* const [usePermissions, providePermissions] = createPermissions({
|
|
4512
|
+
* namespace: 'v0:permissions',
|
|
4513
|
+
* permissions: {
|
|
4514
|
+
* admin: [['read', 'users']],
|
|
4515
|
+
* editor: [['edit', 'posts']],
|
|
4516
|
+
* },
|
|
4517
|
+
* })
|
|
4518
|
+
* ```
|
|
4519
|
+
*/
|
|
4520
|
+
function createPermissions(_options = {}) {
|
|
4521
|
+
const { adapter = new Vuetify0PermissionAdapter(), permissions = {},...options } = _options;
|
|
4522
|
+
const record = {};
|
|
4523
|
+
for (const role in permissions) {
|
|
4524
|
+
if (!record[role]) record[role] = {};
|
|
4525
|
+
for (const [actions, subjects, condition = true] of permissions[role]) for (const action of toArray(actions)) for (const subject of toArray(subjects)) {
|
|
4526
|
+
if (!record[role][action]) record[role][action] = {};
|
|
4527
|
+
record[role][action][subject] = condition;
|
|
4528
|
+
}
|
|
4529
|
+
}
|
|
4530
|
+
const tokens = createTokens(record, options);
|
|
4531
|
+
function can(id, action, subject, context = {}) {
|
|
4532
|
+
return adapter.can(id, action, subject, context, tokens);
|
|
4533
|
+
}
|
|
4534
|
+
return {
|
|
4535
|
+
...tokens,
|
|
4536
|
+
can
|
|
4537
|
+
};
|
|
4538
|
+
}
|
|
4539
|
+
/**
|
|
4540
|
+
* Creates a new permissions context.
|
|
3843
4541
|
*
|
|
3844
|
-
*
|
|
3845
|
-
*
|
|
4542
|
+
* @param options The options for the permissions context.
|
|
4543
|
+
* @template Z The type of the permission ticket.
|
|
4544
|
+
* @template E The type of the permission context.
|
|
4545
|
+
* @returns A new permissions context.
|
|
4546
|
+
*
|
|
4547
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-permissions
|
|
4548
|
+
*
|
|
4549
|
+
* @example
|
|
4550
|
+
* ```ts
|
|
4551
|
+
* import { createPermissionsContext } from '@vuetify/v0'
|
|
4552
|
+
*
|
|
4553
|
+
* export const [usePermissions, providePermissions, context] = createPermissionsContext({
|
|
4554
|
+
* namespace: 'app:permissions',
|
|
4555
|
+
* permissions: {
|
|
4556
|
+
* admin: [['read', 'users'], ['edit', 'users']],
|
|
4557
|
+
* editor: [['edit', 'posts']],
|
|
4558
|
+
* },
|
|
4559
|
+
* })
|
|
3846
4560
|
* ```
|
|
3847
4561
|
*/
|
|
3848
|
-
function
|
|
3849
|
-
const
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
4562
|
+
function createPermissionsContext(_options = {}) {
|
|
4563
|
+
const { namespace = "v0:permissions",...options } = _options;
|
|
4564
|
+
const [usePermissionsContext, _providePermissionsContext] = createContext(namespace);
|
|
4565
|
+
const context = createPermissions(options);
|
|
4566
|
+
function providePermissionsContext(_context = context, app) {
|
|
4567
|
+
return _providePermissionsContext(_context, app);
|
|
4568
|
+
}
|
|
4569
|
+
return createTrinity(usePermissionsContext, providePermissionsContext, context);
|
|
4570
|
+
}
|
|
4571
|
+
/**
|
|
4572
|
+
* Creates a new permissions plugin.
|
|
4573
|
+
*
|
|
4574
|
+
* @param options The options for the permissions plugin.
|
|
4575
|
+
* @template Z The type of the permission ticket.
|
|
4576
|
+
* @template E The type of the permission context.
|
|
4577
|
+
* @returns A new permissions plugin.
|
|
4578
|
+
*
|
|
4579
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-permissions
|
|
4580
|
+
*
|
|
4581
|
+
* @example
|
|
4582
|
+
* ```ts
|
|
4583
|
+
* import { createApp } from 'vue'
|
|
4584
|
+
* import { createPermissionsPlugin } from '@vuetify/v0'
|
|
4585
|
+
* import App from './App.vue'
|
|
4586
|
+
*
|
|
4587
|
+
* const app = createApp(App)
|
|
4588
|
+
*
|
|
4589
|
+
* app.use(
|
|
4590
|
+
* createPermissionsPlugin({
|
|
4591
|
+
* permissions: {
|
|
4592
|
+
* admin: [['read', 'users']],
|
|
4593
|
+
* editor: [['edit', 'posts']],
|
|
4594
|
+
* },
|
|
4595
|
+
* })
|
|
4596
|
+
* )
|
|
4597
|
+
*
|
|
4598
|
+
* app.mount('#app')
|
|
4599
|
+
* ```
|
|
4600
|
+
*/
|
|
4601
|
+
function createPermissionsPlugin(_options = {}) {
|
|
4602
|
+
const { namespace = "v0:permissions",...options } = _options;
|
|
4603
|
+
const [, providePermissionContext, context] = createPermissionsContext({
|
|
4604
|
+
...options,
|
|
4605
|
+
namespace
|
|
4606
|
+
});
|
|
4607
|
+
return createPlugin({
|
|
4608
|
+
namespace,
|
|
4609
|
+
provide: (app) => {
|
|
4610
|
+
providePermissionContext(context, app);
|
|
4611
|
+
}
|
|
4612
|
+
});
|
|
4613
|
+
}
|
|
4614
|
+
/**
|
|
4615
|
+
* Returns the current permissions instance.
|
|
4616
|
+
*
|
|
4617
|
+
* @template Z The type of the permission ticket.
|
|
4618
|
+
* @returns The current permissions instance.
|
|
4619
|
+
*
|
|
4620
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-permissions
|
|
4621
|
+
*
|
|
4622
|
+
* @example
|
|
4623
|
+
* ```vue
|
|
4624
|
+
* <script setup lang="ts">
|
|
4625
|
+
* import { usePermissions } from '@vuetify/v0'
|
|
4626
|
+
*
|
|
4627
|
+
* const { can } = usePermissions()
|
|
4628
|
+
* <\/script>
|
|
4629
|
+
*
|
|
4630
|
+
* <template>
|
|
4631
|
+
* <div>
|
|
4632
|
+
* <p v-if="can('admin', 'read', 'users')">Admin access</p>
|
|
4633
|
+
* </div>
|
|
4634
|
+
* </template>
|
|
4635
|
+
* ```
|
|
4636
|
+
*/
|
|
4637
|
+
function usePermissions(namespace = "v0:permissions") {
|
|
4638
|
+
return useContext(namespace);
|
|
4639
|
+
}
|
|
4640
|
+
|
|
4641
|
+
//#endregion
|
|
4642
|
+
//#region src/composables/useProxyModel/index.ts
|
|
4643
|
+
/**
|
|
4644
|
+
* @module useProxyModel
|
|
4645
|
+
*
|
|
4646
|
+
* @remarks
|
|
4647
|
+
* Proxy composable for bidirectional sync between selection registry and v-model.
|
|
4648
|
+
*
|
|
4649
|
+
* Key features:
|
|
4650
|
+
* - Bidirectional synchronization
|
|
4651
|
+
* - Array and single-value modes
|
|
4652
|
+
* - Automatic cleanup on scope disposal
|
|
4653
|
+
* - Perfect for form controls with selection backing
|
|
4654
|
+
*
|
|
4655
|
+
* Bridges the gap between selection composables and Vue's v-model.
|
|
4656
|
+
*/
|
|
4657
|
+
/**
|
|
4658
|
+
* Syncs a ref with a selection registry bidirectionally.
|
|
4659
|
+
*
|
|
4660
|
+
* @param registry The selection registry to bind to.
|
|
4661
|
+
* @param model The ref to sync.
|
|
4662
|
+
* @param options The options for the proxy model.
|
|
4663
|
+
* @template Z The type of the selection ticket.
|
|
4664
|
+
* @returns A function to stop the sync.
|
|
4665
|
+
*
|
|
4666
|
+
* @see https://0.vuetifyjs.com/composables/forms/use-proxy-model
|
|
4667
|
+
*
|
|
4668
|
+
* @example
|
|
4669
|
+
* ```ts
|
|
4670
|
+
* import { createSelection, useProxyModel } from '@vuetify/v0'
|
|
4671
|
+
*
|
|
4672
|
+
* const model = ref()
|
|
4673
|
+
* const registry = createSelection({ events: true })
|
|
4674
|
+
* registry.onboard([
|
|
4675
|
+
* { id: 'item-1', value: 'Item 1' },
|
|
4676
|
+
* { id: 'item-2', value: 'Item 2' },
|
|
4677
|
+
* ])
|
|
4678
|
+
*
|
|
4679
|
+
* const stop = useProxyModel(registry, model)
|
|
4680
|
+
* ```
|
|
4681
|
+
*/
|
|
4682
|
+
function useProxyModel(registry, model, options) {
|
|
4683
|
+
const multiple = options?.multiple ?? false;
|
|
4684
|
+
const _transformIn = options?.transformIn;
|
|
4685
|
+
const _transformOut = options?.transformOut;
|
|
4686
|
+
function transformIn(val) {
|
|
4687
|
+
const value = toValue(val);
|
|
4688
|
+
return toArray(/* @__PURE__ */ isFunction(_transformIn) ? _transformIn(value) : value);
|
|
4689
|
+
}
|
|
4690
|
+
function transformOut(val) {
|
|
4691
|
+
if (/* @__PURE__ */ isFunction(_transformOut)) return _transformOut(val);
|
|
4692
|
+
return multiple ? val : val[0];
|
|
4693
|
+
}
|
|
4694
|
+
const modelAsArray = transformIn(model);
|
|
4695
|
+
const pending = new Set(modelAsArray);
|
|
4696
|
+
for (const value of modelAsArray) {
|
|
4697
|
+
const ids = registry.browse(value);
|
|
4698
|
+
if (/* @__PURE__ */ isArray(ids)) {
|
|
4699
|
+
for (const id of ids) registry.select(id);
|
|
4700
|
+
pending.delete(value);
|
|
4701
|
+
} else if (ids) {
|
|
4702
|
+
registry.select(ids);
|
|
4703
|
+
pending.delete(value);
|
|
4704
|
+
}
|
|
4705
|
+
}
|
|
4706
|
+
const registryWatch = watch(registry.selectedValues, (val) => {
|
|
4707
|
+
modelWatch.pause();
|
|
4708
|
+
model.value = transformOut(Array.from(toValue(val)));
|
|
4709
|
+
modelWatch.resume();
|
|
4710
|
+
}, { flush: "sync" });
|
|
4711
|
+
const modelWatch = watch(model, (val) => {
|
|
4712
|
+
registryWatch.pause();
|
|
4713
|
+
const currentIds = new Set(toValue(registry.selectedIds));
|
|
4714
|
+
const targetIds = /* @__PURE__ */ new Set();
|
|
4715
|
+
for (const value of transformIn(val)) {
|
|
4716
|
+
const ids = registry.browse(value);
|
|
4717
|
+
if (/* @__PURE__ */ isArray(ids)) for (const single of ids) targetIds.add(single);
|
|
4718
|
+
else if (ids) targetIds.add(ids);
|
|
4719
|
+
}
|
|
4720
|
+
if (multiple) {
|
|
4721
|
+
for (const id of currentIds.difference(targetIds)) registry.selectedIds.delete(id);
|
|
4722
|
+
for (const id of targetIds.difference(currentIds)) registry.selectedIds.add(id);
|
|
4723
|
+
} else {
|
|
4724
|
+
const next = targetIds.values().next().value;
|
|
4725
|
+
const last = currentIds.values().next().value;
|
|
4726
|
+
if (!/* @__PURE__ */ isUndefined(last)) registry.unselect(last);
|
|
4727
|
+
if (!/* @__PURE__ */ isUndefined(next)) registry.select(next);
|
|
4728
|
+
}
|
|
4729
|
+
registryWatch.resume();
|
|
4730
|
+
}, {
|
|
4731
|
+
flush: "sync",
|
|
4732
|
+
deep: multiple
|
|
3854
4733
|
});
|
|
3855
|
-
function
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
4734
|
+
function onRegister(ticket) {
|
|
4735
|
+
if (!pending.has(ticket.value) || ticket.disabled) return;
|
|
4736
|
+
registryWatch.pause();
|
|
4737
|
+
modelWatch.pause();
|
|
4738
|
+
registry.select(ticket.id);
|
|
4739
|
+
pending.delete(ticket.value);
|
|
4740
|
+
modelWatch.resume();
|
|
4741
|
+
registryWatch.resume();
|
|
3860
4742
|
}
|
|
3861
|
-
registry.on("register:ticket",
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
registry.off("clear:registry", update);
|
|
3870
|
-
}, true);
|
|
3871
|
-
return state;
|
|
4743
|
+
registry.on("register:ticket", onRegister);
|
|
4744
|
+
function stop() {
|
|
4745
|
+
registryWatch();
|
|
4746
|
+
modelWatch();
|
|
4747
|
+
registry.off("register:ticket", onRegister);
|
|
4748
|
+
}
|
|
4749
|
+
onScopeDispose(stop, true);
|
|
4750
|
+
return stop;
|
|
3872
4751
|
}
|
|
3873
4752
|
|
|
3874
4753
|
//#endregion
|
|
@@ -3922,300 +4801,144 @@ function useProxyRegistry(registry, options) {
|
|
|
3922
4801
|
function createQueue(_options = {}) {
|
|
3923
4802
|
const { timeout: _timeout = 3e3,...options } = _options;
|
|
3924
4803
|
const registry = useRegistry({
|
|
3925
|
-
...options,
|
|
3926
|
-
events: true
|
|
3927
|
-
});
|
|
3928
|
-
const timeouts = /* @__PURE__ */ new Map();
|
|
3929
|
-
function startTimeout(ticket) {
|
|
3930
|
-
if (ticket.timeout
|
|
3931
|
-
const timeout = setTimeout(() => {
|
|
3932
|
-
timeouts.delete(ticket.id);
|
|
3933
|
-
registry.unregister(ticket.id);
|
|
3934
|
-
resume();
|
|
3935
|
-
}, ticket.timeout);
|
|
3936
|
-
timeouts.set(ticket.id, timeout);
|
|
3937
|
-
}
|
|
3938
|
-
function clearTimeout(id) {
|
|
3939
|
-
const timeout = timeouts.get(id);
|
|
3940
|
-
if (timeout) {
|
|
3941
|
-
globalThis.clearTimeout(timeout);
|
|
3942
|
-
timeouts.delete(id);
|
|
3943
|
-
}
|
|
3944
|
-
}
|
|
3945
|
-
function register(registration = {}) {
|
|
3946
|
-
const id = registration.id ?? /* @__PURE__ */ genId();
|
|
3947
|
-
const timeout = Object.prototype.hasOwnProperty.call(registration, "timeout") ? registration.timeout : _timeout;
|
|
3948
|
-
const ticket = {
|
|
3949
|
-
...registration,
|
|
3950
|
-
id,
|
|
3951
|
-
timeout,
|
|
3952
|
-
isPaused: registry.size > 0,
|
|
3953
|
-
dismiss: () => unregister(id)
|
|
3954
|
-
};
|
|
3955
|
-
const registered = registry.register(ticket);
|
|
3956
|
-
startTimeout(registered);
|
|
3957
|
-
return registered;
|
|
3958
|
-
}
|
|
3959
|
-
function unregister(id) {
|
|
3960
|
-
const ticket = id === void 0 ? registry.seek("first") : registry.get(id);
|
|
3961
|
-
if (!ticket) return void 0;
|
|
3962
|
-
const wasFirst = ticket.index === 0;
|
|
3963
|
-
clearTimeout(ticket.id);
|
|
3964
|
-
registry.unregister(ticket.id);
|
|
3965
|
-
if (wasFirst) resume();
|
|
3966
|
-
return ticket;
|
|
3967
|
-
}
|
|
3968
|
-
function pause() {
|
|
3969
|
-
const ticket = registry.seek("first");
|
|
3970
|
-
if (!ticket || ticket.isPaused) return void 0;
|
|
3971
|
-
clearTimeout(ticket.id);
|
|
3972
|
-
registry.upsert(ticket.id, { isPaused: true });
|
|
3973
|
-
return ticket;
|
|
3974
|
-
}
|
|
3975
|
-
function resume() {
|
|
3976
|
-
const ticket = registry.seek("first");
|
|
3977
|
-
if (!ticket || ticket.index !== 0 || !ticket.isPaused) return void 0;
|
|
3978
|
-
registry.upsert(ticket.id, { isPaused: false });
|
|
3979
|
-
startTimeout(ticket);
|
|
3980
|
-
return ticket;
|
|
3981
|
-
}
|
|
3982
|
-
function clear() {
|
|
3983
|
-
for (const id of timeouts.keys()) clearTimeout(id);
|
|
3984
|
-
registry.clear();
|
|
3985
|
-
}
|
|
3986
|
-
function dispose() {
|
|
3987
|
-
clear();
|
|
3988
|
-
registry.dispose();
|
|
3989
|
-
}
|
|
3990
|
-
onScopeDispose(dispose, true);
|
|
3991
|
-
return {
|
|
3992
|
-
...registry,
|
|
3993
|
-
register,
|
|
3994
|
-
unregister,
|
|
3995
|
-
pause,
|
|
3996
|
-
resume,
|
|
3997
|
-
clear,
|
|
3998
|
-
dispose,
|
|
3999
|
-
get size() {
|
|
4000
|
-
return registry.size;
|
|
4001
|
-
}
|
|
4002
|
-
};
|
|
4003
|
-
}
|
|
4004
|
-
/**
|
|
4005
|
-
* Creates a new queue context.
|
|
4006
|
-
*
|
|
4007
|
-
* @param namespace The namespace for the queue context.
|
|
4008
|
-
* @param options The options for the queue context.
|
|
4009
|
-
* @template Z The type of the queue ticket.
|
|
4010
|
-
* @template E The type of the queue context.
|
|
4011
|
-
* @returns A new queue context.
|
|
4012
|
-
*
|
|
4013
|
-
* @see https://0.vuetifyjs.com/composables/registration/use-queue
|
|
4014
|
-
*
|
|
4015
|
-
* @example
|
|
4016
|
-
* ```ts
|
|
4017
|
-
* import { createQueueContext } from '@vuetify/v0'
|
|
4018
|
-
*
|
|
4019
|
-
* export const [useQueue, provideQueue] = createQueueContext('v0:queue', {
|
|
4020
|
-
* timeout: 5000,
|
|
4021
|
-
* })
|
|
4022
|
-
* ```
|
|
4023
|
-
*/
|
|
4024
|
-
function createQueueContext(_options) {
|
|
4025
|
-
const { namespace,...options } = _options;
|
|
4026
|
-
const [useQueueContext, _provideQueueContext] = createContext(namespace);
|
|
4027
|
-
const context = createQueue(options);
|
|
4028
|
-
function provideQueueContext(_context = context, app) {
|
|
4029
|
-
return _provideQueueContext(_context, app);
|
|
4030
|
-
}
|
|
4031
|
-
return createTrinity(useQueueContext, provideQueueContext, context);
|
|
4032
|
-
}
|
|
4033
|
-
/**
|
|
4034
|
-
* Returns the current queue instance.
|
|
4035
|
-
*
|
|
4036
|
-
* @param namespace The namespace for the queue context. Defaults to `'v0:queue'`.
|
|
4037
|
-
* @returns The current queue instance.
|
|
4038
|
-
*
|
|
4039
|
-
* @see https://0.vuetifyjs.com/composables/registration/use-queue
|
|
4040
|
-
*
|
|
4041
|
-
* @example
|
|
4042
|
-
* ```vue
|
|
4043
|
-
* <script setup lang="ts">
|
|
4044
|
-
* import { useQueue } from '@vuetify/v0'
|
|
4045
|
-
*
|
|
4046
|
-
* const queue = useQueue()
|
|
4047
|
-
* <\/script>
|
|
4048
|
-
* ```
|
|
4049
|
-
*/
|
|
4050
|
-
function useQueue(namespace = "v0:queue") {
|
|
4051
|
-
return useContext(namespace);
|
|
4052
|
-
}
|
|
4053
|
-
|
|
4054
|
-
//#endregion
|
|
4055
|
-
//#region src/composables/useResizeObserver/index.ts
|
|
4056
|
-
/**
|
|
4057
|
-
* @module useResizeObserver
|
|
4058
|
-
*
|
|
4059
|
-
* @remarks
|
|
4060
|
-
* ResizeObserver composable with lifecycle management.
|
|
4061
|
-
*
|
|
4062
|
-
* Key features:
|
|
4063
|
-
* - ResizeObserver API wrapper
|
|
4064
|
-
* - Pause/resume/stop functionality
|
|
4065
|
-
* - Automatic cleanup on unmount
|
|
4066
|
-
* - SSR-safe (checks SUPPORTS_OBSERVER)
|
|
4067
|
-
* - Hydration-aware
|
|
4068
|
-
* - Box model options (content-box/border-box)
|
|
4069
|
-
*
|
|
4070
|
-
* Perfect for responsive components and size-based rendering.
|
|
4071
|
-
*/
|
|
4072
|
-
/**
|
|
4073
|
-
* A composable that uses the Resize Observer API to detect when an element's
|
|
4074
|
-
* size changes.
|
|
4075
|
-
*
|
|
4076
|
-
* @param target The element to observe.
|
|
4077
|
-
* @param callback The callback to execute when the element's size changes.
|
|
4078
|
-
* @param options The options for the Resize Observer.
|
|
4079
|
-
* @returns An object with methods to control the observer.
|
|
4080
|
-
*
|
|
4081
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
|
|
4082
|
-
* @see https://0.vuetifyjs.com/composables/system/use-resize-observer
|
|
4083
|
-
*
|
|
4084
|
-
* @example
|
|
4085
|
-
* ```ts
|
|
4086
|
-
* import { ref } from 'vue'
|
|
4087
|
-
* import { useResizeObserver } from '@vuetify/v0'
|
|
4088
|
-
*
|
|
4089
|
-
* const el = ref<HTMLElement>()
|
|
4090
|
-
* const width = ref(0)
|
|
4091
|
-
* const height = ref(0)
|
|
4092
|
-
*
|
|
4093
|
-
* const { pause, resume, isPaused } = useResizeObserver(
|
|
4094
|
-
* el,
|
|
4095
|
-
* (entries) => {
|
|
4096
|
-
* const entry = entries[0]
|
|
4097
|
-
* if (entry) {
|
|
4098
|
-
* width.value = entry.contentRect.width
|
|
4099
|
-
* height.value = entry.contentRect.height
|
|
4100
|
-
* console.log('Size changed:', width.value, 'x', height.value)
|
|
4101
|
-
* }
|
|
4102
|
-
* },
|
|
4103
|
-
* { immediate: true }
|
|
4104
|
-
* )
|
|
4105
|
-
*
|
|
4106
|
-
* // Pause observation
|
|
4107
|
-
* pause()
|
|
4108
|
-
*
|
|
4109
|
-
* // Resume observation
|
|
4110
|
-
* resume()
|
|
4111
|
-
* ```
|
|
4112
|
-
*/
|
|
4113
|
-
function useResizeObserver(target, callback, options = {}) {
|
|
4114
|
-
const { isHydrated } = useHydration();
|
|
4115
|
-
const observer = shallowRef();
|
|
4116
|
-
const isPaused = shallowRef(false);
|
|
4117
|
-
function setup() {
|
|
4118
|
-
if (!isHydrated.value || !SUPPORTS_OBSERVER || !target.value || isPaused.value) return;
|
|
4119
|
-
observer.value = new ResizeObserver((entries) => {
|
|
4120
|
-
callback(entries.map((entry) => ({
|
|
4121
|
-
contentRect: {
|
|
4122
|
-
width: entry.contentRect.width,
|
|
4123
|
-
height: entry.contentRect.height,
|
|
4124
|
-
top: entry.contentRect.top,
|
|
4125
|
-
left: entry.contentRect.left
|
|
4126
|
-
},
|
|
4127
|
-
target: entry.target
|
|
4128
|
-
})));
|
|
4129
|
-
});
|
|
4130
|
-
observer.value.observe(target.value, { box: options.box || "content-box" });
|
|
4131
|
-
if (options.immediate) {
|
|
4132
|
-
const rect = target.value.getBoundingClientRect();
|
|
4133
|
-
callback([{
|
|
4134
|
-
contentRect: {
|
|
4135
|
-
width: rect.width,
|
|
4136
|
-
height: rect.height,
|
|
4137
|
-
top: rect.top,
|
|
4138
|
-
left: rect.left
|
|
4139
|
-
},
|
|
4140
|
-
target: target.value
|
|
4141
|
-
}]);
|
|
4804
|
+
...options,
|
|
4805
|
+
events: true
|
|
4806
|
+
});
|
|
4807
|
+
const timeouts = /* @__PURE__ */ new Map();
|
|
4808
|
+
function startTimeout(ticket) {
|
|
4809
|
+
if (/* @__PURE__ */ isUndefined(ticket.timeout) || ticket.timeout < 0 || ticket.isPaused) return;
|
|
4810
|
+
const timeout = setTimeout(() => {
|
|
4811
|
+
timeouts.delete(ticket.id);
|
|
4812
|
+
registry.unregister(ticket.id);
|
|
4813
|
+
resume();
|
|
4814
|
+
}, ticket.timeout);
|
|
4815
|
+
timeouts.set(ticket.id, timeout);
|
|
4816
|
+
}
|
|
4817
|
+
function clearTimeout$1(id) {
|
|
4818
|
+
const timeout = timeouts.get(id);
|
|
4819
|
+
if (timeout) {
|
|
4820
|
+
globalThis.clearTimeout(timeout);
|
|
4821
|
+
timeouts.delete(id);
|
|
4142
4822
|
}
|
|
4143
4823
|
}
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4824
|
+
function register(registration = {}) {
|
|
4825
|
+
const id = registration.id ?? /* @__PURE__ */ genId();
|
|
4826
|
+
const timeout = Object.prototype.hasOwnProperty.call(registration, "timeout") ? registration.timeout : _timeout;
|
|
4827
|
+
const ticket = {
|
|
4828
|
+
...registration,
|
|
4829
|
+
id,
|
|
4830
|
+
timeout,
|
|
4831
|
+
isPaused: registry.size > 0,
|
|
4832
|
+
dismiss: () => unregister(id)
|
|
4833
|
+
};
|
|
4834
|
+
const registered = registry.register(ticket);
|
|
4835
|
+
startTimeout(registered);
|
|
4836
|
+
return registered;
|
|
4837
|
+
}
|
|
4838
|
+
function unregister(id) {
|
|
4839
|
+
const ticket = /* @__PURE__ */ isUndefined(id) ? registry.seek("first") : registry.get(id);
|
|
4840
|
+
if (!ticket) return void 0;
|
|
4841
|
+
const wasFirst = ticket.index === 0;
|
|
4842
|
+
clearTimeout$1(ticket.id);
|
|
4843
|
+
registry.unregister(ticket.id);
|
|
4844
|
+
if (wasFirst) resume();
|
|
4845
|
+
return ticket;
|
|
4846
|
+
}
|
|
4847
|
+
function offboard(ids) {
|
|
4848
|
+
let hadFirst = false;
|
|
4849
|
+
for (const id of ids) {
|
|
4850
|
+
const ticket = registry.get(id);
|
|
4851
|
+
if (!ticket) continue;
|
|
4852
|
+
if (ticket.index === 0) hadFirst = true;
|
|
4853
|
+
clearTimeout$1(ticket.id);
|
|
4152
4854
|
}
|
|
4855
|
+
registry.offboard(ids);
|
|
4856
|
+
if (hadFirst) resume();
|
|
4153
4857
|
}
|
|
4154
4858
|
function pause() {
|
|
4155
|
-
|
|
4156
|
-
|
|
4859
|
+
const ticket = registry.seek("first");
|
|
4860
|
+
if (!ticket || ticket.isPaused) return void 0;
|
|
4861
|
+
clearTimeout$1(ticket.id);
|
|
4862
|
+
return registry.upsert(ticket.id, { isPaused: true });
|
|
4157
4863
|
}
|
|
4158
4864
|
function resume() {
|
|
4159
|
-
|
|
4160
|
-
|
|
4865
|
+
const ticket = registry.seek("first");
|
|
4866
|
+
if (!ticket || ticket.index !== 0 || !ticket.isPaused) return void 0;
|
|
4867
|
+
const updated = registry.upsert(ticket.id, { isPaused: false });
|
|
4868
|
+
startTimeout(updated);
|
|
4869
|
+
return updated;
|
|
4161
4870
|
}
|
|
4162
|
-
function
|
|
4163
|
-
|
|
4871
|
+
function clear() {
|
|
4872
|
+
for (const id of timeouts.keys()) clearTimeout$1(id);
|
|
4873
|
+
registry.clear();
|
|
4874
|
+
}
|
|
4875
|
+
function dispose() {
|
|
4876
|
+
clear();
|
|
4877
|
+
registry.dispose();
|
|
4164
4878
|
}
|
|
4165
|
-
|
|
4879
|
+
onScopeDispose(dispose, true);
|
|
4166
4880
|
return {
|
|
4167
|
-
|
|
4881
|
+
...registry,
|
|
4882
|
+
register,
|
|
4883
|
+
unregister,
|
|
4884
|
+
offboard,
|
|
4168
4885
|
pause,
|
|
4169
4886
|
resume,
|
|
4170
|
-
|
|
4887
|
+
clear,
|
|
4888
|
+
dispose,
|
|
4889
|
+
get size() {
|
|
4890
|
+
return registry.size;
|
|
4891
|
+
}
|
|
4171
4892
|
};
|
|
4172
4893
|
}
|
|
4173
4894
|
/**
|
|
4174
|
-
*
|
|
4175
|
-
* element's size.
|
|
4895
|
+
* Creates a new queue context.
|
|
4176
4896
|
*
|
|
4177
|
-
* @param
|
|
4178
|
-
* @
|
|
4897
|
+
* @param namespace The namespace for the queue context.
|
|
4898
|
+
* @param options The options for the queue context.
|
|
4899
|
+
* @template Z The type of the queue ticket.
|
|
4900
|
+
* @template E The type of the queue context.
|
|
4901
|
+
* @returns A new queue context.
|
|
4179
4902
|
*
|
|
4180
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
4903
|
+
* @see https://0.vuetifyjs.com/composables/registration/use-queue
|
|
4181
4904
|
*
|
|
4182
4905
|
* @example
|
|
4183
4906
|
* ```ts
|
|
4184
|
-
* import {
|
|
4185
|
-
* import { useElementSize } from '@vuetify/v0'
|
|
4186
|
-
*
|
|
4187
|
-
* const box = ref<HTMLElement>()
|
|
4188
|
-
* const { width, height } = useElementSize(box)
|
|
4907
|
+
* import { createQueueContext } from '@vuetify/v0'
|
|
4189
4908
|
*
|
|
4190
|
-
*
|
|
4191
|
-
*
|
|
4192
|
-
* console.log('Box size:', width.value, 'x', height.value)
|
|
4909
|
+
* export const [useQueue, provideQueue] = createQueueContext('v0:queue', {
|
|
4910
|
+
* timeout: 5000,
|
|
4193
4911
|
* })
|
|
4194
4912
|
* ```
|
|
4195
4913
|
*/
|
|
4196
|
-
function
|
|
4197
|
-
const
|
|
4198
|
-
const
|
|
4199
|
-
const
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
width.value = entry.contentRect.width;
|
|
4203
|
-
height.value = entry.contentRect.height;
|
|
4204
|
-
}
|
|
4205
|
-
}, { immediate: true });
|
|
4206
|
-
function pause() {
|
|
4207
|
-
width.value = 0;
|
|
4208
|
-
height.value = 0;
|
|
4209
|
-
_pause();
|
|
4914
|
+
function createQueueContext(_options) {
|
|
4915
|
+
const { namespace,...options } = _options;
|
|
4916
|
+
const [useQueueContext, _provideQueueContext] = createContext(namespace);
|
|
4917
|
+
const context = createQueue(options);
|
|
4918
|
+
function provideQueueContext(_context = context, app) {
|
|
4919
|
+
return _provideQueueContext(_context, app);
|
|
4210
4920
|
}
|
|
4211
|
-
return
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4921
|
+
return createTrinity(useQueueContext, provideQueueContext, context);
|
|
4922
|
+
}
|
|
4923
|
+
/**
|
|
4924
|
+
* Returns the current queue instance.
|
|
4925
|
+
*
|
|
4926
|
+
* @param namespace The namespace for the queue context. Defaults to `'v0:queue'`.
|
|
4927
|
+
* @returns The current queue instance.
|
|
4928
|
+
*
|
|
4929
|
+
* @see https://0.vuetifyjs.com/composables/registration/use-queue
|
|
4930
|
+
*
|
|
4931
|
+
* @example
|
|
4932
|
+
* ```vue
|
|
4933
|
+
* <script setup lang="ts">
|
|
4934
|
+
* import { useQueue } from '@vuetify/v0'
|
|
4935
|
+
*
|
|
4936
|
+
* const queue = useQueue()
|
|
4937
|
+
* <\/script>
|
|
4938
|
+
* ```
|
|
4939
|
+
*/
|
|
4940
|
+
function useQueue(namespace = "v0:queue") {
|
|
4941
|
+
return useContext(namespace);
|
|
4219
4942
|
}
|
|
4220
4943
|
|
|
4221
4944
|
//#endregion
|
|
@@ -4331,13 +5054,13 @@ function createStep(_options = {}) {
|
|
|
4331
5054
|
let index = circular ? wrapped(length, currentIndex + count) : currentIndex + count;
|
|
4332
5055
|
if (!circular && (index < 0 || index >= length)) return;
|
|
4333
5056
|
let id = registry.lookup(index);
|
|
4334
|
-
while (
|
|
5057
|
+
while (!/* @__PURE__ */ isUndefined(id) && toValue(registry.get(id)?.disabled) && hops < length) {
|
|
4335
5058
|
index = circular ? wrapped(length, index + direction) : index + direction;
|
|
4336
5059
|
if (!circular && (index < 0 || index >= length)) return;
|
|
4337
5060
|
id = registry.lookup(index);
|
|
4338
5061
|
hops++;
|
|
4339
5062
|
}
|
|
4340
|
-
if (
|
|
5063
|
+
if (/* @__PURE__ */ isUndefined(id) || hops === length) return;
|
|
4341
5064
|
registry.selectedIds.clear();
|
|
4342
5065
|
registry.select(id);
|
|
4343
5066
|
}
|
|
@@ -4356,7 +5079,6 @@ function createStep(_options = {}) {
|
|
|
4356
5079
|
/**
|
|
4357
5080
|
* Creates a new step context.
|
|
4358
5081
|
*
|
|
4359
|
-
* @param namespace The namespace for the step context.
|
|
4360
5082
|
* @param options The options for the step context.
|
|
4361
5083
|
* @template Z The type of the step ticket.
|
|
4362
5084
|
* @template E The type of the step context.
|
|
@@ -4368,18 +5090,19 @@ function createStep(_options = {}) {
|
|
|
4368
5090
|
* ```ts
|
|
4369
5091
|
* import { createStepContext } from '@vuetify/v0'
|
|
4370
5092
|
*
|
|
4371
|
-
*
|
|
5093
|
+
* // With default namespace 'v0:step'
|
|
5094
|
+
* export const [useStep, provideStep, context] = createStepContext()
|
|
4372
5095
|
*
|
|
4373
5096
|
* // In a parent component:
|
|
4374
|
-
*
|
|
5097
|
+
* provideStep()
|
|
4375
5098
|
*
|
|
4376
5099
|
* // In a child component:
|
|
4377
|
-
* const
|
|
4378
|
-
*
|
|
5100
|
+
* const context = useStep()
|
|
5101
|
+
* context.next() // Progress to next step
|
|
4379
5102
|
* ```
|
|
4380
5103
|
*/
|
|
4381
|
-
function createStepContext(_options) {
|
|
4382
|
-
const { namespace,...options } = _options;
|
|
5104
|
+
function createStepContext(_options = {}) {
|
|
5105
|
+
const { namespace = "v0:step",...options } = _options;
|
|
4383
5106
|
const [useStepContext, _provideStepContext] = createContext(namespace);
|
|
4384
5107
|
const context = createStep(options);
|
|
4385
5108
|
function provideStepContext(_context = context, app) {
|
|
@@ -4458,7 +5181,6 @@ var MemoryAdapter = class {
|
|
|
4458
5181
|
*
|
|
4459
5182
|
* Uses adapter pattern to abstract storage implementation details.
|
|
4460
5183
|
*/
|
|
4461
|
-
const [useStorageContext, provideStorageContext] = createContext("v0:storage");
|
|
4462
5184
|
/**
|
|
4463
5185
|
* Creates a new storage instance.
|
|
4464
5186
|
*
|
|
@@ -4506,7 +5228,7 @@ function createStorage(options = {}) {
|
|
|
4506
5228
|
}
|
|
4507
5229
|
const valueRef = ref(initialValue);
|
|
4508
5230
|
const stop = watch(valueRef, (newValue) => {
|
|
4509
|
-
if (
|
|
5231
|
+
if (/* @__PURE__ */ isNullOrUndefined(newValue)) adapter?.removeItem(prefixedKey);
|
|
4510
5232
|
else adapter?.setItem(prefixedKey, serializer.write(newValue));
|
|
4511
5233
|
}, { deep: true });
|
|
4512
5234
|
watchers.set(prefixedKey, stop);
|
|
@@ -4546,12 +5268,12 @@ function createStorage(options = {}) {
|
|
|
4546
5268
|
}
|
|
4547
5269
|
function createStorageContext(_options = {}) {
|
|
4548
5270
|
const { namespace = "v0:storage",...options } = _options;
|
|
4549
|
-
const [useStorageContext
|
|
5271
|
+
const [useStorageContext, _provideStorageContext] = createContext(namespace);
|
|
4550
5272
|
const context = createStorage(options);
|
|
4551
|
-
function provideStorageContext
|
|
5273
|
+
function provideStorageContext(_context = context, app) {
|
|
4552
5274
|
return _provideStorageContext(_context, app);
|
|
4553
5275
|
}
|
|
4554
|
-
return createTrinity(useStorageContext
|
|
5276
|
+
return createTrinity(useStorageContext, provideStorageContext, context);
|
|
4555
5277
|
}
|
|
4556
5278
|
/**
|
|
4557
5279
|
* Creates a new storage plugin.
|
|
@@ -4576,14 +5298,14 @@ function createStorageContext(_options = {}) {
|
|
|
4576
5298
|
*/
|
|
4577
5299
|
function createStoragePlugin(_options = {}) {
|
|
4578
5300
|
const { namespace = "v0:storage",...options } = _options;
|
|
4579
|
-
const [, provideStorageContext
|
|
5301
|
+
const [, provideStorageContext, context] = createStorageContext({
|
|
4580
5302
|
...options,
|
|
4581
5303
|
namespace
|
|
4582
5304
|
});
|
|
4583
5305
|
return createPlugin({
|
|
4584
5306
|
namespace,
|
|
4585
5307
|
provide: (app) => {
|
|
4586
|
-
provideStorageContext
|
|
5308
|
+
provideStorageContext(context, app);
|
|
4587
5309
|
}
|
|
4588
5310
|
});
|
|
4589
5311
|
}
|
|
@@ -4631,7 +5353,7 @@ var ThemeAdapter = class {
|
|
|
4631
5353
|
const vars = Object.entries(themeColors).map(([key, val]) => ` --${this.prefix}-${key}: ${val};`).join("\n");
|
|
4632
5354
|
css += `[data-theme="${theme}"] {\n${vars}\n}\n`;
|
|
4633
5355
|
}
|
|
4634
|
-
if (
|
|
5356
|
+
if (!/* @__PURE__ */ isUndefined(isDark)) css += `:root {\n color-scheme: ${isDark ? "dark" : "light"};\n}\n`;
|
|
4635
5357
|
return css;
|
|
4636
5358
|
}
|
|
4637
5359
|
};
|
|
@@ -5023,13 +5745,12 @@ function createTimeline(_options = {}) {
|
|
|
5023
5745
|
};
|
|
5024
5746
|
}
|
|
5025
5747
|
/**
|
|
5026
|
-
* Creates a new timeline
|
|
5748
|
+
* Creates a new timeline context.
|
|
5027
5749
|
*
|
|
5028
|
-
* @param
|
|
5029
|
-
* @param options The options for the timeline plugin.
|
|
5750
|
+
* @param options The options for the timeline context.
|
|
5030
5751
|
* @template Z The type of the timeline ticket.
|
|
5031
5752
|
* @template E The type of the timeline context.
|
|
5032
|
-
* @returns A new timeline
|
|
5753
|
+
* @returns A new timeline context.
|
|
5033
5754
|
*
|
|
5034
5755
|
* @see https://0.vuetifyjs.com/composables/registration/use-timeline
|
|
5035
5756
|
*
|
|
@@ -5037,7 +5758,9 @@ function createTimeline(_options = {}) {
|
|
|
5037
5758
|
* ```ts
|
|
5038
5759
|
* import { createTimelineContext } from '@vuetify/v0'
|
|
5039
5760
|
*
|
|
5040
|
-
*
|
|
5761
|
+
* // With default namespace 'v0:timeline'
|
|
5762
|
+
* export const [useTimeline, provideTimeline, context] = createTimelineContext({ size: 5 })
|
|
5763
|
+
*
|
|
5041
5764
|
* context.register({ id: 'example' })
|
|
5042
5765
|
*
|
|
5043
5766
|
* // In a parent component
|
|
@@ -5049,39 +5772,409 @@ function createTimeline(_options = {}) {
|
|
|
5049
5772
|
* console.log(timeline.values()) // [{ id: 'example' }]
|
|
5050
5773
|
* ```
|
|
5051
5774
|
*/
|
|
5052
|
-
function createTimelineContext(_options) {
|
|
5053
|
-
const { namespace,...options } = _options;
|
|
5775
|
+
function createTimelineContext(_options = {}) {
|
|
5776
|
+
const { namespace = "v0:timeline",...options } = _options;
|
|
5054
5777
|
const [useTimelineContext, _provideTimelineContext] = createContext(namespace);
|
|
5055
5778
|
const context = createTimeline(options);
|
|
5056
5779
|
function provideTimelineContext(_context = context, app) {
|
|
5057
5780
|
return _provideTimelineContext(_context, app);
|
|
5058
5781
|
}
|
|
5059
|
-
return createTrinity(useTimelineContext, provideTimelineContext, context);
|
|
5060
|
-
}
|
|
5061
|
-
/**
|
|
5062
|
-
* Returns the current timeline instance.
|
|
5063
|
-
*
|
|
5064
|
-
* @param namespace The namespace for the timeline context. Defaults to `'v0:timeline'`.
|
|
5065
|
-
* @returns The current timeline instance.
|
|
5066
|
-
*
|
|
5067
|
-
* @see https://0.vuetifyjs.com/composables/registration/use-timeline
|
|
5068
|
-
*
|
|
5069
|
-
* @example
|
|
5070
|
-
* ```vue
|
|
5071
|
-
* <script setup lang="ts">
|
|
5072
|
-
* import { useTimeline } from '@vuetify/v0'
|
|
5073
|
-
*
|
|
5074
|
-
* const timeline = useTimeline()
|
|
5075
|
-
* <\/script>
|
|
5076
|
-
* ```
|
|
5077
|
-
*/
|
|
5078
|
-
function useTimeline(namespace = "v0:timeline") {
|
|
5079
|
-
return useContext(namespace);
|
|
5782
|
+
return createTrinity(useTimelineContext, provideTimelineContext, context);
|
|
5783
|
+
}
|
|
5784
|
+
/**
|
|
5785
|
+
* Returns the current timeline instance.
|
|
5786
|
+
*
|
|
5787
|
+
* @param namespace The namespace for the timeline context. Defaults to `'v0:timeline'`.
|
|
5788
|
+
* @returns The current timeline instance.
|
|
5789
|
+
*
|
|
5790
|
+
* @see https://0.vuetifyjs.com/composables/registration/use-timeline
|
|
5791
|
+
*
|
|
5792
|
+
* @example
|
|
5793
|
+
* ```vue
|
|
5794
|
+
* <script setup lang="ts">
|
|
5795
|
+
* import { useTimeline } from '@vuetify/v0'
|
|
5796
|
+
*
|
|
5797
|
+
* const timeline = useTimeline()
|
|
5798
|
+
* <\/script>
|
|
5799
|
+
* ```
|
|
5800
|
+
*/
|
|
5801
|
+
function useTimeline(namespace = "v0:timeline") {
|
|
5802
|
+
return useContext(namespace);
|
|
5803
|
+
}
|
|
5804
|
+
|
|
5805
|
+
//#endregion
|
|
5806
|
+
//#region src/composables/useToggleScope/index.ts
|
|
5807
|
+
/**
|
|
5808
|
+
* @module useToggleScope
|
|
5809
|
+
*
|
|
5810
|
+
* @remarks
|
|
5811
|
+
* Conditionally manages an effect scope based on a reactive boolean condition.
|
|
5812
|
+
* When the source becomes true, creates and runs an effect scope. When false, stops the scope.
|
|
5813
|
+
* All reactive effects created within the scoped function are automatically cleaned up on deactivation.
|
|
5814
|
+
*
|
|
5815
|
+
* Key features:
|
|
5816
|
+
* - Uses Vue's effectScope for efficient reactive effect lifecycle management
|
|
5817
|
+
* - Automatic cleanup when condition becomes false
|
|
5818
|
+
* - Supports optional reset callback for scope restart capability
|
|
5819
|
+
* - Handles rapid toggling and parent scope disposal safely
|
|
5820
|
+
* - SSR-safe (effectScope is part of Vue core)
|
|
5821
|
+
*
|
|
5822
|
+
* Perfect for conditional side effects, feature flags, and performance optimization
|
|
5823
|
+
* by only running reactive effects when needed.
|
|
5824
|
+
*/
|
|
5825
|
+
/**
|
|
5826
|
+
* Conditionally manages an effect scope based on a reactive boolean source.
|
|
5827
|
+
*
|
|
5828
|
+
* @param source A reactive boolean value or getter that controls the scope lifecycle
|
|
5829
|
+
* @param fn The function to run within the effect scope. Can optionally receive controls for manual scope management.
|
|
5830
|
+
* @returns Controls object with isActive state and start/stop/reset methods
|
|
5831
|
+
*
|
|
5832
|
+
* @see https://vuejs.org/api/reactivity-advanced.html#effectscope
|
|
5833
|
+
* @see https://0.vuetifyjs.com/composables/system/use-toggle-scope
|
|
5834
|
+
*
|
|
5835
|
+
* @example
|
|
5836
|
+
* ```ts
|
|
5837
|
+
* import { ref } from 'vue'
|
|
5838
|
+
* import { useToggleScope } from '@vuetify/v0'
|
|
5839
|
+
*
|
|
5840
|
+
* const isEnabled = ref(false)
|
|
5841
|
+
*
|
|
5842
|
+
* const { isActive } = useToggleScope(isEnabled, () => {
|
|
5843
|
+
* // This code runs when isEnabled becomes true
|
|
5844
|
+
* const unwatch = watch(someRef, () => {
|
|
5845
|
+
* console.log('Watching...')
|
|
5846
|
+
* })
|
|
5847
|
+
*
|
|
5848
|
+
* // Cleanup happens automatically when isEnabled becomes false
|
|
5849
|
+
* })
|
|
5850
|
+
*
|
|
5851
|
+
* // Toggle the scope on/off
|
|
5852
|
+
* isEnabled.value = true // Starts the scope
|
|
5853
|
+
* console.log(isActive.value) // true
|
|
5854
|
+
* isEnabled.value = false // Stops and cleans up
|
|
5855
|
+
* console.log(isActive.value) // false
|
|
5856
|
+
* ```
|
|
5857
|
+
*
|
|
5858
|
+
* @example
|
|
5859
|
+
* With manual controls:
|
|
5860
|
+
* ```ts
|
|
5861
|
+
* const isEnabled = ref(true)
|
|
5862
|
+
*
|
|
5863
|
+
* useToggleScope(isEnabled, (controls) => {
|
|
5864
|
+
* // Access controls inside the scope
|
|
5865
|
+
* console.log('Active:', controls.isActive.value)
|
|
5866
|
+
*
|
|
5867
|
+
* // Manually reset the scope if needed
|
|
5868
|
+
* someEvent.on('reset', () => controls.reset())
|
|
5869
|
+
* })
|
|
5870
|
+
* ```
|
|
5871
|
+
*/
|
|
5872
|
+
function useToggleScope(source, fn) {
|
|
5873
|
+
const scope = shallowRef();
|
|
5874
|
+
const isActive = toRef(() => !!scope.value);
|
|
5875
|
+
function start() {
|
|
5876
|
+
if (scope.value) return;
|
|
5877
|
+
scope.value = effectScope();
|
|
5878
|
+
scope.value.run(() => fn.length > 0 ? fn(controls) : fn());
|
|
5879
|
+
}
|
|
5880
|
+
function stop() {
|
|
5881
|
+
scope.value?.stop();
|
|
5882
|
+
scope.value = void 0;
|
|
5883
|
+
}
|
|
5884
|
+
function reset() {
|
|
5885
|
+
stop();
|
|
5886
|
+
start();
|
|
5887
|
+
}
|
|
5888
|
+
const controls = {
|
|
5889
|
+
isActive: shallowReadonly(isActive),
|
|
5890
|
+
start,
|
|
5891
|
+
stop,
|
|
5892
|
+
reset
|
|
5893
|
+
};
|
|
5894
|
+
watch(source, (active) => {
|
|
5895
|
+
if (active && !scope.value) start();
|
|
5896
|
+
else if (!active) stop();
|
|
5897
|
+
}, { immediate: true });
|
|
5898
|
+
onScopeDispose(() => {
|
|
5899
|
+
stop();
|
|
5900
|
+
});
|
|
5901
|
+
return controls;
|
|
5902
|
+
}
|
|
5903
|
+
|
|
5904
|
+
//#endregion
|
|
5905
|
+
//#region src/composables/useVirtual/index.ts
|
|
5906
|
+
/**
|
|
5907
|
+
* @module useVirtual
|
|
5908
|
+
*
|
|
5909
|
+
* @remarks
|
|
5910
|
+
* Virtual scrolling composable for efficiently rendering large lists.
|
|
5911
|
+
*
|
|
5912
|
+
* Key features:
|
|
5913
|
+
* - Renders only visible items (viewport + overscan)
|
|
5914
|
+
* - Dynamic or fixed item heights
|
|
5915
|
+
* - SSR-safe (checks IN_BROWSER)
|
|
5916
|
+
* - Bidirectional scrolling (forward/reverse for chat apps)
|
|
5917
|
+
* - Scroll anchoring (maintains position across data changes)
|
|
5918
|
+
* - Edge detection for infinite scroll
|
|
5919
|
+
* - iOS momentum and elastic scrolling
|
|
5920
|
+
* - Configurable overscan (extra items rendered for smooth scrolling)
|
|
5921
|
+
*
|
|
5922
|
+
* Perfect for large data sets, chat apps, and infinite scroll implementations.
|
|
5923
|
+
*/
|
|
5924
|
+
/**
|
|
5925
|
+
* Virtual scrolling composable for efficiently rendering large lists
|
|
5926
|
+
*
|
|
5927
|
+
* @param items Reactive array of items to virtualize
|
|
5928
|
+
* @param options Configuration options
|
|
5929
|
+
* @returns Virtual scrolling context
|
|
5930
|
+
*
|
|
5931
|
+
* @see https://0.vuetifyjs.com/composables/utilities/use-virtual
|
|
5932
|
+
*
|
|
5933
|
+
* @example
|
|
5934
|
+
* ```vue
|
|
5935
|
+
* <script setup lang="ts">
|
|
5936
|
+
* import { useVirtual } from '@vuetify/v0'
|
|
5937
|
+
*
|
|
5938
|
+
* const items = ref(Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` })))
|
|
5939
|
+
* <\/script>
|
|
5940
|
+
*
|
|
5941
|
+
* <template>
|
|
5942
|
+
* <div
|
|
5943
|
+
* ref="element"
|
|
5944
|
+
* style="height: 600px; overflow-y: auto;"
|
|
5945
|
+
* @scroll="scroll"
|
|
5946
|
+
* >
|
|
5947
|
+
* <div :style="{ height: `${offset}px` }" />
|
|
5948
|
+
*
|
|
5949
|
+
* <div v-for="item in items" :key="item.index">
|
|
5950
|
+
* {{ item.raw.name }}
|
|
5951
|
+
* </div>
|
|
5952
|
+
*
|
|
5953
|
+
* <div :style="{ height: `${size}px` }" />
|
|
5954
|
+
* </div>
|
|
5955
|
+
* </template>
|
|
5956
|
+
* ```
|
|
5957
|
+
*/
|
|
5958
|
+
function useVirtual(items, _options = {}) {
|
|
5959
|
+
const { itemHeight: _itemHeight, height, overscan = 5, direction = "forward", anchor = "auto", anchorSmooth = true, onStartReached, onEndReached, startThreshold = 0, endThreshold = 0, momentum: momentumOption, elastic: elasticOption } = _options;
|
|
5960
|
+
const element = ref();
|
|
5961
|
+
const itemHeight = shallowRef(Number.parseFloat(String(_itemHeight || 0)));
|
|
5962
|
+
const heights = shallowRef([]);
|
|
5963
|
+
const offsets = shallowRef([]);
|
|
5964
|
+
const first = shallowRef(0);
|
|
5965
|
+
const last = shallowRef(0);
|
|
5966
|
+
const offset = shallowRef(0);
|
|
5967
|
+
const size = shallowRef(0);
|
|
5968
|
+
const viewportHeight = shallowRef(0);
|
|
5969
|
+
const state = shallowRef("ok");
|
|
5970
|
+
const isIOS = IN_BROWSER && /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
5971
|
+
const momentum = momentumOption ?? isIOS;
|
|
5972
|
+
const elastic = elasticOption ?? isIOS;
|
|
5973
|
+
let raf = -1;
|
|
5974
|
+
let rebuildRaf = -1;
|
|
5975
|
+
let edgeRaf = -1;
|
|
5976
|
+
const cachedViewport = Number.parseInt(String(height)) || 0;
|
|
5977
|
+
let anchorIndex = -1;
|
|
5978
|
+
let anchorOffset = 0;
|
|
5979
|
+
const computedItems = computed(() => items.value.slice(first.value, last.value).map((item, i) => ({
|
|
5980
|
+
raw: item,
|
|
5981
|
+
index: i + first.value
|
|
5982
|
+
})));
|
|
5983
|
+
watch(element, (el) => {
|
|
5984
|
+
if (!IN_BROWSER || !el?.style) return;
|
|
5985
|
+
if (momentum) el.style.webkitOverflowScrolling = "touch";
|
|
5986
|
+
if (!elastic) el.style.overscrollBehavior = "none";
|
|
5987
|
+
});
|
|
5988
|
+
useResizeObserver(element, (entries) => {
|
|
5989
|
+
if (!entries[0]) return;
|
|
5990
|
+
viewportHeight.value = entries[0].contentRect.height;
|
|
5991
|
+
update();
|
|
5992
|
+
});
|
|
5993
|
+
watch(items, (newItems) => {
|
|
5994
|
+
captureAnchor();
|
|
5995
|
+
const length = newItems.length;
|
|
5996
|
+
const newHeights = heights.value.length === length ? heights.value : Array.from({ length }, () => null);
|
|
5997
|
+
if (heights.value !== newHeights) heights.value = newHeights;
|
|
5998
|
+
rebuild();
|
|
5999
|
+
}, { immediate: true });
|
|
6000
|
+
watch(element, () => {
|
|
6001
|
+
if (!element.value) return;
|
|
6002
|
+
if (direction === "reverse" && items.value.length > 0) {
|
|
6003
|
+
const lastIndex = items.value.length - 1;
|
|
6004
|
+
const totalHeight = (offsets.value[lastIndex] || 0) + (heights.value[lastIndex] || itemHeight.value);
|
|
6005
|
+
element.value.scrollTop = totalHeight;
|
|
6006
|
+
}
|
|
6007
|
+
update();
|
|
6008
|
+
});
|
|
6009
|
+
function captureAnchor() {
|
|
6010
|
+
if (!element.value || anchor === "auto") return;
|
|
6011
|
+
if (anchor === "start") {
|
|
6012
|
+
anchorIndex = 0;
|
|
6013
|
+
anchorOffset = 0;
|
|
6014
|
+
} else if (anchor === "end") {
|
|
6015
|
+
anchorIndex = items.value.length - 1;
|
|
6016
|
+
anchorOffset = 0;
|
|
6017
|
+
} else if (/* @__PURE__ */ isFunction(anchor)) {
|
|
6018
|
+
const result = anchor(items.value);
|
|
6019
|
+
if (/* @__PURE__ */ isNumber(result)) {
|
|
6020
|
+
anchorIndex = result;
|
|
6021
|
+
anchorOffset = element.value.scrollTop - (offsets.value[result] || 0);
|
|
6022
|
+
}
|
|
6023
|
+
} else {
|
|
6024
|
+
anchorIndex = first.value;
|
|
6025
|
+
anchorOffset = element.value.scrollTop - (offsets.value[first.value] || 0);
|
|
6026
|
+
}
|
|
6027
|
+
}
|
|
6028
|
+
function restoreAnchor() {
|
|
6029
|
+
if (!element.value || anchorIndex < 0) return;
|
|
6030
|
+
const newScrollTop = (offsets.value[anchorIndex] || 0) + anchorOffset;
|
|
6031
|
+
if (anchorSmooth && direction === "forward") element.value.scrollTo({
|
|
6032
|
+
top: newScrollTop,
|
|
6033
|
+
behavior: "smooth"
|
|
6034
|
+
});
|
|
6035
|
+
else element.value.scrollTop = newScrollTop;
|
|
6036
|
+
anchorIndex = -1;
|
|
6037
|
+
anchorOffset = 0;
|
|
6038
|
+
}
|
|
6039
|
+
function rebuild() {
|
|
6040
|
+
const length = items.value.length;
|
|
6041
|
+
const newOffsets = offsets.value.length === length ? offsets.value : Array.from({ length });
|
|
6042
|
+
let offset$1 = 0;
|
|
6043
|
+
for (let i = 0; i < length; i++) {
|
|
6044
|
+
newOffsets[i] = offset$1;
|
|
6045
|
+
offset$1 += heights.value[i] || itemHeight.value;
|
|
6046
|
+
}
|
|
6047
|
+
if (offsets.value !== newOffsets) offsets.value = newOffsets;
|
|
6048
|
+
update();
|
|
6049
|
+
restoreAnchor();
|
|
6050
|
+
}
|
|
6051
|
+
function findIndex(scrollTop) {
|
|
6052
|
+
const arr = offsets.value;
|
|
6053
|
+
if (arr.length === 0) return 0;
|
|
6054
|
+
let low = 0;
|
|
6055
|
+
let high = arr.length - 1;
|
|
6056
|
+
while (low <= high) {
|
|
6057
|
+
const mid = low + high >> 1;
|
|
6058
|
+
if (arr[mid] <= scrollTop) low = mid + 1;
|
|
6059
|
+
else high = mid - 1;
|
|
6060
|
+
}
|
|
6061
|
+
return Math.max(0, high);
|
|
6062
|
+
}
|
|
6063
|
+
function update() {
|
|
6064
|
+
if (!element.value) return;
|
|
6065
|
+
const viewport = viewportHeight.value || cachedViewport;
|
|
6066
|
+
if (!viewport || !itemHeight.value) return;
|
|
6067
|
+
const scrollTop = element.value.scrollTop || 0;
|
|
6068
|
+
const length = items.value.length;
|
|
6069
|
+
const visibleStart = findIndex(scrollTop);
|
|
6070
|
+
const visibleEnd = findIndex(scrollTop + viewport) + 1;
|
|
6071
|
+
const start = /* @__PURE__ */ clamp(visibleStart - overscan, 0, length);
|
|
6072
|
+
const end = /* @__PURE__ */ clamp(visibleEnd + overscan, start, length);
|
|
6073
|
+
first.value = start;
|
|
6074
|
+
last.value = end;
|
|
6075
|
+
offset.value = offsets.value[start] || 0;
|
|
6076
|
+
const lastIndex = length - 1;
|
|
6077
|
+
const totalHeight = (offsets.value[lastIndex] || 0) + (heights.value[lastIndex] || itemHeight.value);
|
|
6078
|
+
size.value = totalHeight - (offsets.value[end] || totalHeight);
|
|
6079
|
+
}
|
|
6080
|
+
function checkEdges() {
|
|
6081
|
+
if (!element.value) return;
|
|
6082
|
+
const scrollTop = element.value.scrollTop;
|
|
6083
|
+
const scrollHeight = element.value.scrollHeight;
|
|
6084
|
+
const clientHeight = element.value.clientHeight;
|
|
6085
|
+
const distanceFromStart = scrollTop;
|
|
6086
|
+
const distanceFromEnd = scrollHeight - (scrollTop + clientHeight);
|
|
6087
|
+
if (IN_BROWSER) {
|
|
6088
|
+
cancelAnimationFrame(edgeRaf);
|
|
6089
|
+
edgeRaf = requestAnimationFrame(() => {
|
|
6090
|
+
if (onStartReached && distanceFromStart <= startThreshold) onStartReached(distanceFromStart);
|
|
6091
|
+
if (onEndReached && distanceFromEnd <= endThreshold) onEndReached(distanceFromEnd);
|
|
6092
|
+
});
|
|
6093
|
+
} else {
|
|
6094
|
+
if (onStartReached && distanceFromStart <= startThreshold) onStartReached(distanceFromStart);
|
|
6095
|
+
if (onEndReached && distanceFromEnd <= endThreshold) onEndReached(distanceFromEnd);
|
|
6096
|
+
}
|
|
6097
|
+
}
|
|
6098
|
+
function resize(index, height$1) {
|
|
6099
|
+
if (heights.value[index] === height$1) return;
|
|
6100
|
+
heights.value[index] = height$1;
|
|
6101
|
+
if (!itemHeight.value) itemHeight.value = height$1;
|
|
6102
|
+
if (IN_BROWSER) {
|
|
6103
|
+
cancelAnimationFrame(rebuildRaf);
|
|
6104
|
+
rebuildRaf = requestAnimationFrame(rebuild);
|
|
6105
|
+
} else rebuild();
|
|
6106
|
+
}
|
|
6107
|
+
function scroll() {
|
|
6108
|
+
if (IN_BROWSER) {
|
|
6109
|
+
cancelAnimationFrame(raf);
|
|
6110
|
+
raf = requestAnimationFrame(update);
|
|
6111
|
+
checkEdges();
|
|
6112
|
+
} else update();
|
|
6113
|
+
}
|
|
6114
|
+
function scrollTo(index, scrollOptions) {
|
|
6115
|
+
if (!element.value) return;
|
|
6116
|
+
const targetOffset = offsets.value[index] || 0;
|
|
6117
|
+
const behavior = scrollOptions?.behavior ?? "auto";
|
|
6118
|
+
const block = scrollOptions?.block ?? "start";
|
|
6119
|
+
const extraOffset = scrollOptions?.offset ?? 0;
|
|
6120
|
+
let scrollTop = targetOffset + extraOffset;
|
|
6121
|
+
switch (block) {
|
|
6122
|
+
case "center": {
|
|
6123
|
+
const viewport = viewportHeight.value || cachedViewport;
|
|
6124
|
+
const itemH = heights.value[index] || itemHeight.value;
|
|
6125
|
+
scrollTop = targetOffset - viewport / 2 + itemH / 2 + extraOffset;
|
|
6126
|
+
break;
|
|
6127
|
+
}
|
|
6128
|
+
case "end": {
|
|
6129
|
+
const viewport = viewportHeight.value || cachedViewport;
|
|
6130
|
+
const itemH = heights.value[index] || itemHeight.value;
|
|
6131
|
+
scrollTop = targetOffset - viewport + itemH + extraOffset;
|
|
6132
|
+
break;
|
|
6133
|
+
}
|
|
6134
|
+
case "nearest": {
|
|
6135
|
+
const viewport = viewportHeight.value || cachedViewport;
|
|
6136
|
+
const currentScroll = element.value.scrollTop;
|
|
6137
|
+
const itemH = heights.value[index] || itemHeight.value;
|
|
6138
|
+
if (targetOffset < currentScroll) scrollTop = targetOffset + extraOffset;
|
|
6139
|
+
else if (targetOffset + itemH > currentScroll + viewport) scrollTop = targetOffset - viewport + itemH + extraOffset;
|
|
6140
|
+
else return;
|
|
6141
|
+
break;
|
|
6142
|
+
}
|
|
6143
|
+
}
|
|
6144
|
+
if (behavior === "smooth") element.value.scrollTo({
|
|
6145
|
+
top: scrollTop,
|
|
6146
|
+
behavior: "smooth"
|
|
6147
|
+
});
|
|
6148
|
+
else element.value.scrollTop = scrollTop;
|
|
6149
|
+
update();
|
|
6150
|
+
}
|
|
6151
|
+
function reset() {
|
|
6152
|
+
state.value = "ok";
|
|
6153
|
+
anchorIndex = -1;
|
|
6154
|
+
anchorOffset = 0;
|
|
6155
|
+
if (element.value && direction === "reverse" && items.value.length > 0) {
|
|
6156
|
+
const lastIndex = items.value.length - 1;
|
|
6157
|
+
const totalHeight = (offsets.value[lastIndex] || 0) + (heights.value[lastIndex] || itemHeight.value);
|
|
6158
|
+
element.value.scrollTop = totalHeight;
|
|
6159
|
+
}
|
|
6160
|
+
}
|
|
6161
|
+
return {
|
|
6162
|
+
element,
|
|
6163
|
+
items: computedItems,
|
|
6164
|
+
offset: readonly(offset),
|
|
6165
|
+
size: readonly(size),
|
|
6166
|
+
state,
|
|
6167
|
+
scrollTo,
|
|
6168
|
+
scroll,
|
|
6169
|
+
scrollend: scroll,
|
|
6170
|
+
resize,
|
|
6171
|
+
reset
|
|
6172
|
+
};
|
|
5080
6173
|
}
|
|
5081
6174
|
|
|
5082
6175
|
//#endregion
|
|
5083
6176
|
//#region src/components/Avatar/AvatarFallback.vue
|
|
5084
|
-
const _sfc_main$
|
|
6177
|
+
const _sfc_main$24 = /* @__PURE__ */ defineComponent({
|
|
5085
6178
|
name: "AvatarFallback",
|
|
5086
6179
|
__name: "AvatarFallback",
|
|
5087
6180
|
props: {
|
|
@@ -5107,11 +6200,11 @@ const _sfc_main$17 = /* @__PURE__ */ defineComponent({
|
|
|
5107
6200
|
};
|
|
5108
6201
|
}
|
|
5109
6202
|
});
|
|
5110
|
-
var AvatarFallback_default = _sfc_main$
|
|
6203
|
+
var AvatarFallback_default = _sfc_main$24;
|
|
5111
6204
|
|
|
5112
6205
|
//#endregion
|
|
5113
6206
|
//#region src/components/Avatar/AvatarImage.vue
|
|
5114
|
-
const _sfc_main$
|
|
6207
|
+
const _sfc_main$23 = /* @__PURE__ */ defineComponent({
|
|
5115
6208
|
name: "AvatarImage",
|
|
5116
6209
|
inheritAttrs: false,
|
|
5117
6210
|
__name: "AvatarImage",
|
|
@@ -5168,11 +6261,11 @@ const _sfc_main$16 = /* @__PURE__ */ defineComponent({
|
|
|
5168
6261
|
};
|
|
5169
6262
|
}
|
|
5170
6263
|
});
|
|
5171
|
-
var AvatarImage_default = _sfc_main$
|
|
6264
|
+
var AvatarImage_default = _sfc_main$23;
|
|
5172
6265
|
|
|
5173
6266
|
//#endregion
|
|
5174
6267
|
//#region src/components/Avatar/AvatarRoot.vue
|
|
5175
|
-
const _sfc_main$
|
|
6268
|
+
const _sfc_main$22 = /* @__PURE__ */ defineComponent({
|
|
5176
6269
|
name: "AvatarRoot",
|
|
5177
6270
|
__name: "AvatarRoot",
|
|
5178
6271
|
props: {
|
|
@@ -5198,7 +6291,7 @@ const _sfc_main$15 = /* @__PURE__ */ defineComponent({
|
|
|
5198
6291
|
};
|
|
5199
6292
|
}
|
|
5200
6293
|
});
|
|
5201
|
-
var AvatarRoot_default = _sfc_main$
|
|
6294
|
+
var AvatarRoot_default = _sfc_main$22;
|
|
5202
6295
|
|
|
5203
6296
|
//#endregion
|
|
5204
6297
|
//#region src/components/Avatar/index.ts
|
|
@@ -5210,7 +6303,7 @@ const Avatar = {
|
|
|
5210
6303
|
|
|
5211
6304
|
//#endregion
|
|
5212
6305
|
//#region src/components/ExpansionPanel/ExpansionPanelActivator.vue
|
|
5213
|
-
const _sfc_main$
|
|
6306
|
+
const _sfc_main$21 = /* @__PURE__ */ defineComponent({
|
|
5214
6307
|
name: "ExpansionPanelActivator",
|
|
5215
6308
|
__name: "ExpansionPanelActivator",
|
|
5216
6309
|
props: {
|
|
@@ -5226,7 +6319,7 @@ const _sfc_main$14 = /* @__PURE__ */ defineComponent({
|
|
|
5226
6319
|
context.ticket.toggle();
|
|
5227
6320
|
}
|
|
5228
6321
|
}
|
|
5229
|
-
const
|
|
6322
|
+
const slotProps = toRef(() => ({
|
|
5230
6323
|
"id": context.headerId.value,
|
|
5231
6324
|
"role": "button",
|
|
5232
6325
|
"tabindex": context.isDisabled.value ? -1 : 0,
|
|
@@ -5238,20 +6331,24 @@ const _sfc_main$14 = /* @__PURE__ */ defineComponent({
|
|
|
5238
6331
|
"onClick": context.ticket.toggle,
|
|
5239
6332
|
onKeydown
|
|
5240
6333
|
}));
|
|
6334
|
+
const isExpanded = toRef(() => context.ticket.isSelected.value);
|
|
6335
|
+
const isDisabled = toRef(() => context.isDisabled.value);
|
|
5241
6336
|
return (_ctx, _cache) => {
|
|
5242
6337
|
return openBlock(), createBlock(unref(Atom_default), {
|
|
5243
|
-
id:
|
|
5244
|
-
"aria-controls":
|
|
5245
|
-
"aria-disabled":
|
|
5246
|
-
"aria-expanded":
|
|
6338
|
+
id: slotProps.value.id,
|
|
6339
|
+
"aria-controls": slotProps.value["aria-controls"],
|
|
6340
|
+
"aria-disabled": slotProps.value["aria-disabled"],
|
|
6341
|
+
"aria-expanded": slotProps.value["aria-expanded"],
|
|
5247
6342
|
as: __props.as,
|
|
6343
|
+
"data-disabled": isDisabled.value ? "" : void 0,
|
|
6344
|
+
"data-expanded": isExpanded.value ? "" : void 0,
|
|
5248
6345
|
renderless: __props.renderless,
|
|
5249
|
-
role:
|
|
5250
|
-
tabindex:
|
|
6346
|
+
role: slotProps.value.role,
|
|
6347
|
+
tabindex: slotProps.value.tabindex,
|
|
5251
6348
|
onClick: unref(context).ticket.toggle,
|
|
5252
6349
|
onKeydown
|
|
5253
6350
|
}, {
|
|
5254
|
-
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(
|
|
6351
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
5255
6352
|
_: 3
|
|
5256
6353
|
}, 8, [
|
|
5257
6354
|
"id",
|
|
@@ -5259,6 +6356,8 @@ const _sfc_main$14 = /* @__PURE__ */ defineComponent({
|
|
|
5259
6356
|
"aria-disabled",
|
|
5260
6357
|
"aria-expanded",
|
|
5261
6358
|
"as",
|
|
6359
|
+
"data-disabled",
|
|
6360
|
+
"data-expanded",
|
|
5262
6361
|
"renderless",
|
|
5263
6362
|
"role",
|
|
5264
6363
|
"tabindex",
|
|
@@ -5267,51 +6366,54 @@ const _sfc_main$14 = /* @__PURE__ */ defineComponent({
|
|
|
5267
6366
|
};
|
|
5268
6367
|
}
|
|
5269
6368
|
});
|
|
5270
|
-
var ExpansionPanelActivator_default = _sfc_main$
|
|
6369
|
+
var ExpansionPanelActivator_default = _sfc_main$21;
|
|
5271
6370
|
|
|
5272
6371
|
//#endregion
|
|
5273
6372
|
//#region src/components/ExpansionPanel/ExpansionPanelContent.vue
|
|
5274
|
-
const _sfc_main$
|
|
6373
|
+
const _sfc_main$20 = /* @__PURE__ */ defineComponent({
|
|
5275
6374
|
name: "ExpansionPanelContent",
|
|
5276
6375
|
__name: "ExpansionPanelContent",
|
|
5277
6376
|
props: {
|
|
5278
6377
|
itemNamespace: { default: "v0:expansion-panel-item" },
|
|
5279
|
-
as: {},
|
|
6378
|
+
as: { default: "div" },
|
|
5280
6379
|
renderless: { type: Boolean }
|
|
5281
6380
|
},
|
|
5282
6381
|
setup(__props) {
|
|
5283
6382
|
const context = useContext(__props.itemNamespace);
|
|
5284
|
-
const
|
|
6383
|
+
const slotProps = toRef(() => ({
|
|
5285
6384
|
"id": context.contentId.value,
|
|
5286
6385
|
"role": "region",
|
|
5287
6386
|
"aria-labelledby": context.headerId.value,
|
|
5288
6387
|
"isSelected": context.ticket.isSelected.value
|
|
5289
6388
|
}));
|
|
6389
|
+
const isExpanded = toRef(() => context.ticket.isSelected.value);
|
|
5290
6390
|
return (_ctx, _cache) => {
|
|
5291
6391
|
return openBlock(), createBlock(unref(Atom_default), {
|
|
5292
|
-
id:
|
|
5293
|
-
"aria-labelledby":
|
|
6392
|
+
id: slotProps.value.id,
|
|
6393
|
+
"aria-labelledby": slotProps.value["aria-labelledby"],
|
|
5294
6394
|
as: __props.as,
|
|
6395
|
+
"data-expanded": isExpanded.value ? "" : void 0,
|
|
5295
6396
|
renderless: __props.renderless,
|
|
5296
|
-
role:
|
|
6397
|
+
role: slotProps.value.role
|
|
5297
6398
|
}, {
|
|
5298
|
-
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(
|
|
6399
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
5299
6400
|
_: 3
|
|
5300
6401
|
}, 8, [
|
|
5301
6402
|
"id",
|
|
5302
6403
|
"aria-labelledby",
|
|
5303
6404
|
"as",
|
|
6405
|
+
"data-expanded",
|
|
5304
6406
|
"renderless",
|
|
5305
6407
|
"role"
|
|
5306
6408
|
]);
|
|
5307
6409
|
};
|
|
5308
6410
|
}
|
|
5309
6411
|
});
|
|
5310
|
-
var ExpansionPanelContent_default = _sfc_main$
|
|
6412
|
+
var ExpansionPanelContent_default = _sfc_main$20;
|
|
5311
6413
|
|
|
5312
6414
|
//#endregion
|
|
5313
6415
|
//#region src/components/ExpansionPanel/ExpansionPanelItem.vue
|
|
5314
|
-
const _sfc_main$
|
|
6416
|
+
const _sfc_main$19 = /* @__PURE__ */ defineComponent({
|
|
5315
6417
|
name: "ExpansionPanelItem",
|
|
5316
6418
|
__name: "ExpansionPanelItem",
|
|
5317
6419
|
props: {
|
|
@@ -5354,11 +6456,11 @@ const _sfc_main$12 = /* @__PURE__ */ defineComponent({
|
|
|
5354
6456
|
};
|
|
5355
6457
|
}
|
|
5356
6458
|
});
|
|
5357
|
-
var ExpansionPanelItem_default = _sfc_main$
|
|
6459
|
+
var ExpansionPanelItem_default = _sfc_main$19;
|
|
5358
6460
|
|
|
5359
6461
|
//#endregion
|
|
5360
6462
|
//#region src/components/ExpansionPanel/ExpansionPanelRoot.vue
|
|
5361
|
-
const _sfc_main$
|
|
6463
|
+
const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
5362
6464
|
name: "ExpansionPanelRoot",
|
|
5363
6465
|
__name: "ExpansionPanelRoot",
|
|
5364
6466
|
props: /* @__PURE__ */ mergeModels({
|
|
@@ -5432,7 +6534,7 @@ const _sfc_main$11 = /* @__PURE__ */ defineComponent({
|
|
|
5432
6534
|
};
|
|
5433
6535
|
}
|
|
5434
6536
|
});
|
|
5435
|
-
var ExpansionPanelRoot_default = _sfc_main$
|
|
6537
|
+
var ExpansionPanelRoot_default = _sfc_main$18;
|
|
5436
6538
|
|
|
5437
6539
|
//#endregion
|
|
5438
6540
|
//#region src/components/ExpansionPanel/index.ts
|
|
@@ -5445,13 +6547,14 @@ const ExpansionPanel = {
|
|
|
5445
6547
|
|
|
5446
6548
|
//#endregion
|
|
5447
6549
|
//#region src/components/Group/GroupItem.vue
|
|
5448
|
-
const _sfc_main$
|
|
6550
|
+
const _sfc_main$17 = /* @__PURE__ */ defineComponent({
|
|
5449
6551
|
name: "GroupItem",
|
|
5450
6552
|
__name: "GroupItem",
|
|
5451
6553
|
props: {
|
|
5452
6554
|
label: {},
|
|
5453
6555
|
id: {},
|
|
5454
6556
|
disabled: {},
|
|
6557
|
+
indeterminate: { default: false },
|
|
5455
6558
|
value: {},
|
|
5456
6559
|
namespace: { default: "v0:group" }
|
|
5457
6560
|
},
|
|
@@ -5460,9 +6563,10 @@ const _sfc_main$10 = /* @__PURE__ */ defineComponent({
|
|
|
5460
6563
|
const ticket = group.register({
|
|
5461
6564
|
id: __props.id,
|
|
5462
6565
|
value: __props.value,
|
|
5463
|
-
disabled: __props.disabled
|
|
6566
|
+
disabled: __props.disabled,
|
|
6567
|
+
indeterminate: __props.indeterminate
|
|
5464
6568
|
});
|
|
5465
|
-
const isDisabled = toRef(() => ticket.disabled || group.disabled);
|
|
6569
|
+
const isDisabled = toRef(() => toValue(ticket.disabled) || toValue(group.disabled));
|
|
5466
6570
|
onUnmounted(() => {
|
|
5467
6571
|
group.unregister(ticket.id);
|
|
5468
6572
|
});
|
|
@@ -5472,21 +6576,24 @@ const _sfc_main$10 = /* @__PURE__ */ defineComponent({
|
|
|
5472
6576
|
ariaDisabled: toValue(isDisabled.value),
|
|
5473
6577
|
ariaSelected: toValue(unref(ticket).isSelected),
|
|
5474
6578
|
disabled: toValue(isDisabled.value),
|
|
6579
|
+
isMixed: toValue(unref(ticket).isMixed),
|
|
5475
6580
|
isSelected: toValue(unref(ticket).isSelected),
|
|
5476
6581
|
label: __props.label,
|
|
6582
|
+
mix: unref(ticket).mix,
|
|
5477
6583
|
select: unref(ticket).select,
|
|
5478
6584
|
toggle: unref(ticket).toggle,
|
|
6585
|
+
unmix: unref(ticket).unmix,
|
|
5479
6586
|
unselect: unref(ticket).unselect,
|
|
5480
6587
|
value: __props.value
|
|
5481
6588
|
});
|
|
5482
6589
|
};
|
|
5483
6590
|
}
|
|
5484
6591
|
});
|
|
5485
|
-
var GroupItem_default = _sfc_main$
|
|
6592
|
+
var GroupItem_default = _sfc_main$17;
|
|
5486
6593
|
|
|
5487
6594
|
//#endregion
|
|
5488
6595
|
//#region src/components/Group/GroupRoot.vue
|
|
5489
|
-
const _sfc_main$
|
|
6596
|
+
const _sfc_main$16 = /* @__PURE__ */ defineComponent({
|
|
5490
6597
|
name: "GroupRoot",
|
|
5491
6598
|
__name: "GroupRoot",
|
|
5492
6599
|
props: /* @__PURE__ */ mergeModels({
|
|
@@ -5523,14 +6630,20 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
5523
6630
|
return renderSlot(_ctx.$slots, "default", {
|
|
5524
6631
|
ariaMultiselectable: true,
|
|
5525
6632
|
disabled: toValue(unref(context).disabled),
|
|
6633
|
+
isAllSelected: unref(context).isAllSelected.value,
|
|
6634
|
+
isMixed: unref(context).isMixed.value,
|
|
6635
|
+
isNoneSelected: unref(context).isNoneSelected.value,
|
|
5526
6636
|
select: unref(context).select,
|
|
6637
|
+
selectAll: unref(context).selectAll,
|
|
5527
6638
|
toggle: unref(context).toggle,
|
|
5528
|
-
|
|
6639
|
+
toggleAll: unref(context).toggleAll,
|
|
6640
|
+
unselect: unref(context).unselect,
|
|
6641
|
+
unselectAll: unref(context).unselectAll
|
|
5529
6642
|
});
|
|
5530
6643
|
};
|
|
5531
6644
|
}
|
|
5532
6645
|
});
|
|
5533
|
-
var GroupRoot_default = _sfc_main$
|
|
6646
|
+
var GroupRoot_default = _sfc_main$16;
|
|
5534
6647
|
|
|
5535
6648
|
//#endregion
|
|
5536
6649
|
//#region src/components/Group/index.ts
|
|
@@ -5539,6 +6652,512 @@ const Group = {
|
|
|
5539
6652
|
Item: GroupItem_default
|
|
5540
6653
|
};
|
|
5541
6654
|
|
|
6655
|
+
//#endregion
|
|
6656
|
+
//#region src/components/Pagination/PaginationRoot.vue
|
|
6657
|
+
function usePaginationControls(namespace) {
|
|
6658
|
+
return useContext(`${namespace}:controls`);
|
|
6659
|
+
}
|
|
6660
|
+
function usePaginationItems(namespace) {
|
|
6661
|
+
return useContext(`${namespace}:items`);
|
|
6662
|
+
}
|
|
6663
|
+
const _sfc_main$15 = /* @__PURE__ */ defineComponent({
|
|
6664
|
+
name: "PaginationRoot",
|
|
6665
|
+
__name: "PaginationRoot",
|
|
6666
|
+
props: /* @__PURE__ */ mergeModels({
|
|
6667
|
+
namespace: { default: "v0:pagination" },
|
|
6668
|
+
size: { default: 1 },
|
|
6669
|
+
totalVisible: {},
|
|
6670
|
+
itemsPerPage: { default: 10 },
|
|
6671
|
+
ellipsis: {
|
|
6672
|
+
type: [String, Boolean],
|
|
6673
|
+
default: "..."
|
|
6674
|
+
},
|
|
6675
|
+
as: { default: "nav" },
|
|
6676
|
+
renderless: { type: Boolean }
|
|
6677
|
+
}, {
|
|
6678
|
+
"modelValue": { default: 1 },
|
|
6679
|
+
"modelModifiers": {}
|
|
6680
|
+
}),
|
|
6681
|
+
emits: /* @__PURE__ */ mergeModels(["update:model-value"], ["update:modelValue"]),
|
|
6682
|
+
setup(__props) {
|
|
6683
|
+
const page = useModel(__props, "modelValue");
|
|
6684
|
+
const itemWidth = shallowRef(0);
|
|
6685
|
+
const itemGap = shallowRef(0);
|
|
6686
|
+
const atom = useTemplateRef("atom");
|
|
6687
|
+
const locale = useLocale();
|
|
6688
|
+
const [, provideControlContext, controls] = createRegistryContext({ namespace: `${__props.namespace}:controls` });
|
|
6689
|
+
const [, provideItemContext, items] = createRegistryContext({ namespace: `${__props.namespace}:items` });
|
|
6690
|
+
const overflow = createOverflow({
|
|
6691
|
+
container: () => atom.value?.element,
|
|
6692
|
+
itemWidth,
|
|
6693
|
+
gap: itemGap
|
|
6694
|
+
});
|
|
6695
|
+
watch([() => items.size, () => overflow.width.value], () => {
|
|
6696
|
+
const el = items.seek("first")?.value;
|
|
6697
|
+
const root = overflow.container.value;
|
|
6698
|
+
if (!el || !root) return;
|
|
6699
|
+
const rootStyle = getComputedStyle(root);
|
|
6700
|
+
const style = getComputedStyle(el);
|
|
6701
|
+
const marginX = Number.parseFloat(style.marginLeft) + Number.parseFloat(style.marginRight);
|
|
6702
|
+
const gapX = Number.parseFloat(rootStyle.gap) || 0;
|
|
6703
|
+
itemWidth.value = el.offsetWidth + marginX;
|
|
6704
|
+
itemGap.value = gapX;
|
|
6705
|
+
}, { flush: "post" });
|
|
6706
|
+
const visible = computed(() => {
|
|
6707
|
+
const totalCap = overflow.capacity.value;
|
|
6708
|
+
if (totalCap === Infinity) return __props.totalVisible ?? Infinity;
|
|
6709
|
+
const pageCap = Math.max(0, totalCap - controls.size);
|
|
6710
|
+
const noVisible = /* @__PURE__ */ isNullOrUndefined(__props.totalVisible);
|
|
6711
|
+
if (pageCap > 0) return noVisible ? pageCap : Math.min(__props.totalVisible, pageCap);
|
|
6712
|
+
return noVisible ? 1 : __props.totalVisible;
|
|
6713
|
+
});
|
|
6714
|
+
const [, providePaginationContext, pagination] = createPaginationContext({
|
|
6715
|
+
namespace: __props.namespace,
|
|
6716
|
+
page,
|
|
6717
|
+
visible,
|
|
6718
|
+
ellipsis: __props.ellipsis,
|
|
6719
|
+
size: () => __props.size,
|
|
6720
|
+
itemsPerPage: () => __props.itemsPerPage
|
|
6721
|
+
});
|
|
6722
|
+
const slotProps = toRef(() => ({
|
|
6723
|
+
ariaLabel: locale.t("Pagination.label", void 0, "Pagination"),
|
|
6724
|
+
page: pagination.page.value,
|
|
6725
|
+
size: pagination.size,
|
|
6726
|
+
pages: pagination.pages,
|
|
6727
|
+
itemsPerPage: pagination.itemsPerPage,
|
|
6728
|
+
items: pagination.items.value,
|
|
6729
|
+
pageStart: pagination.pageStart.value,
|
|
6730
|
+
pageStop: pagination.pageStop.value,
|
|
6731
|
+
isFirst: pagination.isFirst.value,
|
|
6732
|
+
isLast: pagination.isLast.value,
|
|
6733
|
+
first: pagination.first,
|
|
6734
|
+
last: pagination.last,
|
|
6735
|
+
next: pagination.next,
|
|
6736
|
+
prev: pagination.prev,
|
|
6737
|
+
select: pagination.select
|
|
6738
|
+
}));
|
|
6739
|
+
providePaginationContext();
|
|
6740
|
+
provideControlContext();
|
|
6741
|
+
provideItemContext();
|
|
6742
|
+
return (_ctx, _cache) => {
|
|
6743
|
+
return openBlock(), createBlock(unref(Atom_default), {
|
|
6744
|
+
ref_key: "atom",
|
|
6745
|
+
ref: atom,
|
|
6746
|
+
"aria-label": slotProps.value.ariaLabel,
|
|
6747
|
+
as: __props.as,
|
|
6748
|
+
renderless: __props.renderless
|
|
6749
|
+
}, {
|
|
6750
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
6751
|
+
_: 3
|
|
6752
|
+
}, 8, [
|
|
6753
|
+
"aria-label",
|
|
6754
|
+
"as",
|
|
6755
|
+
"renderless"
|
|
6756
|
+
]);
|
|
6757
|
+
};
|
|
6758
|
+
}
|
|
6759
|
+
});
|
|
6760
|
+
var PaginationRoot_default = _sfc_main$15;
|
|
6761
|
+
|
|
6762
|
+
//#endregion
|
|
6763
|
+
//#region src/components/Pagination/PaginationEllipsis.vue
|
|
6764
|
+
const _sfc_main$14 = /* @__PURE__ */ defineComponent({
|
|
6765
|
+
name: "PaginationEllipsis",
|
|
6766
|
+
__name: "PaginationEllipsis",
|
|
6767
|
+
props: {
|
|
6768
|
+
namespace: { default: "v0:pagination" },
|
|
6769
|
+
ellipsis: {},
|
|
6770
|
+
id: { default: () => /* @__PURE__ */ genId() },
|
|
6771
|
+
as: { default: "span" },
|
|
6772
|
+
renderless: { type: Boolean }
|
|
6773
|
+
},
|
|
6774
|
+
setup(__props) {
|
|
6775
|
+
const pagination = usePagination(__props.namespace);
|
|
6776
|
+
const items = usePaginationItems(__props.namespace);
|
|
6777
|
+
const atom = useTemplateRef("atom");
|
|
6778
|
+
watch(() => atom.value?.element, (el) => {
|
|
6779
|
+
if (!el) return;
|
|
6780
|
+
items.register({
|
|
6781
|
+
id: __props.id,
|
|
6782
|
+
value: el
|
|
6783
|
+
});
|
|
6784
|
+
}, { immediate: true });
|
|
6785
|
+
onBeforeUnmount(() => items.unregister(__props.id));
|
|
6786
|
+
const resolvedEllipsis = toRef(() => __props.ellipsis ?? pagination.ellipsis);
|
|
6787
|
+
const slotProps = toRef(() => ({
|
|
6788
|
+
ariaHidden: "true",
|
|
6789
|
+
ellipsis: resolvedEllipsis.value
|
|
6790
|
+
}));
|
|
6791
|
+
return (_ctx, _cache) => {
|
|
6792
|
+
return openBlock(), createBlock(unref(Atom_default), {
|
|
6793
|
+
ref_key: "atom",
|
|
6794
|
+
ref: atom,
|
|
6795
|
+
"aria-hidden": slotProps.value.ariaHidden,
|
|
6796
|
+
as: __props.as,
|
|
6797
|
+
renderless: __props.renderless
|
|
6798
|
+
}, {
|
|
6799
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)), () => [createTextVNode(toDisplayString(resolvedEllipsis.value), 1)])]),
|
|
6800
|
+
_: 3
|
|
6801
|
+
}, 8, [
|
|
6802
|
+
"aria-hidden",
|
|
6803
|
+
"as",
|
|
6804
|
+
"renderless"
|
|
6805
|
+
]);
|
|
6806
|
+
};
|
|
6807
|
+
}
|
|
6808
|
+
});
|
|
6809
|
+
var PaginationEllipsis_default = _sfc_main$14;
|
|
6810
|
+
|
|
6811
|
+
//#endregion
|
|
6812
|
+
//#region src/components/Pagination/PaginationFirst.vue
|
|
6813
|
+
const _sfc_main$13 = /* @__PURE__ */ defineComponent({
|
|
6814
|
+
name: "PaginationFirst",
|
|
6815
|
+
__name: "PaginationFirst",
|
|
6816
|
+
props: {
|
|
6817
|
+
namespace: { default: "v0:pagination" },
|
|
6818
|
+
disabled: { type: Boolean },
|
|
6819
|
+
id: { default: () => /* @__PURE__ */ genId() },
|
|
6820
|
+
as: { default: "button" },
|
|
6821
|
+
renderless: { type: Boolean }
|
|
6822
|
+
},
|
|
6823
|
+
setup(__props) {
|
|
6824
|
+
const locale = useLocale();
|
|
6825
|
+
const pagination = usePagination(__props.namespace);
|
|
6826
|
+
const controls = usePaginationControls(__props.namespace);
|
|
6827
|
+
const atom = useTemplateRef("atom");
|
|
6828
|
+
watch(() => atom.value?.element, (el) => {
|
|
6829
|
+
if (!el) return;
|
|
6830
|
+
controls.register({
|
|
6831
|
+
id: __props.id,
|
|
6832
|
+
value: el
|
|
6833
|
+
});
|
|
6834
|
+
}, { immediate: true });
|
|
6835
|
+
onBeforeUnmount(() => controls.unregister(__props.id));
|
|
6836
|
+
const isDisabled = toRef(() => __props.disabled || pagination.isFirst.value);
|
|
6837
|
+
function onClick() {
|
|
6838
|
+
if (isDisabled.value) return;
|
|
6839
|
+
pagination.first();
|
|
6840
|
+
}
|
|
6841
|
+
const slotProps = toRef(() => ({
|
|
6842
|
+
ariaLabel: locale.t("Pagination.first", void 0, "Go to first page"),
|
|
6843
|
+
disabled: isDisabled.value,
|
|
6844
|
+
onClick
|
|
6845
|
+
}));
|
|
6846
|
+
return (_ctx, _cache) => {
|
|
6847
|
+
return openBlock(), createBlock(unref(Atom_default), {
|
|
6848
|
+
ref_key: "atom",
|
|
6849
|
+
ref: atom,
|
|
6850
|
+
"aria-disabled": slotProps.value.disabled,
|
|
6851
|
+
"aria-label": slotProps.value.ariaLabel,
|
|
6852
|
+
as: __props.as,
|
|
6853
|
+
"data-disabled": slotProps.value.disabled || void 0,
|
|
6854
|
+
disabled: __props.as === "button" ? slotProps.value.disabled : void 0,
|
|
6855
|
+
renderless: __props.renderless,
|
|
6856
|
+
type: __props.as === "button" ? "button" : void 0,
|
|
6857
|
+
onClick: slotProps.value.onClick
|
|
6858
|
+
}, {
|
|
6859
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
6860
|
+
_: 3
|
|
6861
|
+
}, 8, [
|
|
6862
|
+
"aria-disabled",
|
|
6863
|
+
"aria-label",
|
|
6864
|
+
"as",
|
|
6865
|
+
"data-disabled",
|
|
6866
|
+
"disabled",
|
|
6867
|
+
"renderless",
|
|
6868
|
+
"type",
|
|
6869
|
+
"onClick"
|
|
6870
|
+
]);
|
|
6871
|
+
};
|
|
6872
|
+
}
|
|
6873
|
+
});
|
|
6874
|
+
var PaginationFirst_default = _sfc_main$13;
|
|
6875
|
+
|
|
6876
|
+
//#endregion
|
|
6877
|
+
//#region src/components/Pagination/PaginationItem.vue
|
|
6878
|
+
const _sfc_main$12 = /* @__PURE__ */ defineComponent({
|
|
6879
|
+
name: "PaginationItem",
|
|
6880
|
+
__name: "PaginationItem",
|
|
6881
|
+
props: {
|
|
6882
|
+
namespace: { default: "v0:pagination" },
|
|
6883
|
+
value: {},
|
|
6884
|
+
disabled: {
|
|
6885
|
+
type: Boolean,
|
|
6886
|
+
default: false
|
|
6887
|
+
},
|
|
6888
|
+
id: { default: () => /* @__PURE__ */ genId() },
|
|
6889
|
+
as: { default: "button" },
|
|
6890
|
+
renderless: { type: Boolean }
|
|
6891
|
+
},
|
|
6892
|
+
setup(__props) {
|
|
6893
|
+
const locale = useLocale();
|
|
6894
|
+
const pagination = usePagination(__props.namespace);
|
|
6895
|
+
const items = usePaginationItems(__props.namespace);
|
|
6896
|
+
const atom = useTemplateRef("atom");
|
|
6897
|
+
watch(() => atom.value?.element, (el) => {
|
|
6898
|
+
if (!el) return;
|
|
6899
|
+
items.register({
|
|
6900
|
+
id: __props.id,
|
|
6901
|
+
value: el
|
|
6902
|
+
});
|
|
6903
|
+
}, { immediate: true });
|
|
6904
|
+
onBeforeUnmount(() => items.unregister(__props.id));
|
|
6905
|
+
const isSelected = toRef(() => pagination.page.value === __props.value);
|
|
6906
|
+
const ariaLabel = toRef(() => {
|
|
6907
|
+
return isSelected.value ? locale.t("Pagination.currentPage", { page: __props.value }, `Page ${__props.value}, current page`) : locale.t("Pagination.goToPage", { page: __props.value }, `Go to page ${__props.value}`);
|
|
6908
|
+
});
|
|
6909
|
+
const slotProps = toRef(() => ({
|
|
6910
|
+
ariaLabel: ariaLabel.value,
|
|
6911
|
+
ariaCurrent: isSelected.value ? "page" : void 0,
|
|
6912
|
+
page: __props.value,
|
|
6913
|
+
isSelected: isSelected.value,
|
|
6914
|
+
dataSelected: isSelected.value,
|
|
6915
|
+
disabled: __props.disabled,
|
|
6916
|
+
select
|
|
6917
|
+
}));
|
|
6918
|
+
function select() {
|
|
6919
|
+
if (__props.disabled) return;
|
|
6920
|
+
pagination.select(__props.value);
|
|
6921
|
+
}
|
|
6922
|
+
return (_ctx, _cache) => {
|
|
6923
|
+
return openBlock(), createBlock(unref(Atom_default), {
|
|
6924
|
+
ref_key: "atom",
|
|
6925
|
+
ref: atom,
|
|
6926
|
+
"aria-current": slotProps.value.ariaCurrent,
|
|
6927
|
+
"aria-label": slotProps.value.ariaLabel,
|
|
6928
|
+
as: __props.as,
|
|
6929
|
+
"data-disabled": slotProps.value.disabled || void 0,
|
|
6930
|
+
"data-selected": slotProps.value.dataSelected || void 0,
|
|
6931
|
+
disabled: __props.as === "button" ? slotProps.value.disabled : void 0,
|
|
6932
|
+
renderless: __props.renderless,
|
|
6933
|
+
type: __props.as === "button" ? "button" : void 0,
|
|
6934
|
+
onClick: slotProps.value.select
|
|
6935
|
+
}, {
|
|
6936
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
6937
|
+
_: 3
|
|
6938
|
+
}, 8, [
|
|
6939
|
+
"aria-current",
|
|
6940
|
+
"aria-label",
|
|
6941
|
+
"as",
|
|
6942
|
+
"data-disabled",
|
|
6943
|
+
"data-selected",
|
|
6944
|
+
"disabled",
|
|
6945
|
+
"renderless",
|
|
6946
|
+
"type",
|
|
6947
|
+
"onClick"
|
|
6948
|
+
]);
|
|
6949
|
+
};
|
|
6950
|
+
}
|
|
6951
|
+
});
|
|
6952
|
+
var PaginationItem_default = _sfc_main$12;
|
|
6953
|
+
|
|
6954
|
+
//#endregion
|
|
6955
|
+
//#region src/components/Pagination/PaginationLast.vue
|
|
6956
|
+
const _sfc_main$11 = /* @__PURE__ */ defineComponent({
|
|
6957
|
+
name: "PaginationLast",
|
|
6958
|
+
__name: "PaginationLast",
|
|
6959
|
+
props: {
|
|
6960
|
+
namespace: { default: "v0:pagination" },
|
|
6961
|
+
disabled: { type: Boolean },
|
|
6962
|
+
id: { default: () => /* @__PURE__ */ genId() },
|
|
6963
|
+
as: { default: "button" },
|
|
6964
|
+
renderless: { type: Boolean }
|
|
6965
|
+
},
|
|
6966
|
+
setup(__props) {
|
|
6967
|
+
const locale = useLocale();
|
|
6968
|
+
const pagination = usePagination(__props.namespace);
|
|
6969
|
+
const controls = usePaginationControls(__props.namespace);
|
|
6970
|
+
const atom = useTemplateRef("atom");
|
|
6971
|
+
watch(() => atom.value?.element, (el) => {
|
|
6972
|
+
if (!el) return;
|
|
6973
|
+
controls.register({
|
|
6974
|
+
id: __props.id,
|
|
6975
|
+
value: el
|
|
6976
|
+
});
|
|
6977
|
+
}, { immediate: true });
|
|
6978
|
+
onBeforeUnmount(() => controls.unregister(__props.id));
|
|
6979
|
+
const isDisabled = toRef(() => __props.disabled || pagination.isLast.value);
|
|
6980
|
+
function onClick() {
|
|
6981
|
+
if (isDisabled.value) return;
|
|
6982
|
+
pagination.last();
|
|
6983
|
+
}
|
|
6984
|
+
const slotProps = toRef(() => ({
|
|
6985
|
+
ariaLabel: locale.t("Pagination.last", void 0, "Go to last page"),
|
|
6986
|
+
disabled: isDisabled.value,
|
|
6987
|
+
onClick
|
|
6988
|
+
}));
|
|
6989
|
+
return (_ctx, _cache) => {
|
|
6990
|
+
return openBlock(), createBlock(unref(Atom_default), {
|
|
6991
|
+
ref_key: "atom",
|
|
6992
|
+
ref: atom,
|
|
6993
|
+
"aria-disabled": slotProps.value.disabled,
|
|
6994
|
+
"aria-label": slotProps.value.ariaLabel,
|
|
6995
|
+
as: __props.as,
|
|
6996
|
+
"data-disabled": slotProps.value.disabled || void 0,
|
|
6997
|
+
disabled: __props.as === "button" ? slotProps.value.disabled : void 0,
|
|
6998
|
+
renderless: __props.renderless,
|
|
6999
|
+
type: __props.as === "button" ? "button" : void 0,
|
|
7000
|
+
onClick: slotProps.value.onClick
|
|
7001
|
+
}, {
|
|
7002
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
7003
|
+
_: 3
|
|
7004
|
+
}, 8, [
|
|
7005
|
+
"aria-disabled",
|
|
7006
|
+
"aria-label",
|
|
7007
|
+
"as",
|
|
7008
|
+
"data-disabled",
|
|
7009
|
+
"disabled",
|
|
7010
|
+
"renderless",
|
|
7011
|
+
"type",
|
|
7012
|
+
"onClick"
|
|
7013
|
+
]);
|
|
7014
|
+
};
|
|
7015
|
+
}
|
|
7016
|
+
});
|
|
7017
|
+
var PaginationLast_default = _sfc_main$11;
|
|
7018
|
+
|
|
7019
|
+
//#endregion
|
|
7020
|
+
//#region src/components/Pagination/PaginationNext.vue
|
|
7021
|
+
const _sfc_main$10 = /* @__PURE__ */ defineComponent({
|
|
7022
|
+
name: "PaginationNext",
|
|
7023
|
+
__name: "PaginationNext",
|
|
7024
|
+
props: {
|
|
7025
|
+
namespace: { default: "v0:pagination" },
|
|
7026
|
+
disabled: { type: Boolean },
|
|
7027
|
+
id: { default: () => /* @__PURE__ */ genId() },
|
|
7028
|
+
as: { default: "button" },
|
|
7029
|
+
renderless: { type: Boolean }
|
|
7030
|
+
},
|
|
7031
|
+
setup(__props) {
|
|
7032
|
+
const locale = useLocale();
|
|
7033
|
+
const pagination = usePagination(__props.namespace);
|
|
7034
|
+
const controls = usePaginationControls(__props.namespace);
|
|
7035
|
+
const atom = useTemplateRef("atom");
|
|
7036
|
+
watch(() => atom.value?.element, (el) => {
|
|
7037
|
+
if (!el) return;
|
|
7038
|
+
controls.register({
|
|
7039
|
+
id: __props.id,
|
|
7040
|
+
value: el
|
|
7041
|
+
});
|
|
7042
|
+
}, { immediate: true });
|
|
7043
|
+
onBeforeUnmount(() => controls.unregister(__props.id));
|
|
7044
|
+
const isDisabled = toRef(() => __props.disabled || pagination.isLast.value);
|
|
7045
|
+
function onClick() {
|
|
7046
|
+
if (isDisabled.value) return;
|
|
7047
|
+
pagination.next();
|
|
7048
|
+
}
|
|
7049
|
+
const slotProps = toRef(() => ({
|
|
7050
|
+
ariaLabel: locale.t("Pagination.next", void 0, "Go to next page"),
|
|
7051
|
+
disabled: isDisabled.value,
|
|
7052
|
+
onClick
|
|
7053
|
+
}));
|
|
7054
|
+
return (_ctx, _cache) => {
|
|
7055
|
+
return openBlock(), createBlock(unref(Atom_default), {
|
|
7056
|
+
ref_key: "atom",
|
|
7057
|
+
ref: atom,
|
|
7058
|
+
"aria-disabled": slotProps.value.disabled,
|
|
7059
|
+
"aria-label": slotProps.value.ariaLabel,
|
|
7060
|
+
as: __props.as,
|
|
7061
|
+
"data-disabled": slotProps.value.disabled || void 0,
|
|
7062
|
+
disabled: __props.as === "button" ? slotProps.value.disabled : void 0,
|
|
7063
|
+
renderless: __props.renderless,
|
|
7064
|
+
type: __props.as === "button" ? "button" : void 0,
|
|
7065
|
+
onClick: slotProps.value.onClick
|
|
7066
|
+
}, {
|
|
7067
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
7068
|
+
_: 3
|
|
7069
|
+
}, 8, [
|
|
7070
|
+
"aria-disabled",
|
|
7071
|
+
"aria-label",
|
|
7072
|
+
"as",
|
|
7073
|
+
"data-disabled",
|
|
7074
|
+
"disabled",
|
|
7075
|
+
"renderless",
|
|
7076
|
+
"type",
|
|
7077
|
+
"onClick"
|
|
7078
|
+
]);
|
|
7079
|
+
};
|
|
7080
|
+
}
|
|
7081
|
+
});
|
|
7082
|
+
var PaginationNext_default = _sfc_main$10;
|
|
7083
|
+
|
|
7084
|
+
//#endregion
|
|
7085
|
+
//#region src/components/Pagination/PaginationPrev.vue
|
|
7086
|
+
const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
7087
|
+
name: "PaginationPrev",
|
|
7088
|
+
__name: "PaginationPrev",
|
|
7089
|
+
props: {
|
|
7090
|
+
namespace: { default: "v0:pagination" },
|
|
7091
|
+
disabled: { type: Boolean },
|
|
7092
|
+
id: { default: () => /* @__PURE__ */ genId() },
|
|
7093
|
+
as: { default: "button" },
|
|
7094
|
+
renderless: { type: Boolean }
|
|
7095
|
+
},
|
|
7096
|
+
setup(__props) {
|
|
7097
|
+
const locale = useLocale();
|
|
7098
|
+
const pagination = usePagination(__props.namespace);
|
|
7099
|
+
const controls = usePaginationControls(__props.namespace);
|
|
7100
|
+
const atom = useTemplateRef("atom");
|
|
7101
|
+
watch(() => atom.value?.element, (el) => {
|
|
7102
|
+
if (!el) return;
|
|
7103
|
+
controls.register({
|
|
7104
|
+
id: __props.id,
|
|
7105
|
+
value: el
|
|
7106
|
+
});
|
|
7107
|
+
}, { immediate: true });
|
|
7108
|
+
onBeforeUnmount(() => controls.unregister(__props.id));
|
|
7109
|
+
const isDisabled = toRef(() => __props.disabled || pagination.isFirst.value);
|
|
7110
|
+
function onClick() {
|
|
7111
|
+
if (isDisabled.value) return;
|
|
7112
|
+
pagination.prev();
|
|
7113
|
+
}
|
|
7114
|
+
const slotProps = toRef(() => ({
|
|
7115
|
+
ariaLabel: locale.t("Pagination.prev", void 0, "Go to previous page"),
|
|
7116
|
+
disabled: isDisabled.value,
|
|
7117
|
+
onClick
|
|
7118
|
+
}));
|
|
7119
|
+
return (_ctx, _cache) => {
|
|
7120
|
+
return openBlock(), createBlock(unref(Atom_default), {
|
|
7121
|
+
ref_key: "atom",
|
|
7122
|
+
ref: atom,
|
|
7123
|
+
"aria-disabled": slotProps.value.disabled,
|
|
7124
|
+
"aria-label": slotProps.value.ariaLabel,
|
|
7125
|
+
as: __props.as,
|
|
7126
|
+
"data-disabled": slotProps.value.disabled || void 0,
|
|
7127
|
+
disabled: __props.as === "button" ? slotProps.value.disabled : void 0,
|
|
7128
|
+
renderless: __props.renderless,
|
|
7129
|
+
type: __props.as === "button" ? "button" : void 0,
|
|
7130
|
+
onClick: slotProps.value.onClick
|
|
7131
|
+
}, {
|
|
7132
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
7133
|
+
_: 3
|
|
7134
|
+
}, 8, [
|
|
7135
|
+
"aria-disabled",
|
|
7136
|
+
"aria-label",
|
|
7137
|
+
"as",
|
|
7138
|
+
"data-disabled",
|
|
7139
|
+
"disabled",
|
|
7140
|
+
"renderless",
|
|
7141
|
+
"type",
|
|
7142
|
+
"onClick"
|
|
7143
|
+
]);
|
|
7144
|
+
};
|
|
7145
|
+
}
|
|
7146
|
+
});
|
|
7147
|
+
var PaginationPrev_default = _sfc_main$9;
|
|
7148
|
+
|
|
7149
|
+
//#endregion
|
|
7150
|
+
//#region src/components/Pagination/index.ts
|
|
7151
|
+
const Pagination = {
|
|
7152
|
+
Root: PaginationRoot_default,
|
|
7153
|
+
Item: PaginationItem_default,
|
|
7154
|
+
First: PaginationFirst_default,
|
|
7155
|
+
Prev: PaginationPrev_default,
|
|
7156
|
+
Ellipsis: PaginationEllipsis_default,
|
|
7157
|
+
Next: PaginationNext_default,
|
|
7158
|
+
Last: PaginationLast_default
|
|
7159
|
+
};
|
|
7160
|
+
|
|
5542
7161
|
//#endregion
|
|
5543
7162
|
//#region src/components/Popover/PopoverRoot.vue
|
|
5544
7163
|
const [usePopoverContext, providePopoverContext] = createContext("Popover");
|
|
@@ -5705,7 +7324,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
5705
7324
|
value: __props.value,
|
|
5706
7325
|
disabled: __props.disabled
|
|
5707
7326
|
});
|
|
5708
|
-
const isDisabled = toRef(() => ticket.disabled || selection.disabled);
|
|
7327
|
+
const isDisabled = toRef(() => toValue(ticket.disabled) || toValue(selection.disabled));
|
|
5709
7328
|
onUnmounted(() => {
|
|
5710
7329
|
selection.unregister(ticket.id);
|
|
5711
7330
|
});
|
|
@@ -5807,7 +7426,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
5807
7426
|
value: __props.value,
|
|
5808
7427
|
disabled: __props.disabled
|
|
5809
7428
|
});
|
|
5810
|
-
const isDisabled = toRef(() => ticket.disabled || single.disabled);
|
|
7429
|
+
const isDisabled = toRef(() => toValue(ticket.disabled) || toValue(single.disabled));
|
|
5811
7430
|
onUnmounted(() => {
|
|
5812
7431
|
single.unregister(ticket.id);
|
|
5813
7432
|
});
|
|
@@ -5903,7 +7522,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
5903
7522
|
value: __props.value,
|
|
5904
7523
|
disabled: __props.disabled
|
|
5905
7524
|
});
|
|
5906
|
-
const isDisabled = toRef(() => ticket.disabled || step.disabled);
|
|
7525
|
+
const isDisabled = toRef(() => toValue(ticket.disabled) || toValue(step.disabled));
|
|
5907
7526
|
onUnmounted(() => {
|
|
5908
7527
|
step.unregister(ticket.id);
|
|
5909
7528
|
});
|
|
@@ -5986,4 +7605,4 @@ const Step = {
|
|
|
5986
7605
|
};
|
|
5987
7606
|
|
|
5988
7607
|
//#endregion
|
|
5989
|
-
export { Atom_default as Atom, Avatar, COMMON_ELEMENTS, ConsolaLoggerAdapter, ExpansionPanel, Group, IN_BROWSER, MemoryAdapter, PermissionAdapter, PinoLoggerAdapter, Popover, SELF_CLOSING_TAGS, SUPPORTS_INTERSECTION_OBSERVER, SUPPORTS_MATCH_MEDIA, SUPPORTS_MUTATION_OBSERVER, SUPPORTS_OBSERVER, SUPPORTS_TOUCH, Selection, Single, Step, Vuetify0LocaleAdapter, Vuetify0LoggerAdapter, Vuetify0ThemeAdapter, __LOGGER_ENABLED__, createBreakpoints, createBreakpointsContext, createBreakpointsPlugin, createContext, createFeatures, createFeaturesContext, createFeaturesPlugin, createForm, createFormContext, createGroup, createGroupContext, createHydration, createHydrationContext, createHydrationPlugin, createLocale, createLocaleContext, createLocalePlugin, createLogger, createLoggerContext, createLoggerPlugin, createPermissions, createPermissionsContext, createPermissionsPlugin, createPlugin, createQueue, createQueueContext, createRegistryContext, createSelection, createSelectionContext, createSingle, createSingleContext, createStep, createStepContext, createStorage, createStorageContext, createStoragePlugin, createTheme, createThemeContext, createThemePlugin, createTimeline, createTimelineContext, createTokens, createTokensContext, createTrinity, genId, isArray, isBoolean, isFunction, isNull, isNullOrUndefined, isNumber, isObject, isPrimitive, isSelfClosingTag, isString, isUndefined, mergeDeep, provideContext, providePopoverContext,
|
|
7608
|
+
export { Atom_default as Atom, Avatar, COMMON_ELEMENTS, ConsolaLoggerAdapter, ExpansionPanel, Group, IN_BROWSER, MemoryAdapter, Pagination, PermissionAdapter, PinoLoggerAdapter, Popover, SELF_CLOSING_TAGS, SUPPORTS_INTERSECTION_OBSERVER, SUPPORTS_MATCH_MEDIA, SUPPORTS_MUTATION_OBSERVER, SUPPORTS_OBSERVER, SUPPORTS_TOUCH, Selection, Single, Step, Vuetify0LocaleAdapter, Vuetify0LoggerAdapter, Vuetify0ThemeAdapter, __LOGGER_ENABLED__, clamp, createBreakpoints, createBreakpointsContext, createBreakpointsPlugin, createContext, createFallbackHydration, createFeatures, createFeaturesContext, createFeaturesPlugin, createForm, createFormContext, createGroup, createGroupContext, createHydration, createHydrationContext, createHydrationPlugin, createLocale, createLocaleContext, createLocaleFallback, createLocalePlugin, createLogger, createLoggerContext, createLoggerPlugin, createOverflow, createOverflowContext, createPagination, createPaginationContext, createPermissions, createPermissionsContext, createPermissionsPlugin, createPlugin, createQueue, createQueueContext, createRegistryContext, createSelection, createSelectionContext, createSingle, createSingleContext, createStep, createStepContext, createStorage, createStorageContext, createStoragePlugin, createTheme, createThemeContext, createThemePlugin, createTimeline, createTimelineContext, createTokens, createTokensContext, createTrinity, debounce, genId, isArray, isBoolean, isFunction, isNaN, isNull, isNullOrUndefined, isNumber, isObject, isPrimitive, isSelfClosingTag, isString, isUndefined, mergeDeep, provideContext, providePopoverContext, range, toArray, toReactive, useBreakpoints, useContext, useDocumentEventListener, useElementIntersection, useElementSize, useEventListener, useFeatures, useFilter, useForm, useGroup, useHydration, useIntersectionObserver, useKeydown, useLocale, useLogger, useMutationObserver, useOverflow, usePagination, usePaginationControls, usePaginationItems, usePermissions, usePopoverContext, useProxyModel, useProxyRegistry, useQueue, useRegistry, useResizeObserver, useSelection, useSingle, useStep, useStorage, useTheme, useTimeline, useToggleScope, useTokens, useVirtual, useWindowEventListener, version };
|