@maltjoy/mcp-server 0.4.0 → 0.6.0-beta.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 (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -3
  3. package/dist/doc/VJoyAdminBanner/guideline.md +284 -0
  4. package/dist/doc/VJoyAvailability/guideline.md +352 -0
  5. package/dist/doc/VJoyAvatar/guideline.md +192 -0
  6. package/dist/doc/VJoyAvatarsList/guideline.md +328 -0
  7. package/dist/doc/VJoyBadge/guideline.md +169 -0
  8. package/dist/doc/VJoyBadgeLevel/guideline.md +166 -0
  9. package/dist/doc/VJoyBlockSkeleton/guideline.md +150 -0
  10. package/dist/doc/VJoyBottomSheet/guideline.md +345 -0
  11. package/dist/doc/VJoyBottomSheetTrigger/guideline.md +156 -0
  12. package/dist/doc/VJoyButton/guideline.md +371 -0
  13. package/dist/doc/VJoyButton/metadata.json +0 -16
  14. package/dist/doc/VJoyButtonCard/guideline.md +384 -0
  15. package/dist/doc/VJoyCheckbox/guideline.md +317 -0
  16. package/dist/doc/VJoyCheckboxCard/guideline.md +381 -0
  17. package/dist/doc/VJoyCheckboxGroup/guideline.md +363 -0
  18. package/dist/doc/VJoyCheckboxGroup/metadata.json +7 -7
  19. package/dist/doc/VJoyCollapse/guideline.md +362 -0
  20. package/dist/doc/VJoyCollapseItem/guideline.md +394 -0
  21. package/dist/doc/VJoyCompanyAvatar/guideline.md +162 -0
  22. package/dist/doc/VJoyDialog/guideline.md +425 -0
  23. package/dist/doc/VJoyDialogTrigger/guideline.md +186 -0
  24. package/dist/doc/VJoyDot/guideline.md +177 -0
  25. package/dist/doc/VJoyDrawer/guideline.md +392 -0
  26. package/dist/doc/VJoyDrawerTrigger/guideline.md +145 -0
  27. package/dist/doc/VJoyDropdown/guideline.md +393 -0
  28. package/dist/doc/VJoyDropdown/metadata.json +6 -6
  29. package/dist/doc/VJoyDropdownList/guideline.md +396 -0
  30. package/dist/doc/VJoyDropdownList/metadata.json +7 -7
  31. package/dist/doc/VJoyDropzone/guideline.md +390 -0
  32. package/dist/doc/VJoyDropzone/metadata.json +36 -1
  33. package/dist/doc/VJoyFilterBar/guideline.md +419 -0
  34. package/dist/doc/VJoyFilterBarButton/guideline.md +359 -0
  35. package/dist/doc/VJoyFloatingActionsBar/guideline.md +372 -0
  36. package/dist/doc/VJoyFormError/guideline.md +325 -0
  37. package/dist/doc/VJoyFormError/metadata.json +0 -14
  38. package/dist/doc/VJoyFormFieldSkeleton/guideline.md +159 -0
  39. package/dist/doc/VJoyFormGroup/guideline.md +285 -0
  40. package/dist/doc/VJoyFunnel/guideline.md +349 -0
  41. package/dist/doc/VJoyFunnelFooter/guideline.md +178 -0
  42. package/dist/doc/VJoyFunnelHeader/guideline.md +204 -0
  43. package/dist/doc/VJoyHighlight/guideline.md +169 -0
  44. package/dist/doc/VJoyIcon/JoyIcon.types.ts +1 -1
  45. package/dist/doc/VJoyIcon/guideline.md +168 -0
  46. package/dist/doc/VJoyIcon/metadata.json +0 -1
  47. package/dist/doc/VJoyIconButton/guideline.md +169 -0
  48. package/dist/doc/VJoyIconButton/metadata.json +1 -1
  49. package/dist/doc/VJoyIndicator/guideline.md +168 -0
  50. package/dist/doc/VJoyIndicators/guideline.md +183 -0
  51. package/dist/doc/VJoyInput/JoyInput.types.ts +1 -6
  52. package/dist/doc/VJoyInput/guideline.md +401 -0
  53. package/dist/doc/VJoyInput/metadata.json +5 -14
  54. package/dist/doc/VJoyInputDigit/guideline.md +381 -0
  55. package/dist/doc/VJoyInputNumber/guideline.md +414 -0
  56. package/dist/doc/VJoyInputNumber/metadata.json +22 -17
  57. package/dist/doc/VJoyInputPassword/guideline.md +379 -0
  58. package/dist/doc/VJoyInputPassword/metadata.json +0 -14
  59. package/dist/doc/VJoyLabel/guideline.md +200 -0
  60. package/dist/doc/VJoyLink/guideline.md +360 -0
  61. package/dist/doc/VJoyListItem/guideline.md +335 -0
  62. package/dist/doc/VJoyMenu/guideline.md +304 -0
  63. package/dist/doc/VJoyMenu/metadata.json +21 -21
  64. package/dist/doc/VJoyMenuItem/guideline.md +352 -0
  65. package/dist/doc/VJoyPagination/guideline.md +355 -0
  66. package/dist/doc/VJoyPanel/guideline.md +238 -0
  67. package/dist/doc/VJoyPanelSection/guideline.md +160 -0
  68. package/dist/doc/VJoyPasswordRequirement/guideline.md +336 -0
  69. package/dist/doc/VJoyPasswordRequirement/metadata.json +1 -1
  70. package/dist/doc/VJoyProductTour/JoyProductTour.types.ts +0 -1
  71. package/dist/doc/VJoyProductTour/guideline.md +455 -0
  72. package/dist/doc/VJoyProductTour/metadata.json +1 -1
  73. package/dist/doc/VJoyProductTourTrigger/guideline.md +167 -0
  74. package/dist/doc/VJoyProgressBar/guideline.md +348 -0
  75. package/dist/doc/VJoyRadio/guideline.md +346 -0
  76. package/dist/doc/VJoyRadioGroup/guideline.md +331 -0
  77. package/dist/doc/VJoyRatingStars/guideline.md +306 -0
  78. package/dist/doc/VJoyScreenLoader/guideline.md +172 -0
  79. package/dist/doc/VJoySelect/guideline.md +396 -0
  80. package/dist/doc/VJoySelectableItem/guideline.md +351 -0
  81. package/dist/doc/VJoySelectableItemGroup/guideline.md +370 -0
  82. package/dist/doc/VJoySeparator/guideline.md +161 -0
  83. package/dist/doc/VJoySnackbar/guideline.md +402 -0
  84. package/dist/doc/VJoySpinner/guideline.md +168 -0
  85. package/dist/doc/VJoyStep/guideline.md +182 -0
  86. package/dist/doc/VJoyStepper/guideline.md +390 -0
  87. package/dist/doc/VJoyTab/guideline.md +298 -0
  88. package/dist/doc/VJoyTabs/guideline.md +353 -0
  89. package/dist/doc/VJoyTag/guideline.md +226 -0
  90. package/dist/doc/VJoyTagsInput/guideline.md +387 -0
  91. package/dist/doc/VJoyTagsList/guideline.md +311 -0
  92. package/dist/doc/VJoyTagsList/metadata.json +27 -27
  93. package/dist/doc/VJoyTemplate/guideline.md +366 -0
  94. package/dist/doc/VJoyText/guideline.md +175 -0
  95. package/dist/doc/VJoyText/metadata.json +1 -1
  96. package/dist/doc/VJoyTextarea/guideline.md +378 -0
  97. package/dist/doc/VJoyTitleBrand/guideline.md +155 -0
  98. package/dist/doc/VJoyToggle/guideline.md +327 -0
  99. package/dist/doc/VJoyTooltip/guideline.md +322 -0
  100. package/dist/doc/VJoyUserCard/guideline.md +268 -0
  101. package/dist/doc/VJoyUserCard/metadata.json +3 -17
  102. package/dist/doc/VJoyWalkthrough/guideline.md +351 -0
  103. package/dist/doc/VJoyWalkthroughTrigger/guideline.md +171 -0
  104. package/dist/doc/VJoyWrapper/guideline.md +173 -0
  105. package/dist/doc/css-classes.json +1 -15
  106. package/dist/doc/design-tokens.json +1 -0
  107. package/dist/doc/index.json +20 -30
  108. package/dist/index.js +22 -2
  109. package/dist/index.js.map +1 -1
  110. package/dist/tools/get-component-guideline.d.ts +30 -0
  111. package/dist/tools/get-component-guideline.d.ts.map +1 -0
  112. package/dist/tools/get-component-guideline.js +51 -0
  113. package/dist/tools/get-component-guideline.js.map +1 -0
  114. package/dist/tools/get-documentation-page.d.ts +22 -0
  115. package/dist/tools/get-documentation-page.d.ts.map +1 -0
  116. package/dist/tools/get-documentation-page.js +21 -0
  117. package/dist/tools/get-documentation-page.js.map +1 -0
  118. package/dist/tools/list-documentation-pages.d.ts +22 -0
  119. package/dist/tools/list-documentation-pages.d.ts.map +1 -0
  120. package/dist/tools/list-documentation-pages.js +17 -0
  121. package/dist/tools/list-documentation-pages.js.map +1 -0
  122. package/dist/tools/search-documentation.d.ts +41 -0
  123. package/dist/tools/search-documentation.d.ts.map +1 -0
  124. package/dist/tools/search-documentation.js +25 -0
  125. package/dist/tools/search-documentation.js.map +1 -0
  126. package/dist/zeroheight-parser.d.ts +27 -0
  127. package/dist/zeroheight-parser.d.ts.map +1 -0
  128. package/dist/zeroheight-parser.js +77 -0
  129. package/dist/zeroheight-parser.js.map +1 -0
  130. package/package.json +10 -10
  131. package/dist/doc/VJoyMultiCheckbox/metadata.json +0 -332
@@ -0,0 +1,363 @@
1
+ ---
2
+ component: VJoyCheckboxGroup
3
+ status: draft
4
+ language: en
5
+ dsds: JoyCheckboxGroup.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Checkbox group
10
+
11
+ Use **`VJoyCheckboxGroup`** when the user may select **zero, one, or more** options from a related set and you want selection managed as an **array** (`v-model:value`).
12
+
13
+ It renders a semantic `<fieldset>` with an optional group legend, lays out `VJoyCheckbox` (or `VJoyCheckboxCard`) children, and handles add/remove in the model when you pass `options`. Use the default slot when you need explicit children or card layouts.
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyCheckboxGroup` from `@maltjoy/core-vue` |
18
+ | **Design** | [Joy — Checkbox](https://zeroheight.com/6bf479565/) (page id `1423608`) |
19
+ | **Storybook** | [VJoyCheckboxGroup docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-forms-vjoycheckboxgroup--docs) |
20
+ | **DSDS (machine)** | [`JoyCheckboxGroup.dsds.json`](./JoyCheckboxGroup.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyCheckboxGroup")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use a checkbox group when several options are **independent** — filters, export formats, notification channels, permissions, or bulk-selection lists — and the bound state should be a **string array** of selected `value`s.
28
+
29
+ The `options` prop is the fast path for a uniform list of `VJoyCheckbox` rows. For `VJoyCheckboxCard`, mixed layouts, or per-option `disabled` / `invalid`, declare children in the **default slot** and wire `checked` + `@update:checked` via the slot props (`isChecked`, `updateModel`).
30
+
31
+ ### When not to use this component
32
+
33
+ | Need | Use instead |
34
+ | --- | --- |
35
+ | Exactly one option from a short list | `VJoyRadio` inside `VJoyRadioGroup` |
36
+ | A single on/off preference (settings row) | `VJoyToggle` |
37
+ | One standalone checkbox (consent, select-all row) | `VJoyCheckbox` alone |
38
+ | Rich card option without composing the group yourself | `VJoyCheckboxCard` inside `VJoyCheckboxGroup` (default slot) |
39
+ | Long or searchable option lists (roughly 8+) | `VJoySelect` or `VJoySelectableItemGroup` |
40
+ | Custom-styled checkbox list markup | Still use `VJoyCheckboxGroup` + Joy tokens — don’t reinvent chrome |
41
+
42
+ > **Deprecated:** `VJoyMultiCheckbox` is an alias kept for backward compatibility. Use `VJoyCheckboxGroup` for new work.
43
+
44
+ ---
45
+
46
+ ## How it works
47
+
48
+ ### Anatomy
49
+
50
+ | Part | Required? | What it is |
51
+ | --- | --- | --- |
52
+ | Fieldset wrapper | Yes | Root `<fieldset class="joy-checkbox-group__wrapper">` — groups related checkboxes for AT |
53
+ | Group legend | No | `VJoyLabel` as `<legend>` when `label` is set |
54
+ | Options container | Yes | Flex container (`.joy-checkbox-group`) with `direction` modifier |
55
+ | Checkbox children | Yes | `VJoyCheckbox` from `options`, or explicit children in the default slot |
56
+ | `checkbox` slot | No | Custom inner label per option when using `options` |
57
+ | Focus rings | Yes | On each child checkbox — don’t remove in product CSS |
58
+
59
+ The group `provide`s `JoyFormElementContext` so it integrates with Joy form field patterns.
60
+
61
+ ### Default values
62
+
63
+ - `options` defaults to **`[]`**
64
+ - `value` defaults to **`[]`** — bind with `v-model:value`
65
+ - `direction` defaults to **`vertical`**
66
+ - `required` defaults to **`false`**
67
+ - `labelSize` defaults to **`medium`**
68
+ - `requiredMark` defaults to **`false`**
69
+
70
+ Props, events, and slots: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
71
+
72
+ ### Layout (`direction`)
73
+
74
+ | Value | Use when |
75
+ | --- | --- |
76
+ | `vertical` | Default — stacked options, longer labels, or `VJoyCheckboxCard` with sublabels |
77
+ | `horizontal` | Few short labels in a row (filters, compact toolbars). Avoid horizontal `VJoyCheckboxCard` when sublabels or body copy are long |
78
+
79
+ Spacing between items uses `--joy-core-spacing-4` inside the group — **don’t hardcode gap or margin** on `.joy-checkbox-group` in apps.
80
+
81
+ ### Composition modes
82
+
83
+ **`options` prop** — Group renders `VJoyCheckbox` per option, syncs `v-model:value`, and supports the `checkbox` slot for custom label markup. Each option needs a stable `id` and distinct `value`.
84
+
85
+ **Default slot** — Replaces `options` rendering entirely. Slot props: `value`, `isChecked(value)`, `updateModel(value, checked)`. **You must** bind each child’s `checked` and `@update:checked` (or equivalent) — the group does not auto-wire children in this mode.
86
+
87
+ ---
88
+
89
+ ## States
90
+
91
+ Group-level behavior; per-checkbox hover, focus, checked, disabled, and invalid styling live on **`VJoyCheckbox`** / **`VJoyCheckboxCard`**.
92
+
93
+ | State | What the user sees / can do |
94
+ | --- | --- |
95
+ | Default | Zero or more options checked; each checkbox independently toggleable |
96
+ | Checked (per option) | Option’s `value` is present in `value` array; child shows checked styling |
97
+ | Unchecked (per option) | Option’s `value` absent from array |
98
+ | Disabled (per option) | Set on the child checkbox — use the default slot when an option in `options` must be disabled (`options` rendering does not pass `disabled` today) |
99
+ | Invalid (per option) | Set `invalid` on the child; pair with visible error text — don’t rely on color alone |
100
+ | Required group | `required` / `requiredMark` on the group affect the legend; enforce “at least one selected” in form validation and show `VJoyFormError` when needed |
101
+
102
+ **Array updates:** checking pushes `value` into the array; unchecking removes it. Order follows user interaction, not display order — compare with `Set` semantics if order must not matter.
103
+
104
+ ---
105
+
106
+ ## Best practices
107
+
108
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
109
+
110
+ ### Selection model
111
+
112
+ - **SHOULD** use checkbox groups when any combination of options is valid (including none), unless product rules require at least one.
113
+ - **MUST NOT** use a checkbox group when only one option may be selected — use `VJoyRadioGroup`.
114
+ - **SHOULD** keep **2–7** visible options; beyond that, consider `VJoySelect` or a searchable list.
115
+ - **SHOULD** use distinct, stable `value` strings (API keys); keep human copy in `label`.
116
+
117
+ ### Implementation
118
+
119
+ - **MUST** bind `v-model:value` (or `:value` + `@update:value`) to a string array.
120
+ - **MUST** give every option a unique `id` and `value`.
121
+ - **MUST** use only documented props and `direction` values from MCP (`vertical`, `horizontal`).
122
+ - **MUST** use Joy tokens — no custom `.joy-checkbox-group` layout overrides.
123
+ - **MUST NOT** invent props (`variant`, `size`, `multiple`, …).
124
+ - **SHOULD** prefer `options` for simple lists; use the **default slot** for `VJoyCheckboxCard`, mixed children, or per-option `disabled` / `invalid`.
125
+ - **SHOULD** set `name` on children when submitting native forms (via `option.name` or explicit props in the default slot).
126
+
127
+ ### Interaction
128
+
129
+ - **MUST** wire default-slot children with `isChecked` / `updateModel` — Storybook documents this explicitly.
130
+ - **SHOULD** use `direction="horizontal"` only when labels stay short on one line.
131
+ - **SHOULD** explain disabled options when the reason isn’t obvious from context.
132
+ - **SHOULD** validate “at least one required” at submit with a group-level message, not only `required` on the fieldset.
133
+
134
+ ### Do / don’t
135
+
136
+ | Do | Don’t |
137
+ | --- | --- |
138
+ | `v-model:value` as string array | Boolean per checkbox without syncing the array |
139
+ | Group `label` as the fieldset legend | Repeat the legend text in every option label |
140
+ | Default slot for cards / disabled options | Cram long sublabels into horizontal layout |
141
+ | `VJoyFormError` for group validation | Error color with no message |
142
+ | `VJoyCheckboxGroup` in filter dropdowns | Lone checkboxes with no group semantics |
143
+
144
+ ---
145
+
146
+ ## Content
147
+
148
+ Group copy frames the set; option labels name each choice. Follow the same label rules as `VJoyCheckbox`.
149
+
150
+ ### Legend (group label)
151
+
152
+ Write the **`label`** as a short question or category name:
153
+
154
+ - ✅ Notification channels
155
+ - ✅ Export formats
156
+ - ✅ Which permissions should this role have?
157
+
158
+ Avoid repeating this text in every checkbox label.
159
+
160
+ ### Option labels
161
+
162
+ **Noun phrase or short statement** per option, **parallel** grammar across siblings:
163
+
164
+ - ✅ Email · Push · SMS
165
+ - ✅ PDF · DOCX · XLSX
166
+
167
+ Use the `checkbox` slot (with `options`) or card `label` / `subLabel` when an option needs extra detail — not an overloaded primary label.
168
+
169
+ ### Writing rules
170
+
171
+ | Strength | Rule |
172
+ | --- | --- |
173
+ | **MUST** | Provide a group `label` when the set needs context for screen reader users (unless an adjacent heading already names the set) |
174
+ | **MUST** | Keep option labels scannable — describe the option, not the click action |
175
+ | **MUST NOT** | Duplicate the group legend in every option label |
176
+ | **MUST NOT** | Use Yes / No as the only labels in a multi-option list — name each outcome |
177
+ | **SHOULD** | ≤ 60 characters per option label; move detail to `subLabel` or card content |
178
+ | **SHOULD** | Use `optionalLabel` on the legend when the whole group is optional |
179
+ | **SHOULD** | Localize `label` and option copy; keep `value` as a stable programmatic key |
180
+
181
+ ### Patterns
182
+
183
+ **Filters** — Horizontal group with short labels inside `VJoyDropdown` (`close-on-select="false"` when users pick several before Apply). Legend names the dimension (`Status`, `Format`).
184
+
185
+ **Permissions / bulk export** — Vertical list; pre-check sensible defaults when product rules allow.
186
+
187
+ **Validation** — Legend + `VJoyFormError` below the group: ✅ `Select at least one format` + `Choose one or more formats to continue`.
188
+
189
+ ---
190
+
191
+ ## Accessibility
192
+
193
+ Behaviors (what must happen), not slogans.
194
+
195
+ | Behavior | Expectation |
196
+ | --- | --- |
197
+ | Role | Native `<fieldset>`; group name from `<legend>` (`VJoyLabel` when `label` is set) |
198
+ | Children | Each option remains a native checkbox (`VJoyCheckbox` / card wrapping one) |
199
+ | Name | Group from legend; each option from its label slot or `label` prop |
200
+ | Keyboard | **Tab** between checkboxes; **Space** toggles focused checkbox |
201
+ | Focus | Visible focus ring on each child — don’t remove in product CSS |
202
+ | Selection | Multiple selections allowed; state reflected in `value` array and each `checked` binding |
203
+ | Required | If the form requires at least one selection, expose failure in text (`VJoyFormError`), not only `required` on the fieldset |
204
+ | Disabled | `disabled` on individual inputs; explain restriction in visible copy when it matters |
205
+
206
+ Target: **WCAG 2.2 AA** where the product requires it.
207
+
208
+ ---
209
+
210
+ ## Examples
211
+
212
+ ```vue
213
+ <script setup lang="ts">
214
+ import { ref } from 'vue'
215
+ import { VJoyCheckboxGroup, VJoyCheckbox, VJoyCheckboxCard } from '@maltjoy/core-vue'
216
+
217
+ const formats = ref(['pdf'])
218
+ const channels = ref<string[]>([])
219
+ </script>
220
+
221
+ <template>
222
+ <!-- Options prop — managed array -->
223
+ <VJoyCheckboxGroup
224
+ v-model:value="formats"
225
+ label="Export formats"
226
+ :options="[
227
+ { id: 'fmt-pdf', value: 'pdf', label: 'PDF' },
228
+ { id: 'fmt-docx', value: 'docx', label: 'DOCX' },
229
+ { id: 'fmt-xlsx', value: 'xlsx', label: 'XLSX' },
230
+ ]"
231
+ />
232
+
233
+ <!-- Horizontal filters -->
234
+ <VJoyCheckboxGroup
235
+ v-model:value="channels"
236
+ label="Notification channels"
237
+ direction="horizontal"
238
+ :options="[
239
+ { id: 'ch-email', value: 'email', label: 'Email' },
240
+ { id: 'ch-push', value: 'push', label: 'Push' },
241
+ { id: 'ch-sms', value: 'sms', label: 'SMS' },
242
+ ]"
243
+ />
244
+
245
+ <!-- Default slot — explicit children (wire v-model helpers) -->
246
+ <VJoyCheckboxGroup v-model:value="formats" label="Plans">
247
+ <template #default="{ isChecked, updateModel }">
248
+ <VJoyCheckboxCard
249
+ id="plan-pro"
250
+ value="pro"
251
+ label="Pro"
252
+ sub-label="For growing teams"
253
+ :checked="isChecked('pro')"
254
+ @update:checked="(on) => updateModel('pro', on)"
255
+ />
256
+ <VJoyCheckboxCard
257
+ id="plan-enterprise"
258
+ value="enterprise"
259
+ label="Enterprise"
260
+ sub-label="Contact sales"
261
+ disabled
262
+ :checked="isChecked('enterprise')"
263
+ @update:checked="(on) => updateModel('enterprise', on)"
264
+ />
265
+ </template>
266
+ </VJoyCheckboxGroup>
267
+
268
+ <!-- Customize option label markup via checkbox slot -->
269
+ <VJoyCheckboxGroup
270
+ v-model:value="channels"
271
+ label="Channels"
272
+ :options="[
273
+ { id: 'ch-email', value: 'email', label: 'Email' },
274
+ { id: 'ch-push', value: 'push', label: 'Push' },
275
+ ]"
276
+ >
277
+ <template #checkbox="option">
278
+ <strong>{{ option.label }}</strong>
279
+ </template>
280
+ </VJoyCheckboxGroup>
281
+ </template>
282
+ ```
283
+
284
+ In Nuxt (or apps with auto-import), omit the import if `VJoyCheckboxGroup` is already global.
285
+
286
+ ---
287
+
288
+ ## Related
289
+
290
+ | Component | Use when |
291
+ | --- | --- |
292
+ | `VJoyCheckbox` | Single checkbox or explicit child inside the group |
293
+ | `VJoyCheckboxCard` | Card-style options with title, sublabel, and body |
294
+ | `VJoyRadioGroup` / `VJoyRadio` | Exactly one choice from a list |
295
+ | `VJoyToggle` | Single on/off setting |
296
+ | `VJoyLabel` | Custom legend HTML — prefer `label` prop for plain text |
297
+ | `VJoyFormError` | Group-level validation message |
298
+ | `VJoyDropdown` | Filter UI hosting a checkbox group in `dropdown-items` |
299
+ | `VJoySelectableItemGroup` | Alternative multi-select list pattern |
300
+ | `VJoyMultiCheckbox` | **Deprecated** — use `VJoyCheckboxGroup` |
301
+
302
+ ---
303
+
304
+ ## For agents
305
+
306
+ Optional for readers; **required** for vibe-coding quality. Maps to `agentDocumentBlocks` in [`JoyCheckboxGroup.dsds.json`](./JoyCheckboxGroup.dsds.json).
307
+
308
+ ### Pick the right component
309
+
310
+ | If the intent is… | Emit… | Do not emit… |
311
+ | --- | --- | --- |
312
+ | Multiple independent selections as an array | `VJoyCheckboxGroup` + `v-model:value` | `VJoyRadioGroup` |
313
+ | Exactly one of a few options | `VJoyRadioGroup` | `VJoyCheckboxGroup` |
314
+ | One consent / binary checkbox | `VJoyCheckbox` | Group with a single member |
315
+ | Card multi-select in a group | `VJoyCheckboxGroup` default slot + `VJoyCheckboxCard` | Custom card divs |
316
+ | Simple uniform option list | `options` prop | Manual array splice without the group |
317
+ | Per-option disabled or invalid with `options` | Default slot + explicit children | Assuming `options[].disabled` is wired (it is not in the template today) |
318
+ | Filter menu multi-select | `VJoyCheckboxGroup` inside `VJoyDropdown` | Standalone checkboxes without fieldset |
319
+
320
+ ### Hard rules
321
+
322
+ 1. **MUST** call `joy_get_component_info("VJoyCheckboxGroup")` (or read `VJoyCheckboxGroup.vue` types) before generating props.
323
+ 2. **MUST** bind `v-model:value` to a **string array** (or compatible array of option values).
324
+ 3. **MUST** use `direction` only as `vertical` or `horizontal`.
325
+ 4. **MUST** give each option a unique `id` and `value`.
326
+ 5. **MUST** wire default-slot children with `isChecked` / `updateModel` from slot props.
327
+ 6. **MUST NOT** invent props (`multiple`, `variant`, `size`, …).
328
+ 7. **MUST NOT** override `.joy-checkbox-group` gap, flex, or fieldset chrome in product CSS.
329
+ 8. **MUST NOT** use `VJoyMultiCheckbox` in new code — emit `VJoyCheckboxGroup`.
330
+ 9. **SHOULD** use `options` for flat `VJoyCheckbox` lists; default slot for `VJoyCheckboxCard` or mixed layouts.
331
+ 10. **SHOULD** keep horizontal layout for short labels only.
332
+
333
+ ### Checklist
334
+
335
+ - [ ] Correct component (`VJoyCheckboxGroup` or named alternative)
336
+ - [ ] `v-model:value` bound to an array
337
+ - [ ] `direction` from MCP enum only
338
+ - [ ] Unique `id` / `value` per option
339
+ - [ ] Default slot children wired with `isChecked` / `updateModel`
340
+ - [ ] Group `label` set when the set needs a programmatic name
341
+ - [ ] No invented props / no custom group layout CSS
342
+ - [ ] Exclusive choice → radio group, not checkbox group
343
+ - [ ] Validation uses visible error text (`VJoyFormError`) when at least one selection is required
344
+ - [ ] Disabled / invalid per option via explicit children when `options` is insufficient
345
+
346
+ ---
347
+
348
+ ## DSDS mapping
349
+
350
+ This Markdown mirrors [`JoyCheckboxGroup.dsds.json`](./JoyCheckboxGroup.dsds.json) (DSDS **0.15.2**).
351
+
352
+ | Section here | DSDS block |
353
+ | --- | --- |
354
+ | When to use / not | `use-cases` |
355
+ | Anatomy / layout | `anatomy` |
356
+ | States | `states` |
357
+ | Best practices / content rules | `guidelines` (+ `content`) |
358
+ | Accessibility | `accessibility` |
359
+ | Examples | `sections` |
360
+ | For agents | `agentDocumentBlocks` |
361
+ | Props detail | `api` in JSON + Joy MCP |
362
+ | Imports | `imports` in JSON |
363
+ | Layout tokens | `design-specifications` in JSON (`--joy-core-spacing-4`) |
@@ -28,7 +28,7 @@
28
28
  "type": "string",
29
29
  "declarations": [
30
30
  {
31
- "file": "/home/kevincarnaille/dev/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
31
+ "file": "/Users/pierrereynaud/Documents/Work/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
32
32
  "range": [
33
33
  1310,
34
34
  1321
@@ -46,7 +46,7 @@
46
46
  "type": "string | undefined",
47
47
  "declarations": [
48
48
  {
49
- "file": "/home/kevincarnaille/dev/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
49
+ "file": "/Users/pierrereynaud/Documents/Work/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
50
50
  "range": [
51
51
  1330,
52
52
  1344
@@ -71,7 +71,7 @@
71
71
  "type": "string",
72
72
  "declarations": [
73
73
  {
74
- "file": "/home/kevincarnaille/dev/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
74
+ "file": "/Users/pierrereynaud/Documents/Work/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
75
75
  "range": [
76
76
  1353,
77
77
  1367
@@ -89,7 +89,7 @@
89
89
  "type": "string",
90
90
  "declarations": [
91
91
  {
92
- "file": "/home/kevincarnaille/dev/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
92
+ "file": "/Users/pierrereynaud/Documents/Work/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
93
93
  "range": [
94
94
  1376,
95
95
  1390
@@ -107,7 +107,7 @@
107
107
  "type": "string | undefined",
108
108
  "declarations": [
109
109
  {
110
- "file": "/home/kevincarnaille/dev/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
110
+ "file": "/Users/pierrereynaud/Documents/Work/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
111
111
  "range": [
112
112
  1399,
113
113
  1417
@@ -130,7 +130,7 @@
130
130
  "type": "boolean | undefined",
131
131
  "declarations": [
132
132
  {
133
- "file": "/home/kevincarnaille/dev/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
133
+ "file": "/Users/pierrereynaud/Documents/Work/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
134
134
  "range": [
135
135
  1476,
136
136
  1495
@@ -161,7 +161,7 @@
161
161
  "type": "boolean | undefined",
162
162
  "declarations": [
163
163
  {
164
- "file": "/home/kevincarnaille/dev/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
164
+ "file": "/Users/pierrereynaud/Documents/Work/design-system/packages/core-vue/src/components/JoyCheckboxGroup/VJoyCheckboxGroup.vue",
165
165
  "range": [
166
166
  1554,
167
167
  1573