@vuecs/forms 4.0.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 (90) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +43 -0
  3. package/dist/components/constants.d.ts +5 -0
  4. package/dist/components/constants.d.ts.map +1 -0
  5. package/dist/components/form-checkbox/FormCheckbox.vue.d.ts +205 -0
  6. package/dist/components/form-checkbox/FormCheckbox.vue.d.ts.map +1 -0
  7. package/dist/components/form-checkbox/index.d.ts +5 -0
  8. package/dist/components/form-checkbox/index.d.ts.map +1 -0
  9. package/dist/components/form-checkbox-group/FormCheckboxGroup.vue.d.ts +170 -0
  10. package/dist/components/form-checkbox-group/FormCheckboxGroup.vue.d.ts.map +1 -0
  11. package/dist/components/form-checkbox-group/index.d.ts +5 -0
  12. package/dist/components/form-checkbox-group/index.d.ts.map +1 -0
  13. package/dist/components/form-group/FormGroup.vue.d.ts +218 -0
  14. package/dist/components/form-group/FormGroup.vue.d.ts.map +1 -0
  15. package/dist/components/form-group/index.d.ts +5 -0
  16. package/dist/components/form-group/index.d.ts.map +1 -0
  17. package/dist/components/form-input/FormInput.vue.d.ts +195 -0
  18. package/dist/components/form-input/FormInput.vue.d.ts.map +1 -0
  19. package/dist/components/form-input/index.d.ts +5 -0
  20. package/dist/components/form-input/index.d.ts.map +1 -0
  21. package/dist/components/form-number/FormNumber.vue.d.ts +268 -0
  22. package/dist/components/form-number/FormNumber.vue.d.ts.map +1 -0
  23. package/dist/components/form-number/index.d.ts +5 -0
  24. package/dist/components/form-number/index.d.ts.map +1 -0
  25. package/dist/components/form-pin/FormPin.vue.d.ts +221 -0
  26. package/dist/components/form-pin/FormPin.vue.d.ts.map +1 -0
  27. package/dist/components/form-pin/index.d.ts +5 -0
  28. package/dist/components/form-pin/index.d.ts.map +1 -0
  29. package/dist/components/form-radio/FormRadio.vue.d.ts +170 -0
  30. package/dist/components/form-radio/FormRadio.vue.d.ts.map +1 -0
  31. package/dist/components/form-radio/index.d.ts +5 -0
  32. package/dist/components/form-radio/index.d.ts.map +1 -0
  33. package/dist/components/form-radio-group/FormRadioGroup.vue.d.ts +172 -0
  34. package/dist/components/form-radio-group/FormRadioGroup.vue.d.ts.map +1 -0
  35. package/dist/components/form-radio-group/index.d.ts +5 -0
  36. package/dist/components/form-radio-group/index.d.ts.map +1 -0
  37. package/dist/components/form-select/FormSelect.vue.d.ts +172 -0
  38. package/dist/components/form-select/FormSelect.vue.d.ts.map +1 -0
  39. package/dist/components/form-select/index.d.ts +5 -0
  40. package/dist/components/form-select/index.d.ts.map +1 -0
  41. package/dist/components/form-select-search/FormSelectSearch.vue.d.ts +272 -0
  42. package/dist/components/form-select-search/FormSelectSearch.vue.d.ts.map +1 -0
  43. package/dist/components/form-select-search/FormSelectSearchEntry.vue.d.ts +40 -0
  44. package/dist/components/form-select-search/FormSelectSearchEntry.vue.d.ts.map +1 -0
  45. package/dist/components/form-select-search/index.d.ts +6 -0
  46. package/dist/components/form-select-search/index.d.ts.map +1 -0
  47. package/dist/components/form-select-search/type.d.ts +10 -0
  48. package/dist/components/form-select-search/type.d.ts.map +1 -0
  49. package/dist/components/form-slider/FormSlider.vue.d.ts +227 -0
  50. package/dist/components/form-slider/FormSlider.vue.d.ts.map +1 -0
  51. package/dist/components/form-slider/index.d.ts +5 -0
  52. package/dist/components/form-slider/index.d.ts.map +1 -0
  53. package/dist/components/form-switch/FormSwitch.vue.d.ts +204 -0
  54. package/dist/components/form-switch/FormSwitch.vue.d.ts.map +1 -0
  55. package/dist/components/form-switch/index.d.ts +5 -0
  56. package/dist/components/form-switch/index.d.ts.map +1 -0
  57. package/dist/components/form-tags/FormTags.vue.d.ts +255 -0
  58. package/dist/components/form-tags/FormTags.vue.d.ts.map +1 -0
  59. package/dist/components/form-tags/index.d.ts +5 -0
  60. package/dist/components/form-tags/index.d.ts.map +1 -0
  61. package/dist/components/form-textarea/FormTextarea.vue.d.ts +89 -0
  62. package/dist/components/form-textarea/FormTextarea.vue.d.ts.map +1 -0
  63. package/dist/components/form-textarea/index.d.ts +5 -0
  64. package/dist/components/form-textarea/index.d.ts.map +1 -0
  65. package/dist/components/index.d.ts +18 -0
  66. package/dist/components/index.d.ts.map +1 -0
  67. package/dist/components/type.d.ts +17 -0
  68. package/dist/components/type.d.ts.map +1 -0
  69. package/dist/components/validation-group/ValidationGroup.vue.d.ts +119 -0
  70. package/dist/components/validation-group/ValidationGroup.vue.d.ts.map +1 -0
  71. package/dist/components/validation-group/index.d.ts +5 -0
  72. package/dist/components/validation-group/index.d.ts.map +1 -0
  73. package/dist/composables/index.d.ts +2 -0
  74. package/dist/composables/index.d.ts.map +1 -0
  75. package/dist/composables/use-submit-button.d.ts +63 -0
  76. package/dist/composables/use-submit-button.d.ts.map +1 -0
  77. package/dist/index.d.ts +24 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.mjs +1764 -0
  80. package/dist/index.mjs.map +1 -0
  81. package/dist/style.css +791 -0
  82. package/dist/type.d.ts +3 -0
  83. package/dist/type.d.ts.map +1 -0
  84. package/dist/types/index.d.ts +2 -0
  85. package/dist/types/index.d.ts.map +1 -0
  86. package/dist/types/option.d.ts +40 -0
  87. package/dist/types/option.d.ts.map +1 -0
  88. package/dist/vue.d.ts +20 -0
  89. package/dist/vue.d.ts.map +1 -0
  90. package/package.json +68 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,1764 @@
1
+ import { installDefaultsManager, installThemeManager, useComponentDefaults, useComponentTheme, useId } from "@vuecs/core";
2
+ import { CheckboxGroupRoot, CheckboxIndicator, CheckboxRoot, NumberFieldDecrement, NumberFieldIncrement, NumberFieldInput, NumberFieldRoot, PinInputInput, PinInputRoot, RadioGroupIndicator, RadioGroupItem, RadioGroupRoot, SelectContent, SelectGroup, SelectIcon, SelectItem, SelectItemIndicator, SelectItemText, SelectLabel, SelectPortal, SelectRoot, SelectTrigger, SelectValue, SelectViewport, SliderRange, SliderRoot, SliderThumb, SliderTrack, SwitchRoot, SwitchThumb, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from "reka-ui";
3
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, h, mergeProps, normalizeClass, openBlock, ref, renderList, renderSlot, resolveComponent, toDisplayString, toRef, toValue, vModelText, vShow, watch, withCtx, withDirectives } from "vue";
4
+ import { onClickOutside, useDebounceFn, useInfiniteScroll } from "@vueuse/core";
5
+ //#region src/components/form-checkbox/FormCheckbox.vue?vue&type=script&lang.ts
6
+ const formCheckboxThemeDefaults = { classes: {
7
+ root: "vc-form-checkbox",
8
+ indicator: "vc-form-checkbox-indicator",
9
+ label: "vc-form-checkbox-label",
10
+ group: "vc-form-checkbox-wrapper"
11
+ } };
12
+ const behavioralDefaults$4 = { labelContent: "Input" };
13
+ //#endregion
14
+ //#region src/components/form-checkbox/FormCheckbox.vue
15
+ var FormCheckbox_default = defineComponent({
16
+ name: "VCFormCheckbox",
17
+ inheritAttrs: false,
18
+ props: {
19
+ /** Controlled checked state. `null` is accepted as the documented "unset" value. */
20
+ modelValue: {
21
+ type: [
22
+ Boolean,
23
+ String,
24
+ null
25
+ ],
26
+ default: void 0
27
+ },
28
+ /** Form-submission value when the checkbox is checked. */
29
+ value: {
30
+ type: [
31
+ String,
32
+ Number,
33
+ Boolean,
34
+ Object
35
+ ],
36
+ default: "on"
37
+ },
38
+ /** When `true`, prevents the user from interacting with the checkbox. */
39
+ disabled: {
40
+ type: Boolean,
41
+ default: false
42
+ },
43
+ /** Marks the underlying form field as required. */
44
+ required: {
45
+ type: Boolean,
46
+ default: false
47
+ },
48
+ /** Form-field name for HTML form submission. */
49
+ name: {
50
+ type: String,
51
+ default: void 0
52
+ },
53
+ /** Element id; falls back to an SSR-safe generated id. */
54
+ id: {
55
+ type: String,
56
+ default: void 0
57
+ },
58
+ /** Vuecs convention: render the label by default. Internal control flow, not forwarded to Reka. */
59
+ label: {
60
+ type: Boolean,
61
+ default: true
62
+ },
63
+ /** Default label text (resolved through DefaultsManager). */
64
+ labelContent: {
65
+ type: String,
66
+ default: void 0
67
+ },
68
+ /** Theme-class overrides for this component instance. */
69
+ themeClass: {
70
+ type: Object,
71
+ default: void 0
72
+ },
73
+ /** Theme variant values for this component instance. */
74
+ themeVariant: {
75
+ type: Object,
76
+ default: void 0
77
+ }
78
+ },
79
+ emits: ["update:modelValue"],
80
+ slots: Object,
81
+ setup(props, { attrs, emit, slots }) {
82
+ const theme = useComponentTheme("formCheckbox", props, formCheckboxThemeDefaults);
83
+ const defaults = useComponentDefaults("formCheckbox", props, behavioralDefaults$4);
84
+ const fallbackId = useId(void 0, "vc-form-checkbox");
85
+ return () => {
86
+ const resolved = theme.value;
87
+ const resolvedDefaults = defaults.value;
88
+ const id = props.id ?? fallbackId;
89
+ const checkbox = h(CheckboxRoot, mergeProps(attrs, {
90
+ id,
91
+ value: props.value,
92
+ name: props.name,
93
+ modelValue: props.modelValue,
94
+ disabled: props.disabled,
95
+ required: props.required,
96
+ "onUpdate:modelValue": (value) => emit("update:modelValue", value),
97
+ class: resolved.root || void 0
98
+ }), { default: () => h(CheckboxIndicator, { class: resolved.indicator || void 0 }, { default: () => slots.indicator?.({ class: resolved.indicator }) ?? "" }) });
99
+ if (!props.label) return checkbox;
100
+ const labelNode = slots.label ? slots.label({
101
+ class: resolved.label,
102
+ id
103
+ }) : h("label", {
104
+ class: resolved.label || void 0,
105
+ for: id
106
+ }, [resolvedDefaults.labelContent]);
107
+ return h("div", { class: resolved.group || void 0 }, [checkbox, labelNode]);
108
+ };
109
+ }
110
+ });
111
+ //#endregion
112
+ //#region src/components/form-checkbox-group/FormCheckboxGroup.vue?vue&type=script&lang.ts
113
+ const formCheckboxGroupThemeDefaults = { classes: { root: "vc-form-checkbox-group" } };
114
+ //#endregion
115
+ //#region src/components/form-checkbox-group/FormCheckboxGroup.vue
116
+ var FormCheckboxGroup_default = defineComponent({
117
+ name: "VCFormCheckboxGroup",
118
+ inheritAttrs: false,
119
+ props: {
120
+ /** Controlled array of selected values. */
121
+ modelValue: {
122
+ type: Array,
123
+ default: void 0
124
+ },
125
+ /** Disables every checkbox in the group. */
126
+ disabled: {
127
+ type: Boolean,
128
+ default: false
129
+ },
130
+ /** Marks the group as required for native form validation. */
131
+ required: {
132
+ type: Boolean,
133
+ default: false
134
+ },
135
+ /** Form-field name for HTML form submission. */
136
+ name: {
137
+ type: String,
138
+ default: void 0
139
+ },
140
+ /** Vuecs convention: vertical-stacked layout (Reka leaves this unset; the column layout is what `vc-form-checkbox-group` styles for). */
141
+ orientation: {
142
+ type: String,
143
+ default: "vertical"
144
+ },
145
+ /** Vuecs convention: arrow-key navigation wraps (Reka has no default). */
146
+ loop: {
147
+ type: Boolean,
148
+ default: true
149
+ },
150
+ /** When `false`, disables roving focus on group items. */
151
+ rovingFocus: {
152
+ type: Boolean,
153
+ default: true
154
+ },
155
+ /** Theme-class overrides for this component instance. */
156
+ themeClass: {
157
+ type: Object,
158
+ default: void 0
159
+ },
160
+ /** Theme variant values for this component instance. */
161
+ themeVariant: {
162
+ type: Object,
163
+ default: void 0
164
+ }
165
+ },
166
+ emits: ["update:modelValue"],
167
+ setup(props, { attrs, emit, slots }) {
168
+ const theme = useComponentTheme("formCheckboxGroup", props, formCheckboxGroupThemeDefaults);
169
+ return () => h(CheckboxGroupRoot, mergeProps(attrs, {
170
+ name: props.name,
171
+ orientation: props.orientation,
172
+ loop: props.loop,
173
+ modelValue: props.modelValue,
174
+ disabled: props.disabled,
175
+ required: props.required,
176
+ rovingFocus: props.rovingFocus,
177
+ "onUpdate:modelValue": (value) => emit("update:modelValue", value),
178
+ class: theme.value.root || void 0
179
+ }), { default: () => slots.default?.() });
180
+ }
181
+ });
182
+ //#endregion
183
+ //#region src/components/constants.ts
184
+ let ValidationSeverity = /* @__PURE__ */ function(ValidationSeverity) {
185
+ ValidationSeverity["ERROR"] = "error";
186
+ ValidationSeverity["WARNING"] = "warning";
187
+ return ValidationSeverity;
188
+ }({});
189
+ //#endregion
190
+ //#region src/components/validation-group/ValidationGroup.vue?vue&type=script&lang.ts
191
+ const validationGroupThemeDefaults = { classes: { item: "form-group-hint group-required" } };
192
+ //#endregion
193
+ //#region src/components/validation-group/ValidationGroup.vue
194
+ var ValidationGroup_default = defineComponent({
195
+ name: "VCValidationGroup",
196
+ props: {
197
+ /** Severity used to colour the rendered messages (`error` / `warning`). */
198
+ severity: {
199
+ type: String,
200
+ default: "error"
201
+ },
202
+ /** Validation messages — keyed object or ordered array of `{ key, value }`. */
203
+ messages: {
204
+ type: [Object, Array],
205
+ default: () => ({})
206
+ },
207
+ /** HTML tag used for each rendered message. */
208
+ itemTag: {
209
+ type: String,
210
+ default: "div"
211
+ },
212
+ /** Theme-class overrides for this component instance. */
213
+ themeClass: {
214
+ type: Object,
215
+ default: void 0
216
+ },
217
+ /** Theme variant values for this component instance. */
218
+ themeVariant: {
219
+ type: Object,
220
+ default: void 0
221
+ }
222
+ },
223
+ slots: Object,
224
+ setup(props, { slots }) {
225
+ const theme = useComponentTheme("validationGroup", props, validationGroupThemeDefaults);
226
+ return () => {
227
+ const resolved = theme.value;
228
+ let errors;
229
+ if (Array.isArray(props.messages)) errors = props.messages;
230
+ else {
231
+ errors = [];
232
+ const keys = Object.keys(props.messages);
233
+ for (const key of keys) errors.push({
234
+ key,
235
+ value: props.messages[key]
236
+ });
237
+ }
238
+ if (slots.default) return slots.default({
239
+ data: errors,
240
+ severity: props.severity,
241
+ itemClass: resolved.item,
242
+ itemTag: props.itemTag
243
+ });
244
+ const children = [];
245
+ for (const error of errors) if (slots.item) children.push(slots.item({
246
+ key: error.key,
247
+ value: error.value,
248
+ class: resolved.item,
249
+ tag: props.itemTag,
250
+ severity: props.severity
251
+ }));
252
+ else children.push(h(props.itemTag, { class: resolved.item || void 0 }, [error.value]));
253
+ return children;
254
+ };
255
+ }
256
+ });
257
+ //#endregion
258
+ //#region src/components/form-group/FormGroup.vue?vue&type=script&lang.ts
259
+ const formGroupThemeDefaults = { classes: {
260
+ root: "",
261
+ label: "",
262
+ hint: "",
263
+ validationError: "",
264
+ validationWarning: ""
265
+ } };
266
+ const behavioralDefaults$3 = { validation: true };
267
+ //#endregion
268
+ //#region src/components/form-group/FormGroup.vue
269
+ var FormGroup_default = defineComponent({
270
+ name: "VCFormGroup",
271
+ inheritAttrs: false,
272
+ props: {
273
+ /** When `true`/`false`, force-render or hide the label. When `undefined`, label visibility follows slot/content presence. */
274
+ label: {
275
+ type: Boolean,
276
+ default: void 0
277
+ },
278
+ /** HTML tag used for the label element. */
279
+ labelTag: {
280
+ type: String,
281
+ default: "label"
282
+ },
283
+ /** Default text rendered when no `label` slot is provided. */
284
+ labelContent: {
285
+ type: String,
286
+ default: void 0
287
+ },
288
+ /** When `true`/`false`, force-render or hide the hint. When `undefined`, hint visibility follows slot/content presence. */
289
+ hint: {
290
+ type: Boolean,
291
+ default: void 0
292
+ },
293
+ /** HTML tag used for the hint element. */
294
+ hintTag: {
295
+ type: String,
296
+ default: "div"
297
+ },
298
+ /** Default text rendered when no `hint` slot is provided. */
299
+ hintContent: {
300
+ type: String,
301
+ default: void 0
302
+ },
303
+ /** When `true`, render the validation messages section. Falls back to the global `formGroup.validation` default. */
304
+ validation: {
305
+ type: Boolean,
306
+ default: void 0
307
+ },
308
+ /** Severity used to colour the validation messages (`error` / `warning`). */
309
+ validationSeverity: {
310
+ type: String,
311
+ default: void 0
312
+ },
313
+ /** Validation messages — keyed object or ordered array of `{ key, value }`. */
314
+ validationMessages: {
315
+ type: [Object, Array],
316
+ default: void 0
317
+ },
318
+ /** Theme-class overrides for this component instance. */
319
+ themeClass: {
320
+ type: Object,
321
+ default: void 0
322
+ },
323
+ /** Theme variant values for this component instance. */
324
+ themeVariant: {
325
+ type: Object,
326
+ default: void 0
327
+ }
328
+ },
329
+ slots: Object,
330
+ setup(props, { attrs, slots }) {
331
+ const theme = useComponentTheme("formGroup", props, formGroupThemeDefaults);
332
+ const defaults = useComponentDefaults("formGroup", props, behavioralDefaults$3);
333
+ return () => {
334
+ const resolved = theme.value;
335
+ const resolvedDefaults = defaults.value;
336
+ const children = [];
337
+ if (typeof props.label === "boolean" ? props.label : !!props.labelContent || !!slots.label) {
338
+ if (slots.label) children.push(h(props.labelTag, { class: resolved.label || void 0 }, slots.label({})));
339
+ else if (props.labelContent) children.push(h(props.labelTag, { class: resolved.label || void 0 }, [props.labelContent]));
340
+ }
341
+ if (slots.default) children.push(slots.default({}));
342
+ if (resolvedDefaults.validation) children.push(h(ValidationGroup_default, {
343
+ severity: props.validationSeverity,
344
+ messages: props.validationMessages || {}
345
+ }, {
346
+ ...slots.validationGroup ? { default: slots.validationGroup } : {},
347
+ ...slots.validationItem ? { item: slots.validationItem } : {}
348
+ }));
349
+ if (typeof props.hint === "boolean" ? props.hint : !!props.hintContent || !!slots.hint) {
350
+ if (slots.hint) children.push(h(props.hintTag, { class: resolved.hint || void 0 }, slots.hint({})));
351
+ else if (props.hintContent) children.push(h(props.hintTag, { class: resolved.hint || void 0 }, [props.hintContent]));
352
+ }
353
+ let validationClass;
354
+ if (resolvedDefaults.validation && props.validationMessages) {
355
+ if (Array.isArray(props.validationMessages) ? props.validationMessages.length > 0 : Object.keys(props.validationMessages).length > 0) validationClass = props.validationSeverity === "warning" ? resolved.validationWarning : resolved.validationError;
356
+ }
357
+ return h("div", mergeProps(attrs, { class: [resolved.root || void 0, validationClass || void 0] }), children);
358
+ };
359
+ }
360
+ });
361
+ //#endregion
362
+ //#region src/components/form-input/FormInput.vue?vue&type=script&lang.ts
363
+ const formInputThemeDefaults = { classes: {
364
+ root: "vc-form-input",
365
+ group: "vc-form-input-group",
366
+ groupAppend: "vc-form-input-group-append",
367
+ groupPrepend: "vc-form-input-group-prepend"
368
+ } };
369
+ //#endregion
370
+ //#region src/components/form-input/FormInput.vue
371
+ var FormInput_default = defineComponent({
372
+ name: "VCFormInput",
373
+ inheritAttrs: false,
374
+ props: {
375
+ /** Controlled string value (v-model). */
376
+ modelValue: {
377
+ type: String,
378
+ default: ""
379
+ },
380
+ /** Native `<input type>` attribute. */
381
+ type: {
382
+ type: String,
383
+ default: "text"
384
+ },
385
+ /** Force-render the input-group wrapper even without prepend/append content. */
386
+ group: {
387
+ type: Boolean,
388
+ default: false
389
+ },
390
+ /** When `true`, render a prepended group element using `groupPrependContent` (or the `groupPrepend` slot). */
391
+ groupPrepend: {
392
+ type: Boolean,
393
+ default: false
394
+ },
395
+ /** Default text/HTML rendered inside the prepend slot. */
396
+ groupPrependContent: {
397
+ type: String,
398
+ default: void 0
399
+ },
400
+ /** When `true`, render an appended group element using `groupAppendContent` (or the `groupAppend` slot). */
401
+ groupAppend: {
402
+ type: Boolean,
403
+ default: false
404
+ },
405
+ /** Default text/HTML rendered inside the append slot. */
406
+ groupAppendContent: {
407
+ type: String,
408
+ default: void 0
409
+ },
410
+ /** Debounce window (ms) for `update:modelValue` emissions. `0` disables debouncing. */
411
+ debounce: {
412
+ type: Number,
413
+ default: 0
414
+ },
415
+ /** Theme-class overrides for this component instance. */
416
+ themeClass: {
417
+ type: Object,
418
+ default: void 0
419
+ },
420
+ /** Theme variant values for this component instance. */
421
+ themeVariant: {
422
+ type: Object,
423
+ default: void 0
424
+ }
425
+ },
426
+ emits: ["update:modelValue"],
427
+ slots: Object,
428
+ setup(props, { attrs, emit, slots }) {
429
+ const theme = useComponentTheme("formInput", props, formInputThemeDefaults);
430
+ const localValue = ref(props.modelValue);
431
+ watch(() => props.modelValue, (value) => {
432
+ localValue.value = value;
433
+ });
434
+ const emitUpdate = (value) => emit("update:modelValue", value);
435
+ const emitUpdateDebounced = useDebounceFn(emitUpdate, () => props.debounce);
436
+ const onInput = ($event) => {
437
+ const target = $event.target;
438
+ if (target.composing) return;
439
+ const { value } = target;
440
+ localValue.value = value;
441
+ if (props.debounce > 0) emitUpdateDebounced(value);
442
+ else emitUpdate(value);
443
+ };
444
+ return () => {
445
+ const resolved = theme.value;
446
+ const children = [];
447
+ if (slots.groupPrepend) children.push(slots.groupPrepend({
448
+ class: resolved.groupPrepend,
449
+ tag: "div"
450
+ }));
451
+ else if (props.groupPrepend) children.push(h("div", { class: resolved.groupPrepend || void 0 }, [props.groupPrependContent]));
452
+ children.push(h("input", mergeProps({
453
+ type: props.type,
454
+ class: resolved.root || void 0,
455
+ onInput,
456
+ value: localValue.value
457
+ }, attrs)));
458
+ if (slots.groupAppend) children.push(slots.groupAppend({
459
+ class: resolved.groupAppend,
460
+ tag: "div"
461
+ }));
462
+ else if (props.groupAppend) children.push(h("div", { class: resolved.groupAppend || void 0 }, [props.groupAppendContent]));
463
+ if (children.length > 1 || props.group) return h("div", { class: resolved.group || void 0 }, children);
464
+ return children[0];
465
+ };
466
+ }
467
+ });
468
+ //#endregion
469
+ //#region src/components/form-number/FormNumber.vue?vue&type=script&lang.ts
470
+ const formNumberThemeDefaults = { classes: {
471
+ root: "vc-form-number",
472
+ input: "vc-form-number-input",
473
+ decrement: "vc-form-number-decrement",
474
+ increment: "vc-form-number-increment"
475
+ } };
476
+ //#endregion
477
+ //#region src/components/form-number/FormNumber.vue
478
+ var FormNumber_default = defineComponent({
479
+ name: "VCFormNumber",
480
+ inheritAttrs: false,
481
+ props: {
482
+ /** Controlled numeric value. `null` is the documented "unset" value. */
483
+ modelValue: {
484
+ type: [Number, null],
485
+ default: void 0
486
+ },
487
+ /** Smallest allowed value. */
488
+ min: {
489
+ type: Number,
490
+ default: void 0
491
+ },
492
+ /** Largest allowed value. */
493
+ max: {
494
+ type: Number,
495
+ default: void 0
496
+ },
497
+ /** Increment / decrement step. */
498
+ step: {
499
+ type: Number,
500
+ default: 1
501
+ },
502
+ /** When `true`, snap typed values to the nearest step. */
503
+ stepSnapping: {
504
+ type: Boolean,
505
+ default: true
506
+ },
507
+ /** Vuecs convention: do NOT focus the input on programmatic value change (Reka defaults to `true`; this avoids surprising focus jumps). */
508
+ focusOnChange: {
509
+ type: Boolean,
510
+ default: false
511
+ },
512
+ /** `Intl.NumberFormat` options for display + parsing. */
513
+ formatOptions: {
514
+ type: Object,
515
+ default: void 0
516
+ },
517
+ /** BCP-47 locale used for formatting and currency. */
518
+ locale: {
519
+ type: String,
520
+ default: void 0
521
+ },
522
+ /** When `true`, prevents the user from interacting with the field. */
523
+ disabled: {
524
+ type: Boolean,
525
+ default: false
526
+ },
527
+ /** Marks the underlying form field as required. */
528
+ required: {
529
+ type: Boolean,
530
+ default: false
531
+ },
532
+ /** Form-field name for HTML form submission. */
533
+ name: {
534
+ type: String,
535
+ default: void 0
536
+ },
537
+ /** Element id for the root number field. */
538
+ id: {
539
+ type: String,
540
+ default: void 0
541
+ },
542
+ /** Vuecs internal: show ± stepper buttons. Drives the in-template render branch; not forwarded to Reka. */
543
+ steppers: {
544
+ type: Boolean,
545
+ default: true
546
+ },
547
+ /** Theme-class overrides for this component instance. */
548
+ themeClass: {
549
+ type: Object,
550
+ default: void 0
551
+ },
552
+ /** Theme variant values for this component instance. */
553
+ themeVariant: {
554
+ type: Object,
555
+ default: void 0
556
+ }
557
+ },
558
+ emits: ["update:modelValue"],
559
+ setup(props, { attrs, emit }) {
560
+ const theme = useComponentTheme("formNumber", props, formNumberThemeDefaults);
561
+ return () => h(NumberFieldRoot, mergeProps(attrs, {
562
+ focusOnChange: props.focusOnChange,
563
+ name: props.name,
564
+ id: props.id,
565
+ modelValue: props.modelValue,
566
+ min: props.min,
567
+ max: props.max,
568
+ step: props.step,
569
+ stepSnapping: props.stepSnapping,
570
+ formatOptions: props.formatOptions,
571
+ locale: props.locale,
572
+ disabled: props.disabled,
573
+ required: props.required,
574
+ "onUpdate:modelValue": (value) => emit("update:modelValue", value),
575
+ class: theme.value.root || void 0
576
+ }), { default: () => {
577
+ const children = [];
578
+ if (props.steppers) children.push(h(NumberFieldDecrement, { class: theme.value.decrement || void 0 }, { default: () => "−" }));
579
+ children.push(h(NumberFieldInput, { class: theme.value.input || void 0 }));
580
+ if (props.steppers) children.push(h(NumberFieldIncrement, { class: theme.value.increment || void 0 }, { default: () => "+" }));
581
+ return children;
582
+ } });
583
+ }
584
+ });
585
+ //#endregion
586
+ //#region src/components/form-pin/FormPin.vue?vue&type=script&lang.ts
587
+ const formPinThemeDefaults = { classes: {
588
+ root: "vc-form-pin",
589
+ input: "vc-form-pin-input"
590
+ } };
591
+ //#endregion
592
+ //#region src/components/form-pin/FormPin.vue
593
+ var FormPin_default = defineComponent({
594
+ name: "VCFormPin",
595
+ inheritAttrs: false,
596
+ props: {
597
+ /** Controlled value (per-cell array). `null` is accepted as the documented "unset" value. */
598
+ modelValue: {
599
+ type: [Array, null],
600
+ default: void 0
601
+ },
602
+ /** Vuecs internal: number of input cells rendered. Drives the cell-render loop in setup; not forwarded to Reka. */
603
+ length: {
604
+ type: Number,
605
+ default: 6
606
+ },
607
+ /** Input type for each cell. Drives `inputmode` and modelValue array element type. */
608
+ type: {
609
+ type: String,
610
+ default: "text"
611
+ },
612
+ /** Per-cell placeholder character. */
613
+ placeholder: {
614
+ type: String,
615
+ default: ""
616
+ },
617
+ /** When `true`, render values as `<input type="password">` (dots). */
618
+ mask: {
619
+ type: Boolean,
620
+ default: false
621
+ },
622
+ /** Enable mobile OTP autofill (sets `autocomplete="one-time-code"`). */
623
+ otp: {
624
+ type: Boolean,
625
+ default: false
626
+ },
627
+ /** When `true`, prevents the user from interacting with the pin input. */
628
+ disabled: {
629
+ type: Boolean,
630
+ default: false
631
+ },
632
+ /** Marks the underlying form field as required. */
633
+ required: {
634
+ type: Boolean,
635
+ default: false
636
+ },
637
+ /** Form-field name for HTML form submission. */
638
+ name: {
639
+ type: String,
640
+ default: void 0
641
+ },
642
+ /** Element id for the root pin input. */
643
+ id: {
644
+ type: String,
645
+ default: void 0
646
+ },
647
+ /** Theme-class overrides for this component instance. */
648
+ themeClass: {
649
+ type: Object,
650
+ default: void 0
651
+ },
652
+ /** Theme variant values for this component instance. */
653
+ themeVariant: {
654
+ type: Object,
655
+ default: void 0
656
+ }
657
+ },
658
+ emits: ["update:modelValue", "complete"],
659
+ setup(props, { attrs, emit }) {
660
+ const theme = useComponentTheme("formPin", props, formPinThemeDefaults);
661
+ return () => h(PinInputRoot, mergeProps(attrs, {
662
+ name: props.name,
663
+ id: props.id,
664
+ modelValue: props.modelValue,
665
+ type: props.type,
666
+ placeholder: props.placeholder,
667
+ mask: props.mask,
668
+ otp: props.otp,
669
+ disabled: props.disabled,
670
+ required: props.required,
671
+ "onUpdate:modelValue": (value) => emit("update:modelValue", value),
672
+ onComplete: (value) => emit("complete", value),
673
+ class: theme.value.root || void 0
674
+ }), { default: () => {
675
+ const cells = [];
676
+ for (let i = 0; i < props.length; i += 1) cells.push(h(PinInputInput, {
677
+ key: i,
678
+ index: i,
679
+ class: theme.value.input || void 0
680
+ }));
681
+ return cells;
682
+ } });
683
+ }
684
+ });
685
+ //#endregion
686
+ //#region src/components/form-radio/FormRadio.vue?vue&type=script&lang.ts
687
+ const formRadioThemeDefaults = { classes: {
688
+ root: "vc-form-radio",
689
+ indicator: "vc-form-radio-indicator",
690
+ label: "vc-form-radio-label",
691
+ group: "vc-form-radio-wrapper"
692
+ } };
693
+ const behavioralDefaults$2 = { labelContent: "Option" };
694
+ //#endregion
695
+ //#region src/components/form-radio/FormRadio.vue
696
+ var FormRadio_default = defineComponent({
697
+ name: "VCFormRadio",
698
+ inheritAttrs: false,
699
+ props: {
700
+ /** Form-submission value identifying this radio option. */
701
+ value: {
702
+ type: [
703
+ String,
704
+ Number,
705
+ Boolean,
706
+ Object,
707
+ null
708
+ ],
709
+ required: true
710
+ },
711
+ /** When `true`, prevents the user from interacting with the radio. */
712
+ disabled: {
713
+ type: Boolean,
714
+ default: false
715
+ },
716
+ /** Marks the underlying form field as required. */
717
+ required: {
718
+ type: Boolean,
719
+ default: false
720
+ },
721
+ /** Element id; falls back to an SSR-safe generated id. */
722
+ id: {
723
+ type: String,
724
+ default: void 0
725
+ },
726
+ /** Vuecs convention: render the label by default. Internal control flow, not forwarded to Reka. */
727
+ label: {
728
+ type: Boolean,
729
+ default: true
730
+ },
731
+ /** Default label text (resolved through DefaultsManager). */
732
+ labelContent: {
733
+ type: String,
734
+ default: void 0
735
+ },
736
+ /** Theme-class overrides for this component instance. */
737
+ themeClass: {
738
+ type: Object,
739
+ default: void 0
740
+ },
741
+ /** Theme variant values for this component instance. */
742
+ themeVariant: {
743
+ type: Object,
744
+ default: void 0
745
+ }
746
+ },
747
+ slots: Object,
748
+ setup(props, { attrs, slots }) {
749
+ const theme = useComponentTheme("formRadio", props, formRadioThemeDefaults);
750
+ const defaults = useComponentDefaults("formRadio", props, behavioralDefaults$2);
751
+ const fallbackId = useId(void 0, "vc-form-radio");
752
+ return () => {
753
+ const resolved = theme.value;
754
+ const resolvedDefaults = defaults.value;
755
+ const id = props.id ?? fallbackId;
756
+ const radio = h(RadioGroupItem, mergeProps(attrs, {
757
+ id,
758
+ value: props.value,
759
+ disabled: props.disabled,
760
+ required: props.required,
761
+ class: resolved.root || void 0
762
+ }), { default: () => h(RadioGroupIndicator, { class: resolved.indicator || void 0 }, { default: () => slots.indicator?.({ class: resolved.indicator }) ?? "" }) });
763
+ if (!props.label) return radio;
764
+ const labelNode = slots.label ? slots.label({
765
+ class: resolved.label,
766
+ id
767
+ }) : h("label", {
768
+ class: resolved.label || void 0,
769
+ for: id
770
+ }, [resolvedDefaults.labelContent]);
771
+ return h("div", { class: resolved.group || void 0 }, [radio, labelNode]);
772
+ };
773
+ }
774
+ });
775
+ //#endregion
776
+ //#region src/components/form-radio-group/FormRadioGroup.vue?vue&type=script&lang.ts
777
+ const formRadioGroupThemeDefaults = { classes: { root: "vc-form-radio-group" } };
778
+ //#endregion
779
+ //#region src/components/form-radio-group/FormRadioGroup.vue
780
+ var FormRadioGroup_default = defineComponent({
781
+ name: "VCFormRadioGroup",
782
+ inheritAttrs: false,
783
+ props: {
784
+ /** Controlled selected value. */
785
+ modelValue: {
786
+ type: [
787
+ String,
788
+ Number,
789
+ Boolean,
790
+ Object,
791
+ null
792
+ ],
793
+ default: void 0
794
+ },
795
+ /** Optional declarative shorthand — when set, renders one `<VCFormRadio>` per option. Mutually exclusive with the default slot. */
796
+ options: {
797
+ type: Array,
798
+ default: void 0
799
+ },
800
+ /** Disables every radio in the group. */
801
+ disabled: {
802
+ type: Boolean,
803
+ default: false
804
+ },
805
+ /** Marks the group as required for native form validation. */
806
+ required: {
807
+ type: Boolean,
808
+ default: false
809
+ },
810
+ /** Form-field name for HTML form submission. */
811
+ name: {
812
+ type: String,
813
+ default: void 0
814
+ },
815
+ /** Vuecs convention: vertical-stacked layout (Reka leaves this unset; vuecs styles the column variant in `vc-form-radio-group`). */
816
+ orientation: {
817
+ type: String,
818
+ default: "vertical"
819
+ },
820
+ /** When `true`, arrow-key navigation wraps from last to first item. */
821
+ loop: {
822
+ type: Boolean,
823
+ default: true
824
+ },
825
+ /** Theme-class overrides for this component instance. */
826
+ themeClass: {
827
+ type: Object,
828
+ default: void 0
829
+ },
830
+ /** Theme variant values for this component instance. */
831
+ themeVariant: {
832
+ type: Object,
833
+ default: void 0
834
+ }
835
+ },
836
+ emits: ["update:modelValue"],
837
+ setup(props, { attrs, emit, slots }) {
838
+ const theme = useComponentTheme("formRadioGroup", props, formRadioGroupThemeDefaults);
839
+ return () => h(RadioGroupRoot, mergeProps(attrs, {
840
+ name: props.name,
841
+ orientation: props.orientation,
842
+ modelValue: props.modelValue,
843
+ disabled: props.disabled,
844
+ required: props.required,
845
+ loop: props.loop,
846
+ "onUpdate:modelValue": (value) => emit("update:modelValue", value),
847
+ class: theme.value.root || void 0
848
+ }), { default: () => {
849
+ if (props.options) return props.options.map((option) => h(FormRadio_default, {
850
+ key: String(option.value),
851
+ value: option.value,
852
+ disabled: option.disabled,
853
+ labelContent: option.label
854
+ }));
855
+ return slots.default?.();
856
+ } });
857
+ }
858
+ });
859
+ //#endregion
860
+ //#region src/types/option.ts
861
+ /** Type guard for narrowing in render code. */
862
+ const isFormOptionGroup = (item) => Array.isArray(item.options);
863
+ //#endregion
864
+ //#region src/components/form-select/FormSelect.vue?vue&type=script&lang.ts
865
+ const formSelectThemeDefaults = { classes: {
866
+ trigger: "vc-form-select-trigger",
867
+ value: "vc-form-select-value",
868
+ icon: "vc-form-select-icon",
869
+ content: "vc-form-select-content",
870
+ viewport: "vc-form-select-viewport",
871
+ item: "vc-form-select-item",
872
+ itemIndicator: "vc-form-select-item-indicator",
873
+ group: "vc-form-select-group",
874
+ groupLabel: "vc-form-select-group-label",
875
+ separator: "vc-form-select-separator"
876
+ } };
877
+ const behavioralDefaults$1 = { placeholder: "" };
878
+ const renderItem = (option, classes, groupDisabled = false) => h(SelectItem, {
879
+ key: String(option.value),
880
+ value: option.value,
881
+ disabled: groupDisabled || option.disabled,
882
+ class: classes.item
883
+ }, { default: () => [h(SelectItemText, null, () => [option.label]), h(SelectItemIndicator, { class: classes.itemIndicator }, () => "✓")] });
884
+ const renderGroup = (group, classes) => h(SelectGroup, {
885
+ key: group.label,
886
+ class: classes.group
887
+ }, { default: () => [h(SelectLabel, { class: classes.groupLabel }, () => [group.label]), ...group.options.map((option) => renderItem(option, classes, !!group.disabled))] });
888
+ //#endregion
889
+ //#region src/components/form-select/FormSelect.vue
890
+ var FormSelect_default = defineComponent({
891
+ name: "VCFormSelect",
892
+ inheritAttrs: false,
893
+ props: {
894
+ /** Controlled selected value. */
895
+ modelValue: {
896
+ type: [
897
+ String,
898
+ Number,
899
+ Boolean,
900
+ Object,
901
+ null
902
+ ],
903
+ default: void 0
904
+ },
905
+ /** Options rendered inside the dropdown (flat list or grouped). */
906
+ options: {
907
+ type: Array,
908
+ required: true
909
+ },
910
+ /** Placeholder text rendered inside the trigger when no option is selected. Falls back to the global `formSelect.placeholder` default. */
911
+ placeholder: {
912
+ type: String,
913
+ default: void 0
914
+ },
915
+ /** When `true`, blocks user interaction with the trigger. */
916
+ disabled: {
917
+ type: Boolean,
918
+ default: false
919
+ },
920
+ /** `name` attribute submitted with the owning form. */
921
+ name: {
922
+ type: String,
923
+ default: void 0
924
+ },
925
+ /** When `true`, the field must be set before the owning form can submit. */
926
+ required: {
927
+ type: Boolean,
928
+ default: false
929
+ },
930
+ /** Theme-class overrides for this component instance. */
931
+ themeClass: {
932
+ type: Object,
933
+ default: void 0
934
+ },
935
+ /** Theme variant values for this component instance. */
936
+ themeVariant: {
937
+ type: Object,
938
+ default: void 0
939
+ }
940
+ },
941
+ emits: ["update:modelValue"],
942
+ setup(props, { attrs, emit }) {
943
+ const theme = useComponentTheme("formSelect", props, formSelectThemeDefaults);
944
+ const defaults = useComponentDefaults("formSelect", props, behavioralDefaults$1);
945
+ return () => {
946
+ const resolved = theme.value;
947
+ const { placeholder } = defaults.value;
948
+ const items = [];
949
+ for (const item of props.options) if (isFormOptionGroup(item)) items.push(renderGroup(item, resolved));
950
+ else items.push(renderItem(item, resolved));
951
+ return h(SelectRoot, {
952
+ name: props.name,
953
+ modelValue: props.modelValue,
954
+ disabled: props.disabled,
955
+ required: props.required,
956
+ "onUpdate:modelValue"(value) {
957
+ emit("update:modelValue", value);
958
+ }
959
+ }, { default: () => [h(SelectTrigger, mergeProps({ class: resolved.trigger || void 0 }, attrs), () => [h(SelectValue, {
960
+ class: resolved.value || void 0,
961
+ placeholder
962
+ }), h(SelectIcon, { class: resolved.icon || void 0 }, () => "▾")]), h(SelectPortal, null, () => [h(SelectContent, {
963
+ class: resolved.content || void 0,
964
+ position: "popper"
965
+ }, () => [h(SelectViewport, { class: resolved.viewport || void 0 }, () => items)])])] });
966
+ };
967
+ }
968
+ });
969
+ var FormSelectSearchEntry_vue_vue_type_script_lang_default = defineComponent({
970
+ props: {
971
+ /** The option this row represents. */
972
+ entry: {
973
+ type: Object,
974
+ required: true
975
+ },
976
+ /** The currently-selected options — used to compute `active` state. */
977
+ selected: { type: Array }
978
+ },
979
+ setup(props) {
980
+ return { active: computed(() => props.selected && props.selected.findIndex((el) => el.value === props.entry.value) !== -1) };
981
+ }
982
+ });
983
+ //#endregion
984
+ //#region \0plugin-vue:export-helper
985
+ var _plugin_vue_export_helper_default = (sfc, props) => {
986
+ const target = sfc.__vccOpts || sfc;
987
+ for (const [key, val] of props) target[key] = val;
988
+ return target;
989
+ };
990
+ //#endregion
991
+ //#region src/components/form-select-search/FormSelectSearchEntry.vue
992
+ function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
993
+ return renderSlot(_ctx.$slots, "default", {
994
+ entry: _ctx.entry,
995
+ active: _ctx.active
996
+ }, () => [createTextVNode(toDisplayString(_ctx.entry.label), 1)]);
997
+ }
998
+ var FormSelectSearchEntry_default = /* @__PURE__ */ _plugin_vue_export_helper_default(FormSelectSearchEntry_vue_vue_type_script_lang_default, [["render", _sfc_render$1]]);
999
+ //#endregion
1000
+ //#region src/components/form-select-search/FormSelectSearch.vue?vue&type=script&lang.ts
1001
+ const formSelectSearchThemeDefaults = { classes: {
1002
+ root: "vc-form-select-search",
1003
+ input: "vc-form-select-search-input",
1004
+ content: "vc-form-select-search-content",
1005
+ item: "vc-form-select-search-item",
1006
+ itemActive: "active",
1007
+ itemCurrent: "current",
1008
+ itemDescription: "vc-form-select-search-item-description",
1009
+ selected: "vc-form-select-search-selected",
1010
+ selectedItem: "vc-form-select-search-selected-item",
1011
+ selectedItemRemove: "vc-form-select-search-selected-item-remove"
1012
+ } };
1013
+ var FormSelectSearch_vue_vue_type_script_lang_default = defineComponent({
1014
+ components: { FormSelectSearchEntry: FormSelectSearchEntry_default },
1015
+ props: {
1016
+ /** Controlled selected value(s) — single value or array for multi-select. */
1017
+ modelValue: {
1018
+ type: [
1019
+ String,
1020
+ Number,
1021
+ Boolean,
1022
+ Object,
1023
+ Array,
1024
+ null
1025
+ ],
1026
+ default: void 0
1027
+ },
1028
+ /** Options shown in the dropdown. */
1029
+ options: {
1030
+ type: Array,
1031
+ default: () => []
1032
+ },
1033
+ /** Placeholder shown in the search input when empty. */
1034
+ placeholder: {
1035
+ type: String,
1036
+ required: false,
1037
+ default: "..."
1038
+ },
1039
+ /** When `true`, blocks user interaction with the input and chips. */
1040
+ disabled: {
1041
+ type: Boolean,
1042
+ required: false,
1043
+ default: false
1044
+ },
1045
+ /** Initial page size for the virtualised dropdown list. */
1046
+ maxItems: {
1047
+ type: Number,
1048
+ required: false,
1049
+ default: 10
1050
+ },
1051
+ /** Number of items to append per infinite-scroll step. */
1052
+ scrollDistance: {
1053
+ type: Number,
1054
+ required: false,
1055
+ default: 10
1056
+ },
1057
+ /**
1058
+ * Whether to close the dropdown after a pick. When unset:
1059
+ * - single-select closes (matches the native `<select>` mental model)
1060
+ * - multi-select stays open (so the user can pick several without re-opening)
1061
+ *
1062
+ * Set explicitly (`true` / `false`) to override the mode-default.
1063
+ */
1064
+ closeOnSelect: {
1065
+ type: Boolean,
1066
+ default: void 0
1067
+ },
1068
+ /** Theme-class overrides for this component instance. */
1069
+ themeClass: {
1070
+ type: Object,
1071
+ default: void 0
1072
+ },
1073
+ /** Theme variant values for this component instance. */
1074
+ themeVariant: {
1075
+ type: Object,
1076
+ default: void 0
1077
+ }
1078
+ },
1079
+ emits: ["update:modelValue", "change"],
1080
+ setup(props, { emit }) {
1081
+ const theme = useComponentTheme("formSelectSearch", props, formSelectSearchThemeDefaults);
1082
+ const listElement = ref(null);
1083
+ const inputElement = ref(null);
1084
+ const q = ref("");
1085
+ const currentIndex = ref(-1);
1086
+ const selected = ref([]);
1087
+ const modelValue = toRef(props, "modelValue");
1088
+ const findOption = (value) => props.options.find((option) => option.value === value);
1089
+ const reset = () => {
1090
+ if (Array.isArray(props.modelValue)) {
1091
+ selected.value = props.modelValue.map((value) => findOption(value)).filter((option) => option !== void 0);
1092
+ return;
1093
+ }
1094
+ if (typeof props.modelValue === "undefined" || props.modelValue === null) {
1095
+ selected.value = [];
1096
+ q.value = "";
1097
+ return;
1098
+ }
1099
+ const found = findOption(props.modelValue);
1100
+ if (found) {
1101
+ selected.value = [found];
1102
+ q.value = found.label;
1103
+ } else {
1104
+ selected.value = [];
1105
+ q.value = "";
1106
+ }
1107
+ };
1108
+ reset();
1109
+ watch(modelValue, () => {
1110
+ reset();
1111
+ }, { deep: true });
1112
+ const isMulti = computed(() => Array.isArray(modelValue.value));
1113
+ const items = computed(() => {
1114
+ if (!q.value || q.value.length < 1) return props.options;
1115
+ const escaped = q.value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1116
+ const pattern = new RegExp(escaped, "ig");
1117
+ return props.options.filter((option) => option.label.match(pattern));
1118
+ });
1119
+ const pageSize = computed(() => Math.max(1, props.maxItems));
1120
+ const pageStep = computed(() => Math.max(1, props.scrollDistance));
1121
+ const itemsDisplayed = ref([]);
1122
+ const setItemsDisplayed = () => {
1123
+ itemsDisplayed.value = items.value.slice(0, pageSize.value);
1124
+ };
1125
+ const showMoreItemsDisplayed = () => {
1126
+ const startIndex = itemsDisplayed.value.length;
1127
+ const endIndex = Math.min(startIndex + pageStep.value, items.value.length);
1128
+ if (startIndex >= endIndex) return;
1129
+ itemsDisplayed.value.push(...items.value.slice(startIndex, endIndex));
1130
+ };
1131
+ setItemsDisplayed();
1132
+ watch(items, () => {
1133
+ currentIndex.value = -1;
1134
+ setItemsDisplayed();
1135
+ });
1136
+ useInfiniteScroll(listElement, () => {
1137
+ showMoreItemsDisplayed();
1138
+ }, { canLoadMore() {
1139
+ return itemsDisplayed.value.length < items.value.length;
1140
+ } });
1141
+ const isDisplayed = ref(false);
1142
+ const shouldCloseOnSelect = () => typeof props.closeOnSelect === "boolean" ? props.closeOnSelect : !isMulti.value;
1143
+ const toggle = (option) => {
1144
+ if (props.disabled) return;
1145
+ if (isMulti.value) {
1146
+ const index = selected.value.findIndex((el) => el.value === option.value);
1147
+ if (index === -1) selected.value.push(option);
1148
+ else selected.value.splice(index, 1);
1149
+ const values = selected.value.map((el) => el.value);
1150
+ emit("update:modelValue", values);
1151
+ emit("change", values);
1152
+ if (shouldCloseOnSelect()) isDisplayed.value = false;
1153
+ return;
1154
+ }
1155
+ let isBlank = false;
1156
+ const [selectedValue] = selected.value;
1157
+ if (selectedValue) if (selectedValue.value === option.value) {
1158
+ q.value = "";
1159
+ selected.value.length = 0;
1160
+ isBlank = true;
1161
+ } else {
1162
+ q.value = option.label;
1163
+ selected.value = [option];
1164
+ }
1165
+ else {
1166
+ q.value = option.label;
1167
+ selected.value = [option];
1168
+ }
1169
+ if (shouldCloseOnSelect()) isDisplayed.value = false;
1170
+ if (isBlank) {
1171
+ emit("update:modelValue", null);
1172
+ emit("change", null);
1173
+ return;
1174
+ }
1175
+ emit("update:modelValue", option.value);
1176
+ emit("change", option.value);
1177
+ };
1178
+ const display = () => {
1179
+ if (props.disabled) return;
1180
+ isDisplayed.value = true;
1181
+ };
1182
+ const hide = () => {
1183
+ if (!isMulti.value && selected.value.length === 1) q.value = selected.value[0].label;
1184
+ isDisplayed.value = false;
1185
+ };
1186
+ onClickOutside(listElement, () => {
1187
+ hide();
1188
+ }, { ignore: [inputElement] });
1189
+ const onFocus = () => {
1190
+ q.value = "";
1191
+ display();
1192
+ };
1193
+ const onKeyUp = (ev) => {
1194
+ if (ev.key === "ArrowUp" || ev.key === "ArrowDown") {
1195
+ display();
1196
+ if (ev.key === "ArrowUp") {
1197
+ if (currentIndex.value > 0) currentIndex.value--;
1198
+ return;
1199
+ }
1200
+ if (currentIndex.value < itemsDisplayed.value.length - 1) currentIndex.value++;
1201
+ }
1202
+ if (ev.key !== "Enter") display();
1203
+ };
1204
+ const onKeyDown = (ev) => {
1205
+ if (ev.key === "Enter") {
1206
+ if (!isDisplayed.value) return;
1207
+ if (itemsDisplayed.value.length === 1) {
1208
+ toggle(itemsDisplayed.value[0]);
1209
+ return;
1210
+ }
1211
+ if (currentIndex.value >= 0 && itemsDisplayed.value[currentIndex.value]) {
1212
+ toggle(itemsDisplayed.value[currentIndex.value]);
1213
+ return;
1214
+ }
1215
+ if (selected.value.length === 0) {
1216
+ if (itemsDisplayed.value[0]) toggle(itemsDisplayed.value[0]);
1217
+ return;
1218
+ }
1219
+ hide();
1220
+ return;
1221
+ }
1222
+ if (ev.key === "Tab") hide();
1223
+ };
1224
+ return {
1225
+ theme,
1226
+ listElement,
1227
+ inputElement,
1228
+ isMulti,
1229
+ toggle,
1230
+ currentIndex,
1231
+ q,
1232
+ items: itemsDisplayed,
1233
+ selected,
1234
+ display,
1235
+ onFocus,
1236
+ onKeyUp,
1237
+ onKeyDown,
1238
+ isDisplayed
1239
+ };
1240
+ }
1241
+ });
1242
+ //#endregion
1243
+ //#region src/components/form-select-search/FormSelectSearch.vue
1244
+ const _hoisted_1 = ["disabled", "placeholder"];
1245
+ const _hoisted_2 = ["onMousedown"];
1246
+ const _hoisted_3 = ["disabled", "onClick"];
1247
+ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
1248
+ const _component_FormSelectSearchEntry = resolveComponent("FormSelectSearchEntry");
1249
+ return openBlock(), createElementBlock("div", { class: normalizeClass(_ctx.theme.root) }, [
1250
+ withDirectives(createElementVNode("input", {
1251
+ ref: "inputElement",
1252
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.q = $event),
1253
+ class: normalizeClass(_ctx.theme.input),
1254
+ disabled: _ctx.disabled,
1255
+ placeholder: _ctx.placeholder,
1256
+ onFocus: _cache[1] || (_cache[1] = (...args) => _ctx.onFocus && _ctx.onFocus(...args)),
1257
+ onKeyup: _cache[2] || (_cache[2] = (...args) => _ctx.onKeyUp && _ctx.onKeyUp(...args)),
1258
+ onKeydown: _cache[3] || (_cache[3] = (...args) => _ctx.onKeyDown && _ctx.onKeyDown(...args))
1259
+ }, null, 42, _hoisted_1), [[vModelText, _ctx.q]]),
1260
+ withDirectives(createElementVNode("div", {
1261
+ ref: "listElement",
1262
+ class: normalizeClass(_ctx.theme.content)
1263
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.items, (option, index) => {
1264
+ return openBlock(), createBlock(_component_FormSelectSearchEntry, {
1265
+ key: String(option.value),
1266
+ entry: option,
1267
+ selected: _ctx.selected
1268
+ }, {
1269
+ default: withCtx(({ entry, active }) => [createElementVNode("div", {
1270
+ class: normalizeClass([_ctx.theme.item, {
1271
+ [_ctx.theme.itemActive]: active,
1272
+ [_ctx.theme.itemCurrent]: index === _ctx.currentIndex
1273
+ }]),
1274
+ onMousedown: ($event) => _ctx.toggle(entry)
1275
+ }, [createTextVNode(toDisplayString(entry.label) + " ", 1), entry.description ? (openBlock(), createElementBlock("span", {
1276
+ key: 0,
1277
+ class: normalizeClass(_ctx.theme.itemDescription)
1278
+ }, toDisplayString(entry.description), 3)) : createCommentVNode("v-if", true)], 42, _hoisted_2)]),
1279
+ _: 2
1280
+ }, 1032, ["entry", "selected"]);
1281
+ }), 128))], 2), [[vShow, _ctx.isDisplayed]]),
1282
+ _ctx.isMulti ? (openBlock(), createElementBlock("div", {
1283
+ key: 0,
1284
+ class: normalizeClass(_ctx.theme.selected)
1285
+ }, [renderSlot(_ctx.$slots, "selected", {
1286
+ items: _ctx.selected,
1287
+ toggle: _ctx.toggle
1288
+ }, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.selected, (item) => {
1289
+ return openBlock(), createElementBlock("button", {
1290
+ key: String(item.value),
1291
+ type: "button",
1292
+ class: normalizeClass(_ctx.theme.selectedItem),
1293
+ disabled: _ctx.disabled,
1294
+ onClick: ($event) => _ctx.toggle(item)
1295
+ }, [createTextVNode(toDisplayString(item.label) + " ", 1), createElementVNode("span", {
1296
+ class: normalizeClass(_ctx.theme.selectedItemRemove),
1297
+ "aria-hidden": "true"
1298
+ }, "×", 2)], 10, _hoisted_3);
1299
+ }), 128))])], 2)) : createCommentVNode("v-if", true)
1300
+ ], 2);
1301
+ }
1302
+ var FormSelectSearch_default = /* @__PURE__ */ _plugin_vue_export_helper_default(FormSelectSearch_vue_vue_type_script_lang_default, [["render", _sfc_render]]);
1303
+ //#endregion
1304
+ //#region src/components/form-slider/FormSlider.vue?vue&type=script&lang.ts
1305
+ const formSliderThemeDefaults = { classes: {
1306
+ root: "vc-form-slider",
1307
+ track: "vc-form-slider-track",
1308
+ range: "vc-form-slider-range",
1309
+ thumb: "vc-form-slider-thumb"
1310
+ } };
1311
+ //#endregion
1312
+ //#region src/components/form-slider/FormSlider.vue
1313
+ var FormSlider_default = defineComponent({
1314
+ name: "VCFormSlider",
1315
+ inheritAttrs: false,
1316
+ props: {
1317
+ /** Controlled value — number for single-thumb, array for range / multi-thumb. `null` is the documented "unset" value. */
1318
+ modelValue: {
1319
+ type: [
1320
+ Number,
1321
+ Array,
1322
+ null
1323
+ ],
1324
+ default: void 0
1325
+ },
1326
+ /** Minimum value for the range. */
1327
+ min: {
1328
+ type: Number,
1329
+ default: 0
1330
+ },
1331
+ /** Maximum value for the range. */
1332
+ max: {
1333
+ type: Number,
1334
+ default: 100
1335
+ },
1336
+ /** Stepping interval between values. */
1337
+ step: {
1338
+ type: Number,
1339
+ default: 1
1340
+ },
1341
+ /** Slider axis. */
1342
+ orientation: {
1343
+ type: String,
1344
+ default: "horizontal"
1345
+ },
1346
+ /** When `true`, the slider is visually inverted. */
1347
+ inverted: {
1348
+ type: Boolean,
1349
+ default: false
1350
+ },
1351
+ /** When `true`, prevents the user from interacting with the slider. */
1352
+ disabled: {
1353
+ type: Boolean,
1354
+ default: false
1355
+ },
1356
+ /** Marks the underlying form field as required. */
1357
+ required: {
1358
+ type: Boolean,
1359
+ default: false
1360
+ },
1361
+ /** Form-field name for HTML form submission. */
1362
+ name: {
1363
+ type: String,
1364
+ default: void 0
1365
+ },
1366
+ /** Minimum permitted steps between adjacent thumbs (multi-thumb mode). */
1367
+ minStepsBetweenThumbs: {
1368
+ type: Number,
1369
+ default: 0
1370
+ },
1371
+ /** Theme-class overrides for this component instance. */
1372
+ themeClass: {
1373
+ type: Object,
1374
+ default: void 0
1375
+ },
1376
+ /** Theme variant values for this component instance. */
1377
+ themeVariant: {
1378
+ type: Object,
1379
+ default: void 0
1380
+ }
1381
+ },
1382
+ emits: ["update:modelValue", "valueCommit"],
1383
+ setup(props, { attrs, emit }) {
1384
+ const theme = useComponentTheme("formSlider", props, formSliderThemeDefaults);
1385
+ const isScalar = computed(() => typeof props.modelValue === "number");
1386
+ const internalValue = computed(() => {
1387
+ if (props.modelValue === void 0 || props.modelValue === null) return [props.min];
1388
+ return Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue];
1389
+ });
1390
+ const handleUpdate = (next) => {
1391
+ if (isScalar.value) emit("update:modelValue", next[0]);
1392
+ else emit("update:modelValue", next);
1393
+ };
1394
+ const handleCommit = (next) => {
1395
+ if (isScalar.value) emit("valueCommit", next[0]);
1396
+ else emit("valueCommit", next);
1397
+ };
1398
+ return () => h(SliderRoot, mergeProps(attrs, {
1399
+ modelValue: internalValue.value,
1400
+ name: props.name,
1401
+ min: props.min,
1402
+ max: props.max,
1403
+ step: props.step,
1404
+ orientation: props.orientation,
1405
+ inverted: props.inverted,
1406
+ disabled: props.disabled,
1407
+ required: props.required,
1408
+ minStepsBetweenThumbs: props.minStepsBetweenThumbs,
1409
+ "onUpdate:modelValue": handleUpdate,
1410
+ onValueCommit: handleCommit,
1411
+ class: theme.value.root || void 0
1412
+ }), { default: () => [h(SliderTrack, { class: theme.value.track || void 0 }, { default: () => h(SliderRange, { class: theme.value.range || void 0 }) }), ...internalValue.value.map((_, index) => h(SliderThumb, {
1413
+ key: index,
1414
+ class: theme.value.thumb || void 0
1415
+ }))] });
1416
+ }
1417
+ });
1418
+ //#endregion
1419
+ //#region src/components/form-switch/FormSwitch.vue?vue&type=script&lang.ts
1420
+ const formSwitchThemeDefaults = { classes: {
1421
+ root: "vc-form-switch",
1422
+ thumb: "vc-form-switch-thumb",
1423
+ label: "vc-form-switch-label",
1424
+ group: "vc-form-switch-wrapper"
1425
+ } };
1426
+ const behavioralDefaults = { labelContent: "Toggle" };
1427
+ //#endregion
1428
+ //#region src/components/form-switch/FormSwitch.vue
1429
+ var FormSwitch_default = defineComponent({
1430
+ name: "VCFormSwitch",
1431
+ inheritAttrs: false,
1432
+ props: {
1433
+ /** Controlled checked state. `null` is accepted as the documented "unset" value. */
1434
+ modelValue: {
1435
+ type: [Boolean, null],
1436
+ default: void 0
1437
+ },
1438
+ /** When `true`, prevents the user from interacting with the switch. */
1439
+ disabled: {
1440
+ type: Boolean,
1441
+ default: false
1442
+ },
1443
+ /** Marks the underlying form field as required. */
1444
+ required: {
1445
+ type: Boolean,
1446
+ default: false
1447
+ },
1448
+ /** Form-field name for HTML form submission. */
1449
+ name: {
1450
+ type: String,
1451
+ default: void 0
1452
+ },
1453
+ /** Form-submission value when the switch is on. */
1454
+ value: {
1455
+ type: String,
1456
+ default: "on"
1457
+ },
1458
+ /** Element id; falls back to an SSR-safe generated id. */
1459
+ id: {
1460
+ type: String,
1461
+ default: void 0
1462
+ },
1463
+ /** Vuecs convention: render the label by default. Internal control flow, not forwarded to Reka. */
1464
+ label: {
1465
+ type: Boolean,
1466
+ default: true
1467
+ },
1468
+ /** Default label text (resolved through DefaultsManager). */
1469
+ labelContent: {
1470
+ type: String,
1471
+ default: void 0
1472
+ },
1473
+ /** Theme-class overrides for this component instance. */
1474
+ themeClass: {
1475
+ type: Object,
1476
+ default: void 0
1477
+ },
1478
+ /** Theme variant values for this component instance. */
1479
+ themeVariant: {
1480
+ type: Object,
1481
+ default: void 0
1482
+ }
1483
+ },
1484
+ emits: ["update:modelValue"],
1485
+ slots: Object,
1486
+ setup(props, { attrs, emit, slots }) {
1487
+ const theme = useComponentTheme("formSwitch", props, formSwitchThemeDefaults);
1488
+ const defaults = useComponentDefaults("formSwitch", props, behavioralDefaults);
1489
+ const fallbackId = useId(void 0, "vc-form-switch");
1490
+ return () => {
1491
+ const resolved = theme.value;
1492
+ const resolvedDefaults = defaults.value;
1493
+ const id = props.id ?? fallbackId;
1494
+ const switchEl = h(SwitchRoot, mergeProps(attrs, {
1495
+ id,
1496
+ value: props.value,
1497
+ name: props.name,
1498
+ modelValue: props.modelValue,
1499
+ disabled: props.disabled,
1500
+ required: props.required,
1501
+ "onUpdate:modelValue": (value) => emit("update:modelValue", value),
1502
+ class: resolved.root || void 0
1503
+ }), { default: () => h(SwitchThumb, { class: resolved.thumb || void 0 }, { default: () => slots.thumb?.({ class: resolved.thumb }) ?? "" }) });
1504
+ if (!props.label) return switchEl;
1505
+ const labelNode = slots.label ? slots.label({
1506
+ class: resolved.label,
1507
+ id
1508
+ }) : h("label", {
1509
+ class: resolved.label || void 0,
1510
+ for: id
1511
+ }, [resolvedDefaults.labelContent]);
1512
+ return h("div", { class: resolved.group || void 0 }, [switchEl, labelNode]);
1513
+ };
1514
+ }
1515
+ });
1516
+ //#endregion
1517
+ //#region src/components/form-tags/FormTags.vue?vue&type=script&lang.ts
1518
+ const formTagsThemeDefaults = { classes: {
1519
+ root: "vc-form-tags",
1520
+ item: "vc-form-tags-item",
1521
+ itemText: "vc-form-tags-item-text",
1522
+ itemDelete: "vc-form-tags-item-delete",
1523
+ input: "vc-form-tags-input"
1524
+ } };
1525
+ //#endregion
1526
+ //#region src/components/form-tags/FormTags.vue
1527
+ var FormTags_default = defineComponent({
1528
+ name: "VCFormTags",
1529
+ inheritAttrs: false,
1530
+ props: {
1531
+ /** Controlled list of tag values. `null` is the documented "unset" value. */
1532
+ modelValue: {
1533
+ type: [Array, null],
1534
+ default: void 0
1535
+ },
1536
+ /** Placeholder shown in the empty input field. */
1537
+ placeholder: {
1538
+ type: String,
1539
+ default: void 0
1540
+ },
1541
+ /** When `true`, prevents the user from interacting with the input. */
1542
+ disabled: {
1543
+ type: Boolean,
1544
+ default: false
1545
+ },
1546
+ /** Marks the underlying form field as required. */
1547
+ required: {
1548
+ type: Boolean,
1549
+ default: false
1550
+ },
1551
+ /** Maximum number of tags (0 = unlimited). */
1552
+ max: {
1553
+ type: Number,
1554
+ default: 0
1555
+ },
1556
+ /** When `true`, paste events split on the delimiter and commit the parts. */
1557
+ addOnPaste: {
1558
+ type: Boolean,
1559
+ default: false
1560
+ },
1561
+ /** When `true`, pressing Tab commits the pending tag. */
1562
+ addOnTab: {
1563
+ type: Boolean,
1564
+ default: false
1565
+ },
1566
+ /** Vuecs convention: commit a pending tag when the input loses focus (Reka has no default; vuecs opts in so blur-to-commit "just works"). */
1567
+ addOnBlur: {
1568
+ type: Boolean,
1569
+ default: true
1570
+ },
1571
+ /** When `true`, allow duplicate tag values. */
1572
+ duplicate: {
1573
+ type: Boolean,
1574
+ default: false
1575
+ },
1576
+ /** Character or regular expression that triggers a new tag (and splits pasted text). */
1577
+ delimiter: {
1578
+ type: [String, RegExp],
1579
+ default: ","
1580
+ },
1581
+ /** Form-field name for HTML form submission. */
1582
+ name: {
1583
+ type: String,
1584
+ default: void 0
1585
+ },
1586
+ /** Element id for the root tags input. */
1587
+ id: {
1588
+ type: String,
1589
+ default: void 0
1590
+ },
1591
+ /** Theme-class overrides for this component instance. */
1592
+ themeClass: {
1593
+ type: Object,
1594
+ default: void 0
1595
+ },
1596
+ /** Theme variant values for this component instance. */
1597
+ themeVariant: {
1598
+ type: Object,
1599
+ default: void 0
1600
+ }
1601
+ },
1602
+ emits: ["update:modelValue", "invalid"],
1603
+ setup(props, { attrs, emit }) {
1604
+ const theme = useComponentTheme("formTags", props, formTagsThemeDefaults);
1605
+ return () => h(TagsInputRoot, mergeProps(attrs, {
1606
+ placeholder: props.placeholder,
1607
+ addOnBlur: props.addOnBlur,
1608
+ name: props.name,
1609
+ id: props.id,
1610
+ modelValue: props.modelValue,
1611
+ disabled: props.disabled,
1612
+ required: props.required,
1613
+ max: props.max,
1614
+ addOnPaste: props.addOnPaste,
1615
+ addOnTab: props.addOnTab,
1616
+ duplicate: props.duplicate,
1617
+ delimiter: props.delimiter,
1618
+ "onUpdate:modelValue": (value) => emit("update:modelValue", value),
1619
+ onInvalid: (value) => emit("invalid", value),
1620
+ class: theme.value.root || void 0
1621
+ }), { default: ({ modelValue }) => [...(modelValue ?? []).map((tag) => h(TagsInputItem, {
1622
+ key: String(tag),
1623
+ value: tag,
1624
+ class: theme.value.item || void 0
1625
+ }, { default: () => [h(TagsInputItemText, { class: theme.value.itemText || void 0 }), h(TagsInputItemDelete, { class: theme.value.itemDelete || void 0 }, { default: () => "×" })] })), h(TagsInputInput, {
1626
+ placeholder: props.placeholder,
1627
+ class: theme.value.input || void 0
1628
+ })] });
1629
+ }
1630
+ });
1631
+ //#endregion
1632
+ //#region src/components/form-textarea/FormTextarea.vue?vue&type=script&lang.ts
1633
+ const formTextareaThemeDefaults = { classes: { root: "" } };
1634
+ //#endregion
1635
+ //#region src/components/form-textarea/FormTextarea.vue
1636
+ var FormTextarea_default = defineComponent({
1637
+ name: "VCFormTextarea",
1638
+ props: {
1639
+ /** Controlled string value (v-model). */
1640
+ modelValue: {
1641
+ type: String,
1642
+ default: ""
1643
+ },
1644
+ /** Debounce window (ms) for `update:modelValue` emissions. `0` disables debouncing. */
1645
+ debounce: {
1646
+ type: Number,
1647
+ default: 0
1648
+ },
1649
+ /** Theme-class overrides for this component instance. */
1650
+ themeClass: {
1651
+ type: Object,
1652
+ default: void 0
1653
+ },
1654
+ /** Theme variant values for this component instance. */
1655
+ themeVariant: {
1656
+ type: Object,
1657
+ default: void 0
1658
+ }
1659
+ },
1660
+ emits: ["update:modelValue"],
1661
+ setup(props, { attrs, emit }) {
1662
+ const theme = useComponentTheme("formTextarea", props, formTextareaThemeDefaults);
1663
+ const localValue = ref(props.modelValue);
1664
+ watch(() => props.modelValue, (value) => {
1665
+ localValue.value = value;
1666
+ });
1667
+ const emitUpdate = (value) => emit("update:modelValue", value);
1668
+ const emitUpdateDebounced = useDebounceFn(emitUpdate, () => props.debounce);
1669
+ const onInput = ($event) => {
1670
+ const target = $event.target;
1671
+ if (target.composing) return;
1672
+ const { value } = target;
1673
+ localValue.value = value;
1674
+ if (props.debounce > 0) emitUpdateDebounced(value);
1675
+ else emitUpdate(value);
1676
+ };
1677
+ return () => h("textarea", mergeProps({
1678
+ placeholder: "...",
1679
+ class: theme.value.root || void 0,
1680
+ onInput,
1681
+ value: localValue.value
1682
+ }, attrs));
1683
+ }
1684
+ });
1685
+ //#endregion
1686
+ //#region src/composables/use-submit-button.ts
1687
+ const hardcodedDefaults = {
1688
+ createText: "Create",
1689
+ updateText: "Update",
1690
+ createIcon: "",
1691
+ updateIcon: "",
1692
+ createColor: "success",
1693
+ updateColor: "primary"
1694
+ };
1695
+ /**
1696
+ * @experimental
1697
+ *
1698
+ * Reactive `v-bind` source for `<VCButton>` that swaps label / icon /
1699
+ * color between create and update modes based on `isEditing`. All four
1700
+ * customization knobs (`createText`, `updateText`, `createIcon`,
1701
+ * `updateIcon`, `createColor`, `updateColor`) resolve through the
1702
+ * `DefaultsManager` under the `submitButton` key, so consumers can wire
1703
+ * i18n labels and per-app color/icon choices once at `app.use()` time.
1704
+ *
1705
+ * The API surface (option names, return shape, defaults key) may change
1706
+ * in a future minor release while this stays experimental — pin a
1707
+ * version if you depend on the exact shape.
1708
+ *
1709
+ * @example
1710
+ * ```ts
1711
+ * const submit = useSubmitButton({ isEditing: () => isEditing.value, loading });
1712
+ * ```
1713
+ *
1714
+ * ```vue
1715
+ * <VCButton v-bind="submit" />
1716
+ * ```
1717
+ */
1718
+ function useSubmitButton(options = {}) {
1719
+ const defaults = useComponentDefaults("submitButton", {}, hardcodedDefaults);
1720
+ return computed(() => {
1721
+ const editing = toValue(options.isEditing) ?? false;
1722
+ const resolved = defaults.value;
1723
+ const label = editing ? resolved.updateText : resolved.createText;
1724
+ const iconClass = editing ? resolved.updateIcon : resolved.createIcon;
1725
+ const color = editing ? resolved.updateColor : resolved.createColor;
1726
+ return {
1727
+ type: "submit",
1728
+ label,
1729
+ iconLeft: iconClass || void 0,
1730
+ color,
1731
+ loading: toValue(options.loading) ?? false,
1732
+ disabled: toValue(options.disabled) ?? false
1733
+ };
1734
+ });
1735
+ }
1736
+ //#endregion
1737
+ //#region src/index.ts
1738
+ function install(instance, options = {}) {
1739
+ installThemeManager(instance, options);
1740
+ installDefaultsManager(instance, options);
1741
+ Object.entries({
1742
+ VCFormCheckbox: FormCheckbox_default,
1743
+ VCFormCheckboxGroup: FormCheckboxGroup_default,
1744
+ VCFormGroup: FormGroup_default,
1745
+ VCFormInput: FormInput_default,
1746
+ VCFormNumber: FormNumber_default,
1747
+ VCFormPin: FormPin_default,
1748
+ VCFormRadio: FormRadio_default,
1749
+ VCFormRadioGroup: FormRadioGroup_default,
1750
+ VCFormSelect: FormSelect_default,
1751
+ VCFormSelectSearch: FormSelectSearch_default,
1752
+ VCFormSlider: FormSlider_default,
1753
+ VCFormSwitch: FormSwitch_default,
1754
+ VCFormTags: FormTags_default,
1755
+ VCFormTextarea: FormTextarea_default
1756
+ }).forEach(([componentName, component]) => {
1757
+ instance.component(componentName, component);
1758
+ });
1759
+ }
1760
+ var src_default = { install };
1761
+ //#endregion
1762
+ export { FormCheckbox_default as VCFormCheckbox, FormCheckboxGroup_default as VCFormCheckboxGroup, FormGroup_default as VCFormGroup, FormInput_default as VCFormInput, FormNumber_default as VCFormNumber, FormPin_default as VCFormPin, FormRadio_default as VCFormRadio, FormRadioGroup_default as VCFormRadioGroup, FormSelect_default as VCFormSelect, FormSelectSearch_default as VCFormSelectSearch, FormSlider_default as VCFormSlider, FormSwitch_default as VCFormSwitch, FormTags_default as VCFormTags, FormTextarea_default as VCFormTextarea, ValidationGroup_default as VCValidationGroup, ValidationSeverity, src_default as default, formCheckboxGroupThemeDefaults, formCheckboxThemeDefaults, formGroupThemeDefaults, formInputThemeDefaults, formNumberThemeDefaults, formPinThemeDefaults, formRadioGroupThemeDefaults, formRadioThemeDefaults, formSelectSearchThemeDefaults, formSelectThemeDefaults, formSliderThemeDefaults, formSwitchThemeDefaults, formTagsThemeDefaults, formTextareaThemeDefaults, install, isFormOptionGroup, useSubmitButton, validationGroupThemeDefaults };
1763
+
1764
+ //# sourceMappingURL=index.mjs.map