vectis-ui 0.16.0 → 0.17.0

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 (77) hide show
  1. package/dist/components/VColorPicker/color.js +2 -2
  2. package/dist/components/VColorPicker/color.js.map +1 -1
  3. package/dist/components/VCombobox/VCombobox.d.ts +10 -0
  4. package/dist/components/VCombobox/VCombobox.js.map +1 -1
  5. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +177 -159
  6. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/VDataTable/VDataTable.css +1 -1
  8. package/dist/components/VDataTable/VDataTable.js.map +1 -1
  9. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +1 -1
  10. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/VDatePicker/VDatePicker.css +1 -1
  12. package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
  13. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +3 -2
  14. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/VDialog/VDialog.css +1 -1
  16. package/dist/components/VDialog/VDialog.js.map +1 -1
  17. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +4 -2
  18. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/VDrawer/VDrawer.css +1 -1
  20. package/dist/components/VDrawer/VDrawer.js.map +1 -1
  21. package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js +4 -2
  22. package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  23. package/dist/components/VMeter/VMeter.css +1 -1
  24. package/dist/components/VMeter/VMeter.d.ts +24 -8
  25. package/dist/components/VMeter/VMeter.js.map +1 -1
  26. package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js +65 -48
  27. package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  28. package/dist/components/VMeterGroup/VMeterGroup.css +2 -0
  29. package/dist/components/VMeterGroup/VMeterGroup.d.ts +101 -0
  30. package/dist/components/VMeterGroup/VMeterGroup.js +9 -0
  31. package/dist/components/VMeterGroup/VMeterGroup.js.map +1 -0
  32. package/dist/components/VMeterGroup/VMeterGroup.vue_vue_type_script_setup_true_lang.js +117 -0
  33. package/dist/components/VMeterGroup/VMeterGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  34. package/dist/components/VNumberInput/number.js +2 -2
  35. package/dist/components/VNumberInput/number.js.map +1 -1
  36. package/dist/components/VProgressCircular/VProgressCircular.d.ts +1 -1
  37. package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
  38. package/dist/components/VProgressLinear/VProgressLinear.d.ts +12 -13
  39. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
  40. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +65 -48
  41. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  42. package/dist/components/VSeparator/VSeparator.css +1 -1
  43. package/dist/components/VSeparator/VSeparator.d.ts +42 -2
  44. package/dist/components/VSeparator/VSeparator.js.map +1 -1
  45. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js +50 -9
  46. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  47. package/dist/components/VSideNavigation/VSideNavigation.d.ts +6 -0
  48. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
  49. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +11 -2
  50. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/VSideNavigation/VSideNavigationItem.css +1 -1
  52. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
  53. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  54. package/dist/components/VSnackbar/state.js +2 -3
  55. package/dist/components/VSnackbar/state.js.map +1 -1
  56. package/dist/components/VToast/state.js +2 -3
  57. package/dist/components/VToast/state.js.map +1 -1
  58. package/dist/composables/useAriaLabel.d.ts +5 -0
  59. package/dist/composables/useAriaLabel.js +5 -1
  60. package/dist/composables/useAriaLabel.js.map +1 -1
  61. package/dist/composables/useListbox.d.ts +2 -0
  62. package/dist/composables/useListbox.js +71 -68
  63. package/dist/composables/useListbox.js.map +1 -1
  64. package/dist/i18n/en.js +3 -1
  65. package/dist/i18n/en.js.map +1 -1
  66. package/dist/i18n/fr.js +3 -1
  67. package/dist/i18n/fr.js.map +1 -1
  68. package/dist/i18n/types.d.ts +6 -0
  69. package/dist/index.d.ts +5 -3
  70. package/dist/index.js +21 -20
  71. package/dist/styles.css +1 -1
  72. package/dist/tokens/index.d.ts +10 -5
  73. package/dist/tokens/semantic.d.ts +10 -5
  74. package/dist/tokens/semantic.js +10 -5
  75. package/dist/tokens/semantic.js.map +1 -1
  76. package/dist/tokens.json +39 -14
  77. package/package.json +3 -3
@@ -127,5 +127,7 @@ export interface Listbox {
127
127
  /** Measures a rendered row, in the virtual mode. */
128
128
  measureRow: VirtualList['measure'];
129
129
  }
130
+ /** Every option of a list, the blocks unwrapped and the separators dropped, in the order given. */
131
+ export declare function optionsOf(items: ListboxItem[]): ListboxOption[];
130
132
  export declare function useListbox(options: ListboxOptions): Listbox;
131
133
  export {};
@@ -11,59 +11,62 @@ var u = {
11
11
  md: 40,
12
12
  lg: 48
13
13
  };
14
- function d(l) {
15
- let d = n(() => l.items().flatMap((e) => c(e) ? [] : s(e) ? e.options : [e])), f = n(() => l.filter?.(d.value) ?? d.value), p = n(() => new Set(l.selected())), m = r(/* @__PURE__ */ new Map());
14
+ function d(e) {
15
+ return e.flatMap((e) => c(e) ? [] : s(e) ? e.options : [e]);
16
+ }
17
+ function f(l) {
18
+ let f = n(() => d(l.items())), p = n(() => l.filter?.(f.value) ?? f.value), m = n(() => new Set(l.selected())), h = r(/* @__PURE__ */ new Map());
16
19
  o(() => {
17
- let e = p.value;
18
- for (let t of d.value) e.has(t.value) && m.set(t.value, t);
19
- for (let t of m.keys()) e.has(t) || m.delete(t);
20
+ let e = m.value;
21
+ for (let t of f.value) e.has(t.value) && h.set(t.value, t);
22
+ for (let t of h.keys()) e.has(t) || h.delete(t);
20
23
  });
21
- let h = n(() => {
24
+ let g = n(() => {
22
25
  let e = /* @__PURE__ */ new Map();
23
- for (let t of d.value) e.has(t.value) || e.set(t.value, t);
26
+ for (let t of f.value) e.has(t.value) || e.set(t.value, t);
24
27
  return e;
25
28
  });
26
- function g(e) {
27
- return h.value.get(e) ?? m.get(e);
28
- }
29
- let _ = (e) => g(e)?.label ?? String(e), v = (e) => void m.set(e.value, e), y = i(-1), b = n(() => new Map(d.value.map((e, t) => [e, t]))), x = (e) => {
30
- let t = f.value[e];
31
- return `${l.id}-option-${t ? b.value.get(t) : e}`;
32
- }, S = () => f.value.findIndex((e) => !e.disabled);
33
- function C() {
34
- y.value = S();
29
+ function _(e) {
30
+ return g.value.get(e) ?? h.get(e);
35
31
  }
32
+ let v = (e) => _(e)?.label ?? String(e), y = (e) => void h.set(e.value, e), b = i(-1), x = n(() => new Map(f.value.map((e, t) => [e, t]))), S = (e) => {
33
+ let t = p.value[e];
34
+ return `${l.id}-option-${t ? x.value.get(t) : e}`;
35
+ }, C = () => p.value.findIndex((e) => !e.disabled);
36
36
  function w() {
37
- let e = f.value, t = e.length - 1;
38
- for (; t >= 0 && e[t]?.disabled;) t--;
39
- y.value = t;
37
+ b.value = C();
40
38
  }
41
39
  function T() {
42
- let e = f.value.findIndex((e) => !e.disabled && p.value.has(e.value));
43
- y.value = e >= 0 ? e : S();
40
+ let e = p.value, t = e.length - 1;
41
+ for (; t >= 0 && e[t]?.disabled;) t--;
42
+ b.value = t;
43
+ }
44
+ function E() {
45
+ let e = p.value.findIndex((e) => !e.disabled && m.value.has(e.value));
46
+ b.value = e >= 0 ? e : C();
44
47
  }
45
- function E(e) {
46
- let t = f.value;
48
+ function D(e) {
49
+ let t = p.value;
47
50
  if (t.length === 0) return;
48
- let n = y.value < 0 && e < 0 ? 0 : y.value;
51
+ let n = b.value < 0 && e < 0 ? 0 : b.value;
49
52
  for (let r = 0; r < t.length && (n = (n + e + t.length) % t.length, t[n]?.disabled); r++);
50
- y.value = n;
53
+ b.value = n;
51
54
  }
52
- function D(t) {
53
- let n = f.value, r = e(y.value + t, 0, n.length - 1), i = Math.sign(t);
55
+ function O(t) {
56
+ let n = p.value, r = e(b.value + t, 0, n.length - 1), i = Math.sign(t);
54
57
  for (let e of [i, -i]) for (let t = r; t >= 0 && t < n.length; t += e) if (!n[t]?.disabled) {
55
- y.value = t;
58
+ b.value = t;
56
59
  return;
57
60
  }
58
61
  }
59
- function O(e) {
60
- e.option.disabled || (y.value = e.index);
62
+ function k(e) {
63
+ e.option.disabled || (b.value = e.index);
61
64
  }
62
- a(f, (e) => {
63
- l.open() && (y.value < 0 || y.value >= e.length) && C();
65
+ a(p, (e) => {
66
+ l.open() && (b.value < 0 || b.value >= e.length) && w();
64
67
  });
65
- let k = n(() => {
66
- let e = new Set(f.value), t = 0, n = (n, r) => e.has(n) ? {
68
+ let A = n(() => {
69
+ let e = new Set(p.value), t = 0, n = (n, r) => e.has(n) ? {
67
70
  kind: "option",
68
71
  key: `option:${r}`,
69
72
  option: n,
@@ -91,9 +94,9 @@ function d(l) {
91
94
  }), i = null), r.push(a));
92
95
  }
93
96
  return r;
94
- }), A = n(() => {
95
- let e = [], t = /* @__PURE__ */ new Map(), n = [], r = k.value.filter((e) => e.kind === "option").length, i = 0;
96
- for (let a of k.value) if (a.kind === "separator") e.push(a);
97
+ }), j = n(() => {
98
+ let e = [], t = /* @__PURE__ */ new Map(), n = [], r = A.value.filter((e) => e.kind === "option").length, i = 0;
99
+ for (let a of A.value) if (a.kind === "separator") e.push(a);
97
100
  else if (a.kind === "option") n[a.index] = e.length, e.push({
98
101
  ...a,
99
102
  set: r,
@@ -119,20 +122,20 @@ function d(l) {
119
122
  labels: t,
120
123
  rowOfOption: n
121
124
  };
122
- }), j = t({
125
+ }), M = t({
123
126
  scrollEl: n(() => l.virtual() ? l.panelEl() : null),
124
- count: () => A.value.rows.length,
125
- key: (e) => A.value.rows[e]?.key,
127
+ count: () => j.value.rows.length,
128
+ key: (e) => j.value.rows[e]?.key,
126
129
  itemSize: () => u[l.size()],
127
130
  overscan: () => 5,
128
131
  initialCount: () => 10,
129
132
  pinned: () => {
130
- let e = A.value.rowOfOption[y.value];
133
+ let e = j.value.rowOfOption[b.value];
131
134
  return e === void 0 ? [] : [e];
132
135
  }
133
136
  });
134
- function M(e, t) {
135
- let n = e.index === y.value, r = p.value.has(e.option.value), i = l.virtual() ? {
137
+ function N(e, t) {
138
+ let n = e.index === b.value, r = m.value.has(e.option.value), i = l.virtual() ? {
136
139
  "aria-setsize": l.hasMore?.() ? -1 : e.set,
137
140
  "aria-posinset": e.position
138
141
  } : {};
@@ -140,7 +143,7 @@ function d(l) {
140
143
  ...e,
141
144
  at: t,
142
145
  row: {
143
- id: x(e.index),
146
+ id: S(e.index),
144
147
  icon: e.option.icon,
145
148
  active: n,
146
149
  selected: r,
@@ -155,8 +158,8 @@ function d(l) {
155
158
  }
156
159
  };
157
160
  }
158
- let N = n(() => {
159
- let { rows: e, labels: t } = A.value, n = l.virtual() ? j.segments.value : e.map((e, t) => ({
161
+ let P = n(() => {
162
+ let { rows: e, labels: t } = j.value, n = l.virtual() ? M.segments.value : e.map((e, t) => ({
160
163
  type: "row",
161
164
  index: t
162
165
  })), r = (t) => {
@@ -175,7 +178,7 @@ function d(l) {
175
178
  l = e === r(n[o + 1]) ? e : void 0;
176
179
  } else {
177
180
  let t = e[s.index];
178
- c = t.kind === "option" ? M(t, s.index) : {
181
+ c = t.kind === "option" ? N(t, s.index) : {
179
182
  ...t,
180
183
  at: s.index
181
184
  }, l = r(s);
@@ -189,33 +192,33 @@ function d(l) {
189
192
  }
190
193
  return i;
191
194
  });
192
- return a(y, (e) => {
195
+ return a(b, (e) => {
193
196
  if (!(e < 0)) {
194
197
  if (l.virtual()) {
195
- let t = A.value.rowOfOption[e];
196
- t !== void 0 && j.scrollToIndex(t);
197
- } else document.getElementById(x(e))?.scrollIntoView?.({ block: "nearest" });
198
+ let t = j.value.rowOfOption[e];
199
+ t !== void 0 && M.scrollToIndex(t);
200
+ } else document.getElementById(S(e))?.scrollIntoView?.({ block: "nearest" });
198
201
  }
199
202
  }, { flush: "post" }), {
200
- allOptions: d,
201
- visible: f,
202
- selectedSet: p,
203
- optionOf: g,
204
- labelOf: _,
205
- remember: v,
206
- activeIndex: y,
207
- optionId: x,
208
- highlightFirst: C,
209
- highlightLast: w,
210
- highlightSelected: T,
211
- move: E,
212
- page: D,
213
- hover: O,
214
- blocks: N,
215
- measureRow: j.measure
203
+ allOptions: f,
204
+ visible: p,
205
+ selectedSet: m,
206
+ optionOf: _,
207
+ labelOf: v,
208
+ remember: y,
209
+ activeIndex: b,
210
+ optionId: S,
211
+ highlightFirst: w,
212
+ highlightLast: T,
213
+ highlightSelected: E,
214
+ move: D,
215
+ page: O,
216
+ hover: k,
217
+ blocks: P,
218
+ measureRow: M.measure
216
219
  };
217
220
  }
218
221
  //#endregion
219
- export { l as selectionOf, d as useListbox };
222
+ export { d as optionsOf, l as selectionOf, f as useListbox };
220
223
 
221
224
  //# sourceMappingURL=useListbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useListbox.js","names":["isListboxGroup","item","isListboxSeparator","selectionOf","multiple","value","OPTION_HEIGHT","useListbox","allOptions","computed","options","visible","selectedSet","optionCache","reactive","wanted","option","optionsByValue","map","optionOf","labelOf","remember","activeIndex","ref","sourceIndex","i","optionId","index","firstEnabled","o","highlightFirst","highlightLast","list","highlightSelected","chosen","move","delta","step","page","target","clamp","dir","hover","row","rendered","kept","next","entryOf","key","nodes","pendingSeparator","node","entries","j","entry","flat","rows","labels","rowOfOption","loose","looseSeen","virtualList","useVirtualList","withState","active","selected","placed","blocks","segments","groupAt","segment","out","open","k","block","group","before","watch"],"sources":["../../src/composables/useListbox.ts"],"sourcesContent":["// @keyboard @a11y\n/**\n * Model a listbox whose DOM focus stays on its field, for VCombobox and VSelect: the field names\n * the highlighted option through aria-activedescendant and moves it by hand, and the panel renders\n * `blocks`. Groups and separators exist for the eye alone; the keyboard counts through the flat\n * list of options and therefore never stops on one.\n */\nimport { computed, reactive, ref, watch, watchEffect, type ComputedRef, type Ref } from 'vue'\n\nimport type { IconSource } from '../components/VIcon/types'\nimport type {\n ItemValue,\n ListboxGroup,\n ListboxItem,\n ListboxOption,\n ListboxOptionSlotProps,\n ListboxSeparator,\n} from '../types'\nimport { clamp } from '../utils/number'\nimport { useVirtualList, type VirtualList, type VirtualSegment } from './useVirtualList'\n\nconst isListboxGroup = (item: ListboxItem): item is ListboxGroup => 'options' in item\nconst isListboxSeparator = (item: ListboxItem): item is ListboxSeparator => 'separator' in item\n\n/**\n * The chosen values as a list, whatever the model holds. An empty string is what an emptied\n * single field says, and it is not a value. A NUMBER is a value even at zero; hence the test on\n * the empty string alone rather than on falsiness, which would drop the option keyed `0`.\n */\nexport function selectionOf(value: ItemValue | ItemValue[], multiple: boolean): ItemValue[] {\n if (multiple) return Array.isArray(value) ? value : []\n return !Array.isArray(value) && value !== '' ? [value] : []\n}\n\ntype ListboxSize = 'sm' | 'md' | 'lg'\n\nexport interface ListboxOptions {\n /** What the list offers, as the consumer gave it. */\n items: () => ListboxItem[]\n /**\n * Narrows the flattened options, read inside a computed so it may follow reactive state. Left\n * out, every option stays.\n */\n filter?: (options: ListboxOption[]) => ListboxOption[]\n /** The chosen values. */\n selected: () => ItemValue[]\n /** Whether the panel is showing; the highlight is kept on a valid option only while it is. */\n open: () => boolean\n /** The panel's id, and the prefix of every option's and heading's id. */\n id: string\n /** The scrolling panel, which the virtual mode windows. */\n panelEl: () => HTMLElement | null\n /** Renders only the rows near the visible part of the panel. */\n virtual: () => boolean\n /** More pages are coming, so the last block's size is unknown. */\n hasMore?: () => boolean\n size: () => ListboxSize\n}\n\n/** An option the panel renders, with its index in the visible options. */\nexport interface ListboxRenderedOption {\n kind: 'option'\n key: string\n option: ListboxOption\n index: number\n}\n\ntype RenderedNode =\n | ListboxRenderedOption\n | { kind: 'group'; key: string; id: string; label: string; options: ListboxRenderedOption[] }\n | { kind: 'separator'; key: string }\n\n/**\n * The panel as one flat sequence of rows, the unit the virtual mode windows: a block's name is a\n * row of its own, above its options. Each row knows its block, so the rows rendered can be\n * gathered back into their groups. `set` and `position` are the option's place in its block, or\n * among the options outside any block.\n */\ntype FlatOption = ListboxRenderedOption & { group?: string; set: number; position: number }\ntype FlatRow =\n | FlatOption\n | { kind: 'heading'; key: string; id: string; label: string; group: string }\n | { kind: 'separator'; key: string }\n\n/**\n * A rendered option with its state worked out, once per row: `row` is what the option element\n * takes, `slot` what the `#option` slot receives, and both read the same two answers. `at` is\n * the row's place in the flat sequence, which the virtual mode measures it under.\n */\nexport type ListboxOptionRow = FlatOption & {\n at: number\n row: {\n id: string\n icon?: IconSource\n active: boolean\n selected: boolean\n disabled?: boolean\n 'aria-setsize'?: number\n 'aria-posinset'?: number\n }\n slot: ListboxOptionSlotProps\n}\n\nexport type ListboxRow =\n | ListboxOptionRow\n | { kind: 'heading'; key: string; id: string; label: string; at: number }\n | { kind: 'separator'; key: string; at: number }\n | { kind: 'spacer'; key: string; size: number }\n\n/** What the panel renders: rows, and blocks of rows gathered under their name. */\nexport type ListboxBlock =\n | ListboxRow\n | { kind: 'group'; key: string; label: string; labelId?: string; children: ListboxRow[] }\n\n// Only a starting guess for the virtual mode, every row being measured once rendered: the\n// height of an option at each size in the standard density.\nconst OPTION_HEIGHT: Record<ListboxSize, number> = { sm: 32, md: 40, lg: 48 }\n\nexport interface Listbox {\n /** Every option, the blocks unwrapped and the separators dropped, in the order given. */\n allOptions: ComputedRef<ListboxOption[]>\n /** The options left by the filter: what the keyboard counts through. */\n visible: ComputedRef<ListboxOption[]>\n /** The selection as a set, so that asking \"is this one chosen?\" costs nothing. */\n selectedSet: ComputedRef<Set<ItemValue>>\n /** The option holding a value, found among the options or in the memory of chosen ones. */\n optionOf: (value: ItemValue) => ListboxOption | undefined\n /** The label of a value, or the value itself spelled out when no option holds it. */\n labelOf: (value: ItemValue) => string\n /** Keeps an option just chosen in memory, before the parent passes the value back down. */\n remember: (option: ListboxOption) => void\n /** The index of the highlighted option among `visible`, or -1. */\n activeIndex: Ref<number>\n /** The id of the option at an index of `visible`. */\n optionId: (index: number) => string\n /** Highlights the first option that can be chosen, or nothing. */\n highlightFirst: () => void\n /** Highlights the last option that can be chosen, or nothing. */\n highlightLast: () => void\n /** Highlights the first chosen option, or the first that can be chosen. */\n highlightSelected: () => void\n /** Moves the highlight by `delta` options, wrapping around and skipping disabled ones. */\n move: (delta: number) => void\n /**\n * Moves the highlight by `delta` options without wrapping, the step of Page Up and Page Down:\n * it stops at the first or last option that can be chosen.\n */\n page: (delta: number) => void\n /** Highlights the option under the pointer. */\n hover: (row: ListboxRenderedOption) => void\n /** What the panel renders. */\n blocks: ComputedRef<ListboxBlock[]>\n /** Measures a rendered row, in the virtual mode. */\n measureRow: VirtualList['measure']\n}\n\nexport function useListbox(options: ListboxOptions): Listbox {\n // The ONE reading of the items the rest of the module does: the filtering, the memory of what\n // was chosen, the labels and the paging all ignore the hierarchy entirely.\n const allOptions = computed<ListboxOption[]>(() =>\n options.items().flatMap((item) => {\n if (isListboxSeparator(item)) return []\n return isListboxGroup(item) ? item.options : [item]\n }),\n )\n\n const visible = computed(() => options.filter?.(allOptions.value) ?? allOptions.value)\n\n const selectedSet = computed(() => new Set(options.selected()))\n\n // With a source that answers over the network, the options only ever hold the latest results,\n // and something already chosen is usually absent from them; without this, a chip would show a\n // raw identifier instead of a name. It is kept up to date by an effect rather than by watching\n // the options, because the effect tracks the ITERATION and therefore also notices a page\n // appended in place.\n const optionCache = reactive(new Map<ItemValue, ListboxOption>())\n watchEffect(() => {\n const wanted = selectedSet.value\n for (const option of allOptions.value) {\n if (wanted.has(option.value)) optionCache.set(option.value, option)\n }\n // Without this the memory would grow with every value chosen during the session rather than\n // with the current selection.\n for (const value of optionCache.keys()) if (!wanted.has(value)) optionCache.delete(value)\n })\n\n // A lookup built once per list rather than searched each time: an option is looked up several\n // times per chip and per render, so a linear search would cost chips times options on every\n // keystroke.\n const optionsByValue = computed(() => {\n const map = new Map<ItemValue, ListboxOption>()\n for (const option of allOptions.value) if (!map.has(option.value)) map.set(option.value, option)\n return map\n })\n\n /*\n * An option coming from the memory is a reactive PROXY, since making the map reactive converts\n * the objects inside it. Compare options by their value and never by identity, or the two forms\n * of the same option will not match.\n */\n function optionOf(value: ItemValue) {\n return optionsByValue.value.get(value) ?? optionCache.get(value)\n }\n\n const labelOf = (value: ItemValue) => optionOf(value)?.label ?? String(value)\n\n const remember = (option: ListboxOption) => void optionCache.set(option.value, option)\n\n const activeIndex = ref(-1)\n\n // @a11y\n // An option's id follows the OPTION, from its place among all the options, and never its place\n // in the filtered list: a screen reader announces the current option when\n // `aria-activedescendant` changes, and a positional id would keep the same value while the\n // filter slides another option under the highlight, which then goes unannounced.\n const sourceIndex = computed(() => new Map(allOptions.value.map((option, i) => [option, i])))\n const optionId = (index: number) => {\n const option = visible.value[index]\n return `${options.id}-option-${option ? sourceIndex.value.get(option) : index}`\n }\n\n const firstEnabled = () => visible.value.findIndex((o) => !o.disabled)\n\n function highlightFirst() {\n activeIndex.value = firstEnabled()\n }\n\n function highlightLast() {\n const list = visible.value\n let i = list.length - 1\n while (i >= 0 && list[i]?.disabled) i--\n activeIndex.value = i\n }\n\n function highlightSelected() {\n const chosen = visible.value.findIndex((o) => !o.disabled && selectedSet.value.has(o.value))\n activeIndex.value = chosen >= 0 ? chosen : firstEnabled()\n }\n\n // @keyboard\n function move(delta: number) {\n const list = visible.value\n if (list.length === 0) return\n // From \"nothing highlighted\" the first step lands on an END of the list: starting at -1,\n // a step back would stop on the second-to-last option.\n let i = activeIndex.value < 0 && delta < 0 ? 0 : activeIndex.value\n for (let step = 0; step < list.length; step++) {\n i = (i + delta + list.length) % list.length\n if (!list[i]?.disabled) break\n }\n activeIndex.value = i\n }\n\n // @keyboard\n function page(delta: number) {\n const list = visible.value\n const target = clamp(activeIndex.value + delta, 0, list.length - 1)\n const step = Math.sign(delta)\n // Past a disabled option in the direction of travel, then back if the end was disabled too.\n for (const dir of [step, -step]) {\n for (let i = target; i >= 0 && i < list.length; i += dir) {\n if (!list[i]?.disabled) {\n activeIndex.value = i\n return\n }\n }\n }\n }\n\n function hover(row: ListboxRenderedOption) {\n if (!row.option.disabled) activeIndex.value = row.index\n }\n\n // While the panel is open there must always be a valid option highlighted. It is moved back to\n // the first one whenever the highlighted one has fallen out of the list or there was none at\n // all; without that second case, a search that passed through \"no result\" would leave nothing\n // highlighted, and Enter would not choose the single result that came back.\n watch(visible, (list) => {\n if (!options.open()) return\n if (activeIndex.value < 0 || activeIndex.value >= list.length) highlightFirst()\n })\n\n // Nothing here is keyed by VALUE. Two options may share one (a consumer's duplicate, or `1`\n // beside `'1'`, which a template literal spells the same), and a value-keyed index hands both\n // the same position, so both light up as active and Vue patches two rows under one key.\n const rendered = computed<RenderedNode[]>(() => {\n const kept = new Set(visible.value)\n let next = 0\n\n const entryOf = (option: ListboxOption, key: string): ListboxRenderedOption | null => {\n if (!kept.has(option)) return null\n return { kind: 'option', key: `option:${key}`, option, index: next++ }\n }\n\n const nodes: RenderedNode[] = []\n // A separator is held back and only drawn once something has come before it and something\n // comes after it. That single rule covers all three ways the filtering can strand one: at\n // the top of the list, at the bottom, and two in a row.\n let pendingSeparator: string | null = null\n\n for (const [i, item] of options.items().entries()) {\n if (isListboxSeparator(item)) {\n if (nodes.length > 0) pendingSeparator = `sep:${i}`\n continue\n }\n\n let node: RenderedNode | null\n if (isListboxGroup(item)) {\n const entries = item.options\n .map((option, j) => entryOf(option, `${i}.${j}`))\n .filter((entry): entry is ListboxRenderedOption => entry !== null)\n // A block none of whose options survived is dropped entirely, its name included:\n // a heading over nothing is worse than no heading.\n node =\n entries.length > 0\n ? {\n kind: 'group',\n key: `group:${i}`,\n id: `${options.id}-group-${i}`,\n label: item.label,\n options: entries,\n }\n : null\n } else {\n node = entryOf(item, String(i))\n }\n if (!node) continue\n\n if (pendingSeparator !== null) {\n nodes.push({ kind: 'separator', key: pendingSeparator })\n pendingSeparator = null\n }\n nodes.push(node)\n }\n\n return nodes\n })\n\n const flat = computed(() => {\n const rows: FlatRow[] = []\n const labels = new Map<string, string>()\n // Indexed by the option's place in `visible`: where the keyboard's highlight sits in the rows.\n const rowOfOption: number[] = []\n const loose = rendered.value.filter((node) => node.kind === 'option').length\n let looseSeen = 0\n for (const node of rendered.value) {\n if (node.kind === 'separator') rows.push(node)\n else if (node.kind === 'option') {\n rowOfOption[node.index] = rows.length\n rows.push({ ...node, set: loose, position: ++looseSeen })\n } else {\n labels.set(node.key, node.label)\n rows.push({\n kind: 'heading',\n key: `heading:${node.key}`,\n id: node.id,\n label: node.label,\n group: node.key,\n })\n for (const [j, option] of node.options.entries()) {\n rowOfOption[option.index] = rows.length\n rows.push({ ...option, group: node.key, set: node.options.length, position: j + 1 })\n }\n }\n }\n return { rows, labels, rowOfOption }\n })\n\n // @a11y\n // The highlighted row stays rendered wherever the panel is scrolled: `aria-activedescendant`\n // must name an element that exists.\n const virtualList = useVirtualList({\n scrollEl: computed(() => (options.virtual() ? options.panelEl() : null)),\n count: () => flat.value.rows.length,\n key: (index) => flat.value.rows[index]?.key,\n itemSize: () => OPTION_HEIGHT[options.size()],\n overscan: () => 5,\n initialCount: () => 10,\n pinned: () => {\n const row = flat.value.rowOfOption[activeIndex.value]\n return row === undefined ? [] : [row]\n },\n })\n\n function withState(entry: FlatOption, at: number): ListboxOptionRow {\n const active = entry.index === activeIndex.value\n const selected = selectedSet.value.has(entry.option.value)\n // @a11y\n // Only some options exist in the virtual mode, so each one says where it stands; the last\n // block may still grow while pages are coming.\n const placed = options.virtual()\n ? { 'aria-setsize': options.hasMore?.() ? -1 : entry.set, 'aria-posinset': entry.position }\n : {}\n return {\n ...entry,\n at,\n row: {\n id: optionId(entry.index),\n icon: entry.option.icon,\n active,\n selected,\n disabled: entry.option.disabled,\n ...placed,\n },\n slot: { option: entry.option, index: entry.index, active, selected },\n }\n }\n\n // The rows of the window and the space standing for the others, gathered back into their\n // blocks. Kept apart from `flat` on purpose: the highlight moves on every arrow key, and only\n // this pass over the rendered rows follows it; the filtering and the grouping stay where they\n // are.\n const blocks = computed<ListboxBlock[]>(() => {\n const { rows, labels } = flat.value\n const segments: VirtualSegment[] = options.virtual()\n ? virtualList.segments.value\n : rows.map((_, index) => ({ type: 'row', index }))\n const groupAt = (segment: VirtualSegment | undefined) => {\n const row = segment?.type === 'row' ? rows[segment.index] : undefined\n return row && row.kind !== 'separator' ? row.group : undefined\n }\n\n const out: ListboxBlock[] = []\n let open: Extract<ListboxBlock, { kind: 'group' }> | undefined\n for (const [k, segment] of segments.entries()) {\n let block: ListboxRow\n let group: string | undefined\n if (segment.type === 'spacer') {\n block = { kind: 'spacer', key: segment.key, size: segment.size }\n // Between two rows of one block, the space stands for rows of that block.\n const before = groupAt(segments[k - 1])\n group = before === groupAt(segments[k + 1]) ? before : undefined\n } else {\n const row = rows[segment.index]!\n block =\n row.kind === 'option' ? withState(row, segment.index) : { ...row, at: segment.index }\n group = groupAt(segment)\n }\n if (group === undefined) {\n open = undefined\n out.push(block)\n continue\n }\n if (open?.key !== group) {\n open = { kind: 'group', key: group, label: labels.get(group)!, children: [] }\n out.push(open)\n }\n if (block.kind === 'heading') open.labelId = block.id\n open.children.push(block)\n }\n return out\n })\n\n // @a11y\n // Since the focus never leaves the field, the browser has no reason to scroll the highlighted\n // option into view. It is brought into view by hand instead, and asked for the SMALLEST\n // movement that reveals it, so an option already visible does not make the panel jump.\n watch(\n activeIndex,\n (index) => {\n if (index < 0) return\n if (options.virtual()) {\n const row = flat.value.rowOfOption[index]\n if (row !== undefined) void virtualList.scrollToIndex(row)\n return\n }\n // Called optionally: the unit-test environment implements no scrolling at all.\n document.getElementById(optionId(index))?.scrollIntoView?.({ block: 'nearest' })\n },\n { flush: 'post' },\n )\n\n return {\n allOptions,\n visible,\n selectedSet,\n optionOf,\n labelOf,\n remember,\n activeIndex,\n optionId,\n highlightFirst,\n highlightLast,\n highlightSelected,\n move,\n page,\n hover,\n blocks,\n measureRow: virtualList.measure,\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useListbox.js","names":["isListboxGroup","item","isListboxSeparator","selectionOf","multiple","value","OPTION_HEIGHT","optionsOf","items","useListbox","allOptions","computed","options","visible","selectedSet","optionCache","reactive","wanted","option","optionsByValue","map","optionOf","labelOf","remember","activeIndex","ref","sourceIndex","i","optionId","index","firstEnabled","o","highlightFirst","highlightLast","list","highlightSelected","chosen","move","delta","step","page","target","clamp","dir","hover","row","rendered","kept","next","entryOf","key","nodes","pendingSeparator","node","entries","j","entry","flat","rows","labels","rowOfOption","loose","looseSeen","virtualList","useVirtualList","withState","active","selected","placed","blocks","segments","groupAt","segment","out","open","k","block","group","before","watch"],"sources":["../../src/composables/useListbox.ts"],"sourcesContent":["// @keyboard @a11y\n/**\n * Model a listbox whose DOM focus stays on its field, for VCombobox and VSelect: the field names\n * the highlighted option through aria-activedescendant and moves it by hand, and the panel renders\n * `blocks`. Groups and separators exist for the eye alone; the keyboard counts through the flat\n * list of options and therefore never stops on one.\n */\nimport { computed, reactive, ref, watch, watchEffect, type ComputedRef, type Ref } from 'vue'\n\nimport type { IconSource } from '../components/VIcon/types'\nimport type {\n ItemValue,\n ListboxGroup,\n ListboxItem,\n ListboxOption,\n ListboxOptionSlotProps,\n ListboxSeparator,\n} from '../types'\nimport { clamp } from '../utils/number'\nimport { useVirtualList, type VirtualList, type VirtualSegment } from './useVirtualList'\n\nconst isListboxGroup = (item: ListboxItem): item is ListboxGroup => 'options' in item\nconst isListboxSeparator = (item: ListboxItem): item is ListboxSeparator => 'separator' in item\n\n/**\n * The chosen values as a list, whatever the model holds. An empty string is what an emptied\n * single field says, and it is not a value. A NUMBER is a value even at zero; hence the test on\n * the empty string alone rather than on falsiness, which would drop the option keyed `0`.\n */\nexport function selectionOf(value: ItemValue | ItemValue[], multiple: boolean): ItemValue[] {\n if (multiple) return Array.isArray(value) ? value : []\n return !Array.isArray(value) && value !== '' ? [value] : []\n}\n\ntype ListboxSize = 'sm' | 'md' | 'lg'\n\nexport interface ListboxOptions {\n /** What the list offers, as the consumer gave it. */\n items: () => ListboxItem[]\n /**\n * Narrows the flattened options, read inside a computed so it may follow reactive state. Left\n * out, every option stays.\n */\n filter?: (options: ListboxOption[]) => ListboxOption[]\n /** The chosen values. */\n selected: () => ItemValue[]\n /** Whether the panel is showing; the highlight is kept on a valid option only while it is. */\n open: () => boolean\n /** The panel's id, and the prefix of every option's and heading's id. */\n id: string\n /** The scrolling panel, which the virtual mode windows. */\n panelEl: () => HTMLElement | null\n /** Renders only the rows near the visible part of the panel. */\n virtual: () => boolean\n /** More pages are coming, so the last block's size is unknown. */\n hasMore?: () => boolean\n size: () => ListboxSize\n}\n\n/** An option the panel renders, with its index in the visible options. */\nexport interface ListboxRenderedOption {\n kind: 'option'\n key: string\n option: ListboxOption\n index: number\n}\n\ntype RenderedNode =\n | ListboxRenderedOption\n | { kind: 'group'; key: string; id: string; label: string; options: ListboxRenderedOption[] }\n | { kind: 'separator'; key: string }\n\n/**\n * The panel as one flat sequence of rows, the unit the virtual mode windows: a block's name is a\n * row of its own, above its options. Each row knows its block, so the rows rendered can be\n * gathered back into their groups. `set` and `position` are the option's place in its block, or\n * among the options outside any block.\n */\ntype FlatOption = ListboxRenderedOption & { group?: string; set: number; position: number }\ntype FlatRow =\n | FlatOption\n | { kind: 'heading'; key: string; id: string; label: string; group: string }\n | { kind: 'separator'; key: string }\n\n/**\n * A rendered option with its state worked out, once per row: `row` is what the option element\n * takes, `slot` what the `#option` slot receives, and both read the same two answers. `at` is\n * the row's place in the flat sequence, which the virtual mode measures it under.\n */\nexport type ListboxOptionRow = FlatOption & {\n at: number\n row: {\n id: string\n icon?: IconSource\n active: boolean\n selected: boolean\n disabled?: boolean\n 'aria-setsize'?: number\n 'aria-posinset'?: number\n }\n slot: ListboxOptionSlotProps\n}\n\nexport type ListboxRow =\n | ListboxOptionRow\n | { kind: 'heading'; key: string; id: string; label: string; at: number }\n | { kind: 'separator'; key: string; at: number }\n | { kind: 'spacer'; key: string; size: number }\n\n/** What the panel renders: rows, and blocks of rows gathered under their name. */\nexport type ListboxBlock =\n | ListboxRow\n | { kind: 'group'; key: string; label: string; labelId?: string; children: ListboxRow[] }\n\n// Only a starting guess for the virtual mode, every row being measured once rendered: the\n// height of an option at each size in the standard density.\nconst OPTION_HEIGHT: Record<ListboxSize, number> = { sm: 32, md: 40, lg: 48 }\n\nexport interface Listbox {\n /** Every option, the blocks unwrapped and the separators dropped, in the order given. */\n allOptions: ComputedRef<ListboxOption[]>\n /** The options left by the filter: what the keyboard counts through. */\n visible: ComputedRef<ListboxOption[]>\n /** The selection as a set, so that asking \"is this one chosen?\" costs nothing. */\n selectedSet: ComputedRef<Set<ItemValue>>\n /** The option holding a value, found among the options or in the memory of chosen ones. */\n optionOf: (value: ItemValue) => ListboxOption | undefined\n /** The label of a value, or the value itself spelled out when no option holds it. */\n labelOf: (value: ItemValue) => string\n /** Keeps an option just chosen in memory, before the parent passes the value back down. */\n remember: (option: ListboxOption) => void\n /** The index of the highlighted option among `visible`, or -1. */\n activeIndex: Ref<number>\n /** The id of the option at an index of `visible`. */\n optionId: (index: number) => string\n /** Highlights the first option that can be chosen, or nothing. */\n highlightFirst: () => void\n /** Highlights the last option that can be chosen, or nothing. */\n highlightLast: () => void\n /** Highlights the first chosen option, or the first that can be chosen. */\n highlightSelected: () => void\n /** Moves the highlight by `delta` options, wrapping around and skipping disabled ones. */\n move: (delta: number) => void\n /**\n * Moves the highlight by `delta` options without wrapping, the step of Page Up and Page Down:\n * it stops at the first or last option that can be chosen.\n */\n page: (delta: number) => void\n /** Highlights the option under the pointer. */\n hover: (row: ListboxRenderedOption) => void\n /** What the panel renders. */\n blocks: ComputedRef<ListboxBlock[]>\n /** Measures a rendered row, in the virtual mode. */\n measureRow: VirtualList['measure']\n}\n\n/** Every option of a list, the blocks unwrapped and the separators dropped, in the order given. */\nexport function optionsOf(items: ListboxItem[]): ListboxOption[] {\n return items.flatMap((item) => {\n if (isListboxSeparator(item)) return []\n return isListboxGroup(item) ? item.options : [item]\n })\n}\n\nexport function useListbox(options: ListboxOptions): Listbox {\n // The ONE reading of the items the rest of the module does: the filtering, the memory of what\n // was chosen, the labels and the paging all ignore the hierarchy entirely.\n const allOptions = computed<ListboxOption[]>(() => optionsOf(options.items()))\n\n const visible = computed(() => options.filter?.(allOptions.value) ?? allOptions.value)\n\n const selectedSet = computed(() => new Set(options.selected()))\n\n // With a source that answers over the network, the options only ever hold the latest results,\n // and something already chosen is usually absent from them; without this, a chip would show a\n // raw identifier instead of a name. It is kept up to date by an effect rather than by watching\n // the options, because the effect tracks the ITERATION and therefore also notices a page\n // appended in place.\n const optionCache = reactive(new Map<ItemValue, ListboxOption>())\n watchEffect(() => {\n const wanted = selectedSet.value\n for (const option of allOptions.value) {\n if (wanted.has(option.value)) optionCache.set(option.value, option)\n }\n // Without this the memory would grow with every value chosen during the session rather than\n // with the current selection.\n for (const value of optionCache.keys()) if (!wanted.has(value)) optionCache.delete(value)\n })\n\n // A lookup built once per list rather than searched each time: an option is looked up several\n // times per chip and per render, so a linear search would cost chips times options on every\n // keystroke.\n const optionsByValue = computed(() => {\n const map = new Map<ItemValue, ListboxOption>()\n for (const option of allOptions.value) if (!map.has(option.value)) map.set(option.value, option)\n return map\n })\n\n /*\n * An option coming from the memory is a reactive PROXY, since making the map reactive converts\n * the objects inside it. Compare options by their value and never by identity, or the two forms\n * of the same option will not match.\n */\n function optionOf(value: ItemValue) {\n return optionsByValue.value.get(value) ?? optionCache.get(value)\n }\n\n const labelOf = (value: ItemValue) => optionOf(value)?.label ?? String(value)\n\n const remember = (option: ListboxOption) => void optionCache.set(option.value, option)\n\n const activeIndex = ref(-1)\n\n // @a11y\n // An option's id follows the OPTION, from its place among all the options, and never its place\n // in the filtered list: a screen reader announces the current option when\n // `aria-activedescendant` changes, and a positional id would keep the same value while the\n // filter slides another option under the highlight, which then goes unannounced.\n const sourceIndex = computed(() => new Map(allOptions.value.map((option, i) => [option, i])))\n const optionId = (index: number) => {\n const option = visible.value[index]\n return `${options.id}-option-${option ? sourceIndex.value.get(option) : index}`\n }\n\n const firstEnabled = () => visible.value.findIndex((o) => !o.disabled)\n\n function highlightFirst() {\n activeIndex.value = firstEnabled()\n }\n\n function highlightLast() {\n const list = visible.value\n let i = list.length - 1\n while (i >= 0 && list[i]?.disabled) i--\n activeIndex.value = i\n }\n\n function highlightSelected() {\n const chosen = visible.value.findIndex((o) => !o.disabled && selectedSet.value.has(o.value))\n activeIndex.value = chosen >= 0 ? chosen : firstEnabled()\n }\n\n // @keyboard\n function move(delta: number) {\n const list = visible.value\n if (list.length === 0) return\n // From \"nothing highlighted\" the first step lands on an END of the list: starting at -1,\n // a step back would stop on the second-to-last option.\n let i = activeIndex.value < 0 && delta < 0 ? 0 : activeIndex.value\n for (let step = 0; step < list.length; step++) {\n i = (i + delta + list.length) % list.length\n if (!list[i]?.disabled) break\n }\n activeIndex.value = i\n }\n\n // @keyboard\n function page(delta: number) {\n const list = visible.value\n const target = clamp(activeIndex.value + delta, 0, list.length - 1)\n const step = Math.sign(delta)\n // Past a disabled option in the direction of travel, then back if the end was disabled too.\n for (const dir of [step, -step]) {\n for (let i = target; i >= 0 && i < list.length; i += dir) {\n if (!list[i]?.disabled) {\n activeIndex.value = i\n return\n }\n }\n }\n }\n\n function hover(row: ListboxRenderedOption) {\n if (!row.option.disabled) activeIndex.value = row.index\n }\n\n // While the panel is open there must always be a valid option highlighted. It is moved back to\n // the first one whenever the highlighted one has fallen out of the list or there was none at\n // all; without that second case, a search that passed through \"no result\" would leave nothing\n // highlighted, and Enter would not choose the single result that came back.\n watch(visible, (list) => {\n if (!options.open()) return\n if (activeIndex.value < 0 || activeIndex.value >= list.length) highlightFirst()\n })\n\n // Nothing here is keyed by VALUE. Two options may share one (a consumer's duplicate, or `1`\n // beside `'1'`, which a template literal spells the same), and a value-keyed index hands both\n // the same position, so both light up as active and Vue patches two rows under one key.\n const rendered = computed<RenderedNode[]>(() => {\n const kept = new Set(visible.value)\n let next = 0\n\n const entryOf = (option: ListboxOption, key: string): ListboxRenderedOption | null => {\n if (!kept.has(option)) return null\n return { kind: 'option', key: `option:${key}`, option, index: next++ }\n }\n\n const nodes: RenderedNode[] = []\n // A separator is held back and only drawn once something has come before it and something\n // comes after it. That single rule covers all three ways the filtering can strand one: at\n // the top of the list, at the bottom, and two in a row.\n let pendingSeparator: string | null = null\n\n for (const [i, item] of options.items().entries()) {\n if (isListboxSeparator(item)) {\n if (nodes.length > 0) pendingSeparator = `sep:${i}`\n continue\n }\n\n let node: RenderedNode | null\n if (isListboxGroup(item)) {\n const entries = item.options\n .map((option, j) => entryOf(option, `${i}.${j}`))\n .filter((entry): entry is ListboxRenderedOption => entry !== null)\n // A block none of whose options survived is dropped entirely, its name included:\n // a heading over nothing is worse than no heading.\n node =\n entries.length > 0\n ? {\n kind: 'group',\n key: `group:${i}`,\n id: `${options.id}-group-${i}`,\n label: item.label,\n options: entries,\n }\n : null\n } else {\n node = entryOf(item, String(i))\n }\n if (!node) continue\n\n if (pendingSeparator !== null) {\n nodes.push({ kind: 'separator', key: pendingSeparator })\n pendingSeparator = null\n }\n nodes.push(node)\n }\n\n return nodes\n })\n\n const flat = computed(() => {\n const rows: FlatRow[] = []\n const labels = new Map<string, string>()\n // Indexed by the option's place in `visible`: where the keyboard's highlight sits in the rows.\n const rowOfOption: number[] = []\n const loose = rendered.value.filter((node) => node.kind === 'option').length\n let looseSeen = 0\n for (const node of rendered.value) {\n if (node.kind === 'separator') rows.push(node)\n else if (node.kind === 'option') {\n rowOfOption[node.index] = rows.length\n rows.push({ ...node, set: loose, position: ++looseSeen })\n } else {\n labels.set(node.key, node.label)\n rows.push({\n kind: 'heading',\n key: `heading:${node.key}`,\n id: node.id,\n label: node.label,\n group: node.key,\n })\n for (const [j, option] of node.options.entries()) {\n rowOfOption[option.index] = rows.length\n rows.push({ ...option, group: node.key, set: node.options.length, position: j + 1 })\n }\n }\n }\n return { rows, labels, rowOfOption }\n })\n\n // @a11y\n // The highlighted row stays rendered wherever the panel is scrolled: `aria-activedescendant`\n // must name an element that exists.\n const virtualList = useVirtualList({\n scrollEl: computed(() => (options.virtual() ? options.panelEl() : null)),\n count: () => flat.value.rows.length,\n key: (index) => flat.value.rows[index]?.key,\n itemSize: () => OPTION_HEIGHT[options.size()],\n overscan: () => 5,\n initialCount: () => 10,\n pinned: () => {\n const row = flat.value.rowOfOption[activeIndex.value]\n return row === undefined ? [] : [row]\n },\n })\n\n function withState(entry: FlatOption, at: number): ListboxOptionRow {\n const active = entry.index === activeIndex.value\n const selected = selectedSet.value.has(entry.option.value)\n // @a11y\n // Only some options exist in the virtual mode, so each one says where it stands; the last\n // block may still grow while pages are coming.\n const placed = options.virtual()\n ? { 'aria-setsize': options.hasMore?.() ? -1 : entry.set, 'aria-posinset': entry.position }\n : {}\n return {\n ...entry,\n at,\n row: {\n id: optionId(entry.index),\n icon: entry.option.icon,\n active,\n selected,\n disabled: entry.option.disabled,\n ...placed,\n },\n slot: { option: entry.option, index: entry.index, active, selected },\n }\n }\n\n // The rows of the window and the space standing for the others, gathered back into their\n // blocks. Kept apart from `flat` on purpose: the highlight moves on every arrow key, and only\n // this pass over the rendered rows follows it; the filtering and the grouping stay where they\n // are.\n const blocks = computed<ListboxBlock[]>(() => {\n const { rows, labels } = flat.value\n const segments: VirtualSegment[] = options.virtual()\n ? virtualList.segments.value\n : rows.map((_, index) => ({ type: 'row', index }))\n const groupAt = (segment: VirtualSegment | undefined) => {\n const row = segment?.type === 'row' ? rows[segment.index] : undefined\n return row && row.kind !== 'separator' ? row.group : undefined\n }\n\n const out: ListboxBlock[] = []\n let open: Extract<ListboxBlock, { kind: 'group' }> | undefined\n for (const [k, segment] of segments.entries()) {\n let block: ListboxRow\n let group: string | undefined\n if (segment.type === 'spacer') {\n block = { kind: 'spacer', key: segment.key, size: segment.size }\n // Between two rows of one block, the space stands for rows of that block.\n const before = groupAt(segments[k - 1])\n group = before === groupAt(segments[k + 1]) ? before : undefined\n } else {\n const row = rows[segment.index]!\n block =\n row.kind === 'option' ? withState(row, segment.index) : { ...row, at: segment.index }\n group = groupAt(segment)\n }\n if (group === undefined) {\n open = undefined\n out.push(block)\n continue\n }\n if (open?.key !== group) {\n open = { kind: 'group', key: group, label: labels.get(group)!, children: [] }\n out.push(open)\n }\n if (block.kind === 'heading') open.labelId = block.id\n open.children.push(block)\n }\n return out\n })\n\n // @a11y\n // Since the focus never leaves the field, the browser has no reason to scroll the highlighted\n // option into view. It is brought into view by hand instead, and asked for the SMALLEST\n // movement that reveals it, so an option already visible does not make the panel jump.\n watch(\n activeIndex,\n (index) => {\n if (index < 0) return\n if (options.virtual()) {\n const row = flat.value.rowOfOption[index]\n if (row !== undefined) void virtualList.scrollToIndex(row)\n return\n }\n // Called optionally: the unit-test environment implements no scrolling at all.\n document.getElementById(optionId(index))?.scrollIntoView?.({ block: 'nearest' })\n },\n { flush: 'post' },\n )\n\n return {\n allOptions,\n visible,\n selectedSet,\n optionOf,\n labelOf,\n remember,\n activeIndex,\n optionId,\n highlightFirst,\n highlightLast,\n highlightSelected,\n move,\n page,\n hover,\n blocks,\n measureRow: virtualList.measure,\n }\n}\n"],"mappings":"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"}
package/dist/i18n/en.js CHANGED
@@ -30,7 +30,8 @@ var e = {
30
30
  link: { newTab: ", opens in a new tab" },
31
31
  combobox: {
32
32
  empty: "No results",
33
- clear: "Clear selection"
33
+ clear: "Clear selection",
34
+ create: (e) => `Create "${e}"`
34
35
  },
35
36
  select: { clear: "Clear selection" },
36
37
  commandPalette: {
@@ -77,6 +78,7 @@ var e = {
77
78
  label: "Progress"
78
79
  },
79
80
  meter: { label: "Meter" },
81
+ meterGroup: { label: "Breakdown" },
80
82
  hotkeys: {
81
83
  command: "Command",
82
84
  ctrl: "Ctrl",
@@ -1 +1 @@
1
- {"version":3,"file":"en.js","names":["en","name","page","label","value","index","count","start","end","total","max","percent","keys","saturation","brightness","position","hour","minute","days","day","title","when"],"sources":["../../src/i18n/en.ts"],"sourcesContent":["/**\n * English is the bundled fallback. Labels are also used by tests and play-function queries;\n * update those contracts when changing wording.\n */\n\nimport type { Messages } from './types'\n\nexport const en: Messages = {\n common: {\n loading: 'Loading…',\n clear: 'Clear',\n close: 'Close',\n dismiss: 'Remove',\n remove: (name) => `Remove ${name}`,\n cancel: 'Cancel',\n confirm: 'OK',\n },\n pagination: {\n label: 'Pagination',\n first: 'First page',\n previous: 'Previous page',\n next: 'Next page',\n last: 'Last page',\n page: (page) => `Page ${page}`,\n },\n tabs: {\n label: 'Tabs',\n previous: 'Previous tabs',\n next: 'Next tabs',\n },\n breadcrumb: {\n label: 'Breadcrumb',\n ellipsis: 'Show intermediate pages',\n },\n sideNavigation: { label: 'Navigation' },\n link: { newTab: ', opens in a new tab' },\n combobox: {\n empty: 'No results',\n clear: 'Clear selection',\n },\n select: { clear: 'Clear selection' },\n commandPalette: {\n label: 'Command palette',\n searchLabel: 'Search commands',\n placeholder: 'Type a command or search…',\n empty: 'No results',\n navigate: 'Navigate',\n choose: 'Select',\n },\n dataTable: {\n empty: 'No data',\n noResults: 'No results',\n loading: 'Loading data…',\n searchLabel: 'Search the table',\n searchPlaceholder: 'Search…',\n perPage: 'Rows per page',\n perPageValue: (label, value) => `${label}: ${value}`,\n selectAll: 'Select all',\n selectRow: (index) => `Select row ${index}`,\n // The plural is chosen right here, in the message itself. That one line is the whole\n // of the design system's handling of plurals, and it is meant to be.\n selection: (count) => `${count} item${count === 1 ? '' : 's'} selected`,\n range: ({ start, end, total }) => `${start}–${end} of ${total}`,\n pagination: 'Table pagination',\n },\n toaster: { label: 'Notifications' },\n snackbar: { label: 'Confirmation', action: 'Undo' },\n inputOTP: {\n label: 'Verification code',\n slot: (index, total) => `Character ${index} of ${total}`,\n },\n slider: {\n value: 'Value',\n start: 'Start',\n end: 'End',\n rangeStart: (label) => `${label} (start)`,\n rangeEnd: (label) => `${label} (end)`,\n },\n field: {\n limitExceeded: (max) => `Exceeds the limit of ${max} characters`,\n },\n progress: { percent: (percent) => `${percent}%`, label: 'Progress' },\n meter: { label: 'Meter' },\n hotkeys: {\n command: 'Command',\n ctrl: 'Ctrl',\n alt: 'Alt',\n shift: 'Shift',\n windows: 'Win',\n super: 'Super',\n enter: 'Enter',\n escape: 'Esc',\n space: 'Space',\n backspace: 'Backspace',\n delete: 'Del',\n tab: 'Tab',\n up: 'Up arrow',\n down: 'Down arrow',\n left: 'Left arrow',\n right: 'Right arrow',\n label: (keys) => `Keyboard shortcut: ${keys}`,\n },\n colorPicker: {\n label: 'Colour picker',\n saturation: 'Saturation',\n brightness: 'Brightness',\n areaValue: (saturation, brightness) => `Saturation ${saturation}, brightness ${brightness}`,\n hue: 'Hue',\n alpha: 'Opacity',\n value: 'Colour value',\n format: 'Colour format',\n eyeDropper: 'Pick a colour from the screen',\n swatches: 'Preset colours',\n },\n colorInput: {\n clear: 'Clear colour',\n openPicker: 'Open colour picker',\n pickerLabel: 'Choose a colour',\n },\n datePicker: {\n label: 'Date picker',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n previousYear: 'Previous year',\n nextYear: 'Next year',\n monthPicker: 'Choose month',\n yearPicker: 'Choose year',\n },\n dateInput: {\n clear: 'Clear date',\n openPicker: 'Open calendar',\n pickerLabel: 'Choose a date',\n },\n numberInput: {\n increment: 'Increase',\n decrement: 'Decrease',\n },\n splitButton: { menu: 'More options' },\n rating: {\n label: 'Rating',\n empty: 'No rating',\n value: (value, max) => `${value} out of ${max}`,\n },\n resizable: {\n panel: (position) => `Panel ${position}`,\n },\n stepper: {\n label: 'Progress',\n completed: 'Completed',\n error: 'Error',\n },\n treeView: {\n label: 'Tree',\n loadFailed: 'Could not load',\n loadError: (label) => `Could not load the contents of ${label}`,\n },\n timePicker: {\n label: 'Time picker',\n meridiem: 'AM or PM',\n am: 'AM',\n pm: 'PM',\n selectHour: 'Select hour',\n selectMinutes: 'Select minutes',\n choosingHour: 'Selecting the hour',\n choosingMinutes: 'Selecting the minutes',\n hour: 'Hour',\n minutes: 'Minutes',\n hourValue: (hour) => `${hour} o'clock`,\n minutesValue: (minute) => (minute === 1 ? '1 minute' : `${minute} minutes`),\n },\n timeInput: {\n clear: 'Clear time',\n openPicker: 'Open time picker',\n pickerLabel: 'Choose a time',\n meridiemValue: (value) => `AM or PM: ${value}`,\n maskPlaceholder: 'hh:mm',\n unavailable: 'This time is not available.',\n },\n fileInput: {\n openPicker: 'Choose files',\n clear: 'Clear files',\n files: (count) => `${count} file${count === 1 ? '' : 's'}`,\n placeholder: 'No file selected',\n },\n filePicker: {\n browse: 'Browse files',\n or: 'or',\n list: 'Selected files',\n },\n carousel: {\n label: 'Carousel',\n roleDescription: 'carousel',\n slideRoleDescription: 'slide',\n slides: 'Slides',\n slide: (index, total) => `${index} of ${total}`,\n previous: 'Previous slide',\n next: 'Next slide',\n indicators: 'Choose slide to display',\n },\n calendar: {\n label: 'Calendar',\n roleDescription: 'calendar',\n today: 'Today',\n view: 'View',\n viewDay: 'Day',\n view4Days: '4 days',\n viewWeek: 'Week',\n viewMonth: 'Month',\n viewYear: 'Year',\n viewCustom: (days) => `${days} days`,\n previousDay: 'Previous day',\n nextDay: 'Next day',\n previousWeek: 'Previous week',\n nextWeek: 'Next week',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n previousYear: 'Previous year',\n nextYear: 'Next year',\n previousPeriod: 'Previous period',\n nextPeriod: 'Next period',\n allDay: 'All day',\n moreEvents: (count) => `+${count} more`,\n openDay: (day) => `Open ${day}`,\n untitled: '(No title)',\n eventRoleDescription: 'event',\n eventHint:\n 'Press Enter to open this event. Press Space to take hold of it, then the arrow keys to move it and Shift with the arrow keys to change when it ends.',\n grabbed:\n 'Event held. Use the arrow keys to move it, Enter or Space to place it, Escape to cancel.',\n dropped: 'Event placed.',\n reverted: 'Move cancelled. The event is back where it was.',\n movedTo: (title, when) => `${title} moved to ${when}.`,\n },\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"en.js","names":["en","name","page","query","label","value","index","count","start","end","total","max","percent","keys","saturation","brightness","position","hour","minute","days","day","title","when"],"sources":["../../src/i18n/en.ts"],"sourcesContent":["/**\n * English is the bundled fallback. Labels are also used by tests and play-function queries;\n * update those contracts when changing wording.\n */\n\nimport type { Messages } from './types'\n\nexport const en: Messages = {\n common: {\n loading: 'Loading…',\n clear: 'Clear',\n close: 'Close',\n dismiss: 'Remove',\n remove: (name) => `Remove ${name}`,\n cancel: 'Cancel',\n confirm: 'OK',\n },\n pagination: {\n label: 'Pagination',\n first: 'First page',\n previous: 'Previous page',\n next: 'Next page',\n last: 'Last page',\n page: (page) => `Page ${page}`,\n },\n tabs: {\n label: 'Tabs',\n previous: 'Previous tabs',\n next: 'Next tabs',\n },\n breadcrumb: {\n label: 'Breadcrumb',\n ellipsis: 'Show intermediate pages',\n },\n sideNavigation: { label: 'Navigation' },\n link: { newTab: ', opens in a new tab' },\n combobox: {\n empty: 'No results',\n clear: 'Clear selection',\n create: (query) => `Create \"${query}\"`,\n },\n select: { clear: 'Clear selection' },\n commandPalette: {\n label: 'Command palette',\n searchLabel: 'Search commands',\n placeholder: 'Type a command or search…',\n empty: 'No results',\n navigate: 'Navigate',\n choose: 'Select',\n },\n dataTable: {\n empty: 'No data',\n noResults: 'No results',\n loading: 'Loading data…',\n searchLabel: 'Search the table',\n searchPlaceholder: 'Search…',\n perPage: 'Rows per page',\n perPageValue: (label, value) => `${label}: ${value}`,\n selectAll: 'Select all',\n selectRow: (index) => `Select row ${index}`,\n // The plural is chosen right here, in the message itself. That one line is the whole\n // of the design system's handling of plurals, and it is meant to be.\n selection: (count) => `${count} item${count === 1 ? '' : 's'} selected`,\n range: ({ start, end, total }) => `${start}–${end} of ${total}`,\n pagination: 'Table pagination',\n },\n toaster: { label: 'Notifications' },\n snackbar: { label: 'Confirmation', action: 'Undo' },\n inputOTP: {\n label: 'Verification code',\n slot: (index, total) => `Character ${index} of ${total}`,\n },\n slider: {\n value: 'Value',\n start: 'Start',\n end: 'End',\n rangeStart: (label) => `${label} (start)`,\n rangeEnd: (label) => `${label} (end)`,\n },\n field: {\n limitExceeded: (max) => `Exceeds the limit of ${max} characters`,\n },\n progress: { percent: (percent) => `${percent}%`, label: 'Progress' },\n meter: { label: 'Meter' },\n meterGroup: { label: 'Breakdown' },\n hotkeys: {\n command: 'Command',\n ctrl: 'Ctrl',\n alt: 'Alt',\n shift: 'Shift',\n windows: 'Win',\n super: 'Super',\n enter: 'Enter',\n escape: 'Esc',\n space: 'Space',\n backspace: 'Backspace',\n delete: 'Del',\n tab: 'Tab',\n up: 'Up arrow',\n down: 'Down arrow',\n left: 'Left arrow',\n right: 'Right arrow',\n label: (keys) => `Keyboard shortcut: ${keys}`,\n },\n colorPicker: {\n label: 'Colour picker',\n saturation: 'Saturation',\n brightness: 'Brightness',\n areaValue: (saturation, brightness) => `Saturation ${saturation}, brightness ${brightness}`,\n hue: 'Hue',\n alpha: 'Opacity',\n value: 'Colour value',\n format: 'Colour format',\n eyeDropper: 'Pick a colour from the screen',\n swatches: 'Preset colours',\n },\n colorInput: {\n clear: 'Clear colour',\n openPicker: 'Open colour picker',\n pickerLabel: 'Choose a colour',\n },\n datePicker: {\n label: 'Date picker',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n previousYear: 'Previous year',\n nextYear: 'Next year',\n monthPicker: 'Choose month',\n yearPicker: 'Choose year',\n },\n dateInput: {\n clear: 'Clear date',\n openPicker: 'Open calendar',\n pickerLabel: 'Choose a date',\n },\n numberInput: {\n increment: 'Increase',\n decrement: 'Decrease',\n },\n splitButton: { menu: 'More options' },\n rating: {\n label: 'Rating',\n empty: 'No rating',\n value: (value, max) => `${value} out of ${max}`,\n },\n resizable: {\n panel: (position) => `Panel ${position}`,\n },\n stepper: {\n label: 'Progress',\n completed: 'Completed',\n error: 'Error',\n },\n treeView: {\n label: 'Tree',\n loadFailed: 'Could not load',\n loadError: (label) => `Could not load the contents of ${label}`,\n },\n timePicker: {\n label: 'Time picker',\n meridiem: 'AM or PM',\n am: 'AM',\n pm: 'PM',\n selectHour: 'Select hour',\n selectMinutes: 'Select minutes',\n choosingHour: 'Selecting the hour',\n choosingMinutes: 'Selecting the minutes',\n hour: 'Hour',\n minutes: 'Minutes',\n hourValue: (hour) => `${hour} o'clock`,\n minutesValue: (minute) => (minute === 1 ? '1 minute' : `${minute} minutes`),\n },\n timeInput: {\n clear: 'Clear time',\n openPicker: 'Open time picker',\n pickerLabel: 'Choose a time',\n meridiemValue: (value) => `AM or PM: ${value}`,\n maskPlaceholder: 'hh:mm',\n unavailable: 'This time is not available.',\n },\n fileInput: {\n openPicker: 'Choose files',\n clear: 'Clear files',\n files: (count) => `${count} file${count === 1 ? '' : 's'}`,\n placeholder: 'No file selected',\n },\n filePicker: {\n browse: 'Browse files',\n or: 'or',\n list: 'Selected files',\n },\n carousel: {\n label: 'Carousel',\n roleDescription: 'carousel',\n slideRoleDescription: 'slide',\n slides: 'Slides',\n slide: (index, total) => `${index} of ${total}`,\n previous: 'Previous slide',\n next: 'Next slide',\n indicators: 'Choose slide to display',\n },\n calendar: {\n label: 'Calendar',\n roleDescription: 'calendar',\n today: 'Today',\n view: 'View',\n viewDay: 'Day',\n view4Days: '4 days',\n viewWeek: 'Week',\n viewMonth: 'Month',\n viewYear: 'Year',\n viewCustom: (days) => `${days} days`,\n previousDay: 'Previous day',\n nextDay: 'Next day',\n previousWeek: 'Previous week',\n nextWeek: 'Next week',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n previousYear: 'Previous year',\n nextYear: 'Next year',\n previousPeriod: 'Previous period',\n nextPeriod: 'Next period',\n allDay: 'All day',\n moreEvents: (count) => `+${count} more`,\n openDay: (day) => `Open ${day}`,\n untitled: '(No title)',\n eventRoleDescription: 'event',\n eventHint:\n 'Press Enter to open this event. Press Space to take hold of it, then the arrow keys to move it and Shift with the arrow keys to change when it ends.',\n grabbed:\n 'Event held. Use the arrow keys to move it, Enter or Space to place it, Escape to cancel.',\n dropped: 'Event placed.',\n reverted: 'Move cancelled. The event is back where it was.',\n movedTo: (title, when) => `${title} moved to ${when}.`,\n },\n}\n"],"mappings":"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"}
package/dist/i18n/fr.js CHANGED
@@ -30,7 +30,8 @@ var e = {
30
30
  link: { newTab: ", s’ouvre dans un nouvel onglet" },
31
31
  combobox: {
32
32
  empty: "Aucun résultat",
33
- clear: "Effacer la sélection"
33
+ clear: "Effacer la sélection",
34
+ create: (e) => `Créer « ${e} »`
34
35
  },
35
36
  select: { clear: "Effacer la sélection" },
36
37
  commandPalette: {
@@ -77,6 +78,7 @@ var e = {
77
78
  label: "Progression"
78
79
  },
79
80
  meter: { label: "Jauge" },
81
+ meterGroup: { label: "Répartition" },
80
82
  hotkeys: {
81
83
  command: "Commande",
82
84
  ctrl: "Ctrl",
@@ -1 +1 @@
1
- {"version":3,"file":"fr.js","names":["fr","name","page","label","value","index","count","start","end","total","max","percent","keys","saturation","brightness","position","hour","minute","days","day","title","when"],"sources":["../../src/i18n/fr.ts"],"sourcesContent":["/**\n * Opt-in French dictionary registered through registerMessages. Preserve typographic\n * apostrophes and message signatures.\n */\n\nimport type { Messages } from './types'\n\nexport const fr: Messages = {\n common: {\n loading: 'Chargement…',\n clear: 'Effacer',\n close: 'Fermer',\n dismiss: 'Retirer',\n remove: (name) => `Retirer ${name}`,\n cancel: 'Annuler',\n confirm: 'OK',\n },\n pagination: {\n label: 'Pagination',\n first: 'Première page',\n previous: 'Page précédente',\n next: 'Page suivante',\n last: 'Dernière page',\n page: (page) => `Page ${page}`,\n },\n tabs: {\n label: 'Onglets',\n previous: 'Onglets précédents',\n next: 'Onglets suivants',\n },\n breadcrumb: {\n label: 'Fil d’Ariane',\n ellipsis: 'Afficher les pages intermédiaires',\n },\n sideNavigation: { label: 'Navigation' },\n link: { newTab: ', s’ouvre dans un nouvel onglet' },\n combobox: {\n empty: 'Aucun résultat',\n clear: 'Effacer la sélection',\n },\n select: { clear: 'Effacer la sélection' },\n commandPalette: {\n label: 'Palette de commandes',\n searchLabel: 'Rechercher une commande',\n placeholder: 'Saisissez une commande ou recherchez…',\n empty: 'Aucun résultat',\n navigate: 'Naviguer',\n choose: 'Choisir',\n },\n dataTable: {\n empty: 'Aucune donnée',\n noResults: 'Aucun résultat',\n loading: 'Chargement des données…',\n searchLabel: 'Rechercher dans le tableau',\n searchPlaceholder: 'Rechercher…',\n perPage: 'Lignes par page',\n perPageValue: (label, value) => `${label}\\u00A0: ${value}`,\n selectAll: 'Tout sélectionner',\n selectRow: (index) => `Sélectionner la ligne ${index}`,\n selection: (count) =>\n `${count} élément${count > 1 ? 's' : ''} sélectionné${count > 1 ? 's' : ''}`,\n range: ({ start, end, total }) => `${start}–${end} sur ${total}`,\n pagination: 'Pagination du tableau',\n },\n toaster: { label: 'Notifications' },\n snackbar: { label: 'Confirmation', action: 'Annuler' },\n inputOTP: {\n label: 'Code de vérification',\n slot: (index, total) => `Caractère ${index} sur ${total}`,\n },\n slider: {\n value: 'Valeur',\n start: 'Début',\n end: 'Fin',\n rangeStart: (label) => `${label} (début)`,\n rangeEnd: (label) => `${label} (fin)`,\n },\n field: {\n limitExceeded: (max) => `Dépasse la limite de ${max} caractères`,\n },\n // The space before the sign is a NON-BREAKING one, as French typography requires and\n // English does not. It is written as an escape rather than typed in: the linter refuses\n // the character itself, and it would be indistinguishable from an ordinary space in a\n // review.\n progress: { percent: (percent) => `${percent}\\u00A0%`, label: 'Progression' },\n meter: { label: 'Jauge' },\n hotkeys: {\n command: 'Commande',\n ctrl: 'Ctrl',\n alt: 'Alt',\n shift: 'Maj',\n windows: 'Win',\n super: 'Super',\n enter: 'Entrée',\n escape: 'Échap',\n space: 'Espace',\n backspace: 'Retour arrière',\n delete: 'Suppr',\n tab: 'Tab',\n up: 'Flèche haut',\n down: 'Flèche bas',\n left: 'Flèche gauche',\n right: 'Flèche droite',\n label: (keys) => `Raccourci clavier\\u00A0: ${keys}`,\n },\n colorPicker: {\n label: 'Sélecteur de couleur',\n saturation: 'Saturation',\n brightness: 'Luminosité',\n areaValue: (saturation, brightness) => `Saturation ${saturation}, luminosité ${brightness}`,\n hue: 'Teinte',\n alpha: 'Opacité',\n value: 'Valeur de la couleur',\n format: 'Format de la couleur',\n eyeDropper: 'Prélever une couleur à l’écran',\n swatches: 'Couleurs prédéfinies',\n },\n colorInput: {\n clear: 'Effacer la couleur',\n openPicker: 'Ouvrir le sélecteur de couleur',\n pickerLabel: 'Choisir une couleur',\n },\n datePicker: {\n label: 'Sélecteur de date',\n previousMonth: 'Mois précédent',\n nextMonth: 'Mois suivant',\n previousYear: 'Année précédente',\n nextYear: 'Année suivante',\n monthPicker: 'Choix du mois',\n yearPicker: 'Choix de l’année',\n },\n dateInput: {\n clear: 'Effacer la date',\n openPicker: 'Ouvrir le calendrier',\n pickerLabel: 'Choisir une date',\n },\n numberInput: {\n increment: 'Augmenter',\n decrement: 'Diminuer',\n },\n splitButton: { menu: 'Plus d’options' },\n rating: {\n label: 'Note',\n empty: 'Aucune note',\n value: (value, max) => `${value} sur ${max}`,\n },\n resizable: {\n panel: (position) => `Panneau ${position}`,\n },\n stepper: {\n label: 'Progression',\n completed: 'Terminée',\n error: 'Erreur',\n },\n treeView: {\n label: 'Arborescence',\n loadFailed: 'Chargement impossible',\n loadError: (label) => `Impossible de charger le contenu de ${label}`,\n },\n timePicker: {\n label: 'Sélecteur d’heure',\n meridiem: 'AM ou PM',\n am: 'AM',\n pm: 'PM',\n selectHour: 'Sélectionner l’heure',\n selectMinutes: 'Sélectionner les minutes',\n choosingHour: 'Sélection de l’heure',\n choosingMinutes: 'Sélection des minutes',\n hour: 'Heure',\n minutes: 'Minutes',\n hourValue: (hour) => `${hour} ${hour < 2 ? 'heure' : 'heures'}`,\n minutesValue: (minute) => `${minute} ${minute < 2 ? 'minute' : 'minutes'}`,\n },\n timeInput: {\n clear: 'Effacer l’heure',\n openPicker: 'Ouvrir le sélecteur d’heure',\n pickerLabel: 'Choisir une heure',\n meridiemValue: (value) => `AM ou PM\\u00A0: ${value}`,\n maskPlaceholder: 'hh:mm',\n unavailable: 'Cette heure n’est pas disponible.',\n },\n fileInput: {\n openPicker: 'Choisir des fichiers',\n clear: 'Effacer les fichiers',\n // The French plural starts at two, the English one at zero; \"0 fichier\" against \"0 files\".\n // Each language therefore makes the choice on its own, and there is no shared rule for\n // either to inherit.\n files: (count) => `${count} fichier${count > 1 ? 's' : ''}`,\n placeholder: 'Aucun fichier sélectionné',\n },\n filePicker: {\n browse: 'Parcourir les fichiers',\n or: 'ou',\n list: 'Fichiers sélectionnés',\n },\n carousel: {\n label: 'Carrousel',\n roleDescription: 'carrousel',\n slideRoleDescription: 'diapositive',\n slides: 'Diapositives',\n slide: (index, total) => `${index} sur ${total}`,\n previous: 'Diapositive précédente',\n next: 'Diapositive suivante',\n indicators: 'Choisir la diapositive à afficher',\n },\n calendar: {\n label: 'Calendrier',\n roleDescription: 'calendrier',\n today: 'Aujourd’hui',\n view: 'Affichage',\n viewDay: 'Jour',\n view4Days: '4 jours',\n viewWeek: 'Semaine',\n viewMonth: 'Mois',\n viewYear: 'Année',\n viewCustom: (days) => `${days} jours`,\n previousDay: 'Jour précédent',\n nextDay: 'Jour suivant',\n previousWeek: 'Semaine précédente',\n nextWeek: 'Semaine suivante',\n previousMonth: 'Mois précédent',\n nextMonth: 'Mois suivant',\n previousYear: 'Année précédente',\n nextYear: 'Année suivante',\n previousPeriod: 'Période précédente',\n nextPeriod: 'Période suivante',\n allDay: 'Toute la journée',\n moreEvents: (count) => `+${count} autre${count > 1 ? 's' : ''}`,\n openDay: (day) => `Ouvrir le ${day}`,\n untitled: '(Sans titre)',\n eventRoleDescription: 'évènement',\n eventHint:\n 'Appuyez sur Entrée pour ouvrir cet évènement. Appuyez sur Espace pour le saisir, puis sur les flèches pour le déplacer et sur Maj avec les flèches pour changer son heure de fin.',\n grabbed:\n 'Évènement saisi. Utilisez les flèches pour le déplacer, Entrée ou Espace pour le poser, Échap pour annuler.',\n dropped: 'Évènement posé.',\n reverted: 'Déplacement annulé. L’évènement est revenu à sa place.',\n movedTo: (title, when) => `Déplacement de ${title}\\u00A0: ${when}.`,\n },\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fr.js","names":["fr","name","page","query","label","value","index","count","start","end","total","max","percent","keys","saturation","brightness","position","hour","minute","days","day","title","when"],"sources":["../../src/i18n/fr.ts"],"sourcesContent":["/**\n * Opt-in French dictionary registered through registerMessages. Preserve typographic\n * apostrophes and message signatures.\n */\n\nimport type { Messages } from './types'\n\nexport const fr: Messages = {\n common: {\n loading: 'Chargement…',\n clear: 'Effacer',\n close: 'Fermer',\n dismiss: 'Retirer',\n remove: (name) => `Retirer ${name}`,\n cancel: 'Annuler',\n confirm: 'OK',\n },\n pagination: {\n label: 'Pagination',\n first: 'Première page',\n previous: 'Page précédente',\n next: 'Page suivante',\n last: 'Dernière page',\n page: (page) => `Page ${page}`,\n },\n tabs: {\n label: 'Onglets',\n previous: 'Onglets précédents',\n next: 'Onglets suivants',\n },\n breadcrumb: {\n label: 'Fil d’Ariane',\n ellipsis: 'Afficher les pages intermédiaires',\n },\n sideNavigation: { label: 'Navigation' },\n link: { newTab: ', s’ouvre dans un nouvel onglet' },\n combobox: {\n empty: 'Aucun résultat',\n clear: 'Effacer la sélection',\n create: (query) => `Créer « ${query} »`,\n },\n select: { clear: 'Effacer la sélection' },\n commandPalette: {\n label: 'Palette de commandes',\n searchLabel: 'Rechercher une commande',\n placeholder: 'Saisissez une commande ou recherchez…',\n empty: 'Aucun résultat',\n navigate: 'Naviguer',\n choose: 'Choisir',\n },\n dataTable: {\n empty: 'Aucune donnée',\n noResults: 'Aucun résultat',\n loading: 'Chargement des données…',\n searchLabel: 'Rechercher dans le tableau',\n searchPlaceholder: 'Rechercher…',\n perPage: 'Lignes par page',\n perPageValue: (label, value) => `${label}\\u00A0: ${value}`,\n selectAll: 'Tout sélectionner',\n selectRow: (index) => `Sélectionner la ligne ${index}`,\n selection: (count) =>\n `${count} élément${count > 1 ? 's' : ''} sélectionné${count > 1 ? 's' : ''}`,\n range: ({ start, end, total }) => `${start}–${end} sur ${total}`,\n pagination: 'Pagination du tableau',\n },\n toaster: { label: 'Notifications' },\n snackbar: { label: 'Confirmation', action: 'Annuler' },\n inputOTP: {\n label: 'Code de vérification',\n slot: (index, total) => `Caractère ${index} sur ${total}`,\n },\n slider: {\n value: 'Valeur',\n start: 'Début',\n end: 'Fin',\n rangeStart: (label) => `${label} (début)`,\n rangeEnd: (label) => `${label} (fin)`,\n },\n field: {\n limitExceeded: (max) => `Dépasse la limite de ${max} caractères`,\n },\n // The space before the sign is a NON-BREAKING one, as French typography requires and\n // English does not. It is written as an escape rather than typed in: the linter refuses\n // the character itself, and it would be indistinguishable from an ordinary space in a\n // review.\n progress: { percent: (percent) => `${percent}\\u00A0%`, label: 'Progression' },\n meter: { label: 'Jauge' },\n meterGroup: { label: 'Répartition' },\n hotkeys: {\n command: 'Commande',\n ctrl: 'Ctrl',\n alt: 'Alt',\n shift: 'Maj',\n windows: 'Win',\n super: 'Super',\n enter: 'Entrée',\n escape: 'Échap',\n space: 'Espace',\n backspace: 'Retour arrière',\n delete: 'Suppr',\n tab: 'Tab',\n up: 'Flèche haut',\n down: 'Flèche bas',\n left: 'Flèche gauche',\n right: 'Flèche droite',\n label: (keys) => `Raccourci clavier\\u00A0: ${keys}`,\n },\n colorPicker: {\n label: 'Sélecteur de couleur',\n saturation: 'Saturation',\n brightness: 'Luminosité',\n areaValue: (saturation, brightness) => `Saturation ${saturation}, luminosité ${brightness}`,\n hue: 'Teinte',\n alpha: 'Opacité',\n value: 'Valeur de la couleur',\n format: 'Format de la couleur',\n eyeDropper: 'Prélever une couleur à l’écran',\n swatches: 'Couleurs prédéfinies',\n },\n colorInput: {\n clear: 'Effacer la couleur',\n openPicker: 'Ouvrir le sélecteur de couleur',\n pickerLabel: 'Choisir une couleur',\n },\n datePicker: {\n label: 'Sélecteur de date',\n previousMonth: 'Mois précédent',\n nextMonth: 'Mois suivant',\n previousYear: 'Année précédente',\n nextYear: 'Année suivante',\n monthPicker: 'Choix du mois',\n yearPicker: 'Choix de l’année',\n },\n dateInput: {\n clear: 'Effacer la date',\n openPicker: 'Ouvrir le calendrier',\n pickerLabel: 'Choisir une date',\n },\n numberInput: {\n increment: 'Augmenter',\n decrement: 'Diminuer',\n },\n splitButton: { menu: 'Plus d’options' },\n rating: {\n label: 'Note',\n empty: 'Aucune note',\n value: (value, max) => `${value} sur ${max}`,\n },\n resizable: {\n panel: (position) => `Panneau ${position}`,\n },\n stepper: {\n label: 'Progression',\n completed: 'Terminée',\n error: 'Erreur',\n },\n treeView: {\n label: 'Arborescence',\n loadFailed: 'Chargement impossible',\n loadError: (label) => `Impossible de charger le contenu de ${label}`,\n },\n timePicker: {\n label: 'Sélecteur d’heure',\n meridiem: 'AM ou PM',\n am: 'AM',\n pm: 'PM',\n selectHour: 'Sélectionner l’heure',\n selectMinutes: 'Sélectionner les minutes',\n choosingHour: 'Sélection de l’heure',\n choosingMinutes: 'Sélection des minutes',\n hour: 'Heure',\n minutes: 'Minutes',\n hourValue: (hour) => `${hour} ${hour < 2 ? 'heure' : 'heures'}`,\n minutesValue: (minute) => `${minute} ${minute < 2 ? 'minute' : 'minutes'}`,\n },\n timeInput: {\n clear: 'Effacer l’heure',\n openPicker: 'Ouvrir le sélecteur d’heure',\n pickerLabel: 'Choisir une heure',\n meridiemValue: (value) => `AM ou PM\\u00A0: ${value}`,\n maskPlaceholder: 'hh:mm',\n unavailable: 'Cette heure n’est pas disponible.',\n },\n fileInput: {\n openPicker: 'Choisir des fichiers',\n clear: 'Effacer les fichiers',\n // The French plural starts at two, the English one at zero; \"0 fichier\" against \"0 files\".\n // Each language therefore makes the choice on its own, and there is no shared rule for\n // either to inherit.\n files: (count) => `${count} fichier${count > 1 ? 's' : ''}`,\n placeholder: 'Aucun fichier sélectionné',\n },\n filePicker: {\n browse: 'Parcourir les fichiers',\n or: 'ou',\n list: 'Fichiers sélectionnés',\n },\n carousel: {\n label: 'Carrousel',\n roleDescription: 'carrousel',\n slideRoleDescription: 'diapositive',\n slides: 'Diapositives',\n slide: (index, total) => `${index} sur ${total}`,\n previous: 'Diapositive précédente',\n next: 'Diapositive suivante',\n indicators: 'Choisir la diapositive à afficher',\n },\n calendar: {\n label: 'Calendrier',\n roleDescription: 'calendrier',\n today: 'Aujourd’hui',\n view: 'Affichage',\n viewDay: 'Jour',\n view4Days: '4 jours',\n viewWeek: 'Semaine',\n viewMonth: 'Mois',\n viewYear: 'Année',\n viewCustom: (days) => `${days} jours`,\n previousDay: 'Jour précédent',\n nextDay: 'Jour suivant',\n previousWeek: 'Semaine précédente',\n nextWeek: 'Semaine suivante',\n previousMonth: 'Mois précédent',\n nextMonth: 'Mois suivant',\n previousYear: 'Année précédente',\n nextYear: 'Année suivante',\n previousPeriod: 'Période précédente',\n nextPeriod: 'Période suivante',\n allDay: 'Toute la journée',\n moreEvents: (count) => `+${count} autre${count > 1 ? 's' : ''}`,\n openDay: (day) => `Ouvrir le ${day}`,\n untitled: '(Sans titre)',\n eventRoleDescription: 'évènement',\n eventHint:\n 'Appuyez sur Entrée pour ouvrir cet évènement. Appuyez sur Espace pour le saisir, puis sur les flèches pour le déplacer et sur Maj avec les flèches pour changer son heure de fin.',\n grabbed:\n 'Évènement saisi. Utilisez les flèches pour le déplacer, Entrée ou Espace pour le poser, Échap pour annuler.',\n dropped: 'Évènement posé.',\n reverted: 'Déplacement annulé. L’évènement est revenu à sa place.',\n movedTo: (title, when) => `Déplacement de ${title}\\u00A0: ${when}.`,\n },\n}\n"],"mappings":"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"}
@@ -53,6 +53,8 @@ export interface Messages {
53
53
  combobox: {
54
54
  empty: string;
55
55
  clear: string;
56
+ /** The row of a `creatable` list that adds what has been typed as a new value. */
57
+ create: (query: string) => string;
56
58
  };
57
59
  select: {
58
60
  clear: string;
@@ -141,6 +143,10 @@ export interface Messages {
141
143
  */
142
144
  label: string;
143
145
  };
146
+ meterGroup: {
147
+ /** What a group of meters is called when the consumer gives it no label. */
148
+ label: string;
149
+ };
144
150
  /**
145
151
  * The keys of a keyboard shortcut, in words. Where a symbol exists it wins on screen, and the
146
152
  * word wins in what a screen reader says.
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export type { TypographyTone, TypographyVariant } from './components/VTypography
13
13
  export { default as VPopover } from './components/VPopover/VPopover.js';
14
14
  export type { PopoverMode, PopoverPlacement, PopoverTriggerProps, } from './components/VPopover/VPopover.js';
15
15
  export { default as VSeparator } from './components/VSeparator/VSeparator.js';
16
- export type { SeparatorOrientation } from './components/VSeparator/VSeparator.js';
16
+ export type { SeparatorContentPosition, SeparatorOrientation, SeparatorSize, SeparatorVariant, } from './components/VSeparator/VSeparator.js';
17
17
  export { default as VResizable } from './components/VResizable/VResizable.js';
18
18
  export type { ResizableLength, ResizableOrientation } from './components/VResizable/VResizable.js';
19
19
  export { default as VResizablePanel } from './components/VResizable/VResizablePanel.js';
@@ -121,11 +121,13 @@ export type { VirtualListAlign, VirtualListItemSlotProps, VirtualListProps, } fr
121
121
  export { default as VInputOTP } from './components/VInputOTP/VInputOTP.js';
122
122
  export type { InputOTPSize, InputOTPFormat } from './components/VInputOTP/VInputOTP.js';
123
123
  export { default as VMeter } from './components/VMeter/VMeter.js';
124
- export type { MeterTone, MeterSize } from './components/VMeter/VMeter.js';
124
+ export type { MeterTone, MeterSize, MeterValuePosition, MeterOrientation, } from './components/VMeter/VMeter.js';
125
+ export { default as VMeterGroup } from './components/VMeterGroup/VMeterGroup.js';
126
+ export type { MeterGroupTone, MeterGroupSize, MeterGroupOrientation, MeterGroupItem, MeterGroupItemSlotProps, MeterGroupValueSlotProps, } from './components/VMeterGroup/VMeterGroup.js';
125
127
  export { default as VProgressCircular } from './components/VProgressCircular/VProgressCircular.js';
126
128
  export type { ProgressCircularTone, ProgressCircularShape, ProgressCircularSlotProps, } from './components/VProgressCircular/VProgressCircular.js';
127
129
  export { default as VProgressLinear } from './components/VProgressLinear/VProgressLinear.js';
128
- export type { ProgressLinearTone, ProgressLinearShape, ProgressLinearValuePosition, ProgressLinearOrientation, ProgressLinearSlotProps, } from './components/VProgressLinear/VProgressLinear.js';
130
+ export type { ProgressLinearTone, ProgressLinearShape, ProgressLinearSize, ProgressLinearValuePosition, ProgressLinearOrientation, ProgressLinearSlotProps, } from './components/VProgressLinear/VProgressLinear.js';
129
131
  export { default as VRating } from './components/VRating/VRating.js';
130
132
  export type { RatingSize, RatingTone } from './components/VRating/VRating.js';
131
133
  export { default as VSlider } from './components/VSlider/VSlider.js';