@fiscozen/checkbox 0.1.6 → 0.2.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 (44) hide show
  1. package/.eslintrc.cjs +19 -0
  2. package/.prettierrc.js +6 -0
  3. package/README.md +514 -0
  4. package/coverage/clover.xml +789 -215
  5. package/coverage/coverage-final.json +6 -6
  6. package/coverage/index.html +32 -32
  7. package/coverage/src/FzCheckbox.vue.html +1099 -151
  8. package/coverage/src/FzCheckboxGroup.vue.html +444 -81
  9. package/coverage/src/common.ts.html +79 -19
  10. package/coverage/src/components/ErrorAlert.vue.html +268 -0
  11. package/coverage/src/components/FzCheckboxGroupOption.vue.html +343 -70
  12. package/coverage/src/components/index.html +22 -22
  13. package/coverage/src/index.html +45 -45
  14. package/coverage/src/utils.ts.html +265 -0
  15. package/package.json +13 -11
  16. package/src/FzCheckbox.vue +411 -95
  17. package/src/FzCheckboxGroup.vue +179 -58
  18. package/src/__test__/FzCheckbox.test.ts +91 -19
  19. package/src/__test__/FzCheckboxGroup.test.ts +167 -4
  20. package/src/common.ts +20 -0
  21. package/src/components/ErrorAlert.vue +61 -0
  22. package/src/components/FzCheckboxGroupOption.vue +137 -46
  23. package/src/index.ts +1 -0
  24. package/src/types.ts +166 -23
  25. package/src/utils.ts +60 -0
  26. package/tsconfig.json +1 -1
  27. package/coverage/.tmp/coverage-0.json +0 -1
  28. package/coverage/.tmp/coverage-1.json +0 -1
  29. package/coverage/src/components/FzCheckboxErrorText.vue.html +0 -145
  30. package/coverage/src/types.ts.html +0 -310
  31. package/dist/checkbox.js +0 -301
  32. package/dist/checkbox.umd.cjs +0 -1
  33. package/dist/index.d.ts +0 -1
  34. package/dist/src/FzCheckbox.vue.d.ts +0 -95
  35. package/dist/src/FzCheckboxGroup.vue.d.ts +0 -70
  36. package/dist/src/__test__/FzCheckbox.test.d.ts +0 -1
  37. package/dist/src/__test__/FzCheckboxGroup.test.d.ts +0 -1
  38. package/dist/src/common.d.ts +0 -4
  39. package/dist/src/components/FzCheckboxErrorText.vue.d.ts +0 -24
  40. package/dist/src/components/FzCheckboxGroupOption.vue.d.ts +0 -82
  41. package/dist/src/index.d.ts +0 -3
  42. package/dist/src/types.d.ts +0 -76
  43. package/dist/style.css +0 -1
  44. package/src/components/FzCheckboxErrorText.vue +0 -20
package/.eslintrc.cjs ADDED
@@ -0,0 +1,19 @@
1
+ /* eslint-env node */
2
+ require('@rushstack/eslint-patch/modern-module-resolution')
3
+
4
+ module.exports = {
5
+ root: true,
6
+ 'extends': ['@fiscozen/eslint-config', 'plugin:storybook/recommended'],
7
+ overrides: [
8
+ {
9
+ files: [
10
+ 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}',
11
+ 'cypress/support/**/*.{js,ts,jsx,tsx}'
12
+ ],
13
+ 'extends': [
14
+ 'plugin:cypress/recommended'
15
+ ]
16
+ }
17
+ ]
18
+ }
19
+
package/.prettierrc.js ADDED
@@ -0,0 +1,6 @@
1
+ import fiscozenPrettierConfig from '@fiscozen/prettier-config';
2
+
3
+ export default {
4
+ ...fiscozenPrettierConfig
5
+ };
6
+
package/README.md CHANGED
@@ -1 +1,515 @@
1
1
  # @fiscozen/checkbox
2
+
3
+ A fully accessible, WCAG 2.1 AA compliant checkbox component library for Vue 3 applications. Built with enterprise-grade accessibility features, support for single and multi-selection patterns, hierarchical checkbox groups with automatic indeterminate state management, and comprehensive keyboard navigation.
4
+
5
+ ## Features
6
+
7
+ - **WCAG 2.1 AA Compliant** - Full accessibility support with comprehensive ARIA attributes
8
+ - **Flexible Data Models** - Support for boolean (single) and array (multi-select) v-model binding
9
+ - **Hierarchical Structures** - Parent-child checkbox relationships with automatic indeterminate state
10
+ - **Keyboard Navigation** - Complete keyboard accessibility with visible focus indicators
11
+ - **Screen Reader Optimized** - Proper semantic markup and live region announcements
12
+ - **Error Handling** - Built-in validation states with accessible error messages
13
+ - **Customizable** - Multiple size variants, emphasis mode, and tooltip support
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @fiscozen/checkbox
19
+ ```
20
+
21
+ **Peer Dependencies:** This package requires Vue 3.x and the following Fiscozen Design System packages:
22
+ - `@fiscozen/icons` - Icon system
23
+ - `@fiscozen/tooltip` - Tooltip component for contextual help
24
+ - `@fiscozen/alert` - Alert component for error messages
25
+
26
+ ## Basic Usage
27
+
28
+ ### Single Checkbox (Boolean Model)
29
+
30
+ ```vue
31
+ <script setup lang="ts">
32
+ import { ref } from 'vue';
33
+ import { FzCheckbox } from '@fiscozen/checkbox';
34
+
35
+ const accepted = ref(false);
36
+ </script>
37
+
38
+ <template>
39
+ <div>
40
+ <FzCheckbox
41
+ v-model="accepted"
42
+ label="I accept the terms and conditions"
43
+ />
44
+
45
+ <p v-if="accepted">Terms accepted!</p>
46
+ </div>
47
+ </template>
48
+ ```
49
+
50
+ ### Multiple Checkboxes (Array Model)
51
+
52
+ ```vue
53
+ <script setup lang="ts">
54
+ import { ref } from 'vue';
55
+ import { FzCheckbox } from '@fiscozen/checkbox';
56
+
57
+ const selectedFeatures = ref<string[]>([]);
58
+ </script>
59
+
60
+ <template>
61
+ <div>
62
+ <h3>Select Features:</h3>
63
+
64
+ <FzCheckbox
65
+ v-model="selectedFeatures"
66
+ value="feature-a"
67
+ label="Feature A"
68
+ />
69
+
70
+ <FzCheckbox
71
+ v-model="selectedFeatures"
72
+ value="feature-b"
73
+ label="Feature B"
74
+ />
75
+
76
+ <FzCheckbox
77
+ v-model="selectedFeatures"
78
+ value="feature-c"
79
+ label="Feature C"
80
+ />
81
+
82
+ <p>Selected: {{ selectedFeatures.join(', ') }}</p>
83
+ </div>
84
+ </template>
85
+ ```
86
+
87
+ ### Checkbox Group
88
+
89
+ ```vue
90
+ <script setup lang="ts">
91
+ import { ref } from 'vue';
92
+ import { FzCheckboxGroup } from '@fiscozen/checkbox';
93
+
94
+ const selectedOptions = ref<string[]>([]);
95
+
96
+ const options = [
97
+ { label: 'Option 1', value: 'opt1' },
98
+ { label: 'Option 2', value: 'opt2' },
99
+ { label: 'Option 3', value: 'opt3' },
100
+ ];
101
+ </script>
102
+
103
+ <template>
104
+ <FzCheckboxGroup
105
+ v-model="selectedOptions"
106
+ label="Choose your options"
107
+ :options="options"
108
+ >
109
+ <template #help>
110
+ <span>Select one or more options</span>
111
+ </template>
112
+ </FzCheckboxGroup>
113
+ </template>
114
+ ```
115
+
116
+ ## API Reference
117
+
118
+ ### FzCheckbox
119
+
120
+ Core checkbox component supporting both single and multi-selection patterns. Can be used standalone or composed within checkbox groups.
121
+
122
+ #### Props
123
+
124
+ | Prop | Type | Default | Description |
125
+ |------|------|---------|-------------|
126
+ | `label` | `string` | **required** | Checkbox label text |
127
+ | `value` | `string \| number \| boolean` | `label` | Value when used in array model |
128
+ | `indeterminate` | `boolean` | `false` | Shows indeterminate state (partial selection) |
129
+ | `emphasis` | `boolean` | `false` | Applies emphasis styling (blue when checked) |
130
+ | `disabled` | `boolean` | `false` | Disables the checkbox |
131
+ | `error` | `boolean` | `false` | Shows error state |
132
+ | `required` | `boolean` | `false` | Marks field as required |
133
+ | `standalone` | `boolean` | `false` | Renders only icon without label text |
134
+ | `tooltip` | `FzTooltipProps` | `undefined` | Tooltip configuration |
135
+ | `ariaOwns` | `string` | `undefined` | Space-separated child IDs for hierarchical structures |
136
+ | `checkboxId` | `string` | auto-generated | Custom ID for the input element |
137
+
138
+ #### v-model
139
+
140
+ ```typescript
141
+ // Single checkbox
142
+ v-model: boolean | null | undefined
143
+
144
+ // Multi-select checkbox
145
+ v-model: (string | number | boolean)[]
146
+ ```
147
+
148
+ #### Events
149
+
150
+ | Event | Payload | Description |
151
+ |-------|---------|-------------|
152
+ | `change` | `Event` | Emitted when checkbox state changes |
153
+
154
+ #### Slots
155
+
156
+ | Slot | Description |
157
+ |------|-------------|
158
+ | `error` | Error message content |
159
+ | `children` | Child checkboxes (used internally by hierarchical structures) |
160
+
161
+ ---
162
+
163
+ ### FzCheckboxGroup
164
+
165
+ Container component for managing multiple related checkboxes with shared labeling, validation, and accessibility features.
166
+
167
+ #### Props
168
+
169
+ | Prop | Type | Default | Description |
170
+ |------|------|---------|-------------|
171
+ | `label` | `string` | **required** | Group label |
172
+ | `options` | `ParentCheckbox[]` | **required** | Array of checkbox options |
173
+ | `emphasis` | `boolean` | `false` | Applies to all checkboxes |
174
+ | `disabled` | `boolean` | `false` | Disables all checkboxes |
175
+ | `error` | `boolean` | `false` | Shows error state |
176
+ | `required` | `boolean` | `false` | Marks group as required |
177
+ | `horizontal` | `boolean` | `false` | Arranges checkboxes horizontally |
178
+
179
+ #### v-model
180
+
181
+ ```typescript
182
+ v-model: string[]
183
+ ```
184
+
185
+ #### Slots
186
+
187
+ | Slot | Description |
188
+ |------|-------------|
189
+ | `help` | Help text displayed below the label |
190
+ | `error` | Error message content |
191
+
192
+ ---
193
+
194
+ ## Advanced Usage
195
+
196
+ ### With Error Validation
197
+
198
+ ```vue
199
+ <script setup lang="ts">
200
+ import { ref, computed } from 'vue';
201
+ import { FzCheckbox } from '@fiscozen/checkbox';
202
+
203
+ const agreedToTerms = ref(false);
204
+ const submitted = ref(false);
205
+
206
+ const hasError = computed(() => submitted.value && !agreedToTerms.value);
207
+
208
+ function handleSubmit() {
209
+ submitted.value = true;
210
+ if (!agreedToTerms.value) {
211
+ // Handle validation error
212
+ return;
213
+ }
214
+ // Process form
215
+ }
216
+ </script>
217
+
218
+ <template>
219
+ <div>
220
+ <FzCheckbox
221
+ v-model="agreedToTerms"
222
+ label="I agree to the terms"
223
+ required
224
+ :error="hasError"
225
+ >
226
+ <template #error>
227
+ <p>You must accept the terms to continue</p>
228
+ </template>
229
+ </FzCheckbox>
230
+
231
+ <button @click="handleSubmit">Submit</button>
232
+ </div>
233
+ </template>
234
+ ```
235
+
236
+ ### With Tooltip
237
+
238
+ ```vue
239
+ <script setup lang="ts">
240
+ import { ref } from 'vue';
241
+ import { FzCheckbox } from '@fiscozen/checkbox';
242
+
243
+ const enableFeature = ref(false);
244
+ </script>
245
+
246
+ <template>
247
+ <FzCheckbox
248
+ v-model="enableFeature"
249
+ label="Enable advanced mode"
250
+ :tooltip="{
251
+ text: 'This enables experimental features that may be unstable',
252
+ status: 'informative'
253
+ }"
254
+ />
255
+ </template>
256
+ ```
257
+
258
+ ### Emphasis Mode
259
+
260
+ ```vue
261
+ <script setup lang="ts">
262
+ import { ref } from 'vue';
263
+ import { FzCheckbox } from '@fiscozen/checkbox';
264
+
265
+ const isPrimary = ref(false);
266
+ </script>
267
+
268
+ <template>
269
+ <FzCheckbox
270
+ v-model="isPrimary"
271
+ label="Primary selection"
272
+ emphasis
273
+ />
274
+ </template>
275
+ ```
276
+
277
+ ### Standalone (Icon Only)
278
+
279
+ ```vue
280
+ <script setup lang="ts">
281
+ import { ref } from 'vue';
282
+ import { FzCheckbox } from '@fiscozen/checkbox';
283
+
284
+ const selected = ref(false);
285
+ </script>
286
+
287
+ <template>
288
+ <div>
289
+ <label for="custom-checkbox">Select this item:</label>
290
+ <FzCheckbox
291
+ v-model="selected"
292
+ label="Select item"
293
+ standalone
294
+ />
295
+ </div>
296
+ </template>
297
+ ```
298
+
299
+ ### Hierarchical Checkbox Group
300
+
301
+ ```vue
302
+ <script setup lang="ts">
303
+ import { ref } from 'vue';
304
+ import { FzCheckboxGroup } from '@fiscozen/checkbox';
305
+
306
+ const selectedPermissions = ref<string[]>([]);
307
+
308
+ const permissionOptions = [
309
+ {
310
+ label: 'Admin Access',
311
+ value: 'admin',
312
+ children: [
313
+ { label: 'User Management', value: 'admin.users' },
314
+ { label: 'System Settings', value: 'admin.settings' },
315
+ { label: 'View Logs', value: 'admin.logs' },
316
+ ]
317
+ },
318
+ {
319
+ label: 'Content Access',
320
+ value: 'content',
321
+ children: [
322
+ { label: 'Create Content', value: 'content.create' },
323
+ { label: 'Edit Content', value: 'content.edit' },
324
+ { label: 'Delete Content', value: 'content.delete' },
325
+ ]
326
+ }
327
+ ];
328
+ </script>
329
+
330
+ <template>
331
+ <FzCheckboxGroup
332
+ v-model="selectedPermissions"
333
+ label="Select Permissions"
334
+ :options="permissionOptions"
335
+ >
336
+ <template #help>
337
+ <span>Parent checkboxes show indeterminate state when partially selected</span>
338
+ </template>
339
+ </FzCheckboxGroup>
340
+ </template>
341
+ ```
342
+
343
+ ### Horizontal Layout
344
+
345
+ ```vue
346
+ <script setup lang="ts">
347
+ import { ref } from 'vue';
348
+ import { FzCheckboxGroup } from '@fiscozen/checkbox';
349
+
350
+ const selectedDays = ref<string[]>([]);
351
+
352
+ const dayOptions = [
353
+ { label: 'Mon', value: 'monday' },
354
+ { label: 'Tue', value: 'tuesday' },
355
+ { label: 'Wed', value: 'wednesday' },
356
+ { label: 'Thu', value: 'thursday' },
357
+ { label: 'Fri', value: 'friday' },
358
+ ];
359
+ </script>
360
+
361
+ <template>
362
+ <FzCheckboxGroup
363
+ v-model="selectedDays"
364
+ label="Working Days"
365
+ :options="dayOptions"
366
+ horizontal
367
+ />
368
+ </template>
369
+ ```
370
+
371
+ ### Disabled State
372
+
373
+ ```vue
374
+ <script setup lang="ts">
375
+ import { ref } from 'vue';
376
+ import { FzCheckbox, FzCheckboxGroup } from '@fiscozen/checkbox';
377
+
378
+ const checked = ref(true);
379
+ const groupSelection = ref<string[]>(['opt1']);
380
+
381
+ const options = [
382
+ { label: 'Option 1', value: 'opt1' },
383
+ { label: 'Option 2', value: 'opt2' },
384
+ ];
385
+ </script>
386
+
387
+ <template>
388
+ <div>
389
+ <!-- Disabled single checkbox -->
390
+ <FzCheckbox
391
+ v-model="checked"
392
+ label="This is disabled"
393
+ disabled
394
+ />
395
+
396
+ <!-- Disabled group -->
397
+ <FzCheckboxGroup
398
+ v-model="groupSelection"
399
+ label="Disabled Group"
400
+ :options="options"
401
+ disabled
402
+ />
403
+ </div>
404
+ </template>
405
+ ```
406
+
407
+ ### With Form Validation
408
+
409
+ ```vue
410
+ <script setup lang="ts">
411
+ import { ref, computed } from 'vue';
412
+ import { FzCheckboxGroup } from '@fiscozen/checkbox';
413
+
414
+ const selectedOptions = ref<string[]>([]);
415
+ const touched = ref(false);
416
+
417
+ const options = [
418
+ { label: 'Option A', value: 'a' },
419
+ { label: 'Option B', value: 'b' },
420
+ { label: 'Option C', value: 'c' },
421
+ ];
422
+
423
+ const hasError = computed(() =>
424
+ touched.value && selectedOptions.value.length === 0
425
+ );
426
+
427
+ function handleBlur() {
428
+ touched.value = true;
429
+ }
430
+ </script>
431
+
432
+ <template>
433
+ <div @blur="handleBlur">
434
+ <FzCheckboxGroup
435
+ v-model="selectedOptions"
436
+ label="Required Selection"
437
+ :options="options"
438
+ required
439
+ :error="hasError"
440
+ >
441
+ <template #help>
442
+ <span>Select at least one option</span>
443
+ </template>
444
+
445
+ <template #error>
446
+ <span>Please select at least one option to continue</span>
447
+ </template>
448
+ </FzCheckboxGroup>
449
+ </div>
450
+ </template>
451
+ ```
452
+
453
+ ## TypeScript Support
454
+
455
+ This package is written in TypeScript and provides full type definitions.
456
+
457
+ ```typescript
458
+ import type {
459
+ FzCheckboxProps,
460
+ FzCheckboxGroupProps,
461
+ ParentCheckbox,
462
+ ChildCheckbox
463
+ } from '@fiscozen/checkbox';
464
+
465
+ // Example: Typed options array
466
+ const options: ParentCheckbox[] = [
467
+ {
468
+ label: 'Parent Option',
469
+ value: 'parent',
470
+ children: [
471
+ { label: 'Child 1', value: 'child1' },
472
+ { label: 'Child 2', value: 'child2' }
473
+ ]
474
+ }
475
+ ];
476
+ ```
477
+
478
+ ## Accessibility Features
479
+
480
+ ### WCAG 2.1 AA Compliance
481
+
482
+ This component implements comprehensive accessibility features following WCAG 2.1 Level AA guidelines:
483
+
484
+ - **Keyboard Navigation** - Full support for Tab and Space key interactions
485
+ - **Screen Reader Support** - Proper ARIA roles, labels, and state announcements
486
+ - **Focus Management** - Visible focus indicators meeting 3:1 contrast ratio requirements
487
+ - **Error Handling** - Live region announcements for dynamic validation messages
488
+ - **Semantic Markup** - Native checkbox inputs with accessible label associations
489
+
490
+ ### Keyboard Interactions
491
+
492
+ | Key | Action |
493
+ |-----|--------|
494
+ | `Tab` | Move focus to next checkbox |
495
+ | `Shift + Tab` | Move focus to previous checkbox |
496
+ | `Space` | Toggle checkbox state |
497
+
498
+ ### Screen Reader Behavior
499
+
500
+ The component provides rich semantic information to assistive technologies:
501
+
502
+ - **State Announcements** - "checked", "unchecked", or "mixed" (indeterminate)
503
+ - **Label Associations** - `aria-labelledby` and `aria-label` for proper identification
504
+ - **Error Messages** - `aria-describedby` linking to error content with `role="alert"`
505
+ - **Group Context** - `role="group"` with `aria-labelledby` for related checkbox sets
506
+ - **Hierarchical Relationships** - `aria-owns` establishing parent-child checkbox connections
507
+ - **Required Fields** - `aria-required` indicating mandatory selections
508
+ - **Validation State** - `aria-invalid` signaling validation errors
509
+
510
+ ### Focus Indicators
511
+
512
+ - Focus ring appears as blue border around checkbox icon
513
+ - Meets WCAG 3:1 contrast ratio requirement against background
514
+ - Visible in all states: default, hover, checked, indeterminate
515
+ - Tab order follows logical DOM structure