@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,51 +1,82 @@
1
1
  # VibeFormTextarea
2
2
 
3
- Multi-line text input component.
3
+ Multi-line text input with optional character counting, built-in validation, and accessibility.
4
4
 
5
- ## Basic Usage
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `modelValue` | `string` | `''` | The textarea 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
+ | `placeholder` | `string` | `undefined` | Placeholder text. |
13
+ | `rows` | `number \| string` | `3` | Number of visible text rows. |
14
+ | `maxlength` | `number \| string` | `undefined` | Maximum character count (also shown in the counter when `showCharCount` is set). |
15
+ | `disabled` | `boolean` | `false` | Disable the textarea. |
16
+ | `readonly` | `boolean` | `false` | Make the textarea read-only. |
17
+ | `required` | `boolean` | `false` | Mark as required. |
18
+ | `size` | `'sm' \| 'lg'` | `undefined` | Control size. |
19
+ | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Visual validation state. |
20
+ | `validationMessage` | `string` | `undefined` | Feedback message for the current state. |
21
+ | `validationRules` | `ValidationRule[] \| ValidatorFunction` | `undefined` | Rules carried for use with a validation composable. |
22
+ | `validateOn` | `'input' \| 'blur' \| 'change'` | `'blur'` | When the `validate` event fires. |
23
+ | `helpText` | `string` | `undefined` | Help text below the textarea. |
24
+ | `noResize` | `boolean` | `false` | Disable manual resizing (`resize: none`). |
25
+ | `showCharCount` | `boolean` | `false` | Show a character counter (`count` or `count / maxlength`). |
26
+
27
+ ## Events
28
+
29
+ | Event | Payload | Description |
30
+ |-------|---------|-------------|
31
+ | `update:modelValue` | `string` | Emitted on input. |
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
6
45
 
7
46
  ```vue
8
47
  <script setup lang="ts">
9
48
  import { ref } from 'vue'
10
- const text = ref('')
49
+ const bio = ref('')
11
50
  </script>
12
51
 
13
52
  <template>
14
- <VibeFormTextarea
15
- v-model="text"
16
- label="Comments"
17
- placeholder="Enter your comments here..."
18
- />
53
+ <VibeFormGroup label="Bio">
54
+ <VibeFormTextarea v-model="bio" :rows="5" :maxlength="280" show-char-count />
55
+ </VibeFormGroup>
19
56
  </template>
20
57
  ```
21
58
 
22
- ## Props
59
+ ### Standalone
23
60
 
24
- | Prop | Type | Default | Description |
25
- |------|------|---------|-------------|
26
- | `modelValue` | `String` | `''` | The textarea value (v-model) |
27
- | `id` | `String` | `Auto-generated` | Unique identifier |
28
- | `label` | `String` | `undefined` | Label text |
29
- | `placeholder` | `String` | `undefined` | Placeholder text |
30
- | `rows` | `Number \| String` | `3` | Number of visible rows |
31
- | `disabled` | `Boolean` | `false` | Disable the textarea |
32
- | `readonly` | `Boolean` | `false` | Make readonly |
33
- | `required` | `Boolean` | `false` | Mark as required |
34
- | `size` | `'sm' \| 'lg'` | `undefined` | Textarea 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
- | `noResize` | `Boolean` | `false` | Disable resizing |
61
+ ```vue
62
+ <script setup lang="ts">
63
+ import { ref } from 'vue'
64
+ const notes = ref('')
65
+ </script>
40
66
 
41
- ## Important Notes
67
+ <template>
68
+ <VibeFormTextarea v-model="notes" label="Notes" no-resize />
69
+ </template>
70
+ ```
42
71
 
43
- **Automatic ID Generation:** This component automatically generates a unique ID if one is not provided.
72
+ ## Important Notes
44
73
 
45
- **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
+ - **Character counter:** `showCharCount` renders inside the help-text row. When inside a `VibeFormGroup` that provides its own help text, the counter is suppressed (the group owns help rendering).
75
+ - **Group linking:** wrapped in a `VibeFormGroup`, the textarea consumes the group id so the label and feedback link automatically.
46
76
 
47
77
  ## Bootstrap CSS Classes
48
78
 
49
79
  - `.form-control`
50
- - `.form-control-{size}`
80
+ - `.form-control-{sm|lg}`
51
81
  - `.is-valid`, `.is-invalid`
82
+ - `.form-text`
@@ -1,64 +1,99 @@
1
1
  # VibeFormWysiwyg
2
2
 
3
- WYSIWYG (What You See Is What You Get) editor component powered by QuillJS.
3
+ Rich-text editor powered by Quill. HTML is sanitized with DOMPurify on the way in and on the way out (XSS defense-in-depth).
4
4
 
5
- ## Installation
5
+ ## Peer dependencies
6
6
 
7
- First, install Quill as a dependency:
7
+ This component requires two optional peers — install both:
8
8
 
9
9
  ```bash
10
- npm install quill
10
+ npm install quill dompurify
11
11
  ```
12
12
 
13
- ## Basic Usage
13
+ Quill and DOMPurify are loaded lazily on mount. If `quill` is missing, the component shows a warning alert and emits a `component-error` event instead of crashing.
14
+
15
+ ## Props
16
+
17
+ | Prop | Type | Default | Description |
18
+ |------|------|---------|-------------|
19
+ | `modelValue` | `string` | `''` | HTML content (v-model). Sanitized with DOMPurify before being rendered. |
20
+ | `id` | `string` | auto-generated | Element id. Auto-generated, or inherited from a parent `VibeFormGroup`. |
21
+ | `label` | `string` | `undefined` | Label text. |
22
+ | `placeholder` | `string` | `'Write something...'` | Placeholder shown when empty. |
23
+ | `disabled` | `boolean` | `false` | Disable editing. |
24
+ | `readonly` | `boolean` | `false` | Make the editor read-only. |
25
+ | `required` | `boolean` | `false` | Mark as required. |
26
+ | `theme` | `'snow' \| 'bubble'` | `'snow'` | Quill theme. |
27
+ | `toolbar` | `unknown[] \| string \| boolean` | `undefined` | Toolbar config: a Quill toolbar array, a preset name (`'minimal'`, `'standard'`, `'full'`), `false` to hide, or omit for the default toolbar. |
28
+ | `mobileToolbar` | `unknown[] \| string \| boolean` | `undefined` | Toolbar used at mobile breakpoints (same value forms as `toolbar`). |
29
+ | `height` | `string` | `'200px'` | Minimum editor height. Must be a valid CSS length; invalid values fall back to `200px`. |
30
+ | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Visual validation state. |
31
+ | `validationMessage` | `string` | `undefined` | Feedback message for the current state. |
32
+ | `validationRules` | `ValidationRule[] \| ValidatorFunction` | `undefined` | Rules carried for use with a validation composable. |
33
+ | `validateOn` | `'change' \| 'blur'` | `'blur'` | When the `validate` event fires. |
34
+ | `helpText` | `string` | `undefined` | Help text below the editor. |
35
+
36
+ ## Events
37
+
38
+ | Event | Payload | Description |
39
+ |-------|---------|-------------|
40
+ | `update:modelValue` | `string` | Emitted with sanitized HTML as content changes. |
41
+ | `change` | — | Emitted on content change. |
42
+ | `blur` | — | Emitted on blur. |
43
+ | `focus` | — | Emitted on focus. |
44
+ | `validate` | — | Emitted when the `validateOn` trigger occurs. |
45
+ | `ready` | `unknown` | Emitted with the Quill instance once initialized. |
46
+ | `component-error` | `ComponentError` | Emitted if Quill fails to load (e.g. peer not installed). |
47
+
48
+ ## Slots
49
+
50
+ None.
51
+
52
+ ## Usage
53
+
54
+ ### Recommended: inside a VibeFormGroup
14
55
 
15
56
  ```vue
16
57
  <script setup lang="ts">
17
58
  import { ref } from 'vue'
18
- const content = ref('')
59
+ const content = ref('<p>Hello <strong>world</strong></p>')
19
60
  </script>
20
61
 
21
62
  <template>
22
- <VibeFormWysiwyg
23
- v-model="content"
24
- label="Content"
25
- placeholder="Write something amazing..."
26
- />
63
+ <VibeFormGroup label="Description">
64
+ <VibeFormWysiwyg v-model="content" toolbar="standard" height="300px" />
65
+ </VibeFormGroup>
27
66
  </template>
28
67
  ```
29
68
 
30
- ## Props
69
+ ### Handling a missing peer
31
70
 
32
- | Prop | Type | Default | Description |
33
- |------|------|---------|-------------|
34
- | `modelValue` | `String` | `''` | The HTML content (v-model) |
35
- | `id` | `String` | `Auto-generated` | Unique identifier |
36
- | `label` | `String` | `undefined` | Label text |
37
- | `placeholder` | `String` | `'Write something...'` | Placeholder text |
38
- | `disabled` | `Boolean` | `false` | Disable the editor |
39
- | `readonly` | `Boolean` | `false` | Make readonly |
40
- | `required` | `Boolean` | `false` | Mark as required |
41
- | `theme` | `'snow' \| 'bubble'` | `'snow'` | Quill theme |
42
- | `toolbar` | `Array \| String \| Boolean` | default toolbar | Full toolbar configuration |
43
- | `mobileToolbar` | `Array \| String \| Boolean` | default mobile toolbar | Simplified toolbar for small screens |
44
- | `height` | `String` | `'200px'` | Minimum height |
45
- | `validationState` | `'valid' \| 'invalid' \| null` | `null` | Validation state |
46
- | `validationMessage` | `String` | `undefined` | Validation message |
47
- | `validationRules` | `ValidationRule[] \| ValidatorFunction` | `undefined` | Validation rules |
48
- | `validateOn` | `'change' \| 'blur'` | `'blur'` | When to validate |
49
- | `helpText` | `String` | `undefined` | Help text |
71
+ ```vue
72
+ <script setup lang="ts">
73
+ import { ref } from 'vue'
74
+ import type { ComponentError } from '@velkymx/vibeui'
50
75
 
51
- ## Important Notes
76
+ const content = ref('')
77
+ const onError = (err: ComponentError) => console.error(err.message)
78
+ </script>
52
79
 
53
- **Automatic Initialization:** This component dynamically imports Quill and initializes it when mounted. If Quill is not installed in your project, it will display a helpful error message.
80
+ <template>
81
+ <VibeFormWysiwyg v-model="content" @component-error="onError" />
82
+ </template>
83
+ ```
54
84
 
55
- **Lifecycle Management:** VibeFormWysiwyg automatically cleans up its internal Quill instance and removes orphaned toolbar elements from the DOM on unmount to prevent memory leaks.
85
+ ## Important Notes
56
86
 
57
- **Automatic ID Injection:** When used inside a `VibeFormGroup`, this component will automatically inherit the group's ID for proper label association.
87
+ - **Sanitization:** incoming `modelValue` HTML is sanitized before it is rendered, and the emitted HTML is sanitized too. Unsafe tags and attributes (e.g. `<script>`, inline event handlers) are stripped. Do not rely on the editor to preserve dangerous markup.
88
+ - **Both peers required:** `dompurify` is needed for sanitization and `quill` for the editor; install them together.
89
+ - **`height` is validated:** only CSS length values are accepted; anything else falls back to `200px`.
90
+ - **Responsive toolbar:** at mobile breakpoints `mobileToolbar` (or a compact default) is used, and the editor re-initializes while preserving content.
91
+ - **Group linking:** wrapped in a `VibeFormGroup`, the editor consumes the group id so the label and feedback link automatically.
58
92
 
59
93
  ## Bootstrap CSS Classes
60
94
 
61
- - `.vibe-wysiwyg-container`
62
- - `.is-valid`
63
- - `.is-invalid`
64
- - Uses native Quill CSS classes internally.
95
+ - `.form-label`, `.form-text`
96
+ - `.alert`, `.alert-warning` (load-failure message)
97
+ - `.valid-feedback`, `.invalid-feedback`
98
+
99
+ The editor shell uses VibeUI's own `.vibe-wysiwyg-container` class plus Quill's `.ql-*` classes.
@@ -1,51 +1,70 @@
1
1
  # VibeInputGroup
2
2
 
3
- Input groups allow you to prepend or append text, buttons, or other elements to your input fields.
4
-
5
- ## Basic Usage
6
-
7
- ```vue
8
- <VibeInputGroup prepend="@">
9
- <VibeFormInput noWrapper v-model="username" placeholder="Username" />
10
- </VibeInputGroup>
11
-
12
- <VibeInputGroup append=".00">
13
- <VibeFormInput noWrapper v-model="price" placeholder="Price" />
14
- </VibeInputGroup>
15
- ```
3
+ Wraps a control with prepended/appended text, buttons, or other elements using Bootstrap's input-group.
16
4
 
17
5
  ## Props
18
6
 
19
7
  | Prop | Type | Default | Description |
20
8
  |------|------|---------|-------------|
21
- | `prepend` | `String` | `undefined` | Shorthand for prepending text |
22
- | `append` | `String` | `undefined` | Shorthand for appending text |
23
- | `size` | `'sm' \| 'lg'` | `undefined` | Size of the input group |
24
- | `tag` | `String` | `'div'` | HTML tag to use for the container |
9
+ | `size` | `'sm' \| 'lg'` | `undefined` | Input-group size. |
10
+ | `prepend` | `string` | `undefined` | Convenience text rendered before the control as `.input-group-text`. |
11
+ | `append` | `string` | `undefined` | Convenience text rendered after the control as `.input-group-text`. |
12
+ | `tag` | `Tag` | `'div'` | Root element tag. |
13
+
14
+ ## Events
15
+
16
+ None.
25
17
 
26
18
  ## Slots
27
19
 
28
20
  | Slot | Description |
29
21
  |------|-------------|
30
- | `default` | The main content, usually a `VibeFormInput` with the `noWrapper` prop |
31
- | `prepend` | Slot for complex prepend content (e.g., icons or buttons) |
32
- | `append` | Slot for complex append content |
22
+ | default | The control to wrap (typically a `VibeFormInput` with `no-wrapper`). |
23
+ | `prepend` | Custom prepended content (overrides the `prepend` prop). |
24
+ | `append` | Custom appended content (overrides the `append` prop). |
33
25
 
34
- ## Advanced Example
26
+ ## Usage
27
+
28
+ ### Text prepend / append
35
29
 
36
30
  ```vue
37
- <VibeInputGroup>
38
- <template #prepend>
39
- <VibeButton variant="outline-secondary">Search</VibeButton>
40
- </template>
41
- <VibeFormInput noWrapper v-model="query" />
42
- <template #append>
43
- <span class="input-group-text">
44
- <VibeIcon name="search" />
45
- </span>
46
- </template>
47
- </VibeInputGroup>
31
+ <script setup lang="ts">
32
+ import { ref } from 'vue'
33
+ const price = ref('')
34
+ </script>
35
+
36
+ <template>
37
+ <VibeInputGroup prepend="$" append=".00">
38
+ <VibeFormInput v-model="price" type="number" no-wrapper />
39
+ </VibeInputGroup>
40
+ </template>
48
41
  ```
49
42
 
50
- ## Mobile Note
51
- Input groups work seamlessly with the `noWrapper` prop on `VibeFormInput`, ensuring that the Bootstrap `.input-group` classes apply correctly without extra wrapping divs breaking the layout.
43
+ ### Custom slots with a button
44
+
45
+ ```vue
46
+ <script setup lang="ts">
47
+ import { ref } from 'vue'
48
+ const term = ref('')
49
+ </script>
50
+
51
+ <template>
52
+ <VibeInputGroup>
53
+ <VibeFormInput v-model="term" placeholder="Search" no-wrapper />
54
+ <template #append>
55
+ <VibeButton variant="primary">Go</VibeButton>
56
+ </template>
57
+ </VibeInputGroup>
58
+ </template>
59
+ ```
60
+
61
+ ## Important Notes
62
+
63
+ - **Use `no-wrapper` on the input:** pass `no-wrapper` to `VibeFormInput` so it renders just the `<input>` and Bootstrap can style it as part of the group.
64
+ - **Slots override props:** providing the `prepend`/`append` slots replaces the corresponding text props.
65
+
66
+ ## Bootstrap CSS Classes
67
+
68
+ - `.input-group`
69
+ - `.input-group-{sm|lg}`
70
+ - `.input-group-text`