@vuetify/v0 0.0.18 → 0.0.20
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/README.md +125 -47
- package/dist/browser/index.js +1483 -1499
- package/dist/components/index.d.mts +3 -3
- package/dist/components/index.mjs +4 -4
- package/dist/{components-DRdenC8b.mjs → components-D590hSY0.mjs} +3 -3
- package/dist/composables/index.d.mts +4 -4
- package/dist/composables/index.mjs +5 -5
- package/dist/{composables-DG1MHp-R.mjs → composables-FE6B8JUW.mjs} +240 -274
- package/dist/constants/index.mjs +1 -1
- package/dist/{globals-BGVqrlN7.mjs → globals-exvZ8fiO.mjs} +1 -1
- package/dist/index-4jSy8KIt.d.mts +73 -0
- package/dist/{index-CH7DpIK8.d.mts → index-BYyEPh1S.d.mts} +127 -10
- package/dist/index-CjzlIAtF.d.mts +296 -0
- package/dist/{index-oQuVnpOj.d.mts → index-DahjxaTj.d.mts} +251 -204
- package/dist/{index-DaX9-kmY.d.mts → index-Gr6XPRWt.d.mts} +7 -5
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +6 -6
- package/dist/types/index.d.mts +1 -1
- package/dist/{useStep-DC_JvZpy.mjs → useStep-Dw7XloDM.mjs} +996 -1202
- package/dist/utilities/index.d.mts +2 -2
- package/dist/utilities/index.mjs +1 -1
- package/dist/utilities-BrFKLHFS.mjs +363 -0
- package/package.json +3 -3
- package/dist/index-B-jVvwsm.d.mts +0 -71
- package/dist/index-C5LQZd3v.d.mts +0 -11
- package/dist/utilities-JxCe-nF2.mjs +0 -139
package/dist/browser/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, createBlock, createCommentVNode, createPropsRestProxy, createTextVNode, defineComponent, effectScope, getCurrentInstance, guardReactiveProps, inject, isRef, mergeModels, mergeProps, normalizeProps, 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";
|
|
1
|
+
import { computed, createBlock, createCommentVNode, createPropsRestProxy, createTextVNode, defineComponent, effectScope, getCurrentInstance, guardReactiveProps, inject, isRef, mergeModels, mergeProps, normalizeProps, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, openBlock, provide, reactive, readonly, ref, renderSlot, resolveDynamicComponent, shallowReactive, shallowReadonly, shallowRef, toDisplayString, toRef, toValue, unref, useAttrs, useId, useModel, useTemplateRef, vShow, watch, watchEffect, withCtx, withDirectives } from "vue";
|
|
2
2
|
|
|
3
3
|
//#region src/constants/htmlElements.ts
|
|
4
4
|
const selfClosingTags = [
|
|
@@ -78,54 +78,263 @@ function isSelfClosingTag(tag) {
|
|
|
78
78
|
|
|
79
79
|
//#endregion
|
|
80
80
|
//#region src/utilities/helpers.ts
|
|
81
|
+
/**
|
|
82
|
+
* Checks if a value is a function
|
|
83
|
+
*
|
|
84
|
+
* @param item The value to check
|
|
85
|
+
* @returns True if the value is a function
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* isFunction(() => {}) // true
|
|
90
|
+
* isFunction('string') // false
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
81
93
|
/* @__NO_SIDE_EFFECTS__ */
|
|
82
94
|
function isFunction(item) {
|
|
83
95
|
return typeof item === "function";
|
|
84
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Checks if a value is a string
|
|
99
|
+
*
|
|
100
|
+
* @param item The value to check
|
|
101
|
+
* @returns True if the value is a string
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* isString('hello') // true
|
|
106
|
+
* isString(123) // false
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
85
109
|
/* @__NO_SIDE_EFFECTS__ */
|
|
86
110
|
function isString(item) {
|
|
87
111
|
return typeof item === "string";
|
|
88
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Checks if a value is a number
|
|
115
|
+
*
|
|
116
|
+
* @param item The value to check
|
|
117
|
+
* @returns True if the value is a number (including NaN)
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* isNumber(123) // true
|
|
122
|
+
* isNumber(NaN) // true
|
|
123
|
+
* isNumber('123') // false
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @see {@link isNaN} to check for NaN specifically
|
|
127
|
+
*/
|
|
89
128
|
/* @__NO_SIDE_EFFECTS__ */
|
|
90
129
|
function isNumber(item) {
|
|
91
130
|
return typeof item === "number";
|
|
92
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Checks if a value is a boolean
|
|
134
|
+
*
|
|
135
|
+
* @param item The value to check
|
|
136
|
+
* @returns True if the value is a boolean
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* isBoolean(true) // true
|
|
141
|
+
* isBoolean(false) // true
|
|
142
|
+
* isBoolean(0) // false
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
93
145
|
/* @__NO_SIDE_EFFECTS__ */
|
|
94
146
|
function isBoolean(item) {
|
|
95
147
|
return typeof item === "boolean";
|
|
96
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Checks if a value is a plain object (excludes null and arrays)
|
|
151
|
+
*
|
|
152
|
+
* @param item The value to check
|
|
153
|
+
* @returns True if the value is a plain object
|
|
154
|
+
*
|
|
155
|
+
* @remarks
|
|
156
|
+
* Returns false for null and arrays, even though `typeof null === 'object'`
|
|
157
|
+
* and `typeof [] === 'object'` in JavaScript.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* isObject({}) // true
|
|
162
|
+
* isObject({ a: 1 }) // true
|
|
163
|
+
* isObject(null) // false
|
|
164
|
+
* isObject([]) // false
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* @see {@link isArray} to check for arrays
|
|
168
|
+
* @see {@link isNull} to check for null
|
|
169
|
+
*/
|
|
97
170
|
/* @__NO_SIDE_EFFECTS__ */
|
|
98
171
|
function isObject(item) {
|
|
99
172
|
return typeof item === "object" && item !== null && !Array.isArray(item);
|
|
100
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Checks if a value is an array
|
|
176
|
+
*
|
|
177
|
+
* @param item The value to check
|
|
178
|
+
* @returns True if the value is an array
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* isArray([]) // true
|
|
183
|
+
* isArray([1, 2, 3]) // true
|
|
184
|
+
* isArray('string') // false
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
101
187
|
/* @__NO_SIDE_EFFECTS__ */
|
|
102
188
|
function isArray(item) {
|
|
103
189
|
return Array.isArray(item);
|
|
104
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Checks if a value is null
|
|
193
|
+
*
|
|
194
|
+
* @param item The value to check
|
|
195
|
+
* @returns True if the value is null
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```ts
|
|
199
|
+
* isNull(null) // true
|
|
200
|
+
* isNull(undefined) // false
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* @see {@link isUndefined} to check for undefined
|
|
204
|
+
* @see {@link isNullOrUndefined} to check for either
|
|
205
|
+
*/
|
|
105
206
|
/* @__NO_SIDE_EFFECTS__ */
|
|
106
207
|
function isNull(item) {
|
|
107
208
|
return item === null;
|
|
108
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Checks if a value is null or undefined
|
|
212
|
+
*
|
|
213
|
+
* @param item The value to check
|
|
214
|
+
* @returns True if the value is null or undefined
|
|
215
|
+
*
|
|
216
|
+
* @remarks
|
|
217
|
+
* Uses loose equality (`== null`) which matches both null and undefined.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```ts
|
|
221
|
+
* isNullOrUndefined(null) // true
|
|
222
|
+
* isNullOrUndefined(undefined) // true
|
|
223
|
+
* isNullOrUndefined(0) // false
|
|
224
|
+
* isNullOrUndefined('') // false
|
|
225
|
+
* ```
|
|
226
|
+
*
|
|
227
|
+
* @see {@link isNull} to check for null only
|
|
228
|
+
* @see {@link isUndefined} to check for undefined only
|
|
229
|
+
*/
|
|
109
230
|
/* @__NO_SIDE_EFFECTS__ */
|
|
110
231
|
function isNullOrUndefined(item) {
|
|
111
232
|
return item == null;
|
|
112
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Checks if a value is undefined
|
|
236
|
+
*
|
|
237
|
+
* @param item The value to check
|
|
238
|
+
* @returns True if the value is undefined
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* isUndefined(undefined) // true
|
|
243
|
+
* isUndefined(null) // false
|
|
244
|
+
* ```
|
|
245
|
+
*
|
|
246
|
+
* @see {@link isNull} to check for null
|
|
247
|
+
* @see {@link isNullOrUndefined} to check for either
|
|
248
|
+
*/
|
|
113
249
|
/* @__NO_SIDE_EFFECTS__ */
|
|
114
250
|
function isUndefined(item) {
|
|
115
251
|
return item === void 0;
|
|
116
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Checks if a value is a primitive (string, number, or boolean)
|
|
255
|
+
*
|
|
256
|
+
* @param item The value to check
|
|
257
|
+
* @returns True if the value is a string, number, or boolean
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```ts
|
|
261
|
+
* isPrimitive('hello') // true
|
|
262
|
+
* isPrimitive(123) // true
|
|
263
|
+
* isPrimitive(true) // true
|
|
264
|
+
* isPrimitive({}) // false
|
|
265
|
+
* isPrimitive(null) // false
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
117
268
|
/* @__NO_SIDE_EFFECTS__ */
|
|
118
269
|
function isPrimitive(item) {
|
|
119
270
|
return typeof item === "string" || typeof item === "number" || typeof item === "boolean";
|
|
120
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Checks if a value is a symbol
|
|
274
|
+
*
|
|
275
|
+
* @param item The value to check
|
|
276
|
+
* @returns True if the value is a symbol
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```ts
|
|
280
|
+
* isSymbol(Symbol('test')) // true
|
|
281
|
+
* isSymbol('symbol') // false
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
121
284
|
/* @__NO_SIDE_EFFECTS__ */
|
|
122
285
|
function isSymbol(item) {
|
|
123
286
|
return typeof item === "symbol";
|
|
124
287
|
}
|
|
288
|
+
/**
|
|
289
|
+
* Checks if a value is NaN (Not a Number)
|
|
290
|
+
*
|
|
291
|
+
* @param item The value to check
|
|
292
|
+
* @returns True if the value is NaN
|
|
293
|
+
*
|
|
294
|
+
* @remarks
|
|
295
|
+
* Uses `Number.isNaN()` which only returns true for the actual NaN value,
|
|
296
|
+
* unlike the global `isNaN()` which coerces the argument to a number first.
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```ts
|
|
300
|
+
* isNaN(NaN) // true
|
|
301
|
+
* isNaN(123) // false
|
|
302
|
+
* isNaN('hello') // false (unlike global isNaN)
|
|
303
|
+
* isNaN(undefined) // false (unlike global isNaN)
|
|
304
|
+
* ```
|
|
305
|
+
*
|
|
306
|
+
* @see {@link isNumber} to check if a value is a number type
|
|
307
|
+
*/
|
|
125
308
|
/* @__NO_SIDE_EFFECTS__ */
|
|
126
309
|
function isNaN(item) {
|
|
127
310
|
return /* @__PURE__ */ isNumber(item) && Number.isNaN(item);
|
|
128
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Deeply merges source objects into a target object
|
|
314
|
+
*
|
|
315
|
+
* @param target The target object to merge into (will be mutated)
|
|
316
|
+
* @param sources One or more source objects to merge from
|
|
317
|
+
* @returns The mutated target object
|
|
318
|
+
*
|
|
319
|
+
* @remarks
|
|
320
|
+
* - Mutates the target object in place
|
|
321
|
+
* - Nested objects are recursively merged
|
|
322
|
+
* - Arrays are replaced, not merged
|
|
323
|
+
* - Primitives from sources overwrite target values
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```ts
|
|
327
|
+
* const target = { a: 1, b: { c: 2 } }
|
|
328
|
+
* mergeDeep(target, { b: { d: 3 } })
|
|
329
|
+
* // target is now { a: 1, b: { c: 2, d: 3 } }
|
|
330
|
+
*
|
|
331
|
+
* // Multiple sources
|
|
332
|
+
* mergeDeep({}, { a: 1 }, { b: 2 }) // { a: 1, b: 2 }
|
|
333
|
+
*
|
|
334
|
+
* // Arrays are replaced
|
|
335
|
+
* mergeDeep({ arr: [1, 2] }, { arr: [3] }) // { arr: [3] }
|
|
336
|
+
* ```
|
|
337
|
+
*/
|
|
129
338
|
/* @__NO_SIDE_EFFECTS__ */
|
|
130
339
|
function mergeDeep(target, ...sources) {
|
|
131
340
|
if (sources.length === 0) return target;
|
|
@@ -141,6 +350,21 @@ function mergeDeep(target, ...sources) {
|
|
|
141
350
|
}
|
|
142
351
|
return /* @__PURE__ */ mergeDeep(target, ...sources);
|
|
143
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* Generates a random 7-character alphanumeric ID
|
|
355
|
+
*
|
|
356
|
+
* @returns A random string of 7 characters (a-z, 0-9)
|
|
357
|
+
*
|
|
358
|
+
* @remarks
|
|
359
|
+
* Uses `Math.random()` converted to base-36. Not cryptographically secure.
|
|
360
|
+
* Suitable for unique keys in UI components, not for security purposes.
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* ```ts
|
|
364
|
+
* genId() // 'k7x9m2p'
|
|
365
|
+
* genId() // 'a3b8c1d'
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
144
368
|
/* @__NO_SIDE_EFFECTS__ */
|
|
145
369
|
function genId() {
|
|
146
370
|
return Math.random().toString(36).slice(2, 9);
|
|
@@ -252,22 +476,6 @@ var Atom_default = _sfc_main$27;
|
|
|
252
476
|
//#endregion
|
|
253
477
|
//#region src/composables/createContext/index.ts
|
|
254
478
|
/**
|
|
255
|
-
* @module createContext
|
|
256
|
-
*
|
|
257
|
-
* @see https://0.vuetifyjs.com/composables/foundation/create-context
|
|
258
|
-
*
|
|
259
|
-
* @remarks
|
|
260
|
-
* Factory for creating type-safe Vue dependency injection contexts.
|
|
261
|
-
*
|
|
262
|
-
* Provides a wrapper around Vue's provide/inject that throws errors when context is not found,
|
|
263
|
-
* eliminating silent failures and improving developer experience. Supports both app-level and
|
|
264
|
-
* component-level provision.
|
|
265
|
-
*
|
|
266
|
-
* Supports two modes:
|
|
267
|
-
* - **Static key**: `createContext('my-key')` - key is fixed at creation time
|
|
268
|
-
* - **Dynamic key**: `createContext()` or `createContext({ suffix: 'item' })` - key provided at runtime
|
|
269
|
-
*/
|
|
270
|
-
/**
|
|
271
479
|
* Injects a context provided by an ancestor component.
|
|
272
480
|
*
|
|
273
481
|
* @param key The key of the context to inject.
|
|
@@ -513,7 +721,7 @@ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && "matchMedia" in window && typeof wind
|
|
|
513
721
|
const SUPPORTS_OBSERVER = IN_BROWSER && "ResizeObserver" in window;
|
|
514
722
|
const SUPPORTS_INTERSECTION_OBSERVER = IN_BROWSER && "IntersectionObserver" in window;
|
|
515
723
|
const SUPPORTS_MUTATION_OBSERVER = IN_BROWSER && "MutationObserver" in window;
|
|
516
|
-
const version = "0.0.
|
|
724
|
+
const version = "0.0.20";
|
|
517
725
|
const __LOGGER_ENABLED__ = false;
|
|
518
726
|
|
|
519
727
|
//#endregion
|
|
@@ -815,21 +1023,6 @@ function useLogger(namespace = "v0:logger") {
|
|
|
815
1023
|
//#endregion
|
|
816
1024
|
//#region src/composables/useRegistry/index.ts
|
|
817
1025
|
/**
|
|
818
|
-
* @module useRegistry
|
|
819
|
-
*
|
|
820
|
-
* @remarks
|
|
821
|
-
* A foundational composable for managing collections of items (tickets) with:
|
|
822
|
-
* - Unique ID-based access
|
|
823
|
-
* - Index-based ordering
|
|
824
|
-
* - Value-based reverse lookup
|
|
825
|
-
* - Automatic reindexing
|
|
826
|
-
* - Optional event emission
|
|
827
|
-
* - Performance-optimized caching
|
|
828
|
-
*
|
|
829
|
-
* The registry serves as the base for many other composables in the system,
|
|
830
|
-
* including useSelection, useForm, useTimeline, and more.
|
|
831
|
-
*/
|
|
832
|
-
/**
|
|
833
1026
|
* Creates a new registry instance.
|
|
834
1027
|
*
|
|
835
1028
|
* @param options The options for the registry instance.
|
|
@@ -873,17 +1066,21 @@ function useRegistry(options) {
|
|
|
873
1066
|
}
|
|
874
1067
|
function on(event, cb) {
|
|
875
1068
|
if (!events) {
|
|
876
|
-
logger.warn(`
|
|
1069
|
+
logger.warn(`Events are disabled. Initialize with \`useRegistry({ events: true })\` to enable.`);
|
|
877
1070
|
return;
|
|
878
1071
|
}
|
|
879
1072
|
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
880
1073
|
listeners.get(event).add(cb);
|
|
881
1074
|
}
|
|
882
1075
|
function off(event, cb) {
|
|
1076
|
+
if (!events) {
|
|
1077
|
+
logger.warn(`Events are disabled. Initialize with \`useRegistry({ events: true })\` to enable.`);
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
883
1080
|
listeners.get(event)?.delete(cb);
|
|
884
1081
|
}
|
|
885
1082
|
function dispose() {
|
|
886
|
-
|
|
1083
|
+
listeners.clear();
|
|
887
1084
|
clear();
|
|
888
1085
|
}
|
|
889
1086
|
function get(id) {
|
|
@@ -972,9 +1169,9 @@ function useRegistry(options) {
|
|
|
972
1169
|
return entries$1;
|
|
973
1170
|
}
|
|
974
1171
|
function clear() {
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1172
|
+
collection.clear();
|
|
1173
|
+
catalog.clear();
|
|
1174
|
+
directory.clear();
|
|
978
1175
|
invalidate();
|
|
979
1176
|
indexDependentCount = 0;
|
|
980
1177
|
needsReindex = false;
|
|
@@ -983,7 +1180,7 @@ function useRegistry(options) {
|
|
|
983
1180
|
}
|
|
984
1181
|
function invalidate() {
|
|
985
1182
|
if (batching) return;
|
|
986
|
-
|
|
1183
|
+
cache.clear();
|
|
987
1184
|
}
|
|
988
1185
|
function queueEmit(event, data) {
|
|
989
1186
|
if (batching) pendingEmits.push({
|
|
@@ -998,7 +1195,7 @@ function useRegistry(options) {
|
|
|
998
1195
|
pendingEmits = [];
|
|
999
1196
|
try {
|
|
1000
1197
|
const result = fn();
|
|
1001
|
-
|
|
1198
|
+
cache.clear();
|
|
1002
1199
|
for (const { event, data } of pendingEmits) emit(event, data);
|
|
1003
1200
|
return result;
|
|
1004
1201
|
} finally {
|
|
@@ -1009,8 +1206,8 @@ function useRegistry(options) {
|
|
|
1009
1206
|
function reindex() {
|
|
1010
1207
|
const startIndex = minDirtyIndex === Infinity ? 0 : minDirtyIndex;
|
|
1011
1208
|
if (startIndex === 0) {
|
|
1012
|
-
|
|
1013
|
-
|
|
1209
|
+
catalog.clear();
|
|
1210
|
+
directory.clear();
|
|
1014
1211
|
}
|
|
1015
1212
|
invalidate();
|
|
1016
1213
|
let index = 0;
|
|
@@ -1037,7 +1234,7 @@ function useRegistry(options) {
|
|
|
1037
1234
|
const size = collection.size;
|
|
1038
1235
|
const id = registration.id ?? /* @__PURE__ */ genId();
|
|
1039
1236
|
if (has(id)) {
|
|
1040
|
-
logger.warn(`Ticket
|
|
1237
|
+
logger.warn(`Ticket "${id}" already exists. Use \`upsert()\` to update or check \`has()\` before registering.`);
|
|
1041
1238
|
return get(id);
|
|
1042
1239
|
}
|
|
1043
1240
|
const valueIsUndefined = /* @__PURE__ */ isUndefined(registration.value);
|
|
@@ -1087,12 +1284,16 @@ function useRegistry(options) {
|
|
|
1087
1284
|
}
|
|
1088
1285
|
if (removed.length === 0) return;
|
|
1089
1286
|
invalidate();
|
|
1090
|
-
|
|
1287
|
+
for (const ticket of removed) queueEmit("unregister:ticket", ticket);
|
|
1091
1288
|
needsReindex = true;
|
|
1092
1289
|
}
|
|
1093
1290
|
function seek(direction = "first", from, predicate) {
|
|
1094
1291
|
if (collection.size === 0) return void 0;
|
|
1095
1292
|
if (needsReindex) reindex();
|
|
1293
|
+
if (!predicate && /* @__PURE__ */ isUndefined(from)) {
|
|
1294
|
+
const tickets$1 = values();
|
|
1295
|
+
return direction === "first" ? tickets$1[0] : tickets$1.at(-1);
|
|
1296
|
+
}
|
|
1096
1297
|
const tickets = values();
|
|
1097
1298
|
const index = /* @__PURE__ */ isUndefined(from) ? void 0 : Math.max(0, Math.min(from, tickets.length - 1));
|
|
1098
1299
|
if (direction === "last") {
|
|
@@ -1179,21 +1380,6 @@ function createRegistryContext(_options = {}) {
|
|
|
1179
1380
|
//#endregion
|
|
1180
1381
|
//#region src/composables/useSelection/index.ts
|
|
1181
1382
|
/**
|
|
1182
|
-
* @module useSelection
|
|
1183
|
-
*
|
|
1184
|
-
* @remarks
|
|
1185
|
-
* Base composable for managing selected items in a collection with Set-based tracking.
|
|
1186
|
-
*
|
|
1187
|
-
* Key features:
|
|
1188
|
-
* - Set-based selectedIds for O(1) selection checks
|
|
1189
|
-
* - Mandatory selection mode (prevents deselecting last item)
|
|
1190
|
-
* - Auto-enrollment option (selects non-disabled items on register)
|
|
1191
|
-
* - Disabled item filtering
|
|
1192
|
-
* - Computed selectedItems and selectedValues Sets
|
|
1193
|
-
*
|
|
1194
|
-
* Extends useRegistry and serves as the base for useSingle, useGroup, useStep, and useFeatures.
|
|
1195
|
-
*/
|
|
1196
|
-
/**
|
|
1197
1383
|
* Creates a new selection instance for managing multiple selected items.
|
|
1198
1384
|
*
|
|
1199
1385
|
* Extends `useRegistry` with selection tracking via a reactive `Set` of selected IDs.
|
|
@@ -1569,20 +1755,6 @@ function toArray(value) {
|
|
|
1569
1755
|
//#endregion
|
|
1570
1756
|
//#region src/composables/useProxyModel/index.ts
|
|
1571
1757
|
/**
|
|
1572
|
-
* @module useProxyModel
|
|
1573
|
-
*
|
|
1574
|
-
* @remarks
|
|
1575
|
-
* Proxy composable for bidirectional sync between selection registry and v-model.
|
|
1576
|
-
*
|
|
1577
|
-
* Key features:
|
|
1578
|
-
* - Bidirectional synchronization
|
|
1579
|
-
* - Array and single-value modes
|
|
1580
|
-
* - Automatic cleanup on scope disposal
|
|
1581
|
-
* - Perfect for form controls with selection backing
|
|
1582
|
-
*
|
|
1583
|
-
* Bridges the gap between selection composables and Vue's v-model.
|
|
1584
|
-
*/
|
|
1585
|
-
/**
|
|
1586
1758
|
* Syncs a ref with a selection registry bidirectionally.
|
|
1587
1759
|
*
|
|
1588
1760
|
* @param registry The selection registry to bind to.
|
|
@@ -1655,7 +1827,8 @@ function useProxyModel(registry, model, options) {
|
|
|
1655
1827
|
flush: "sync",
|
|
1656
1828
|
deep: multiple
|
|
1657
1829
|
});
|
|
1658
|
-
function onRegister(
|
|
1830
|
+
function onRegister(data) {
|
|
1831
|
+
const ticket = data;
|
|
1659
1832
|
if (!pending.has(ticket.value) || ticket.disabled) return;
|
|
1660
1833
|
registryWatch.pause();
|
|
1661
1834
|
modelWatch.pause();
|
|
@@ -1917,21 +2090,6 @@ const ExpansionPanel = {
|
|
|
1917
2090
|
//#endregion
|
|
1918
2091
|
//#region src/composables/useProxyRegistry/index.ts
|
|
1919
2092
|
/**
|
|
1920
|
-
* @module useProxyRegistry
|
|
1921
|
-
*
|
|
1922
|
-
* @remarks
|
|
1923
|
-
* Proxy composable for reactive registry keys, values, entries, and size.
|
|
1924
|
-
*
|
|
1925
|
-
* Key features:
|
|
1926
|
-
* - Reactive proxy for registry data
|
|
1927
|
-
* - Deep or shallow reactivity options
|
|
1928
|
-
* - Event-based updates
|
|
1929
|
-
* - Automatic cleanup on scope disposal
|
|
1930
|
-
* - Transforms Map-based registry into reactive refs
|
|
1931
|
-
*
|
|
1932
|
-
* Perfect for exposing registry data as reactive computed properties.
|
|
1933
|
-
*/
|
|
1934
|
-
/**
|
|
1935
2093
|
* Creates a proxy registry that provides reactive objects for registry data.
|
|
1936
2094
|
*
|
|
1937
2095
|
* @param registry The registry instance to proxy.
|
|
@@ -1981,26 +2139,6 @@ function useProxyRegistry(registry, options) {
|
|
|
1981
2139
|
//#endregion
|
|
1982
2140
|
//#region src/composables/useGroup/index.ts
|
|
1983
2141
|
/**
|
|
1984
|
-
* @module useGroup
|
|
1985
|
-
*
|
|
1986
|
-
* @remarks
|
|
1987
|
-
* Multi-selection composable that extends useSelection with batch operations and tri-state support.
|
|
1988
|
-
*
|
|
1989
|
-
* Key features:
|
|
1990
|
-
* - Batch operations (select/unselect/toggle accept ID | ID[])
|
|
1991
|
-
* - Tri-state support via mixed/indeterminate state (mix/unmix)
|
|
1992
|
-
* - selectedIndexes computed Set for position-based tracking
|
|
1993
|
-
* - Perfect for checkbox trees, multi-select dropdowns, filter panels
|
|
1994
|
-
*
|
|
1995
|
-
* Tri-state behavior:
|
|
1996
|
-
* - Items can be selected, mixed (indeterminate), or unselected
|
|
1997
|
-
* - select() clears mixed state, mix() clears selected state (mutually exclusive)
|
|
1998
|
-
* - toggle() on a mixed item selects it (resolves positively)
|
|
1999
|
-
*
|
|
2000
|
-
* Inheritance chain: useRegistry → useSelection → useGroup
|
|
2001
|
-
* Extended by: useFeatures
|
|
2002
|
-
*/
|
|
2003
|
-
/**
|
|
2004
2142
|
* Creates a new group instance with batch selection and tri-state support.
|
|
2005
2143
|
*
|
|
2006
2144
|
* Extends `createSelection` to support selecting, unselecting, and toggling multiple items
|
|
@@ -2385,1345 +2523,1239 @@ const Group = {
|
|
|
2385
2523
|
};
|
|
2386
2524
|
|
|
2387
2525
|
//#endregion
|
|
2388
|
-
//#region src/composables/
|
|
2526
|
+
//#region src/composables/useLocale/adapters/v0.ts
|
|
2389
2527
|
/**
|
|
2390
|
-
*
|
|
2391
|
-
*
|
|
2392
|
-
* @see https://0.vuetifyjs.com/composables/plugins/use-hydration
|
|
2393
|
-
*
|
|
2394
|
-
* @remarks
|
|
2395
|
-
* SSR hydration state management composable.
|
|
2396
|
-
*
|
|
2397
|
-
* Key features:
|
|
2398
|
-
* - Hydration state detection (browser vs SSR)
|
|
2399
|
-
* - Root component detection
|
|
2400
|
-
* - Readonly hydration state refs
|
|
2401
|
-
* - Plugin installation support
|
|
2402
|
-
* - Perfect for hydration-safe rendering
|
|
2528
|
+
* Vuetify0.x locale adapter implementation
|
|
2403
2529
|
*
|
|
2404
|
-
*
|
|
2530
|
+
* This adapter provides translation and number formatting
|
|
2531
|
+
* capabilities using the Intl API and supports both
|
|
2532
|
+
* numbered ({0}, {1}) and named ({name}) variables in translation strings.
|
|
2405
2533
|
*/
|
|
2534
|
+
var Vuetify0LocaleAdapter = class {
|
|
2535
|
+
t(message, ...params) {
|
|
2536
|
+
let resolvedMessage = message;
|
|
2537
|
+
if (params.length > 0 && /* @__PURE__ */ isObject(params[0])) {
|
|
2538
|
+
const variables = params[0];
|
|
2539
|
+
resolvedMessage = resolvedMessage.replace(/{([a-zA-Z][a-zA-Z0-9_]*)}/g, (match, name) => {
|
|
2540
|
+
return /* @__PURE__ */ isUndefined(variables[name]) ? match : String(variables[name]);
|
|
2541
|
+
});
|
|
2542
|
+
params = params.slice(1);
|
|
2543
|
+
}
|
|
2544
|
+
resolvedMessage = resolvedMessage.replace(/\{(\d+)\}/g, (match, index) => {
|
|
2545
|
+
const idx = Number.parseInt(index, 10);
|
|
2546
|
+
if (!/* @__PURE__ */ isUndefined(params[idx])) return String(params[idx]);
|
|
2547
|
+
return match;
|
|
2548
|
+
});
|
|
2549
|
+
return resolvedMessage;
|
|
2550
|
+
}
|
|
2551
|
+
n(value, locale, ...params) {
|
|
2552
|
+
if (!IN_BROWSER || !locale) return value.toString();
|
|
2553
|
+
const options = params[0];
|
|
2554
|
+
return new Intl.NumberFormat(String(locale), options).format(value);
|
|
2555
|
+
}
|
|
2556
|
+
};
|
|
2557
|
+
|
|
2558
|
+
//#endregion
|
|
2559
|
+
//#region src/composables/useSingle/index.ts
|
|
2406
2560
|
/**
|
|
2407
|
-
* Creates a new
|
|
2561
|
+
* Creates a new single selection instance that enforces only one selected item at a time.
|
|
2408
2562
|
*
|
|
2409
|
-
*
|
|
2563
|
+
* Extends `createSelection` by automatically clearing previous selections when a new item is selected.
|
|
2564
|
+
* Adds computed singular properties: `selectedId`, `selectedItem`, `selectedIndex`, `selectedValue`.
|
|
2410
2565
|
*
|
|
2411
|
-
* @
|
|
2566
|
+
* @param options The options for the single selection instance.
|
|
2567
|
+
* @template Z The type of the single selection ticket.
|
|
2568
|
+
* @template E The type of the single selection context.
|
|
2569
|
+
* @returns A new single selection instance with single-selection enforcement.
|
|
2412
2570
|
*
|
|
2413
|
-
* @
|
|
2414
|
-
*
|
|
2415
|
-
*
|
|
2571
|
+
* @remarks
|
|
2572
|
+
* **Key Differences from `createSelection`:**
|
|
2573
|
+
* - Automatically clears `selectedIds` before selecting a new item (enforces single selection)
|
|
2574
|
+
* - Provides singular computed properties instead of plural sets
|
|
2575
|
+
* - Perfect for tabs, radio buttons, theme selectors, and other single-choice UI components
|
|
2416
2576
|
*
|
|
2417
|
-
*
|
|
2418
|
-
*
|
|
2419
|
-
*
|
|
2420
|
-
*
|
|
2421
|
-
*
|
|
2422
|
-
*/
|
|
2423
|
-
function createHydration() {
|
|
2424
|
-
const isHydrated = shallowRef(false);
|
|
2425
|
-
function hydrate() {
|
|
2426
|
-
isHydrated.value = true;
|
|
2427
|
-
}
|
|
2428
|
-
return {
|
|
2429
|
-
isHydrated: shallowReadonly(isHydrated),
|
|
2430
|
-
hydrate
|
|
2431
|
-
};
|
|
2432
|
-
}
|
|
2433
|
-
function createFallbackHydration() {
|
|
2434
|
-
return {
|
|
2435
|
-
isHydrated: shallowReadonly(shallowRef(true)),
|
|
2436
|
-
hydrate: () => {}
|
|
2437
|
-
};
|
|
2438
|
-
}
|
|
2439
|
-
/**
|
|
2440
|
-
* Creates a new hydration context trinity.
|
|
2577
|
+
* **Computed Properties:**
|
|
2578
|
+
* - `selectedId`: The ID of the selected item (undefined if none selected)
|
|
2579
|
+
* - `selectedItem`: The selected ticket object (undefined if none selected)
|
|
2580
|
+
* - `selectedIndex`: The index of the selected item (-1 if none selected)
|
|
2581
|
+
* - `selectedValue`: The value of the selected item (undefined if none selected)
|
|
2441
2582
|
*
|
|
2442
|
-
*
|
|
2443
|
-
*
|
|
2444
|
-
* @returns A new hydration context trinity.
|
|
2583
|
+
* **Inheritance Chain:**
|
|
2584
|
+
* `useRegistry` → `createSelection` → `createSingle` → `createStep`
|
|
2445
2585
|
*
|
|
2446
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
2586
|
+
* @see https://0.vuetifyjs.com/composables/selection/use-single
|
|
2447
2587
|
*
|
|
2448
2588
|
* @example
|
|
2449
2589
|
* ```ts
|
|
2450
|
-
* import {
|
|
2590
|
+
* import { createSingle } from '@vuetify/v0'
|
|
2451
2591
|
*
|
|
2452
|
-
*
|
|
2453
|
-
*
|
|
2454
|
-
*
|
|
2592
|
+
* const tabs = createSingle({ mandatory: true })
|
|
2593
|
+
*
|
|
2594
|
+
* tabs.onboard([
|
|
2595
|
+
* { id: 'home', value: 'Home' },
|
|
2596
|
+
* { id: 'about', value: 'About' },
|
|
2597
|
+
* { id: 'contact', value: 'Contact' },
|
|
2598
|
+
* ])
|
|
2599
|
+
*
|
|
2600
|
+
* tabs.first() // Select first tab
|
|
2601
|
+
*
|
|
2602
|
+
* console.log(tabs.selectedId.value) // 'home'
|
|
2603
|
+
* console.log(tabs.selectedIndex.value) // 0
|
|
2604
|
+
*
|
|
2605
|
+
* tabs.select('about') // Switch to about tab
|
|
2606
|
+
* console.log(tabs.selectedId.value) // 'about'
|
|
2607
|
+
* console.log(tabs.selectedIds.size) // 1 (always enforces single selection)
|
|
2455
2608
|
* ```
|
|
2456
2609
|
*/
|
|
2457
|
-
function
|
|
2458
|
-
const {
|
|
2459
|
-
const
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2610
|
+
function createSingle(_options = {}) {
|
|
2611
|
+
const { mandatory = false, multiple = false, ...options } = _options;
|
|
2612
|
+
const registry = createSelection({
|
|
2613
|
+
...options,
|
|
2614
|
+
mandatory,
|
|
2615
|
+
multiple
|
|
2616
|
+
});
|
|
2617
|
+
const selectedId = computed(() => registry.selectedIds.values().next().value);
|
|
2618
|
+
const selectedItem = computed(() => registry.selectedItems.value.values().next().value);
|
|
2619
|
+
const selectedIndex = computed(() => selectedItem.value?.index ?? -1);
|
|
2620
|
+
const selectedValue = computed(() => selectedItem.value?.value);
|
|
2621
|
+
function unselect(id) {
|
|
2622
|
+
if (mandatory && registry.selectedIds.size === 1) return;
|
|
2623
|
+
registry.selectedIds.delete(id);
|
|
2463
2624
|
}
|
|
2464
|
-
|
|
2625
|
+
function toggle(id) {
|
|
2626
|
+
if (registry.selectedIds.has(id)) unselect(id);
|
|
2627
|
+
else registry.select(id);
|
|
2628
|
+
}
|
|
2629
|
+
return {
|
|
2630
|
+
...registry,
|
|
2631
|
+
selectedId,
|
|
2632
|
+
selectedItem,
|
|
2633
|
+
selectedIndex,
|
|
2634
|
+
selectedValue,
|
|
2635
|
+
unselect,
|
|
2636
|
+
toggle,
|
|
2637
|
+
get size() {
|
|
2638
|
+
return registry.size;
|
|
2639
|
+
}
|
|
2640
|
+
};
|
|
2465
2641
|
}
|
|
2466
2642
|
/**
|
|
2467
|
-
* Creates a new
|
|
2643
|
+
* Creates a new single selection context.
|
|
2468
2644
|
*
|
|
2469
|
-
* @param options The options for the
|
|
2470
|
-
* @template
|
|
2471
|
-
* @
|
|
2645
|
+
* @param options The options for the single selection context.
|
|
2646
|
+
* @template Z The type of the single selection ticket.
|
|
2647
|
+
* @template E The type of the single selection context.
|
|
2648
|
+
* @returns A new single selection context.
|
|
2472
2649
|
*
|
|
2473
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
2650
|
+
* @see https://0.vuetifyjs.com/composables/selection/use-single
|
|
2474
2651
|
*
|
|
2475
2652
|
* @example
|
|
2476
2653
|
* ```ts
|
|
2477
|
-
* import {
|
|
2478
|
-
* import { createHydrationPlugin } from '@vuetify/v0'
|
|
2479
|
-
* import App from './App.vue'
|
|
2654
|
+
* import { createSingleContext } from '@vuetify/v0'
|
|
2480
2655
|
*
|
|
2481
|
-
*
|
|
2656
|
+
* // With default namespace 'v0:single'
|
|
2657
|
+
* export const [useSingle, provideSingle, context] = createSingleContext()
|
|
2482
2658
|
*
|
|
2483
|
-
*
|
|
2659
|
+
* // In a parent component:
|
|
2660
|
+
* provideSingle()
|
|
2484
2661
|
*
|
|
2485
|
-
*
|
|
2662
|
+
* // In a child component:
|
|
2663
|
+
* const single = useSingle()
|
|
2664
|
+
* single.select('tab-1')
|
|
2486
2665
|
* ```
|
|
2487
2666
|
*/
|
|
2488
|
-
function
|
|
2489
|
-
const { namespace = "v0:
|
|
2490
|
-
const [,
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
provide: (app) => {
|
|
2497
|
-
provideHydrationContext(context, app);
|
|
2498
|
-
},
|
|
2499
|
-
setup: (app) => {
|
|
2500
|
-
app.mixin({ mounted() {
|
|
2501
|
-
if (this.$parent !== null) return;
|
|
2502
|
-
context.hydrate();
|
|
2503
|
-
} });
|
|
2504
|
-
}
|
|
2505
|
-
});
|
|
2667
|
+
function createSingleContext(_options = {}) {
|
|
2668
|
+
const { namespace = "v0:single", ...options } = _options;
|
|
2669
|
+
const [useSingleContext, _provideSingleContext] = createContext(namespace);
|
|
2670
|
+
const context = createSingle(options);
|
|
2671
|
+
function provideSingleContext(_context = context, app) {
|
|
2672
|
+
return _provideSingleContext(_context, app);
|
|
2673
|
+
}
|
|
2674
|
+
return createTrinity(useSingleContext, provideSingleContext, context);
|
|
2506
2675
|
}
|
|
2507
2676
|
/**
|
|
2508
|
-
* Returns the current
|
|
2677
|
+
* Returns the current single selection instance.
|
|
2509
2678
|
*
|
|
2510
|
-
* @param namespace The namespace for the
|
|
2511
|
-
* @returns The current
|
|
2679
|
+
* @param namespace The namespace for the single selection context. Defaults to `'v0:single'`.
|
|
2680
|
+
* @returns The current single selection instance.
|
|
2512
2681
|
*
|
|
2513
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
2682
|
+
* @see https://0.vuetifyjs.com/composables/selection/use-single
|
|
2514
2683
|
*
|
|
2515
2684
|
* @example
|
|
2516
2685
|
* ```vue
|
|
2517
2686
|
* <script setup lang="ts">
|
|
2518
|
-
* import {
|
|
2687
|
+
* import { useSingle } from '@vuetify/v0'
|
|
2519
2688
|
*
|
|
2520
|
-
* const
|
|
2689
|
+
* const tabs = useSingle()
|
|
2521
2690
|
* <\/script>
|
|
2522
2691
|
*
|
|
2523
2692
|
* <template>
|
|
2524
2693
|
* <div>
|
|
2525
|
-
* <p>
|
|
2694
|
+
* <p>Selected: {{ tabs.selectedId }}</p>
|
|
2526
2695
|
* </div>
|
|
2527
2696
|
* </template>
|
|
2528
2697
|
* ```
|
|
2529
2698
|
*/
|
|
2530
|
-
function
|
|
2531
|
-
|
|
2532
|
-
if (!getCurrentInstance()) return fallback;
|
|
2533
|
-
try {
|
|
2534
|
-
return useContext(namespace, fallback);
|
|
2535
|
-
} catch {
|
|
2536
|
-
return fallback;
|
|
2537
|
-
}
|
|
2699
|
+
function useSingle(namespace = "v0:single") {
|
|
2700
|
+
return useContext(namespace);
|
|
2538
2701
|
}
|
|
2539
2702
|
|
|
2540
2703
|
//#endregion
|
|
2541
|
-
//#region src/composables/
|
|
2542
|
-
/**
|
|
2543
|
-
* @module useResizeObserver
|
|
2544
|
-
*
|
|
2545
|
-
* @remarks
|
|
2546
|
-
* ResizeObserver composable with lifecycle management.
|
|
2547
|
-
*
|
|
2548
|
-
* Key features:
|
|
2549
|
-
* - ResizeObserver API wrapper
|
|
2550
|
-
* - Pause/resume/stop functionality
|
|
2551
|
-
* - Automatic cleanup on unmount
|
|
2552
|
-
* - SSR-safe (checks SUPPORTS_OBSERVER)
|
|
2553
|
-
* - Hydration-aware
|
|
2554
|
-
* - Box model options (content-box/border-box)
|
|
2555
|
-
*
|
|
2556
|
-
* Perfect for responsive components and size-based rendering.
|
|
2557
|
-
*/
|
|
2704
|
+
//#region src/composables/useTokens/index.ts
|
|
2558
2705
|
/**
|
|
2559
|
-
*
|
|
2560
|
-
* size changes.
|
|
2706
|
+
* Creates a new token instance.
|
|
2561
2707
|
*
|
|
2562
|
-
* @param
|
|
2563
|
-
* @param
|
|
2564
|
-
* @
|
|
2565
|
-
* @
|
|
2708
|
+
* @param tokens The tokens to use.
|
|
2709
|
+
* @param options The options for the token instance.
|
|
2710
|
+
* @template Z The type of the token ticket.
|
|
2711
|
+
* @template E The type of the token context.
|
|
2712
|
+
* @returns A new token instance.
|
|
2566
2713
|
*
|
|
2567
|
-
* @see https://
|
|
2568
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
2714
|
+
* @see https://www.designtokens.org/tr/drafts/format/
|
|
2715
|
+
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
2569
2716
|
*
|
|
2570
2717
|
* @example
|
|
2571
2718
|
* ```ts
|
|
2572
|
-
* import {
|
|
2573
|
-
* import { useResizeObserver } from '@vuetify/v0'
|
|
2574
|
-
*
|
|
2575
|
-
* const el = ref<HTMLElement>()
|
|
2576
|
-
* const width = ref(0)
|
|
2577
|
-
* const height = ref(0)
|
|
2719
|
+
* import { useTokens } from '@vuetify/v0'
|
|
2578
2720
|
*
|
|
2579
|
-
* const
|
|
2580
|
-
*
|
|
2581
|
-
*
|
|
2582
|
-
*
|
|
2583
|
-
* if (entry) {
|
|
2584
|
-
* width.value = entry.contentRect.width
|
|
2585
|
-
* height.value = entry.contentRect.height
|
|
2586
|
-
* console.log('Size changed:', width.value, 'x', height.value)
|
|
2587
|
-
* }
|
|
2721
|
+
* const tokens = useTokens({
|
|
2722
|
+
* colors: {
|
|
2723
|
+
* primary: '#3b82f6',
|
|
2724
|
+
* secondary: '{colors.primary}', // Alias reference
|
|
2588
2725
|
* },
|
|
2589
|
-
*
|
|
2590
|
-
* )
|
|
2591
|
-
*
|
|
2592
|
-
* // Pause observation
|
|
2593
|
-
* pause()
|
|
2726
|
+
* })
|
|
2594
2727
|
*
|
|
2595
|
-
* //
|
|
2596
|
-
*
|
|
2728
|
+
* console.log(tokens.resolve('{colors.primary}')) // '#3b82f6'
|
|
2729
|
+
* console.log(tokens.resolve('{colors.secondary}')) // '#3b82f6'
|
|
2597
2730
|
* ```
|
|
2598
2731
|
*/
|
|
2599
|
-
function
|
|
2600
|
-
const
|
|
2601
|
-
const
|
|
2602
|
-
const
|
|
2603
|
-
|
|
2604
|
-
function
|
|
2605
|
-
|
|
2606
|
-
observer.value = new ResizeObserver((entries) => {
|
|
2607
|
-
callback(entries.map((entry) => ({
|
|
2608
|
-
contentRect: {
|
|
2609
|
-
width: entry.contentRect.width,
|
|
2610
|
-
height: entry.contentRect.height,
|
|
2611
|
-
top: entry.contentRect.top,
|
|
2612
|
-
left: entry.contentRect.left
|
|
2613
|
-
},
|
|
2614
|
-
target: entry.target
|
|
2615
|
-
})));
|
|
2616
|
-
});
|
|
2617
|
-
observer.value.observe(target.value, { box: options.box || "content-box" });
|
|
2618
|
-
if (options.immediate) {
|
|
2619
|
-
const rect = target.value.getBoundingClientRect();
|
|
2620
|
-
callback([{
|
|
2621
|
-
contentRect: {
|
|
2622
|
-
width: rect.width,
|
|
2623
|
-
height: rect.height,
|
|
2624
|
-
top: rect.top,
|
|
2625
|
-
left: rect.left
|
|
2626
|
-
},
|
|
2627
|
-
target: target.value
|
|
2628
|
-
}]);
|
|
2629
|
-
}
|
|
2630
|
-
}
|
|
2631
|
-
watch([isHydrated, target], () => {
|
|
2632
|
-
cleanup();
|
|
2633
|
-
setup();
|
|
2634
|
-
}, { immediate: true });
|
|
2635
|
-
function cleanup() {
|
|
2636
|
-
if (observer.value) {
|
|
2637
|
-
observer.value.disconnect();
|
|
2638
|
-
observer.value = void 0;
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2641
|
-
function pause() {
|
|
2642
|
-
isPaused.value = true;
|
|
2643
|
-
observer.value?.disconnect();
|
|
2644
|
-
}
|
|
2645
|
-
function resume() {
|
|
2646
|
-
isPaused.value = false;
|
|
2647
|
-
setup();
|
|
2732
|
+
function createTokens(tokens = {}, options = {}) {
|
|
2733
|
+
const logger = useLogger();
|
|
2734
|
+
const registry = useRegistry(options);
|
|
2735
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2736
|
+
registry.onboard(flatten(tokens, options.prefix, !!options.flat));
|
|
2737
|
+
function isAlias(token) {
|
|
2738
|
+
return /* @__PURE__ */ isString(token) && token.length > 2 && token[0] === "{" && token.at(-1) === "}";
|
|
2648
2739
|
}
|
|
2649
|
-
function
|
|
2650
|
-
|
|
2740
|
+
function isTokenAlias(value) {
|
|
2741
|
+
return /* @__PURE__ */ isObject(value) && "$value" in value;
|
|
2651
2742
|
}
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
}
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2743
|
+
function resolve(token, visited = /* @__PURE__ */ new Set()) {
|
|
2744
|
+
const cacheKey = /* @__PURE__ */ isString(token) ? token : JSON.stringify(token);
|
|
2745
|
+
const cached = cache.get(cacheKey);
|
|
2746
|
+
if (!/* @__PURE__ */ isUndefined(cached)) return cached;
|
|
2747
|
+
const reference = isTokenAlias(token) ? token.$value : token;
|
|
2748
|
+
const isAliasReference = /* @__PURE__ */ isString(reference) && isAlias(reference);
|
|
2749
|
+
const clean = isAliasReference ? reference.slice(1, -1) : String(reference);
|
|
2750
|
+
if (visited.has(clean)) {
|
|
2751
|
+
logger.warn(`Circular alias detected for "${clean}"`);
|
|
2752
|
+
cache.set(cacheKey, void 0);
|
|
2753
|
+
return;
|
|
2754
|
+
}
|
|
2755
|
+
visited.add(clean);
|
|
2756
|
+
let found = registry.get(clean);
|
|
2757
|
+
let segments = [];
|
|
2758
|
+
if (!found && clean.includes(".")) {
|
|
2759
|
+
const parts = clean.split(".");
|
|
2760
|
+
for (let i = parts.length - 1; i > 0; i--) {
|
|
2761
|
+
const prefix = parts.slice(0, i).join(".");
|
|
2762
|
+
const suffix = parts.slice(i);
|
|
2763
|
+
const candidate = registry.get(prefix);
|
|
2764
|
+
if (!/* @__PURE__ */ isUndefined(candidate?.value)) {
|
|
2765
|
+
found = candidate;
|
|
2766
|
+
segments = suffix;
|
|
2767
|
+
break;
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
if (/* @__PURE__ */ isUndefined(found?.value)) {
|
|
2772
|
+
if (isAliasReference) logger.warn(`Alias not found for "${String(reference)}"`);
|
|
2773
|
+
cache.set(cacheKey, void 0);
|
|
2774
|
+
return;
|
|
2775
|
+
}
|
|
2776
|
+
let result;
|
|
2777
|
+
let current = found.value;
|
|
2778
|
+
if (segments.length > 0) {
|
|
2779
|
+
if (isTokenAlias(current)) current = current.$value;
|
|
2780
|
+
for (const segment of segments) {
|
|
2781
|
+
if (!/* @__PURE__ */ isObject(current) || !(segment in current)) {
|
|
2782
|
+
current = void 0;
|
|
2783
|
+
break;
|
|
2784
|
+
}
|
|
2785
|
+
current = current[segment];
|
|
2786
|
+
if (isTokenAlias(current)) current = current.$value;
|
|
2787
|
+
}
|
|
2788
|
+
if (/* @__PURE__ */ isUndefined(current)) {
|
|
2789
|
+
logger.warn(`Path not found inside "${clean}": ${segments.join(".")}`);
|
|
2790
|
+
cache.set(cacheKey, void 0);
|
|
2791
|
+
return;
|
|
2792
|
+
}
|
|
2793
|
+
result = current;
|
|
2794
|
+
} else if (isTokenAlias(current)) {
|
|
2795
|
+
const inner = current.$value;
|
|
2796
|
+
if (/* @__PURE__ */ isString(inner) && isAlias(inner)) return resolve(inner, visited);
|
|
2797
|
+
result = inner;
|
|
2798
|
+
} else if (/* @__PURE__ */ isString(current) && isAlias(current)) return resolve(current, visited);
|
|
2799
|
+
else result = current;
|
|
2800
|
+
cache.set(cacheKey, result);
|
|
2801
|
+
return result;
|
|
2802
|
+
}
|
|
2803
|
+
return {
|
|
2804
|
+
...registry,
|
|
2805
|
+
resolve,
|
|
2806
|
+
isAlias,
|
|
2807
|
+
get size() {
|
|
2808
|
+
return registry.size;
|
|
2809
|
+
}
|
|
2810
|
+
};
|
|
2811
|
+
}
|
|
2812
|
+
/**
|
|
2813
|
+
* Creates a new token context.
|
|
2667
2814
|
*
|
|
2668
|
-
* @
|
|
2815
|
+
* @param namespace The namespace for the token context.
|
|
2816
|
+
* @param tokens The tokens to use.
|
|
2817
|
+
* @template Z The type of the token ticket.
|
|
2818
|
+
* @template E The type of the token context.
|
|
2819
|
+
* @returns A new token context.
|
|
2820
|
+
*
|
|
2821
|
+
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
2669
2822
|
*
|
|
2670
2823
|
* @example
|
|
2671
2824
|
* ```ts
|
|
2672
|
-
* import {
|
|
2673
|
-
* import { useElementSize } from '@vuetify/v0'
|
|
2674
|
-
*
|
|
2675
|
-
* const box = ref<HTMLElement>()
|
|
2676
|
-
* const { width, height } = useElementSize(box)
|
|
2825
|
+
* import { createTokensContext } from '@vuetify/v0'
|
|
2677
2826
|
*
|
|
2678
|
-
*
|
|
2679
|
-
*
|
|
2680
|
-
*
|
|
2827
|
+
* export const [useTokens, provideTokens, context] = createTokensContext({
|
|
2828
|
+
* namespace: 'v0:tokens',
|
|
2829
|
+
* tokens: {
|
|
2830
|
+
* colors: {
|
|
2831
|
+
* primary: '#3b82f6',
|
|
2832
|
+
* secondary: '{colors.primary}', // Alias reference
|
|
2833
|
+
* },
|
|
2834
|
+
* },
|
|
2681
2835
|
* })
|
|
2682
2836
|
* ```
|
|
2683
2837
|
*/
|
|
2684
|
-
function
|
|
2685
|
-
const
|
|
2686
|
-
const
|
|
2687
|
-
const
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
width.value = entry.contentRect.width;
|
|
2691
|
-
height.value = entry.contentRect.height;
|
|
2692
|
-
}
|
|
2693
|
-
}, { immediate: true });
|
|
2694
|
-
function pause() {
|
|
2695
|
-
width.value = 0;
|
|
2696
|
-
height.value = 0;
|
|
2697
|
-
_pause();
|
|
2838
|
+
function createTokensContext(_options) {
|
|
2839
|
+
const { namespace = "v0:tokens", tokens = {}, ...options } = _options;
|
|
2840
|
+
const [useTokensContext, _provideTokensContext] = createContext(namespace);
|
|
2841
|
+
const context = createTokens(tokens, options);
|
|
2842
|
+
function provideTokensContext(_context = context, app) {
|
|
2843
|
+
return _provideTokensContext(_context, app);
|
|
2698
2844
|
}
|
|
2699
|
-
return
|
|
2700
|
-
width,
|
|
2701
|
-
height,
|
|
2702
|
-
isActive,
|
|
2703
|
-
isPaused,
|
|
2704
|
-
pause,
|
|
2705
|
-
resume,
|
|
2706
|
-
stop
|
|
2707
|
-
};
|
|
2845
|
+
return createTrinity(useTokensContext, provideTokensContext, context);
|
|
2708
2846
|
}
|
|
2709
|
-
|
|
2710
|
-
//#endregion
|
|
2711
|
-
//#region src/composables/useOverflow/index.ts
|
|
2712
2847
|
/**
|
|
2713
|
-
*
|
|
2714
|
-
*
|
|
2715
|
-
* @remarks
|
|
2716
|
-
* Composable for computing how many items fit in a container based on available width.
|
|
2717
|
-
* Enables responsive truncation logic for Pagination, Breadcrumbs, and similar components.
|
|
2848
|
+
* Returns the current tokens instance.
|
|
2718
2849
|
*
|
|
2719
|
-
*
|
|
2720
|
-
*
|
|
2721
|
-
* - Two modes: variable-width (per-item) or uniform-width (sample-based)
|
|
2722
|
-
* - Computes capacity (how many items fit)
|
|
2723
|
-
* - SSR-safe with Infinity fallback
|
|
2724
|
-
* - Supports reserved space for nav buttons, ellipsis, etc.
|
|
2725
|
-
*
|
|
2726
|
-
* Use variable mode (default) for items with different widths like Breadcrumbs.
|
|
2727
|
-
* Use uniform mode (itemWidth option) for same-width items like Pagination buttons.
|
|
2728
|
-
*/
|
|
2729
|
-
/**
|
|
2730
|
-
* Creates a new overflow context for computing how many items fit in a container.
|
|
2850
|
+
* @param namespace The namespace for the tokens context. Defaults to `'v0:tokens'`.
|
|
2851
|
+
* @returns The current tokens instance.
|
|
2731
2852
|
*
|
|
2732
|
-
* @
|
|
2733
|
-
* @returns Overflow context with container ref, capacity, and measurement functions
|
|
2853
|
+
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
2734
2854
|
*
|
|
2735
|
-
* @example
|
|
2855
|
+
* @example
|
|
2736
2856
|
* ```vue
|
|
2737
|
-
* <script lang="ts"
|
|
2738
|
-
* import {
|
|
2739
|
-
* import { createOverflow } from '@vuetify/v0'
|
|
2857
|
+
* <script setup lang="ts">
|
|
2858
|
+
* import { useTokens } from '@vuetify/v0'
|
|
2740
2859
|
*
|
|
2741
|
-
* const
|
|
2742
|
-
* const overflow = createOverflow({
|
|
2743
|
-
* container: containerRef,
|
|
2744
|
-
* gap: 8,
|
|
2745
|
-
* reserved: 40,
|
|
2746
|
-
* })
|
|
2860
|
+
* const tokens = useTokens()
|
|
2747
2861
|
* <\/script>
|
|
2748
|
-
*
|
|
2749
|
-
* <template>
|
|
2750
|
-
* <div ref="container">
|
|
2751
|
-
* <span
|
|
2752
|
-
* v-for="(item, i) in items.slice(0, overflow.capacity.value)"
|
|
2753
|
-
* :key="i"
|
|
2754
|
-
* :ref="el => overflow.measure(i, el)"
|
|
2755
|
-
* >
|
|
2756
|
-
* {{ item }}
|
|
2757
|
-
* </span>
|
|
2758
|
-
* <span v-if="overflow.isOverflowing.value">...</span>
|
|
2759
|
-
* </div>
|
|
2760
|
-
* </template>
|
|
2761
|
-
* ```
|
|
2762
|
-
*
|
|
2763
|
-
* @example Uniform-width mode (Pagination)
|
|
2764
|
-
* ```ts
|
|
2765
|
-
* const overflow = createOverflow({
|
|
2766
|
-
* container: () => atom.value?.element,
|
|
2767
|
-
* itemWidth: buttonWidth,
|
|
2768
|
-
* reserved: () => buttonWidth.value * 4,
|
|
2769
|
-
* })
|
|
2770
2862
|
* ```
|
|
2771
2863
|
*/
|
|
2772
|
-
function
|
|
2773
|
-
|
|
2774
|
-
const container = /* @__PURE__ */ isUndefined(_container) ? shallowRef() : toRef(_container);
|
|
2775
|
-
const widths = shallowRef(/* @__PURE__ */ new Map());
|
|
2776
|
-
const { width } = useElementSize(container);
|
|
2777
|
-
function measure(index, el) {
|
|
2778
|
-
if (!el) {
|
|
2779
|
-
if (widths.value.has(index)) {
|
|
2780
|
-
const next = new Map(widths.value);
|
|
2781
|
-
next.delete(index);
|
|
2782
|
-
widths.value = next;
|
|
2783
|
-
}
|
|
2784
|
-
return;
|
|
2785
|
-
}
|
|
2786
|
-
const style = getComputedStyle(el);
|
|
2787
|
-
const marginX = Number.parseFloat(style.marginLeft) + Number.parseFloat(style.marginRight);
|
|
2788
|
-
const w = el.offsetWidth + marginX;
|
|
2789
|
-
if (widths.value.get(index) !== w) widths.value = new Map(widths.value).set(index, w);
|
|
2790
|
-
}
|
|
2791
|
-
function reset() {
|
|
2792
|
-
widths.value = /* @__PURE__ */ new Map();
|
|
2793
|
-
}
|
|
2794
|
-
const total = computed(() => {
|
|
2795
|
-
const g = toValue(gap);
|
|
2796
|
-
let sum = 0;
|
|
2797
|
-
let count = 0;
|
|
2798
|
-
for (const w of widths.value.values()) {
|
|
2799
|
-
sum += w + (count > 0 ? g : 0);
|
|
2800
|
-
count++;
|
|
2801
|
-
}
|
|
2802
|
-
return sum;
|
|
2803
|
-
});
|
|
2804
|
-
return {
|
|
2805
|
-
container,
|
|
2806
|
-
width,
|
|
2807
|
-
capacity: computed(() => {
|
|
2808
|
-
const available = width.value - toValue(reserved);
|
|
2809
|
-
if (width.value === 0) return Infinity;
|
|
2810
|
-
if (available <= 0) return 0;
|
|
2811
|
-
const g = toValue(gap);
|
|
2812
|
-
const uniformWidth = toValue(itemWidth);
|
|
2813
|
-
if (uniformWidth && uniformWidth > 0) {
|
|
2814
|
-
const first = uniformWidth;
|
|
2815
|
-
const subsequent = uniformWidth + g;
|
|
2816
|
-
if (available < first) return 0;
|
|
2817
|
-
return Math.max(1, Math.floor((available - first) / subsequent) + 1);
|
|
2818
|
-
}
|
|
2819
|
-
const entries = [...widths.value.entries()].toSorted((a, b) => a[0] - b[0]);
|
|
2820
|
-
if (toValue(reverse)) entries.reverse();
|
|
2821
|
-
let sum = 0;
|
|
2822
|
-
let count = 0;
|
|
2823
|
-
for (const [, w] of entries) {
|
|
2824
|
-
const next = sum + w + (count > 0 ? g : 0);
|
|
2825
|
-
if (next > available) break;
|
|
2826
|
-
sum = next;
|
|
2827
|
-
count++;
|
|
2828
|
-
}
|
|
2829
|
-
return count;
|
|
2830
|
-
}),
|
|
2831
|
-
total,
|
|
2832
|
-
isOverflowing: toRef(() => {
|
|
2833
|
-
return total.value > width.value - toValue(reserved);
|
|
2834
|
-
}),
|
|
2835
|
-
measure,
|
|
2836
|
-
reset
|
|
2837
|
-
};
|
|
2864
|
+
function useTokens(namespace = "v0:tokens") {
|
|
2865
|
+
return useContext(namespace);
|
|
2838
2866
|
}
|
|
2839
2867
|
/**
|
|
2840
|
-
*
|
|
2841
|
-
*
|
|
2842
|
-
* @param
|
|
2843
|
-
* @
|
|
2844
|
-
*
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2868
|
+
* Flattens a nested collection of tokens into a flat array of tokens.
|
|
2869
|
+
* Each token is represented by an object containing its ID & value.
|
|
2870
|
+
* @param tokens The collection of tokens to flatten.
|
|
2871
|
+
* @param prefix An optional prefix to prepend to each token ID.
|
|
2872
|
+
* @returns An array of flattened tokens, each with an ID and value.
|
|
2873
|
+
*/
|
|
2874
|
+
function flatten(tokens, prefix = "", flat = false) {
|
|
2875
|
+
const flattened = [];
|
|
2876
|
+
const stack = [{
|
|
2877
|
+
tokens,
|
|
2878
|
+
prefix,
|
|
2879
|
+
flat
|
|
2880
|
+
}];
|
|
2881
|
+
while (stack.length > 0) {
|
|
2882
|
+
const { tokens: currentTokens, prefix: currentPrefix, flat: flat$1 } = stack.pop();
|
|
2883
|
+
const meta = {};
|
|
2884
|
+
for (const k in currentTokens) if (k.startsWith("$")) meta[k] = currentTokens[k];
|
|
2885
|
+
if (Object.keys(meta).length > 0 && currentPrefix) flattened.push({
|
|
2886
|
+
id: currentPrefix,
|
|
2887
|
+
value: meta
|
|
2888
|
+
});
|
|
2889
|
+
for (const key in currentTokens) {
|
|
2890
|
+
if (key.startsWith("$")) continue;
|
|
2891
|
+
const value = currentTokens[key];
|
|
2892
|
+
const id = currentPrefix ? `${currentPrefix}.${key}` : key;
|
|
2893
|
+
if (!/* @__PURE__ */ isObject(value)) {
|
|
2894
|
+
flattened.push({
|
|
2895
|
+
id,
|
|
2896
|
+
value
|
|
2897
|
+
});
|
|
2898
|
+
continue;
|
|
2899
|
+
}
|
|
2900
|
+
if ("$value" in value) {
|
|
2901
|
+
flattened.push({
|
|
2902
|
+
id,
|
|
2903
|
+
value
|
|
2904
|
+
});
|
|
2905
|
+
const inner = value.$value;
|
|
2906
|
+
if (/* @__PURE__ */ isObject(inner) && !flat$1) for (const innerKey in inner) {
|
|
2907
|
+
if (innerKey.startsWith("$")) continue;
|
|
2908
|
+
const child = inner[innerKey];
|
|
2909
|
+
const childId = `${id}.${innerKey}`;
|
|
2910
|
+
if (!/* @__PURE__ */ isObject(child)) flattened.push({
|
|
2911
|
+
id: childId,
|
|
2912
|
+
value: child
|
|
2913
|
+
});
|
|
2914
|
+
else if ("$value" in child) flattened.push({
|
|
2915
|
+
id: childId,
|
|
2916
|
+
value: child
|
|
2917
|
+
});
|
|
2918
|
+
else stack.push({
|
|
2919
|
+
tokens: child,
|
|
2920
|
+
prefix: childId,
|
|
2921
|
+
flat: flat$1
|
|
2922
|
+
});
|
|
2923
|
+
}
|
|
2924
|
+
continue;
|
|
2925
|
+
}
|
|
2926
|
+
if (flat$1) {
|
|
2927
|
+
flattened.push({
|
|
2928
|
+
id,
|
|
2929
|
+
value
|
|
2930
|
+
});
|
|
2931
|
+
continue;
|
|
2932
|
+
}
|
|
2933
|
+
stack.push({
|
|
2934
|
+
tokens: value,
|
|
2935
|
+
prefix: id,
|
|
2936
|
+
flat: flat$1
|
|
2937
|
+
});
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
return flattened;
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
//#endregion
|
|
2944
|
+
//#region src/composables/useLocale/index.ts
|
|
2945
|
+
/**
|
|
2946
|
+
* Creates a new locale instance.
|
|
2853
2947
|
*
|
|
2854
|
-
*
|
|
2855
|
-
*
|
|
2948
|
+
* @param options The options for the locale instance.
|
|
2949
|
+
* @template Z The type of the locale ticket.
|
|
2950
|
+
* @template E The type of the locale context.
|
|
2951
|
+
* @returns A new locale instance.
|
|
2856
2952
|
*
|
|
2857
|
-
*
|
|
2858
|
-
* const overflow = useOverflow()
|
|
2859
|
-
* ```
|
|
2953
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-locale
|
|
2860
2954
|
*/
|
|
2861
|
-
function
|
|
2862
|
-
const {
|
|
2863
|
-
const
|
|
2864
|
-
const
|
|
2865
|
-
|
|
2866
|
-
|
|
2955
|
+
function createLocale(_options = {}) {
|
|
2956
|
+
const { adapter = new Vuetify0LocaleAdapter(), messages = {}, ...options } = _options;
|
|
2957
|
+
const tokens = createTokens(messages);
|
|
2958
|
+
const registry = createSingle(options);
|
|
2959
|
+
for (const id in messages) {
|
|
2960
|
+
registry.register({ id });
|
|
2961
|
+
if (id === options.default && !registry.selectedId.value) registry.select(id);
|
|
2867
2962
|
}
|
|
2868
|
-
|
|
2963
|
+
function t(key, params, fallback) {
|
|
2964
|
+
const locale = registry.selectedId.value;
|
|
2965
|
+
const args = toArray(params);
|
|
2966
|
+
if (!locale) return adapter.t(fallback ?? key, ...args);
|
|
2967
|
+
const path = `${locale}.${key}`;
|
|
2968
|
+
const message = tokens.get(path)?.value;
|
|
2969
|
+
const template = /* @__PURE__ */ isString(message) ? resolve(locale, message) : fallback ?? key;
|
|
2970
|
+
return adapter.t(template, ...args);
|
|
2971
|
+
}
|
|
2972
|
+
function n(value, ...params) {
|
|
2973
|
+
return adapter.n(value, registry.selectedId.value, ...params);
|
|
2974
|
+
}
|
|
2975
|
+
function resolve(locale, str) {
|
|
2976
|
+
return str.replace(/{([a-zA-Z0-9.-_]+)}/g, (match, key) => {
|
|
2977
|
+
const [prefix, ...rest] = key.split(".");
|
|
2978
|
+
const target = registry.has(prefix) ? prefix : locale;
|
|
2979
|
+
const path = `${target}.${registry.has(prefix) ? rest.join(".") : key}`;
|
|
2980
|
+
const resolved = tokens.get(path)?.value;
|
|
2981
|
+
if (/* @__PURE__ */ isString(resolved)) return resolve(target, resolved);
|
|
2982
|
+
return match;
|
|
2983
|
+
});
|
|
2984
|
+
}
|
|
2985
|
+
return {
|
|
2986
|
+
...registry,
|
|
2987
|
+
t,
|
|
2988
|
+
n,
|
|
2989
|
+
get size() {
|
|
2990
|
+
return registry.size;
|
|
2991
|
+
}
|
|
2992
|
+
};
|
|
2993
|
+
}
|
|
2994
|
+
function createLocaleFallback() {
|
|
2995
|
+
return {
|
|
2996
|
+
size: 0,
|
|
2997
|
+
t: (key, _params, fallback) => fallback ?? key,
|
|
2998
|
+
n: String
|
|
2999
|
+
};
|
|
2869
3000
|
}
|
|
2870
3001
|
/**
|
|
2871
|
-
*
|
|
3002
|
+
* Creates a new locale context.
|
|
2872
3003
|
*
|
|
2873
|
-
* @param
|
|
2874
|
-
* @
|
|
3004
|
+
* @param options The options for the locale context.
|
|
3005
|
+
* @template Z The type of the locale ticket.
|
|
3006
|
+
* @template E The type of the locale context.
|
|
3007
|
+
* @returns A new locale context.
|
|
3008
|
+
*
|
|
3009
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-locale
|
|
2875
3010
|
*
|
|
2876
3011
|
* @example
|
|
2877
|
-
* ```
|
|
2878
|
-
*
|
|
2879
|
-
* import { useOverflow } from '@vuetify/v0'
|
|
3012
|
+
* ```ts
|
|
3013
|
+
* import { createLocaleContext } from '@vuetify/v0'
|
|
2880
3014
|
*
|
|
2881
|
-
*
|
|
2882
|
-
*
|
|
2883
|
-
*
|
|
3015
|
+
* export const [useAppLocale, provideAppLocale, appLocale] = createLocaleContext({
|
|
3016
|
+
* namespace: 'app:locale',
|
|
3017
|
+
* messages: {
|
|
3018
|
+
* en: { hello: 'Hello' },
|
|
3019
|
+
* es: { hello: 'Hola' },
|
|
3020
|
+
* },
|
|
3021
|
+
* })
|
|
2884
3022
|
*
|
|
2885
|
-
*
|
|
2886
|
-
*
|
|
2887
|
-
*
|
|
2888
|
-
*
|
|
2889
|
-
*
|
|
3023
|
+
* // In a parent component:
|
|
3024
|
+
* provideAppLocale()
|
|
3025
|
+
*
|
|
3026
|
+
* // In a child component:
|
|
3027
|
+
* const locale = useAppLocale()
|
|
3028
|
+
* locale.select('es')
|
|
2890
3029
|
* ```
|
|
2891
3030
|
*/
|
|
2892
|
-
function
|
|
2893
|
-
|
|
3031
|
+
function createLocaleContext(_options = {}) {
|
|
3032
|
+
const { namespace = "v0:locale", ...options } = _options;
|
|
3033
|
+
const [useLocaleContext, _provideLocaleContext] = createContext(namespace);
|
|
3034
|
+
const context = createLocale(options);
|
|
3035
|
+
function provideLocaleContext(_context = context, app) {
|
|
3036
|
+
return _provideLocaleContext(_context, app);
|
|
3037
|
+
}
|
|
3038
|
+
return createTrinity(useLocaleContext, provideLocaleContext, context);
|
|
3039
|
+
}
|
|
3040
|
+
/**
|
|
3041
|
+
* Creates a new locale plugin.
|
|
3042
|
+
*
|
|
3043
|
+
* @param options The options for the locale plugin.
|
|
3044
|
+
* @template Z The type of the locale ticket.
|
|
3045
|
+
* @template E The type of the locale context.
|
|
3046
|
+
* @template R The type of the token ticket.
|
|
3047
|
+
* @template O The type of the token context.
|
|
3048
|
+
* @returns A new locale plugin.
|
|
3049
|
+
*
|
|
3050
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-locale
|
|
3051
|
+
*/
|
|
3052
|
+
function createLocalePlugin(_options = {}) {
|
|
3053
|
+
const { namespace = "v0:locale", adapter = new Vuetify0LocaleAdapter(), messages = {}, ...options } = _options;
|
|
3054
|
+
const [, provideLocaleContext, context] = createLocaleContext({
|
|
3055
|
+
...options,
|
|
3056
|
+
namespace,
|
|
3057
|
+
adapter,
|
|
3058
|
+
messages
|
|
3059
|
+
});
|
|
3060
|
+
return createPlugin({
|
|
3061
|
+
namespace,
|
|
3062
|
+
provide: (app) => {
|
|
3063
|
+
provideLocaleContext(context, app);
|
|
3064
|
+
}
|
|
3065
|
+
});
|
|
2894
3066
|
}
|
|
2895
|
-
|
|
2896
|
-
//#endregion
|
|
2897
|
-
//#region src/composables/usePagination/index.ts
|
|
2898
3067
|
/**
|
|
2899
|
-
*
|
|
3068
|
+
* Returns the current locale instance.
|
|
2900
3069
|
*
|
|
2901
|
-
* @
|
|
2902
|
-
* Lightweight pagination composable for navigating through pages.
|
|
3070
|
+
* @returns The current locale instance.
|
|
2903
3071
|
*
|
|
2904
|
-
*
|
|
2905
|
-
* - No registry overhead - just a bounded integer
|
|
2906
|
-
* - Direct ref support for v-model compatibility
|
|
2907
|
-
* - Navigation methods: next, prev, first, last
|
|
2908
|
-
* - Computed visible items with ellipsis
|
|
2909
|
-
* - Trinity pattern for dependency injection
|
|
2910
|
-
*
|
|
2911
|
-
* Unlike registry-based composables, pagination tracks a single number
|
|
2912
|
-
* within a range, making it efficient for large page counts.
|
|
3072
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-locale
|
|
2913
3073
|
*/
|
|
3074
|
+
function useLocale(namespace = "v0:locale") {
|
|
3075
|
+
const fallback = createLocaleFallback();
|
|
3076
|
+
if (!getCurrentInstance()) return fallback;
|
|
3077
|
+
try {
|
|
3078
|
+
return useContext(namespace, fallback);
|
|
3079
|
+
} catch {
|
|
3080
|
+
return fallback;
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
|
|
3084
|
+
//#endregion
|
|
3085
|
+
//#region src/composables/useHydration/index.ts
|
|
2914
3086
|
/**
|
|
2915
|
-
* Creates a
|
|
3087
|
+
* Creates a new hydration instance.
|
|
2916
3088
|
*
|
|
2917
|
-
* @
|
|
2918
|
-
*
|
|
3089
|
+
* @returns A new hydration instance.
|
|
3090
|
+
*
|
|
3091
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-hydration
|
|
2919
3092
|
*
|
|
2920
3093
|
* @example
|
|
2921
3094
|
* ```ts
|
|
2922
|
-
* import {
|
|
2923
|
-
*
|
|
2924
|
-
* // Basic usage
|
|
2925
|
-
* const pagination = createPagination({ size: 100 })
|
|
2926
|
-
* pagination.next()
|
|
2927
|
-
* pagination.items.value // [{ type: 'page', value: 1 }, { type: 'page', value: 2 }, ...]
|
|
3095
|
+
* import { createHydration } from '@vuetify/v0'
|
|
2928
3096
|
*
|
|
2929
|
-
*
|
|
2930
|
-
*
|
|
2931
|
-
*
|
|
2932
|
-
*
|
|
2933
|
-
* ```
|
|
2934
|
-
*/
|
|
2935
|
-
function
|
|
2936
|
-
const
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
const size = toValue(_size);
|
|
2940
|
-
const perPage = toValue(_itemsPerPage);
|
|
2941
|
-
if (size <= 0 || /* @__PURE__ */ isNaN(size)) return 0;
|
|
2942
|
-
return Math.ceil(size / perPage);
|
|
2943
|
-
});
|
|
2944
|
-
function first() {
|
|
2945
|
-
page.value = 1;
|
|
2946
|
-
}
|
|
2947
|
-
function last() {
|
|
2948
|
-
page.value = Math.max(1, pages.value);
|
|
2949
|
-
}
|
|
2950
|
-
function next() {
|
|
2951
|
-
if (page.value < pages.value) page.value++;
|
|
2952
|
-
}
|
|
2953
|
-
function prev() {
|
|
2954
|
-
if (page.value > 1) page.value--;
|
|
2955
|
-
}
|
|
2956
|
-
function select(value) {
|
|
2957
|
-
if (value < 1) page.value = 1;
|
|
2958
|
-
else if (value > pages.value) page.value = Math.max(1, pages.value);
|
|
2959
|
-
else page.value = value;
|
|
2960
|
-
}
|
|
2961
|
-
const isFirst = computed(() => page.value <= 1);
|
|
2962
|
-
const isLast = computed(() => page.value >= pages.value);
|
|
2963
|
-
const pageStart = computed(() => (page.value - 1) * toValue(_itemsPerPage));
|
|
2964
|
-
const pageStop = computed(() => Math.min(pageStart.value + toValue(_itemsPerPage), toValue(_size)));
|
|
2965
|
-
function toPage(value) {
|
|
2966
|
-
return {
|
|
2967
|
-
type: "page",
|
|
2968
|
-
value
|
|
2969
|
-
};
|
|
2970
|
-
}
|
|
2971
|
-
function toEllipsis() {
|
|
2972
|
-
return ellipsis === false ? false : {
|
|
2973
|
-
type: "ellipsis",
|
|
2974
|
-
value: ellipsis
|
|
2975
|
-
};
|
|
2976
|
-
}
|
|
2977
|
-
function filter(array) {
|
|
2978
|
-
return array.filter((item) => item !== false);
|
|
3097
|
+
* const hydration = createHydration()
|
|
3098
|
+
* console.log(hydration.isHydrated.value) // false
|
|
3099
|
+
* hydration.hydrate()
|
|
3100
|
+
* console.log(hydration.isHydrated.value) // true
|
|
3101
|
+
* ```
|
|
3102
|
+
*/
|
|
3103
|
+
function createHydration() {
|
|
3104
|
+
const isHydrated = shallowRef(false);
|
|
3105
|
+
function hydrate() {
|
|
3106
|
+
isHydrated.value = true;
|
|
2979
3107
|
}
|
|
2980
3108
|
return {
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
if (visible <= 2) return [toPage(current)];
|
|
2990
|
-
if (pageCount <= visible) return (/* @__PURE__ */ range(pageCount, 1)).map(toPage);
|
|
2991
|
-
if (visible === 3) {
|
|
2992
|
-
const mid = current <= 1 ? 2 : current >= pageCount ? pageCount - 1 : current;
|
|
2993
|
-
return [
|
|
2994
|
-
toPage(1),
|
|
2995
|
-
toPage(mid),
|
|
2996
|
-
toPage(pageCount)
|
|
2997
|
-
];
|
|
2998
|
-
}
|
|
2999
|
-
const boundary = visible - 2;
|
|
3000
|
-
const middle = visible - 4;
|
|
3001
|
-
if (middle <= 0) {
|
|
3002
|
-
if (current <= boundary) return filter([
|
|
3003
|
-
...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
|
|
3004
|
-
toEllipsis(),
|
|
3005
|
-
toPage(pageCount)
|
|
3006
|
-
]);
|
|
3007
|
-
if (current > pageCount - boundary) return filter([
|
|
3008
|
-
toPage(1),
|
|
3009
|
-
toEllipsis(),
|
|
3010
|
-
...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
|
|
3011
|
-
]);
|
|
3012
|
-
return current <= Math.ceil(pageCount / 2) ? filter([
|
|
3013
|
-
toPage(1),
|
|
3014
|
-
toPage(current),
|
|
3015
|
-
toEllipsis(),
|
|
3016
|
-
toPage(pageCount)
|
|
3017
|
-
]) : filter([
|
|
3018
|
-
toPage(1),
|
|
3019
|
-
toEllipsis(),
|
|
3020
|
-
toPage(current),
|
|
3021
|
-
toPage(pageCount)
|
|
3022
|
-
]);
|
|
3023
|
-
}
|
|
3024
|
-
const leftThreshold = boundary - 1;
|
|
3025
|
-
const rightThreshold = pageCount - boundary + 2;
|
|
3026
|
-
if (current <= leftThreshold) return filter([
|
|
3027
|
-
...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
|
|
3028
|
-
toEllipsis(),
|
|
3029
|
-
toPage(pageCount)
|
|
3030
|
-
]);
|
|
3031
|
-
else if (current >= rightThreshold) return filter([
|
|
3032
|
-
toPage(1),
|
|
3033
|
-
toEllipsis(),
|
|
3034
|
-
...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
|
|
3035
|
-
]);
|
|
3036
|
-
else {
|
|
3037
|
-
const start = current - Math.floor(middle / 2);
|
|
3038
|
-
return filter([
|
|
3039
|
-
toPage(1),
|
|
3040
|
-
toEllipsis(),
|
|
3041
|
-
...(/* @__PURE__ */ range(middle, start)).map(toPage),
|
|
3042
|
-
toEllipsis(),
|
|
3043
|
-
toPage(pageCount)
|
|
3044
|
-
]);
|
|
3045
|
-
}
|
|
3046
|
-
}),
|
|
3047
|
-
pageStart,
|
|
3048
|
-
pageStop,
|
|
3049
|
-
isFirst,
|
|
3050
|
-
isLast,
|
|
3051
|
-
first,
|
|
3052
|
-
last,
|
|
3053
|
-
next,
|
|
3054
|
-
prev,
|
|
3055
|
-
select,
|
|
3056
|
-
get itemsPerPage() {
|
|
3057
|
-
return toValue(_itemsPerPage);
|
|
3058
|
-
},
|
|
3059
|
-
get size() {
|
|
3060
|
-
return toValue(_size);
|
|
3061
|
-
},
|
|
3062
|
-
get pages() {
|
|
3063
|
-
return pages.value;
|
|
3064
|
-
}
|
|
3109
|
+
isHydrated: shallowReadonly(isHydrated),
|
|
3110
|
+
hydrate
|
|
3111
|
+
};
|
|
3112
|
+
}
|
|
3113
|
+
function createFallbackHydration() {
|
|
3114
|
+
return {
|
|
3115
|
+
isHydrated: shallowReadonly(shallowRef(true)),
|
|
3116
|
+
hydrate: () => {}
|
|
3065
3117
|
};
|
|
3066
3118
|
}
|
|
3067
3119
|
/**
|
|
3068
|
-
* Creates a
|
|
3120
|
+
* Creates a new hydration context trinity.
|
|
3069
3121
|
*
|
|
3070
|
-
* @param options
|
|
3071
|
-
* @
|
|
3122
|
+
* @param options Options for creating the hydration context.
|
|
3123
|
+
* @template E The type of the hydration context.
|
|
3124
|
+
* @returns A new hydration context trinity.
|
|
3125
|
+
*
|
|
3126
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-hydration
|
|
3072
3127
|
*
|
|
3073
3128
|
* @example
|
|
3074
3129
|
* ```ts
|
|
3075
|
-
*
|
|
3076
|
-
* const [usePagination, providePaginationContext] = createPaginationContext({ size: 50 })
|
|
3130
|
+
* import { createHydrationContext } from '@vuetify/v0'
|
|
3077
3131
|
*
|
|
3078
|
-
*
|
|
3079
|
-
*
|
|
3080
|
-
* namespace: 'my-pagination',
|
|
3081
|
-
* size: 50,
|
|
3132
|
+
* export const [useHydrationContext, provideHydrationContext, context] = createHydrationContext({
|
|
3133
|
+
* namespace: 'app:hydration',
|
|
3082
3134
|
* })
|
|
3135
|
+
* ```
|
|
3136
|
+
*/
|
|
3137
|
+
function createHydrationContext(_options = {}) {
|
|
3138
|
+
const { namespace = "v0:hydration" } = _options;
|
|
3139
|
+
const [useHydrationContext, _provideHydrationContext] = createContext(namespace);
|
|
3140
|
+
const context = createHydration();
|
|
3141
|
+
function provideHydrationContext(_context = context, app) {
|
|
3142
|
+
return _provideHydrationContext(_context, app);
|
|
3143
|
+
}
|
|
3144
|
+
return createTrinity(useHydrationContext, provideHydrationContext, context);
|
|
3145
|
+
}
|
|
3146
|
+
/**
|
|
3147
|
+
* Creates a new hydration plugin.
|
|
3083
3148
|
*
|
|
3084
|
-
*
|
|
3085
|
-
*
|
|
3149
|
+
* @param options The options for the hydration plugin.
|
|
3150
|
+
* @template E The type of the hydration context.
|
|
3151
|
+
* @returns A new hydration plugin.
|
|
3086
3152
|
*
|
|
3087
|
-
*
|
|
3088
|
-
*
|
|
3089
|
-
*
|
|
3153
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-hydration
|
|
3154
|
+
*
|
|
3155
|
+
* @example
|
|
3156
|
+
* ```ts
|
|
3157
|
+
* import { createApp } from 'vue'
|
|
3158
|
+
* import { createHydrationPlugin } from '@vuetify/v0'
|
|
3159
|
+
* import App from './App.vue'
|
|
3160
|
+
*
|
|
3161
|
+
* const app = createApp(App)
|
|
3162
|
+
*
|
|
3163
|
+
* app.use(createHydrationPlugin())
|
|
3164
|
+
*
|
|
3165
|
+
* app.mount('#app')
|
|
3090
3166
|
* ```
|
|
3091
3167
|
*/
|
|
3092
|
-
function
|
|
3093
|
-
const { namespace = "v0:
|
|
3094
|
-
const [
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3168
|
+
function createHydrationPlugin(_options = {}) {
|
|
3169
|
+
const { namespace = "v0:hydration", ...options } = _options;
|
|
3170
|
+
const [, provideHydrationContext, context] = createHydrationContext({
|
|
3171
|
+
...options,
|
|
3172
|
+
namespace
|
|
3173
|
+
});
|
|
3174
|
+
return createPlugin({
|
|
3175
|
+
namespace,
|
|
3176
|
+
provide: (app) => {
|
|
3177
|
+
provideHydrationContext(context, app);
|
|
3178
|
+
},
|
|
3179
|
+
setup: (app) => {
|
|
3180
|
+
app.mixin({ mounted() {
|
|
3181
|
+
if (this.$parent !== null) return;
|
|
3182
|
+
context.hydrate();
|
|
3183
|
+
} });
|
|
3184
|
+
}
|
|
3185
|
+
});
|
|
3100
3186
|
}
|
|
3101
3187
|
/**
|
|
3102
|
-
* Returns the current
|
|
3188
|
+
* Returns the current hydration instance.
|
|
3103
3189
|
*
|
|
3104
|
-
* @param namespace The namespace.
|
|
3105
|
-
* @returns The
|
|
3190
|
+
* @param namespace The namespace for the hydration context. Defaults to `v0:hydration`.
|
|
3191
|
+
* @returns The current hydration instance.
|
|
3192
|
+
*
|
|
3193
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-hydration
|
|
3106
3194
|
*
|
|
3107
3195
|
* @example
|
|
3108
3196
|
* ```vue
|
|
3109
|
-
* <script setup>
|
|
3110
|
-
*
|
|
3197
|
+
* <script setup lang="ts">
|
|
3198
|
+
* import { useHydration } from '@vuetify/v0'
|
|
3111
3199
|
*
|
|
3112
|
-
*
|
|
3200
|
+
* const hydration = useHydration()
|
|
3113
3201
|
* <\/script>
|
|
3114
3202
|
*
|
|
3115
3203
|
* <template>
|
|
3116
|
-
* <
|
|
3117
|
-
*
|
|
3204
|
+
* <div>
|
|
3205
|
+
* <p>Is hydrated: {{ hydration.isHydrated.value }}</p>
|
|
3206
|
+
* </div>
|
|
3118
3207
|
* </template>
|
|
3119
3208
|
* ```
|
|
3120
3209
|
*/
|
|
3121
|
-
function
|
|
3122
|
-
|
|
3210
|
+
function useHydration(namespace = "v0:hydration") {
|
|
3211
|
+
const fallback = createFallbackHydration();
|
|
3212
|
+
if (!getCurrentInstance()) return fallback;
|
|
3213
|
+
try {
|
|
3214
|
+
return useContext(namespace, fallback);
|
|
3215
|
+
} catch {
|
|
3216
|
+
return fallback;
|
|
3217
|
+
}
|
|
3123
3218
|
}
|
|
3124
3219
|
|
|
3125
3220
|
//#endregion
|
|
3126
|
-
//#region src/composables/
|
|
3221
|
+
//#region src/composables/useResizeObserver/index.ts
|
|
3127
3222
|
/**
|
|
3128
|
-
*
|
|
3223
|
+
* A composable that uses the Resize Observer API to detect when an element's
|
|
3224
|
+
* size changes.
|
|
3129
3225
|
*
|
|
3130
|
-
* @
|
|
3131
|
-
*
|
|
3132
|
-
*
|
|
3133
|
-
*
|
|
3134
|
-
* - Auto-clears previous selection when selecting new item
|
|
3135
|
-
* - Singular computed properties (selectedId, selectedItem, selectedIndex, selectedValue)
|
|
3136
|
-
* - Perfect for tabs, radio buttons, theme selectors
|
|
3137
|
-
*
|
|
3138
|
-
* Inheritance chain: useRegistry → useSelection → useSingle
|
|
3139
|
-
*/
|
|
3140
|
-
/**
|
|
3141
|
-
* Creates a new single selection instance that enforces only one selected item at a time.
|
|
3142
|
-
*
|
|
3143
|
-
* Extends `createSelection` by automatically clearing previous selections when a new item is selected.
|
|
3144
|
-
* Adds computed singular properties: `selectedId`, `selectedItem`, `selectedIndex`, `selectedValue`.
|
|
3145
|
-
*
|
|
3146
|
-
* @param options The options for the single selection instance.
|
|
3147
|
-
* @template Z The type of the single selection ticket.
|
|
3148
|
-
* @template E The type of the single selection context.
|
|
3149
|
-
* @returns A new single selection instance with single-selection enforcement.
|
|
3150
|
-
*
|
|
3151
|
-
* @remarks
|
|
3152
|
-
* **Key Differences from `createSelection`:**
|
|
3153
|
-
* - Automatically clears `selectedIds` before selecting a new item (enforces single selection)
|
|
3154
|
-
* - Provides singular computed properties instead of plural sets
|
|
3155
|
-
* - Perfect for tabs, radio buttons, theme selectors, and other single-choice UI components
|
|
3156
|
-
*
|
|
3157
|
-
* **Computed Properties:**
|
|
3158
|
-
* - `selectedId`: The ID of the selected item (undefined if none selected)
|
|
3159
|
-
* - `selectedItem`: The selected ticket object (undefined if none selected)
|
|
3160
|
-
* - `selectedIndex`: The index of the selected item (-1 if none selected)
|
|
3161
|
-
* - `selectedValue`: The value of the selected item (undefined if none selected)
|
|
3162
|
-
*
|
|
3163
|
-
* **Inheritance Chain:**
|
|
3164
|
-
* `useRegistry` → `createSelection` → `createSingle` → `createStep`
|
|
3226
|
+
* @param target The element to observe.
|
|
3227
|
+
* @param callback The callback to execute when the element's size changes.
|
|
3228
|
+
* @param options The options for the Resize Observer.
|
|
3229
|
+
* @returns An object with methods to control the observer.
|
|
3165
3230
|
*
|
|
3166
|
-
* @see https://
|
|
3231
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
|
|
3232
|
+
* @see https://0.vuetifyjs.com/composables/system/use-resize-observer
|
|
3167
3233
|
*
|
|
3168
3234
|
* @example
|
|
3169
3235
|
* ```ts
|
|
3170
|
-
* import {
|
|
3171
|
-
*
|
|
3172
|
-
* const tabs = createSingle({ mandatory: true })
|
|
3236
|
+
* import { ref } from 'vue'
|
|
3237
|
+
* import { useResizeObserver } from '@vuetify/v0'
|
|
3173
3238
|
*
|
|
3174
|
-
*
|
|
3175
|
-
*
|
|
3176
|
-
*
|
|
3177
|
-
* { id: 'contact', value: 'Contact' },
|
|
3178
|
-
* ])
|
|
3239
|
+
* const el = ref<HTMLElement>()
|
|
3240
|
+
* const width = ref(0)
|
|
3241
|
+
* const height = ref(0)
|
|
3179
3242
|
*
|
|
3180
|
-
*
|
|
3243
|
+
* const { pause, resume, isPaused } = useResizeObserver(
|
|
3244
|
+
* el,
|
|
3245
|
+
* (entries) => {
|
|
3246
|
+
* const entry = entries[0]
|
|
3247
|
+
* if (entry) {
|
|
3248
|
+
* width.value = entry.contentRect.width
|
|
3249
|
+
* height.value = entry.contentRect.height
|
|
3250
|
+
* console.log('Size changed:', width.value, 'x', height.value)
|
|
3251
|
+
* }
|
|
3252
|
+
* },
|
|
3253
|
+
* { immediate: true }
|
|
3254
|
+
* )
|
|
3181
3255
|
*
|
|
3182
|
-
*
|
|
3183
|
-
*
|
|
3256
|
+
* // Pause observation
|
|
3257
|
+
* pause()
|
|
3184
3258
|
*
|
|
3185
|
-
*
|
|
3186
|
-
*
|
|
3187
|
-
* console.log(tabs.selectedIds.size) // 1 (always enforces single selection)
|
|
3259
|
+
* // Resume observation
|
|
3260
|
+
* resume()
|
|
3188
3261
|
* ```
|
|
3189
3262
|
*/
|
|
3190
|
-
function
|
|
3191
|
-
const {
|
|
3192
|
-
const
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3263
|
+
function useResizeObserver(target, callback, options = {}) {
|
|
3264
|
+
const { isHydrated } = useHydration();
|
|
3265
|
+
const observer = shallowRef();
|
|
3266
|
+
const isPaused = shallowRef(false);
|
|
3267
|
+
const isActive = toRef(() => !!observer.value);
|
|
3268
|
+
function setup() {
|
|
3269
|
+
if (observer.value === null) return;
|
|
3270
|
+
if (!isHydrated.value || !SUPPORTS_OBSERVER || !target.value || isPaused.value) return;
|
|
3271
|
+
observer.value = new ResizeObserver((entries) => {
|
|
3272
|
+
callback(entries.map((entry) => ({
|
|
3273
|
+
contentRect: {
|
|
3274
|
+
width: entry.contentRect.width,
|
|
3275
|
+
height: entry.contentRect.height,
|
|
3276
|
+
top: entry.contentRect.top,
|
|
3277
|
+
left: entry.contentRect.left
|
|
3278
|
+
},
|
|
3279
|
+
target: entry.target
|
|
3280
|
+
})));
|
|
3281
|
+
if (options.once) stop();
|
|
3282
|
+
});
|
|
3283
|
+
observer.value.observe(target.value, { box: options.box || "content-box" });
|
|
3284
|
+
if (options.immediate) {
|
|
3285
|
+
const rect = target.value.getBoundingClientRect();
|
|
3286
|
+
callback([{
|
|
3287
|
+
contentRect: {
|
|
3288
|
+
width: rect.width,
|
|
3289
|
+
height: rect.height,
|
|
3290
|
+
top: rect.top,
|
|
3291
|
+
left: rect.left
|
|
3292
|
+
},
|
|
3293
|
+
target: target.value
|
|
3294
|
+
}]);
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
watchEffect(() => {
|
|
3298
|
+
const hydrated = isHydrated.value;
|
|
3299
|
+
const el = target.value;
|
|
3300
|
+
cleanup();
|
|
3301
|
+
if (hydrated && el) setup();
|
|
3196
3302
|
});
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
if (mandatory && registry.selectedIds.size === 1) return;
|
|
3203
|
-
registry.selectedIds.delete(id);
|
|
3303
|
+
function cleanup() {
|
|
3304
|
+
if (observer.value) {
|
|
3305
|
+
observer.value.disconnect();
|
|
3306
|
+
observer.value = void 0;
|
|
3307
|
+
}
|
|
3204
3308
|
}
|
|
3205
|
-
function
|
|
3206
|
-
|
|
3207
|
-
|
|
3309
|
+
function pause() {
|
|
3310
|
+
isPaused.value = true;
|
|
3311
|
+
observer.value?.disconnect();
|
|
3208
3312
|
}
|
|
3313
|
+
function resume() {
|
|
3314
|
+
isPaused.value = false;
|
|
3315
|
+
setup();
|
|
3316
|
+
}
|
|
3317
|
+
function stop() {
|
|
3318
|
+
cleanup();
|
|
3319
|
+
observer.value = null;
|
|
3320
|
+
}
|
|
3321
|
+
onScopeDispose(stop, true);
|
|
3209
3322
|
return {
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
unselect,
|
|
3216
|
-
toggle,
|
|
3217
|
-
get size() {
|
|
3218
|
-
return registry.size;
|
|
3219
|
-
}
|
|
3323
|
+
isActive: shallowReadonly(isActive),
|
|
3324
|
+
isPaused: shallowReadonly(isPaused),
|
|
3325
|
+
pause,
|
|
3326
|
+
resume,
|
|
3327
|
+
stop
|
|
3220
3328
|
};
|
|
3221
3329
|
}
|
|
3222
3330
|
/**
|
|
3223
|
-
*
|
|
3331
|
+
* A convenience composable that uses the Resize Observer API to track an
|
|
3332
|
+
* element's size.
|
|
3224
3333
|
*
|
|
3225
|
-
* @param
|
|
3226
|
-
* @
|
|
3227
|
-
* @template E The type of the single selection context.
|
|
3228
|
-
* @returns A new single selection context.
|
|
3334
|
+
* @param target The element to observe.
|
|
3335
|
+
* @returns An object with the element's width and height.
|
|
3229
3336
|
*
|
|
3230
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
3337
|
+
* @see https://0.vuetifyjs.com/composables/system/use-resize-observer#use-element-size
|
|
3231
3338
|
*
|
|
3232
3339
|
* @example
|
|
3233
3340
|
* ```ts
|
|
3234
|
-
* import {
|
|
3235
|
-
*
|
|
3236
|
-
* // With default namespace 'v0:single'
|
|
3237
|
-
* export const [useSingle, provideSingle, context] = createSingleContext()
|
|
3341
|
+
* import { ref, watchEffect } from 'vue'
|
|
3342
|
+
* import { useElementSize } from '@vuetify/v0'
|
|
3238
3343
|
*
|
|
3239
|
-
*
|
|
3240
|
-
*
|
|
3344
|
+
* const box = ref<HTMLElement>()
|
|
3345
|
+
* const { width, height } = useElementSize(box)
|
|
3241
3346
|
*
|
|
3242
|
-
* //
|
|
3243
|
-
*
|
|
3244
|
-
*
|
|
3347
|
+
* // Width and height are reactive refs
|
|
3348
|
+
* watchEffect(() => {
|
|
3349
|
+
* console.log('Box size:', width.value, 'x', height.value)
|
|
3350
|
+
* })
|
|
3245
3351
|
* ```
|
|
3246
3352
|
*/
|
|
3247
|
-
function
|
|
3248
|
-
const
|
|
3249
|
-
const
|
|
3250
|
-
const
|
|
3251
|
-
|
|
3252
|
-
|
|
3353
|
+
function useElementSize(target) {
|
|
3354
|
+
const width = shallowRef(0);
|
|
3355
|
+
const height = shallowRef(0);
|
|
3356
|
+
const { pause: _pause, resume, stop, isActive, isPaused } = useResizeObserver(target, (entries) => {
|
|
3357
|
+
const entry = entries[0];
|
|
3358
|
+
if (entry) {
|
|
3359
|
+
width.value = entry.contentRect.width;
|
|
3360
|
+
height.value = entry.contentRect.height;
|
|
3361
|
+
}
|
|
3362
|
+
}, { immediate: true });
|
|
3363
|
+
function pause() {
|
|
3364
|
+
width.value = 0;
|
|
3365
|
+
height.value = 0;
|
|
3366
|
+
_pause();
|
|
3253
3367
|
}
|
|
3254
|
-
return
|
|
3368
|
+
return {
|
|
3369
|
+
width,
|
|
3370
|
+
height,
|
|
3371
|
+
isActive,
|
|
3372
|
+
isPaused,
|
|
3373
|
+
pause,
|
|
3374
|
+
resume,
|
|
3375
|
+
stop
|
|
3376
|
+
};
|
|
3255
3377
|
}
|
|
3378
|
+
|
|
3379
|
+
//#endregion
|
|
3380
|
+
//#region src/composables/useOverflow/index.ts
|
|
3256
3381
|
/**
|
|
3257
|
-
*
|
|
3258
|
-
*
|
|
3259
|
-
* @param namespace The namespace for the single selection context. Defaults to `'v0:single'`.
|
|
3260
|
-
* @returns The current single selection instance.
|
|
3382
|
+
* Creates a new overflow context for computing how many items fit in a container.
|
|
3261
3383
|
*
|
|
3262
|
-
* @
|
|
3384
|
+
* @param options Configuration options
|
|
3385
|
+
* @returns Overflow context with container ref, capacity, and measurement functions
|
|
3263
3386
|
*
|
|
3264
|
-
* @example
|
|
3387
|
+
* @example Variable-width mode (Breadcrumbs)
|
|
3265
3388
|
* ```vue
|
|
3266
|
-
* <script
|
|
3267
|
-
* import {
|
|
3389
|
+
* <script lang="ts" setup>
|
|
3390
|
+
* import { useTemplateRef } from 'vue'
|
|
3391
|
+
* import { createOverflow } from '@vuetify/v0'
|
|
3268
3392
|
*
|
|
3269
|
-
* const
|
|
3393
|
+
* const containerRef = useTemplateRef('container')
|
|
3394
|
+
* const overflow = createOverflow({
|
|
3395
|
+
* container: containerRef,
|
|
3396
|
+
* gap: 8,
|
|
3397
|
+
* reserved: 40,
|
|
3398
|
+
* })
|
|
3270
3399
|
* <\/script>
|
|
3271
3400
|
*
|
|
3272
3401
|
* <template>
|
|
3273
|
-
* <div>
|
|
3274
|
-
* <
|
|
3402
|
+
* <div ref="container">
|
|
3403
|
+
* <span
|
|
3404
|
+
* v-for="(item, i) in items.slice(0, overflow.capacity.value)"
|
|
3405
|
+
* :key="i"
|
|
3406
|
+
* :ref="el => overflow.measure(i, el)"
|
|
3407
|
+
* >
|
|
3408
|
+
* {{ item }}
|
|
3409
|
+
* </span>
|
|
3410
|
+
* <span v-if="overflow.isOverflowing.value">...</span>
|
|
3275
3411
|
* </div>
|
|
3276
3412
|
* </template>
|
|
3277
3413
|
* ```
|
|
3278
|
-
*/
|
|
3279
|
-
function useSingle(namespace = "v0:single") {
|
|
3280
|
-
return useContext(namespace);
|
|
3281
|
-
}
|
|
3282
|
-
|
|
3283
|
-
//#endregion
|
|
3284
|
-
//#region src/composables/useTokens/index.ts
|
|
3285
|
-
/**
|
|
3286
|
-
* @module useTokens
|
|
3287
|
-
*
|
|
3288
|
-
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
3289
3414
|
*
|
|
3290
|
-
* @
|
|
3291
|
-
* Design token registry with alias resolution and W3C Design Tokens format support.
|
|
3292
|
-
*
|
|
3293
|
-
* Key features:
|
|
3294
|
-
* - Alias resolution with circular reference detection
|
|
3295
|
-
* - Nested token flattening with dot notation
|
|
3296
|
-
* - W3C Design Tokens format ($value, $type, $description, $extensions)
|
|
3297
|
-
* - Path-based resolution (e.g., {colors}.blue.500)
|
|
3298
|
-
* - Resolution caching for performance (~28,590 ops/sec)
|
|
3299
|
-
*
|
|
3300
|
-
* Used by useTheme, useLocale, and useFeatures for token-based configuration.
|
|
3301
|
-
*/
|
|
3302
|
-
/**
|
|
3303
|
-
* Creates a new token instance.
|
|
3304
|
-
*
|
|
3305
|
-
* @param tokens The tokens to use.
|
|
3306
|
-
* @param options The options for the token instance.
|
|
3307
|
-
* @template Z The type of the token ticket.
|
|
3308
|
-
* @template E The type of the token context.
|
|
3309
|
-
* @returns A new token instance.
|
|
3310
|
-
*
|
|
3311
|
-
* @see https://www.designtokens.org/tr/drafts/format/
|
|
3312
|
-
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
3313
|
-
*
|
|
3314
|
-
* @example
|
|
3415
|
+
* @example Uniform-width mode (Pagination)
|
|
3315
3416
|
* ```ts
|
|
3316
|
-
*
|
|
3317
|
-
*
|
|
3318
|
-
*
|
|
3319
|
-
*
|
|
3320
|
-
* primary: '#3b82f6',
|
|
3321
|
-
* secondary: '{colors.primary}', // Alias reference
|
|
3322
|
-
* },
|
|
3417
|
+
* const overflow = createOverflow({
|
|
3418
|
+
* container: () => atom.value?.element,
|
|
3419
|
+
* itemWidth: buttonWidth,
|
|
3420
|
+
* reserved: () => buttonWidth.value * 4,
|
|
3323
3421
|
* })
|
|
3324
|
-
*
|
|
3325
|
-
* console.log(tokens.resolve('{colors.primary}')) // '#3b82f6'
|
|
3326
|
-
* console.log(tokens.resolve('{colors.secondary}')) // '#3b82f6'
|
|
3327
3422
|
* ```
|
|
3328
3423
|
*/
|
|
3329
|
-
function
|
|
3330
|
-
const
|
|
3331
|
-
const
|
|
3332
|
-
const
|
|
3333
|
-
|
|
3334
|
-
function
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
function resolve(token, visited = /* @__PURE__ */ new Set()) {
|
|
3341
|
-
const cacheKey = /* @__PURE__ */ isString(token) ? token : JSON.stringify(token);
|
|
3342
|
-
const cached = cache.get(cacheKey);
|
|
3343
|
-
if (!/* @__PURE__ */ isUndefined(cached)) return cached;
|
|
3344
|
-
const reference = isTokenAlias(token) ? token.$value : token;
|
|
3345
|
-
const isAliasReference = /* @__PURE__ */ isString(reference) && isAlias(reference);
|
|
3346
|
-
const clean = isAliasReference ? reference.slice(1, -1) : String(reference);
|
|
3347
|
-
if (visited.has(clean)) {
|
|
3348
|
-
logger.warn(`Circular alias detected for "${clean}"`);
|
|
3349
|
-
cache.set(cacheKey, void 0);
|
|
3350
|
-
return;
|
|
3351
|
-
}
|
|
3352
|
-
visited.add(clean);
|
|
3353
|
-
let found = registry.get(clean);
|
|
3354
|
-
let segments = [];
|
|
3355
|
-
if (!found && clean.includes(".")) {
|
|
3356
|
-
const parts = clean.split(".");
|
|
3357
|
-
for (let i = parts.length - 1; i > 0; i--) {
|
|
3358
|
-
const prefix = parts.slice(0, i).join(".");
|
|
3359
|
-
const suffix = parts.slice(i);
|
|
3360
|
-
const candidate = registry.get(prefix);
|
|
3361
|
-
if (!/* @__PURE__ */ isUndefined(candidate?.value)) {
|
|
3362
|
-
found = candidate;
|
|
3363
|
-
segments = suffix;
|
|
3364
|
-
break;
|
|
3365
|
-
}
|
|
3424
|
+
function createOverflow(options = {}) {
|
|
3425
|
+
const { container: _container, gap = 0, reserved = 0, itemWidth, reverse } = options;
|
|
3426
|
+
const container = /* @__PURE__ */ isUndefined(_container) ? shallowRef() : toRef(_container);
|
|
3427
|
+
const widths = shallowRef(/* @__PURE__ */ new Map());
|
|
3428
|
+
const { width } = useElementSize(container);
|
|
3429
|
+
function measure(index, el) {
|
|
3430
|
+
if (!el) {
|
|
3431
|
+
if (widths.value.has(index)) {
|
|
3432
|
+
const next = new Map(widths.value);
|
|
3433
|
+
next.delete(index);
|
|
3434
|
+
widths.value = next;
|
|
3366
3435
|
}
|
|
3367
|
-
}
|
|
3368
|
-
if (/* @__PURE__ */ isUndefined(found?.value)) {
|
|
3369
|
-
if (isAliasReference) logger.warn(`Alias not found for "${String(reference)}"`);
|
|
3370
|
-
cache.set(cacheKey, void 0);
|
|
3371
3436
|
return;
|
|
3372
3437
|
}
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
for (const segment of segments) {
|
|
3378
|
-
if (!/* @__PURE__ */ isObject(current) || !(segment in current)) {
|
|
3379
|
-
current = void 0;
|
|
3380
|
-
break;
|
|
3381
|
-
}
|
|
3382
|
-
current = current[segment];
|
|
3383
|
-
if (isTokenAlias(current)) current = current.$value;
|
|
3384
|
-
}
|
|
3385
|
-
if (/* @__PURE__ */ isUndefined(current)) {
|
|
3386
|
-
logger.warn(`Path not found inside "${clean}": ${segments.join(".")}`);
|
|
3387
|
-
cache.set(cacheKey, void 0);
|
|
3388
|
-
return;
|
|
3389
|
-
}
|
|
3390
|
-
result = current;
|
|
3391
|
-
} else if (isTokenAlias(current)) {
|
|
3392
|
-
const inner = current.$value;
|
|
3393
|
-
if (/* @__PURE__ */ isString(inner) && isAlias(inner)) return resolve(inner, visited);
|
|
3394
|
-
result = inner;
|
|
3395
|
-
} else if (/* @__PURE__ */ isString(current) && isAlias(current)) return resolve(current, visited);
|
|
3396
|
-
else result = current;
|
|
3397
|
-
cache.set(cacheKey, result);
|
|
3398
|
-
return result;
|
|
3438
|
+
const style = getComputedStyle(el);
|
|
3439
|
+
const marginX = Number.parseFloat(style.marginLeft) + Number.parseFloat(style.marginRight);
|
|
3440
|
+
const w = el.offsetWidth + marginX;
|
|
3441
|
+
if (widths.value.get(index) !== w) widths.value = new Map(widths.value).set(index, w);
|
|
3399
3442
|
}
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3443
|
+
function reset() {
|
|
3444
|
+
widths.value = /* @__PURE__ */ new Map();
|
|
3445
|
+
}
|
|
3446
|
+
const total = computed(() => {
|
|
3447
|
+
const g = toValue(gap);
|
|
3448
|
+
let sum = 0;
|
|
3449
|
+
let count = 0;
|
|
3450
|
+
for (const w of widths.value.values()) {
|
|
3451
|
+
sum += w + (count > 0 ? g : 0);
|
|
3452
|
+
count++;
|
|
3406
3453
|
}
|
|
3454
|
+
return sum;
|
|
3455
|
+
});
|
|
3456
|
+
return {
|
|
3457
|
+
container,
|
|
3458
|
+
width,
|
|
3459
|
+
capacity: computed(() => {
|
|
3460
|
+
const available = width.value - toValue(reserved);
|
|
3461
|
+
if (width.value === 0) return Infinity;
|
|
3462
|
+
if (available <= 0) return 0;
|
|
3463
|
+
const g = toValue(gap);
|
|
3464
|
+
const uniformWidth = toValue(itemWidth);
|
|
3465
|
+
if (uniformWidth && uniformWidth > 0) {
|
|
3466
|
+
const first = uniformWidth;
|
|
3467
|
+
const subsequent = uniformWidth + g;
|
|
3468
|
+
if (available < first) return 0;
|
|
3469
|
+
return Math.max(1, Math.floor((available - first) / subsequent) + 1);
|
|
3470
|
+
}
|
|
3471
|
+
const entries = [...widths.value.entries()].toSorted((a, b) => a[0] - b[0]);
|
|
3472
|
+
if (toValue(reverse)) entries.reverse();
|
|
3473
|
+
let sum = 0;
|
|
3474
|
+
let count = 0;
|
|
3475
|
+
for (const [, w] of entries) {
|
|
3476
|
+
const next = sum + w + (count > 0 ? g : 0);
|
|
3477
|
+
if (next > available) break;
|
|
3478
|
+
sum = next;
|
|
3479
|
+
count++;
|
|
3480
|
+
}
|
|
3481
|
+
return count;
|
|
3482
|
+
}),
|
|
3483
|
+
total,
|
|
3484
|
+
isOverflowing: toRef(() => {
|
|
3485
|
+
return total.value > width.value - toValue(reserved);
|
|
3486
|
+
}),
|
|
3487
|
+
measure,
|
|
3488
|
+
reset
|
|
3407
3489
|
};
|
|
3408
3490
|
}
|
|
3409
3491
|
/**
|
|
3410
|
-
* Creates
|
|
3411
|
-
*
|
|
3412
|
-
* @param namespace The namespace for the token context.
|
|
3413
|
-
* @param tokens The tokens to use.
|
|
3414
|
-
* @template Z The type of the token ticket.
|
|
3415
|
-
* @template E The type of the token context.
|
|
3416
|
-
* @returns A new token context.
|
|
3492
|
+
* Creates an overflow context with dependency injection support.
|
|
3417
3493
|
*
|
|
3418
|
-
* @
|
|
3494
|
+
* @param options Configuration options including namespace
|
|
3495
|
+
* @returns Trinity tuple: [useContext, provideContext, defaultContext]
|
|
3419
3496
|
*
|
|
3420
3497
|
* @example
|
|
3421
3498
|
* ```ts
|
|
3422
|
-
*
|
|
3423
|
-
*
|
|
3424
|
-
*
|
|
3425
|
-
*
|
|
3426
|
-
*
|
|
3427
|
-
*
|
|
3428
|
-
*
|
|
3429
|
-
*
|
|
3430
|
-
*
|
|
3431
|
-
*
|
|
3432
|
-
*
|
|
3433
|
-
*
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
const
|
|
3438
|
-
const
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
return createTrinity(useTokensContext, provideTokensContext, context);
|
|
3443
|
-
}
|
|
3444
|
-
/**
|
|
3445
|
-
* Returns the current tokens instance.
|
|
3446
|
-
*
|
|
3447
|
-
* @param namespace The namespace for the tokens context. Defaults to `'v0:tokens'`.
|
|
3448
|
-
* @returns The current tokens instance.
|
|
3449
|
-
*
|
|
3450
|
-
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
3451
|
-
*
|
|
3452
|
-
* @example
|
|
3453
|
-
* ```vue
|
|
3454
|
-
* <script setup lang="ts">
|
|
3455
|
-
* import { useTokens } from '@vuetify/v0'
|
|
3456
|
-
*
|
|
3457
|
-
* const tokens = useTokens()
|
|
3458
|
-
* <\/script>
|
|
3459
|
-
* ```
|
|
3460
|
-
*/
|
|
3461
|
-
function useTokens(namespace = "v0:tokens") {
|
|
3462
|
-
return useContext(namespace);
|
|
3463
|
-
}
|
|
3464
|
-
/**
|
|
3465
|
-
* Flattens a nested collection of tokens into a flat array of tokens.
|
|
3466
|
-
* Each token is represented by an object containing its ID & value.
|
|
3467
|
-
* @param tokens The collection of tokens to flatten.
|
|
3468
|
-
* @param prefix An optional prefix to prepend to each token ID.
|
|
3469
|
-
* @returns An array of flattened tokens, each with an ID and value.
|
|
3470
|
-
*/
|
|
3471
|
-
function flatten(tokens, prefix = "", flat = false) {
|
|
3472
|
-
const flattened = [];
|
|
3473
|
-
const stack = [{
|
|
3474
|
-
tokens,
|
|
3475
|
-
prefix,
|
|
3476
|
-
flat
|
|
3477
|
-
}];
|
|
3478
|
-
while (stack.length > 0) {
|
|
3479
|
-
const { tokens: currentTokens, prefix: currentPrefix, flat: flat$1 } = stack.pop();
|
|
3480
|
-
const meta = {};
|
|
3481
|
-
for (const k in currentTokens) if (k.startsWith("$")) meta[k] = currentTokens[k];
|
|
3482
|
-
if (Object.keys(meta).length > 0 && currentPrefix) flattened.push({
|
|
3483
|
-
id: currentPrefix,
|
|
3484
|
-
value: meta
|
|
3485
|
-
});
|
|
3486
|
-
for (const key in currentTokens) {
|
|
3487
|
-
if (key.startsWith("$")) continue;
|
|
3488
|
-
const value = currentTokens[key];
|
|
3489
|
-
const id = currentPrefix ? `${currentPrefix}.${key}` : key;
|
|
3490
|
-
if (!/* @__PURE__ */ isObject(value)) {
|
|
3491
|
-
flattened.push({
|
|
3492
|
-
id,
|
|
3493
|
-
value
|
|
3494
|
-
});
|
|
3495
|
-
continue;
|
|
3496
|
-
}
|
|
3497
|
-
if ("$value" in value) {
|
|
3498
|
-
flattened.push({
|
|
3499
|
-
id,
|
|
3500
|
-
value
|
|
3501
|
-
});
|
|
3502
|
-
const inner = value.$value;
|
|
3503
|
-
if (/* @__PURE__ */ isObject(inner) && !flat$1) for (const innerKey in inner) {
|
|
3504
|
-
if (innerKey.startsWith("$")) continue;
|
|
3505
|
-
const child = inner[innerKey];
|
|
3506
|
-
const childId = `${id}.${innerKey}`;
|
|
3507
|
-
if (!/* @__PURE__ */ isObject(child)) flattened.push({
|
|
3508
|
-
id: childId,
|
|
3509
|
-
value: child
|
|
3510
|
-
});
|
|
3511
|
-
else if ("$value" in child) flattened.push({
|
|
3512
|
-
id: childId,
|
|
3513
|
-
value: child
|
|
3514
|
-
});
|
|
3515
|
-
else stack.push({
|
|
3516
|
-
tokens: child,
|
|
3517
|
-
prefix: childId,
|
|
3518
|
-
flat: flat$1
|
|
3519
|
-
});
|
|
3520
|
-
}
|
|
3521
|
-
continue;
|
|
3522
|
-
}
|
|
3523
|
-
if (flat$1) {
|
|
3524
|
-
flattened.push({
|
|
3525
|
-
id,
|
|
3526
|
-
value
|
|
3527
|
-
});
|
|
3528
|
-
continue;
|
|
3529
|
-
}
|
|
3530
|
-
stack.push({
|
|
3531
|
-
tokens: value,
|
|
3532
|
-
prefix: id,
|
|
3533
|
-
flat: flat$1
|
|
3534
|
-
});
|
|
3535
|
-
}
|
|
3536
|
-
}
|
|
3537
|
-
return flattened;
|
|
3538
|
-
}
|
|
3539
|
-
|
|
3540
|
-
//#endregion
|
|
3541
|
-
//#region src/composables/useLocale/adapters/v0.ts
|
|
3542
|
-
/**
|
|
3543
|
-
* Vuetify0.x locale adapter implementation
|
|
3544
|
-
*
|
|
3545
|
-
* This adapter provides translation and number formatting
|
|
3546
|
-
* capabilities using the Intl API and supports both
|
|
3547
|
-
* numbered ({0}, {1}) and named ({name}) variables in translation strings.
|
|
3548
|
-
*/
|
|
3549
|
-
var Vuetify0LocaleAdapter = class {
|
|
3550
|
-
t(message, ...params) {
|
|
3551
|
-
let resolvedMessage = message;
|
|
3552
|
-
if (params.length > 0 && /* @__PURE__ */ isObject(params[0])) {
|
|
3553
|
-
const variables = params[0];
|
|
3554
|
-
resolvedMessage = resolvedMessage.replace(/{([a-zA-Z][a-zA-Z0-9_]*)}/g, (match, name) => {
|
|
3555
|
-
return /* @__PURE__ */ isUndefined(variables[name]) ? match : String(variables[name]);
|
|
3556
|
-
});
|
|
3557
|
-
params = params.slice(1);
|
|
3558
|
-
}
|
|
3559
|
-
resolvedMessage = resolvedMessage.replace(/\{(\d+)\}/g, (match, index) => {
|
|
3560
|
-
const idx = Number.parseInt(index, 10);
|
|
3561
|
-
if (!/* @__PURE__ */ isUndefined(params[idx])) return String(params[idx]);
|
|
3562
|
-
return match;
|
|
3563
|
-
});
|
|
3564
|
-
return resolvedMessage;
|
|
3565
|
-
}
|
|
3566
|
-
n(value, locale, ...params) {
|
|
3567
|
-
if (!IN_BROWSER || !locale) return value.toString();
|
|
3568
|
-
const options = params[0];
|
|
3569
|
-
return new Intl.NumberFormat(String(locale), options).format(value);
|
|
3499
|
+
* // Create injectable context
|
|
3500
|
+
* const [useOverflow, provideOverflow, overflow] = createOverflowContext({
|
|
3501
|
+
* namespace: 'my-overflow',
|
|
3502
|
+
* gap: 8,
|
|
3503
|
+
* reserved: 160,
|
|
3504
|
+
* })
|
|
3505
|
+
*
|
|
3506
|
+
* // In parent component
|
|
3507
|
+
* provideOverflow()
|
|
3508
|
+
*
|
|
3509
|
+
* // In child component
|
|
3510
|
+
* const overflow = useOverflow()
|
|
3511
|
+
* ```
|
|
3512
|
+
*/
|
|
3513
|
+
function createOverflowContext(_options = {}) {
|
|
3514
|
+
const { namespace = "v0:overflow", ...options } = _options;
|
|
3515
|
+
const [useOverflowContext, _provideOverflowContext] = createContext(namespace);
|
|
3516
|
+
const context = createOverflow(options);
|
|
3517
|
+
function provideOverflowContext(_context = context, app) {
|
|
3518
|
+
return _provideOverflowContext(_context, app);
|
|
3570
3519
|
}
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
//#endregion
|
|
3574
|
-
//#region src/composables/useLocale/index.ts
|
|
3520
|
+
return createTrinity(useOverflowContext, provideOverflowContext, context);
|
|
3521
|
+
}
|
|
3575
3522
|
/**
|
|
3576
|
-
*
|
|
3523
|
+
* Returns the current overflow context from dependency injection.
|
|
3577
3524
|
*
|
|
3578
|
-
* @
|
|
3579
|
-
*
|
|
3525
|
+
* @param namespace The namespace for the overflow context. Defaults to `v0:overflow`.
|
|
3526
|
+
* @returns The current overflow context.
|
|
3580
3527
|
*
|
|
3581
|
-
*
|
|
3582
|
-
*
|
|
3583
|
-
*
|
|
3584
|
-
*
|
|
3585
|
-
*
|
|
3586
|
-
*
|
|
3528
|
+
* @example
|
|
3529
|
+
* ```vue
|
|
3530
|
+
* <script lang="ts" setup>
|
|
3531
|
+
* import { useOverflow } from '@vuetify/v0'
|
|
3532
|
+
*
|
|
3533
|
+
* // Inject overflow context provided by parent
|
|
3534
|
+
* const overflow = useOverflow()
|
|
3535
|
+
* <\/script>
|
|
3587
3536
|
*
|
|
3588
|
-
*
|
|
3537
|
+
* <template>
|
|
3538
|
+
* <div>
|
|
3539
|
+
* <p>Capacity: {{ overflow.capacity.value }}</p>
|
|
3540
|
+
* </div>
|
|
3541
|
+
* </template>
|
|
3542
|
+
* ```
|
|
3589
3543
|
*/
|
|
3544
|
+
function useOverflow(namespace = "v0:overflow") {
|
|
3545
|
+
return useContext(namespace);
|
|
3546
|
+
}
|
|
3547
|
+
|
|
3548
|
+
//#endregion
|
|
3549
|
+
//#region src/composables/usePagination/index.ts
|
|
3590
3550
|
/**
|
|
3591
|
-
* Creates a
|
|
3551
|
+
* Creates a pagination instance.
|
|
3592
3552
|
*
|
|
3593
|
-
* @param options The options for the
|
|
3594
|
-
* @
|
|
3595
|
-
* @template E The type of the locale context.
|
|
3596
|
-
* @returns A new locale instance.
|
|
3553
|
+
* @param options The options for the pagination instance.
|
|
3554
|
+
* @returns A pagination context with navigation methods.
|
|
3597
3555
|
*
|
|
3598
|
-
* @
|
|
3556
|
+
* @example
|
|
3557
|
+
* ```ts
|
|
3558
|
+
* import { createPagination } from '@vuetify/v0'
|
|
3559
|
+
*
|
|
3560
|
+
* // Basic usage
|
|
3561
|
+
* const pagination = createPagination({ size: 100 })
|
|
3562
|
+
* pagination.next()
|
|
3563
|
+
* pagination.items.value // [{ type: 'page', value: 1 }, { type: 'page', value: 2 }, ...]
|
|
3564
|
+
*
|
|
3565
|
+
* // With v-model (pass a ref)
|
|
3566
|
+
* const page = ref(1)
|
|
3567
|
+
* const pagination = createPagination({ page, size: 100 })
|
|
3568
|
+
* // Mutating pagination.page or the passed ref syncs both
|
|
3569
|
+
* ```
|
|
3599
3570
|
*/
|
|
3600
|
-
function
|
|
3601
|
-
const {
|
|
3602
|
-
const
|
|
3603
|
-
const
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
if (
|
|
3571
|
+
function createPagination(_options = {}) {
|
|
3572
|
+
const { page: _page = 1, itemsPerPage: _itemsPerPage = 10, size: _size = 0, visible: _visible = 7, ellipsis = "..." } = _options;
|
|
3573
|
+
const page = isRef(_page) ? _page : shallowRef(_page);
|
|
3574
|
+
const pages = computed(() => {
|
|
3575
|
+
const size = toValue(_size);
|
|
3576
|
+
const perPage = toValue(_itemsPerPage);
|
|
3577
|
+
if (size <= 0 || /* @__PURE__ */ isNaN(size)) return 0;
|
|
3578
|
+
return Math.ceil(size / perPage);
|
|
3579
|
+
});
|
|
3580
|
+
function first() {
|
|
3581
|
+
page.value = 1;
|
|
3607
3582
|
}
|
|
3608
|
-
function
|
|
3609
|
-
|
|
3610
|
-
const args = toArray(params);
|
|
3611
|
-
if (!locale) return adapter.t(fallback ?? key, ...args);
|
|
3612
|
-
const path = `${locale}.${key}`;
|
|
3613
|
-
const message = tokens.get(path)?.value;
|
|
3614
|
-
const template = /* @__PURE__ */ isString(message) ? resolve(locale, message) : fallback ?? key;
|
|
3615
|
-
return adapter.t(template, ...args);
|
|
3583
|
+
function last() {
|
|
3584
|
+
page.value = Math.max(1, pages.value);
|
|
3616
3585
|
}
|
|
3617
|
-
function
|
|
3618
|
-
|
|
3586
|
+
function next() {
|
|
3587
|
+
if (page.value < pages.value) page.value++;
|
|
3619
3588
|
}
|
|
3620
|
-
function
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3589
|
+
function prev() {
|
|
3590
|
+
if (page.value > 1) page.value--;
|
|
3591
|
+
}
|
|
3592
|
+
function select(value) {
|
|
3593
|
+
if (value < 1) page.value = 1;
|
|
3594
|
+
else if (value > pages.value) page.value = Math.max(1, pages.value);
|
|
3595
|
+
else page.value = value;
|
|
3596
|
+
}
|
|
3597
|
+
const isFirst = computed(() => page.value <= 1);
|
|
3598
|
+
const isLast = computed(() => page.value >= pages.value);
|
|
3599
|
+
const pageStart = computed(() => (page.value - 1) * toValue(_itemsPerPage));
|
|
3600
|
+
const pageStop = computed(() => Math.min(pageStart.value + toValue(_itemsPerPage), toValue(_size)));
|
|
3601
|
+
function toPage(value) {
|
|
3602
|
+
return {
|
|
3603
|
+
type: "page",
|
|
3604
|
+
value
|
|
3605
|
+
};
|
|
3606
|
+
}
|
|
3607
|
+
function toEllipsis() {
|
|
3608
|
+
return ellipsis === false ? false : {
|
|
3609
|
+
type: "ellipsis",
|
|
3610
|
+
value: ellipsis
|
|
3611
|
+
};
|
|
3612
|
+
}
|
|
3613
|
+
function filter(array) {
|
|
3614
|
+
return array.filter((item) => item !== false);
|
|
3629
3615
|
}
|
|
3630
3616
|
return {
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3617
|
+
page,
|
|
3618
|
+
ellipsis,
|
|
3619
|
+
items: computed(() => {
|
|
3620
|
+
const pageCount = pages.value;
|
|
3621
|
+
const visible = toValue(_visible);
|
|
3622
|
+
const current = page.value;
|
|
3623
|
+
if (pageCount <= 0 || /* @__PURE__ */ isNaN(pageCount) || pageCount > Number.MAX_SAFE_INTEGER) return [];
|
|
3624
|
+
if (visible <= 0) return [];
|
|
3625
|
+
if (visible <= 2) return [toPage(current)];
|
|
3626
|
+
if (pageCount <= visible) return (/* @__PURE__ */ range(pageCount, 1)).map(toPage);
|
|
3627
|
+
if (visible === 3) {
|
|
3628
|
+
const mid = current <= 1 ? 2 : current >= pageCount ? pageCount - 1 : current;
|
|
3629
|
+
return [
|
|
3630
|
+
toPage(1),
|
|
3631
|
+
toPage(mid),
|
|
3632
|
+
toPage(pageCount)
|
|
3633
|
+
];
|
|
3634
|
+
}
|
|
3635
|
+
const boundary = visible - 2;
|
|
3636
|
+
const middle = visible - 4;
|
|
3637
|
+
if (middle <= 0) {
|
|
3638
|
+
if (current <= boundary) return filter([
|
|
3639
|
+
...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
|
|
3640
|
+
toEllipsis(),
|
|
3641
|
+
toPage(pageCount)
|
|
3642
|
+
]);
|
|
3643
|
+
if (current > pageCount - boundary) return filter([
|
|
3644
|
+
toPage(1),
|
|
3645
|
+
toEllipsis(),
|
|
3646
|
+
...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
|
|
3647
|
+
]);
|
|
3648
|
+
return current <= Math.ceil(pageCount / 2) ? filter([
|
|
3649
|
+
toPage(1),
|
|
3650
|
+
toPage(current),
|
|
3651
|
+
toEllipsis(),
|
|
3652
|
+
toPage(pageCount)
|
|
3653
|
+
]) : filter([
|
|
3654
|
+
toPage(1),
|
|
3655
|
+
toEllipsis(),
|
|
3656
|
+
toPage(current),
|
|
3657
|
+
toPage(pageCount)
|
|
3658
|
+
]);
|
|
3659
|
+
}
|
|
3660
|
+
const leftThreshold = boundary - 1;
|
|
3661
|
+
const rightThreshold = pageCount - boundary + 2;
|
|
3662
|
+
if (current <= leftThreshold) return filter([
|
|
3663
|
+
...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
|
|
3664
|
+
toEllipsis(),
|
|
3665
|
+
toPage(pageCount)
|
|
3666
|
+
]);
|
|
3667
|
+
else if (current >= rightThreshold) return filter([
|
|
3668
|
+
toPage(1),
|
|
3669
|
+
toEllipsis(),
|
|
3670
|
+
...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
|
|
3671
|
+
]);
|
|
3672
|
+
else {
|
|
3673
|
+
const start = current - Math.floor(middle / 2);
|
|
3674
|
+
return filter([
|
|
3675
|
+
toPage(1),
|
|
3676
|
+
toEllipsis(),
|
|
3677
|
+
...(/* @__PURE__ */ range(middle, start)).map(toPage),
|
|
3678
|
+
toEllipsis(),
|
|
3679
|
+
toPage(pageCount)
|
|
3680
|
+
]);
|
|
3681
|
+
}
|
|
3682
|
+
}),
|
|
3683
|
+
pageStart,
|
|
3684
|
+
pageStop,
|
|
3685
|
+
isFirst,
|
|
3686
|
+
isLast,
|
|
3687
|
+
first,
|
|
3688
|
+
last,
|
|
3689
|
+
next,
|
|
3690
|
+
prev,
|
|
3691
|
+
select,
|
|
3692
|
+
get itemsPerPage() {
|
|
3693
|
+
return toValue(_itemsPerPage);
|
|
3694
|
+
},
|
|
3634
3695
|
get size() {
|
|
3635
|
-
return
|
|
3696
|
+
return toValue(_size);
|
|
3697
|
+
},
|
|
3698
|
+
get pages() {
|
|
3699
|
+
return pages.value;
|
|
3636
3700
|
}
|
|
3637
3701
|
};
|
|
3638
3702
|
}
|
|
3639
|
-
function createLocaleFallback() {
|
|
3640
|
-
return {
|
|
3641
|
-
size: 0,
|
|
3642
|
-
t: (key, _params, fallback) => fallback ?? key,
|
|
3643
|
-
n: String
|
|
3644
|
-
};
|
|
3645
|
-
}
|
|
3646
3703
|
/**
|
|
3647
|
-
* Creates a
|
|
3648
|
-
*
|
|
3649
|
-
* @param options The options for the locale context.
|
|
3650
|
-
* @template Z The type of the locale ticket.
|
|
3651
|
-
* @template E The type of the locale context.
|
|
3652
|
-
* @returns A new locale context.
|
|
3704
|
+
* Creates a pagination context for dependency injection.
|
|
3653
3705
|
*
|
|
3654
|
-
* @
|
|
3706
|
+
* @param options The options including namespace.
|
|
3707
|
+
* @returns A trinity: [usePagination, providePagination, defaultContext]
|
|
3655
3708
|
*
|
|
3656
3709
|
* @example
|
|
3657
3710
|
* ```ts
|
|
3658
|
-
*
|
|
3711
|
+
* // With default namespace 'v0:pagination'
|
|
3712
|
+
* const [usePagination, providePaginationContext] = createPaginationContext({ size: 50 })
|
|
3659
3713
|
*
|
|
3660
|
-
*
|
|
3661
|
-
*
|
|
3662
|
-
*
|
|
3663
|
-
*
|
|
3664
|
-
* es: { hello: 'Hola' },
|
|
3665
|
-
* },
|
|
3714
|
+
* // Or with custom namespace
|
|
3715
|
+
* const [usePagination, providePaginationContext] = createPaginationContext({
|
|
3716
|
+
* namespace: 'my-pagination',
|
|
3717
|
+
* size: 50,
|
|
3666
3718
|
* })
|
|
3667
3719
|
*
|
|
3668
|
-
* //
|
|
3669
|
-
*
|
|
3720
|
+
* // Parent component
|
|
3721
|
+
* providePaginationContext()
|
|
3670
3722
|
*
|
|
3671
|
-
* //
|
|
3672
|
-
* const
|
|
3673
|
-
*
|
|
3723
|
+
* // Child component
|
|
3724
|
+
* const pagination = usePagination()
|
|
3725
|
+
* pagination.next()
|
|
3674
3726
|
* ```
|
|
3675
3727
|
*/
|
|
3676
|
-
function
|
|
3677
|
-
const { namespace = "v0:
|
|
3678
|
-
const [
|
|
3679
|
-
const context =
|
|
3680
|
-
function
|
|
3681
|
-
return
|
|
3728
|
+
function createPaginationContext(_options = {}) {
|
|
3729
|
+
const { namespace = "v0:pagination", ...options } = _options;
|
|
3730
|
+
const [usePaginationContext, _providePaginationContext] = createContext(namespace);
|
|
3731
|
+
const context = createPagination(options);
|
|
3732
|
+
function providePaginationContext(_context = context, app) {
|
|
3733
|
+
return _providePaginationContext(_context, app);
|
|
3682
3734
|
}
|
|
3683
|
-
return createTrinity(
|
|
3735
|
+
return createTrinity(usePaginationContext, providePaginationContext, context);
|
|
3684
3736
|
}
|
|
3685
3737
|
/**
|
|
3686
|
-
*
|
|
3738
|
+
* Returns the current pagination instance from context.
|
|
3687
3739
|
*
|
|
3688
|
-
* @param
|
|
3689
|
-
* @
|
|
3690
|
-
* @template E The type of the locale context.
|
|
3691
|
-
* @template R The type of the token ticket.
|
|
3692
|
-
* @template O The type of the token context.
|
|
3693
|
-
* @returns A new locale plugin.
|
|
3740
|
+
* @param namespace The namespace. @default 'v0:pagination'
|
|
3741
|
+
* @returns The pagination context.
|
|
3694
3742
|
*
|
|
3695
|
-
* @
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
const [, provideLocaleContext, context] = createLocaleContext({
|
|
3700
|
-
...options,
|
|
3701
|
-
namespace,
|
|
3702
|
-
adapter,
|
|
3703
|
-
messages
|
|
3704
|
-
});
|
|
3705
|
-
return createPlugin({
|
|
3706
|
-
namespace,
|
|
3707
|
-
provide: (app) => {
|
|
3708
|
-
provideLocaleContext(context, app);
|
|
3709
|
-
}
|
|
3710
|
-
});
|
|
3711
|
-
}
|
|
3712
|
-
/**
|
|
3713
|
-
* Returns the current locale instance.
|
|
3743
|
+
* @example
|
|
3744
|
+
* ```vue
|
|
3745
|
+
* <script setup lang="ts">
|
|
3746
|
+
* import { usePagination } from '@vuetify/v0'
|
|
3714
3747
|
*
|
|
3715
|
-
*
|
|
3748
|
+
* const pagination = usePagination()
|
|
3749
|
+
* <\/script>
|
|
3716
3750
|
*
|
|
3717
|
-
*
|
|
3751
|
+
* <template>
|
|
3752
|
+
* <button @click="pagination.prev()" :disabled="pagination.isFirst.value">Prev</button>
|
|
3753
|
+
* <button @click="pagination.next()" :disabled="pagination.isLast.value">Next</button>
|
|
3754
|
+
* </template>
|
|
3755
|
+
* ```
|
|
3718
3756
|
*/
|
|
3719
|
-
function
|
|
3720
|
-
|
|
3721
|
-
if (!getCurrentInstance()) return fallback;
|
|
3722
|
-
try {
|
|
3723
|
-
return useContext(namespace, fallback);
|
|
3724
|
-
} catch {
|
|
3725
|
-
return fallback;
|
|
3726
|
-
}
|
|
3757
|
+
function usePagination(namespace = "v0:pagination") {
|
|
3758
|
+
return useContext(namespace);
|
|
3727
3759
|
}
|
|
3728
3760
|
|
|
3729
3761
|
//#endregion
|
|
@@ -4621,20 +4653,6 @@ const Single = {
|
|
|
4621
4653
|
//#endregion
|
|
4622
4654
|
//#region src/composables/useStep/index.ts
|
|
4623
4655
|
/**
|
|
4624
|
-
* @module useStep
|
|
4625
|
-
*
|
|
4626
|
-
* @remarks
|
|
4627
|
-
* Navigation composable that extends useSingle with first/last/next/prev/step methods.
|
|
4628
|
-
*
|
|
4629
|
-
* Key features:
|
|
4630
|
-
* - Configurable circular or bounded navigation
|
|
4631
|
-
* - Automatic disabled item skipping
|
|
4632
|
-
* - Arbitrary step counts (positive/negative)
|
|
4633
|
-
* - Perfect for wizards, carousels, pagination, onboarding flows
|
|
4634
|
-
*
|
|
4635
|
-
* Inheritance chain: useRegistry → useSelection → useSingle → useStep
|
|
4636
|
-
*/
|
|
4637
|
-
/**
|
|
4638
4656
|
* Creates a new step instance with navigation through items.
|
|
4639
4657
|
*
|
|
4640
4658
|
* Extends `createSingle` with `first()`, `last()`, `next()`, `prev()`, and `step(count)` methods
|
|
@@ -4930,21 +4948,6 @@ const Step = {
|
|
|
4930
4948
|
//#endregion
|
|
4931
4949
|
//#region src/composables/toReactive/index.ts
|
|
4932
4950
|
/**
|
|
4933
|
-
* @module toReactive
|
|
4934
|
-
*
|
|
4935
|
-
* @remarks
|
|
4936
|
-
* Utility function to convert values and refs into reactive proxies with ref unwrapping.
|
|
4937
|
-
*
|
|
4938
|
-
* Key features:
|
|
4939
|
-
* - Automatic ref unwrapping
|
|
4940
|
-
* - Deep reactive proxying
|
|
4941
|
-
* - Map and Set support with ref unwrapping
|
|
4942
|
-
* - Nested object/array reactivity
|
|
4943
|
-
* - Type preservation
|
|
4944
|
-
*
|
|
4945
|
-
* Perfect for creating reactive versions of plain objects while automatically unwrapping refs.
|
|
4946
|
-
*/
|
|
4947
|
-
/**
|
|
4948
4951
|
* Converts a `MaybeRef` to a `UnwrapNestedRefs`.
|
|
4949
4952
|
*
|
|
4950
4953
|
* @param objectRef The object to convert.
|
|
@@ -5065,21 +5068,6 @@ function toReactive(objectRef) {
|
|
|
5065
5068
|
//#endregion
|
|
5066
5069
|
//#region src/composables/useEventListener/index.ts
|
|
5067
5070
|
/**
|
|
5068
|
-
* @module useEventListener
|
|
5069
|
-
*
|
|
5070
|
-
* @remarks
|
|
5071
|
-
* Event listener composable with automatic cleanup on scope disposal.
|
|
5072
|
-
*
|
|
5073
|
-
* Key features:
|
|
5074
|
-
* - Supports Window, Document, and HTMLElement targets
|
|
5075
|
-
* - Reactive targets, events, and listeners
|
|
5076
|
-
* - Event options support (capture, passive, once)
|
|
5077
|
-
* - Automatic removeEventListener on unmount
|
|
5078
|
-
* - Multiple overloads for type safety
|
|
5079
|
-
*
|
|
5080
|
-
* Perfect for safely managing event listeners in Vue components.
|
|
5081
|
-
*/
|
|
5082
|
-
/**
|
|
5083
5071
|
* Attaches an event listener to a target.
|
|
5084
5072
|
*
|
|
5085
5073
|
* @param target The target to attach the event listener to.
|
|
@@ -5134,7 +5122,7 @@ function useEventListener(target, event, listener, options) {
|
|
|
5134
5122
|
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
5135
5123
|
*/
|
|
5136
5124
|
function useWindowEventListener(event, listener, options) {
|
|
5137
|
-
return useEventListener(window, event, listener, options);
|
|
5125
|
+
return IN_BROWSER ? useEventListener(window, event, listener, options) : () => {};
|
|
5138
5126
|
}
|
|
5139
5127
|
/**
|
|
5140
5128
|
* Attaches an event listener to the document.
|
|
@@ -5148,30 +5136,12 @@ function useWindowEventListener(event, listener, options) {
|
|
|
5148
5136
|
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
5149
5137
|
*/
|
|
5150
5138
|
function useDocumentEventListener(event, listener, options) {
|
|
5151
|
-
return useEventListener(document, event, listener, options);
|
|
5139
|
+
return IN_BROWSER ? useEventListener(document, event, listener, options) : () => {};
|
|
5152
5140
|
}
|
|
5153
5141
|
|
|
5154
5142
|
//#endregion
|
|
5155
5143
|
//#region src/composables/useBreakpoints/index.ts
|
|
5156
5144
|
/**
|
|
5157
|
-
* @module useBreakpoints
|
|
5158
|
-
*
|
|
5159
|
-
* @see https://0.vuetifyjs.com/composables/plugins/use-breakpoints
|
|
5160
|
-
*
|
|
5161
|
-
* @remarks
|
|
5162
|
-
* Responsive breakpoint detection composable with window resize handling.
|
|
5163
|
-
*
|
|
5164
|
-
* Key features:
|
|
5165
|
-
* - Window matchMedia integration
|
|
5166
|
-
* - Six built-in breakpoints (xs, sm, md, lg, xl, xxl)
|
|
5167
|
-
* - Automatic resize listener with cleanup
|
|
5168
|
-
* - SSR-safe (checks IN_BROWSER)
|
|
5169
|
-
* - Hydration-aware
|
|
5170
|
-
* - Custom breakpoint configuration
|
|
5171
|
-
*
|
|
5172
|
-
* Perfect for responsive layouts and conditional rendering based on screen size.
|
|
5173
|
-
*/
|
|
5174
|
-
/**
|
|
5175
5145
|
* Creates default breakpoint configuration.
|
|
5176
5146
|
*
|
|
5177
5147
|
* @returns The default breakpoint configuration object.
|
|
@@ -5417,25 +5387,217 @@ function useBreakpoints(namespace = "v0:breakpoints") {
|
|
|
5417
5387
|
}
|
|
5418
5388
|
|
|
5419
5389
|
//#endregion
|
|
5420
|
-
//#region src/composables/
|
|
5390
|
+
//#region src/composables/useClickOutside/index.ts
|
|
5421
5391
|
/**
|
|
5422
|
-
*
|
|
5392
|
+
* Detects clicks outside of the specified element(s).
|
|
5423
5393
|
*
|
|
5424
|
-
*
|
|
5394
|
+
* Uses two-phase detection (pointerdown → pointerup) to prevent false positives
|
|
5395
|
+
* when users drag from inside to outside an element.
|
|
5425
5396
|
*
|
|
5426
|
-
* @
|
|
5427
|
-
*
|
|
5397
|
+
* @param target Element ref(s) to detect clicks outside of. Accepts a single ref/getter or array of refs/getters.
|
|
5398
|
+
* @param handler Callback invoked when a click outside is detected.
|
|
5399
|
+
* @param options Configuration options.
|
|
5400
|
+
* @returns An object with methods to control the listener.
|
|
5428
5401
|
*
|
|
5429
|
-
*
|
|
5430
|
-
*
|
|
5431
|
-
*
|
|
5432
|
-
*
|
|
5433
|
-
*
|
|
5434
|
-
*
|
|
5435
|
-
*
|
|
5436
|
-
*
|
|
5437
|
-
*
|
|
5402
|
+
* @see https://0.vuetifyjs.com/composables/system/use-click-outside
|
|
5403
|
+
*
|
|
5404
|
+
* @example Native element ref
|
|
5405
|
+
* ```ts
|
|
5406
|
+
* const menuRef = useTemplateRef<HTMLElement>('menu')
|
|
5407
|
+
*
|
|
5408
|
+
* useClickOutside(menuRef, () => { isOpen.value = false })
|
|
5409
|
+
* ```
|
|
5410
|
+
*
|
|
5411
|
+
* @example Component ref (e.g., Atom)
|
|
5412
|
+
* ```ts
|
|
5413
|
+
* const atomRef = useTemplateRef<AtomExpose>('atom')
|
|
5414
|
+
*
|
|
5415
|
+
* // Pass the exposed element TemplateRef via getter
|
|
5416
|
+
* useClickOutside(
|
|
5417
|
+
* () => atomRef.value?.element,
|
|
5418
|
+
* () => { isOpen.value = false }
|
|
5419
|
+
* )
|
|
5420
|
+
* ```
|
|
5421
|
+
*
|
|
5422
|
+
* @example Multiple targets
|
|
5423
|
+
* ```ts
|
|
5424
|
+
* const popoverRef = useTemplateRef<AtomExpose>('popover')
|
|
5425
|
+
* const anchorRef = useTemplateRef<HTMLElement>('anchor')
|
|
5426
|
+
*
|
|
5427
|
+
* useClickOutside(
|
|
5428
|
+
* [() => popoverRef.value?.element, anchorRef],
|
|
5429
|
+
* () => { isOpen.value = false }
|
|
5430
|
+
* )
|
|
5431
|
+
* ```
|
|
5432
|
+
*
|
|
5433
|
+
* @example Ignoring elements (CSS selectors or refs)
|
|
5434
|
+
* ```ts
|
|
5435
|
+
* useClickOutside(
|
|
5436
|
+
* () => navRef.value?.element,
|
|
5437
|
+
* () => { isOpen.value = false },
|
|
5438
|
+
* { ignore: ['[data-app-bar]'] }
|
|
5439
|
+
* )
|
|
5440
|
+
* ```
|
|
5438
5441
|
*/
|
|
5442
|
+
function useClickOutside(target, handler, options = {}) {
|
|
5443
|
+
const { capture = true, touchScrollThreshold = 30, detectIframe = false, ignore = [] } = options;
|
|
5444
|
+
const isPaused = shallowRef(false);
|
|
5445
|
+
const isActive = toRef(() => !isPaused.value);
|
|
5446
|
+
let initialTarget = null;
|
|
5447
|
+
let startPosition = {
|
|
5448
|
+
x: 0,
|
|
5449
|
+
y: 0
|
|
5450
|
+
};
|
|
5451
|
+
let cleanupPointerDown;
|
|
5452
|
+
let cleanupPointerUp;
|
|
5453
|
+
let cleanupBlur;
|
|
5454
|
+
/**
|
|
5455
|
+
* Resolve target(s) to an array of HTMLElements.
|
|
5456
|
+
*/
|
|
5457
|
+
function getTargets() {
|
|
5458
|
+
return (Array.isArray(target) ? target : [target]).map((source) => toValue(source)).filter((el) => !/* @__PURE__ */ isNullOrUndefined(el));
|
|
5459
|
+
}
|
|
5460
|
+
/**
|
|
5461
|
+
* Resolve ignore targets to a tuple of [selectors, elements].
|
|
5462
|
+
* Called once per event to avoid repeated toValue() calls in hot path.
|
|
5463
|
+
*/
|
|
5464
|
+
function resolveIgnoreTargets() {
|
|
5465
|
+
const ignoreTargets = toValue(ignore);
|
|
5466
|
+
if (ignoreTargets.length === 0) return [[], []];
|
|
5467
|
+
const selectors = [];
|
|
5468
|
+
const elements = [];
|
|
5469
|
+
for (const ignoreTarget of ignoreTargets) if (/* @__PURE__ */ isString(ignoreTarget)) selectors.push(ignoreTarget);
|
|
5470
|
+
else {
|
|
5471
|
+
const ignoreEl = toValue(ignoreTarget);
|
|
5472
|
+
if (ignoreEl) elements.push(ignoreEl);
|
|
5473
|
+
}
|
|
5474
|
+
return [selectors, elements];
|
|
5475
|
+
}
|
|
5476
|
+
/**
|
|
5477
|
+
* Check if an element matches resolved ignore targets.
|
|
5478
|
+
*/
|
|
5479
|
+
function isIgnored(el, selectors, elements) {
|
|
5480
|
+
if (!el) return false;
|
|
5481
|
+
for (const selector of selectors) try {
|
|
5482
|
+
if (el.matches(selector) || !/* @__PURE__ */ isNull(el.closest(selector))) return true;
|
|
5483
|
+
} catch {}
|
|
5484
|
+
for (const ignoreEl of elements) if (ignoreEl === el || ignoreEl.contains(el)) return true;
|
|
5485
|
+
return false;
|
|
5486
|
+
}
|
|
5487
|
+
/**
|
|
5488
|
+
* Check if any element in the event path should be ignored.
|
|
5489
|
+
*/
|
|
5490
|
+
function shouldIgnore(path) {
|
|
5491
|
+
const [selectors, elements] = resolveIgnoreTargets();
|
|
5492
|
+
if (selectors.length === 0 && elements.length === 0) return false;
|
|
5493
|
+
return path.some((node) => node instanceof Element && isIgnored(node, selectors, elements));
|
|
5494
|
+
}
|
|
5495
|
+
/**
|
|
5496
|
+
* Check if the event target is outside all target elements.
|
|
5497
|
+
*/
|
|
5498
|
+
function isOutside(eventTarget) {
|
|
5499
|
+
if (!eventTarget) return false;
|
|
5500
|
+
if (!(eventTarget instanceof Node)) return false;
|
|
5501
|
+
const targets = getTargets();
|
|
5502
|
+
if (targets.length === 0) return false;
|
|
5503
|
+
return targets.every((el) => {
|
|
5504
|
+
return el !== eventTarget && !el.contains(eventTarget);
|
|
5505
|
+
});
|
|
5506
|
+
}
|
|
5507
|
+
/**
|
|
5508
|
+
* Validate that the target is still in the DOM.
|
|
5509
|
+
*/
|
|
5510
|
+
function isValidTarget(eventTarget) {
|
|
5511
|
+
if (!(eventTarget instanceof Element)) return false;
|
|
5512
|
+
if (!eventTarget.isConnected) return false;
|
|
5513
|
+
return true;
|
|
5514
|
+
}
|
|
5515
|
+
/**
|
|
5516
|
+
* Handle pointerdown - store initial target and position.
|
|
5517
|
+
*/
|
|
5518
|
+
function onPointerDown(event) {
|
|
5519
|
+
if (isPaused.value) return;
|
|
5520
|
+
if (event.defaultPrevented) return;
|
|
5521
|
+
initialTarget = event.composedPath()[0] ?? event.target;
|
|
5522
|
+
startPosition = {
|
|
5523
|
+
x: event.clientX,
|
|
5524
|
+
y: event.clientY
|
|
5525
|
+
};
|
|
5526
|
+
}
|
|
5527
|
+
/**
|
|
5528
|
+
* Handle pointerup - check if it's an outside click.
|
|
5529
|
+
*/
|
|
5530
|
+
function onPointerUp(event) {
|
|
5531
|
+
if (isPaused.value) return;
|
|
5532
|
+
if (event.defaultPrevented) return;
|
|
5533
|
+
if (!initialTarget) return;
|
|
5534
|
+
const pointerdownTarget = initialTarget;
|
|
5535
|
+
initialTarget = null;
|
|
5536
|
+
if (!isValidTarget(pointerdownTarget)) return;
|
|
5537
|
+
const path = event.composedPath();
|
|
5538
|
+
const pointerupTarget = path[0] ?? event.target;
|
|
5539
|
+
if (event.pointerType === "touch") {
|
|
5540
|
+
const dx = Math.abs(event.clientX - startPosition.x);
|
|
5541
|
+
const dy = Math.abs(event.clientY - startPosition.y);
|
|
5542
|
+
if (dx >= touchScrollThreshold || dy >= touchScrollThreshold) return;
|
|
5543
|
+
}
|
|
5544
|
+
if (isOutside(pointerdownTarget) && isOutside(pointerupTarget) && !shouldIgnore(path)) handler(event);
|
|
5545
|
+
}
|
|
5546
|
+
/**
|
|
5547
|
+
* Handle window blur - detect focus moving to iframe.
|
|
5548
|
+
*/
|
|
5549
|
+
function onBlur(event) {
|
|
5550
|
+
if (isPaused.value) return;
|
|
5551
|
+
if (event.defaultPrevented) return;
|
|
5552
|
+
if (document.activeElement instanceof HTMLIFrameElement) {
|
|
5553
|
+
const iframeIsOutside = getTargets().every((el) => !el.contains(document.activeElement));
|
|
5554
|
+
const [selectors, elements] = resolveIgnoreTargets();
|
|
5555
|
+
if (iframeIsOutside && !isIgnored(document.activeElement, selectors, elements)) handler(event);
|
|
5556
|
+
}
|
|
5557
|
+
}
|
|
5558
|
+
function setup() {
|
|
5559
|
+
cleanupPointerDown = useDocumentEventListener("pointerdown", onPointerDown, capture);
|
|
5560
|
+
cleanupPointerUp = useDocumentEventListener("pointerup", onPointerUp, capture);
|
|
5561
|
+
if (!detectIframe) return;
|
|
5562
|
+
cleanupBlur = useWindowEventListener("blur", onBlur, capture);
|
|
5563
|
+
}
|
|
5564
|
+
function cleanup() {
|
|
5565
|
+
cleanupPointerDown?.();
|
|
5566
|
+
cleanupPointerUp?.();
|
|
5567
|
+
cleanupBlur?.();
|
|
5568
|
+
cleanupPointerDown = void 0;
|
|
5569
|
+
cleanupPointerUp = void 0;
|
|
5570
|
+
cleanupBlur = void 0;
|
|
5571
|
+
}
|
|
5572
|
+
function pause() {
|
|
5573
|
+
if (isPaused.value) return;
|
|
5574
|
+
isPaused.value = true;
|
|
5575
|
+
initialTarget = null;
|
|
5576
|
+
cleanup();
|
|
5577
|
+
}
|
|
5578
|
+
function resume() {
|
|
5579
|
+
if (!isPaused.value) return;
|
|
5580
|
+
isPaused.value = false;
|
|
5581
|
+
setup();
|
|
5582
|
+
}
|
|
5583
|
+
function stop() {
|
|
5584
|
+
isPaused.value = true;
|
|
5585
|
+
initialTarget = null;
|
|
5586
|
+
cleanup();
|
|
5587
|
+
}
|
|
5588
|
+
setup();
|
|
5589
|
+
onScopeDispose(stop, true);
|
|
5590
|
+
return {
|
|
5591
|
+
isActive: shallowReadonly(isActive),
|
|
5592
|
+
isPaused: shallowReadonly(isPaused),
|
|
5593
|
+
pause,
|
|
5594
|
+
resume,
|
|
5595
|
+
stop
|
|
5596
|
+
};
|
|
5597
|
+
}
|
|
5598
|
+
|
|
5599
|
+
//#endregion
|
|
5600
|
+
//#region src/composables/useFeatures/index.ts
|
|
5439
5601
|
/**
|
|
5440
5602
|
* Creates a new features instance.
|
|
5441
5603
|
*
|
|
@@ -5596,22 +5758,6 @@ function useFeatures(namespace = "v0:features") {
|
|
|
5596
5758
|
|
|
5597
5759
|
//#endregion
|
|
5598
5760
|
//#region src/composables/useFilter/index.ts
|
|
5599
|
-
/**
|
|
5600
|
-
* @module useFilter
|
|
5601
|
-
*
|
|
5602
|
-
* @remarks
|
|
5603
|
-
* Reactive array filtering composable with multiple filter modes.
|
|
5604
|
-
*
|
|
5605
|
-
* Key features:
|
|
5606
|
-
* - Four filter modes: some, every, union, intersection
|
|
5607
|
-
* - Case-insensitive filtering
|
|
5608
|
-
* - Custom filter functions
|
|
5609
|
-
* - Reactive updates
|
|
5610
|
-
* - Context-based DI support
|
|
5611
|
-
* - Perfect for search, multi-criteria filtering
|
|
5612
|
-
*
|
|
5613
|
-
* Filters arrays based on query strings with configurable matching strategies.
|
|
5614
|
-
*/
|
|
5615
5761
|
function defaultFilter(query, item, keys, mode = "some") {
|
|
5616
5762
|
const queries = Array.isArray(query) ? query.map((q) => String(q).toLowerCase()) : [String(query).toLowerCase()];
|
|
5617
5763
|
function match(value, q) {
|
|
@@ -5765,22 +5911,6 @@ function useFilterContext(namespace = "v0:filter") {
|
|
|
5765
5911
|
//#endregion
|
|
5766
5912
|
//#region src/composables/useForm/index.ts
|
|
5767
5913
|
/**
|
|
5768
|
-
* @module useForm
|
|
5769
|
-
*
|
|
5770
|
-
* @remarks
|
|
5771
|
-
* Form validation composable with async rule support and multiple validation modes.
|
|
5772
|
-
*
|
|
5773
|
-
* Key features:
|
|
5774
|
-
* - Sync and async validation rules
|
|
5775
|
-
* - Multiple validation modes (submit, change, combined)
|
|
5776
|
-
* - Tri-state isValid (null/true/false)
|
|
5777
|
-
* - isPristine tracking
|
|
5778
|
-
* - Silent validation mode
|
|
5779
|
-
* - Form-level validation and reset
|
|
5780
|
-
*
|
|
5781
|
-
* Each field is registered with validation rules and tracks its own state independently.
|
|
5782
|
-
*/
|
|
5783
|
-
/**
|
|
5784
5914
|
* Creates a new form instance.
|
|
5785
5915
|
*
|
|
5786
5916
|
* @param options The options for the form instance.
|
|
@@ -5986,22 +6116,6 @@ function useForm(namespace = "v0:form") {
|
|
|
5986
6116
|
//#endregion
|
|
5987
6117
|
//#region src/composables/useIntersectionObserver/index.ts
|
|
5988
6118
|
/**
|
|
5989
|
-
* @module useIntersectionObserver
|
|
5990
|
-
*
|
|
5991
|
-
* @remarks
|
|
5992
|
-
* IntersectionObserver composable with lifecycle management.
|
|
5993
|
-
*
|
|
5994
|
-
* Key features:
|
|
5995
|
-
* - IntersectionObserver API wrapper
|
|
5996
|
-
* - Pause/resume/stop functionality
|
|
5997
|
-
* - Automatic cleanup on unmount
|
|
5998
|
-
* - SSR-safe (checks SUPPORTS_INTERSECTION_OBSERVER)
|
|
5999
|
-
* - Hydration-aware
|
|
6000
|
-
* - Immediate callback option
|
|
6001
|
-
*
|
|
6002
|
-
* Perfect for lazy loading, infinite scroll, and visibility detection.
|
|
6003
|
-
*/
|
|
6004
|
-
/**
|
|
6005
6119
|
* A composable that uses the Intersection Observer API to detect when an element
|
|
6006
6120
|
* is visible in the viewport.
|
|
6007
6121
|
*
|
|
@@ -6042,12 +6156,14 @@ function useForm(namespace = "v0:form") {
|
|
|
6042
6156
|
*/
|
|
6043
6157
|
function useIntersectionObserver(target, callback, options = {}) {
|
|
6044
6158
|
const { isHydrated } = useHydration();
|
|
6159
|
+
const targetRef = isRef(target) ? target : shallowRef(target);
|
|
6045
6160
|
const observer = shallowRef();
|
|
6046
6161
|
const isPaused = shallowRef(false);
|
|
6047
6162
|
const isIntersecting = shallowRef(false);
|
|
6048
6163
|
const isActive = toRef(() => !!observer.value);
|
|
6049
6164
|
function setup() {
|
|
6050
|
-
if (
|
|
6165
|
+
if (observer.value === null) return;
|
|
6166
|
+
if (!isHydrated.value || !SUPPORTS_INTERSECTION_OBSERVER || !targetRef.value || isPaused.value) return;
|
|
6051
6167
|
observer.value = new IntersectionObserver((entries) => {
|
|
6052
6168
|
const transformedEntries = entries.map((entry) => ({
|
|
6053
6169
|
boundingClientRect: entry.boundingClientRect,
|
|
@@ -6061,26 +6177,29 @@ function useIntersectionObserver(target, callback, options = {}) {
|
|
|
6061
6177
|
const latestEntry = transformedEntries.at(-1);
|
|
6062
6178
|
if (latestEntry) isIntersecting.value = latestEntry.isIntersecting;
|
|
6063
6179
|
callback(transformedEntries);
|
|
6180
|
+
if (options.once && latestEntry?.isIntersecting) stop();
|
|
6064
6181
|
}, {
|
|
6065
6182
|
root: options.root || null,
|
|
6066
6183
|
rootMargin: options.rootMargin || "0px",
|
|
6067
6184
|
threshold: options.threshold || 0
|
|
6068
6185
|
});
|
|
6069
|
-
observer.value.observe(
|
|
6186
|
+
observer.value.observe(targetRef.value);
|
|
6070
6187
|
if (options.immediate) callback([{
|
|
6071
|
-
boundingClientRect:
|
|
6188
|
+
boundingClientRect: targetRef.value.getBoundingClientRect(),
|
|
6072
6189
|
intersectionRatio: 0,
|
|
6073
6190
|
intersectionRect: new DOMRect(0, 0, 0, 0),
|
|
6074
6191
|
isIntersecting: false,
|
|
6075
6192
|
rootBounds: null,
|
|
6076
|
-
target:
|
|
6193
|
+
target: targetRef.value,
|
|
6077
6194
|
time: performance.now()
|
|
6078
6195
|
}]);
|
|
6079
6196
|
}
|
|
6080
|
-
|
|
6197
|
+
watchEffect(() => {
|
|
6198
|
+
const hydrated = isHydrated.value;
|
|
6199
|
+
const target$1 = targetRef.value;
|
|
6081
6200
|
cleanup();
|
|
6082
|
-
setup();
|
|
6083
|
-
}
|
|
6201
|
+
if (hydrated && target$1) setup();
|
|
6202
|
+
});
|
|
6084
6203
|
function cleanup() {
|
|
6085
6204
|
if (observer.value) {
|
|
6086
6205
|
observer.value.disconnect();
|
|
@@ -6098,6 +6217,7 @@ function useIntersectionObserver(target, callback, options = {}) {
|
|
|
6098
6217
|
}
|
|
6099
6218
|
function stop() {
|
|
6100
6219
|
cleanup();
|
|
6220
|
+
observer.value = null;
|
|
6101
6221
|
}
|
|
6102
6222
|
onScopeDispose(stop, true);
|
|
6103
6223
|
return {
|
|
@@ -6169,20 +6289,6 @@ function useElementIntersection(target, options = {}) {
|
|
|
6169
6289
|
//#endregion
|
|
6170
6290
|
//#region src/composables/useKeydown/index.ts
|
|
6171
6291
|
/**
|
|
6172
|
-
* @module useKeydown
|
|
6173
|
-
*
|
|
6174
|
-
* @remarks
|
|
6175
|
-
* Keydown event listener composable with key filtering.
|
|
6176
|
-
*
|
|
6177
|
-
* Key features:
|
|
6178
|
-
* - Key-specific event handling
|
|
6179
|
-
* - preventDefault and stopPropagation options
|
|
6180
|
-
* - Automatic cleanup on scope disposal
|
|
6181
|
-
* - Built on useEventListener for consistent event handling
|
|
6182
|
-
*
|
|
6183
|
-
* Simplified wrapper around useEventListener for keyboard interactions.
|
|
6184
|
-
*/
|
|
6185
|
-
/**
|
|
6186
6292
|
* A composable that adds a keydown event listener to the document.
|
|
6187
6293
|
*
|
|
6188
6294
|
* @param handlers The key handlers to add.
|
|
@@ -6194,6 +6300,10 @@ function useElementIntersection(target, options = {}) {
|
|
|
6194
6300
|
* ```ts
|
|
6195
6301
|
* import { useKeydown } from '@vuetify/v0'
|
|
6196
6302
|
*
|
|
6303
|
+
* // Single handler
|
|
6304
|
+
* useKeydown({ key: 'Escape', handler: () => console.log('Escape pressed') })
|
|
6305
|
+
*
|
|
6306
|
+
* // Multiple handlers
|
|
6197
6307
|
* const { isActive, start, stop } = useKeydown([
|
|
6198
6308
|
* { key: 'Enter', handler: () => console.log('Enter pressed') },
|
|
6199
6309
|
* { key: 'Escape', handler: () => console.log('Escape pressed'), preventDefault: true },
|
|
@@ -6238,22 +6348,6 @@ function useKeydown(handlers) {
|
|
|
6238
6348
|
//#endregion
|
|
6239
6349
|
//#region src/composables/useMutationObserver/index.ts
|
|
6240
6350
|
/**
|
|
6241
|
-
* @module useMutationObserver
|
|
6242
|
-
*
|
|
6243
|
-
* @remarks
|
|
6244
|
-
* MutationObserver composable with lifecycle management.
|
|
6245
|
-
*
|
|
6246
|
-
* Key features:
|
|
6247
|
-
* - MutationObserver API wrapper
|
|
6248
|
-
* - Pause/resume/stop functionality
|
|
6249
|
-
* - Automatic cleanup on unmount
|
|
6250
|
-
* - SSR-safe (checks SUPPORTS_MUTATION_OBSERVER)
|
|
6251
|
-
* - Hydration-aware
|
|
6252
|
-
* - Configurable observation options (childList, attributes, characterData, etc.)
|
|
6253
|
-
*
|
|
6254
|
-
* Perfect for detecting DOM changes and responding to mutations.
|
|
6255
|
-
*/
|
|
6256
|
-
/**
|
|
6257
6351
|
* A composable that uses the Mutation Observer API to detect changes in the DOM.
|
|
6258
6352
|
*
|
|
6259
6353
|
* @param target The element to observe.
|
|
@@ -6300,7 +6394,7 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6300
6394
|
const { isHydrated } = useHydration();
|
|
6301
6395
|
const observer = shallowRef();
|
|
6302
6396
|
const isPaused = shallowRef(false);
|
|
6303
|
-
const isActive =
|
|
6397
|
+
const isActive = toRef(() => !!observer.value);
|
|
6304
6398
|
const observerOptions = {
|
|
6305
6399
|
childList: options.childList ?? true,
|
|
6306
6400
|
attributes: options.attributes ?? false,
|
|
@@ -6311,6 +6405,7 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6311
6405
|
attributeFilter: options.attributeFilter
|
|
6312
6406
|
};
|
|
6313
6407
|
function setup() {
|
|
6408
|
+
if (observer.value === null) return;
|
|
6314
6409
|
if (!isHydrated.value || !SUPPORTS_MUTATION_OBSERVER || !target.value || isPaused.value) return;
|
|
6315
6410
|
observer.value = new MutationObserver((mutations) => {
|
|
6316
6411
|
callback(mutations.map((mutation) => ({
|
|
@@ -6324,6 +6419,7 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6324
6419
|
attributeNamespace: mutation.attributeNamespace,
|
|
6325
6420
|
oldValue: mutation.oldValue
|
|
6326
6421
|
})));
|
|
6422
|
+
if (options.once) stop();
|
|
6327
6423
|
});
|
|
6328
6424
|
observer.value.observe(target.value, observerOptions);
|
|
6329
6425
|
if (options.immediate) {
|
|
@@ -6344,12 +6440,15 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6344
6440
|
attributeNamespace: null,
|
|
6345
6441
|
oldValue: null
|
|
6346
6442
|
}]);
|
|
6443
|
+
if (options.once) stop();
|
|
6347
6444
|
}
|
|
6348
6445
|
}
|
|
6349
|
-
|
|
6446
|
+
watchEffect(() => {
|
|
6447
|
+
const hydrated = isHydrated.value;
|
|
6448
|
+
const el = target.value;
|
|
6350
6449
|
cleanup();
|
|
6351
|
-
setup();
|
|
6352
|
-
}
|
|
6450
|
+
if (hydrated && el) setup();
|
|
6451
|
+
});
|
|
6353
6452
|
function cleanup() {
|
|
6354
6453
|
if (observer.value) {
|
|
6355
6454
|
observer.value.disconnect();
|
|
@@ -6366,6 +6465,7 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6366
6465
|
}
|
|
6367
6466
|
function stop() {
|
|
6368
6467
|
cleanup();
|
|
6468
|
+
observer.value = null;
|
|
6369
6469
|
}
|
|
6370
6470
|
onScopeDispose(stop, true);
|
|
6371
6471
|
return {
|
|
@@ -6398,23 +6498,6 @@ var Vuetify0PermissionAdapter = class extends PermissionAdapter {
|
|
|
6398
6498
|
//#endregion
|
|
6399
6499
|
//#region src/composables/usePermissions/index.ts
|
|
6400
6500
|
/**
|
|
6401
|
-
* @module usePermissions
|
|
6402
|
-
*
|
|
6403
|
-
* @see https://0.vuetifyjs.com/composables/plugins/use-permissions
|
|
6404
|
-
*
|
|
6405
|
-
* @remarks
|
|
6406
|
-
* Permission management composable with support for RBAC and ABAC patterns.
|
|
6407
|
-
*
|
|
6408
|
-
* Key features:
|
|
6409
|
-
* - Role-Based Access Control (RBAC) support
|
|
6410
|
-
* - Attribute-Based Access Control (ABAC) with context
|
|
6411
|
-
* - Functional permission conditions
|
|
6412
|
-
* - Token-based permission storage
|
|
6413
|
-
* - Adapter pattern for custom permission systems
|
|
6414
|
-
*
|
|
6415
|
-
* Built on useTokens for flexible permission configuration.
|
|
6416
|
-
*/
|
|
6417
|
-
/**
|
|
6418
6501
|
* Creates a new permissions instance.
|
|
6419
6502
|
*
|
|
6420
6503
|
* @param options The options for the permissions instance.
|
|
@@ -6561,21 +6644,6 @@ function usePermissions(namespace = "v0:permissions") {
|
|
|
6561
6644
|
//#endregion
|
|
6562
6645
|
//#region src/composables/useQueue/index.ts
|
|
6563
6646
|
/**
|
|
6564
|
-
* @module useQueue
|
|
6565
|
-
*
|
|
6566
|
-
* @remarks
|
|
6567
|
-
* A queue composable for managing time-based collections with:
|
|
6568
|
-
* - Automatic timeout-based removal
|
|
6569
|
-
* - Pause/resume functionality
|
|
6570
|
-
* - FIFO (First In, First Out) ordering
|
|
6571
|
-
* - Manual dismissal support
|
|
6572
|
-
* - Queue progression management
|
|
6573
|
-
*
|
|
6574
|
-
* Built on top of useRegistry, the queue automatically manages timeouts for tickets,
|
|
6575
|
-
* ensuring only the first ticket in the queue is active at any time. When an ticket
|
|
6576
|
-
* expires or is removed, the next ticket in the queue automatically becomes active.
|
|
6577
|
-
*/
|
|
6578
|
-
/**
|
|
6579
6647
|
* Creates a new queue instance
|
|
6580
6648
|
*
|
|
6581
6649
|
* @param options The options for the queue instance
|
|
@@ -6777,21 +6845,6 @@ var MemoryAdapter = class {
|
|
|
6777
6845
|
//#endregion
|
|
6778
6846
|
//#region src/composables/useStorage/index.ts
|
|
6779
6847
|
/**
|
|
6780
|
-
* @module useStorage
|
|
6781
|
-
*
|
|
6782
|
-
* @remarks
|
|
6783
|
-
* Reactive storage composable with adapter pattern for localStorage, sessionStorage, or memory.
|
|
6784
|
-
*
|
|
6785
|
-
* Key features:
|
|
6786
|
-
* - Reactive refs that sync with storage
|
|
6787
|
-
* - localStorage, sessionStorage, and memory adapters
|
|
6788
|
-
* - Custom serialization support
|
|
6789
|
-
* - SSR fallback to memory adapter
|
|
6790
|
-
* - Automatic cleanup on remove/clear
|
|
6791
|
-
*
|
|
6792
|
-
* Uses adapter pattern to abstract storage implementation details.
|
|
6793
|
-
*/
|
|
6794
|
-
/**
|
|
6795
6848
|
* Creates a new storage instance.
|
|
6796
6849
|
*
|
|
6797
6850
|
* @param options The options for the storage instance.
|
|
@@ -7028,24 +7081,6 @@ var Vuetify0ThemeAdapter = class extends ThemeAdapter {
|
|
|
7028
7081
|
//#endregion
|
|
7029
7082
|
//#region src/composables/useTheme/index.ts
|
|
7030
7083
|
/**
|
|
7031
|
-
* @module useTheme
|
|
7032
|
-
*
|
|
7033
|
-
* @see https://0.vuetifyjs.com/composables/plugins/use-theme
|
|
7034
|
-
*
|
|
7035
|
-
* @remarks
|
|
7036
|
-
* Theme management composable with token resolution and CSS variable injection.
|
|
7037
|
-
*
|
|
7038
|
-
* Key features:
|
|
7039
|
-
* - Single-selection theme switching (extends createSingle)
|
|
7040
|
-
* - Token alias resolution via useTokens
|
|
7041
|
-
* - Lazy theme loading (compute colors only when selected)
|
|
7042
|
-
* - CSS variable generation via adapter pattern
|
|
7043
|
-
* - SSR support with head integration
|
|
7044
|
-
* - Theme cycling
|
|
7045
|
-
*
|
|
7046
|
-
* Integrates with createSingle for selection and useTokens for color resolution.
|
|
7047
|
-
*/
|
|
7048
|
-
/**
|
|
7049
7084
|
* Creates a new theme instance.
|
|
7050
7085
|
*
|
|
7051
7086
|
* @param options The options for the theme instance.
|
|
@@ -7266,21 +7301,6 @@ function useTheme(namespace = "v0:theme") {
|
|
|
7266
7301
|
//#endregion
|
|
7267
7302
|
//#region src/composables/useTimeline/index.ts
|
|
7268
7303
|
/**
|
|
7269
|
-
* @module useTimeline
|
|
7270
|
-
*
|
|
7271
|
-
* @remarks
|
|
7272
|
-
* Bounded undo/redo system with overflow management.
|
|
7273
|
-
*
|
|
7274
|
-
* Key features:
|
|
7275
|
-
* - Fixed-size history (default: 10 items)
|
|
7276
|
-
* - Undo/redo stack management
|
|
7277
|
-
* - Overflow queue (preserves oldest items)
|
|
7278
|
-
* - Automatic reindexing after operations
|
|
7279
|
-
* - Perfect for command pattern, history tracking
|
|
7280
|
-
*
|
|
7281
|
-
* Extends useRegistry with temporal navigation capabilities.
|
|
7282
|
-
*/
|
|
7283
|
-
/**
|
|
7284
7304
|
* Creates a new timeline instance.
|
|
7285
7305
|
*
|
|
7286
7306
|
* @param _options The options for the timeline instance.
|
|
@@ -7415,24 +7435,6 @@ function useTimeline(namespace = "v0:timeline") {
|
|
|
7415
7435
|
//#endregion
|
|
7416
7436
|
//#region src/composables/useToggleScope/index.ts
|
|
7417
7437
|
/**
|
|
7418
|
-
* @module useToggleScope
|
|
7419
|
-
*
|
|
7420
|
-
* @remarks
|
|
7421
|
-
* Conditionally manages an effect scope based on a reactive boolean condition.
|
|
7422
|
-
* When the source becomes true, creates and runs an effect scope. When false, stops the scope.
|
|
7423
|
-
* All reactive effects created within the scoped function are automatically cleaned up on deactivation.
|
|
7424
|
-
*
|
|
7425
|
-
* Key features:
|
|
7426
|
-
* - Uses Vue's effectScope for efficient reactive effect lifecycle management
|
|
7427
|
-
* - Automatic cleanup when condition becomes false
|
|
7428
|
-
* - Supports optional reset callback for scope restart capability
|
|
7429
|
-
* - Handles rapid toggling and parent scope disposal safely
|
|
7430
|
-
* - SSR-safe (effectScope is part of Vue core)
|
|
7431
|
-
*
|
|
7432
|
-
* Perfect for conditional side effects, feature flags, and performance optimization
|
|
7433
|
-
* by only running reactive effects when needed.
|
|
7434
|
-
*/
|
|
7435
|
-
/**
|
|
7436
7438
|
* Conditionally manages an effect scope based on a reactive boolean source.
|
|
7437
7439
|
*
|
|
7438
7440
|
* @param source A reactive boolean value or getter that controls the scope lifecycle
|
|
@@ -7514,24 +7516,6 @@ function useToggleScope(source, fn) {
|
|
|
7514
7516
|
//#endregion
|
|
7515
7517
|
//#region src/composables/useVirtual/index.ts
|
|
7516
7518
|
/**
|
|
7517
|
-
* @module useVirtual
|
|
7518
|
-
*
|
|
7519
|
-
* @remarks
|
|
7520
|
-
* Virtual scrolling composable for efficiently rendering large lists.
|
|
7521
|
-
*
|
|
7522
|
-
* Key features:
|
|
7523
|
-
* - Renders only visible items (viewport + overscan)
|
|
7524
|
-
* - Dynamic or fixed item heights
|
|
7525
|
-
* - SSR-safe (checks IN_BROWSER)
|
|
7526
|
-
* - Bidirectional scrolling (forward/reverse for chat apps)
|
|
7527
|
-
* - Scroll anchoring (maintains position across data changes)
|
|
7528
|
-
* - Edge detection for infinite scroll
|
|
7529
|
-
* - iOS momentum and elastic scrolling
|
|
7530
|
-
* - Configurable overscan (extra items rendered for smooth scrolling)
|
|
7531
|
-
*
|
|
7532
|
-
* Perfect for large data sets, chat apps, and infinite scroll implementations.
|
|
7533
|
-
*/
|
|
7534
|
-
/**
|
|
7535
7519
|
* Virtual scrolling composable for efficiently rendering large lists
|
|
7536
7520
|
*
|
|
7537
7521
|
* @param items Reactive array of items to virtualize
|
|
@@ -7772,7 +7756,7 @@ function useVirtual(items, _options = {}) {
|
|
|
7772
7756
|
cancelAnimationFrame(raf);
|
|
7773
7757
|
cancelAnimationFrame(rebuildRaf);
|
|
7774
7758
|
cancelAnimationFrame(edgeRaf);
|
|
7775
|
-
});
|
|
7759
|
+
}, true);
|
|
7776
7760
|
return {
|
|
7777
7761
|
element,
|
|
7778
7762
|
items: computedItems,
|
|
@@ -7788,4 +7772,4 @@ function useVirtual(items, _options = {}) {
|
|
|
7788
7772
|
}
|
|
7789
7773
|
|
|
7790
7774
|
//#endregion
|
|
7791
|
-
export { Atom_default as Atom, Avatar, AvatarFallback_default as AvatarFallback, AvatarImage_default as AvatarImage, AvatarRoot_default as AvatarRoot, COMMON_ELEMENTS, ConsolaLoggerAdapter, ExpansionPanel, ExpansionPanelActivator_default as ExpansionPanelActivator, ExpansionPanelContent_default as ExpansionPanelContent, ExpansionPanelHeader_default as ExpansionPanelHeader, ExpansionPanelItem_default as ExpansionPanelItem, ExpansionPanelRoot_default as ExpansionPanelRoot, Group, GroupItem_default as GroupItem, GroupRoot_default as GroupRoot, IN_BROWSER, MemoryAdapter, Pagination, PaginationEllipsis_default as PaginationEllipsis, PaginationFirst_default as PaginationFirst, PaginationItem_default as PaginationItem, PaginationLast_default as PaginationLast, PaginationNext_default as PaginationNext, PaginationPrev_default as PaginationPrev, PaginationRoot_default as PaginationRoot, PaginationStatus_default as PaginationStatus, PermissionAdapter, PinoLoggerAdapter, Popover, PopoverAnchor_default as PopoverAnchor, PopoverContent_default as PopoverContent, PopoverRoot_default as PopoverRoot, SELF_CLOSING_TAGS, SUPPORTS_INTERSECTION_OBSERVER, SUPPORTS_MATCH_MEDIA, SUPPORTS_MUTATION_OBSERVER, SUPPORTS_OBSERVER, SUPPORTS_TOUCH, Selection, SelectionItem_default as SelectionItem, SelectionRoot_default as SelectionRoot, Single, SingleItem_default as SingleItem, SingleRoot_default as SingleRoot, Step, StepItem_default as StepItem, StepRoot_default as StepRoot, Vuetify0LocaleAdapter, Vuetify0LoggerAdapter, Vuetify0ThemeAdapter, __LOGGER_ENABLED__, clamp, createBreakpoints, createBreakpointsContext, createBreakpointsPlugin, createContext, createFallbackHydration, createFeatures, createFeaturesContext, createFeaturesPlugin, createFilter, createFilterContext, 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, isSymbol, isUndefined, mergeDeep, provideAvatarContext, provideContext, provideExpansionPanelItem, provideExpansionPanelSelection, provideGroupRoot, providePaginationControls, providePaginationItems, providePaginationRoot, providePopoverContext, provideSelectionRoot, provideSingleRoot, provideStepRoot, range, toArray, toReactive, useAvatarRoot, useBreakpoints, useContext, useDocumentEventListener, useElementIntersection, useElementSize, useEventListener, useExpansionPanelItem, useExpansionPanelRoot, useFeatures, useFilter, useFilterContext, useForm, useGroup, useGroupRoot, useHydration, useIntersectionObserver, useKeydown, useLocale, useLogger, useMutationObserver, useOverflow, usePagination, usePaginationControls, usePaginationItems, usePaginationRoot, usePermissions, usePopoverContext, useProxyModel, useProxyRegistry, useQueue, useRegistry, useResizeObserver, useSelection, useSelectionRoot, useSingle, useSingleRoot, useStep, useStepRoot, useStorage, useTheme, useTimeline, useToggleScope, useTokens, useVirtual, useWindowEventListener, version };
|
|
7775
|
+
export { Atom_default as Atom, Avatar, AvatarFallback_default as AvatarFallback, AvatarImage_default as AvatarImage, AvatarRoot_default as AvatarRoot, COMMON_ELEMENTS, ConsolaLoggerAdapter, ExpansionPanel, ExpansionPanelActivator_default as ExpansionPanelActivator, ExpansionPanelContent_default as ExpansionPanelContent, ExpansionPanelHeader_default as ExpansionPanelHeader, ExpansionPanelItem_default as ExpansionPanelItem, ExpansionPanelRoot_default as ExpansionPanelRoot, Group, GroupItem_default as GroupItem, GroupRoot_default as GroupRoot, IN_BROWSER, MemoryAdapter, Pagination, PaginationEllipsis_default as PaginationEllipsis, PaginationFirst_default as PaginationFirst, PaginationItem_default as PaginationItem, PaginationLast_default as PaginationLast, PaginationNext_default as PaginationNext, PaginationPrev_default as PaginationPrev, PaginationRoot_default as PaginationRoot, PaginationStatus_default as PaginationStatus, PermissionAdapter, PinoLoggerAdapter, Popover, PopoverAnchor_default as PopoverAnchor, PopoverContent_default as PopoverContent, PopoverRoot_default as PopoverRoot, SELF_CLOSING_TAGS, SUPPORTS_INTERSECTION_OBSERVER, SUPPORTS_MATCH_MEDIA, SUPPORTS_MUTATION_OBSERVER, SUPPORTS_OBSERVER, SUPPORTS_TOUCH, Selection, SelectionItem_default as SelectionItem, SelectionRoot_default as SelectionRoot, Single, SingleItem_default as SingleItem, SingleRoot_default as SingleRoot, Step, StepItem_default as StepItem, StepRoot_default as StepRoot, Vuetify0LocaleAdapter, Vuetify0LoggerAdapter, Vuetify0ThemeAdapter, __LOGGER_ENABLED__, clamp, createBreakpoints, createBreakpointsContext, createBreakpointsPlugin, createContext, createFallbackHydration, createFeatures, createFeaturesContext, createFeaturesPlugin, createFilter, createFilterContext, 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, isSymbol, isUndefined, mergeDeep, provideAvatarContext, provideContext, provideExpansionPanelItem, provideExpansionPanelSelection, provideGroupRoot, providePaginationControls, providePaginationItems, providePaginationRoot, providePopoverContext, provideSelectionRoot, provideSingleRoot, provideStepRoot, range, toArray, toReactive, useAvatarRoot, useBreakpoints, useClickOutside, useContext, useDocumentEventListener, useElementIntersection, useElementSize, useEventListener, useExpansionPanelItem, useExpansionPanelRoot, useFeatures, useFilter, useFilterContext, useForm, useGroup, useGroupRoot, useHydration, useIntersectionObserver, useKeydown, useLocale, useLogger, useMutationObserver, useOverflow, usePagination, usePaginationControls, usePaginationItems, usePaginationRoot, usePermissions, usePopoverContext, useProxyModel, useProxyRegistry, useQueue, useRegistry, useResizeObserver, useSelection, useSelectionRoot, useSingle, useSingleRoot, useStep, useStepRoot, useStorage, useTheme, useTimeline, useToggleScope, useTokens, useVirtual, useWindowEventListener, version };
|