@vuetify/v0 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/adapter-CJIj5ySf.d.mts +11 -0
  2. package/dist/adapter-Cmeg49W9.mjs +229 -0
  3. package/dist/adapter-D2JoR-4d.d.mts +344 -0
  4. package/dist/adapters-BQ-Lr3PW.mjs +1 -0
  5. package/dist/adapters-DEXpW9If.mjs +1 -0
  6. package/dist/adapters-Q9WaOsJp.mjs +1 -0
  7. package/dist/adapters-SSDVth5e.mjs +1 -0
  8. package/dist/browser/index.js +953 -1026
  9. package/dist/components/index.d.mts +20 -7
  10. package/dist/components/index.mjs +38 -6
  11. package/dist/{components-C0zEvP7w.mjs → components-BbbGkTcN.mjs} +579 -107
  12. package/dist/composables/index.d.mts +17 -4
  13. package/dist/composables/index.mjs +36 -4
  14. package/dist/consola-DiUk9j3y.d.mts +15 -0
  15. package/dist/consola-GBy8XRuL.mjs +31 -0
  16. package/dist/constants/index.d.mts +1 -1
  17. package/dist/constants/index.mjs +3 -3
  18. package/dist/constants-B8pMSkcW.mjs +1 -0
  19. package/dist/createDataTable-cNf6DdHz.mjs +387 -0
  20. package/dist/createGroup-BrZPZudL.mjs +363 -0
  21. package/dist/createPagination-Wc_vRGNQ.mjs +234 -0
  22. package/dist/createSelection-BURpoE3p.mjs +261 -0
  23. package/dist/createSingle-BE1vHaZy.mjs +179 -0
  24. package/dist/createTokens-jwf8-iGn.mjs +682 -0
  25. package/dist/createTrinity-DkwPrPRS.mjs +149 -0
  26. package/dist/data-table/adapters/client/index.d.mts +3 -0
  27. package/dist/data-table/adapters/client/index.mjs +9 -0
  28. package/dist/data-table/adapters/index.d.mts +5 -0
  29. package/dist/data-table/adapters/index.mjs +12 -0
  30. package/dist/data-table/adapters/server/index.d.mts +3 -0
  31. package/dist/data-table/adapters/server/index.mjs +7 -0
  32. package/dist/data-table/adapters/virtual/index.d.mts +3 -0
  33. package/dist/data-table/adapters/virtual/index.mjs +9 -0
  34. package/dist/data-table/index.d.mts +7 -0
  35. package/dist/data-table/index.mjs +25 -0
  36. package/dist/date/index.d.mts +1 -1
  37. package/dist/date/index.mjs +2 -2
  38. package/dist/features/adapters/flagsmith/index.d.mts +16 -0
  39. package/dist/features/adapters/flagsmith/index.mjs +3 -0
  40. package/dist/features/adapters/launchdarkly/index.d.mts +15 -0
  41. package/dist/features/adapters/launchdarkly/index.mjs +3 -0
  42. package/dist/features/adapters/posthog/index.d.mts +15 -0
  43. package/dist/features/adapters/posthog/index.mjs +4 -0
  44. package/dist/features/index.d.mts +17 -0
  45. package/dist/features/index.mjs +18 -0
  46. package/dist/flagsmith-CHmpPGR7.mjs +40 -0
  47. package/dist/{globals-BwYsH-rt.mjs → globals-vN-O052q.mjs} +2 -2
  48. package/dist/index-BDTbJClL.d.mts +11 -0
  49. package/dist/{index-2wh69fk5.d.mts → index-BTMzRHep.d.mts} +187 -1417
  50. package/dist/index-BuOz3Rgm.d.mts +32 -0
  51. package/dist/{index-Bmem4l8m.d.mts → index-Bv1VN_j5.d.mts} +1 -1
  52. package/dist/{index-DFM5iBqh.d.mts → index-DRax9EgT.d.mts} +1044 -437
  53. package/dist/index-DdWxDPX3.d.mts +251 -0
  54. package/dist/{index-DBZTizq2.d.mts → index-UNwEBkQT.d.mts} +16 -2
  55. package/dist/index.d.mts +20 -7
  56. package/dist/index.mjs +39 -7
  57. package/dist/json/attributes.json +172 -0
  58. package/dist/json/importMap.json +28 -0
  59. package/dist/json/tags.json +73 -0
  60. package/dist/json/web-types.json +475 -1
  61. package/dist/launchdarkly-W8t8ZANX.mjs +28 -0
  62. package/dist/locale/adapters/index.d.mts +3 -0
  63. package/dist/locale/adapters/index.mjs +6 -0
  64. package/dist/locale/adapters/v0/index.d.mts +3 -0
  65. package/dist/locale/adapters/v0/index.mjs +5 -0
  66. package/dist/locale/index.d.mts +17 -0
  67. package/dist/locale/index.mjs +17 -0
  68. package/dist/logger/adapters/consola/index.d.mts +3 -0
  69. package/dist/logger/adapters/consola/index.mjs +3 -0
  70. package/dist/logger/adapters/index.d.mts +5 -0
  71. package/dist/logger/adapters/index.mjs +8 -0
  72. package/dist/logger/adapters/pino/index.d.mts +3 -0
  73. package/dist/logger/adapters/pino/index.mjs +5 -0
  74. package/dist/logger/adapters/v0/index.d.mts +3 -0
  75. package/dist/logger/adapters/v0/index.mjs +5 -0
  76. package/dist/logger/index.d.mts +17 -0
  77. package/dist/logger/index.mjs +10 -0
  78. package/dist/memory-BsZGbGnG.mjs +27 -0
  79. package/dist/memory-DVjquu_v.d.mts +25 -0
  80. package/dist/permissions/adapters/index.d.mts +18 -0
  81. package/dist/permissions/adapters/index.mjs +6 -0
  82. package/dist/permissions/adapters/v0/index.d.mts +18 -0
  83. package/dist/permissions/adapters/v0/index.mjs +5 -0
  84. package/dist/permissions/index.d.mts +17 -0
  85. package/dist/permissions/index.mjs +15 -0
  86. package/dist/pino-DFxkZLiu.mjs +49 -0
  87. package/dist/pino-p-jDkNQd.d.mts +24 -0
  88. package/dist/posthog-BOUoZTTf.mjs +50 -0
  89. package/dist/server-B-HWxaTQ.d.mts +20 -0
  90. package/dist/server-C2R2POGE.mjs +45 -0
  91. package/dist/storage/adapters/index.d.mts +3 -0
  92. package/dist/storage/adapters/index.mjs +3 -0
  93. package/dist/storage/adapters/memory/index.d.mts +2 -0
  94. package/dist/storage/adapters/memory/index.mjs +3 -0
  95. package/dist/storage/index.d.mts +17 -0
  96. package/dist/storage/index.mjs +37 -0
  97. package/dist/theme/adapters/index.d.mts +17 -0
  98. package/dist/theme/adapters/index.mjs +6 -0
  99. package/dist/theme/adapters/v0/index.d.mts +17 -0
  100. package/dist/theme/adapters/v0/index.mjs +5 -0
  101. package/dist/theme/index.d.mts +17 -0
  102. package/dist/theme/index.mjs +16 -0
  103. package/dist/toArray-VIn8vYt3.mjs +38 -0
  104. package/dist/types/index.d.mts +1 -1
  105. package/dist/useClickOutside-DIi0kjN5.mjs +4716 -0
  106. package/dist/useFeatures-6O7EPJUS.mjs +122 -0
  107. package/dist/useLocale-DHjbekzS.mjs +85 -0
  108. package/dist/useLogger-BXqiUvt2.mjs +283 -0
  109. package/dist/usePermissions-DFacFVqO.mjs +128 -0
  110. package/dist/useTheme-D0_1mjTw.mjs +135 -0
  111. package/dist/utilities/index.d.mts +3 -3
  112. package/dist/utilities/index.mjs +3 -3
  113. package/dist/{utilities-BbKjbXTx.mjs → utilities-Dx8wzGa5.mjs} +20 -3
  114. package/dist/v0-BNXo1ecc.d.mts +10 -0
  115. package/dist/v0-BOxb3nD1.d.mts +33 -0
  116. package/dist/v0-BPzPP8C5.d.mts +9 -0
  117. package/dist/v0-BYqmw3qM.mjs +21 -0
  118. package/dist/v0-C8DBv9mh.mjs +73 -0
  119. package/dist/v0-CfSj99gF.mjs +37 -0
  120. package/dist/v0-DHMoZ7dS.d.mts +22 -0
  121. package/dist/v0-Dc5mcpQs.mjs +41 -0
  122. package/dist/v0-Dwufx8ae.mjs +83 -0
  123. package/dist/virtual-A4e1yrdn.d.mts +9 -0
  124. package/dist/virtual-BoTGK6HT.mjs +44 -0
  125. package/package.json +34 -2
  126. package/dist/useClickOutside-DrkNYxDe.mjs +0 -8871
  127. /package/dist/{adapter-D95FHAtt.d.mts → adapter-DcwxFryd.d.mts} +0 -0
  128. /package/dist/{constants-DHKqjdjH.mjs → adapters-BGJKsBrw.mjs} +0 -0
  129. /package/dist/{htmlElements-DO9n35bD.mjs → htmlElements-d8iBCGpO.mjs} +0 -0
  130. /package/dist/{index-BLK67J_-.d.mts → index-BFBN5Zl3.d.mts} +0 -0
@@ -0,0 +1,363 @@
1
+ import { h as isUndefined, v as useId$1 } from "./utilities-Dx8wzGa5.mjs";
2
+ import { i as useContext, n as createContext, t as createTrinity } from "./createTrinity-DkwPrPRS.mjs";
3
+ import { t as createSelection } from "./createSelection-BURpoE3p.mjs";
4
+ import { t as toArray } from "./toArray-VIn8vYt3.mjs";
5
+ import { computed, onScopeDispose, reactive, shallowReactive, toRef, toValue } from "vue";
6
+
7
+ //#region src/composables/useProxyRegistry/index.ts
8
+ /**
9
+ * @module useProxyRegistry
10
+ *
11
+ * @remarks
12
+ * Proxy composable for reactive registry keys, values, entries, and size.
13
+ *
14
+ * Key features:
15
+ * - Reactive proxy for registry data
16
+ * - Deep or shallow reactivity options
17
+ * - Event-based updates
18
+ * - Automatic cleanup on scope disposal
19
+ * - Transforms Map-based registry into reactive refs
20
+ *
21
+ * Perfect for exposing registry data as reactive computed properties.
22
+ */
23
+ /**
24
+ * Creates a proxy registry that provides reactive objects for registry data.
25
+ *
26
+ * @param registry The registry instance to proxy.
27
+ * @param options The options for the proxy registry.
28
+ * @template Z The type of the registry ticket.
29
+ * @returns A proxy registry with reactive objects.
30
+ *
31
+ * @see https://0.vuetifyjs.com/composables/registration/use-proxy-registry
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * import { createRegistry, useProxyRegistry } from '@vuetify/v0'
36
+ *
37
+ * const registry = createRegistry({ events: true })
38
+ * const proxy = useProxyRegistry(registry)
39
+ *
40
+ * registry.register({ value: 'Item 1' })
41
+ * console.log(proxy.size) // 1
42
+ * ```
43
+ */
44
+ function useProxyRegistry(registry, options) {
45
+ const state = (options?.deep ? reactive : shallowReactive)({
46
+ keys: registry.keys(),
47
+ values: registry.values(),
48
+ entries: registry.entries(),
49
+ size: registry.size
50
+ });
51
+ function update() {
52
+ state.keys = registry.keys();
53
+ state.values = registry.values();
54
+ state.entries = registry.entries();
55
+ state.size = registry.size;
56
+ }
57
+ registry.on("register:ticket", update);
58
+ registry.on("unregister:ticket", update);
59
+ registry.on("update:ticket", update);
60
+ registry.on("clear:registry", update);
61
+ onScopeDispose(() => {
62
+ registry.off("register:ticket", update);
63
+ registry.off("unregister:ticket", update);
64
+ registry.off("update:ticket", update);
65
+ registry.off("clear:registry", update);
66
+ }, true);
67
+ return state;
68
+ }
69
+
70
+ //#endregion
71
+ //#region src/composables/createGroup/index.ts
72
+ /**
73
+ * @module useGroup
74
+ *
75
+ * @remarks
76
+ * Multi-selection composable that extends useSelection with batch operations and tri-state support.
77
+ *
78
+ * Key features:
79
+ * - Batch operations (select/unselect/toggle accept ID | ID[])
80
+ * - Tri-state support via mixed/indeterminate state (mix/unmix)
81
+ * - selectedIndexes computed Set for position-based tracking
82
+ * - Perfect for checkbox trees, multi-select dropdowns, filter panels
83
+ *
84
+ * Tri-state behavior:
85
+ * - Items can be selected, mixed (indeterminate), or unselected
86
+ * - select() clears mixed state, mix() clears selected state (mutually exclusive)
87
+ * - toggle() on a mixed item selects it (resolves positively)
88
+ *
89
+ * Inheritance chain: useRegistry → useSelection → useGroup
90
+ * Extended by: useFeatures
91
+ */
92
+ /**
93
+ * Creates a new group instance with batch selection and tri-state support.
94
+ *
95
+ * Extends `createSelection` to support selecting, unselecting, and toggling multiple items
96
+ * at once by passing an array of IDs. Adds tri-state (mixed/indeterminate) support for
97
+ * checkbox trees and similar use cases.
98
+ *
99
+ * @param options The options for the group instance.
100
+ * @template Z The type of the group ticket.
101
+ * @template E The type of the group context.
102
+ * @returns A new group instance with batch selection and tri-state support.
103
+ *
104
+ * @remarks
105
+ * **Key Differences from `createSelection`:**
106
+ * - `select()` accepts `ID | ID[]` for batch operations
107
+ * - `unselect()` accepts `ID | ID[]` for batch operations
108
+ * - `toggle()` accepts `ID | ID[]` for batch operations
109
+ * - Adds `selectedIndexes` computed Set for getting selected item indexes
110
+ * - Adds tri-state support via `mix()`, `unmix()`, `mixed()`, `mixedIds`, `mixedItems`
111
+ * - Perfect for checkbox trees, multi-select dropdowns, and bulk operations
112
+ *
113
+ * **Tri-State Support:**
114
+ * - Items can be in one of three states: selected, mixed (indeterminate), or unselected
115
+ * - `mix(id)` sets item to mixed state (clears selected if set)
116
+ * - `unmix(id)` clears mixed state
117
+ * - `select(id)` clears mixed state before selecting
118
+ * - `toggle(id)` on a mixed item selects it (resolves the indeterminate state positively)
119
+ * - Mixed state works on disabled items (it's a computed state, not user action)
120
+ *
121
+ * **Batch Operations:**
122
+ * - Single ID: `group.select('item-1')`
123
+ * - Array of IDs: `group.select(['item-1', 'item-2', 'item-3'])`
124
+ * - Uses `toArray()` utility internally to normalize input
125
+ * - Disabled items are automatically skipped in select operations
126
+ * - Non-existent IDs are silently ignored
127
+ *
128
+ * **Inheritance Chain:**
129
+ * `useRegistry` → `createSelection` → `createGroup`
130
+ *
131
+ * **Used By:**
132
+ * - `createFeatures` for feature flag management with multiple selections
133
+ *
134
+ * @see https://0.vuetifyjs.com/composables/selection/use-group
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * import { createGroup } from '@vuetify/v0'
139
+ *
140
+ * const checkboxes = createGroup()
141
+ *
142
+ * checkboxes.onboard([
143
+ * { id: 'option-a', value: 'Option A' },
144
+ * { id: 'option-b', value: 'Option B' },
145
+ * { id: 'option-c', value: 'Option C' },
146
+ * ])
147
+ *
148
+ * // Select multiple items at once
149
+ * checkboxes.select(['option-a', 'option-c'])
150
+ *
151
+ * console.log(checkboxes.selectedIds) // Set { 'option-a', 'option-c' }
152
+ * console.log(Array.from(checkboxes.selectedIndexes.value)) // [0, 2]
153
+ *
154
+ * // Set item to mixed/indeterminate state
155
+ * checkboxes.mix('option-a')
156
+ * console.log(checkboxes.mixedIds) // Set { 'option-a' }
157
+ * console.log(checkboxes.selectedIds) // Set { 'option-c' } (option-a removed)
158
+ *
159
+ * // Toggle a mixed item selects it
160
+ * checkboxes.toggle('option-a')
161
+ * console.log(checkboxes.selectedIds) // Set { 'option-a', 'option-c' }
162
+ * console.log(checkboxes.mixedIds) // Set {} (cleared)
163
+ * ```
164
+ */
165
+ function createGroup(_options = {}) {
166
+ const { mandatory = false, multiple = true, ...options } = _options;
167
+ const selection = createSelection({
168
+ ...options,
169
+ mandatory,
170
+ multiple,
171
+ events: true
172
+ });
173
+ const proxy = useProxyRegistry(selection);
174
+ const mixedIds = shallowReactive(/* @__PURE__ */ new Set());
175
+ const selectedIndexes = computed(() => {
176
+ return new Set(Array.from(selection.selectedItems.value).map((item) => item?.index).filter((index) => !/* @__PURE__ */ isUndefined(index)));
177
+ });
178
+ const mixedItems = computed(() => {
179
+ return new Set(Array.from(mixedIds).map((id) => selection.get(id)).filter((item) => !/* @__PURE__ */ isUndefined(item)));
180
+ });
181
+ function mixed(id) {
182
+ return mixedIds.has(id);
183
+ }
184
+ function mix(ids) {
185
+ for (const id of toArray(ids)) {
186
+ if (!selection.has(id)) continue;
187
+ selection.selectedIds.delete(id);
188
+ mixedIds.add(id);
189
+ }
190
+ }
191
+ function unmix(ids) {
192
+ for (const id of toArray(ids)) mixedIds.delete(id);
193
+ }
194
+ function select(ids) {
195
+ for (const id of toArray(ids)) {
196
+ mixedIds.delete(id);
197
+ selection.select(id);
198
+ }
199
+ }
200
+ function unselect(ids) {
201
+ for (const id of toArray(ids)) selection.unselect(id);
202
+ }
203
+ function toggle(ids) {
204
+ for (const id of toArray(ids)) if (mixed(id)) select(id);
205
+ else selection.toggle(id);
206
+ }
207
+ function register(registration = {}) {
208
+ const id = registration.id ?? /* @__PURE__ */ useId$1();
209
+ const item = {
210
+ ...registration,
211
+ id,
212
+ isMixed: toRef(() => mixed(id)),
213
+ select: () => select(id),
214
+ unselect: () => unselect(id),
215
+ toggle: () => toggle(id),
216
+ mix: () => mix(id),
217
+ unmix: () => unmix(id)
218
+ };
219
+ const ticket = selection.register(item);
220
+ if (toValue(registration.indeterminate)) mix(id);
221
+ return ticket;
222
+ }
223
+ function unregister(id) {
224
+ mixedIds.delete(id);
225
+ selection.unregister(id);
226
+ }
227
+ function offboard(ids) {
228
+ for (const id of ids) mixedIds.delete(id);
229
+ selection.offboard(ids);
230
+ }
231
+ function onboard(registrations) {
232
+ const tickets = selection.batch(() => registrations.map((registration) => register(registration)));
233
+ if (toValue(mandatory) === "force") selection.mandate();
234
+ return tickets;
235
+ }
236
+ function reset() {
237
+ mixedIds.clear();
238
+ selection.reset();
239
+ }
240
+ const selectableItems = computed(() => {
241
+ return proxy.values.filter((item) => !toValue(item.disabled));
242
+ });
243
+ const isAllSelected = computed(() => {
244
+ const items = selectableItems.value;
245
+ if (items.length === 0) return false;
246
+ return items.every((item) => selection.selectedIds.has(item.id));
247
+ });
248
+ const isNoneSelected = computed(() => selection.selectedIds.size === 0);
249
+ const isMixed = computed(() => {
250
+ return mixedIds.size > 0 || !isNoneSelected.value && !isAllSelected.value;
251
+ });
252
+ function selectAll() {
253
+ for (const item of selectableItems.value) {
254
+ mixedIds.delete(item.id);
255
+ selection.select(item.id);
256
+ }
257
+ }
258
+ function unselectAll() {
259
+ const first = selection.selectedIds.values().next().value;
260
+ selection.selectedIds.clear();
261
+ if (!toValue(mandatory) || !first) return;
262
+ selection.select(first);
263
+ }
264
+ function toggleAll() {
265
+ if (isAllSelected.value) unselectAll();
266
+ else selectAll();
267
+ }
268
+ return {
269
+ ...selection,
270
+ mixed,
271
+ mix,
272
+ unmix,
273
+ select,
274
+ unselect,
275
+ toggle,
276
+ register,
277
+ unregister,
278
+ offboard,
279
+ onboard,
280
+ reset,
281
+ selectAll,
282
+ unselectAll,
283
+ toggleAll,
284
+ mixedIds,
285
+ mixedItems,
286
+ selectedIndexes,
287
+ isNoneSelected,
288
+ isAllSelected,
289
+ isMixed,
290
+ get size() {
291
+ return selection.size;
292
+ }
293
+ };
294
+ }
295
+ /**
296
+ * Creates a new group context.
297
+ *
298
+ * @param options The options for the group context.
299
+ * @template Z The input ticket type.
300
+ * @template E The output ticket type.
301
+ * @template R The context type.
302
+ * @returns A new group context.
303
+ *
304
+ * @see https://0.vuetifyjs.com/composables/selection/use-group
305
+ *
306
+ * @example
307
+ * ```ts
308
+ * import { createGroupContext } from '@vuetify/v0'
309
+ *
310
+ * // With default namespace 'v0:group'
311
+ * export const [useMyGroup, provideMyGroup, myGroup] = createGroupContext()
312
+ *
313
+ * // Or with custom namespace
314
+ * export const [useMyGroup, provideMyGroup, myGroup] = createGroupContext({ namespace: 'my-group' })
315
+ *
316
+ * // In a parent component:
317
+ * provideMyGroup()
318
+ *
319
+ * // In a child component:
320
+ * const group = useMyGroup()
321
+ * ```
322
+ */
323
+ function createGroupContext(_options = {}) {
324
+ const { namespace = "v0:group", ...options } = _options;
325
+ const [useGroupContext, _provideGroupContext] = createContext(namespace);
326
+ const context = createGroup(options);
327
+ function provideGroupContext(_context = context, app) {
328
+ return _provideGroupContext(_context, app);
329
+ }
330
+ return createTrinity(useGroupContext, provideGroupContext, context);
331
+ }
332
+ /**
333
+ * Returns the current group instance.
334
+ *
335
+ * @param namespace The namespace for the group context. Defaults to `'v0:group'`.
336
+ * @template Z The input ticket type.
337
+ * @template E The output ticket type.
338
+ * @template R The context type.
339
+ * @returns The current group instance.
340
+ *
341
+ * @see https://0.vuetifyjs.com/composables/selection/use-group
342
+ *
343
+ * @example
344
+ * ```vue
345
+ * <script setup lang="ts">
346
+ * import { useGroup } from '@vuetify/v0'
347
+ *
348
+ * const group = useGroup()
349
+ * <\/script>
350
+ *
351
+ * <template>
352
+ * <div>
353
+ * <p>Selected: {{ group.selectedIds.size }}</p>
354
+ * </div>
355
+ * </template>
356
+ * ```
357
+ */
358
+ function useGroup(namespace = "v0:group") {
359
+ return useContext(namespace);
360
+ }
361
+
362
+ //#endregion
363
+ export { useProxyRegistry as i, createGroupContext as n, useGroup as r, createGroup as t };
@@ -0,0 +1,234 @@
1
+ import { _ as range, s as isNaN } from "./utilities-Dx8wzGa5.mjs";
2
+ import { i as useContext, n as createContext, t as createTrinity } from "./createTrinity-DkwPrPRS.mjs";
3
+ import { computed, isRef, shallowRef, toValue } from "vue";
4
+
5
+ //#region src/composables/createPagination/index.ts
6
+ /**
7
+ * @module usePagination
8
+ *
9
+ * @remarks
10
+ * Lightweight pagination composable for navigating through pages.
11
+ *
12
+ * Key features:
13
+ * - No registry overhead - just a bounded integer
14
+ * - Direct ref support for v-model compatibility
15
+ * - Navigation methods: next, prev, first, last
16
+ * - Computed visible items with ellipsis
17
+ * - Trinity pattern for dependency injection
18
+ *
19
+ * Unlike registry-based composables, pagination tracks a single number
20
+ * within a range, making it efficient for large page counts.
21
+ */
22
+ /**
23
+ * Creates a pagination instance.
24
+ *
25
+ * @param options The options for the pagination instance.
26
+ * @returns A pagination context with navigation methods.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { createPagination } from '@vuetify/v0'
31
+ *
32
+ * // Basic usage
33
+ * const pagination = createPagination({ size: 100 })
34
+ * pagination.next()
35
+ * pagination.items.value // [{ type: 'page', value: 1 }, { type: 'page', value: 2 }, ...]
36
+ *
37
+ * // With v-model (pass a ref)
38
+ * const page = ref(1)
39
+ * const pagination = createPagination({ page, size: 100 })
40
+ * // Mutating pagination.page or the passed ref syncs both
41
+ * ```
42
+ */
43
+ function createPagination(_options = {}) {
44
+ const { page: _page = 1, itemsPerPage: _itemsPerPage = 10, size: _size = 0, visible: _visible = 7, ellipsis = "..." } = _options;
45
+ const page = isRef(_page) ? _page : shallowRef(_page);
46
+ const pages = computed(() => {
47
+ const size = toValue(_size);
48
+ const perPage = toValue(_itemsPerPage);
49
+ if (size <= 0 || /* @__PURE__ */ isNaN(size)) return 0;
50
+ return Math.ceil(size / perPage);
51
+ });
52
+ function first() {
53
+ page.value = 1;
54
+ }
55
+ function last() {
56
+ page.value = Math.max(1, pages.value);
57
+ }
58
+ function next() {
59
+ if (page.value < pages.value) page.value++;
60
+ }
61
+ function prev() {
62
+ if (page.value > 1) page.value--;
63
+ }
64
+ function select(value) {
65
+ if (value < 1) page.value = 1;
66
+ else if (value > pages.value) page.value = Math.max(1, pages.value);
67
+ else page.value = value;
68
+ }
69
+ const isFirst = computed(() => page.value <= 1);
70
+ const isLast = computed(() => page.value >= pages.value);
71
+ const pageStart = computed(() => (page.value - 1) * toValue(_itemsPerPage));
72
+ const pageStop = computed(() => Math.min(pageStart.value + toValue(_itemsPerPage), toValue(_size)));
73
+ function toPage(value) {
74
+ return {
75
+ type: "page",
76
+ value
77
+ };
78
+ }
79
+ function toEllipsis() {
80
+ return ellipsis === false ? false : {
81
+ type: "ellipsis",
82
+ value: ellipsis
83
+ };
84
+ }
85
+ function filter(array) {
86
+ return array.filter((item) => item !== false);
87
+ }
88
+ return {
89
+ page,
90
+ ellipsis,
91
+ items: computed(() => {
92
+ const pageCount = pages.value;
93
+ const visible = toValue(_visible);
94
+ const current = page.value;
95
+ if (pageCount <= 0 || /* @__PURE__ */ isNaN(pageCount) || pageCount > Number.MAX_SAFE_INTEGER) return [];
96
+ if (visible <= 0) return [];
97
+ if (visible <= 2) return [toPage(current)];
98
+ if (pageCount <= visible) return (/* @__PURE__ */ range(pageCount, 1)).map(toPage);
99
+ if (visible === 3) {
100
+ const mid = current <= 1 ? 2 : current >= pageCount ? pageCount - 1 : current;
101
+ return [
102
+ toPage(1),
103
+ toPage(mid),
104
+ toPage(pageCount)
105
+ ];
106
+ }
107
+ const boundary = visible - 2;
108
+ const middle = visible - 4;
109
+ if (middle <= 0) {
110
+ if (current <= boundary) return filter([
111
+ ...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
112
+ toEllipsis(),
113
+ toPage(pageCount)
114
+ ]);
115
+ if (current > pageCount - boundary) return filter([
116
+ toPage(1),
117
+ toEllipsis(),
118
+ ...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
119
+ ]);
120
+ return current <= Math.ceil(pageCount / 2) ? filter([
121
+ toPage(1),
122
+ toPage(current),
123
+ toEllipsis(),
124
+ toPage(pageCount)
125
+ ]) : filter([
126
+ toPage(1),
127
+ toEllipsis(),
128
+ toPage(current),
129
+ toPage(pageCount)
130
+ ]);
131
+ }
132
+ const leftThreshold = boundary - 1;
133
+ const rightThreshold = pageCount - boundary + 2;
134
+ if (current <= leftThreshold) return filter([
135
+ ...(/* @__PURE__ */ range(boundary, 1)).map(toPage),
136
+ toEllipsis(),
137
+ toPage(pageCount)
138
+ ]);
139
+ else if (current >= rightThreshold) return filter([
140
+ toPage(1),
141
+ toEllipsis(),
142
+ ...(/* @__PURE__ */ range(boundary, pageCount - boundary + 1)).map(toPage)
143
+ ]);
144
+ else {
145
+ const start = current - Math.floor(middle / 2);
146
+ return filter([
147
+ toPage(1),
148
+ toEllipsis(),
149
+ ...(/* @__PURE__ */ range(middle, start)).map(toPage),
150
+ toEllipsis(),
151
+ toPage(pageCount)
152
+ ]);
153
+ }
154
+ }),
155
+ pageStart,
156
+ pageStop,
157
+ isFirst,
158
+ isLast,
159
+ first,
160
+ last,
161
+ next,
162
+ prev,
163
+ select,
164
+ get itemsPerPage() {
165
+ return toValue(_itemsPerPage);
166
+ },
167
+ get size() {
168
+ return toValue(_size);
169
+ },
170
+ get pages() {
171
+ return pages.value;
172
+ }
173
+ };
174
+ }
175
+ /**
176
+ * Creates a pagination context for dependency injection.
177
+ *
178
+ * @param options The options including namespace.
179
+ * @returns A trinity: [usePagination, providePagination, defaultContext]
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * // With default namespace 'v0:pagination'
184
+ * const [usePagination, providePaginationContext] = createPaginationContext({ size: 50 })
185
+ *
186
+ * // Or with custom namespace
187
+ * const [usePagination, providePaginationContext] = createPaginationContext({
188
+ * namespace: 'my-pagination',
189
+ * size: 50,
190
+ * })
191
+ *
192
+ * // Parent component
193
+ * providePaginationContext()
194
+ *
195
+ * // Child component
196
+ * const pagination = usePagination()
197
+ * pagination.next()
198
+ * ```
199
+ */
200
+ function createPaginationContext(_options = {}) {
201
+ const { namespace = "v0:pagination", ...options } = _options;
202
+ const [usePaginationContext, _providePaginationContext] = createContext(namespace);
203
+ const context = createPagination(options);
204
+ function providePaginationContext(_context = context, app) {
205
+ return _providePaginationContext(_context, app);
206
+ }
207
+ return createTrinity(usePaginationContext, providePaginationContext, context);
208
+ }
209
+ /**
210
+ * Returns the current pagination instance from context.
211
+ *
212
+ * @param namespace The namespace. @default 'v0:pagination'
213
+ * @returns The pagination context.
214
+ *
215
+ * @example
216
+ * ```vue
217
+ * <script setup lang="ts">
218
+ * import { usePagination } from '@vuetify/v0'
219
+ *
220
+ * const pagination = usePagination()
221
+ * <\/script>
222
+ *
223
+ * <template>
224
+ * <button @click="pagination.prev()" :disabled="pagination.isFirst.value">Prev</button>
225
+ * <button @click="pagination.next()" :disabled="pagination.isLast.value">Next</button>
226
+ * </template>
227
+ * ```
228
+ */
229
+ function usePagination(namespace = "v0:pagination") {
230
+ return useContext(namespace);
231
+ }
232
+
233
+ //#endregion
234
+ export { createPaginationContext as n, usePagination as r, createPagination as t };