@velkymx/vibeui 0.8.2 → 1.0.2

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 (200) hide show
  1. package/AGENTS.md +44 -0
  2. package/README.md +245 -58
  3. package/dist/purify.es-1D-VntFD.mjs +679 -0
  4. package/dist/src/App.vue.d.ts +3 -0
  5. package/dist/src/components/HelloWorld.vue.d.ts +6 -0
  6. package/dist/src/components/VibeAccordion.vue.d.ts +89 -0
  7. package/dist/{components → src/components}/VibeAlert.vue.d.ts +24 -30
  8. package/dist/src/components/VibeAutocomplete.vue.d.ts +74 -0
  9. package/dist/{components → src/components}/VibeBadge.vue.d.ts +10 -18
  10. package/dist/src/components/VibeBreadcrumb.vue.d.ts +51 -0
  11. package/dist/{components → src/components}/VibeButton.vue.d.ts +16 -20
  12. package/dist/{components → src/components}/VibeButtonGroup.vue.d.ts +10 -18
  13. package/dist/{components → src/components}/VibeCard.vue.d.ts +51 -24
  14. package/dist/{components → src/components}/VibeCarousel.vue.d.ts +27 -49
  15. package/dist/src/components/VibeChartBar.vue.d.ts +61 -0
  16. package/dist/src/components/VibeChartLine.vue.d.ts +70 -0
  17. package/dist/src/components/VibeChartPie.vue.d.ts +34 -0
  18. package/dist/{components → src/components}/VibeCloseButton.vue.d.ts +9 -7
  19. package/dist/{components → src/components}/VibeCol.vue.d.ts +9 -17
  20. package/dist/src/components/VibeCollapse.vue.d.ts +76 -0
  21. package/dist/src/components/VibeContainer.vue.d.ts +36 -0
  22. package/dist/src/components/VibeDataTable.vue.d.ts +131 -0
  23. package/dist/src/components/VibeDatePicker.vue.d.ts +120 -0
  24. package/dist/src/components/VibeDraggable.vue.d.ts +77 -0
  25. package/dist/{components → src/components}/VibeDropdown.vue.d.ts +46 -43
  26. package/dist/src/components/VibeDroppable.vue.d.ts +70 -0
  27. package/dist/src/components/VibeFileInput.vue.d.ts +127 -0
  28. package/dist/{components → src/components}/VibeFormCheckbox.vue.d.ts +30 -22
  29. package/dist/{components → src/components}/VibeFormDatepicker.vue.d.ts +27 -30
  30. package/dist/{components → src/components}/VibeFormGroup.vue.d.ts +11 -14
  31. package/dist/{components → src/components}/VibeFormInput.vue.d.ts +22 -23
  32. package/dist/{components → src/components}/VibeFormRadio.vue.d.ts +23 -24
  33. package/dist/{components → src/components}/VibeFormSelect.vue.d.ts +28 -34
  34. package/dist/{components → src/components}/VibeFormSpinbutton.vue.d.ts +31 -34
  35. package/dist/{components → src/components}/VibeFormSwitch.vue.d.ts +22 -23
  36. package/dist/{components → src/components}/VibeFormTextarea.vue.d.ts +24 -25
  37. package/dist/{components → src/components}/VibeFormWysiwyg.vue.d.ts +24 -23
  38. package/dist/src/components/VibeHero.vue.d.ts +108 -0
  39. package/dist/{components → src/components}/VibeIcon.vue.d.ts +27 -7
  40. package/dist/{components → src/components}/VibeInputGroup.vue.d.ts +11 -13
  41. package/dist/{components → src/components}/VibeLink.vue.d.ts +14 -18
  42. package/dist/{components → src/components}/VibeListGroup.vue.d.ts +26 -22
  43. package/dist/{components → src/components}/VibeModal.vue.d.ts +29 -45
  44. package/dist/{components → src/components}/VibeNav.vue.d.ts +40 -20
  45. package/dist/{components → src/components}/VibeNavbar.vue.d.ts +12 -19
  46. package/dist/src/components/VibeNavbarBrand.vue.d.ts +34 -0
  47. package/dist/src/components/VibeNavbarNav.vue.d.ts +80 -0
  48. package/dist/{components → src/components}/VibeNavbarToggle.vue.d.ts +7 -5
  49. package/dist/{components → src/components}/VibeOffcanvas.vue.d.ts +28 -43
  50. package/dist/{components → src/components}/VibePagination.vue.d.ts +38 -29
  51. package/dist/{components → src/components}/VibePlaceholder.vue.d.ts +9 -17
  52. package/dist/src/components/VibePopover.vue.d.ts +72 -0
  53. package/dist/src/components/VibeProgress.vue.d.ts +37 -0
  54. package/dist/src/components/VibeResizable.vue.d.ts +140 -0
  55. package/dist/{components → src/components}/VibeRow.vue.d.ts +9 -17
  56. package/dist/src/components/VibeScrollspy.vue.d.ts +89 -0
  57. package/dist/src/components/VibeSkeleton.vue.d.ts +54 -0
  58. package/dist/src/components/VibeSlider.vue.d.ts +77 -0
  59. package/dist/src/components/VibeSortable.vue.d.ts +59 -0
  60. package/dist/{components → src/components}/VibeSpinner.vue.d.ts +4 -7
  61. package/dist/src/components/VibeStepper.vue.d.ts +133 -0
  62. package/dist/src/components/VibeTab.vue.d.ts +41 -0
  63. package/dist/src/components/VibeTabContent.vue.d.ts +56 -0
  64. package/dist/src/components/VibeTabs.vue.d.ts +78 -0
  65. package/dist/{components → src/components}/VibeToast.vue.d.ts +40 -42
  66. package/dist/src/components/VibeToastHost.vue.d.ts +16 -0
  67. package/dist/src/components/VibeTooltip.vue.d.ts +63 -0
  68. package/dist/src/components/chart/chartColors.d.ts +3 -0
  69. package/dist/src/components/chart/chartResize.d.ts +2 -0
  70. package/dist/src/components/chart/chartTooltip.d.ts +2 -0
  71. package/dist/src/components/chart/chartTypes.d.ts +6 -0
  72. package/dist/src/components/chart/drawBar.d.ts +5 -0
  73. package/dist/src/components/chart/drawLine.d.ts +18 -0
  74. package/dist/src/components/chart/drawPie.d.ts +4 -0
  75. package/dist/src/components/dndStore.d.ts +7 -0
  76. package/dist/{components → src/components}/index.d.ts +18 -1
  77. package/dist/{composables → src/composables}/useBreakpoints.d.ts +1 -0
  78. package/dist/{composables → src/composables}/useColorMode.d.ts +1 -1
  79. package/dist/src/composables/useForm.d.ts +22 -0
  80. package/dist/src/composables/useId.d.ts +2 -0
  81. package/dist/src/composables/usePosition.d.ts +20 -0
  82. package/dist/src/composables/useToast.d.ts +52 -0
  83. package/dist/src/directives/vTooltip.d.ts +24 -0
  84. package/dist/{index.d.ts → src/index.d.ts} +6 -0
  85. package/dist/src/injectionKeys.d.ts +28 -0
  86. package/dist/{types.d.ts → src/types.d.ts} +32 -6
  87. package/dist/src/utils/safeCss.d.ts +16 -0
  88. package/dist/src/utils/safeHref.d.ts +7 -0
  89. package/dist/src/utils/sanitizeHtml.d.ts +13 -0
  90. package/dist/vibeui.css +2 -1
  91. package/dist/vibeui.es.js +8351 -3508
  92. package/dist/vibeui.umd.js +3 -1
  93. package/docs/README.md +85 -13
  94. package/docs/components/advanced/popover.md +27 -52
  95. package/docs/components/advanced/scrollspy.md +57 -15
  96. package/docs/components/advanced/tooltip.md +26 -47
  97. package/docs/components/card/card.md +9 -1
  98. package/docs/components/charts/chart-bar.md +129 -0
  99. package/docs/components/charts/chart-line.md +136 -0
  100. package/docs/components/charts/chart-pie.md +102 -0
  101. package/docs/components/core/alert.md +27 -5
  102. package/docs/components/core/badge.md +0 -6
  103. package/docs/components/core/button-group.md +0 -6
  104. package/docs/components/core/button.md +1 -1
  105. package/docs/components/core/close-button.md +5 -5
  106. package/docs/components/core/link.md +60 -17
  107. package/docs/components/core/placeholder.md +0 -6
  108. package/docs/components/core/skeleton.md +40 -0
  109. package/docs/components/core/spinner.md +0 -6
  110. package/docs/components/data/datatable.md +29 -10
  111. package/docs/components/hero/hero.md +64 -0
  112. package/docs/components/interactive/accordion.md +29 -0
  113. package/docs/components/interactive/carousel.md +19 -4
  114. package/docs/components/interactive/collapse.md +3 -2
  115. package/docs/components/interactive/date-picker.md +78 -0
  116. package/docs/components/interactive/draggable.md +91 -0
  117. package/docs/components/interactive/dropdown.md +54 -18
  118. package/docs/components/interactive/modal.md +15 -20
  119. package/docs/components/interactive/offcanvas.md +4 -1
  120. package/docs/components/interactive/resizable.md +73 -0
  121. package/docs/components/interactive/slider.md +57 -0
  122. package/docs/components/interactive/sortable.md +52 -0
  123. package/docs/components/interactive/stepper.md +83 -0
  124. package/docs/components/interactive/tabs.md +66 -0
  125. package/docs/components/interactive/toast.md +93 -30
  126. package/docs/components/layout/col.md +0 -6
  127. package/docs/components/layout/container.md +0 -6
  128. package/docs/components/layout/row.md +0 -6
  129. package/docs/components/list/list-group.md +4 -0
  130. package/docs/components/navigation/breadcrumb.md +4 -0
  131. package/docs/components/navigation/nav.md +64 -1
  132. package/docs/components/navigation/navbar.md +2 -0
  133. package/docs/components/navigation/pagination.md +16 -0
  134. package/docs/components/progress/progress.md +7 -1
  135. package/docs/composables/color-mode.md +44 -6
  136. package/docs/composables/use-form.md +78 -0
  137. package/docs/composables/use-position.md +68 -0
  138. package/docs/composables/use-toast.md +91 -0
  139. package/docs/directives/v-tooltip.md +58 -0
  140. package/docs/forms/README.md +60 -61
  141. package/docs/forms/autocomplete.md +96 -0
  142. package/docs/forms/file-input.md +97 -0
  143. package/docs/forms/form-checkbox.md +75 -25
  144. package/docs/forms/form-datepicker.md +58 -28
  145. package/docs/forms/form-group.md +79 -44
  146. package/docs/forms/form-input.md +88 -31
  147. package/docs/forms/form-radio.md +60 -36
  148. package/docs/forms/form-select.md +75 -31
  149. package/docs/forms/form-spinbutton.md +72 -33
  150. package/docs/forms/form-switch.md +53 -25
  151. package/docs/forms/form-textarea.md +60 -29
  152. package/docs/forms/form-wysiwyg.md +73 -38
  153. package/docs/forms/input-group.md +53 -34
  154. package/docs/forms/validation.md +135 -521
  155. package/docs/getting-started/starter-template.md +136 -0
  156. package/docs/superpowers/plans/2026-05-12-vibe-charts.md +1999 -0
  157. package/docs/superpowers/plans/2026-05-29-e2e-browser-testing.md +615 -0
  158. package/docs/superpowers/specs/2026-05-12-charting-design.md +185 -0
  159. package/docs/superpowers/specs/2026-05-29-e2e-browser-testing-design.md +168 -0
  160. package/docs/utilities/position.md +82 -0
  161. package/docs/versioning.md +57 -0
  162. package/examples/README.md +201 -0
  163. package/examples/album.html +262 -0
  164. package/examples/blog.html +166 -0
  165. package/examples/carousel.html +114 -0
  166. package/examples/checkout.html +275 -0
  167. package/examples/cover.html +89 -0
  168. package/examples/dashboard.html +156 -0
  169. package/examples/index.html +129 -0
  170. package/examples/jumbotron.html +56 -0
  171. package/examples/mobile-dashboard.html +138 -0
  172. package/examples/pricing.html +172 -0
  173. package/examples/product.html +145 -0
  174. package/examples/sidebars.html +166 -0
  175. package/examples/sign-in.html +119 -0
  176. package/examples/starter.html +314 -0
  177. package/examples/sticky-footer-navbar.html +70 -0
  178. package/examples/sticky-footer.html +60 -0
  179. package/examples/test-simple.html +91 -0
  180. package/llms.txt +407 -47
  181. package/package.json +42 -13
  182. package/dist/App.vue.d.ts +0 -2
  183. package/dist/components/HelloWorld.vue.d.ts +0 -5
  184. package/dist/components/VibeAccordion.vue.d.ts +0 -90
  185. package/dist/components/VibeBreadcrumb.vue.d.ts +0 -47
  186. package/dist/components/VibeCollapse.vue.d.ts +0 -84
  187. package/dist/components/VibeContainer.vue.d.ts +0 -44
  188. package/dist/components/VibeDataTable.vue.d.ts +0 -76
  189. package/dist/components/VibeNavbarBrand.vue.d.ts +0 -42
  190. package/dist/components/VibeNavbarNav.vue.d.ts +0 -61
  191. package/dist/components/VibePopover.vue.d.ts +0 -95
  192. package/dist/components/VibeProgress.vue.d.ts +0 -45
  193. package/dist/components/VibeScrollspy.vue.d.ts +0 -77
  194. package/dist/components/VibeTabContent.vue.d.ts +0 -74
  195. package/dist/components/VibeTooltip.vue.d.ts +0 -86
  196. package/dist/composables/useId.d.ts +0 -5
  197. package/dist/types/index.d.ts +0 -6
  198. /package/dist/{composables → src/composables}/useBackButton.d.ts +0 -0
  199. /package/dist/{composables → src/composables}/useFormValidation.d.ts +0 -0
  200. /package/dist/{main.d.ts → src/main.d.ts} +0 -0
@@ -1,8 +1,49 @@
1
1
  # VibeFormInput
2
2
 
3
- Text input component with built-in validation support for various input types.
3
+ Single-line text input supporting all standard HTML input types, with built-in validation and accessibility.
4
4
 
5
- ## Basic Usage
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `modelValue` | `string \| number` | `''` | The input value (v-model). Coerced to a number when `type="number"`. |
10
+ | `type` | `InputType` | `'text'` | HTML input type (`text`, `email`, `password`, `number`, `tel`, `url`, `search`, `date`, `time`, `datetime-local`, `month`, `week`, `color`). |
11
+ | `id` | `string` | auto-generated | Element id. Auto-generated, or inherited from a parent `VibeFormGroup`. |
12
+ | `label` | `string` | `undefined` | Standalone label text (omit when inside a `VibeFormGroup`). |
13
+ | `placeholder` | `string` | `undefined` | Placeholder text. |
14
+ | `disabled` | `boolean` | `false` | Disable the input. |
15
+ | `readonly` | `boolean` | `false` | Make the input read-only. |
16
+ | `required` | `boolean` | `false` | Mark as required (renders a `*` next to a standalone label). |
17
+ | `size` | `'sm' \| 'lg'` | `undefined` | Control size. |
18
+ | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Visual validation state. |
19
+ | `validationMessage` | `string` | `undefined` | Feedback message shown for the current `validationState`. |
20
+ | `validationRules` | `ValidationRule[] \| ValidatorFunction` | `undefined` | Rules carried for use with a validation composable. |
21
+ | `validateOn` | `'input' \| 'blur' \| 'change'` | `'blur'` | When the `validate` event fires. |
22
+ | `helpText` | `string` | `undefined` | Help text below the input. |
23
+ | `plaintext` | `boolean` | `false` | Render as read-only plain text (`.form-control-plaintext`). |
24
+ | `noWrapper` | `boolean` | `false` | Render only the `<input>` (no wrapper/label/feedback). Use inside `VibeInputGroup`. |
25
+ | `focusRing` | `boolean` | `false` | Add the Bootstrap 5.3 `.focus-ring` helper. |
26
+
27
+ ## Events
28
+
29
+ | Event | Payload | Description |
30
+ |-------|---------|-------------|
31
+ | `update:modelValue` | `string \| number` | Emitted on input (number-coerced for `type="number"`). |
32
+ | `input` | `Event` | Native input event. |
33
+ | `change` | `Event` | Native change event. |
34
+ | `blur` | `FocusEvent` | Emitted on blur. |
35
+ | `focus` | `FocusEvent` | Emitted on focus. |
36
+ | `validate` | — | Emitted when the `validateOn` trigger occurs. |
37
+
38
+ ## Slots
39
+
40
+ None.
41
+
42
+ ## Usage
43
+
44
+ ### Recommended: inside a VibeFormGroup
45
+
46
+ `VibeFormGroup` generates the id, links the `<label>`, and wires `aria-describedby`, help text, and validation feedback for the first child control.
6
47
 
7
48
  ```vue
8
49
  <script setup lang="ts">
@@ -11,45 +52,61 @@ const name = ref('')
11
52
  </script>
12
53
 
13
54
  <template>
14
- <VibeFormInput
15
- v-model="name"
16
- label="Full Name"
17
- placeholder="Enter your name"
18
- />
55
+ <VibeFormGroup label="Full Name" help-text="As it appears on your ID.">
56
+ <VibeFormInput v-model="name" placeholder="Jane Doe" />
57
+ </VibeFormGroup>
19
58
  </template>
20
59
  ```
21
60
 
22
- ## Props
61
+ ### With validation
23
62
 
24
- | Prop | Type | Default | Description |
25
- |------|------|---------|-------------|
26
- | `modelValue` | `String \| Number` | `''` | The input value (v-model) |
27
- | `id` | `String` | `Auto-generated` | Unique identifier |
28
- | `label` | `String` | `undefined` | Label text |
29
- | `type` | `InputType` | `'text'` | HTML input type |
30
- | `placeholder` | `String` | `undefined` | Placeholder text |
31
- | `disabled` | `Boolean` | `false` | Disable the input |
32
- | `readonly` | `Boolean` | `false` | Make the input readonly |
33
- | `required` | `Boolean` | `false` | Mark as required |
34
- | `size` | `'sm' \| 'lg'` | `undefined` | Input size |
35
- | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Validation state |
36
- | `validationMessage` | `String` | `undefined` | Validation message |
37
- | `validateOn` | `'input' \| 'blur' \| 'change'` | `'blur'` | When to validate |
38
- | `helpText` | `String` | `undefined` | Help text |
39
- | `plaintext` | `Boolean` | `false` | Display as plain text |
40
- | `noWrapper` | `Boolean` | `false` | Removes the wrapping div, label, and feedback. Useful inside `VibeInputGroup`. |
41
- | `focusRing` | `Boolean` | `false` | Enable the Bootstrap 5.3 focus-ring helper |
63
+ ```vue
64
+ <script setup lang="ts">
65
+ import { useFormValidation, validators } from '@velkymx/vibeui'
42
66
 
43
- ## Important Notes
67
+ const email = useFormValidation('')
68
+ const validateEmail = () =>
69
+ email.validate([validators.required(), validators.email()])
70
+ </script>
44
71
 
45
- **Automatic ID Generation:** This component automatically generates a unique ID if one is not provided.
72
+ <template>
73
+ <VibeFormGroup
74
+ label="Email"
75
+ :validation-state="email.validationState"
76
+ :validation-message="email.validationMessage"
77
+ >
78
+ <VibeFormInput
79
+ v-model="email.value"
80
+ type="email"
81
+ @validate="validateEmail"
82
+ />
83
+ </VibeFormGroup>
84
+ </template>
85
+ ```
46
86
 
47
- **Automatic ID Injection:** When used inside a `VibeFormGroup`, this component will automatically inherit the group's ID to ensure proper label association and accessibility.
87
+ ### Standalone
88
+
89
+ ```vue
90
+ <script setup lang="ts">
91
+ import { ref } from 'vue'
92
+ const search = ref('')
93
+ </script>
94
+
95
+ <template>
96
+ <VibeFormInput v-model="search" label="Search" type="search" />
97
+ </template>
98
+ ```
99
+
100
+ ## Important Notes
101
+
102
+ - **Automatic ID & label linking:** when wrapped in a `VibeFormGroup`, the first child control consumes the group id, so the group's `<label>`, help text, and feedback are linked automatically. Do not also set `label`/`helpText` on the input in that case — the group renders them.
103
+ - **Number coercion:** with `type="number"`, an empty field emits `''`; otherwise the emitted value is a `number`.
104
+ - **Plain text:** `plaintext` forces the control read-only.
48
105
 
49
106
  ## Bootstrap CSS Classes
50
107
 
51
108
  - `.form-control`
52
- - `.form-control-{size}`
53
- - `.is-valid`, `.is-invalid`
109
+ - `.form-control-{sm|lg}`
54
110
  - `.form-control-plaintext`
111
+ - `.is-valid`, `.is-invalid`
55
112
  - `.focus-ring`
@@ -1,58 +1,82 @@
1
1
  # VibeFormRadio
2
2
 
3
- Radio button component for exclusive selection within a group.
3
+ Radio button for exclusive selection within a named group.
4
4
 
5
- ## Basic Usage
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `modelValue` | `string \| number \| boolean` | `''` | Selected value shared across the group (v-model). |
10
+ | `value` | `string \| number \| boolean` | — (required) | This radio's value. |
11
+ | `name` | `string` | — (required) | Group name; all radios in a group share the same `name`. |
12
+ | `id` | `string` | auto-generated | Element id. Auto-generated, or inherited from a parent `VibeFormGroup`. |
13
+ | `label` | `string` | `undefined` | Radio label text. |
14
+ | `disabled` | `boolean` | `false` | Disable the radio. |
15
+ | `required` | `boolean` | `false` | Mark as required. |
16
+ | `inline` | `boolean` | `false` | Render inline (`.form-check-inline`). |
17
+ | `reverse` | `boolean` | `false` | Place the label before the radio (`.form-check-reverse`). |
18
+ | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Visual validation state. |
19
+ | `validationMessage` | `string` | `undefined` | Feedback message for the current state. |
20
+ | `validationRules` | `ValidationRule[] \| ValidatorFunction` | `undefined` | Rules carried for use with a validation composable. |
21
+ | `validateOn` | `'change' \| 'blur'` | `'change'` | When the `validate` event fires. |
22
+ | `helpText` | `string` | `undefined` | Help text below the radio. |
23
+
24
+ ## Events
25
+
26
+ | Event | Payload | Description |
27
+ |-------|---------|-------------|
28
+ | `update:modelValue` | `string \| number \| boolean` | Emitted with this radio's `value` when selected. |
29
+ | `change` | `Event` | Native change event. |
30
+ | `blur` | `FocusEvent` | Emitted on blur. |
31
+ | `focus` | `FocusEvent` | Emitted on focus. |
32
+ | `validate` | — | Emitted when the `validateOn` trigger occurs. |
33
+
34
+ ## Slots
35
+
36
+ None.
37
+
38
+ ## Usage
39
+
40
+ ### Recommended: a group inside VibeFormGroup
6
41
 
7
42
  ```vue
8
43
  <script setup lang="ts">
9
44
  import { ref } from 'vue'
10
- const picked = ref('one')
45
+ const plan = ref('free')
11
46
  </script>
12
47
 
13
48
  <template>
14
- <VibeFormRadio
15
- v-model="picked"
16
- name="myGroup"
17
- value="one"
18
- label="Option One"
19
- />
20
- <VibeFormRadio
21
- v-model="picked"
22
- name="myGroup"
23
- value="two"
24
- label="Option Two"
25
- />
49
+ <VibeFormGroup label="Plan">
50
+ <VibeFormRadio v-model="plan" name="plan" value="free" label="Free" />
51
+ <VibeFormRadio v-model="plan" name="plan" value="pro" label="Pro" />
52
+ <VibeFormRadio v-model="plan" name="plan" value="team" label="Team" />
53
+ </VibeFormGroup>
26
54
  </template>
27
55
  ```
28
56
 
29
- ## Props
57
+ ### Inline
30
58
 
31
- | Prop | Type | Default | Description |
32
- |------|------|---------|-------------|
33
- | `modelValue` | `any` | `''` | The picked value (v-model) |
34
- | `value` | `any` | Required | Value of this radio |
35
- | `name` | `String` | Required | Shared name for the radio group |
36
- | `id` | `String` | `Auto-generated` | Unique identifier |
37
- | `label` | `String` | `undefined` | Label text |
38
- | `disabled` | `Boolean` | `false` | Disable the radio |
39
- | `required` | `Boolean` | `false` | Mark as required |
40
- | `inline` | `Boolean` | `false` | Display inline |
41
- | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Validation state |
42
- | `validationMessage` | `String` | `undefined` | Validation message |
43
- | `validateOn` | `'change' \| 'blur'` | `'change'` | When to validate |
44
- | `helpText` | `String` | `undefined` | Help text |
45
- | `reverse` | `Boolean` | `false` | Reverse label and input |
59
+ ```vue
60
+ <script setup lang="ts">
61
+ import { ref } from 'vue'
62
+ const size = ref('m')
63
+ </script>
46
64
 
47
- ## Important Notes
65
+ <template>
66
+ <VibeFormRadio v-model="size" name="size" value="s" label="Small" inline />
67
+ <VibeFormRadio v-model="size" name="size" value="m" label="Medium" inline />
68
+ <VibeFormRadio v-model="size" name="size" value="l" label="Large" inline />
69
+ </template>
70
+ ```
48
71
 
49
- **Automatic ID Generation:** This component automatically generates a unique ID if one is not provided.
72
+ ## Important Notes
50
73
 
51
- **Automatic ID Injection:** When used inside a `VibeFormGroup`, this component will automatically inherit the group's ID to ensure proper label association and accessibility.
74
+ - **Shared `name`:** every radio in the same logical group must share a `name` so the browser enforces exclusivity.
75
+ - **Group linking:** the first radio in a `VibeFormGroup` consumes the group id; subsequent radios generate their own ids.
52
76
 
53
77
  ## Bootstrap CSS Classes
54
78
 
55
79
  - `.form-check`
56
- - `.form-check-input`
57
- - `.form-check-label`
80
+ - `.form-check-input`, `.form-check-label`
81
+ - `.form-check-inline`, `.form-check-reverse`
58
82
  - `.is-valid`, `.is-invalid`
@@ -1,54 +1,98 @@
1
1
  # VibeFormSelect
2
2
 
3
- Custom select component with support for single and multiple selection.
3
+ Single or multiple selection dropdown driven by an `options` array, with built-in validation and accessibility.
4
4
 
5
- ## Basic Usage
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `modelValue` | `FormSelectOptionValue \| FormSelectOptionValue[]` | `''` | Selected value(s). An array when `multiple` is set. `FormSelectOptionValue` is `string \| number \| boolean \| null \| undefined`. |
10
+ | `options` | `FormSelectOption[]` | `[]` | Options to render: `{ value, text, disabled? }`. |
11
+ | `id` | `string` | auto-generated | Element id. Auto-generated, or inherited from a parent `VibeFormGroup`. |
12
+ | `label` | `string` | `undefined` | Standalone label text. |
13
+ | `multiple` | `boolean` | `false` | Allow multiple selection (model becomes an array). |
14
+ | `selectSize` | `number` | `undefined` | Number of visible rows (native `size`). |
15
+ | `htmlSize` | `number` | `undefined` | Number of visible rows (native `size`); takes precedence over `selectSize`. |
16
+ | `placeholder` | `string` | `undefined` | Disabled placeholder option (single-select only). |
17
+ | `disabled` | `boolean` | `false` | Disable the select. |
18
+ | `required` | `boolean` | `false` | Mark as required. |
19
+ | `size` | `'sm' \| 'lg'` | `undefined` | Control size (`.form-select-sm/lg`). |
20
+ | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Visual validation state. |
21
+ | `validationMessage` | `string` | `undefined` | Feedback message for the current state. |
22
+ | `validationRules` | `ValidationRule[] \| ValidatorFunction` | `undefined` | Rules carried for use with a validation composable. |
23
+ | `validateOn` | `'change' \| 'blur'` | `'change'` | When the `validate` event fires. |
24
+ | `helpText` | `string` | `undefined` | Help text below the select. |
25
+
26
+ ## Events
27
+
28
+ | Event | Payload | Description |
29
+ |-------|---------|-------------|
30
+ | `update:modelValue` | `FormSelectOptionValue \| FormSelectOptionValue[]` | Emitted on selection. Array when `multiple`. |
31
+ | `change` | `Event` | Native change event. |
32
+ | `blur` | `FocusEvent` | Emitted on blur. |
33
+ | `focus` | `FocusEvent` | Emitted on focus. |
34
+ | `validate` | — | Emitted when the `validateOn` trigger occurs. |
35
+
36
+ ## Slots
37
+
38
+ | Slot | Description |
39
+ |------|-------------|
40
+ | default | Override the auto-rendered `<option>` list (provide your own `<option>` / `<optgroup>` elements). |
41
+
42
+ ## Usage
43
+
44
+ ### Recommended: inside a VibeFormGroup
6
45
 
7
46
  ```vue
8
47
  <script setup lang="ts">
9
48
  import { ref } from 'vue'
10
- const selected = ref('')
11
- const options = [
12
- { value: '1', text: 'Option 1' },
13
- { value: '2', text: 'Option 2' }
49
+ import type { FormSelectOption } from '@velkymx/vibeui'
50
+
51
+ const country = ref('')
52
+ const options: FormSelectOption[] = [
53
+ { value: 'us', text: 'United States' },
54
+ { value: 'ca', text: 'Canada' },
55
+ { value: 'mx', text: 'Mexico' }
14
56
  ]
15
57
  </script>
16
58
 
17
59
  <template>
18
- <VibeFormSelect
19
- v-model="selected"
20
- label="Choose an option"
21
- :options="options"
22
- />
60
+ <VibeFormGroup label="Country">
61
+ <VibeFormSelect v-model="country" :options="options" placeholder="Choose…" />
62
+ </VibeFormGroup>
23
63
  </template>
24
64
  ```
25
65
 
26
- ## Props
66
+ ### Multiple selection
27
67
 
28
- | Prop | Type | Default | Description |
29
- |------|------|---------|-------------|
30
- | `modelValue` | `any` | `''` | Selected value (v-model) |
31
- | `id` | `String` | `Auto-generated` | Unique identifier |
32
- | `label` | `String` | `undefined` | Label text |
33
- | `options` | `FormSelectOption[]` | `[]` | Array of options |
34
- | `multiple` | `Boolean` | `false` | Enable multiple selection |
35
- | `selectSize` | `Number` | `undefined` | Visible rows |
36
- | `disabled` | `Boolean` | `false` | Disable the select |
37
- | `required` | `Boolean` | `false` | Mark as required |
38
- | `size` | `'sm' \| 'lg'` | `undefined` | Select size |
39
- | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Validation state |
40
- | `validationMessage` | `String` | `undefined` | Validation message |
41
- | `validateOn` | `'change' \| 'blur'` | `'change'` | When to validate |
42
- | `helpText` | `String` | `undefined` | Help text |
68
+ ```vue
69
+ <script setup lang="ts">
70
+ import { ref } from 'vue'
71
+ import type { FormSelectOption } from '@velkymx/vibeui'
43
72
 
44
- ## Important Notes
73
+ const tags = ref<string[]>([])
74
+ const options: FormSelectOption[] = [
75
+ { value: 'vue', text: 'Vue' },
76
+ { value: 'ts', text: 'TypeScript' },
77
+ { value: 'bs', text: 'Bootstrap' }
78
+ ]
79
+ </script>
80
+
81
+ <template>
82
+ <VibeFormGroup label="Tags">
83
+ <VibeFormSelect v-model="tags" :options="options" multiple :select-size="5" />
84
+ </VibeFormGroup>
85
+ </template>
86
+ ```
45
87
 
46
- **Automatic ID Generation:** This component automatically generates a unique ID if one is not provided.
88
+ ## Important Notes
47
89
 
48
- **Automatic ID Injection:** When used inside a `VibeFormGroup`, this component will automatically inherit the group's ID to ensure proper label association and accessibility.
90
+ - **Non-string values preserved:** option values keep their original type (`number`, `boolean`, etc.). The component encodes options by index internally, so `v-model` round-trips the exact value you do not have to stringify.
91
+ - **Placeholder:** only applies to single-select; it renders a disabled empty-value option.
92
+ - **Group linking:** wrapped in a `VibeFormGroup`, the select consumes the group id so the label and feedback link automatically.
49
93
 
50
94
  ## Bootstrap CSS Classes
51
95
 
52
96
  - `.form-select`
53
- - `.form-select-{size}`
97
+ - `.form-select-{sm|lg}`
54
98
  - `.is-valid`, `.is-invalid`
@@ -1,55 +1,94 @@
1
1
  # VibeFormSpinbutton
2
2
 
3
- Numeric input component with increment and decrement buttons.
3
+ Numeric input flanked by increment and decrement buttons, with clamping, stepping, and built-in validation.
4
4
 
5
- ## Basic Usage
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `modelValue` | `number` | `0` | The numeric value (v-model). |
10
+ | `id` | `string` | auto-generated | Element id. Auto-generated, or inherited from a parent `VibeFormGroup`. |
11
+ | `label` | `string` | `undefined` | Standalone label text. |
12
+ | `disabled` | `boolean` | `false` | Disable the control. |
13
+ | `readonly` | `boolean` | `false` | Make the input read-only (buttons are also disabled). |
14
+ | `required` | `boolean` | `false` | Mark as required. |
15
+ | `min` | `number` | `undefined` | Minimum value (clamped on change/blur). |
16
+ | `max` | `number` | `undefined` | Maximum value (clamped on change/blur). |
17
+ | `step` | `number` | `1` | Increment/decrement step. Must be greater than 0. |
18
+ | `wrap` | `boolean` | `false` | Wrap from max back to min (and vice versa) at the bounds. |
19
+ | `vertical` | `boolean` | `false` | Stack the buttons vertically. |
20
+ | `size` | `'sm' \| 'lg'` | `undefined` | Control size. |
21
+ | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Visual validation state. |
22
+ | `validationMessage` | `string` | `undefined` | Feedback message for the current state. |
23
+ | `validationRules` | `ValidationRule[] \| ValidatorFunction` | `undefined` | Rules carried for use with a validation composable. |
24
+ | `validateOn` | `'input' \| 'blur' \| 'change'` | `'blur'` | When the `validate` event fires from typing. |
25
+ | `helpText` | `string` | `undefined` | Help text below the control. |
26
+
27
+ ## Events
28
+
29
+ | Event | Payload | Description |
30
+ |-------|---------|-------------|
31
+ | `update:modelValue` | `number` | Emitted whenever the value changes. |
32
+ | `increment` | `number` | Emitted with the new value after the increment button is pressed. |
33
+ | `decrement` | `number` | Emitted with the new value after the decrement button is pressed. |
34
+ | `input` | `Event` | Native input event (typing). |
35
+ | `change` | `Event` | Native change event. |
36
+ | `blur` | `FocusEvent` | Emitted on blur. |
37
+ | `focus` | `FocusEvent` | Emitted on focus. |
38
+ | `validate` | — | Emitted on each button press and on the `validateOn` typing trigger. |
39
+
40
+ ## Slots
41
+
42
+ None.
43
+
44
+ ## Usage
45
+
46
+ ### Recommended: inside a VibeFormGroup
47
+
48
+ ```vue
49
+ <script setup lang="ts">
50
+ import { ref } from 'vue'
51
+ const quantity = ref(1)
52
+ </script>
53
+
54
+ <template>
55
+ <VibeFormGroup label="Quantity">
56
+ <VibeFormSpinbutton v-model="quantity" :min="1" :max="10" />
57
+ </VibeFormGroup>
58
+ </template>
59
+ ```
60
+
61
+ ### Stepping and wrapping
6
62
 
7
63
  ```vue
8
64
  <script setup lang="ts">
9
65
  import { ref } from 'vue'
10
- const count = ref(0)
66
+ const rating = ref(0)
67
+ const onIncrement = (value: number) => console.log('new value', value)
11
68
  </script>
12
69
 
13
70
  <template>
14
71
  <VibeFormSpinbutton
15
- v-model="count"
16
- label="Quantity"
72
+ v-model="rating"
17
73
  :min="0"
18
- :max="10"
74
+ :max="5"
75
+ :step="0.5"
76
+ wrap
77
+ @increment="onIncrement"
19
78
  />
20
79
  </template>
21
80
  ```
22
81
 
23
- ## Props
24
-
25
- | Prop | Type | Default | Description |
26
- |------|------|---------|-------------|
27
- | `modelValue` | `Number` | `0` | The numeric value (v-model) |
28
- | `id` | `String` | `Auto-generated` | Unique identifier |
29
- | `label` | `String` | `undefined` | Label text |
30
- | `disabled` | `Boolean` | `false` | Disable the spinbutton |
31
- | `readonly` | `Boolean` | `false` | Make readonly |
32
- | `required` | `Boolean` | `false` | Mark as required |
33
- | `min` | `Number` | `undefined` | Minimum value |
34
- | `max` | `Number` | `undefined` | Maximum value |
35
- | `step` | `Number` | `1` | Increment/decrement step |
36
- | `size` | `'sm' \| 'lg'` | `undefined` | Button and input size |
37
- | `wrap` | `Boolean` | `false` | Wrap around when min/max reached |
38
- | `vertical` | `Boolean` | `false` | Stack buttons vertically |
39
- | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Validation state |
40
- | `validationMessage` | `String` | `undefined` | Validation message |
41
- | `validateOn` | `'input' \| 'blur' \| 'change'` | `'blur'` | When to validate |
42
- | `helpText` | `String` | `undefined` | Help text |
43
-
44
82
  ## Important Notes
45
83
 
46
- **Automatic ID Generation:** This component automatically generates a unique ID if one is not provided.
47
-
48
- **Automatic ID Injection:** When used inside a `VibeFormGroup`, this component will automatically inherit the group's ID to ensure proper label association and accessibility.
84
+ - **`step` must be greater than 0.** Decimal steps are snapped to the step's precision (e.g. `step="0.5"` keeps one decimal place).
85
+ - **Clamping:** typed values are clamped to `min`/`max` on `change` and `blur`; an empty field is treated as `0`.
86
+ - **`increment` / `decrement` payload:** both events carry the resulting numeric value, so you do not need to read `modelValue` separately.
87
+ - **Number model only:** when using a validation composable, bind to `.value` (a dev-mode warning fires if an object is passed).
49
88
 
50
89
  ## Bootstrap CSS Classes
51
90
 
52
- - `.form-control`
53
- - `.input-group`
54
- - `.btn`
91
+ - `.input-group`, `.input-group-{sm|lg}`
92
+ - `.form-control`, `.form-control-{sm|lg}`
93
+ - `.btn`, `.btn-outline-secondary`
55
94
  - `.is-valid`, `.is-invalid`
@@ -1,47 +1,75 @@
1
1
  # VibeFormSwitch
2
2
 
3
- Toggle switch component for boolean values.
3
+ Toggle switch for boolean values, rendered as an accessible `role="switch"` control.
4
4
 
5
- ## Basic Usage
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `modelValue` | `boolean` | `false` | The toggle state (v-model). |
10
+ | `id` | `string` | auto-generated | Element id. Auto-generated, or inherited from a parent `VibeFormGroup`. |
11
+ | `label` | `string` | `undefined` | Switch label text. |
12
+ | `disabled` | `boolean` | `false` | Disable the switch. |
13
+ | `required` | `boolean` | `false` | Mark as required. |
14
+ | `inline` | `boolean` | `false` | Render inline (`.form-check-inline`). |
15
+ | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Visual validation state. |
16
+ | `validationMessage` | `string` | `undefined` | Feedback message for the current state. |
17
+ | `validationRules` | `ValidationRule[] \| ValidatorFunction` | `undefined` | Rules carried for use with a validation composable. |
18
+ | `validateOn` | `'change' \| 'blur'` | `'change'` | When the `validate` event fires. |
19
+ | `helpText` | `string` | `undefined` | Help text below the switch. |
20
+
21
+ ## Events
22
+
23
+ | Event | Payload | Description |
24
+ |-------|---------|-------------|
25
+ | `update:modelValue` | `boolean` | Emitted on toggle. |
26
+ | `change` | `Event` | Native change event. |
27
+ | `blur` | `FocusEvent` | Emitted on blur. |
28
+ | `focus` | `FocusEvent` | Emitted on focus. |
29
+ | `validate` | — | Emitted when the `validateOn` trigger occurs. |
30
+
31
+ ## Slots
32
+
33
+ None.
34
+
35
+ ## Usage
36
+
37
+ ### Standalone
6
38
 
7
39
  ```vue
8
40
  <script setup lang="ts">
9
41
  import { ref } from 'vue'
10
- const isEnabled = ref(false)
42
+ const notifications = ref(true)
11
43
  </script>
12
44
 
13
45
  <template>
14
- <VibeFormSwitch
15
- v-model="isEnabled"
16
- label="Enable notifications"
17
- />
46
+ <VibeFormSwitch v-model="notifications" label="Email notifications" />
18
47
  </template>
19
48
  ```
20
49
 
21
- ## Props
50
+ ### Inside a VibeFormGroup
22
51
 
23
- | Prop | Type | Default | Description |
24
- |------|------|---------|-------------|
25
- | `modelValue` | `Boolean` | `false` | The toggle state (v-model) |
26
- | `id` | `String` | `Auto-generated` | Unique identifier |
27
- | `label` | `String` | `undefined` | Label text |
28
- | `disabled` | `Boolean` | `false` | Disable the switch |
29
- | `required` | `Boolean` | `false` | Mark as required |
30
- | `inline` | `Boolean` | `false` | Display inline |
31
- | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Validation state |
32
- | `validationMessage` | `String` | `undefined` | Validation message |
33
- | `validateOn` | `'change' \| 'blur'` | `'change'` | When to validate |
34
- | `helpText` | `String` | `undefined` | Help text |
52
+ ```vue
53
+ <script setup lang="ts">
54
+ import { ref } from 'vue'
55
+ const darkMode = ref(false)
56
+ </script>
35
57
 
36
- ## Important Notes
58
+ <template>
59
+ <VibeFormGroup label="Appearance">
60
+ <VibeFormSwitch v-model="darkMode" label="Dark mode" />
61
+ </VibeFormGroup>
62
+ </template>
63
+ ```
37
64
 
38
- **Automatic ID Generation:** This component automatically generates a unique ID if one is not provided.
65
+ ## Important Notes
39
66
 
40
- **Automatic ID Injection:** When used inside a `VibeFormGroup`, this component will automatically inherit the group's ID to ensure proper label association and accessibility.
67
+ - **Accessibility:** the underlying input is a checkbox with `role="switch"` and Bootstrap's `.form-switch` styling.
68
+ - **Group linking:** wrapped in a `VibeFormGroup`, the switch consumes the group id so the label and feedback link automatically.
41
69
 
42
70
  ## Bootstrap CSS Classes
43
71
 
44
72
  - `.form-check`, `.form-switch`
45
- - `.form-check-input`
46
- - `.form-check-label`
73
+ - `.form-check-input`, `.form-check-label`
74
+ - `.form-check-inline`
47
75
  - `.is-valid`, `.is-invalid`