@vuetify/v0 0.0.16 → 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 +1801 -1604
- package/dist/components/index.d.mts +4 -4
- package/dist/components/index.mjs +6 -6
- package/dist/{components-Dk00OFL2.mjs → components-D590hSY0.mjs} +151 -54
- package/dist/composables/index.d.mts +4 -4
- package/dist/composables/index.mjs +5 -5
- package/dist/{composables-YOUVfUsn.mjs → composables-FE6B8JUW.mjs} +370 -303
- package/dist/constants/index.d.mts +1 -1
- package/dist/constants/index.mjs +3 -3
- package/dist/{globals-Rnihe4SF.mjs → globals-exvZ8fiO.mjs} +1 -1
- package/dist/index-4jSy8KIt.d.mts +73 -0
- package/dist/{index-BzW68rBC.d.mts → index-BYyEPh1S.d.mts} +227 -17
- package/dist/index-CjzlIAtF.d.mts +296 -0
- package/dist/{index-BeJMYhId.d.mts → index-DahjxaTj.d.mts} +899 -136
- package/dist/{index-BulceeMA.d.mts → index-Gr6XPRWt.d.mts} +50 -18
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +8 -8
- package/dist/types/index.d.mts +1 -1
- package/dist/{useStep-Bqhi_DDs.mjs → useStep-Dw7XloDM.mjs} +1067 -1258
- 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-BXN7M6o_.d.mts +0 -71
- package/dist/index-Bd3J4RNS.d.mts +0 -11
- package/dist/utilities-DQWf_4V_.mjs +0 -139
- /package/dist/{constants-BWV0uYsM.mjs → constants-DypzAkYp.mjs} +0 -0
- /package/dist/{htmlElements-BYo-fMlZ.mjs → htmlElements-CXObxj0V.mjs} +0 -0
- /package/dist/{index-B6lIRI3i.d.mts → index-B9mKi4pr.d.mts} +0 -0
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);
|
|
@@ -216,7 +440,7 @@ function debounce(fn, delay) {
|
|
|
216
440
|
|
|
217
441
|
//#endregion
|
|
218
442
|
//#region src/components/Atom/Atom.vue
|
|
219
|
-
const _sfc_main$
|
|
443
|
+
const _sfc_main$27 = /* @__PURE__ */ defineComponent({
|
|
220
444
|
name: "Atom",
|
|
221
445
|
__name: "Atom",
|
|
222
446
|
props: {
|
|
@@ -247,27 +471,11 @@ const _sfc_main$26 = /* @__PURE__ */ defineComponent({
|
|
|
247
471
|
};
|
|
248
472
|
}
|
|
249
473
|
});
|
|
250
|
-
var Atom_default = _sfc_main$
|
|
474
|
+
var Atom_default = _sfc_main$27;
|
|
251
475
|
|
|
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
|
|
@@ -700,12 +908,12 @@ function createFallbackLogger(namespace = "v0:logger") {
|
|
|
700
908
|
return `[${namespace} ${type}] ${message}`;
|
|
701
909
|
}
|
|
702
910
|
return {
|
|
703
|
-
debug: (message, ...args) => console.
|
|
704
|
-
info: (message, ...args) => console.
|
|
705
|
-
warn: (message, ...args) => console.
|
|
706
|
-
error: (message, ...args) => console.
|
|
707
|
-
trace: (message, ...args) => console.
|
|
708
|
-
fatal: (message, ...args) => console.
|
|
911
|
+
debug: (message, ...args) => console.debug(format(message, "debug"), ...args),
|
|
912
|
+
info: (message, ...args) => console.info(format(message, "info"), ...args),
|
|
913
|
+
warn: (message, ...args) => console.warn(format(message, "warn"), ...args),
|
|
914
|
+
error: (message, ...args) => console.error(format(message, "error"), ...args),
|
|
915
|
+
trace: (message, ...args) => console.trace(format(message, "trace"), ...args),
|
|
916
|
+
fatal: (message, ...args) => console.error(format(message, "fatal"), ...args),
|
|
709
917
|
level: () => {},
|
|
710
918
|
current: () => "info",
|
|
711
919
|
enabled: () => true,
|
|
@@ -733,7 +941,7 @@ function createFallbackLogger(namespace = "v0:logger") {
|
|
|
733
941
|
* ```
|
|
734
942
|
*/
|
|
735
943
|
function createLoggerContext(_options = {}) {
|
|
736
|
-
const { namespace = "v0:logger"
|
|
944
|
+
const { namespace = "v0:logger", ...options } = _options;
|
|
737
945
|
const [useLoggerContext, _provideLoggerContext] = createContext(namespace);
|
|
738
946
|
const context = createLogger(options);
|
|
739
947
|
function provideLoggerContext(_context = context, app) {
|
|
@@ -768,7 +976,7 @@ function createLoggerContext(_options = {}) {
|
|
|
768
976
|
* ```
|
|
769
977
|
*/
|
|
770
978
|
function createLoggerPlugin(_options = {}) {
|
|
771
|
-
const { namespace = "v0:logger"
|
|
979
|
+
const { namespace = "v0:logger", ...options } = _options;
|
|
772
980
|
const [, provideLoggerContext, context] = createLoggerContext({
|
|
773
981
|
...options,
|
|
774
982
|
namespace
|
|
@@ -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.
|
|
@@ -863,6 +1056,8 @@ function useRegistry(options) {
|
|
|
863
1056
|
let indexDependentCount = 0;
|
|
864
1057
|
let needsReindex = false;
|
|
865
1058
|
let minDirtyIndex = Infinity;
|
|
1059
|
+
let batching = false;
|
|
1060
|
+
let pendingEmits = [];
|
|
866
1061
|
function emit(event, data = void 0) {
|
|
867
1062
|
if (!events) return;
|
|
868
1063
|
const cbs = listeners.get(event);
|
|
@@ -871,17 +1066,21 @@ function useRegistry(options) {
|
|
|
871
1066
|
}
|
|
872
1067
|
function on(event, cb) {
|
|
873
1068
|
if (!events) {
|
|
874
|
-
logger.warn(`
|
|
1069
|
+
logger.warn(`Events are disabled. Initialize with \`useRegistry({ events: true })\` to enable.`);
|
|
875
1070
|
return;
|
|
876
1071
|
}
|
|
877
1072
|
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
878
1073
|
listeners.get(event).add(cb);
|
|
879
1074
|
}
|
|
880
1075
|
function off(event, cb) {
|
|
1076
|
+
if (!events) {
|
|
1077
|
+
logger.warn(`Events are disabled. Initialize with \`useRegistry({ events: true })\` to enable.`);
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
881
1080
|
listeners.get(event)?.delete(cb);
|
|
882
1081
|
}
|
|
883
1082
|
function dispose() {
|
|
884
|
-
|
|
1083
|
+
listeners.clear();
|
|
885
1084
|
clear();
|
|
886
1085
|
}
|
|
887
1086
|
function get(id) {
|
|
@@ -938,24 +1137,19 @@ function useRegistry(options) {
|
|
|
938
1137
|
function assign(value, id) {
|
|
939
1138
|
const bucket = catalog.get(value);
|
|
940
1139
|
if (bucket) {
|
|
941
|
-
if (
|
|
942
|
-
|
|
943
|
-
} else if (bucket !== id) catalog.set(value, [bucket, id]);
|
|
944
|
-
} else catalog.set(value, id);
|
|
1140
|
+
if (!bucket.includes(id)) bucket.push(id);
|
|
1141
|
+
} else catalog.set(value, [id]);
|
|
945
1142
|
}
|
|
946
1143
|
function unassign(value, id) {
|
|
947
1144
|
const bucket = catalog.get(value);
|
|
948
1145
|
if (!bucket) return;
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
else if (next.length === 1) catalog.set(value, next[0]);
|
|
953
|
-
else catalog.set(value, next);
|
|
954
|
-
} else if (bucket === id) catalog.delete(value);
|
|
1146
|
+
const next = bucket.filter((v) => v !== id);
|
|
1147
|
+
if (next.length === 0) catalog.delete(value);
|
|
1148
|
+
else catalog.set(value, next);
|
|
955
1149
|
}
|
|
956
1150
|
function keys() {
|
|
957
1151
|
const cached = cache.get("keys");
|
|
958
|
-
if (
|
|
1152
|
+
if (!/* @__PURE__ */ isUndefined(cached)) return cached;
|
|
959
1153
|
const keys$1 = Array.from(collection.keys());
|
|
960
1154
|
cache.set("keys", keys$1);
|
|
961
1155
|
return keys$1;
|
|
@@ -975,9 +1169,9 @@ function useRegistry(options) {
|
|
|
975
1169
|
return entries$1;
|
|
976
1170
|
}
|
|
977
1171
|
function clear() {
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1172
|
+
collection.clear();
|
|
1173
|
+
catalog.clear();
|
|
1174
|
+
directory.clear();
|
|
981
1175
|
invalidate();
|
|
982
1176
|
indexDependentCount = 0;
|
|
983
1177
|
needsReindex = false;
|
|
@@ -985,13 +1179,35 @@ function useRegistry(options) {
|
|
|
985
1179
|
emit("clear:registry");
|
|
986
1180
|
}
|
|
987
1181
|
function invalidate() {
|
|
988
|
-
if (
|
|
1182
|
+
if (batching) return;
|
|
1183
|
+
cache.clear();
|
|
1184
|
+
}
|
|
1185
|
+
function queueEmit(event, data) {
|
|
1186
|
+
if (batching) pendingEmits.push({
|
|
1187
|
+
event,
|
|
1188
|
+
data
|
|
1189
|
+
});
|
|
1190
|
+
else emit(event, data);
|
|
1191
|
+
}
|
|
1192
|
+
function batch(fn) {
|
|
1193
|
+
if (batching) return fn();
|
|
1194
|
+
batching = true;
|
|
1195
|
+
pendingEmits = [];
|
|
1196
|
+
try {
|
|
1197
|
+
const result = fn();
|
|
1198
|
+
cache.clear();
|
|
1199
|
+
for (const { event, data } of pendingEmits) emit(event, data);
|
|
1200
|
+
return result;
|
|
1201
|
+
} finally {
|
|
1202
|
+
batching = false;
|
|
1203
|
+
pendingEmits = [];
|
|
1204
|
+
}
|
|
989
1205
|
}
|
|
990
1206
|
function reindex() {
|
|
991
1207
|
const startIndex = minDirtyIndex === Infinity ? 0 : minDirtyIndex;
|
|
992
1208
|
if (startIndex === 0) {
|
|
993
|
-
|
|
994
|
-
|
|
1209
|
+
catalog.clear();
|
|
1210
|
+
directory.clear();
|
|
995
1211
|
}
|
|
996
1212
|
invalidate();
|
|
997
1213
|
let index = 0;
|
|
@@ -1018,7 +1234,7 @@ function useRegistry(options) {
|
|
|
1018
1234
|
const size = collection.size;
|
|
1019
1235
|
const id = registration.id ?? /* @__PURE__ */ genId();
|
|
1020
1236
|
if (has(id)) {
|
|
1021
|
-
logger.warn(`Ticket
|
|
1237
|
+
logger.warn(`Ticket "${id}" already exists. Use \`upsert()\` to update or check \`has()\` before registering.`);
|
|
1022
1238
|
return get(id);
|
|
1023
1239
|
}
|
|
1024
1240
|
const valueIsUndefined = /* @__PURE__ */ isUndefined(registration.value);
|
|
@@ -1037,7 +1253,7 @@ function useRegistry(options) {
|
|
|
1037
1253
|
directory.set(ticket.index, ticket.id);
|
|
1038
1254
|
assign(ticket.value, ticket.id);
|
|
1039
1255
|
invalidate();
|
|
1040
|
-
|
|
1256
|
+
queueEmit("register:ticket", ticket);
|
|
1041
1257
|
return ticket;
|
|
1042
1258
|
}
|
|
1043
1259
|
function unregister(id) {
|
|
@@ -1047,15 +1263,12 @@ function useRegistry(options) {
|
|
|
1047
1263
|
collection.delete(ticket.id);
|
|
1048
1264
|
directory.delete(ticket.index);
|
|
1049
1265
|
unassign(ticket.value, ticket.id);
|
|
1050
|
-
|
|
1266
|
+
const willReindex = indexDependentCount > 0 && ticket.index < collection.size;
|
|
1267
|
+
if (!willReindex) invalidate();
|
|
1051
1268
|
emit("unregister:ticket", ticket);
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
} else {
|
|
1056
|
-
minDirtyIndex = Math.min(minDirtyIndex, ticket.index);
|
|
1057
|
-
needsReindex = true;
|
|
1058
|
-
}
|
|
1269
|
+
minDirtyIndex = Math.min(minDirtyIndex, ticket.index);
|
|
1270
|
+
if (willReindex) reindex();
|
|
1271
|
+
else needsReindex = true;
|
|
1059
1272
|
}
|
|
1060
1273
|
function offboard(ids) {
|
|
1061
1274
|
const removed = [];
|
|
@@ -1071,12 +1284,16 @@ function useRegistry(options) {
|
|
|
1071
1284
|
}
|
|
1072
1285
|
if (removed.length === 0) return;
|
|
1073
1286
|
invalidate();
|
|
1074
|
-
|
|
1287
|
+
for (const ticket of removed) queueEmit("unregister:ticket", ticket);
|
|
1075
1288
|
needsReindex = true;
|
|
1076
1289
|
}
|
|
1077
1290
|
function seek(direction = "first", from, predicate) {
|
|
1078
1291
|
if (collection.size === 0) return void 0;
|
|
1079
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
|
+
}
|
|
1080
1297
|
const tickets = values();
|
|
1081
1298
|
const index = /* @__PURE__ */ isUndefined(from) ? void 0 : Math.max(0, Math.min(from, tickets.length - 1));
|
|
1082
1299
|
if (direction === "last") {
|
|
@@ -1112,8 +1329,9 @@ function useRegistry(options) {
|
|
|
1112
1329
|
unregister,
|
|
1113
1330
|
reindex,
|
|
1114
1331
|
seek,
|
|
1332
|
+
batch,
|
|
1115
1333
|
onboard(registrations) {
|
|
1116
|
-
return registrations.map((registration) => register(registration));
|
|
1334
|
+
return batch(() => registrations.map((registration) => register(registration)));
|
|
1117
1335
|
},
|
|
1118
1336
|
offboard,
|
|
1119
1337
|
get size() {
|
|
@@ -1124,8 +1342,7 @@ function useRegistry(options) {
|
|
|
1124
1342
|
/**
|
|
1125
1343
|
* Creates a new registry context.
|
|
1126
1344
|
*
|
|
1127
|
-
* @param
|
|
1128
|
-
* @param options The options for the registry context.
|
|
1345
|
+
* @param options The options for the registry context, including `namespace` (defaults to `'v0:registry'`) and `events`.
|
|
1129
1346
|
* @template Z The type of registry ticket that extends RegistryTicket. Use this to add custom properties to tickets.
|
|
1130
1347
|
* @template E The type of registry context that extends RegistryContext<Z>. Use this when extending the registry with additional methods.
|
|
1131
1348
|
* @returns A new registry context.
|
|
@@ -1151,7 +1368,7 @@ function useRegistry(options) {
|
|
|
1151
1368
|
* ```
|
|
1152
1369
|
*/
|
|
1153
1370
|
function createRegistryContext(_options = {}) {
|
|
1154
|
-
const { namespace = "v0:registry"
|
|
1371
|
+
const { namespace = "v0:registry", ...options } = _options;
|
|
1155
1372
|
const [useRegistryContext, _provideRegistryContext] = createContext(namespace);
|
|
1156
1373
|
const context = useRegistry(options);
|
|
1157
1374
|
function provideRegistryContext(_context = context, app) {
|
|
@@ -1163,21 +1380,6 @@ function createRegistryContext(_options = {}) {
|
|
|
1163
1380
|
//#endregion
|
|
1164
1381
|
//#region src/composables/useSelection/index.ts
|
|
1165
1382
|
/**
|
|
1166
|
-
* @module useSelection
|
|
1167
|
-
*
|
|
1168
|
-
* @remarks
|
|
1169
|
-
* Base composable for managing selected items in a collection with Set-based tracking.
|
|
1170
|
-
*
|
|
1171
|
-
* Key features:
|
|
1172
|
-
* - Set-based selectedIds for O(1) selection checks
|
|
1173
|
-
* - Mandatory selection mode (prevents deselecting last item)
|
|
1174
|
-
* - Auto-enrollment option (selects non-disabled items on register)
|
|
1175
|
-
* - Disabled item filtering
|
|
1176
|
-
* - Computed selectedItems and selectedValues Sets
|
|
1177
|
-
*
|
|
1178
|
-
* Extends useRegistry and serves as the base for useSingle, useGroup, useStep, and useFeatures.
|
|
1179
|
-
*/
|
|
1180
|
-
/**
|
|
1181
1383
|
* Creates a new selection instance for managing multiple selected items.
|
|
1182
1384
|
*
|
|
1183
1385
|
* Extends `useRegistry` with selection tracking via a reactive `Set` of selected IDs.
|
|
@@ -1224,14 +1426,14 @@ function createRegistryContext(_options = {}) {
|
|
|
1224
1426
|
* ```
|
|
1225
1427
|
*/
|
|
1226
1428
|
function createSelection(_options = {}) {
|
|
1227
|
-
const { disabled = false, enroll = false, mandatory = false, multiple = false
|
|
1429
|
+
const { disabled = false, enroll = false, mandatory = false, multiple = false, ...options } = _options;
|
|
1228
1430
|
const registry = useRegistry(options);
|
|
1229
1431
|
const selectedIds = shallowReactive(/* @__PURE__ */ new Set());
|
|
1230
1432
|
const selectedItems = computed(() => {
|
|
1231
|
-
return new Set(Array.from(selectedIds).map((id) => registry.get(id)));
|
|
1433
|
+
return new Set(Array.from(selectedIds).map((id) => registry.get(id)).filter((item) => !/* @__PURE__ */ isUndefined(item)));
|
|
1232
1434
|
});
|
|
1233
1435
|
const selectedValues = computed(() => {
|
|
1234
|
-
return new Set(Array.from(selectedItems.value).map((item) => item
|
|
1436
|
+
return new Set(Array.from(selectedItems.value).map((item) => item.value));
|
|
1235
1437
|
});
|
|
1236
1438
|
function seek(direction = "first", from) {
|
|
1237
1439
|
return registry.seek(direction, from, (ticket) => !toValue(ticket.disabled));
|
|
@@ -1242,16 +1444,19 @@ function createSelection(_options = {}) {
|
|
|
1242
1444
|
if (ticket) select(ticket.id);
|
|
1243
1445
|
}
|
|
1244
1446
|
function select(id) {
|
|
1447
|
+
if (toValue(disabled)) return;
|
|
1245
1448
|
const item = registry.get(id);
|
|
1246
1449
|
if (!item || toValue(item.disabled)) return;
|
|
1247
1450
|
if (!multiple) selectedIds.clear();
|
|
1248
1451
|
selectedIds.add(id);
|
|
1249
1452
|
}
|
|
1250
1453
|
function unselect(id) {
|
|
1454
|
+
if (toValue(disabled)) return;
|
|
1251
1455
|
if (mandatory && selectedIds.size === 1) return;
|
|
1252
1456
|
selectedIds.delete(id);
|
|
1253
1457
|
}
|
|
1254
1458
|
function toggle(id) {
|
|
1459
|
+
if (toValue(disabled)) return;
|
|
1255
1460
|
if (selected(id)) unselect(id);
|
|
1256
1461
|
else select(id);
|
|
1257
1462
|
}
|
|
@@ -1270,7 +1475,7 @@ function createSelection(_options = {}) {
|
|
|
1270
1475
|
id
|
|
1271
1476
|
};
|
|
1272
1477
|
const ticket = registry.register(item);
|
|
1273
|
-
if (enroll && !toValue(item.disabled)) selectedIds.add(ticket.id);
|
|
1478
|
+
if (enroll && !toValue(disabled) && !toValue(item.disabled)) selectedIds.add(ticket.id);
|
|
1274
1479
|
if (mandatory === "force") mandate();
|
|
1275
1480
|
return ticket;
|
|
1276
1481
|
}
|
|
@@ -1341,7 +1546,7 @@ function createSelection(_options = {}) {
|
|
|
1341
1546
|
* ```
|
|
1342
1547
|
*/
|
|
1343
1548
|
function createSelectionContext(_options = {}) {
|
|
1344
|
-
const { namespace = "v0:selection"
|
|
1549
|
+
const { namespace = "v0:selection", ...options } = _options;
|
|
1345
1550
|
const [useSelectionContext, _provideSelectionContext] = createContext(namespace);
|
|
1346
1551
|
const context = createSelection(options);
|
|
1347
1552
|
function provideSelectionContext(_context = context, app) {
|
|
@@ -1379,7 +1584,7 @@ function useSelection(namespace = "v0:selection") {
|
|
|
1379
1584
|
//#endregion
|
|
1380
1585
|
//#region src/components/Avatar/AvatarRoot.vue
|
|
1381
1586
|
const [useAvatarRoot, provideAvatarContext] = createContext();
|
|
1382
|
-
const _sfc_main$
|
|
1587
|
+
const _sfc_main$26 = /* @__PURE__ */ defineComponent({
|
|
1383
1588
|
name: "AvatarRoot",
|
|
1384
1589
|
__name: "AvatarRoot",
|
|
1385
1590
|
props: {
|
|
@@ -1404,11 +1609,11 @@ const _sfc_main$25 = /* @__PURE__ */ defineComponent({
|
|
|
1404
1609
|
};
|
|
1405
1610
|
}
|
|
1406
1611
|
});
|
|
1407
|
-
var AvatarRoot_default = _sfc_main$
|
|
1612
|
+
var AvatarRoot_default = _sfc_main$26;
|
|
1408
1613
|
|
|
1409
1614
|
//#endregion
|
|
1410
1615
|
//#region src/components/Avatar/AvatarFallback.vue
|
|
1411
|
-
const _sfc_main$
|
|
1616
|
+
const _sfc_main$25 = /* @__PURE__ */ defineComponent({
|
|
1412
1617
|
name: "AvatarFallback",
|
|
1413
1618
|
__name: "AvatarFallback",
|
|
1414
1619
|
props: {
|
|
@@ -1433,11 +1638,11 @@ const _sfc_main$24 = /* @__PURE__ */ defineComponent({
|
|
|
1433
1638
|
};
|
|
1434
1639
|
}
|
|
1435
1640
|
});
|
|
1436
|
-
var AvatarFallback_default = _sfc_main$
|
|
1641
|
+
var AvatarFallback_default = _sfc_main$25;
|
|
1437
1642
|
|
|
1438
1643
|
//#endregion
|
|
1439
1644
|
//#region src/components/Avatar/AvatarImage.vue
|
|
1440
|
-
const _sfc_main$
|
|
1645
|
+
const _sfc_main$24 = /* @__PURE__ */ defineComponent({
|
|
1441
1646
|
name: "AvatarImage",
|
|
1442
1647
|
inheritAttrs: false,
|
|
1443
1648
|
__name: "AvatarImage",
|
|
@@ -1497,14 +1702,19 @@ const _sfc_main$23 = /* @__PURE__ */ defineComponent({
|
|
|
1497
1702
|
};
|
|
1498
1703
|
}
|
|
1499
1704
|
});
|
|
1500
|
-
var AvatarImage_default = _sfc_main$
|
|
1705
|
+
var AvatarImage_default = _sfc_main$24;
|
|
1501
1706
|
|
|
1502
1707
|
//#endregion
|
|
1503
1708
|
//#region src/components/Avatar/index.ts
|
|
1709
|
+
/**
|
|
1710
|
+
* Avatar component with sub-components for building avatars.
|
|
1711
|
+
*
|
|
1712
|
+
* @see https://0.vuetifyjs.com/components/avatar
|
|
1713
|
+
*/
|
|
1504
1714
|
const Avatar = {
|
|
1505
|
-
|
|
1715
|
+
Root: AvatarRoot_default,
|
|
1506
1716
|
Image: AvatarImage_default,
|
|
1507
|
-
|
|
1717
|
+
Fallback: AvatarFallback_default
|
|
1508
1718
|
};
|
|
1509
1719
|
|
|
1510
1720
|
//#endregion
|
|
@@ -1545,20 +1755,6 @@ function toArray(value) {
|
|
|
1545
1755
|
//#endregion
|
|
1546
1756
|
//#region src/composables/useProxyModel/index.ts
|
|
1547
1757
|
/**
|
|
1548
|
-
* @module useProxyModel
|
|
1549
|
-
*
|
|
1550
|
-
* @remarks
|
|
1551
|
-
* Proxy composable for bidirectional sync between selection registry and v-model.
|
|
1552
|
-
*
|
|
1553
|
-
* Key features:
|
|
1554
|
-
* - Bidirectional synchronization
|
|
1555
|
-
* - Array and single-value modes
|
|
1556
|
-
* - Automatic cleanup on scope disposal
|
|
1557
|
-
* - Perfect for form controls with selection backing
|
|
1558
|
-
*
|
|
1559
|
-
* Bridges the gap between selection composables and Vue's v-model.
|
|
1560
|
-
*/
|
|
1561
|
-
/**
|
|
1562
1758
|
* Syncs a ref with a selection registry bidirectionally.
|
|
1563
1759
|
*
|
|
1564
1760
|
* @param registry The selection registry to bind to.
|
|
@@ -1599,12 +1795,9 @@ function useProxyModel(registry, model, options) {
|
|
|
1599
1795
|
const pending = new Set(modelAsArray);
|
|
1600
1796
|
for (const value of modelAsArray) {
|
|
1601
1797
|
const ids = registry.browse(value);
|
|
1602
|
-
if (
|
|
1798
|
+
if (ids) {
|
|
1603
1799
|
for (const id of ids) registry.select(id);
|
|
1604
1800
|
pending.delete(value);
|
|
1605
|
-
} else if (ids) {
|
|
1606
|
-
registry.select(ids);
|
|
1607
|
-
pending.delete(value);
|
|
1608
1801
|
}
|
|
1609
1802
|
}
|
|
1610
1803
|
const registryWatch = watch(registry.selectedValues, (val) => {
|
|
@@ -1618,8 +1811,7 @@ function useProxyModel(registry, model, options) {
|
|
|
1618
1811
|
const targetIds = /* @__PURE__ */ new Set();
|
|
1619
1812
|
for (const value of transformIn(val)) {
|
|
1620
1813
|
const ids = registry.browse(value);
|
|
1621
|
-
if (
|
|
1622
|
-
else if (ids) targetIds.add(ids);
|
|
1814
|
+
if (ids) for (const id of ids) targetIds.add(id);
|
|
1623
1815
|
}
|
|
1624
1816
|
if (multiple) {
|
|
1625
1817
|
for (const id of currentIds.difference(targetIds)) registry.selectedIds.delete(id);
|
|
@@ -1635,7 +1827,8 @@ function useProxyModel(registry, model, options) {
|
|
|
1635
1827
|
flush: "sync",
|
|
1636
1828
|
deep: multiple
|
|
1637
1829
|
});
|
|
1638
|
-
function onRegister(
|
|
1830
|
+
function onRegister(data) {
|
|
1831
|
+
const ticket = data;
|
|
1639
1832
|
if (!pending.has(ticket.value) || ticket.disabled) return;
|
|
1640
1833
|
registryWatch.pause();
|
|
1641
1834
|
modelWatch.pause();
|
|
@@ -1657,7 +1850,7 @@ function useProxyModel(registry, model, options) {
|
|
|
1657
1850
|
//#endregion
|
|
1658
1851
|
//#region src/components/ExpansionPanel/ExpansionPanelRoot.vue
|
|
1659
1852
|
const [useExpansionPanelRoot, provideExpansionPanelSelection] = createContext();
|
|
1660
|
-
const _sfc_main$
|
|
1853
|
+
const _sfc_main$23 = /* @__PURE__ */ defineComponent({
|
|
1661
1854
|
name: "ExpansionPanelRoot",
|
|
1662
1855
|
__name: "ExpansionPanelRoot",
|
|
1663
1856
|
props: /* @__PURE__ */ mergeModels({
|
|
@@ -1714,12 +1907,12 @@ const _sfc_main$22 = /* @__PURE__ */ defineComponent({
|
|
|
1714
1907
|
};
|
|
1715
1908
|
}
|
|
1716
1909
|
});
|
|
1717
|
-
var ExpansionPanelRoot_default = _sfc_main$
|
|
1910
|
+
var ExpansionPanelRoot_default = _sfc_main$23;
|
|
1718
1911
|
|
|
1719
1912
|
//#endregion
|
|
1720
1913
|
//#region src/components/ExpansionPanel/ExpansionPanelItem.vue
|
|
1721
1914
|
const [useExpansionPanelItem, provideExpansionPanelItem] = createContext({ suffix: "item" });
|
|
1722
|
-
const _sfc_main$
|
|
1915
|
+
const _sfc_main$22 = /* @__PURE__ */ defineComponent({
|
|
1723
1916
|
name: "ExpansionPanelItem",
|
|
1724
1917
|
__name: "ExpansionPanelItem",
|
|
1725
1918
|
props: {
|
|
@@ -1763,11 +1956,11 @@ const _sfc_main$21 = /* @__PURE__ */ defineComponent({
|
|
|
1763
1956
|
};
|
|
1764
1957
|
}
|
|
1765
1958
|
});
|
|
1766
|
-
var ExpansionPanelItem_default = _sfc_main$
|
|
1959
|
+
var ExpansionPanelItem_default = _sfc_main$22;
|
|
1767
1960
|
|
|
1768
1961
|
//#endregion
|
|
1769
1962
|
//#region src/components/ExpansionPanel/ExpansionPanelActivator.vue
|
|
1770
|
-
const _sfc_main$
|
|
1963
|
+
const _sfc_main$21 = /* @__PURE__ */ defineComponent({
|
|
1771
1964
|
name: "ExpansionPanelActivator",
|
|
1772
1965
|
__name: "ExpansionPanelActivator",
|
|
1773
1966
|
props: {
|
|
@@ -1813,11 +2006,11 @@ const _sfc_main$20 = /* @__PURE__ */ defineComponent({
|
|
|
1813
2006
|
};
|
|
1814
2007
|
}
|
|
1815
2008
|
});
|
|
1816
|
-
var ExpansionPanelActivator_default = _sfc_main$
|
|
2009
|
+
var ExpansionPanelActivator_default = _sfc_main$21;
|
|
1817
2010
|
|
|
1818
2011
|
//#endregion
|
|
1819
2012
|
//#region src/components/ExpansionPanel/ExpansionPanelContent.vue
|
|
1820
|
-
const _sfc_main$
|
|
2013
|
+
const _sfc_main$20 = /* @__PURE__ */ defineComponent({
|
|
1821
2014
|
name: "ExpansionPanelContent",
|
|
1822
2015
|
__name: "ExpansionPanelContent",
|
|
1823
2016
|
props: {
|
|
@@ -1848,11 +2041,11 @@ const _sfc_main$19 = /* @__PURE__ */ defineComponent({
|
|
|
1848
2041
|
};
|
|
1849
2042
|
}
|
|
1850
2043
|
});
|
|
1851
|
-
var ExpansionPanelContent_default = _sfc_main$
|
|
2044
|
+
var ExpansionPanelContent_default = _sfc_main$20;
|
|
1852
2045
|
|
|
1853
2046
|
//#endregion
|
|
1854
2047
|
//#region src/components/ExpansionPanel/ExpansionPanelHeader.vue
|
|
1855
|
-
const _sfc_main$
|
|
2048
|
+
const _sfc_main$19 = /* @__PURE__ */ defineComponent({
|
|
1856
2049
|
name: "ExpansionPanelHeader",
|
|
1857
2050
|
__name: "ExpansionPanelHeader",
|
|
1858
2051
|
props: {
|
|
@@ -1877,10 +2070,15 @@ const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
|
1877
2070
|
};
|
|
1878
2071
|
}
|
|
1879
2072
|
});
|
|
1880
|
-
var ExpansionPanelHeader_default = _sfc_main$
|
|
2073
|
+
var ExpansionPanelHeader_default = _sfc_main$19;
|
|
1881
2074
|
|
|
1882
2075
|
//#endregion
|
|
1883
2076
|
//#region src/components/ExpansionPanel/index.ts
|
|
2077
|
+
/**
|
|
2078
|
+
* ExpansionPanel component with sub-components for building expansion panels.
|
|
2079
|
+
*
|
|
2080
|
+
* @see https://0.vuetifyjs.com/components/expansion-panels
|
|
2081
|
+
*/
|
|
1884
2082
|
const ExpansionPanel = {
|
|
1885
2083
|
Root: ExpansionPanelRoot_default,
|
|
1886
2084
|
Item: ExpansionPanelItem_default,
|
|
@@ -1892,21 +2090,6 @@ const ExpansionPanel = {
|
|
|
1892
2090
|
//#endregion
|
|
1893
2091
|
//#region src/composables/useProxyRegistry/index.ts
|
|
1894
2092
|
/**
|
|
1895
|
-
* @module useProxyRegistry
|
|
1896
|
-
*
|
|
1897
|
-
* @remarks
|
|
1898
|
-
* Proxy composable for reactive registry keys, values, entries, and size.
|
|
1899
|
-
*
|
|
1900
|
-
* Key features:
|
|
1901
|
-
* - Reactive proxy for registry data
|
|
1902
|
-
* - Deep or shallow reactivity options
|
|
1903
|
-
* - Event-based updates
|
|
1904
|
-
* - Automatic cleanup on scope disposal
|
|
1905
|
-
* - Transforms Map-based registry into reactive refs
|
|
1906
|
-
*
|
|
1907
|
-
* Perfect for exposing registry data as reactive computed properties.
|
|
1908
|
-
*/
|
|
1909
|
-
/**
|
|
1910
2093
|
* Creates a proxy registry that provides reactive objects for registry data.
|
|
1911
2094
|
*
|
|
1912
2095
|
* @param registry The registry instance to proxy.
|
|
@@ -1956,26 +2139,6 @@ function useProxyRegistry(registry, options) {
|
|
|
1956
2139
|
//#endregion
|
|
1957
2140
|
//#region src/composables/useGroup/index.ts
|
|
1958
2141
|
/**
|
|
1959
|
-
* @module useGroup
|
|
1960
|
-
*
|
|
1961
|
-
* @remarks
|
|
1962
|
-
* Multi-selection composable that extends useSelection with batch operations and tri-state support.
|
|
1963
|
-
*
|
|
1964
|
-
* Key features:
|
|
1965
|
-
* - Batch operations (select/unselect/toggle accept ID | ID[])
|
|
1966
|
-
* - Tri-state support via mixed/indeterminate state (mix/unmix)
|
|
1967
|
-
* - selectedIndexes computed Set for position-based tracking
|
|
1968
|
-
* - Perfect for checkbox trees, multi-select dropdowns, filter panels
|
|
1969
|
-
*
|
|
1970
|
-
* Tri-state behavior:
|
|
1971
|
-
* - Items can be selected, mixed (indeterminate), or unselected
|
|
1972
|
-
* - select() clears mixed state, mix() clears selected state (mutually exclusive)
|
|
1973
|
-
* - toggle() on a mixed item selects it (resolves positively)
|
|
1974
|
-
*
|
|
1975
|
-
* Inheritance chain: useRegistry → useSelection → useGroup
|
|
1976
|
-
* Extended by: useFeatures
|
|
1977
|
-
*/
|
|
1978
|
-
/**
|
|
1979
2142
|
* Creates a new group instance with batch selection and tri-state support.
|
|
1980
2143
|
*
|
|
1981
2144
|
* Extends `createSelection` to support selecting, unselecting, and toggling multiple items
|
|
@@ -2049,7 +2212,7 @@ function useProxyRegistry(registry, options) {
|
|
|
2049
2212
|
* ```
|
|
2050
2213
|
*/
|
|
2051
2214
|
function createGroup(_options = {}) {
|
|
2052
|
-
const { mandatory = false, multiple = true
|
|
2215
|
+
const { mandatory = false, multiple = true, ...options } = _options;
|
|
2053
2216
|
const selection = createSelection({
|
|
2054
2217
|
...options,
|
|
2055
2218
|
mandatory,
|
|
@@ -2059,10 +2222,10 @@ function createGroup(_options = {}) {
|
|
|
2059
2222
|
const proxy = useProxyRegistry(selection);
|
|
2060
2223
|
const mixedIds = shallowReactive(/* @__PURE__ */ new Set());
|
|
2061
2224
|
const selectedIndexes = computed(() => {
|
|
2062
|
-
return new Set(Array.from(selection.selectedItems.value).map((item) => item?.index));
|
|
2225
|
+
return new Set(Array.from(selection.selectedItems.value).map((item) => item?.index).filter((index) => !/* @__PURE__ */ isUndefined(index)));
|
|
2063
2226
|
});
|
|
2064
2227
|
const mixedItems = computed(() => {
|
|
2065
|
-
return new Set(Array.from(mixedIds).map((id) => selection.get(id)));
|
|
2228
|
+
return new Set(Array.from(mixedIds).map((id) => selection.get(id)).filter((item) => !/* @__PURE__ */ isUndefined(item)));
|
|
2066
2229
|
});
|
|
2067
2230
|
function mixed(id) {
|
|
2068
2231
|
return mixedIds.has(id);
|
|
@@ -2129,10 +2292,10 @@ function createGroup(_options = {}) {
|
|
|
2129
2292
|
if (items.length === 0) return false;
|
|
2130
2293
|
return items.every((item) => selection.selectedIds.has(item.id));
|
|
2131
2294
|
});
|
|
2132
|
-
const
|
|
2295
|
+
const isNoneSelected = computed(() => selection.selectedIds.size === 0);
|
|
2296
|
+
const isMixed = computed(() => {
|
|
2133
2297
|
return mixedIds.size > 0 || !isNoneSelected.value && !isAllSelected.value;
|
|
2134
2298
|
});
|
|
2135
|
-
const isNoneSelected = toRef(() => selection.selectedIds.size === 0);
|
|
2136
2299
|
function selectAll() {
|
|
2137
2300
|
for (const item of selectableItems.value) {
|
|
2138
2301
|
mixedIds.delete(item.id);
|
|
@@ -2204,7 +2367,7 @@ function createGroup(_options = {}) {
|
|
|
2204
2367
|
* ```
|
|
2205
2368
|
*/
|
|
2206
2369
|
function createGroupContext(_options = {}) {
|
|
2207
|
-
const { namespace = "v0:group"
|
|
2370
|
+
const { namespace = "v0:group", ...options } = _options;
|
|
2208
2371
|
const [useGroupContext, _provideGroupContext] = createContext(namespace);
|
|
2209
2372
|
const context = createGroup(options);
|
|
2210
2373
|
function provideGroupContext(_context = context, app) {
|
|
@@ -2242,7 +2405,7 @@ function useGroup(namespace = "v0:group") {
|
|
|
2242
2405
|
//#endregion
|
|
2243
2406
|
//#region src/components/Group/GroupRoot.vue
|
|
2244
2407
|
const [useGroupRoot, provideGroupRoot] = createContext();
|
|
2245
|
-
const _sfc_main$
|
|
2408
|
+
const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
2246
2409
|
name: "GroupRoot",
|
|
2247
2410
|
__name: "GroupRoot",
|
|
2248
2411
|
props: /* @__PURE__ */ mergeModels({
|
|
@@ -2263,7 +2426,7 @@ const _sfc_main$17 = /* @__PURE__ */ defineComponent({
|
|
|
2263
2426
|
"modelValue": {},
|
|
2264
2427
|
"modelModifiers": {}
|
|
2265
2428
|
}),
|
|
2266
|
-
emits: ["update:modelValue"],
|
|
2429
|
+
emits: /* @__PURE__ */ mergeModels(["update:model-value"], ["update:modelValue"]),
|
|
2267
2430
|
setup(__props) {
|
|
2268
2431
|
const model = useModel(__props, "modelValue");
|
|
2269
2432
|
const group = createGroup({
|
|
@@ -2292,11 +2455,11 @@ const _sfc_main$17 = /* @__PURE__ */ defineComponent({
|
|
|
2292
2455
|
};
|
|
2293
2456
|
}
|
|
2294
2457
|
});
|
|
2295
|
-
var GroupRoot_default = _sfc_main$
|
|
2458
|
+
var GroupRoot_default = _sfc_main$18;
|
|
2296
2459
|
|
|
2297
2460
|
//#endregion
|
|
2298
2461
|
//#region src/components/Group/GroupItem.vue
|
|
2299
|
-
const _sfc_main$
|
|
2462
|
+
const _sfc_main$17 = /* @__PURE__ */ defineComponent({
|
|
2300
2463
|
name: "GroupItem",
|
|
2301
2464
|
__name: "GroupItem",
|
|
2302
2465
|
props: {
|
|
@@ -2332,7 +2495,8 @@ const _sfc_main$16 = /* @__PURE__ */ defineComponent({
|
|
|
2332
2495
|
mix: ticket.mix,
|
|
2333
2496
|
unmix: ticket.unmix,
|
|
2334
2497
|
attrs: {
|
|
2335
|
-
"
|
|
2498
|
+
"role": "checkbox",
|
|
2499
|
+
"aria-checked": toValue(ticket.isMixed) ? "mixed" : toValue(ticket.isSelected),
|
|
2336
2500
|
"aria-disabled": toValue(isDisabled),
|
|
2337
2501
|
"data-selected": toValue(ticket.isSelected) || void 0,
|
|
2338
2502
|
"data-disabled": toValue(isDisabled) || void 0,
|
|
@@ -2344,1355 +2508,1254 @@ const _sfc_main$16 = /* @__PURE__ */ defineComponent({
|
|
|
2344
2508
|
};
|
|
2345
2509
|
}
|
|
2346
2510
|
});
|
|
2347
|
-
var GroupItem_default = _sfc_main$
|
|
2511
|
+
var GroupItem_default = _sfc_main$17;
|
|
2348
2512
|
|
|
2349
2513
|
//#endregion
|
|
2350
2514
|
//#region src/components/Group/index.ts
|
|
2515
|
+
/**
|
|
2516
|
+
* Group component with sub-components for multi-selection.
|
|
2517
|
+
*
|
|
2518
|
+
* @see https://0.vuetifyjs.com/components/group
|
|
2519
|
+
*/
|
|
2351
2520
|
const Group = {
|
|
2352
2521
|
Root: GroupRoot_default,
|
|
2353
2522
|
Item: GroupItem_default
|
|
2354
2523
|
};
|
|
2355
2524
|
|
|
2356
2525
|
//#endregion
|
|
2357
|
-
//#region src/composables/
|
|
2526
|
+
//#region src/composables/useLocale/adapters/v0.ts
|
|
2358
2527
|
/**
|
|
2359
|
-
*
|
|
2360
|
-
*
|
|
2361
|
-
* @see https://0.vuetifyjs.com/composables/plugins/use-hydration
|
|
2362
|
-
*
|
|
2363
|
-
* @remarks
|
|
2364
|
-
* SSR hydration state management composable.
|
|
2365
|
-
*
|
|
2366
|
-
* Key features:
|
|
2367
|
-
* - Hydration state detection (browser vs SSR)
|
|
2368
|
-
* - Root component detection
|
|
2369
|
-
* - Readonly hydration state refs
|
|
2370
|
-
* - Plugin installation support
|
|
2371
|
-
* - Perfect for hydration-safe rendering
|
|
2528
|
+
* Vuetify0.x locale adapter implementation
|
|
2372
2529
|
*
|
|
2373
|
-
*
|
|
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.
|
|
2374
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
|
|
2375
2560
|
/**
|
|
2376
|
-
* Creates a new
|
|
2377
|
-
*
|
|
2378
|
-
* @returns A new hydration instance.
|
|
2561
|
+
* Creates a new single selection instance that enforces only one selected item at a time.
|
|
2379
2562
|
*
|
|
2380
|
-
*
|
|
2563
|
+
* Extends `createSelection` by automatically clearing previous selections when a new item is selected.
|
|
2564
|
+
* Adds computed singular properties: `selectedId`, `selectedItem`, `selectedIndex`, `selectedValue`.
|
|
2381
2565
|
*
|
|
2382
|
-
* @
|
|
2383
|
-
*
|
|
2384
|
-
*
|
|
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.
|
|
2385
2570
|
*
|
|
2386
|
-
*
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2389
|
-
*
|
|
2390
|
-
*
|
|
2391
|
-
*/
|
|
2392
|
-
function createHydration() {
|
|
2393
|
-
const isHydrated = shallowRef(false);
|
|
2394
|
-
function hydrate() {
|
|
2395
|
-
isHydrated.value = true;
|
|
2396
|
-
}
|
|
2397
|
-
return {
|
|
2398
|
-
isHydrated: shallowReadonly(isHydrated),
|
|
2399
|
-
hydrate
|
|
2400
|
-
};
|
|
2401
|
-
}
|
|
2402
|
-
function createFallbackHydration() {
|
|
2403
|
-
return {
|
|
2404
|
-
isHydrated: shallowReadonly(shallowRef(true)),
|
|
2405
|
-
hydrate: () => {}
|
|
2406
|
-
};
|
|
2407
|
-
}
|
|
2408
|
-
/**
|
|
2409
|
-
* Creates a new hydration context trinity.
|
|
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
|
|
2410
2576
|
*
|
|
2411
|
-
*
|
|
2412
|
-
*
|
|
2413
|
-
*
|
|
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)
|
|
2414
2582
|
*
|
|
2415
|
-
*
|
|
2583
|
+
* **Inheritance Chain:**
|
|
2584
|
+
* `useRegistry` → `createSelection` → `createSingle` → `createStep`
|
|
2585
|
+
*
|
|
2586
|
+
* @see https://0.vuetifyjs.com/composables/selection/use-single
|
|
2416
2587
|
*
|
|
2417
2588
|
* @example
|
|
2418
2589
|
* ```ts
|
|
2419
|
-
* import {
|
|
2590
|
+
* import { createSingle } from '@vuetify/v0'
|
|
2420
2591
|
*
|
|
2421
|
-
*
|
|
2422
|
-
*
|
|
2423
|
-
*
|
|
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)
|
|
2424
2608
|
* ```
|
|
2425
2609
|
*/
|
|
2426
|
-
function
|
|
2427
|
-
const {
|
|
2428
|
-
const
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
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);
|
|
2432
2624
|
}
|
|
2433
|
-
|
|
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
|
+
};
|
|
2434
2641
|
}
|
|
2435
2642
|
/**
|
|
2436
|
-
* Creates a new
|
|
2643
|
+
* Creates a new single selection context.
|
|
2437
2644
|
*
|
|
2438
|
-
* @param options The options for the
|
|
2439
|
-
* @template
|
|
2440
|
-
* @
|
|
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.
|
|
2441
2649
|
*
|
|
2442
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
2650
|
+
* @see https://0.vuetifyjs.com/composables/selection/use-single
|
|
2443
2651
|
*
|
|
2444
2652
|
* @example
|
|
2445
2653
|
* ```ts
|
|
2446
|
-
* import {
|
|
2447
|
-
* import { createHydrationPlugin } from '@vuetify/v0'
|
|
2448
|
-
* import App from './App.vue'
|
|
2654
|
+
* import { createSingleContext } from '@vuetify/v0'
|
|
2449
2655
|
*
|
|
2450
|
-
*
|
|
2656
|
+
* // With default namespace 'v0:single'
|
|
2657
|
+
* export const [useSingle, provideSingle, context] = createSingleContext()
|
|
2451
2658
|
*
|
|
2452
|
-
*
|
|
2659
|
+
* // In a parent component:
|
|
2660
|
+
* provideSingle()
|
|
2453
2661
|
*
|
|
2454
|
-
*
|
|
2662
|
+
* // In a child component:
|
|
2663
|
+
* const single = useSingle()
|
|
2664
|
+
* single.select('tab-1')
|
|
2455
2665
|
* ```
|
|
2456
2666
|
*/
|
|
2457
|
-
function
|
|
2458
|
-
const { namespace = "v0:
|
|
2459
|
-
const [,
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
provide: (app) => {
|
|
2466
|
-
provideHydrationContext(context, app);
|
|
2467
|
-
},
|
|
2468
|
-
setup: (app) => {
|
|
2469
|
-
app.mixin({ mounted() {
|
|
2470
|
-
if (this.$parent !== null) return;
|
|
2471
|
-
context.hydrate();
|
|
2472
|
-
} });
|
|
2473
|
-
}
|
|
2474
|
-
});
|
|
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);
|
|
2475
2675
|
}
|
|
2476
2676
|
/**
|
|
2477
|
-
* Returns the current
|
|
2677
|
+
* Returns the current single selection instance.
|
|
2478
2678
|
*
|
|
2479
|
-
* @param namespace The namespace for the
|
|
2480
|
-
* @returns The current
|
|
2679
|
+
* @param namespace The namespace for the single selection context. Defaults to `'v0:single'`.
|
|
2680
|
+
* @returns The current single selection instance.
|
|
2481
2681
|
*
|
|
2482
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
2682
|
+
* @see https://0.vuetifyjs.com/composables/selection/use-single
|
|
2483
2683
|
*
|
|
2484
2684
|
* @example
|
|
2485
2685
|
* ```vue
|
|
2486
2686
|
* <script setup lang="ts">
|
|
2487
|
-
* import {
|
|
2687
|
+
* import { useSingle } from '@vuetify/v0'
|
|
2488
2688
|
*
|
|
2489
|
-
* const
|
|
2689
|
+
* const tabs = useSingle()
|
|
2490
2690
|
* <\/script>
|
|
2491
2691
|
*
|
|
2492
2692
|
* <template>
|
|
2493
2693
|
* <div>
|
|
2494
|
-
* <p>
|
|
2694
|
+
* <p>Selected: {{ tabs.selectedId }}</p>
|
|
2495
2695
|
* </div>
|
|
2496
2696
|
* </template>
|
|
2497
2697
|
* ```
|
|
2498
2698
|
*/
|
|
2499
|
-
function
|
|
2500
|
-
|
|
2501
|
-
if (!getCurrentInstance()) return fallback;
|
|
2502
|
-
try {
|
|
2503
|
-
return useContext(namespace, fallback);
|
|
2504
|
-
} catch {
|
|
2505
|
-
return fallback;
|
|
2506
|
-
}
|
|
2699
|
+
function useSingle(namespace = "v0:single") {
|
|
2700
|
+
return useContext(namespace);
|
|
2507
2701
|
}
|
|
2508
2702
|
|
|
2509
2703
|
//#endregion
|
|
2510
|
-
//#region src/composables/
|
|
2511
|
-
/**
|
|
2512
|
-
* @module useResizeObserver
|
|
2513
|
-
*
|
|
2514
|
-
* @remarks
|
|
2515
|
-
* ResizeObserver composable with lifecycle management.
|
|
2516
|
-
*
|
|
2517
|
-
* Key features:
|
|
2518
|
-
* - ResizeObserver API wrapper
|
|
2519
|
-
* - Pause/resume/stop functionality
|
|
2520
|
-
* - Automatic cleanup on unmount
|
|
2521
|
-
* - SSR-safe (checks SUPPORTS_OBSERVER)
|
|
2522
|
-
* - Hydration-aware
|
|
2523
|
-
* - Box model options (content-box/border-box)
|
|
2524
|
-
*
|
|
2525
|
-
* Perfect for responsive components and size-based rendering.
|
|
2526
|
-
*/
|
|
2704
|
+
//#region src/composables/useTokens/index.ts
|
|
2527
2705
|
/**
|
|
2528
|
-
*
|
|
2529
|
-
* size changes.
|
|
2706
|
+
* Creates a new token instance.
|
|
2530
2707
|
*
|
|
2531
|
-
* @param
|
|
2532
|
-
* @param
|
|
2533
|
-
* @
|
|
2534
|
-
* @
|
|
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.
|
|
2535
2713
|
*
|
|
2536
|
-
* @see https://
|
|
2537
|
-
* @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
|
|
2538
2716
|
*
|
|
2539
2717
|
* @example
|
|
2540
2718
|
* ```ts
|
|
2541
|
-
* import {
|
|
2542
|
-
* import { useResizeObserver } from '@vuetify/v0'
|
|
2543
|
-
*
|
|
2544
|
-
* const el = ref<HTMLElement>()
|
|
2545
|
-
* const width = ref(0)
|
|
2546
|
-
* const height = ref(0)
|
|
2719
|
+
* import { useTokens } from '@vuetify/v0'
|
|
2547
2720
|
*
|
|
2548
|
-
* const
|
|
2549
|
-
*
|
|
2550
|
-
*
|
|
2551
|
-
*
|
|
2552
|
-
* if (entry) {
|
|
2553
|
-
* width.value = entry.contentRect.width
|
|
2554
|
-
* height.value = entry.contentRect.height
|
|
2555
|
-
* console.log('Size changed:', width.value, 'x', height.value)
|
|
2556
|
-
* }
|
|
2721
|
+
* const tokens = useTokens({
|
|
2722
|
+
* colors: {
|
|
2723
|
+
* primary: '#3b82f6',
|
|
2724
|
+
* secondary: '{colors.primary}', // Alias reference
|
|
2557
2725
|
* },
|
|
2558
|
-
*
|
|
2559
|
-
* )
|
|
2560
|
-
*
|
|
2561
|
-
* // Pause observation
|
|
2562
|
-
* pause()
|
|
2726
|
+
* })
|
|
2563
2727
|
*
|
|
2564
|
-
* //
|
|
2565
|
-
*
|
|
2728
|
+
* console.log(tokens.resolve('{colors.primary}')) // '#3b82f6'
|
|
2729
|
+
* console.log(tokens.resolve('{colors.secondary}')) // '#3b82f6'
|
|
2566
2730
|
* ```
|
|
2567
2731
|
*/
|
|
2568
|
-
function
|
|
2569
|
-
const
|
|
2570
|
-
const
|
|
2571
|
-
const
|
|
2572
|
-
|
|
2573
|
-
function
|
|
2574
|
-
|
|
2575
|
-
observer.value = new ResizeObserver((entries) => {
|
|
2576
|
-
callback(entries.map((entry) => ({
|
|
2577
|
-
contentRect: {
|
|
2578
|
-
width: entry.contentRect.width,
|
|
2579
|
-
height: entry.contentRect.height,
|
|
2580
|
-
top: entry.contentRect.top,
|
|
2581
|
-
left: entry.contentRect.left
|
|
2582
|
-
},
|
|
2583
|
-
target: entry.target
|
|
2584
|
-
})));
|
|
2585
|
-
});
|
|
2586
|
-
observer.value.observe(target.value, { box: options.box || "content-box" });
|
|
2587
|
-
if (options.immediate) {
|
|
2588
|
-
const rect = target.value.getBoundingClientRect();
|
|
2589
|
-
callback([{
|
|
2590
|
-
contentRect: {
|
|
2591
|
-
width: rect.width,
|
|
2592
|
-
height: rect.height,
|
|
2593
|
-
top: rect.top,
|
|
2594
|
-
left: rect.left
|
|
2595
|
-
},
|
|
2596
|
-
target: target.value
|
|
2597
|
-
}]);
|
|
2598
|
-
}
|
|
2599
|
-
}
|
|
2600
|
-
watch([isHydrated, target], () => {
|
|
2601
|
-
cleanup();
|
|
2602
|
-
setup();
|
|
2603
|
-
}, { immediate: true });
|
|
2604
|
-
function cleanup() {
|
|
2605
|
-
if (observer.value) {
|
|
2606
|
-
observer.value.disconnect();
|
|
2607
|
-
observer.value = void 0;
|
|
2608
|
-
}
|
|
2609
|
-
}
|
|
2610
|
-
function pause() {
|
|
2611
|
-
isPaused.value = true;
|
|
2612
|
-
observer.value?.disconnect();
|
|
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) === "}";
|
|
2613
2739
|
}
|
|
2614
|
-
function
|
|
2615
|
-
|
|
2616
|
-
setup();
|
|
2740
|
+
function isTokenAlias(value) {
|
|
2741
|
+
return /* @__PURE__ */ isObject(value) && "$value" in value;
|
|
2617
2742
|
}
|
|
2618
|
-
function
|
|
2619
|
-
|
|
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;
|
|
2620
2802
|
}
|
|
2621
|
-
onScopeDispose(stop, true);
|
|
2622
2803
|
return {
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2804
|
+
...registry,
|
|
2805
|
+
resolve,
|
|
2806
|
+
isAlias,
|
|
2807
|
+
get size() {
|
|
2808
|
+
return registry.size;
|
|
2809
|
+
}
|
|
2628
2810
|
};
|
|
2629
2811
|
}
|
|
2630
2812
|
/**
|
|
2631
|
-
*
|
|
2632
|
-
* element's size.
|
|
2813
|
+
* Creates a new token context.
|
|
2633
2814
|
*
|
|
2634
|
-
* @param
|
|
2635
|
-
* @
|
|
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.
|
|
2636
2820
|
*
|
|
2637
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
2821
|
+
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
2638
2822
|
*
|
|
2639
2823
|
* @example
|
|
2640
2824
|
* ```ts
|
|
2641
|
-
* import {
|
|
2642
|
-
* import { useElementSize } from '@vuetify/v0'
|
|
2643
|
-
*
|
|
2644
|
-
* const box = ref<HTMLElement>()
|
|
2645
|
-
* const { width, height } = useElementSize(box)
|
|
2825
|
+
* import { createTokensContext } from '@vuetify/v0'
|
|
2646
2826
|
*
|
|
2647
|
-
*
|
|
2648
|
-
*
|
|
2649
|
-
*
|
|
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
|
+
* },
|
|
2650
2835
|
* })
|
|
2651
2836
|
* ```
|
|
2652
2837
|
*/
|
|
2653
|
-
function
|
|
2654
|
-
const
|
|
2655
|
-
const
|
|
2656
|
-
const
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
width.value = entry.contentRect.width;
|
|
2660
|
-
height.value = entry.contentRect.height;
|
|
2661
|
-
}
|
|
2662
|
-
}, { immediate: true });
|
|
2663
|
-
function pause() {
|
|
2664
|
-
width.value = 0;
|
|
2665
|
-
height.value = 0;
|
|
2666
|
-
_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);
|
|
2667
2844
|
}
|
|
2668
|
-
return
|
|
2669
|
-
width,
|
|
2670
|
-
height,
|
|
2671
|
-
isActive,
|
|
2672
|
-
isPaused,
|
|
2673
|
-
pause,
|
|
2674
|
-
resume,
|
|
2675
|
-
stop
|
|
2676
|
-
};
|
|
2845
|
+
return createTrinity(useTokensContext, provideTokensContext, context);
|
|
2677
2846
|
}
|
|
2678
|
-
|
|
2679
|
-
//#endregion
|
|
2680
|
-
//#region src/composables/useOverflow/index.ts
|
|
2681
2847
|
/**
|
|
2682
|
-
*
|
|
2683
|
-
*
|
|
2684
|
-
* @remarks
|
|
2685
|
-
* Composable for computing how many items fit in a container based on available width.
|
|
2686
|
-
* Enables responsive truncation logic for Pagination, Breadcrumbs, and similar components.
|
|
2848
|
+
* Returns the current tokens instance.
|
|
2687
2849
|
*
|
|
2688
|
-
*
|
|
2689
|
-
*
|
|
2690
|
-
* - Two modes: variable-width (per-item) or uniform-width (sample-based)
|
|
2691
|
-
* - Computes capacity (how many items fit)
|
|
2692
|
-
* - SSR-safe with Infinity fallback
|
|
2693
|
-
* - Supports reserved space for nav buttons, ellipsis, etc.
|
|
2694
|
-
*
|
|
2695
|
-
* Use variable mode (default) for items with different widths like Breadcrumbs.
|
|
2696
|
-
* Use uniform mode (itemWidth option) for same-width items like Pagination buttons.
|
|
2697
|
-
*/
|
|
2698
|
-
/**
|
|
2699
|
-
* 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.
|
|
2700
2852
|
*
|
|
2701
|
-
* @
|
|
2702
|
-
* @returns Overflow context with container ref, capacity, and measurement functions
|
|
2853
|
+
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
2703
2854
|
*
|
|
2704
|
-
* @example
|
|
2855
|
+
* @example
|
|
2705
2856
|
* ```vue
|
|
2706
|
-
* <script lang="ts"
|
|
2707
|
-
* import {
|
|
2708
|
-
* import { createOverflow } from '@vuetify/v0'
|
|
2857
|
+
* <script setup lang="ts">
|
|
2858
|
+
* import { useTokens } from '@vuetify/v0'
|
|
2709
2859
|
*
|
|
2710
|
-
* const
|
|
2711
|
-
* const overflow = createOverflow({
|
|
2712
|
-
* container: containerRef,
|
|
2713
|
-
* gap: 8,
|
|
2714
|
-
* reserved: 40,
|
|
2715
|
-
* })
|
|
2860
|
+
* const tokens = useTokens()
|
|
2716
2861
|
* <\/script>
|
|
2717
|
-
*
|
|
2718
|
-
* <template>
|
|
2719
|
-
* <div ref="container">
|
|
2720
|
-
* <span
|
|
2721
|
-
* v-for="(item, i) in items.slice(0, overflow.capacity.value)"
|
|
2722
|
-
* :key="i"
|
|
2723
|
-
* :ref="el => overflow.measure(i, el)"
|
|
2724
|
-
* >
|
|
2725
|
-
* {{ item }}
|
|
2726
|
-
* </span>
|
|
2727
|
-
* <span v-if="overflow.isOverflowing.value">...</span>
|
|
2728
|
-
* </div>
|
|
2729
|
-
* </template>
|
|
2730
|
-
* ```
|
|
2731
|
-
*
|
|
2732
|
-
* @example Uniform-width mode (Pagination)
|
|
2733
|
-
* ```ts
|
|
2734
|
-
* const overflow = createOverflow({
|
|
2735
|
-
* container: () => atom.value?.element,
|
|
2736
|
-
* itemWidth: buttonWidth,
|
|
2737
|
-
* reserved: () => buttonWidth.value * 4,
|
|
2738
|
-
* })
|
|
2739
2862
|
* ```
|
|
2740
2863
|
*/
|
|
2741
|
-
function
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2864
|
+
function useTokens(namespace = "v0:tokens") {
|
|
2865
|
+
return useContext(namespace);
|
|
2866
|
+
}
|
|
2867
|
+
/**
|
|
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;
|
|
2752
2899
|
}
|
|
2753
|
-
|
|
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
|
+
});
|
|
2754
2938
|
}
|
|
2755
|
-
const style = getComputedStyle(el);
|
|
2756
|
-
const marginX = Number.parseFloat(style.marginLeft) + Number.parseFloat(style.marginRight);
|
|
2757
|
-
const w = el.offsetWidth + marginX;
|
|
2758
|
-
if (widths.value.get(index) !== w) widths.value = new Map(widths.value).set(index, w);
|
|
2759
2939
|
}
|
|
2760
|
-
|
|
2761
|
-
|
|
2940
|
+
return flattened;
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
//#endregion
|
|
2944
|
+
//#region src/composables/useLocale/index.ts
|
|
2945
|
+
/**
|
|
2946
|
+
* Creates a new locale instance.
|
|
2947
|
+
*
|
|
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.
|
|
2952
|
+
*
|
|
2953
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-locale
|
|
2954
|
+
*/
|
|
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);
|
|
2762
2962
|
}
|
|
2763
|
-
|
|
2764
|
-
const
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
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;
|
|
2770
2991
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
2992
|
+
};
|
|
2993
|
+
}
|
|
2994
|
+
function createLocaleFallback() {
|
|
2773
2995
|
return {
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
const available = width.value - toValue(reserved);
|
|
2778
|
-
if (width.value === 0) return Infinity;
|
|
2779
|
-
if (available <= 0) return 0;
|
|
2780
|
-
const g = toValue(gap);
|
|
2781
|
-
const uniformWidth = toValue(itemWidth);
|
|
2782
|
-
if (uniformWidth && uniformWidth > 0) {
|
|
2783
|
-
const first = uniformWidth;
|
|
2784
|
-
const subsequent = uniformWidth + g;
|
|
2785
|
-
if (available < first) return 0;
|
|
2786
|
-
return Math.max(1, Math.floor((available - first) / subsequent) + 1);
|
|
2787
|
-
}
|
|
2788
|
-
const entries = [...widths.value.entries()].toSorted((a, b) => a[0] - b[0]);
|
|
2789
|
-
if (toValue(reverse)) entries.reverse();
|
|
2790
|
-
let sum = 0;
|
|
2791
|
-
let count = 0;
|
|
2792
|
-
for (const [, w] of entries) {
|
|
2793
|
-
const next = sum + w + (count > 0 ? g : 0);
|
|
2794
|
-
if (next > available) break;
|
|
2795
|
-
sum = next;
|
|
2796
|
-
count++;
|
|
2797
|
-
}
|
|
2798
|
-
return count;
|
|
2799
|
-
}),
|
|
2800
|
-
total,
|
|
2801
|
-
isOverflowing: toRef(() => {
|
|
2802
|
-
return total.value > width.value - toValue(reserved);
|
|
2803
|
-
}),
|
|
2804
|
-
measure,
|
|
2805
|
-
reset
|
|
2996
|
+
size: 0,
|
|
2997
|
+
t: (key, _params, fallback) => fallback ?? key,
|
|
2998
|
+
n: String
|
|
2806
2999
|
};
|
|
2807
3000
|
}
|
|
2808
3001
|
/**
|
|
2809
|
-
* Creates
|
|
3002
|
+
* Creates a new locale context.
|
|
2810
3003
|
*
|
|
2811
|
-
* @param options
|
|
2812
|
-
* @
|
|
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
|
|
2813
3010
|
*
|
|
2814
3011
|
* @example
|
|
2815
3012
|
* ```ts
|
|
2816
|
-
*
|
|
2817
|
-
*
|
|
2818
|
-
*
|
|
2819
|
-
*
|
|
2820
|
-
*
|
|
3013
|
+
* import { createLocaleContext } from '@vuetify/v0'
|
|
3014
|
+
*
|
|
3015
|
+
* export const [useAppLocale, provideAppLocale, appLocale] = createLocaleContext({
|
|
3016
|
+
* namespace: 'app:locale',
|
|
3017
|
+
* messages: {
|
|
3018
|
+
* en: { hello: 'Hello' },
|
|
3019
|
+
* es: { hello: 'Hola' },
|
|
3020
|
+
* },
|
|
2821
3021
|
* })
|
|
2822
3022
|
*
|
|
2823
|
-
* // In parent component
|
|
2824
|
-
*
|
|
3023
|
+
* // In a parent component:
|
|
3024
|
+
* provideAppLocale()
|
|
2825
3025
|
*
|
|
2826
|
-
* // In child component
|
|
2827
|
-
* const
|
|
3026
|
+
* // In a child component:
|
|
3027
|
+
* const locale = useAppLocale()
|
|
3028
|
+
* locale.select('es')
|
|
2828
3029
|
* ```
|
|
2829
3030
|
*/
|
|
2830
|
-
function
|
|
2831
|
-
const { namespace = "v0:
|
|
2832
|
-
const [
|
|
2833
|
-
const context =
|
|
2834
|
-
function
|
|
2835
|
-
return
|
|
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);
|
|
2836
3037
|
}
|
|
2837
|
-
return createTrinity(
|
|
3038
|
+
return createTrinity(useLocaleContext, provideLocaleContext, context);
|
|
2838
3039
|
}
|
|
2839
3040
|
/**
|
|
2840
|
-
*
|
|
3041
|
+
* Creates a new locale plugin.
|
|
2841
3042
|
*
|
|
2842
|
-
* @param
|
|
2843
|
-
* @
|
|
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.
|
|
2844
3049
|
*
|
|
2845
|
-
* @
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
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
|
+
});
|
|
3066
|
+
}
|
|
3067
|
+
/**
|
|
3068
|
+
* Returns the current locale instance.
|
|
2849
3069
|
*
|
|
2850
|
-
*
|
|
2851
|
-
* const overflow = useOverflow()
|
|
2852
|
-
* <\/script>
|
|
3070
|
+
* @returns The current locale instance.
|
|
2853
3071
|
*
|
|
2854
|
-
*
|
|
2855
|
-
* <div>
|
|
2856
|
-
* <p>Capacity: {{ overflow.capacity.value }}</p>
|
|
2857
|
-
* </div>
|
|
2858
|
-
* </template>
|
|
2859
|
-
* ```
|
|
3072
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-locale
|
|
2860
3073
|
*/
|
|
2861
|
-
function
|
|
2862
|
-
|
|
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
|
+
}
|
|
2863
3082
|
}
|
|
2864
3083
|
|
|
2865
3084
|
//#endregion
|
|
2866
|
-
//#region src/composables/
|
|
3085
|
+
//#region src/composables/useHydration/index.ts
|
|
2867
3086
|
/**
|
|
2868
|
-
*
|
|
2869
|
-
*
|
|
2870
|
-
* @remarks
|
|
2871
|
-
* Lightweight pagination composable for navigating through pages.
|
|
3087
|
+
* Creates a new hydration instance.
|
|
2872
3088
|
*
|
|
2873
|
-
*
|
|
2874
|
-
* - No registry overhead - just a bounded integer
|
|
2875
|
-
* - Direct ref support for v-model compatibility
|
|
2876
|
-
* - Navigation methods: next, prev, first, last
|
|
2877
|
-
* - Computed visible items with ellipsis
|
|
2878
|
-
* - Trinity pattern for dependency injection
|
|
2879
|
-
*
|
|
2880
|
-
* Unlike registry-based composables, pagination tracks a single number
|
|
2881
|
-
* within a range, making it efficient for large page counts.
|
|
2882
|
-
*/
|
|
2883
|
-
/**
|
|
2884
|
-
* Creates a pagination instance.
|
|
3089
|
+
* @returns A new hydration instance.
|
|
2885
3090
|
*
|
|
2886
|
-
* @
|
|
2887
|
-
* @returns A pagination context with navigation methods.
|
|
3091
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-hydration
|
|
2888
3092
|
*
|
|
2889
3093
|
* @example
|
|
2890
3094
|
* ```ts
|
|
2891
|
-
* import {
|
|
2892
|
-
*
|
|
2893
|
-
* // Basic usage
|
|
2894
|
-
* const pagination = createPagination({ size: 100 })
|
|
2895
|
-
* pagination.next()
|
|
2896
|
-
* pagination.items.value // [{ type: 'page', value: 1 }, { type: 'page', value: 2 }, ...]
|
|
3095
|
+
* import { createHydration } from '@vuetify/v0'
|
|
2897
3096
|
*
|
|
2898
|
-
*
|
|
2899
|
-
*
|
|
2900
|
-
*
|
|
2901
|
-
*
|
|
3097
|
+
* const hydration = createHydration()
|
|
3098
|
+
* console.log(hydration.isHydrated.value) // false
|
|
3099
|
+
* hydration.hydrate()
|
|
3100
|
+
* console.log(hydration.isHydrated.value) // true
|
|
2902
3101
|
* ```
|
|
2903
3102
|
*/
|
|
2904
|
-
function
|
|
2905
|
-
const
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
const size = toValue(_size);
|
|
2909
|
-
const perPage = toValue(_itemsPerPage);
|
|
2910
|
-
if (size <= 0 || /* @__PURE__ */ isNaN(size)) return 0;
|
|
2911
|
-
return Math.ceil(size / perPage);
|
|
2912
|
-
});
|
|
2913
|
-
function first() {
|
|
2914
|
-
page.value = 1;
|
|
2915
|
-
}
|
|
2916
|
-
function last() {
|
|
2917
|
-
page.value = Math.max(1, pages.value);
|
|
2918
|
-
}
|
|
2919
|
-
function next() {
|
|
2920
|
-
if (page.value < pages.value) page.value++;
|
|
2921
|
-
}
|
|
2922
|
-
function prev() {
|
|
2923
|
-
if (page.value > 1) page.value--;
|
|
2924
|
-
}
|
|
2925
|
-
function select(value) {
|
|
2926
|
-
if (value < 1) page.value = 1;
|
|
2927
|
-
else if (value > pages.value) page.value = Math.max(1, pages.value);
|
|
2928
|
-
else page.value = value;
|
|
2929
|
-
}
|
|
2930
|
-
const isFirst = computed(() => page.value <= 1);
|
|
2931
|
-
const isLast = computed(() => page.value >= pages.value);
|
|
2932
|
-
const pageStart = computed(() => (page.value - 1) * toValue(_itemsPerPage));
|
|
2933
|
-
const pageStop = computed(() => Math.min(pageStart.value + toValue(_itemsPerPage), toValue(_size)));
|
|
2934
|
-
function toPage(value) {
|
|
2935
|
-
return {
|
|
2936
|
-
type: "page",
|
|
2937
|
-
value
|
|
2938
|
-
};
|
|
2939
|
-
}
|
|
2940
|
-
function toEllipsis() {
|
|
2941
|
-
return ellipsis === false ? false : {
|
|
2942
|
-
type: "ellipsis",
|
|
2943
|
-
value: ellipsis
|
|
2944
|
-
};
|
|
2945
|
-
}
|
|
2946
|
-
function filter(array) {
|
|
2947
|
-
return array.filter(Boolean);
|
|
3103
|
+
function createHydration() {
|
|
3104
|
+
const isHydrated = shallowRef(false);
|
|
3105
|
+
function hydrate() {
|
|
3106
|
+
isHydrated.value = true;
|
|
2948
3107
|
}
|
|
2949
3108
|
return {
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
if (visible <= 2) return [toPage(current)];
|
|
2959
|
-
if (pageCount <= visible) return (/* @__PURE__ */ range(pageCount, 1)).map(toPage);
|
|
2960
|
-
if (visible === 3) {
|
|
2961
|
-
const mid = current <= 1 ? 2 : current >= pageCount ? pageCount - 1 : current;
|
|
2962
|
-
return [
|
|
2963
|
-
toPage(1),
|
|
2964
|
-
toPage(mid),
|
|
2965
|
-
toPage(pageCount)
|
|
2966
|
-
];
|
|
2967
|
-
}
|
|
2968
|
-
const boundary = visible - 2;
|
|
2969
|
-
const middle = visible - 4;
|
|
2970
|
-
if (middle <= 0) {
|
|
2971
|
-
if (current <= boundary) return filter([
|
|
2972
|
-
...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
|
|
2973
|
-
toEllipsis(),
|
|
2974
|
-
toPage(pageCount)
|
|
2975
|
-
]);
|
|
2976
|
-
if (current > pageCount - boundary) return filter([
|
|
2977
|
-
toPage(1),
|
|
2978
|
-
toEllipsis(),
|
|
2979
|
-
...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
|
|
2980
|
-
]);
|
|
2981
|
-
return current <= Math.ceil(pageCount / 2) ? filter([
|
|
2982
|
-
toPage(1),
|
|
2983
|
-
toPage(current),
|
|
2984
|
-
toEllipsis(),
|
|
2985
|
-
toPage(pageCount)
|
|
2986
|
-
]) : filter([
|
|
2987
|
-
toPage(1),
|
|
2988
|
-
toEllipsis(),
|
|
2989
|
-
toPage(current),
|
|
2990
|
-
toPage(pageCount)
|
|
2991
|
-
]);
|
|
2992
|
-
}
|
|
2993
|
-
const leftThreshold = boundary - 1;
|
|
2994
|
-
const rightThreshold = pageCount - boundary + 2;
|
|
2995
|
-
if (current <= leftThreshold) return filter([
|
|
2996
|
-
...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
|
|
2997
|
-
toEllipsis(),
|
|
2998
|
-
toPage(pageCount)
|
|
2999
|
-
]);
|
|
3000
|
-
else if (current >= rightThreshold) return filter([
|
|
3001
|
-
toPage(1),
|
|
3002
|
-
toEllipsis(),
|
|
3003
|
-
...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
|
|
3004
|
-
]);
|
|
3005
|
-
else {
|
|
3006
|
-
const start = current - Math.floor(middle / 2);
|
|
3007
|
-
return filter([
|
|
3008
|
-
toPage(1),
|
|
3009
|
-
toEllipsis(),
|
|
3010
|
-
...(/* @__PURE__ */ range(middle, start)).map(toPage),
|
|
3011
|
-
toEllipsis(),
|
|
3012
|
-
toPage(pageCount)
|
|
3013
|
-
]);
|
|
3014
|
-
}
|
|
3015
|
-
}),
|
|
3016
|
-
pageStart,
|
|
3017
|
-
pageStop,
|
|
3018
|
-
isFirst,
|
|
3019
|
-
isLast,
|
|
3020
|
-
first,
|
|
3021
|
-
last,
|
|
3022
|
-
next,
|
|
3023
|
-
prev,
|
|
3024
|
-
select,
|
|
3025
|
-
get itemsPerPage() {
|
|
3026
|
-
return toValue(_itemsPerPage);
|
|
3027
|
-
},
|
|
3028
|
-
get size() {
|
|
3029
|
-
return toValue(_size);
|
|
3030
|
-
},
|
|
3031
|
-
get pages() {
|
|
3032
|
-
return pages.value;
|
|
3033
|
-
}
|
|
3109
|
+
isHydrated: shallowReadonly(isHydrated),
|
|
3110
|
+
hydrate
|
|
3111
|
+
};
|
|
3112
|
+
}
|
|
3113
|
+
function createFallbackHydration() {
|
|
3114
|
+
return {
|
|
3115
|
+
isHydrated: shallowReadonly(shallowRef(true)),
|
|
3116
|
+
hydrate: () => {}
|
|
3034
3117
|
};
|
|
3035
3118
|
}
|
|
3036
3119
|
/**
|
|
3037
|
-
* Creates a
|
|
3120
|
+
* Creates a new hydration context trinity.
|
|
3121
|
+
*
|
|
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
|
|
3127
|
+
*
|
|
3128
|
+
* @example
|
|
3129
|
+
* ```ts
|
|
3130
|
+
* import { createHydrationContext } from '@vuetify/v0'
|
|
3131
|
+
*
|
|
3132
|
+
* export const [useHydrationContext, provideHydrationContext, context] = createHydrationContext({
|
|
3133
|
+
* namespace: 'app:hydration',
|
|
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.
|
|
3038
3148
|
*
|
|
3039
|
-
* @param options The options
|
|
3040
|
-
* @
|
|
3149
|
+
* @param options The options for the hydration plugin.
|
|
3150
|
+
* @template E The type of the hydration context.
|
|
3151
|
+
* @returns A new hydration plugin.
|
|
3152
|
+
*
|
|
3153
|
+
* @see https://0.vuetifyjs.com/composables/plugins/use-hydration
|
|
3041
3154
|
*
|
|
3042
3155
|
* @example
|
|
3043
3156
|
* ```ts
|
|
3044
|
-
*
|
|
3045
|
-
*
|
|
3157
|
+
* import { createApp } from 'vue'
|
|
3158
|
+
* import { createHydrationPlugin } from '@vuetify/v0'
|
|
3159
|
+
* import App from './App.vue'
|
|
3046
3160
|
*
|
|
3047
|
-
*
|
|
3048
|
-
* const [usePagination, providePaginationContext] = createPaginationContext({
|
|
3049
|
-
* namespace: 'my-pagination',
|
|
3050
|
-
* size: 50,
|
|
3051
|
-
* })
|
|
3161
|
+
* const app = createApp(App)
|
|
3052
3162
|
*
|
|
3053
|
-
*
|
|
3054
|
-
* providePaginationContext()
|
|
3163
|
+
* app.use(createHydrationPlugin())
|
|
3055
3164
|
*
|
|
3056
|
-
*
|
|
3057
|
-
* const pagination = usePagination()
|
|
3058
|
-
* pagination.next()
|
|
3165
|
+
* app.mount('#app')
|
|
3059
3166
|
* ```
|
|
3060
3167
|
*/
|
|
3061
|
-
function
|
|
3062
|
-
const { namespace = "v0:
|
|
3063
|
-
const [
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
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
|
+
});
|
|
3069
3186
|
}
|
|
3070
3187
|
/**
|
|
3071
|
-
* Returns the current
|
|
3188
|
+
* Returns the current hydration instance.
|
|
3072
3189
|
*
|
|
3073
|
-
* @param namespace The namespace.
|
|
3074
|
-
* @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
|
|
3075
3194
|
*
|
|
3076
3195
|
* @example
|
|
3077
3196
|
* ```vue
|
|
3078
|
-
* <script setup>
|
|
3079
|
-
*
|
|
3197
|
+
* <script setup lang="ts">
|
|
3198
|
+
* import { useHydration } from '@vuetify/v0'
|
|
3080
3199
|
*
|
|
3081
|
-
*
|
|
3200
|
+
* const hydration = useHydration()
|
|
3082
3201
|
* <\/script>
|
|
3083
3202
|
*
|
|
3084
3203
|
* <template>
|
|
3085
|
-
* <
|
|
3086
|
-
*
|
|
3204
|
+
* <div>
|
|
3205
|
+
* <p>Is hydrated: {{ hydration.isHydrated.value }}</p>
|
|
3206
|
+
* </div>
|
|
3087
3207
|
* </template>
|
|
3088
3208
|
* ```
|
|
3089
3209
|
*/
|
|
3090
|
-
function
|
|
3091
|
-
|
|
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
|
+
}
|
|
3092
3218
|
}
|
|
3093
3219
|
|
|
3094
3220
|
//#endregion
|
|
3095
|
-
//#region src/composables/
|
|
3096
|
-
/**
|
|
3097
|
-
* @module useSingle
|
|
3098
|
-
*
|
|
3099
|
-
* @remarks
|
|
3100
|
-
* Single-selection composable that extends useSelection to enforce only one selected item.
|
|
3101
|
-
*
|
|
3102
|
-
* Key features:
|
|
3103
|
-
* - Auto-clears previous selection when selecting new item
|
|
3104
|
-
* - Singular computed properties (selectedId, selectedItem, selectedIndex, selectedValue)
|
|
3105
|
-
* - Perfect for tabs, radio buttons, theme selectors
|
|
3106
|
-
*
|
|
3107
|
-
* Inheritance chain: useRegistry → useSelection → useSingle
|
|
3108
|
-
*/
|
|
3221
|
+
//#region src/composables/useResizeObserver/index.ts
|
|
3109
3222
|
/**
|
|
3110
|
-
*
|
|
3111
|
-
*
|
|
3112
|
-
* Extends `createSelection` by automatically clearing previous selections when a new item is selected.
|
|
3113
|
-
* Adds computed singular properties: `selectedId`, `selectedItem`, `selectedIndex`, `selectedValue`.
|
|
3114
|
-
*
|
|
3115
|
-
* @param options The options for the single selection instance.
|
|
3116
|
-
* @template Z The type of the single selection ticket.
|
|
3117
|
-
* @template E The type of the single selection context.
|
|
3118
|
-
* @returns A new single selection instance with single-selection enforcement.
|
|
3119
|
-
*
|
|
3120
|
-
* @remarks
|
|
3121
|
-
* **Key Differences from `createSelection`:**
|
|
3122
|
-
* - Automatically clears `selectedIds` before selecting a new item (enforces single selection)
|
|
3123
|
-
* - Provides singular computed properties instead of plural sets
|
|
3124
|
-
* - Perfect for tabs, radio buttons, theme selectors, and other single-choice UI components
|
|
3125
|
-
*
|
|
3126
|
-
* **Computed Properties:**
|
|
3127
|
-
* - `selectedId`: The ID of the selected item (undefined if none selected)
|
|
3128
|
-
* - `selectedItem`: The selected ticket object (undefined if none selected)
|
|
3129
|
-
* - `selectedIndex`: The index of the selected item (-1 if none selected)
|
|
3130
|
-
* - `selectedValue`: The value of the selected item (undefined if none selected)
|
|
3223
|
+
* A composable that uses the Resize Observer API to detect when an element's
|
|
3224
|
+
* size changes.
|
|
3131
3225
|
*
|
|
3132
|
-
*
|
|
3133
|
-
*
|
|
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.
|
|
3134
3230
|
*
|
|
3135
|
-
* @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
|
|
3136
3233
|
*
|
|
3137
3234
|
* @example
|
|
3138
3235
|
* ```ts
|
|
3139
|
-
* import {
|
|
3140
|
-
*
|
|
3141
|
-
* const tabs = createSingle({ mandatory: true })
|
|
3236
|
+
* import { ref } from 'vue'
|
|
3237
|
+
* import { useResizeObserver } from '@vuetify/v0'
|
|
3142
3238
|
*
|
|
3143
|
-
*
|
|
3144
|
-
*
|
|
3145
|
-
*
|
|
3146
|
-
* { id: 'contact', value: 'Contact' },
|
|
3147
|
-
* ])
|
|
3239
|
+
* const el = ref<HTMLElement>()
|
|
3240
|
+
* const width = ref(0)
|
|
3241
|
+
* const height = ref(0)
|
|
3148
3242
|
*
|
|
3149
|
-
*
|
|
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
|
+
* )
|
|
3150
3255
|
*
|
|
3151
|
-
*
|
|
3152
|
-
*
|
|
3256
|
+
* // Pause observation
|
|
3257
|
+
* pause()
|
|
3153
3258
|
*
|
|
3154
|
-
*
|
|
3155
|
-
*
|
|
3156
|
-
* console.log(tabs.selectedIds.size) // 1 (always enforces single selection)
|
|
3259
|
+
* // Resume observation
|
|
3260
|
+
* resume()
|
|
3157
3261
|
* ```
|
|
3158
3262
|
*/
|
|
3159
|
-
function
|
|
3160
|
-
const {
|
|
3161
|
-
const
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
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();
|
|
3165
3302
|
});
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
if (mandatory && registry.selectedIds.size === 1) return;
|
|
3172
|
-
registry.selectedIds.delete(id);
|
|
3303
|
+
function cleanup() {
|
|
3304
|
+
if (observer.value) {
|
|
3305
|
+
observer.value.disconnect();
|
|
3306
|
+
observer.value = void 0;
|
|
3307
|
+
}
|
|
3173
3308
|
}
|
|
3174
|
-
function
|
|
3175
|
-
|
|
3176
|
-
|
|
3309
|
+
function pause() {
|
|
3310
|
+
isPaused.value = true;
|
|
3311
|
+
observer.value?.disconnect();
|
|
3312
|
+
}
|
|
3313
|
+
function resume() {
|
|
3314
|
+
isPaused.value = false;
|
|
3315
|
+
setup();
|
|
3316
|
+
}
|
|
3317
|
+
function stop() {
|
|
3318
|
+
cleanup();
|
|
3319
|
+
observer.value = null;
|
|
3177
3320
|
}
|
|
3321
|
+
onScopeDispose(stop, true);
|
|
3178
3322
|
return {
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
unselect,
|
|
3185
|
-
toggle,
|
|
3186
|
-
get size() {
|
|
3187
|
-
return registry.size;
|
|
3188
|
-
}
|
|
3323
|
+
isActive: shallowReadonly(isActive),
|
|
3324
|
+
isPaused: shallowReadonly(isPaused),
|
|
3325
|
+
pause,
|
|
3326
|
+
resume,
|
|
3327
|
+
stop
|
|
3189
3328
|
};
|
|
3190
3329
|
}
|
|
3191
3330
|
/**
|
|
3192
|
-
*
|
|
3331
|
+
* A convenience composable that uses the Resize Observer API to track an
|
|
3332
|
+
* element's size.
|
|
3193
3333
|
*
|
|
3194
|
-
* @param
|
|
3195
|
-
* @
|
|
3196
|
-
* @template E The type of the single selection context.
|
|
3197
|
-
* @returns A new single selection context.
|
|
3334
|
+
* @param target The element to observe.
|
|
3335
|
+
* @returns An object with the element's width and height.
|
|
3198
3336
|
*
|
|
3199
|
-
* @see https://0.vuetifyjs.com/composables/
|
|
3337
|
+
* @see https://0.vuetifyjs.com/composables/system/use-resize-observer#use-element-size
|
|
3200
3338
|
*
|
|
3201
3339
|
* @example
|
|
3202
3340
|
* ```ts
|
|
3203
|
-
* import {
|
|
3204
|
-
*
|
|
3205
|
-
* // With default namespace 'v0:single'
|
|
3206
|
-
* export const [useSingle, provideSingle, context] = createSingleContext()
|
|
3341
|
+
* import { ref, watchEffect } from 'vue'
|
|
3342
|
+
* import { useElementSize } from '@vuetify/v0'
|
|
3207
3343
|
*
|
|
3208
|
-
*
|
|
3209
|
-
*
|
|
3344
|
+
* const box = ref<HTMLElement>()
|
|
3345
|
+
* const { width, height } = useElementSize(box)
|
|
3210
3346
|
*
|
|
3211
|
-
* //
|
|
3212
|
-
*
|
|
3213
|
-
*
|
|
3347
|
+
* // Width and height are reactive refs
|
|
3348
|
+
* watchEffect(() => {
|
|
3349
|
+
* console.log('Box size:', width.value, 'x', height.value)
|
|
3350
|
+
* })
|
|
3214
3351
|
* ```
|
|
3215
3352
|
*/
|
|
3216
|
-
function
|
|
3217
|
-
const
|
|
3218
|
-
const
|
|
3219
|
-
const
|
|
3220
|
-
|
|
3221
|
-
|
|
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();
|
|
3222
3367
|
}
|
|
3223
|
-
return
|
|
3368
|
+
return {
|
|
3369
|
+
width,
|
|
3370
|
+
height,
|
|
3371
|
+
isActive,
|
|
3372
|
+
isPaused,
|
|
3373
|
+
pause,
|
|
3374
|
+
resume,
|
|
3375
|
+
stop
|
|
3376
|
+
};
|
|
3224
3377
|
}
|
|
3378
|
+
|
|
3379
|
+
//#endregion
|
|
3380
|
+
//#region src/composables/useOverflow/index.ts
|
|
3225
3381
|
/**
|
|
3226
|
-
*
|
|
3227
|
-
*
|
|
3228
|
-
* @param namespace The namespace for the single selection context. Defaults to `'v0:single'`.
|
|
3229
|
-
* @returns The current single selection instance.
|
|
3382
|
+
* Creates a new overflow context for computing how many items fit in a container.
|
|
3230
3383
|
*
|
|
3231
|
-
* @
|
|
3384
|
+
* @param options Configuration options
|
|
3385
|
+
* @returns Overflow context with container ref, capacity, and measurement functions
|
|
3232
3386
|
*
|
|
3233
|
-
* @example
|
|
3387
|
+
* @example Variable-width mode (Breadcrumbs)
|
|
3234
3388
|
* ```vue
|
|
3235
|
-
* <script
|
|
3236
|
-
* import {
|
|
3389
|
+
* <script lang="ts" setup>
|
|
3390
|
+
* import { useTemplateRef } from 'vue'
|
|
3391
|
+
* import { createOverflow } from '@vuetify/v0'
|
|
3237
3392
|
*
|
|
3238
|
-
* const
|
|
3393
|
+
* const containerRef = useTemplateRef('container')
|
|
3394
|
+
* const overflow = createOverflow({
|
|
3395
|
+
* container: containerRef,
|
|
3396
|
+
* gap: 8,
|
|
3397
|
+
* reserved: 40,
|
|
3398
|
+
* })
|
|
3239
3399
|
* <\/script>
|
|
3240
3400
|
*
|
|
3241
3401
|
* <template>
|
|
3242
|
-
* <div>
|
|
3243
|
-
* <
|
|
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>
|
|
3244
3411
|
* </div>
|
|
3245
3412
|
* </template>
|
|
3246
3413
|
* ```
|
|
3247
|
-
*/
|
|
3248
|
-
function useSingle(namespace = "v0:single") {
|
|
3249
|
-
return useContext(namespace);
|
|
3250
|
-
}
|
|
3251
|
-
|
|
3252
|
-
//#endregion
|
|
3253
|
-
//#region src/composables/useTokens/index.ts
|
|
3254
|
-
/**
|
|
3255
|
-
* @module useTokens
|
|
3256
|
-
*
|
|
3257
|
-
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
3258
3414
|
*
|
|
3259
|
-
* @
|
|
3260
|
-
* Design token registry with alias resolution and W3C Design Tokens format support.
|
|
3261
|
-
*
|
|
3262
|
-
* Key features:
|
|
3263
|
-
* - Alias resolution with circular reference detection
|
|
3264
|
-
* - Nested token flattening with dot notation
|
|
3265
|
-
* - W3C Design Tokens format ($value, $type, $description, $extensions)
|
|
3266
|
-
* - Path-based resolution (e.g., {colors}.blue.500)
|
|
3267
|
-
* - Resolution caching for performance (~28,590 ops/sec)
|
|
3268
|
-
*
|
|
3269
|
-
* Used by useTheme, useLocale, and useFeatures for token-based configuration.
|
|
3270
|
-
*/
|
|
3271
|
-
/**
|
|
3272
|
-
* Creates a new token instance.
|
|
3273
|
-
*
|
|
3274
|
-
* @param tokens The tokens to use.
|
|
3275
|
-
* @param options The options for the token instance.
|
|
3276
|
-
* @template Z The type of the token ticket.
|
|
3277
|
-
* @template E The type of the token context.
|
|
3278
|
-
* @returns A new token instance.
|
|
3279
|
-
*
|
|
3280
|
-
* @see https://www.designtokens.org/tr/drafts/format/
|
|
3281
|
-
* @see https://0.vuetifyjs.com/composables/registration/use-tokens
|
|
3282
|
-
*
|
|
3283
|
-
* @example
|
|
3415
|
+
* @example Uniform-width mode (Pagination)
|
|
3284
3416
|
* ```ts
|
|
3285
|
-
*
|
|
3286
|
-
*
|
|
3287
|
-
*
|
|
3288
|
-
*
|
|
3289
|
-
* primary: '#3b82f6',
|
|
3290
|
-
* secondary: '{colors.primary}', // Alias reference
|
|
3291
|
-
* },
|
|
3417
|
+
* const overflow = createOverflow({
|
|
3418
|
+
* container: () => atom.value?.element,
|
|
3419
|
+
* itemWidth: buttonWidth,
|
|
3420
|
+
* reserved: () => buttonWidth.value * 4,
|
|
3292
3421
|
* })
|
|
3293
|
-
*
|
|
3294
|
-
* console.log(tokens.resolve('{colors.primary}')) // '#3b82f6'
|
|
3295
|
-
* console.log(tokens.resolve('{colors.secondary}')) // '#3b82f6'
|
|
3296
3422
|
* ```
|
|
3297
3423
|
*/
|
|
3298
|
-
function
|
|
3299
|
-
const
|
|
3300
|
-
const
|
|
3301
|
-
const
|
|
3302
|
-
|
|
3303
|
-
function
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
function resolve(token, visited = /* @__PURE__ */ new Set()) {
|
|
3310
|
-
const cacheKey = /* @__PURE__ */ isString(token) ? token : JSON.stringify(token);
|
|
3311
|
-
const cached = cache.get(cacheKey);
|
|
3312
|
-
if (!/* @__PURE__ */ isUndefined(cached)) return cached;
|
|
3313
|
-
const reference = isTokenAlias(token) ? token.$value : token;
|
|
3314
|
-
const isAliasReference = /* @__PURE__ */ isString(reference) && isAlias(reference);
|
|
3315
|
-
const clean = isAliasReference ? reference.slice(1, -1) : String(reference);
|
|
3316
|
-
if (visited.has(clean)) {
|
|
3317
|
-
logger.warn(`Circular alias detected for "${clean}"`);
|
|
3318
|
-
cache.set(cacheKey, void 0);
|
|
3319
|
-
return;
|
|
3320
|
-
}
|
|
3321
|
-
visited.add(clean);
|
|
3322
|
-
let found = registry.get(clean);
|
|
3323
|
-
let segments = [];
|
|
3324
|
-
if (!found && clean.includes(".")) {
|
|
3325
|
-
const parts = clean.split(".");
|
|
3326
|
-
for (let i = parts.length - 1; i > 0; i--) {
|
|
3327
|
-
const prefix = parts.slice(0, i).join(".");
|
|
3328
|
-
const suffix = parts.slice(i);
|
|
3329
|
-
const candidate = registry.get(prefix);
|
|
3330
|
-
if (!/* @__PURE__ */ isUndefined(candidate?.value)) {
|
|
3331
|
-
found = candidate;
|
|
3332
|
-
segments = suffix;
|
|
3333
|
-
break;
|
|
3334
|
-
}
|
|
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;
|
|
3335
3435
|
}
|
|
3336
|
-
}
|
|
3337
|
-
if (/* @__PURE__ */ isUndefined(found?.value)) {
|
|
3338
|
-
if (isAliasReference) logger.warn(`Alias not found for "${String(reference)}"`);
|
|
3339
|
-
cache.set(cacheKey, void 0);
|
|
3340
3436
|
return;
|
|
3341
3437
|
}
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
for (const segment of segments) {
|
|
3347
|
-
if (!/* @__PURE__ */ isObject(current) || !(segment in current)) {
|
|
3348
|
-
current = void 0;
|
|
3349
|
-
break;
|
|
3350
|
-
}
|
|
3351
|
-
current = current[segment];
|
|
3352
|
-
if (isTokenAlias(current)) current = current.$value;
|
|
3353
|
-
}
|
|
3354
|
-
if (/* @__PURE__ */ isUndefined(current)) {
|
|
3355
|
-
logger.warn(`Path not found inside "${clean}": ${segments.join(".")}`);
|
|
3356
|
-
cache.set(cacheKey, void 0);
|
|
3357
|
-
return;
|
|
3358
|
-
}
|
|
3359
|
-
result = current;
|
|
3360
|
-
} else if (isTokenAlias(current)) {
|
|
3361
|
-
const inner = current.$value;
|
|
3362
|
-
if (/* @__PURE__ */ isString(inner) && isAlias(inner)) return resolve(inner, visited);
|
|
3363
|
-
result = inner;
|
|
3364
|
-
} else if (/* @__PURE__ */ isString(current) && isAlias(current)) return resolve(current, visited);
|
|
3365
|
-
else result = current;
|
|
3366
|
-
cache.set(cacheKey, result);
|
|
3367
|
-
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);
|
|
3368
3442
|
}
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
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++;
|
|
3375
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
|
|
3376
3489
|
};
|
|
3377
3490
|
}
|
|
3378
3491
|
/**
|
|
3379
|
-
* Creates
|
|
3380
|
-
*
|
|
3381
|
-
* @param namespace The namespace for the token context.
|
|
3382
|
-
* @param tokens The tokens to use.
|
|
3383
|
-
* @template Z The type of the token ticket.
|
|
3384
|
-
* @template E The type of the token context.
|
|
3385
|
-
* @returns A new token context.
|
|
3492
|
+
* Creates an overflow context with dependency injection support.
|
|
3386
3493
|
*
|
|
3387
|
-
* @
|
|
3494
|
+
* @param options Configuration options including namespace
|
|
3495
|
+
* @returns Trinity tuple: [useContext, provideContext, defaultContext]
|
|
3388
3496
|
*
|
|
3389
3497
|
* @example
|
|
3390
3498
|
* ```ts
|
|
3391
|
-
*
|
|
3392
|
-
*
|
|
3393
|
-
*
|
|
3394
|
-
*
|
|
3395
|
-
*
|
|
3396
|
-
* colors: {
|
|
3397
|
-
* primary: '#3b82f6',
|
|
3398
|
-
* secondary: '{colors.primary}', // Alias reference
|
|
3399
|
-
* },
|
|
3400
|
-
* },
|
|
3499
|
+
* // Create injectable context
|
|
3500
|
+
* const [useOverflow, provideOverflow, overflow] = createOverflowContext({
|
|
3501
|
+
* namespace: 'my-overflow',
|
|
3502
|
+
* gap: 8,
|
|
3503
|
+
* reserved: 160,
|
|
3401
3504
|
* })
|
|
3505
|
+
*
|
|
3506
|
+
* // In parent component
|
|
3507
|
+
* provideOverflow()
|
|
3508
|
+
*
|
|
3509
|
+
* // In child component
|
|
3510
|
+
* const overflow = useOverflow()
|
|
3402
3511
|
* ```
|
|
3403
3512
|
*/
|
|
3404
|
-
function
|
|
3405
|
-
const { namespace = "v0:
|
|
3406
|
-
const [
|
|
3407
|
-
const context =
|
|
3408
|
-
function
|
|
3409
|
-
return
|
|
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);
|
|
3410
3519
|
}
|
|
3411
|
-
return createTrinity(
|
|
3520
|
+
return createTrinity(useOverflowContext, provideOverflowContext, context);
|
|
3412
3521
|
}
|
|
3413
3522
|
/**
|
|
3414
|
-
* Returns the current
|
|
3415
|
-
*
|
|
3416
|
-
* @param namespace The namespace for the tokens context. Defaults to `'v0:tokens'`.
|
|
3417
|
-
* @returns The current tokens instance.
|
|
3523
|
+
* Returns the current overflow context from dependency injection.
|
|
3418
3524
|
*
|
|
3419
|
-
* @
|
|
3525
|
+
* @param namespace The namespace for the overflow context. Defaults to `v0:overflow`.
|
|
3526
|
+
* @returns The current overflow context.
|
|
3420
3527
|
*
|
|
3421
3528
|
* @example
|
|
3422
3529
|
* ```vue
|
|
3423
|
-
* <script
|
|
3424
|
-
* import {
|
|
3530
|
+
* <script lang="ts" setup>
|
|
3531
|
+
* import { useOverflow } from '@vuetify/v0'
|
|
3425
3532
|
*
|
|
3426
|
-
*
|
|
3533
|
+
* // Inject overflow context provided by parent
|
|
3534
|
+
* const overflow = useOverflow()
|
|
3427
3535
|
* <\/script>
|
|
3536
|
+
*
|
|
3537
|
+
* <template>
|
|
3538
|
+
* <div>
|
|
3539
|
+
* <p>Capacity: {{ overflow.capacity.value }}</p>
|
|
3540
|
+
* </div>
|
|
3541
|
+
* </template>
|
|
3428
3542
|
* ```
|
|
3429
3543
|
*/
|
|
3430
|
-
function
|
|
3544
|
+
function useOverflow(namespace = "v0:overflow") {
|
|
3431
3545
|
return useContext(namespace);
|
|
3432
3546
|
}
|
|
3433
|
-
/**
|
|
3434
|
-
* Flattens a nested collection of tokens into a flat array of tokens.
|
|
3435
|
-
* Each token is represented by an object containing its ID & value.
|
|
3436
|
-
* @param tokens The collection of tokens to flatten.
|
|
3437
|
-
* @param prefix An optional prefix to prepend to each token ID.
|
|
3438
|
-
* @returns An array of flattened tokens, each with an ID and value.
|
|
3439
|
-
*/
|
|
3440
|
-
function flatten(tokens, prefix = "", flat = false) {
|
|
3441
|
-
const flattened = [];
|
|
3442
|
-
const stack = [{
|
|
3443
|
-
tokens,
|
|
3444
|
-
prefix,
|
|
3445
|
-
flat
|
|
3446
|
-
}];
|
|
3447
|
-
while (stack.length > 0) {
|
|
3448
|
-
const { tokens: currentTokens, prefix: currentPrefix, flat: flat$1 } = stack.pop();
|
|
3449
|
-
const meta = {};
|
|
3450
|
-
for (const k in currentTokens) if (k.startsWith("$")) meta[k] = currentTokens[k];
|
|
3451
|
-
if (Object.keys(meta).length > 0 && currentPrefix) flattened.push({
|
|
3452
|
-
id: currentPrefix,
|
|
3453
|
-
value: meta
|
|
3454
|
-
});
|
|
3455
|
-
for (const key in currentTokens) {
|
|
3456
|
-
if (key.startsWith("$")) continue;
|
|
3457
|
-
const value = currentTokens[key];
|
|
3458
|
-
const id = currentPrefix ? `${currentPrefix}.${key}` : key;
|
|
3459
|
-
if (!/* @__PURE__ */ isObject(value)) {
|
|
3460
|
-
flattened.push({
|
|
3461
|
-
id,
|
|
3462
|
-
value
|
|
3463
|
-
});
|
|
3464
|
-
continue;
|
|
3465
|
-
}
|
|
3466
|
-
if ("$value" in value) {
|
|
3467
|
-
flattened.push({
|
|
3468
|
-
id,
|
|
3469
|
-
value
|
|
3470
|
-
});
|
|
3471
|
-
const inner = value.$value;
|
|
3472
|
-
if (/* @__PURE__ */ isObject(inner) && !flat$1) for (const innerKey in inner) {
|
|
3473
|
-
if (innerKey.startsWith("$")) continue;
|
|
3474
|
-
const child = inner[innerKey];
|
|
3475
|
-
const childId = `${id}.${innerKey}`;
|
|
3476
|
-
if (!/* @__PURE__ */ isObject(child)) flattened.push({
|
|
3477
|
-
id: childId,
|
|
3478
|
-
value: child
|
|
3479
|
-
});
|
|
3480
|
-
else if ("$value" in child) flattened.push({
|
|
3481
|
-
id: childId,
|
|
3482
|
-
value: child
|
|
3483
|
-
});
|
|
3484
|
-
else stack.push({
|
|
3485
|
-
tokens: child,
|
|
3486
|
-
prefix: childId,
|
|
3487
|
-
flat: flat$1
|
|
3488
|
-
});
|
|
3489
|
-
}
|
|
3490
|
-
continue;
|
|
3491
|
-
}
|
|
3492
|
-
if (flat$1) {
|
|
3493
|
-
flattened.push({
|
|
3494
|
-
id,
|
|
3495
|
-
value
|
|
3496
|
-
});
|
|
3497
|
-
continue;
|
|
3498
|
-
}
|
|
3499
|
-
stack.push({
|
|
3500
|
-
tokens: value,
|
|
3501
|
-
prefix: id,
|
|
3502
|
-
flat: flat$1
|
|
3503
|
-
});
|
|
3504
|
-
}
|
|
3505
|
-
}
|
|
3506
|
-
return flattened;
|
|
3507
|
-
}
|
|
3508
|
-
|
|
3509
|
-
//#endregion
|
|
3510
|
-
//#region src/composables/useLocale/adapters/v0.ts
|
|
3511
|
-
/**
|
|
3512
|
-
* Vuetify0.x locale adapter implementation
|
|
3513
|
-
*
|
|
3514
|
-
* This adapter provides translation and number formatting
|
|
3515
|
-
* capabilities using the Intl API and supports both
|
|
3516
|
-
* numbered ({0}, {1}) and named ({name}) variables in translation strings.
|
|
3517
|
-
*/
|
|
3518
|
-
var Vuetify0LocaleAdapter = class {
|
|
3519
|
-
t(message, ...params) {
|
|
3520
|
-
let resolvedMessage = message;
|
|
3521
|
-
if (params.length > 0 && /* @__PURE__ */ isObject(params[0])) {
|
|
3522
|
-
const variables = params[0];
|
|
3523
|
-
resolvedMessage = resolvedMessage.replace(/{([a-zA-Z][a-zA-Z0-9_]*)}/g, (match, name) => {
|
|
3524
|
-
return /* @__PURE__ */ isUndefined(variables[name]) ? match : String(variables[name]);
|
|
3525
|
-
});
|
|
3526
|
-
params = params.slice(1);
|
|
3527
|
-
}
|
|
3528
|
-
resolvedMessage = resolvedMessage.replace(/\{(\d+)\}/g, (match, index) => {
|
|
3529
|
-
const idx = Number.parseInt(index, 10);
|
|
3530
|
-
if (!/* @__PURE__ */ isUndefined(params[idx])) return String(params[idx]);
|
|
3531
|
-
return match;
|
|
3532
|
-
});
|
|
3533
|
-
return resolvedMessage;
|
|
3534
|
-
}
|
|
3535
|
-
n(value, locale, ...params) {
|
|
3536
|
-
if (!IN_BROWSER || !locale) return value.toString();
|
|
3537
|
-
const options = params[0];
|
|
3538
|
-
return new Intl.NumberFormat(String(locale), options).format(value);
|
|
3539
|
-
}
|
|
3540
|
-
};
|
|
3541
3547
|
|
|
3542
3548
|
//#endregion
|
|
3543
|
-
//#region src/composables/
|
|
3549
|
+
//#region src/composables/usePagination/index.ts
|
|
3544
3550
|
/**
|
|
3545
|
-
*
|
|
3546
|
-
*
|
|
3547
|
-
* @remarks
|
|
3548
|
-
* Internationalization (i18n) composable with adapter pattern for message translation.
|
|
3551
|
+
* Creates a pagination instance.
|
|
3549
3552
|
*
|
|
3550
|
-
*
|
|
3551
|
-
*
|
|
3552
|
-
* - Token-based message storage with useTokens
|
|
3553
|
-
* - Numbered and named placeholder support ({0}, {name})
|
|
3554
|
-
* - Number formatting with Intl.NumberFormat
|
|
3555
|
-
* - Adapter pattern for integration with i18n providers
|
|
3553
|
+
* @param options The options for the pagination instance.
|
|
3554
|
+
* @returns A pagination context with navigation methods.
|
|
3556
3555
|
*
|
|
3557
|
-
*
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
* Creates a new locale instance.
|
|
3556
|
+
* @example
|
|
3557
|
+
* ```ts
|
|
3558
|
+
* import { createPagination } from '@vuetify/v0'
|
|
3561
3559
|
*
|
|
3562
|
-
*
|
|
3563
|
-
*
|
|
3564
|
-
*
|
|
3565
|
-
*
|
|
3560
|
+
* // Basic usage
|
|
3561
|
+
* const pagination = createPagination({ size: 100 })
|
|
3562
|
+
* pagination.next()
|
|
3563
|
+
* pagination.items.value // [{ type: 'page', value: 1 }, { type: 'page', value: 2 }, ...]
|
|
3566
3564
|
*
|
|
3567
|
-
*
|
|
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
|
+
* ```
|
|
3568
3570
|
*/
|
|
3569
|
-
function
|
|
3570
|
-
const {
|
|
3571
|
-
const
|
|
3572
|
-
const
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
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;
|
|
3576
3582
|
}
|
|
3577
|
-
function
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3583
|
+
function last() {
|
|
3584
|
+
page.value = Math.max(1, pages.value);
|
|
3585
|
+
}
|
|
3586
|
+
function next() {
|
|
3587
|
+
if (page.value < pages.value) page.value++;
|
|
3588
|
+
}
|
|
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
|
+
};
|
|
3585
3606
|
}
|
|
3586
|
-
function
|
|
3587
|
-
return
|
|
3607
|
+
function toEllipsis() {
|
|
3608
|
+
return ellipsis === false ? false : {
|
|
3609
|
+
type: "ellipsis",
|
|
3610
|
+
value: ellipsis
|
|
3611
|
+
};
|
|
3588
3612
|
}
|
|
3589
|
-
function
|
|
3590
|
-
return
|
|
3591
|
-
const [prefix, ...rest] = key.split(".");
|
|
3592
|
-
const target = registry.has(prefix) ? prefix : locale;
|
|
3593
|
-
const path = `${target}.${registry.has(prefix) ? rest.join(".") : key}`;
|
|
3594
|
-
const resolved = tokens.get(path)?.value;
|
|
3595
|
-
if (/* @__PURE__ */ isString(resolved)) return resolve(target, resolved);
|
|
3596
|
-
return match;
|
|
3597
|
-
});
|
|
3613
|
+
function filter(array) {
|
|
3614
|
+
return array.filter((item) => item !== false);
|
|
3598
3615
|
}
|
|
3599
3616
|
return {
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
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
|
+
},
|
|
3603
3695
|
get size() {
|
|
3604
|
-
return
|
|
3696
|
+
return toValue(_size);
|
|
3697
|
+
},
|
|
3698
|
+
get pages() {
|
|
3699
|
+
return pages.value;
|
|
3605
3700
|
}
|
|
3606
3701
|
};
|
|
3607
3702
|
}
|
|
3608
|
-
function createLocaleFallback() {
|
|
3609
|
-
return {
|
|
3610
|
-
size: 0,
|
|
3611
|
-
t: (key, _params, fallback) => fallback ?? key,
|
|
3612
|
-
n: String
|
|
3613
|
-
};
|
|
3614
|
-
}
|
|
3615
3703
|
/**
|
|
3616
|
-
* Creates a
|
|
3617
|
-
*
|
|
3618
|
-
* @param options The options for the locale context.
|
|
3619
|
-
* @template Z The type of the locale ticket.
|
|
3620
|
-
* @template E The type of the locale context.
|
|
3621
|
-
* @returns A new locale context.
|
|
3704
|
+
* Creates a pagination context for dependency injection.
|
|
3622
3705
|
*
|
|
3623
|
-
* @
|
|
3706
|
+
* @param options The options including namespace.
|
|
3707
|
+
* @returns A trinity: [usePagination, providePagination, defaultContext]
|
|
3624
3708
|
*
|
|
3625
3709
|
* @example
|
|
3626
3710
|
* ```ts
|
|
3627
|
-
*
|
|
3711
|
+
* // With default namespace 'v0:pagination'
|
|
3712
|
+
* const [usePagination, providePaginationContext] = createPaginationContext({ size: 50 })
|
|
3628
3713
|
*
|
|
3629
|
-
*
|
|
3630
|
-
*
|
|
3631
|
-
*
|
|
3632
|
-
*
|
|
3633
|
-
* es: { hello: 'Hola' },
|
|
3634
|
-
* },
|
|
3714
|
+
* // Or with custom namespace
|
|
3715
|
+
* const [usePagination, providePaginationContext] = createPaginationContext({
|
|
3716
|
+
* namespace: 'my-pagination',
|
|
3717
|
+
* size: 50,
|
|
3635
3718
|
* })
|
|
3636
3719
|
*
|
|
3637
|
-
* //
|
|
3638
|
-
*
|
|
3720
|
+
* // Parent component
|
|
3721
|
+
* providePaginationContext()
|
|
3639
3722
|
*
|
|
3640
|
-
* //
|
|
3641
|
-
* const
|
|
3642
|
-
*
|
|
3723
|
+
* // Child component
|
|
3724
|
+
* const pagination = usePagination()
|
|
3725
|
+
* pagination.next()
|
|
3643
3726
|
* ```
|
|
3644
3727
|
*/
|
|
3645
|
-
function
|
|
3646
|
-
const { namespace = "v0:
|
|
3647
|
-
const [
|
|
3648
|
-
const context =
|
|
3649
|
-
function
|
|
3650
|
-
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);
|
|
3651
3734
|
}
|
|
3652
|
-
return createTrinity(
|
|
3735
|
+
return createTrinity(usePaginationContext, providePaginationContext, context);
|
|
3653
3736
|
}
|
|
3654
3737
|
/**
|
|
3655
|
-
*
|
|
3738
|
+
* Returns the current pagination instance from context.
|
|
3656
3739
|
*
|
|
3657
|
-
* @param
|
|
3658
|
-
* @
|
|
3659
|
-
* @template E The type of the locale context.
|
|
3660
|
-
* @template R The type of the token ticket.
|
|
3661
|
-
* @template O The type of the token context.
|
|
3662
|
-
* @returns A new locale plugin.
|
|
3740
|
+
* @param namespace The namespace. @default 'v0:pagination'
|
|
3741
|
+
* @returns The pagination context.
|
|
3663
3742
|
*
|
|
3664
|
-
* @
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
const [, provideLocaleContext, context] = createLocaleContext({
|
|
3669
|
-
...options,
|
|
3670
|
-
namespace,
|
|
3671
|
-
adapter,
|
|
3672
|
-
messages
|
|
3673
|
-
});
|
|
3674
|
-
return createPlugin({
|
|
3675
|
-
namespace,
|
|
3676
|
-
provide: (app) => {
|
|
3677
|
-
provideLocaleContext(context, app);
|
|
3678
|
-
}
|
|
3679
|
-
});
|
|
3680
|
-
}
|
|
3681
|
-
/**
|
|
3682
|
-
* Returns the current locale instance.
|
|
3743
|
+
* @example
|
|
3744
|
+
* ```vue
|
|
3745
|
+
* <script setup lang="ts">
|
|
3746
|
+
* import { usePagination } from '@vuetify/v0'
|
|
3683
3747
|
*
|
|
3684
|
-
*
|
|
3748
|
+
* const pagination = usePagination()
|
|
3749
|
+
* <\/script>
|
|
3685
3750
|
*
|
|
3686
|
-
*
|
|
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
|
+
* ```
|
|
3687
3756
|
*/
|
|
3688
|
-
function
|
|
3689
|
-
|
|
3690
|
-
if (!getCurrentInstance()) return fallback;
|
|
3691
|
-
try {
|
|
3692
|
-
return useContext(namespace, fallback);
|
|
3693
|
-
} catch {
|
|
3694
|
-
return fallback;
|
|
3695
|
-
}
|
|
3757
|
+
function usePagination(namespace = "v0:pagination") {
|
|
3758
|
+
return useContext(namespace);
|
|
3696
3759
|
}
|
|
3697
3760
|
|
|
3698
3761
|
//#endregion
|
|
@@ -3700,7 +3763,7 @@ function useLocale(namespace = "v0:locale") {
|
|
|
3700
3763
|
const [usePaginationRoot, providePaginationRoot] = createContext();
|
|
3701
3764
|
const [usePaginationControls, providePaginationControls] = createContext({ suffix: "controls" });
|
|
3702
3765
|
const [usePaginationItems, providePaginationItems] = createContext({ suffix: "items" });
|
|
3703
|
-
const _sfc_main$
|
|
3766
|
+
const _sfc_main$16 = /* @__PURE__ */ defineComponent({
|
|
3704
3767
|
name: "PaginationRoot",
|
|
3705
3768
|
__name: "PaginationRoot",
|
|
3706
3769
|
props: /* @__PURE__ */ mergeModels({
|
|
@@ -3748,7 +3811,7 @@ const _sfc_main$15 = /* @__PURE__ */ defineComponent({
|
|
|
3748
3811
|
page,
|
|
3749
3812
|
visible: computed(() => {
|
|
3750
3813
|
const totalCap = overflow.capacity.value;
|
|
3751
|
-
if (totalCap === Infinity) return __props.totalVisible ??
|
|
3814
|
+
if (totalCap === Infinity) return __props.totalVisible ?? 7;
|
|
3752
3815
|
const pageCap = Math.max(0, totalCap - controls.size);
|
|
3753
3816
|
const noVisible = /* @__PURE__ */ isNullOrUndefined(__props.totalVisible);
|
|
3754
3817
|
if (pageCap > 0) return noVisible ? pageCap : Math.min(__props.totalVisible, pageCap);
|
|
@@ -3773,7 +3836,10 @@ const _sfc_main$15 = /* @__PURE__ */ defineComponent({
|
|
|
3773
3836
|
next: pagination.next,
|
|
3774
3837
|
prev: pagination.prev,
|
|
3775
3838
|
select: pagination.select,
|
|
3776
|
-
attrs: {
|
|
3839
|
+
attrs: {
|
|
3840
|
+
"aria-label": locale.t("Pagination.label", void 0, "Pagination"),
|
|
3841
|
+
"role": __props.as === "nav" ? void 0 : "navigation"
|
|
3842
|
+
}
|
|
3777
3843
|
}));
|
|
3778
3844
|
providePaginationRoot(__props.namespace, pagination);
|
|
3779
3845
|
providePaginationControls(__props.namespace, controls);
|
|
@@ -3792,11 +3858,11 @@ const _sfc_main$15 = /* @__PURE__ */ defineComponent({
|
|
|
3792
3858
|
};
|
|
3793
3859
|
}
|
|
3794
3860
|
});
|
|
3795
|
-
var PaginationRoot_default = _sfc_main$
|
|
3861
|
+
var PaginationRoot_default = _sfc_main$16;
|
|
3796
3862
|
|
|
3797
3863
|
//#endregion
|
|
3798
3864
|
//#region src/components/Pagination/PaginationEllipsis.vue
|
|
3799
|
-
const _sfc_main$
|
|
3865
|
+
const _sfc_main$15 = /* @__PURE__ */ defineComponent({
|
|
3800
3866
|
name: "PaginationEllipsis",
|
|
3801
3867
|
__name: "PaginationEllipsis",
|
|
3802
3868
|
props: {
|
|
@@ -3837,11 +3903,11 @@ const _sfc_main$14 = /* @__PURE__ */ defineComponent({
|
|
|
3837
3903
|
};
|
|
3838
3904
|
}
|
|
3839
3905
|
});
|
|
3840
|
-
var PaginationEllipsis_default = _sfc_main$
|
|
3906
|
+
var PaginationEllipsis_default = _sfc_main$15;
|
|
3841
3907
|
|
|
3842
3908
|
//#endregion
|
|
3843
3909
|
//#region src/components/Pagination/PaginationFirst.vue
|
|
3844
|
-
const _sfc_main$
|
|
3910
|
+
const _sfc_main$14 = /* @__PURE__ */ defineComponent({
|
|
3845
3911
|
name: "PaginationFirst",
|
|
3846
3912
|
__name: "PaginationFirst",
|
|
3847
3913
|
props: {
|
|
@@ -3873,9 +3939,10 @@ const _sfc_main$13 = /* @__PURE__ */ defineComponent({
|
|
|
3873
3939
|
first,
|
|
3874
3940
|
attrs: {
|
|
3875
3941
|
"aria-label": locale.t("Pagination.first", void 0, "Go to first page"),
|
|
3876
|
-
"aria-disabled":
|
|
3942
|
+
"aria-disabled": isDisabled.value,
|
|
3877
3943
|
"data-disabled": isDisabled.value || void 0,
|
|
3878
3944
|
"disabled": __props.as === "button" ? isDisabled.value : void 0,
|
|
3945
|
+
"tabindex": isDisabled.value ? -1 : 0,
|
|
3879
3946
|
"type": __props.as === "button" ? "button" : void 0,
|
|
3880
3947
|
"onClick": first
|
|
3881
3948
|
}
|
|
@@ -3895,11 +3962,11 @@ const _sfc_main$13 = /* @__PURE__ */ defineComponent({
|
|
|
3895
3962
|
};
|
|
3896
3963
|
}
|
|
3897
3964
|
});
|
|
3898
|
-
var PaginationFirst_default = _sfc_main$
|
|
3965
|
+
var PaginationFirst_default = _sfc_main$14;
|
|
3899
3966
|
|
|
3900
3967
|
//#endregion
|
|
3901
3968
|
//#region src/components/Pagination/PaginationItem.vue
|
|
3902
|
-
const _sfc_main$
|
|
3969
|
+
const _sfc_main$13 = /* @__PURE__ */ defineComponent({
|
|
3903
3970
|
name: "PaginationItem",
|
|
3904
3971
|
__name: "PaginationItem",
|
|
3905
3972
|
props: {
|
|
@@ -3941,9 +4008,11 @@ const _sfc_main$12 = /* @__PURE__ */ defineComponent({
|
|
|
3941
4008
|
attrs: {
|
|
3942
4009
|
"aria-label": ariaLabel.value,
|
|
3943
4010
|
"aria-current": isSelected.value ? "page" : void 0,
|
|
4011
|
+
"aria-disabled": __props.disabled,
|
|
3944
4012
|
"data-selected": isSelected.value || void 0,
|
|
3945
4013
|
"data-disabled": __props.disabled || void 0,
|
|
3946
4014
|
"disabled": __props.as === "button" ? __props.disabled : void 0,
|
|
4015
|
+
"tabindex": __props.disabled ? -1 : 0,
|
|
3947
4016
|
"type": __props.as === "button" ? "button" : void 0,
|
|
3948
4017
|
"onClick": select
|
|
3949
4018
|
}
|
|
@@ -3957,17 +4026,17 @@ const _sfc_main$12 = /* @__PURE__ */ defineComponent({
|
|
|
3957
4026
|
as: __props.as,
|
|
3958
4027
|
renderless: __props.renderless
|
|
3959
4028
|
}), {
|
|
3960
|
-
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
4029
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)), () => [createTextVNode(toDisplayString(__props.value), 1)])]),
|
|
3961
4030
|
_: 3
|
|
3962
4031
|
}, 16, ["as", "renderless"]);
|
|
3963
4032
|
};
|
|
3964
4033
|
}
|
|
3965
4034
|
});
|
|
3966
|
-
var PaginationItem_default = _sfc_main$
|
|
4035
|
+
var PaginationItem_default = _sfc_main$13;
|
|
3967
4036
|
|
|
3968
4037
|
//#endregion
|
|
3969
4038
|
//#region src/components/Pagination/PaginationLast.vue
|
|
3970
|
-
const _sfc_main$
|
|
4039
|
+
const _sfc_main$12 = /* @__PURE__ */ defineComponent({
|
|
3971
4040
|
name: "PaginationLast",
|
|
3972
4041
|
__name: "PaginationLast",
|
|
3973
4042
|
props: {
|
|
@@ -3999,9 +4068,10 @@ const _sfc_main$11 = /* @__PURE__ */ defineComponent({
|
|
|
3999
4068
|
last,
|
|
4000
4069
|
attrs: {
|
|
4001
4070
|
"aria-label": locale.t("Pagination.last", void 0, "Go to last page"),
|
|
4002
|
-
"aria-disabled":
|
|
4071
|
+
"aria-disabled": isDisabled.value,
|
|
4003
4072
|
"data-disabled": isDisabled.value || void 0,
|
|
4004
4073
|
"disabled": __props.as === "button" ? isDisabled.value : void 0,
|
|
4074
|
+
"tabindex": isDisabled.value ? -1 : 0,
|
|
4005
4075
|
"type": __props.as === "button" ? "button" : void 0,
|
|
4006
4076
|
"onClick": last
|
|
4007
4077
|
}
|
|
@@ -4021,11 +4091,11 @@ const _sfc_main$11 = /* @__PURE__ */ defineComponent({
|
|
|
4021
4091
|
};
|
|
4022
4092
|
}
|
|
4023
4093
|
});
|
|
4024
|
-
var PaginationLast_default = _sfc_main$
|
|
4094
|
+
var PaginationLast_default = _sfc_main$12;
|
|
4025
4095
|
|
|
4026
4096
|
//#endregion
|
|
4027
4097
|
//#region src/components/Pagination/PaginationNext.vue
|
|
4028
|
-
const _sfc_main$
|
|
4098
|
+
const _sfc_main$11 = /* @__PURE__ */ defineComponent({
|
|
4029
4099
|
name: "PaginationNext",
|
|
4030
4100
|
__name: "PaginationNext",
|
|
4031
4101
|
props: {
|
|
@@ -4057,9 +4127,10 @@ const _sfc_main$10 = /* @__PURE__ */ defineComponent({
|
|
|
4057
4127
|
next,
|
|
4058
4128
|
attrs: {
|
|
4059
4129
|
"aria-label": locale.t("Pagination.next", void 0, "Go to next page"),
|
|
4060
|
-
"aria-disabled":
|
|
4130
|
+
"aria-disabled": isDisabled.value,
|
|
4061
4131
|
"data-disabled": isDisabled.value || void 0,
|
|
4062
4132
|
"disabled": __props.as === "button" ? isDisabled.value : void 0,
|
|
4133
|
+
"tabindex": isDisabled.value ? -1 : 0,
|
|
4063
4134
|
"type": __props.as === "button" ? "button" : void 0,
|
|
4064
4135
|
"onClick": next
|
|
4065
4136
|
}
|
|
@@ -4079,11 +4150,11 @@ const _sfc_main$10 = /* @__PURE__ */ defineComponent({
|
|
|
4079
4150
|
};
|
|
4080
4151
|
}
|
|
4081
4152
|
});
|
|
4082
|
-
var PaginationNext_default = _sfc_main$
|
|
4153
|
+
var PaginationNext_default = _sfc_main$11;
|
|
4083
4154
|
|
|
4084
4155
|
//#endregion
|
|
4085
4156
|
//#region src/components/Pagination/PaginationPrev.vue
|
|
4086
|
-
const _sfc_main$
|
|
4157
|
+
const _sfc_main$10 = /* @__PURE__ */ defineComponent({
|
|
4087
4158
|
name: "PaginationPrev",
|
|
4088
4159
|
__name: "PaginationPrev",
|
|
4089
4160
|
props: {
|
|
@@ -4115,32 +4186,84 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
4115
4186
|
prev,
|
|
4116
4187
|
attrs: {
|
|
4117
4188
|
"aria-label": locale.t("Pagination.prev", void 0, "Go to previous page"),
|
|
4118
|
-
"aria-disabled":
|
|
4189
|
+
"aria-disabled": isDisabled.value,
|
|
4119
4190
|
"data-disabled": isDisabled.value || void 0,
|
|
4120
4191
|
"disabled": __props.as === "button" ? isDisabled.value : void 0,
|
|
4192
|
+
"tabindex": isDisabled.value ? -1 : 0,
|
|
4121
4193
|
"type": __props.as === "button" ? "button" : void 0,
|
|
4122
4194
|
"onClick": prev
|
|
4123
4195
|
}
|
|
4124
4196
|
}));
|
|
4125
|
-
onBeforeUnmount(() => controls.unregister(__props.id));
|
|
4197
|
+
onBeforeUnmount(() => controls.unregister(__props.id));
|
|
4198
|
+
return (_ctx, _cache) => {
|
|
4199
|
+
return openBlock(), createBlock(unref(Atom_default), mergeProps({
|
|
4200
|
+
ref_key: "atom",
|
|
4201
|
+
ref: atom
|
|
4202
|
+
}, slotProps.value.attrs, {
|
|
4203
|
+
as: __props.as,
|
|
4204
|
+
renderless: __props.renderless
|
|
4205
|
+
}), {
|
|
4206
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
4207
|
+
_: 3
|
|
4208
|
+
}, 16, ["as", "renderless"]);
|
|
4209
|
+
};
|
|
4210
|
+
}
|
|
4211
|
+
});
|
|
4212
|
+
var PaginationPrev_default = _sfc_main$10;
|
|
4213
|
+
|
|
4214
|
+
//#endregion
|
|
4215
|
+
//#region src/components/Pagination/PaginationStatus.vue
|
|
4216
|
+
const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
4217
|
+
name: "PaginationStatus",
|
|
4218
|
+
__name: "PaginationStatus",
|
|
4219
|
+
props: {
|
|
4220
|
+
namespace: { default: "v0:pagination" },
|
|
4221
|
+
as: { default: "div" },
|
|
4222
|
+
renderless: { type: Boolean }
|
|
4223
|
+
},
|
|
4224
|
+
setup(__props) {
|
|
4225
|
+
const locale = useLocale();
|
|
4226
|
+
const pagination = usePaginationRoot(__props.namespace);
|
|
4227
|
+
const text = shallowRef("");
|
|
4228
|
+
watch(() => pagination.page.value, (page, prevPage) => {
|
|
4229
|
+
if (prevPage === void 0) return;
|
|
4230
|
+
setTimeout(() => {
|
|
4231
|
+
text.value = locale.t("Pagination.status", {
|
|
4232
|
+
page,
|
|
4233
|
+
pages: pagination.pages
|
|
4234
|
+
}, `Page ${page} of ${pagination.pages}`);
|
|
4235
|
+
}, 100);
|
|
4236
|
+
});
|
|
4237
|
+
const slotProps = toRef(() => ({
|
|
4238
|
+
page: pagination.page.value,
|
|
4239
|
+
pages: pagination.pages,
|
|
4240
|
+
text: text.value,
|
|
4241
|
+
attrs: {
|
|
4242
|
+
"aria-atomic": true,
|
|
4243
|
+
"aria-live": "polite",
|
|
4244
|
+
"role": "status"
|
|
4245
|
+
}
|
|
4246
|
+
}));
|
|
4126
4247
|
return (_ctx, _cache) => {
|
|
4127
|
-
return openBlock(), createBlock(unref(Atom_default), mergeProps({
|
|
4128
|
-
ref_key: "atom",
|
|
4129
|
-
ref: atom
|
|
4130
|
-
}, slotProps.value.attrs, {
|
|
4248
|
+
return openBlock(), createBlock(unref(Atom_default), mergeProps(slotProps.value.attrs, {
|
|
4131
4249
|
as: __props.as,
|
|
4132
4250
|
renderless: __props.renderless
|
|
4133
4251
|
}), {
|
|
4134
|
-
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)))]),
|
|
4252
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps.value)), () => [createTextVNode(toDisplayString(text.value), 1)])]),
|
|
4135
4253
|
_: 3
|
|
4136
4254
|
}, 16, ["as", "renderless"]);
|
|
4137
4255
|
};
|
|
4138
4256
|
}
|
|
4139
4257
|
});
|
|
4140
|
-
var
|
|
4258
|
+
var PaginationStatus_default = _sfc_main$9;
|
|
4141
4259
|
|
|
4142
4260
|
//#endregion
|
|
4143
4261
|
//#region src/components/Pagination/index.ts
|
|
4262
|
+
/**
|
|
4263
|
+
* Pagination component with sub-components for building pagination controls.
|
|
4264
|
+
*
|
|
4265
|
+
* @see https://0.vuetifyjs.com/components/pagination
|
|
4266
|
+
*/
|
|
4144
4267
|
const Pagination = {
|
|
4145
4268
|
Root: PaginationRoot_default,
|
|
4146
4269
|
Item: PaginationItem_default,
|
|
@@ -4148,7 +4271,8 @@ const Pagination = {
|
|
|
4148
4271
|
Prev: PaginationPrev_default,
|
|
4149
4272
|
Ellipsis: PaginationEllipsis_default,
|
|
4150
4273
|
Next: PaginationNext_default,
|
|
4151
|
-
Last: PaginationLast_default
|
|
4274
|
+
Last: PaginationLast_default,
|
|
4275
|
+
Status: PaginationStatus_default
|
|
4152
4276
|
};
|
|
4153
4277
|
|
|
4154
4278
|
//#endregion
|
|
@@ -4295,6 +4419,11 @@ var PopoverContent_default = _sfc_main$6;
|
|
|
4295
4419
|
|
|
4296
4420
|
//#endregion
|
|
4297
4421
|
//#region src/components/Popover/index.ts
|
|
4422
|
+
/**
|
|
4423
|
+
* Popover component with sub-components for building popovers.
|
|
4424
|
+
*
|
|
4425
|
+
* @see https://0.vuetifyjs.com/components/popover
|
|
4426
|
+
*/
|
|
4298
4427
|
const Popover = {
|
|
4299
4428
|
Root: PopoverRoot_default,
|
|
4300
4429
|
Anchor: PopoverAnchor_default,
|
|
@@ -4329,7 +4458,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
4329
4458
|
"modelValue": {},
|
|
4330
4459
|
"modelModifiers": {}
|
|
4331
4460
|
}),
|
|
4332
|
-
emits: ["update:modelValue"],
|
|
4461
|
+
emits: /* @__PURE__ */ mergeModels(["update:model-value"], ["update:modelValue"]),
|
|
4333
4462
|
setup(__props) {
|
|
4334
4463
|
const model = useModel(__props, "modelValue");
|
|
4335
4464
|
const selection = createSelection({
|
|
@@ -4404,6 +4533,11 @@ var SelectionItem_default = _sfc_main$4;
|
|
|
4404
4533
|
|
|
4405
4534
|
//#endregion
|
|
4406
4535
|
//#region src/components/Selection/index.ts
|
|
4536
|
+
/**
|
|
4537
|
+
* Selection component with sub-components for managing item selection state.
|
|
4538
|
+
*
|
|
4539
|
+
* @see https://0.vuetifyjs.com/components/selection
|
|
4540
|
+
*/
|
|
4407
4541
|
const Selection = {
|
|
4408
4542
|
Root: SelectionRoot_default,
|
|
4409
4543
|
Item: SelectionItem_default
|
|
@@ -4506,6 +4640,11 @@ var SingleItem_default = _sfc_main$2;
|
|
|
4506
4640
|
|
|
4507
4641
|
//#endregion
|
|
4508
4642
|
//#region src/components/Single/index.ts
|
|
4643
|
+
/**
|
|
4644
|
+
* Single component with sub-components for building single-selection interfaces.
|
|
4645
|
+
*
|
|
4646
|
+
* @see https://0.vuetifyjs.com/components/single
|
|
4647
|
+
*/
|
|
4509
4648
|
const Single = {
|
|
4510
4649
|
Root: SingleRoot_default,
|
|
4511
4650
|
Item: SingleItem_default
|
|
@@ -4514,20 +4653,6 @@ const Single = {
|
|
|
4514
4653
|
//#endregion
|
|
4515
4654
|
//#region src/composables/useStep/index.ts
|
|
4516
4655
|
/**
|
|
4517
|
-
* @module useStep
|
|
4518
|
-
*
|
|
4519
|
-
* @remarks
|
|
4520
|
-
* Navigation composable that extends useSingle with first/last/next/prev/step methods.
|
|
4521
|
-
*
|
|
4522
|
-
* Key features:
|
|
4523
|
-
* - Configurable circular or bounded navigation
|
|
4524
|
-
* - Automatic disabled item skipping
|
|
4525
|
-
* - Arbitrary step counts (positive/negative)
|
|
4526
|
-
* - Perfect for wizards, carousels, pagination, onboarding flows
|
|
4527
|
-
*
|
|
4528
|
-
* Inheritance chain: useRegistry → useSelection → useSingle → useStep
|
|
4529
|
-
*/
|
|
4530
|
-
/**
|
|
4531
4656
|
* Creates a new step instance with navigation through items.
|
|
4532
4657
|
*
|
|
4533
4658
|
* Extends `createSingle` with `first()`, `last()`, `next()`, `prev()`, and `step(count)` methods
|
|
@@ -4596,7 +4721,7 @@ const Single = {
|
|
|
4596
4721
|
* ```
|
|
4597
4722
|
*/
|
|
4598
4723
|
function createStep(_options = {}) {
|
|
4599
|
-
const { circular = false
|
|
4724
|
+
const { circular = false, ...options } = _options;
|
|
4600
4725
|
const registry = createSingle(options);
|
|
4601
4726
|
function first() {
|
|
4602
4727
|
const ticket = registry.seek("first");
|
|
@@ -4672,7 +4797,7 @@ function createStep(_options = {}) {
|
|
|
4672
4797
|
* ```
|
|
4673
4798
|
*/
|
|
4674
4799
|
function createStepContext(_options = {}) {
|
|
4675
|
-
const { namespace = "v0:step"
|
|
4800
|
+
const { namespace = "v0:step", ...options } = _options;
|
|
4676
4801
|
const [useStepContext, _provideStepContext] = createContext(namespace);
|
|
4677
4802
|
const context = createStep(options);
|
|
4678
4803
|
function provideStepContext(_context = context, app) {
|
|
@@ -4810,6 +4935,11 @@ var StepItem_default = _sfc_main;
|
|
|
4810
4935
|
|
|
4811
4936
|
//#endregion
|
|
4812
4937
|
//#region src/components/Step/index.ts
|
|
4938
|
+
/**
|
|
4939
|
+
* Step component with sub-components for building stepper navigation.
|
|
4940
|
+
*
|
|
4941
|
+
* @see https://0.vuetifyjs.com/components/step
|
|
4942
|
+
*/
|
|
4813
4943
|
const Step = {
|
|
4814
4944
|
Root: StepRoot_default,
|
|
4815
4945
|
Item: StepItem_default
|
|
@@ -4818,21 +4948,6 @@ const Step = {
|
|
|
4818
4948
|
//#endregion
|
|
4819
4949
|
//#region src/composables/toReactive/index.ts
|
|
4820
4950
|
/**
|
|
4821
|
-
* @module toReactive
|
|
4822
|
-
*
|
|
4823
|
-
* @remarks
|
|
4824
|
-
* Utility function to convert values and refs into reactive proxies with ref unwrapping.
|
|
4825
|
-
*
|
|
4826
|
-
* Key features:
|
|
4827
|
-
* - Automatic ref unwrapping
|
|
4828
|
-
* - Deep reactive proxying
|
|
4829
|
-
* - Map and Set support with ref unwrapping
|
|
4830
|
-
* - Nested object/array reactivity
|
|
4831
|
-
* - Type preservation
|
|
4832
|
-
*
|
|
4833
|
-
* Perfect for creating reactive versions of plain objects while automatically unwrapping refs.
|
|
4834
|
-
*/
|
|
4835
|
-
/**
|
|
4836
4951
|
* Converts a `MaybeRef` to a `UnwrapNestedRefs`.
|
|
4837
4952
|
*
|
|
4838
4953
|
* @param objectRef The object to convert.
|
|
@@ -4953,21 +5068,6 @@ function toReactive(objectRef) {
|
|
|
4953
5068
|
//#endregion
|
|
4954
5069
|
//#region src/composables/useEventListener/index.ts
|
|
4955
5070
|
/**
|
|
4956
|
-
* @module useEventListener
|
|
4957
|
-
*
|
|
4958
|
-
* @remarks
|
|
4959
|
-
* Event listener composable with automatic cleanup on scope disposal.
|
|
4960
|
-
*
|
|
4961
|
-
* Key features:
|
|
4962
|
-
* - Supports Window, Document, and HTMLElement targets
|
|
4963
|
-
* - Reactive targets, events, and listeners
|
|
4964
|
-
* - Event options support (capture, passive, once)
|
|
4965
|
-
* - Automatic removeEventListener on unmount
|
|
4966
|
-
* - Multiple overloads for type safety
|
|
4967
|
-
*
|
|
4968
|
-
* Perfect for safely managing event listeners in Vue components.
|
|
4969
|
-
*/
|
|
4970
|
-
/**
|
|
4971
5071
|
* Attaches an event listener to a target.
|
|
4972
5072
|
*
|
|
4973
5073
|
* @param target The target to attach the event listener to.
|
|
@@ -5022,7 +5122,7 @@ function useEventListener(target, event, listener, options) {
|
|
|
5022
5122
|
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
5023
5123
|
*/
|
|
5024
5124
|
function useWindowEventListener(event, listener, options) {
|
|
5025
|
-
return useEventListener(window, event, listener, options);
|
|
5125
|
+
return IN_BROWSER ? useEventListener(window, event, listener, options) : () => {};
|
|
5026
5126
|
}
|
|
5027
5127
|
/**
|
|
5028
5128
|
* Attaches an event listener to the document.
|
|
@@ -5036,30 +5136,12 @@ function useWindowEventListener(event, listener, options) {
|
|
|
5036
5136
|
* @see https://0.vuetifyjs.com/composables/system/use-event-listener
|
|
5037
5137
|
*/
|
|
5038
5138
|
function useDocumentEventListener(event, listener, options) {
|
|
5039
|
-
return useEventListener(document, event, listener, options);
|
|
5139
|
+
return IN_BROWSER ? useEventListener(document, event, listener, options) : () => {};
|
|
5040
5140
|
}
|
|
5041
5141
|
|
|
5042
5142
|
//#endregion
|
|
5043
5143
|
//#region src/composables/useBreakpoints/index.ts
|
|
5044
5144
|
/**
|
|
5045
|
-
* @module useBreakpoints
|
|
5046
|
-
*
|
|
5047
|
-
* @see https://0.vuetifyjs.com/composables/plugins/use-breakpoints
|
|
5048
|
-
*
|
|
5049
|
-
* @remarks
|
|
5050
|
-
* Responsive breakpoint detection composable with window resize handling.
|
|
5051
|
-
*
|
|
5052
|
-
* Key features:
|
|
5053
|
-
* - Window matchMedia integration
|
|
5054
|
-
* - Six built-in breakpoints (xs, sm, md, lg, xl, xxl)
|
|
5055
|
-
* - Automatic resize listener with cleanup
|
|
5056
|
-
* - SSR-safe (checks IN_BROWSER)
|
|
5057
|
-
* - Hydration-aware
|
|
5058
|
-
* - Custom breakpoint configuration
|
|
5059
|
-
*
|
|
5060
|
-
* Perfect for responsive layouts and conditional rendering based on screen size.
|
|
5061
|
-
*/
|
|
5062
|
-
/**
|
|
5063
5145
|
* Creates default breakpoint configuration.
|
|
5064
5146
|
*
|
|
5065
5147
|
* @returns The default breakpoint configuration object.
|
|
@@ -5203,7 +5285,7 @@ function createBreakpoints(_options = {}) {
|
|
|
5203
5285
|
* ```
|
|
5204
5286
|
*/
|
|
5205
5287
|
function createBreakpointsContext(_options = {}) {
|
|
5206
|
-
const { namespace = "v0:breakpoints"
|
|
5288
|
+
const { namespace = "v0:breakpoints", ...options } = _options;
|
|
5207
5289
|
const [useBreakpointsContext, _provideBreakpointsContext] = createContext(namespace);
|
|
5208
5290
|
const context = createBreakpoints(options);
|
|
5209
5291
|
function provideBreakpointsContext(_context = context, app) {
|
|
@@ -5247,7 +5329,7 @@ function createBreakpointsContext(_options = {}) {
|
|
|
5247
5329
|
* ```
|
|
5248
5330
|
*/
|
|
5249
5331
|
function createBreakpointsPlugin(_options = {}) {
|
|
5250
|
-
const { namespace = "v0:breakpoints"
|
|
5332
|
+
const { namespace = "v0:breakpoints", ...options } = _options;
|
|
5251
5333
|
const [, provideBreakpointsContext, context] = createBreakpointsContext({
|
|
5252
5334
|
...options,
|
|
5253
5335
|
namespace
|
|
@@ -5305,25 +5387,217 @@ function useBreakpoints(namespace = "v0:breakpoints") {
|
|
|
5305
5387
|
}
|
|
5306
5388
|
|
|
5307
5389
|
//#endregion
|
|
5308
|
-
//#region src/composables/
|
|
5390
|
+
//#region src/composables/useClickOutside/index.ts
|
|
5309
5391
|
/**
|
|
5310
|
-
*
|
|
5392
|
+
* Detects clicks outside of the specified element(s).
|
|
5311
5393
|
*
|
|
5312
|
-
*
|
|
5394
|
+
* Uses two-phase detection (pointerdown → pointerup) to prevent false positives
|
|
5395
|
+
* when users drag from inside to outside an element.
|
|
5313
5396
|
*
|
|
5314
|
-
* @
|
|
5315
|
-
*
|
|
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.
|
|
5316
5401
|
*
|
|
5317
|
-
*
|
|
5318
|
-
*
|
|
5319
|
-
*
|
|
5320
|
-
*
|
|
5321
|
-
*
|
|
5322
|
-
*
|
|
5323
|
-
*
|
|
5324
|
-
*
|
|
5325
|
-
*
|
|
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
|
+
* ```
|
|
5326
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
|
|
5327
5601
|
/**
|
|
5328
5602
|
* Creates a new features instance.
|
|
5329
5603
|
*
|
|
@@ -5348,7 +5622,7 @@ function useBreakpoints(namespace = "v0:breakpoints") {
|
|
|
5348
5622
|
* ```
|
|
5349
5623
|
*/
|
|
5350
5624
|
function createFeatures(_options = {}) {
|
|
5351
|
-
const { features
|
|
5625
|
+
const { features, ...options } = _options;
|
|
5352
5626
|
const tokens = createTokens(features, { flat: true });
|
|
5353
5627
|
const registry = createGroup(options);
|
|
5354
5628
|
for (const [id, { value }] of tokens.entries()) register({
|
|
@@ -5402,7 +5676,7 @@ function createFeatures(_options = {}) {
|
|
|
5402
5676
|
* ```
|
|
5403
5677
|
*/
|
|
5404
5678
|
function createFeaturesContext(_options = {}) {
|
|
5405
|
-
const { namespace = "v0:features"
|
|
5679
|
+
const { namespace = "v0:features", ...options } = _options;
|
|
5406
5680
|
const [useFeaturesContext, _provideFeaturesContext] = createContext(namespace);
|
|
5407
5681
|
const context = createFeatures(options);
|
|
5408
5682
|
function provideFeaturesContext(_context = context, app) {
|
|
@@ -5441,7 +5715,7 @@ function createFeaturesContext(_options = {}) {
|
|
|
5441
5715
|
* ```
|
|
5442
5716
|
*/
|
|
5443
5717
|
function createFeaturesPlugin(_options = {}) {
|
|
5444
|
-
const { namespace = "v0:features"
|
|
5718
|
+
const { namespace = "v0:features", ...options } = _options;
|
|
5445
5719
|
const [, provideFeaturesContext, context] = createFeaturesContext({
|
|
5446
5720
|
...options,
|
|
5447
5721
|
namespace
|
|
@@ -5484,21 +5758,6 @@ function useFeatures(namespace = "v0:features") {
|
|
|
5484
5758
|
|
|
5485
5759
|
//#endregion
|
|
5486
5760
|
//#region src/composables/useFilter/index.ts
|
|
5487
|
-
/**
|
|
5488
|
-
* @module useFilter
|
|
5489
|
-
*
|
|
5490
|
-
* @remarks
|
|
5491
|
-
* Reactive array filtering composable with multiple filter modes.
|
|
5492
|
-
*
|
|
5493
|
-
* Key features:
|
|
5494
|
-
* - Four filter modes: some, every, union, intersection
|
|
5495
|
-
* - Case-insensitive filtering
|
|
5496
|
-
* - Custom filter functions
|
|
5497
|
-
* - Reactive updates
|
|
5498
|
-
* - Perfect for search, multi-criteria filtering
|
|
5499
|
-
*
|
|
5500
|
-
* Filters arrays based on query strings with configurable matching strategies.
|
|
5501
|
-
*/
|
|
5502
5761
|
function defaultFilter(query, item, keys, mode = "some") {
|
|
5503
5762
|
const queries = Array.isArray(query) ? query.map((q) => String(q).toLowerCase()) : [String(query).toLowerCase()];
|
|
5504
5763
|
function match(value, q) {
|
|
@@ -5512,6 +5771,89 @@ function defaultFilter(query, item, keys, mode = "some") {
|
|
|
5512
5771
|
return false;
|
|
5513
5772
|
}
|
|
5514
5773
|
/**
|
|
5774
|
+
* Creates a filter context with pre-configured options.
|
|
5775
|
+
*
|
|
5776
|
+
* @param options The filter options
|
|
5777
|
+
* @template Z The type of the items
|
|
5778
|
+
* @template E The type of the filter context
|
|
5779
|
+
* @returns A filter context
|
|
5780
|
+
*
|
|
5781
|
+
* @see https://0.vuetifyjs.com/composables/utilities/use-filter
|
|
5782
|
+
*
|
|
5783
|
+
* @example
|
|
5784
|
+
* ```ts
|
|
5785
|
+
* import { createFilter } from '@vuetify/v0'
|
|
5786
|
+
*
|
|
5787
|
+
* const filter = createFilter({
|
|
5788
|
+
* mode: 'intersection',
|
|
5789
|
+
* keys: ['name', 'email'],
|
|
5790
|
+
* })
|
|
5791
|
+
*
|
|
5792
|
+
* const { items } = filter.apply(query, users)
|
|
5793
|
+
* ```
|
|
5794
|
+
*/
|
|
5795
|
+
function createFilter(options = {}) {
|
|
5796
|
+
const { customFilter, keys, mode = "some" } = options;
|
|
5797
|
+
const filterFunction = customFilter ?? ((q, i) => defaultFilter(q, i, keys, mode));
|
|
5798
|
+
const query = toRef("");
|
|
5799
|
+
function apply(_query, items) {
|
|
5800
|
+
const itemsRef = isRef(items) ? items : toRef(() => items);
|
|
5801
|
+
const queryRef = toRef(_query);
|
|
5802
|
+
return { items: computed(() => {
|
|
5803
|
+
const q = toValue(queryRef);
|
|
5804
|
+
query.value = q;
|
|
5805
|
+
const queries = (Array.isArray(q) ? q : [q]).filter((q$1) => String(q$1).trim());
|
|
5806
|
+
if (queries.length === 0) return itemsRef.value;
|
|
5807
|
+
const queryParam = queries.length === 1 ? queries[0] : queries;
|
|
5808
|
+
return itemsRef.value.filter((item) => filterFunction(queryParam, item));
|
|
5809
|
+
}) };
|
|
5810
|
+
}
|
|
5811
|
+
return {
|
|
5812
|
+
mode,
|
|
5813
|
+
keys,
|
|
5814
|
+
customFilter,
|
|
5815
|
+
query,
|
|
5816
|
+
apply
|
|
5817
|
+
};
|
|
5818
|
+
}
|
|
5819
|
+
/**
|
|
5820
|
+
* Creates a filter context with dependency injection support.
|
|
5821
|
+
*
|
|
5822
|
+
* @param options The filter context options
|
|
5823
|
+
* @template Z The type of the items
|
|
5824
|
+
* @template E The type of the filter context
|
|
5825
|
+
* @returns A trinity tuple: [useContext, provideContext, defaultContext]
|
|
5826
|
+
*
|
|
5827
|
+
* @see https://0.vuetifyjs.com/composables/utilities/use-filter
|
|
5828
|
+
*
|
|
5829
|
+
* @example
|
|
5830
|
+
* ```ts
|
|
5831
|
+
* import { createFilterContext } from '@vuetify/v0'
|
|
5832
|
+
*
|
|
5833
|
+
* export const [useSearchFilter, provideSearchFilter, searchFilter] = createFilterContext({
|
|
5834
|
+
* namespace: 'app:search',
|
|
5835
|
+
* mode: 'union',
|
|
5836
|
+
* keys: ['title', 'description'],
|
|
5837
|
+
* })
|
|
5838
|
+
*
|
|
5839
|
+
* // In parent component
|
|
5840
|
+
* provideSearchFilter()
|
|
5841
|
+
*
|
|
5842
|
+
* // In child component
|
|
5843
|
+
* const filter = useSearchFilter()
|
|
5844
|
+
* const { items } = filter.apply(query, products)
|
|
5845
|
+
* ```
|
|
5846
|
+
*/
|
|
5847
|
+
function createFilterContext(_options = {}) {
|
|
5848
|
+
const { namespace = "v0:filter", ...options } = _options;
|
|
5849
|
+
const [useFilterContext$1, _provideFilterContext] = createContext(namespace);
|
|
5850
|
+
const context = createFilter(options);
|
|
5851
|
+
function provideFilterContext(_context = context, app) {
|
|
5852
|
+
return _provideFilterContext(_context, app);
|
|
5853
|
+
}
|
|
5854
|
+
return createTrinity(useFilterContext$1, provideFilterContext, context);
|
|
5855
|
+
}
|
|
5856
|
+
/**
|
|
5515
5857
|
* A reusable function for filtering an array of items.
|
|
5516
5858
|
*
|
|
5517
5859
|
* @param query The query to filter by.
|
|
@@ -5540,37 +5882,34 @@ function defaultFilter(query, item, keys, mode = "some") {
|
|
|
5540
5882
|
* ```
|
|
5541
5883
|
*/
|
|
5542
5884
|
function useFilter(query, items, options = {}) {
|
|
5543
|
-
|
|
5544
|
-
const filterFunction = customFilter ?? ((q, i) => defaultFilter(q, i, keys, mode));
|
|
5545
|
-
const itemsRef = isRef(items) ? items : toRef(() => items);
|
|
5546
|
-
const queryRef = toRef(query);
|
|
5547
|
-
return { items: computed(() => {
|
|
5548
|
-
const q = toValue(queryRef);
|
|
5549
|
-
const queries = (Array.isArray(q) ? q : [q]).filter((q$1) => String(q$1).trim());
|
|
5550
|
-
if (queries.length === 0) return itemsRef.value;
|
|
5551
|
-
const queryParam = queries.length === 1 ? queries[0] : queries;
|
|
5552
|
-
return itemsRef.value.filter((item) => filterFunction(queryParam, item));
|
|
5553
|
-
}) };
|
|
5885
|
+
return createFilter(options).apply(query, items);
|
|
5554
5886
|
}
|
|
5555
|
-
|
|
5556
|
-
//#endregion
|
|
5557
|
-
//#region src/composables/useForm/index.ts
|
|
5558
5887
|
/**
|
|
5559
|
-
*
|
|
5888
|
+
* Returns the current filter context from dependency injection.
|
|
5560
5889
|
*
|
|
5561
|
-
* @
|
|
5562
|
-
*
|
|
5890
|
+
* @param namespace The namespace for the filter context. Defaults to `'v0:filter'`.
|
|
5891
|
+
* @template Z The type of the items.
|
|
5892
|
+
* @template E The type of the filter context.
|
|
5893
|
+
* @returns The current filter context.
|
|
5563
5894
|
*
|
|
5564
|
-
*
|
|
5565
|
-
*
|
|
5566
|
-
*
|
|
5567
|
-
*
|
|
5568
|
-
*
|
|
5569
|
-
*
|
|
5570
|
-
*
|
|
5571
|
-
*
|
|
5572
|
-
*
|
|
5895
|
+
* @see https://0.vuetifyjs.com/composables/utilities/use-filter
|
|
5896
|
+
*
|
|
5897
|
+
* @example
|
|
5898
|
+
* ```vue
|
|
5899
|
+
* <script setup lang="ts">
|
|
5900
|
+
* import { useFilterContext } from '@vuetify/v0'
|
|
5901
|
+
*
|
|
5902
|
+
* const filter = useFilterContext()
|
|
5903
|
+
* const { items } = filter.apply(query, products)
|
|
5904
|
+
* <\/script>
|
|
5905
|
+
* ```
|
|
5573
5906
|
*/
|
|
5907
|
+
function useFilterContext(namespace = "v0:filter") {
|
|
5908
|
+
return useContext(namespace);
|
|
5909
|
+
}
|
|
5910
|
+
|
|
5911
|
+
//#endregion
|
|
5912
|
+
//#region src/composables/useForm/index.ts
|
|
5574
5913
|
/**
|
|
5575
5914
|
* Creates a new form instance.
|
|
5576
5915
|
*
|
|
@@ -5739,7 +6078,7 @@ function createForm(options) {
|
|
|
5739
6078
|
* ```
|
|
5740
6079
|
*/
|
|
5741
6080
|
function createFormContext(_options = {}) {
|
|
5742
|
-
const { namespace = "v0:form"
|
|
6081
|
+
const { namespace = "v0:form", ...options } = _options;
|
|
5743
6082
|
const [useFormContext, _provideFormContext] = createContext(namespace);
|
|
5744
6083
|
const context = createForm(options);
|
|
5745
6084
|
function provideFormContext(_context = context, app) {
|
|
@@ -5777,22 +6116,6 @@ function useForm(namespace = "v0:form") {
|
|
|
5777
6116
|
//#endregion
|
|
5778
6117
|
//#region src/composables/useIntersectionObserver/index.ts
|
|
5779
6118
|
/**
|
|
5780
|
-
* @module useIntersectionObserver
|
|
5781
|
-
*
|
|
5782
|
-
* @remarks
|
|
5783
|
-
* IntersectionObserver composable with lifecycle management.
|
|
5784
|
-
*
|
|
5785
|
-
* Key features:
|
|
5786
|
-
* - IntersectionObserver API wrapper
|
|
5787
|
-
* - Pause/resume/stop functionality
|
|
5788
|
-
* - Automatic cleanup on unmount
|
|
5789
|
-
* - SSR-safe (checks SUPPORTS_INTERSECTION_OBSERVER)
|
|
5790
|
-
* - Hydration-aware
|
|
5791
|
-
* - Immediate callback option
|
|
5792
|
-
*
|
|
5793
|
-
* Perfect for lazy loading, infinite scroll, and visibility detection.
|
|
5794
|
-
*/
|
|
5795
|
-
/**
|
|
5796
6119
|
* A composable that uses the Intersection Observer API to detect when an element
|
|
5797
6120
|
* is visible in the viewport.
|
|
5798
6121
|
*
|
|
@@ -5833,12 +6156,14 @@ function useForm(namespace = "v0:form") {
|
|
|
5833
6156
|
*/
|
|
5834
6157
|
function useIntersectionObserver(target, callback, options = {}) {
|
|
5835
6158
|
const { isHydrated } = useHydration();
|
|
6159
|
+
const targetRef = isRef(target) ? target : shallowRef(target);
|
|
5836
6160
|
const observer = shallowRef();
|
|
5837
6161
|
const isPaused = shallowRef(false);
|
|
5838
6162
|
const isIntersecting = shallowRef(false);
|
|
5839
6163
|
const isActive = toRef(() => !!observer.value);
|
|
5840
6164
|
function setup() {
|
|
5841
|
-
if (
|
|
6165
|
+
if (observer.value === null) return;
|
|
6166
|
+
if (!isHydrated.value || !SUPPORTS_INTERSECTION_OBSERVER || !targetRef.value || isPaused.value) return;
|
|
5842
6167
|
observer.value = new IntersectionObserver((entries) => {
|
|
5843
6168
|
const transformedEntries = entries.map((entry) => ({
|
|
5844
6169
|
boundingClientRect: entry.boundingClientRect,
|
|
@@ -5852,26 +6177,29 @@ function useIntersectionObserver(target, callback, options = {}) {
|
|
|
5852
6177
|
const latestEntry = transformedEntries.at(-1);
|
|
5853
6178
|
if (latestEntry) isIntersecting.value = latestEntry.isIntersecting;
|
|
5854
6179
|
callback(transformedEntries);
|
|
6180
|
+
if (options.once && latestEntry?.isIntersecting) stop();
|
|
5855
6181
|
}, {
|
|
5856
6182
|
root: options.root || null,
|
|
5857
6183
|
rootMargin: options.rootMargin || "0px",
|
|
5858
6184
|
threshold: options.threshold || 0
|
|
5859
6185
|
});
|
|
5860
|
-
observer.value.observe(
|
|
6186
|
+
observer.value.observe(targetRef.value);
|
|
5861
6187
|
if (options.immediate) callback([{
|
|
5862
|
-
boundingClientRect:
|
|
6188
|
+
boundingClientRect: targetRef.value.getBoundingClientRect(),
|
|
5863
6189
|
intersectionRatio: 0,
|
|
5864
6190
|
intersectionRect: new DOMRect(0, 0, 0, 0),
|
|
5865
6191
|
isIntersecting: false,
|
|
5866
6192
|
rootBounds: null,
|
|
5867
|
-
target:
|
|
6193
|
+
target: targetRef.value,
|
|
5868
6194
|
time: performance.now()
|
|
5869
6195
|
}]);
|
|
5870
6196
|
}
|
|
5871
|
-
|
|
6197
|
+
watchEffect(() => {
|
|
6198
|
+
const hydrated = isHydrated.value;
|
|
6199
|
+
const target$1 = targetRef.value;
|
|
5872
6200
|
cleanup();
|
|
5873
|
-
setup();
|
|
5874
|
-
}
|
|
6201
|
+
if (hydrated && target$1) setup();
|
|
6202
|
+
});
|
|
5875
6203
|
function cleanup() {
|
|
5876
6204
|
if (observer.value) {
|
|
5877
6205
|
observer.value.disconnect();
|
|
@@ -5889,6 +6217,7 @@ function useIntersectionObserver(target, callback, options = {}) {
|
|
|
5889
6217
|
}
|
|
5890
6218
|
function stop() {
|
|
5891
6219
|
cleanup();
|
|
6220
|
+
observer.value = null;
|
|
5892
6221
|
}
|
|
5893
6222
|
onScopeDispose(stop, true);
|
|
5894
6223
|
return {
|
|
@@ -5960,20 +6289,6 @@ function useElementIntersection(target, options = {}) {
|
|
|
5960
6289
|
//#endregion
|
|
5961
6290
|
//#region src/composables/useKeydown/index.ts
|
|
5962
6291
|
/**
|
|
5963
|
-
* @module useKeydown
|
|
5964
|
-
*
|
|
5965
|
-
* @remarks
|
|
5966
|
-
* Keydown event listener composable with key filtering.
|
|
5967
|
-
*
|
|
5968
|
-
* Key features:
|
|
5969
|
-
* - Key-specific event handling
|
|
5970
|
-
* - preventDefault and stopPropagation options
|
|
5971
|
-
* - Automatic cleanup on scope disposal
|
|
5972
|
-
* - Built on useEventListener for consistent event handling
|
|
5973
|
-
*
|
|
5974
|
-
* Simplified wrapper around useEventListener for keyboard interactions.
|
|
5975
|
-
*/
|
|
5976
|
-
/**
|
|
5977
6292
|
* A composable that adds a keydown event listener to the document.
|
|
5978
6293
|
*
|
|
5979
6294
|
* @param handlers The key handlers to add.
|
|
@@ -5985,6 +6300,10 @@ function useElementIntersection(target, options = {}) {
|
|
|
5985
6300
|
* ```ts
|
|
5986
6301
|
* import { useKeydown } from '@vuetify/v0'
|
|
5987
6302
|
*
|
|
6303
|
+
* // Single handler
|
|
6304
|
+
* useKeydown({ key: 'Escape', handler: () => console.log('Escape pressed') })
|
|
6305
|
+
*
|
|
6306
|
+
* // Multiple handlers
|
|
5988
6307
|
* const { isActive, start, stop } = useKeydown([
|
|
5989
6308
|
* { key: 'Enter', handler: () => console.log('Enter pressed') },
|
|
5990
6309
|
* { key: 'Escape', handler: () => console.log('Escape pressed'), preventDefault: true },
|
|
@@ -6029,22 +6348,6 @@ function useKeydown(handlers) {
|
|
|
6029
6348
|
//#endregion
|
|
6030
6349
|
//#region src/composables/useMutationObserver/index.ts
|
|
6031
6350
|
/**
|
|
6032
|
-
* @module useMutationObserver
|
|
6033
|
-
*
|
|
6034
|
-
* @remarks
|
|
6035
|
-
* MutationObserver composable with lifecycle management.
|
|
6036
|
-
*
|
|
6037
|
-
* Key features:
|
|
6038
|
-
* - MutationObserver API wrapper
|
|
6039
|
-
* - Pause/resume/stop functionality
|
|
6040
|
-
* - Automatic cleanup on unmount
|
|
6041
|
-
* - SSR-safe (checks SUPPORTS_MUTATION_OBSERVER)
|
|
6042
|
-
* - Hydration-aware
|
|
6043
|
-
* - Configurable observation options (childList, attributes, characterData, etc.)
|
|
6044
|
-
*
|
|
6045
|
-
* Perfect for detecting DOM changes and responding to mutations.
|
|
6046
|
-
*/
|
|
6047
|
-
/**
|
|
6048
6351
|
* A composable that uses the Mutation Observer API to detect changes in the DOM.
|
|
6049
6352
|
*
|
|
6050
6353
|
* @param target The element to observe.
|
|
@@ -6091,7 +6394,7 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6091
6394
|
const { isHydrated } = useHydration();
|
|
6092
6395
|
const observer = shallowRef();
|
|
6093
6396
|
const isPaused = shallowRef(false);
|
|
6094
|
-
const isActive =
|
|
6397
|
+
const isActive = toRef(() => !!observer.value);
|
|
6095
6398
|
const observerOptions = {
|
|
6096
6399
|
childList: options.childList ?? true,
|
|
6097
6400
|
attributes: options.attributes ?? false,
|
|
@@ -6102,6 +6405,7 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6102
6405
|
attributeFilter: options.attributeFilter
|
|
6103
6406
|
};
|
|
6104
6407
|
function setup() {
|
|
6408
|
+
if (observer.value === null) return;
|
|
6105
6409
|
if (!isHydrated.value || !SUPPORTS_MUTATION_OBSERVER || !target.value || isPaused.value) return;
|
|
6106
6410
|
observer.value = new MutationObserver((mutations) => {
|
|
6107
6411
|
callback(mutations.map((mutation) => ({
|
|
@@ -6115,6 +6419,7 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6115
6419
|
attributeNamespace: mutation.attributeNamespace,
|
|
6116
6420
|
oldValue: mutation.oldValue
|
|
6117
6421
|
})));
|
|
6422
|
+
if (options.once) stop();
|
|
6118
6423
|
});
|
|
6119
6424
|
observer.value.observe(target.value, observerOptions);
|
|
6120
6425
|
if (options.immediate) {
|
|
@@ -6135,12 +6440,15 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6135
6440
|
attributeNamespace: null,
|
|
6136
6441
|
oldValue: null
|
|
6137
6442
|
}]);
|
|
6443
|
+
if (options.once) stop();
|
|
6138
6444
|
}
|
|
6139
6445
|
}
|
|
6140
|
-
|
|
6446
|
+
watchEffect(() => {
|
|
6447
|
+
const hydrated = isHydrated.value;
|
|
6448
|
+
const el = target.value;
|
|
6141
6449
|
cleanup();
|
|
6142
|
-
setup();
|
|
6143
|
-
}
|
|
6450
|
+
if (hydrated && el) setup();
|
|
6451
|
+
});
|
|
6144
6452
|
function cleanup() {
|
|
6145
6453
|
if (observer.value) {
|
|
6146
6454
|
observer.value.disconnect();
|
|
@@ -6157,6 +6465,7 @@ function useMutationObserver(target, callback, options = {}) {
|
|
|
6157
6465
|
}
|
|
6158
6466
|
function stop() {
|
|
6159
6467
|
cleanup();
|
|
6468
|
+
observer.value = null;
|
|
6160
6469
|
}
|
|
6161
6470
|
onScopeDispose(stop, true);
|
|
6162
6471
|
return {
|
|
@@ -6189,23 +6498,6 @@ var Vuetify0PermissionAdapter = class extends PermissionAdapter {
|
|
|
6189
6498
|
//#endregion
|
|
6190
6499
|
//#region src/composables/usePermissions/index.ts
|
|
6191
6500
|
/**
|
|
6192
|
-
* @module usePermissions
|
|
6193
|
-
*
|
|
6194
|
-
* @see https://0.vuetifyjs.com/composables/plugins/use-permissions
|
|
6195
|
-
*
|
|
6196
|
-
* @remarks
|
|
6197
|
-
* Permission management composable with support for RBAC and ABAC patterns.
|
|
6198
|
-
*
|
|
6199
|
-
* Key features:
|
|
6200
|
-
* - Role-Based Access Control (RBAC) support
|
|
6201
|
-
* - Attribute-Based Access Control (ABAC) with context
|
|
6202
|
-
* - Functional permission conditions
|
|
6203
|
-
* - Token-based permission storage
|
|
6204
|
-
* - Adapter pattern for custom permission systems
|
|
6205
|
-
*
|
|
6206
|
-
* Built on useTokens for flexible permission configuration.
|
|
6207
|
-
*/
|
|
6208
|
-
/**
|
|
6209
6501
|
* Creates a new permissions instance.
|
|
6210
6502
|
*
|
|
6211
6503
|
* @param options The options for the permissions instance.
|
|
@@ -6229,7 +6521,7 @@ var Vuetify0PermissionAdapter = class extends PermissionAdapter {
|
|
|
6229
6521
|
* ```
|
|
6230
6522
|
*/
|
|
6231
6523
|
function createPermissions(_options = {}) {
|
|
6232
|
-
const { adapter = new Vuetify0PermissionAdapter(), permissions = {}
|
|
6524
|
+
const { adapter = new Vuetify0PermissionAdapter(), permissions = {}, ...options } = _options;
|
|
6233
6525
|
const record = {};
|
|
6234
6526
|
for (const role in permissions) {
|
|
6235
6527
|
if (!record[role]) record[role] = {};
|
|
@@ -6271,7 +6563,7 @@ function createPermissions(_options = {}) {
|
|
|
6271
6563
|
* ```
|
|
6272
6564
|
*/
|
|
6273
6565
|
function createPermissionsContext(_options = {}) {
|
|
6274
|
-
const { namespace = "v0:permissions"
|
|
6566
|
+
const { namespace = "v0:permissions", ...options } = _options;
|
|
6275
6567
|
const [usePermissionsContext, _providePermissionsContext] = createContext(namespace);
|
|
6276
6568
|
const context = createPermissions(options);
|
|
6277
6569
|
function providePermissionsContext(_context = context, app) {
|
|
@@ -6310,7 +6602,7 @@ function createPermissionsContext(_options = {}) {
|
|
|
6310
6602
|
* ```
|
|
6311
6603
|
*/
|
|
6312
6604
|
function createPermissionsPlugin(_options = {}) {
|
|
6313
|
-
const { namespace = "v0:permissions"
|
|
6605
|
+
const { namespace = "v0:permissions", ...options } = _options;
|
|
6314
6606
|
const [, providePermissionContext, context] = createPermissionsContext({
|
|
6315
6607
|
...options,
|
|
6316
6608
|
namespace
|
|
@@ -6352,21 +6644,6 @@ function usePermissions(namespace = "v0:permissions") {
|
|
|
6352
6644
|
//#endregion
|
|
6353
6645
|
//#region src/composables/useQueue/index.ts
|
|
6354
6646
|
/**
|
|
6355
|
-
* @module useQueue
|
|
6356
|
-
*
|
|
6357
|
-
* @remarks
|
|
6358
|
-
* A queue composable for managing time-based collections with:
|
|
6359
|
-
* - Automatic timeout-based removal
|
|
6360
|
-
* - Pause/resume functionality
|
|
6361
|
-
* - FIFO (First In, First Out) ordering
|
|
6362
|
-
* - Manual dismissal support
|
|
6363
|
-
* - Queue progression management
|
|
6364
|
-
*
|
|
6365
|
-
* Built on top of useRegistry, the queue automatically manages timeouts for tickets,
|
|
6366
|
-
* ensuring only the first ticket in the queue is active at any time. When an ticket
|
|
6367
|
-
* expires or is removed, the next ticket in the queue automatically becomes active.
|
|
6368
|
-
*/
|
|
6369
|
-
/**
|
|
6370
6647
|
* Creates a new queue instance
|
|
6371
6648
|
*
|
|
6372
6649
|
* @param options The options for the queue instance
|
|
@@ -6398,7 +6675,7 @@ function usePermissions(namespace = "v0:permissions") {
|
|
|
6398
6675
|
* ```
|
|
6399
6676
|
*/
|
|
6400
6677
|
function createQueue(_options = {}) {
|
|
6401
|
-
const { timeout: _timeout = 3e3
|
|
6678
|
+
const { timeout: _timeout = 3e3, ...options } = _options;
|
|
6402
6679
|
const registry = useRegistry({
|
|
6403
6680
|
...options,
|
|
6404
6681
|
events: true
|
|
@@ -6493,7 +6770,6 @@ function createQueue(_options = {}) {
|
|
|
6493
6770
|
/**
|
|
6494
6771
|
* Creates a new queue context.
|
|
6495
6772
|
*
|
|
6496
|
-
* @param namespace The namespace for the queue context.
|
|
6497
6773
|
* @param options The options for the queue context.
|
|
6498
6774
|
* @template Z The type of the queue ticket.
|
|
6499
6775
|
* @template E The type of the queue context.
|
|
@@ -6505,13 +6781,13 @@ function createQueue(_options = {}) {
|
|
|
6505
6781
|
* ```ts
|
|
6506
6782
|
* import { createQueueContext } from '@vuetify/v0'
|
|
6507
6783
|
*
|
|
6508
|
-
* export const [useQueue, provideQueue] = createQueueContext(
|
|
6784
|
+
* export const [useQueue, provideQueue, context] = createQueueContext({
|
|
6509
6785
|
* timeout: 5000,
|
|
6510
6786
|
* })
|
|
6511
6787
|
* ```
|
|
6512
6788
|
*/
|
|
6513
|
-
function createQueueContext(_options) {
|
|
6514
|
-
const { namespace
|
|
6789
|
+
function createQueueContext(_options = {}) {
|
|
6790
|
+
const { namespace = "v0:queue", ...options } = _options;
|
|
6515
6791
|
const [useQueueContext, _provideQueueContext] = createContext(namespace);
|
|
6516
6792
|
const context = createQueue(options);
|
|
6517
6793
|
function provideQueueContext(_context = context, app) {
|
|
@@ -6569,21 +6845,6 @@ var MemoryAdapter = class {
|
|
|
6569
6845
|
//#endregion
|
|
6570
6846
|
//#region src/composables/useStorage/index.ts
|
|
6571
6847
|
/**
|
|
6572
|
-
* @module useStorage
|
|
6573
|
-
*
|
|
6574
|
-
* @remarks
|
|
6575
|
-
* Reactive storage composable with adapter pattern for localStorage, sessionStorage, or memory.
|
|
6576
|
-
*
|
|
6577
|
-
* Key features:
|
|
6578
|
-
* - Reactive refs that sync with storage
|
|
6579
|
-
* - localStorage, sessionStorage, and memory adapters
|
|
6580
|
-
* - Custom serialization support
|
|
6581
|
-
* - SSR fallback to memory adapter
|
|
6582
|
-
* - Automatic cleanup on remove/clear
|
|
6583
|
-
*
|
|
6584
|
-
* Uses adapter pattern to abstract storage implementation details.
|
|
6585
|
-
*/
|
|
6586
|
-
/**
|
|
6587
6848
|
* Creates a new storage instance.
|
|
6588
6849
|
*
|
|
6589
6850
|
* @param options The options for the storage instance.
|
|
@@ -6669,7 +6930,7 @@ function createStorage(options = {}) {
|
|
|
6669
6930
|
};
|
|
6670
6931
|
}
|
|
6671
6932
|
function createStorageContext(_options = {}) {
|
|
6672
|
-
const { namespace = "v0:storage"
|
|
6933
|
+
const { namespace = "v0:storage", ...options } = _options;
|
|
6673
6934
|
const [useStorageContext, _provideStorageContext] = createContext(namespace);
|
|
6674
6935
|
const context = createStorage(options);
|
|
6675
6936
|
function provideStorageContext(_context = context, app) {
|
|
@@ -6699,7 +6960,7 @@ function createStorageContext(_options = {}) {
|
|
|
6699
6960
|
* ```
|
|
6700
6961
|
*/
|
|
6701
6962
|
function createStoragePlugin(_options = {}) {
|
|
6702
|
-
const { namespace = "v0:storage"
|
|
6963
|
+
const { namespace = "v0:storage", ...options } = _options;
|
|
6703
6964
|
const [, provideStorageContext, context] = createStorageContext({
|
|
6704
6965
|
...options,
|
|
6705
6966
|
namespace
|
|
@@ -6820,24 +7081,6 @@ var Vuetify0ThemeAdapter = class extends ThemeAdapter {
|
|
|
6820
7081
|
//#endregion
|
|
6821
7082
|
//#region src/composables/useTheme/index.ts
|
|
6822
7083
|
/**
|
|
6823
|
-
* @module useTheme
|
|
6824
|
-
*
|
|
6825
|
-
* @see https://0.vuetifyjs.com/composables/plugins/use-theme
|
|
6826
|
-
*
|
|
6827
|
-
* @remarks
|
|
6828
|
-
* Theme management composable with token resolution and CSS variable injection.
|
|
6829
|
-
*
|
|
6830
|
-
* Key features:
|
|
6831
|
-
* - Single-selection theme switching (extends createSingle)
|
|
6832
|
-
* - Token alias resolution via useTokens
|
|
6833
|
-
* - Lazy theme loading (compute colors only when selected)
|
|
6834
|
-
* - CSS variable generation via adapter pattern
|
|
6835
|
-
* - SSR support with head integration
|
|
6836
|
-
* - Theme cycling
|
|
6837
|
-
*
|
|
6838
|
-
* Integrates with createSingle for selection and useTokens for color resolution.
|
|
6839
|
-
*/
|
|
6840
|
-
/**
|
|
6841
7084
|
* Creates a new theme instance.
|
|
6842
7085
|
*
|
|
6843
7086
|
* @param options The options for the theme instance.
|
|
@@ -6872,14 +7115,14 @@ var Vuetify0ThemeAdapter = class extends ThemeAdapter {
|
|
|
6872
7115
|
* ```
|
|
6873
7116
|
*/
|
|
6874
7117
|
function createTheme(_options = {}) {
|
|
6875
|
-
const { themes = {}, palette = {}
|
|
7118
|
+
const { themes = {}, palette = {}, ...options } = _options;
|
|
6876
7119
|
const tokens = createTokens({
|
|
6877
7120
|
palette,
|
|
6878
7121
|
...themes
|
|
6879
7122
|
}, { flat: true });
|
|
6880
7123
|
const registry = createSingle(options);
|
|
6881
7124
|
for (const id in themes) {
|
|
6882
|
-
const { colors: value
|
|
7125
|
+
const { colors: value, ...theme } = themes[id];
|
|
6883
7126
|
register({
|
|
6884
7127
|
id,
|
|
6885
7128
|
value,
|
|
@@ -6961,7 +7204,7 @@ function createTheme(_options = {}) {
|
|
|
6961
7204
|
* ```
|
|
6962
7205
|
*/
|
|
6963
7206
|
function createThemeContext(_options = {}) {
|
|
6964
|
-
const { namespace = "v0:theme"
|
|
7207
|
+
const { namespace = "v0:theme", ...options } = _options;
|
|
6965
7208
|
const [useThemeContext, _provideThemeContext] = createContext(namespace);
|
|
6966
7209
|
const context = createTheme(options);
|
|
6967
7210
|
function provideThemeContext(_context = context, app) {
|
|
@@ -7011,7 +7254,7 @@ function createThemeContext(_options = {}) {
|
|
|
7011
7254
|
* ```
|
|
7012
7255
|
*/
|
|
7013
7256
|
function createThemePlugin(_options = {}) {
|
|
7014
|
-
const { adapter = new Vuetify0ThemeAdapter(), namespace = "v0:theme", palette = {}, themes = {}, target
|
|
7257
|
+
const { adapter = new Vuetify0ThemeAdapter(), namespace = "v0:theme", palette = {}, themes = {}, target, ...options } = _options;
|
|
7015
7258
|
const [, provideThemeContext, context] = createThemeContext({
|
|
7016
7259
|
...options,
|
|
7017
7260
|
namespace,
|
|
@@ -7058,21 +7301,6 @@ function useTheme(namespace = "v0:theme") {
|
|
|
7058
7301
|
//#endregion
|
|
7059
7302
|
//#region src/composables/useTimeline/index.ts
|
|
7060
7303
|
/**
|
|
7061
|
-
* @module useTimeline
|
|
7062
|
-
*
|
|
7063
|
-
* @remarks
|
|
7064
|
-
* Bounded undo/redo system with overflow management.
|
|
7065
|
-
*
|
|
7066
|
-
* Key features:
|
|
7067
|
-
* - Fixed-size history (default: 10 items)
|
|
7068
|
-
* - Undo/redo stack management
|
|
7069
|
-
* - Overflow queue (preserves oldest items)
|
|
7070
|
-
* - Automatic reindexing after operations
|
|
7071
|
-
* - Perfect for command pattern, history tracking
|
|
7072
|
-
*
|
|
7073
|
-
* Extends useRegistry with temporal navigation capabilities.
|
|
7074
|
-
*/
|
|
7075
|
-
/**
|
|
7076
7304
|
* Creates a new timeline instance.
|
|
7077
7305
|
*
|
|
7078
7306
|
* @param _options The options for the timeline instance.
|
|
@@ -7100,7 +7328,7 @@ function useTheme(namespace = "v0:theme") {
|
|
|
7100
7328
|
* ```
|
|
7101
7329
|
*/
|
|
7102
7330
|
function createTimeline(_options = {}) {
|
|
7103
|
-
const { size = 10
|
|
7331
|
+
const { size = 10, ...options } = _options;
|
|
7104
7332
|
const registry = useRegistry(options);
|
|
7105
7333
|
const stack = [];
|
|
7106
7334
|
const overflow = [];
|
|
@@ -7175,7 +7403,7 @@ function createTimeline(_options = {}) {
|
|
|
7175
7403
|
* ```
|
|
7176
7404
|
*/
|
|
7177
7405
|
function createTimelineContext(_options = {}) {
|
|
7178
|
-
const { namespace = "v0:timeline"
|
|
7406
|
+
const { namespace = "v0:timeline", ...options } = _options;
|
|
7179
7407
|
const [useTimelineContext, _provideTimelineContext] = createContext(namespace);
|
|
7180
7408
|
const context = createTimeline(options);
|
|
7181
7409
|
function provideTimelineContext(_context = context, app) {
|
|
@@ -7207,24 +7435,6 @@ function useTimeline(namespace = "v0:timeline") {
|
|
|
7207
7435
|
//#endregion
|
|
7208
7436
|
//#region src/composables/useToggleScope/index.ts
|
|
7209
7437
|
/**
|
|
7210
|
-
* @module useToggleScope
|
|
7211
|
-
*
|
|
7212
|
-
* @remarks
|
|
7213
|
-
* Conditionally manages an effect scope based on a reactive boolean condition.
|
|
7214
|
-
* When the source becomes true, creates and runs an effect scope. When false, stops the scope.
|
|
7215
|
-
* All reactive effects created within the scoped function are automatically cleaned up on deactivation.
|
|
7216
|
-
*
|
|
7217
|
-
* Key features:
|
|
7218
|
-
* - Uses Vue's effectScope for efficient reactive effect lifecycle management
|
|
7219
|
-
* - Automatic cleanup when condition becomes false
|
|
7220
|
-
* - Supports optional reset callback for scope restart capability
|
|
7221
|
-
* - Handles rapid toggling and parent scope disposal safely
|
|
7222
|
-
* - SSR-safe (effectScope is part of Vue core)
|
|
7223
|
-
*
|
|
7224
|
-
* Perfect for conditional side effects, feature flags, and performance optimization
|
|
7225
|
-
* by only running reactive effects when needed.
|
|
7226
|
-
*/
|
|
7227
|
-
/**
|
|
7228
7438
|
* Conditionally manages an effect scope based on a reactive boolean source.
|
|
7229
7439
|
*
|
|
7230
7440
|
* @param source A reactive boolean value or getter that controls the scope lifecycle
|
|
@@ -7306,24 +7516,6 @@ function useToggleScope(source, fn) {
|
|
|
7306
7516
|
//#endregion
|
|
7307
7517
|
//#region src/composables/useVirtual/index.ts
|
|
7308
7518
|
/**
|
|
7309
|
-
* @module useVirtual
|
|
7310
|
-
*
|
|
7311
|
-
* @remarks
|
|
7312
|
-
* Virtual scrolling composable for efficiently rendering large lists.
|
|
7313
|
-
*
|
|
7314
|
-
* Key features:
|
|
7315
|
-
* - Renders only visible items (viewport + overscan)
|
|
7316
|
-
* - Dynamic or fixed item heights
|
|
7317
|
-
* - SSR-safe (checks IN_BROWSER)
|
|
7318
|
-
* - Bidirectional scrolling (forward/reverse for chat apps)
|
|
7319
|
-
* - Scroll anchoring (maintains position across data changes)
|
|
7320
|
-
* - Edge detection for infinite scroll
|
|
7321
|
-
* - iOS momentum and elastic scrolling
|
|
7322
|
-
* - Configurable overscan (extra items rendered for smooth scrolling)
|
|
7323
|
-
*
|
|
7324
|
-
* Perfect for large data sets, chat apps, and infinite scroll implementations.
|
|
7325
|
-
*/
|
|
7326
|
-
/**
|
|
7327
7519
|
* Virtual scrolling composable for efficiently rendering large lists
|
|
7328
7520
|
*
|
|
7329
7521
|
* @param items Reactive array of items to virtualize
|
|
@@ -7560,6 +7752,11 @@ function useVirtual(items, _options = {}) {
|
|
|
7560
7752
|
element.value.scrollTop = totalHeight;
|
|
7561
7753
|
}
|
|
7562
7754
|
}
|
|
7755
|
+
onScopeDispose(() => {
|
|
7756
|
+
cancelAnimationFrame(raf);
|
|
7757
|
+
cancelAnimationFrame(rebuildRaf);
|
|
7758
|
+
cancelAnimationFrame(edgeRaf);
|
|
7759
|
+
}, true);
|
|
7563
7760
|
return {
|
|
7564
7761
|
element,
|
|
7565
7762
|
items: computedItems,
|
|
@@ -7575,4 +7772,4 @@ function useVirtual(items, _options = {}) {
|
|
|
7575
7772
|
}
|
|
7576
7773
|
|
|
7577
7774
|
//#endregion
|
|
7578
|
-
export { Atom_default as Atom, Avatar, COMMON_ELEMENTS, ConsolaLoggerAdapter, ExpansionPanel, Group, IN_BROWSER, MemoryAdapter, Pagination, PermissionAdapter, PinoLoggerAdapter, Popover, SELF_CLOSING_TAGS, SUPPORTS_INTERSECTION_OBSERVER, SUPPORTS_MATCH_MEDIA, SUPPORTS_MUTATION_OBSERVER, SUPPORTS_OBSERVER, SUPPORTS_TOUCH, Selection, Single, Step, Vuetify0LocaleAdapter, Vuetify0LoggerAdapter, Vuetify0ThemeAdapter, __LOGGER_ENABLED__, clamp, createBreakpoints, createBreakpointsContext, createBreakpointsPlugin, createContext, createFallbackHydration, createFeatures, createFeaturesContext, createFeaturesPlugin, createForm, createFormContext, createGroup, createGroupContext, createHydration, createHydrationContext, createHydrationPlugin, createLocale, createLocaleContext, createLocaleFallback, createLocalePlugin, createLogger, createLoggerContext, createLoggerPlugin, createOverflow, createOverflowContext, createPagination, createPaginationContext, createPermissions, createPermissionsContext, createPermissionsPlugin, createPlugin, createQueue, createQueueContext, createRegistryContext, createSelection, createSelectionContext, createSingle, createSingleContext, createStep, createStepContext, createStorage, createStorageContext, createStoragePlugin, createTheme, createThemeContext, createThemePlugin, createTimeline, createTimelineContext, createTokens, createTokensContext, createTrinity, debounce, genId, isArray, isBoolean, isFunction, isNaN, isNull, isNullOrUndefined, isNumber, isObject, isPrimitive, isSelfClosingTag, isString, 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, 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 };
|