@vuecs/forms 5.1.1 → 5.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,40 +1,63 @@
1
1
  # @vuecs/forms
2
2
 
3
- [![npm version](https://badge.fury.io/js/@vuecs%2Fforms.svg)](https://badge.fury.io/js/@vuecs%2Fforms)
4
- [![main](https://github.com/Tada5hi/vuecs/actions/workflows/main.yml/badge.svg)](https://github.com/Tada5hi/vuecs/actions/workflows/main.yml)
5
-
6
- Form input components for Vue 3 on top of [Reka UI](https://reka-ui.com) primitives: a complete set of accessible inputs with `v-model` contract, validation hooks, and a shared `FormOption` shape across the pickers.
7
-
8
- Full documentation:
9
-
10
- - [FormInput](https://vuecs.dev/components/form-input)
11
- - [FormNumber](https://vuecs.dev/components/form-number)
12
- - [FormPin](https://vuecs.dev/components/form-pin)
13
- - [FormTextarea](https://vuecs.dev/components/form-textarea)
14
- - [FormCheckbox + CheckboxGroup](https://vuecs.dev/components/form-checkbox)
15
- - [FormSwitch](https://vuecs.dev/components/form-switch)
16
- - [FormRadio + RadioGroup](https://vuecs.dev/components/form-radio)
17
- - [FormSelect](https://vuecs.dev/components/form-select)
18
- - [FormSelectSearch](https://vuecs.dev/components/form-select-search)
19
- - [FormSlider](https://vuecs.dev/components/form-slider) — single value or range, same component
20
- - [FormTags](https://vuecs.dev/components/form-tags)
21
- - [FormGroup + ValidationGroup](https://vuecs.dev/components/form-group)
22
- - [Button + `useSubmitButton()`](https://vuecs.dev/components/button) — the previous `VCFormSubmit` is now `VCButton` driven by an experimental composable
3
+ [![npm version](https://img.shields.io/npm/v/@vuecs/forms)](https://www.npmjs.com/package/@vuecs/forms)
4
+ [![CI](https://github.com/Tada5hi/vuecs/actions/workflows/main.yml/badge.svg)](https://github.com/Tada5hi/vuecs/actions/workflows/main.yml)
5
+ [![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE)
6
+
7
+ **The complete form-input family of [vuecs](https://github.com/tada5hi/vuecs)** — accessible inputs on [Reka UI](https://reka-ui.com) primitives with a clean `v-model` contract, validation feedback, and a shared `FormOption` shape across every picker.
8
+
9
+ ## ✨ What's inside
10
+
11
+ - ⌨️ **Text & numbers** — `<VCFormInput>`, `<VCFormTextarea>`, `<VCFormNumber>` (typed, with steppers), `<VCFormPin>` (PIN/OTP).
12
+ - ✅ **Toggles** — `<VCFormCheckbox>` (incl. `indeterminate`), `<VCFormCheckboxGroup>`, `<VCFormSwitch>`, `<VCFormRadio>` / `<VCFormRadioGroup>`.
13
+ - 📋 **Pickers** — `<VCFormSelect>`, `<VCFormSelectSearch>`, `<VCFormTags>`, all driven by the same `FormOption<T>` shape (`{ value, label, disabled?, icon?, … }`) + `FormOptionGroup<T>`.
14
+ - 🎚️ **`<VCFormSlider>`** — single value or range from one component; thumb count derives from the `v-model` shape.
15
+ - 🧪 **Validation feedback** — wrap any input in `<VCFormGroup>`: it renders label + messages and folds an `error` / `warning` severity onto the input's theme variant automatically, with zero per-input wiring.
16
+ - 🌐 **i18n-ready defaults** — placeholders, labels, and validation copy resolve through `@vuecs/core`'s behavioral-defaults pipeline (reactive `MaybeRef` values welcome).
17
+ - 🚀 **`useSubmitButton()`** *(experimental)* — a reactive bind-object for create/update submit buttons on `@vuecs/button`.
18
+
19
+ ## 📦 Installation
23
20
 
24
21
  ```bash
25
22
  npm install @vuecs/forms
26
23
  ```
27
24
 
28
- ## 3.0 — major rename + Reka migration
25
+ ## Usage
26
+
27
+ ```vue
28
+ <VCFormGroup label-content="Email" :validation-messages="errors.email">
29
+ <VCFormInput v-model="form.email" type="email" />
30
+ </VCFormGroup>
31
+
32
+ <VCFormSelect
33
+ v-model="form.role"
34
+ :options="[
35
+ { value: 'admin', label: 'Administrator' },
36
+ { value: 'user', label: 'User' },
37
+ ]"
38
+ placeholder="-- Select a role --"
39
+ />
40
+
41
+ <VCFormSlider v-model="priceRange" :min="0" :max="500" /> <!-- range: v-model is number[] -->
42
+ ```
43
+
44
+ ## 📚 Documentation
45
+
46
+ One page per component on **[vuecs.dev](https://vuecs.dev/components/)**:
47
+
48
+ [Input](https://vuecs.dev/components/form-input) · [Textarea](https://vuecs.dev/components/form-textarea) · [Number](https://vuecs.dev/components/form-number) · [Pin](https://vuecs.dev/components/form-pin) · [Checkbox](https://vuecs.dev/components/form-checkbox) · [Switch](https://vuecs.dev/components/form-switch) · [Radio](https://vuecs.dev/components/form-radio) · [Select](https://vuecs.dev/components/form-select) · [SelectSearch](https://vuecs.dev/components/form-select-search) · [Slider](https://vuecs.dev/components/form-slider) · [Tags](https://vuecs.dev/components/form-tags)
49
+
50
+ Guide: [Validation feedback](https://vuecs.dev/guide/validation-feedback)
51
+
52
+ ## 🔄 Migrating from `@vuecs/form-controls` (≤2.x)
29
53
 
30
- `@vuecs/form-controls` (≤2.x) was renamed to **`@vuecs/forms`** in 3.0. Highlights:
54
+ `@vuecs/form-controls` was renamed to **`@vuecs/forms`** in 3.0 — a clean break, no shim:
31
55
 
32
- - **Renamed** — update imports: `import { ... } from '@vuecs/forms'`. The old `@vuecs/form-controls` package is removed; no shim. Migrate in one pass.
33
- - **`VCFormInputCheckbox` was split** into three Reka-backed components: `<VCFormCheckbox>` (single, supports `boolean | 'indeterminate'`), `<VCFormCheckboxGroup>` (array v-model with roving focus), `<VCFormSwitch>` (Reka `Switch` primitive — distinct ARIA semantics).
34
- - **`VCFormRangeMultiSlider` was replaced** by `<VCFormSlider>` (Reka `Slider` primitive). One component handles both single (scalar `v-model`) and range (`number[]` `v-model`) modes; thumb count derives from the array shape.
35
- - **Option shape redesign** — `FormSelectOption` (`{ id, value }` — value-was-the-label, inverted) replaced with `FormOption<T>` (`{ value, label, disabled?, description?, icon?, meta? }`) + `FormOptionGroup<T>` for `<optgroup>`. Single `placeholder` prop replaces the `optionDefault` / `optionDefaultId` / `optionDefaultValue` triplet.
36
- - **New components on Reka primitives** — `<VCFormRadio>` + `<VCFormRadioGroup>`, `<VCFormPin>` (PIN/OTP), `<VCFormNumber>` (typed number input with steppers), `<VCFormTags>` (multi-value chip input).
37
- - **`vue-tsc --emitDeclarationOnly`** runs without `|| true` masking — types are validated.
56
+ - `VCFormInputCheckbox` split into `<VCFormCheckbox>` / `<VCFormCheckboxGroup>` / `<VCFormSwitch>` (distinct ARIA semantics).
57
+ - `VCFormRangeMultiSlider` replaced by `<VCFormSlider>` (one component, single + range).
58
+ - `FormSelectOption` (`{ id, value }`) replaced by `FormOption<T>` (`{ value, label, }`); the `optionDefault*` triplet collapsed into one `placeholder` prop.
59
+ - New Reka-backed components: Radio, Pin, Number, Tags.
60
+ - `VCFormSubmit` decomposed into `<VCButton>` + `useSubmitButton()`.
38
61
 
39
62
  ## License
40
63
 
@@ -1 +1 @@
1
- {"version":3,"file":"FormSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/components/form-select/FormSelect.vue"],"names":[],"mappings":"AAuMA,OAAO,KAAK,EACR,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,aAAa,EAChB,MAAM,aAAa,CAAC;AAerB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EACR,sBAAsB,EACtB,QAAQ,EACR,KAAK,EAER,MAAM,KAAK,CAAC;AAMb,OAAO,EAGH,KAAK,eAAe,EAEvB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,sBAAsB,GAAG;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC7B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,OAAO,QAAQ,aAAa,CAAC;IACzB,UAAU,aAAa;QACnB,UAAU,CAAC,EAAE,sBAAsB,CAAC,sBAAsB,CAAC,CAAC;KAC/D;IACD,UAAU,iBAAiB;QACvB,UAAU,CAAC,EAAE,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;KAC3D;CACJ;AAED,eAAO,MAAM,uBAAuB,EAAE,wBAAwB,CAAC,sBAAsB,CAapF,CAAC;AAmCF,QAAA,MAAM,eAAe;IACjB,iCAAiC;;cAEoB,QAAQ,CAAC,eAAe,GAAG,SAAS,CAAC;;;IAG1F,mEAAmE;;cAEhD,QAAQ,CAAC,eAAe,CAAC;;;IAG5C,0IAA0I;;;;;IAE1I,6DAA6D;;;;;IAE7D,uDAAuD;;;;;IAEvD,4EAA4E;;;;;IAE5E,yDAAyD;;cAC3B,QAAQ,CAAC,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;;;IACpF,wDAAwD;;cACxB,QAAQ,CAAC,aAAa,CAAC;;;CAC1D,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,sBAAsB,CAAC,OAAO,eAAe,CAAC,CAAC;wBAExD,OAAO,YAAY;AAAxC,wBAAyC;AAQzC,QAAA,MAAM,YAAY;IAlCd,iCAAiC;;cAEoB,QAAQ,CAAC,eAAe,GAAG,SAAS,CAAC;;;IAG1F,mEAAmE;;cAEhD,QAAQ,CAAC,eAAe,CAAC;;;IAG5C,0IAA0I;;;;;IAE1I,6DAA6D;;;;;IAE7D,uDAAuD;;;;;IAEvD,4EAA4E;;;;;IAE5E,yDAAyD;;cAC3B,QAAQ,CAAC,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;;;IACpF,wDAAwD;;cACxB,QAAQ,CAAC,aAAa,CAAC;;;;;;IArBvD,iCAAiC;;cAEoB,QAAQ,CAAC,eAAe,GAAG,SAAS,CAAC;;;IAG1F,mEAAmE;;cAEhD,QAAQ,CAAC,eAAe,CAAC;;;IAG5C,0IAA0I;;;;;IAE1I,6DAA6D;;;;;IAE7D,uDAAuD;;;;;IAEvD,4EAA4E;;;;;IAE5E,yDAAyD;;cAC3B,QAAQ,CAAC,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;;;IACpF,wDAAwD;;cACxB,QAAQ,CAAC,aAAa,CAAC;;;;;;;;;;;;;4EA0DzD,CAAC"}
1
+ {"version":3,"file":"FormSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/components/form-select/FormSelect.vue"],"names":[],"mappings":"AAmNA,OAAO,KAAK,EACR,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,aAAa,EAChB,MAAM,aAAa,CAAC;AAerB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EACR,sBAAsB,EACtB,QAAQ,EACR,KAAK,EAER,MAAM,KAAK,CAAC;AAMb,OAAO,EAGH,KAAK,eAAe,EAEvB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,sBAAsB,GAAG;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC7B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,OAAO,QAAQ,aAAa,CAAC;IACzB,UAAU,aAAa;QACnB,UAAU,CAAC,EAAE,sBAAsB,CAAC,sBAAsB,CAAC,CAAC;KAC/D;IACD,UAAU,iBAAiB;QACvB,UAAU,CAAC,EAAE,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;KAC3D;CACJ;AAED,eAAO,MAAM,uBAAuB,EAAE,wBAAwB,CAAC,sBAAsB,CAapF,CAAC;AAmCF,QAAA,MAAM,eAAe;IACjB,iCAAiC;;cAEoB,QAAQ,CAAC,eAAe,GAAG,SAAS,CAAC;;;IAG1F,mEAAmE;;cAEhD,QAAQ,CAAC,eAAe,CAAC;;;IAG5C,0IAA0I;;;;;IAE1I,6DAA6D;;;;;IAE7D,uDAAuD;;;;;IAEvD,4EAA4E;;;;;IAE5E,yDAAyD;;cAC3B,QAAQ,CAAC,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;;;IACpF,wDAAwD;;cACxB,QAAQ,CAAC,aAAa,CAAC;;;CAC1D,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,sBAAsB,CAAC,OAAO,eAAe,CAAC,CAAC;wBAExD,OAAO,YAAY;AAAxC,wBAAyC;AAQzC,QAAA,MAAM,YAAY;IAlCd,iCAAiC;;cAEoB,QAAQ,CAAC,eAAe,GAAG,SAAS,CAAC;;;IAG1F,mEAAmE;;cAEhD,QAAQ,CAAC,eAAe,CAAC;;;IAG5C,0IAA0I;;;;;IAE1I,6DAA6D;;;;;IAE7D,uDAAuD;;;;;IAEvD,4EAA4E;;;;;IAE5E,yDAAyD;;cAC3B,QAAQ,CAAC,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;;;IACpF,wDAAwD;;cACxB,QAAQ,CAAC,aAAa,CAAC;;;;;;IArBvD,iCAAiC;;cAEoB,QAAQ,CAAC,eAAe,GAAG,SAAS,CAAC;;;IAG1F,mEAAmE;;cAEhD,QAAQ,CAAC,eAAe,CAAC;;;IAG5C,0IAA0I;;;;;IAE1I,6DAA6D;;;;;IAE7D,uDAAuD;;;;;IAEvD,4EAA4E;;;;;IAE5E,yDAAyD;;cAC3B,QAAQ,CAAC,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;;;IACpF,wDAAwD;;cACxB,QAAQ,CAAC,aAAa,CAAC;;;;;;;;;;;;;4EAsEzD,CAAC"}
package/dist/index.mjs CHANGED
@@ -1035,12 +1035,16 @@ var FormSelect_default = defineComponent({
1035
1035
  setup(props, { attrs, emit }) {
1036
1036
  const theme = useComponentTheme("formSelect", useFormInputThemeProps(props), formSelectThemeDefaults);
1037
1037
  const defaults = useComponentDefaults("formSelect", props, behavioralDefaults$1);
1038
+ const renderItems = () => {
1039
+ const classes = theme.value;
1040
+ const items = [];
1041
+ for (const item of props.options) if (isFormOptionGroup(item)) items.push(renderGroup(item, classes));
1042
+ else items.push(renderItem(item, classes));
1043
+ return items;
1044
+ };
1038
1045
  return () => {
1039
1046
  const resolved = theme.value;
1040
1047
  const { placeholder } = defaults.value;
1041
- const items = [];
1042
- for (const item of props.options) if (isFormOptionGroup(item)) items.push(renderGroup(item, resolved));
1043
- else items.push(renderItem(item, resolved));
1044
1048
  return h(SelectRoot, {
1045
1049
  name: props.name,
1046
1050
  modelValue: props.modelValue,
@@ -1055,7 +1059,7 @@ var FormSelect_default = defineComponent({
1055
1059
  }), h(SelectIcon, { class: resolved.icon || void 0 }, () => "▾")]), h(SelectPortal, null, () => [h(SelectContent, {
1056
1060
  class: resolved.content || void 0,
1057
1061
  position: "popper"
1058
- }, () => [h(SelectViewport, { class: resolved.viewport || void 0 }, () => items)])])] });
1062
+ }, () => [h(SelectViewport, { class: resolved.viewport || void 0 }, () => renderItems())])])] });
1059
1063
  };
1060
1064
  }
1061
1065
  });