@arbor-education/design-system.components 3.0.2 → 3.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 (89) hide show
  1. package/.github/pull_request_template.md +4 -3
  2. package/CHANGELOG.md +16 -0
  3. package/CONTRIBUTING.md +1 -0
  4. package/dist/components/formField/FormField.d.ts +34 -18
  5. package/dist/components/formField/FormField.d.ts.map +1 -1
  6. package/dist/components/formField/FormField.js +5 -1
  7. package/dist/components/formField/FormField.js.map +1 -1
  8. package/dist/components/formField/FormField.stories.d.ts +4 -0
  9. package/dist/components/formField/FormField.stories.d.ts.map +1 -1
  10. package/dist/components/formField/FormField.stories.js +314 -7
  11. package/dist/components/formField/FormField.stories.js.map +1 -1
  12. package/dist/components/formField/FormField.test.js +66 -0
  13. package/dist/components/formField/FormField.test.js.map +1 -1
  14. package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts +1 -0
  15. package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts.map +1 -1
  16. package/dist/components/formField/inputs/checkbox/CheckboxGroup.js +2 -2
  17. package/dist/components/formField/inputs/checkbox/CheckboxGroup.js.map +1 -1
  18. package/dist/components/formField/inputs/checkbox/CheckboxInput.d.ts +1 -0
  19. package/dist/components/formField/inputs/checkbox/CheckboxInput.d.ts.map +1 -1
  20. package/dist/components/formField/inputs/checkbox/CheckboxInput.js +2 -2
  21. package/dist/components/formField/inputs/checkbox/CheckboxInput.js.map +1 -1
  22. package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts +1 -0
  23. package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts.map +1 -1
  24. package/dist/components/formField/inputs/radio/RadioButtonGroup.js +2 -2
  25. package/dist/components/formField/inputs/radio/RadioButtonGroup.js.map +1 -1
  26. package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.d.ts +2 -2
  27. package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.d.ts.map +1 -1
  28. package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.js +0 -1
  29. package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.js.map +1 -1
  30. package/dist/components/formField/inputs/time/TimeInput.d.ts +1 -1
  31. package/dist/components/formField/inputs/time/TimeInput.stories.d.ts +1 -1
  32. package/dist/components/icon/Icon.d.ts.map +1 -1
  33. package/dist/components/icon/Icon.js +18 -3
  34. package/dist/components/icon/Icon.js.map +1 -1
  35. package/dist/components/icon/Icon.stories.d.ts +4 -2
  36. package/dist/components/icon/Icon.stories.d.ts.map +1 -1
  37. package/dist/components/icon/Icon.stories.js +150 -102
  38. package/dist/components/icon/Icon.stories.js.map +1 -1
  39. package/dist/components/icon/Icon.test.js +146 -6
  40. package/dist/components/icon/Icon.test.js.map +1 -1
  41. package/dist/components/icon/LucideIcon.d.ts +17 -0
  42. package/dist/components/icon/LucideIcon.d.ts.map +1 -0
  43. package/dist/components/icon/LucideIcon.js +73 -0
  44. package/dist/components/icon/LucideIcon.js.map +1 -0
  45. package/dist/components/icon/allowedIcons.d.ts +44 -108
  46. package/dist/components/icon/allowedIcons.d.ts.map +1 -1
  47. package/dist/components/icon/allowedIcons.js +52 -112
  48. package/dist/components/icon/allowedIcons.js.map +1 -1
  49. package/dist/components/icon/types.d.ts +5 -4
  50. package/dist/components/icon/types.d.ts.map +1 -1
  51. package/dist/components/tabs/Tabs.d.ts +1 -1
  52. package/dist/components/tabs/Tabs.stories.d.ts +1 -1
  53. package/dist/components/tabs/Tabs.stories.js +1 -1
  54. package/dist/components/tabs/Tabs.stories.js.map +1 -1
  55. package/dist/components/tabs/TabsItem.d.ts +2 -2
  56. package/dist/components/tabs/TabsItem.d.ts.map +1 -1
  57. package/dist/components/tabs/TabsItem.stories.d.ts +5 -5
  58. package/dist/components/tabs/TabsItem.stories.d.ts.map +1 -1
  59. package/dist/components/tabs/TabsItem.stories.js +7 -4
  60. package/dist/components/tabs/TabsItem.stories.js.map +1 -1
  61. package/dist/components/toggle/Toggle.d.ts +7 -1
  62. package/dist/components/toggle/Toggle.d.ts.map +1 -1
  63. package/dist/components/toggle/Toggle.js +2 -2
  64. package/dist/components/toggle/Toggle.js.map +1 -1
  65. package/dist/components/toggle/Toggle.stories.d.ts +1 -1
  66. package/dist/index.css +21 -0
  67. package/dist/index.css.map +1 -1
  68. package/package.json +1 -1
  69. package/src/components/formField/FormField.stories.tsx +398 -7
  70. package/src/components/formField/FormField.test.tsx +100 -0
  71. package/src/components/formField/FormField.tsx +46 -27
  72. package/src/components/formField/inputs/checkbox/CheckboxGroup.tsx +3 -2
  73. package/src/components/formField/inputs/checkbox/CheckboxInput.tsx +3 -0
  74. package/src/components/formField/inputs/checkbox/checkboxInput.scss +4 -0
  75. package/src/components/formField/inputs/radio/RadioButtonGroup.tsx +11 -1
  76. package/src/components/formField/inputs/radio/radioButtonInput.scss +8 -0
  77. package/src/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.tsx +2 -2
  78. package/src/components/icon/Icon.stories.tsx +224 -119
  79. package/src/components/icon/Icon.test.tsx +178 -6
  80. package/src/components/icon/Icon.tsx +25 -3
  81. package/src/components/icon/LucideIcon.tsx +94 -0
  82. package/src/components/icon/allowedIcons.tsx +67 -207
  83. package/src/components/icon/lucideDynamic.d.ts +13 -0
  84. package/src/components/icon/types.ts +5 -4
  85. package/src/components/tabs/Tabs.stories.tsx +1 -1
  86. package/src/components/tabs/TabsItem.stories.tsx +8 -4
  87. package/src/components/tabs/TabsItem.tsx +2 -2
  88. package/src/components/toggle/Toggle.tsx +13 -3
  89. package/src/components/toggle/toggle.scss +22 -0
@@ -21,12 +21,13 @@
21
21
  <!-- Step-by-step testing instructions. Include any browser-specific or environment-specific notes.
22
22
  Chromatic will post a Storybook link automatically — no need to include one here. -->
23
23
 
24
- 1.
25
- 2.
26
- 3.
24
+ 1.
25
+ 2.
26
+ 3.
27
27
 
28
28
  ## Checklist
29
29
 
30
+ - [ ] This contribution has been discussed with the design system team in the [contribution process Slack channel](https://arbor-education.slack.com/archives/C0BJU1K3HH9)
30
31
  - [ ] This PR does **one thing** — the title does not contain "and" or "also"
31
32
  - [ ] The meaningful code diff is under 400 lines (or a justification is written in "Notes for code owners")
32
33
  - [ ] `yarn check-types` passes with no errors
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#252](https://github.com/arbor-education/design-system.components/pull/252) [`9247537`](https://github.com/arbor-education/design-system.components/commit/9247537f0297ad464e0e4d059b186ba10db6d0d6) Thanks [@Alex-DN-SP](https://github.com/Alex-DN-SP)! - MIS-73878 Allow all lucide icons in DS Icon component
8
+
9
+ ### Patch Changes
10
+
11
+ - [#251](https://github.com/arbor-education/design-system.components/pull/251) [`a084aa2`](https://github.com/arbor-education/design-system.components/commit/a084aa29dd18c4fa4ccb8300087140330d66ed49) Thanks [@rickbairstow](https://github.com/rickbairstow)! - MIS-74535 Updates PR template
12
+
13
+ ## 3.1.0
14
+
15
+ ### Minor Changes
16
+
17
+ - [#248](https://github.com/arbor-education/design-system.components/pull/248) [`05a0a40`](https://github.com/arbor-education/design-system.components/commit/05a0a40b01301ddebbd99cf70a23d0267a2c6dd1) Thanks [@angusmglfraser](https://github.com/angusmglfraser)! - MIS-73787 ✨ Add checkbox, checkboxgroup, toggle and radio to the FormField union
18
+
3
19
  ## 3.0.2
4
20
 
5
21
  ### Patch Changes
package/CONTRIBUTING.md CHANGED
@@ -110,6 +110,7 @@ Each commit should tell part of the story. A reviewer should be able to follow y
110
110
 
111
111
  Run through this checklist yourself before requesting review:
112
112
 
113
+ - [ ] This contribution has been discussed with the design system team in the [contribution process Slack channel](https://arbor-education.slack.com/archives/C0BJU1K3HH9)
113
114
  - [ ] My branch name includes the Jira ticket number (e.g. `feature/MIS-12345-add-button-variant`)
114
115
  - [ ] My PR does **one thing**. The title does not contain "and" or "also"
115
116
  - [ ] The diff is under 400 lines of meaningful code (or I have written a justification)
@@ -1,12 +1,16 @@
1
- import type { ComboboxProps } from '../combobox/types.js';
2
- import { type DatePickerProps } from '../datePicker/DatePicker.js';
3
- import { type DateTimePickerProps } from '../dateTimePicker/DateTimePicker.js';
4
- import { type ColourPickerDropdownProps } from './inputs/colourPickerDropdown/ColourPickerDropdown.js';
5
- import { type NumberInputProps } from './inputs/number/NumberInput.js';
6
- import { type SelectDropdownInputProps } from './inputs/selectDropdown/SelectDropdown.js';
7
- import { type TextInputProps } from './inputs/text/TextInput.js';
8
- import { type TimeInputProps } from './inputs/time/TimeInput.js';
9
- import { type TextAreaProps } from './inputs/textArea/TextArea.js';
1
+ import { Combobox } from '../combobox/Combobox.js';
2
+ import { DatePicker } from '../datePicker/DatePicker.js';
3
+ import { DateTimePicker } from '../dateTimePicker/DateTimePicker.js';
4
+ import { ColourPickerDropdown } from './inputs/colourPickerDropdown/ColourPickerDropdown.js';
5
+ import { NumberInput } from './inputs/number/NumberInput.js';
6
+ import { SelectDropdown } from './inputs/selectDropdown/SelectDropdown.js';
7
+ import { TextInput } from './inputs/text/TextInput.js';
8
+ import { TimeInput } from './inputs/time/TimeInput.js';
9
+ import { TextArea } from './inputs/textArea/TextArea.js';
10
+ import { CheckboxInput } from './inputs/checkbox/CheckboxInput.js';
11
+ import { CheckboxGroup } from './inputs/checkbox/CheckboxGroup.js';
12
+ import { RadioButtonGroup } from './inputs/radio/RadioButtonGroup.js';
13
+ import { Toggle } from '../toggle/Toggle.js';
10
14
  export type FormFieldProps = {
11
15
  className?: string;
12
16
  label?: string;
@@ -17,31 +21,43 @@ export type FormFieldProps = {
17
21
  errorText?: string;
18
22
  } & ({
19
23
  inputType?: 'text';
20
- inputProps?: TextInputProps;
24
+ inputProps?: TextInput.Props;
21
25
  } | {
22
26
  inputType?: 'textarea';
23
- inputProps?: TextAreaProps;
27
+ inputProps?: TextArea.Props;
24
28
  } | {
25
29
  inputType?: 'number';
26
- inputProps?: NumberInputProps;
30
+ inputProps?: NumberInput.Props;
27
31
  } | {
28
32
  inputType?: 'time';
29
- inputProps?: TimeInputProps;
33
+ inputProps?: TimeInput.Props;
30
34
  } | {
31
35
  inputType?: 'colourPicker';
32
- inputProps?: ColourPickerDropdownProps;
36
+ inputProps?: ColourPickerDropdown.Props;
33
37
  } | {
34
38
  inputType?: 'selectDropdown';
35
- inputProps?: SelectDropdownInputProps;
39
+ inputProps?: SelectDropdown.Props;
36
40
  } | {
37
41
  inputType?: 'datePicker';
38
- inputProps?: DatePickerProps;
42
+ inputProps?: DatePicker.Props;
39
43
  } | {
40
44
  inputType?: 'dateTimePicker';
41
- inputProps?: DateTimePickerProps;
45
+ inputProps?: DateTimePicker.Props;
42
46
  } | {
43
47
  inputType?: 'combobox';
44
- inputProps?: ComboboxProps;
48
+ inputProps?: Combobox.Props;
49
+ } | {
50
+ inputType?: 'checkbox';
51
+ inputProps: CheckboxInput.Props;
52
+ } | {
53
+ inputType?: 'checkboxGroup';
54
+ inputProps: CheckboxGroup.Props;
55
+ } | {
56
+ inputType?: 'toggle';
57
+ inputProps: Toggle.Props;
58
+ } | {
59
+ inputType?: 'radio';
60
+ inputProps: RadioButtonGroup.Props;
45
61
  });
46
62
  export declare const FormField: (props: FormFieldProps) => import("react").JSX.Element;
47
63
  export declare namespace FormField {
@@ -1 +1 @@
1
- {"version":3,"file":"FormField.d.ts","sourceRoot":"","sources":["../../../src/components/formField/FormField.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACpF,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpG,OAAO,EAAwB,KAAK,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAC7H,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACpF,OAAO,EAAkB,KAAK,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAC1G,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAG7E,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,CACA;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,cAAc,CAAA;CAAE,GACnD;IAAE,SAAS,CAAC,EAAE,UAAU,CAAC;IAAC,UAAU,CAAC,EAAE,aAAa,CAAA;CAAE,GACtD;IAAE,SAAS,CAAC,EAAE,QAAQ,CAAC;IAAC,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAAE,GACvD;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,cAAc,CAAA;CAAE,GACnD;IAAE,SAAS,CAAC,EAAE,cAAc,CAAC;IAAC,UAAU,CAAC,EAAE,yBAAyB,CAAA;CAAE,GACtE;IAAE,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAAC,UAAU,CAAC,EAAE,wBAAwB,CAAA;CAAE,GACvE;IAAE,SAAS,CAAC,EAAE,YAAY,CAAC;IAAC,UAAU,CAAC,EAAE,eAAe,CAAA;CAAE,GAC1D;IAAE,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAAC,UAAU,CAAC,EAAE,mBAAmB,CAAA;CAAE,GAClE;IAAE,SAAS,CAAC,EAAE,UAAU,CAAC;IAAC,UAAU,CAAC,EAAE,aAAa,CAAA;CAAE,CACzD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,OAAO,cAAc,gCA0E9C,CAAC;AAEF,yBAAiB,SAAS,CAAC;IACzB,KAAY,KAAK,GAAG,cAAc,CAAC;CACpC"}
1
+ {"version":3,"file":"FormField.d.ts","sourceRoot":"","sources":["../../../src/components/formField/FormField.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uDAAuD,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,CACA;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,SAAS,CAAC,KAAK,CAAA;CAAE,GACpD;IAAE,SAAS,CAAC,EAAE,UAAU,CAAC;IAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAA;CAAE,GACvD;IAAE,SAAS,CAAC,EAAE,QAAQ,CAAC;IAAC,UAAU,CAAC,EAAE,WAAW,CAAC,KAAK,CAAA;CAAE,GACxD;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,SAAS,CAAC,KAAK,CAAA;CAAE,GACpD;IAAE,SAAS,CAAC,EAAE,cAAc,CAAC;IAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC,KAAK,CAAA;CAAE,GACvE;IAAE,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAAC,UAAU,CAAC,EAAE,cAAc,CAAC,KAAK,CAAA;CAAE,GACnE;IAAE,SAAS,CAAC,EAAE,YAAY,CAAC;IAAC,UAAU,CAAC,EAAE,UAAU,CAAC,KAAK,CAAA;CAAE,GAC3D;IAAE,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAAC,UAAU,CAAC,EAAE,cAAc,CAAC,KAAK,CAAA;CAAE,GACnE;IAAE,SAAS,CAAC,EAAE,UAAU,CAAC;IAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAA;CAAE,GACvD;IAAE,SAAS,CAAC,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,aAAa,CAAC,KAAK,CAAA;CAAE,GAC3D;IAAE,SAAS,CAAC,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,aAAa,CAAC,KAAK,CAAA;CAAE,GAChE;IAAE,SAAS,CAAC,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAA;CAAE,GAClD;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,gBAAgB,CAAC,KAAK,CAAA;CAAE,CAC9D,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,OAAO,cAAc,gCAsF9C,CAAC;AAEF,yBAAiB,SAAS,CAAC;IACzB,KAAY,KAAK,GAAG,cAAc,CAAC;CACpC"}
@@ -11,6 +11,10 @@ import { TextInput } from './inputs/text/TextInput.js';
11
11
  import { TimeInput } from './inputs/time/TimeInput.js';
12
12
  import { TextArea } from './inputs/textArea/TextArea.js';
13
13
  import { Label } from './label/Label.js';
14
+ import { CheckboxInput } from './inputs/checkbox/CheckboxInput.js';
15
+ import { CheckboxGroup } from './inputs/checkbox/CheckboxGroup.js';
16
+ import { RadioButtonGroup } from './inputs/radio/RadioButtonGroup.js';
17
+ import { Toggle } from '../toggle/Toggle.js';
14
18
  export const FormField = (props) => {
15
19
  const { className, label, id, inputType = 'text', helperLinkText, helperLinkUrl, errorText, inputProps, fieldDescription } = props;
16
20
  const classes = classNames('ds-form-field', className);
@@ -27,6 +31,6 @@ export const FormField = (props) => {
27
31
  'hasError': !!errorText,
28
32
  'aria-invalid': !!errorText,
29
33
  };
30
- return (_jsxs("div", { className: classes, children: [label && (_jsx(Label, { htmlFor: id, children: label })), fieldDescription && (_jsx("span", { id: `${id}-description`, className: "ds-form-field__description", children: fieldDescription })), inputType === 'text' && (_jsx(TextInput, { ...sharedProps, ...inputProps })), inputType === 'textarea' && (_jsx(TextArea, { ...sharedProps, ...inputProps })), inputType === 'number' && (_jsx(NumberInput, { ...sharedProps, ...inputProps })), inputType === 'time' && (_jsx(TimeInput, { ...sharedProps, ...inputProps })), inputType === 'colourPicker' && (_jsx(ColourPickerDropdown, { ...sharedProps, ...inputProps })), inputType === 'selectDropdown' && (_jsx(SelectDropdown, { ...sharedProps, ...inputProps })), inputType === 'datePicker' && (_jsx(DatePicker, { ...sharedProps, ...inputProps })), inputType === 'dateTimePicker' && (_jsx(DateTimePicker, { ...sharedProps, ...inputProps })), inputType === 'combobox' && (_jsx(Combobox, { ...sharedProps, ...inputProps })), ((helperLinkText && helperLinkUrl) || errorText) && (_jsxs("div", { className: "ds-form-field__message", children: [errorText && (_jsxs("span", { className: "ds-form-field__message--error", id: `${id}-error`, children: [_jsx(Icon, { size: 12, name: "triangle-alert" }), errorText] })), helperLinkText && helperLinkUrl && (_jsxs("a", { href: helperLinkUrl, "aria-label": `${label} helper link`, className: "ds-form-field__message--helper", children: [helperLinkText, ' ', _jsx(Icon, { size: 12, name: "arrow-up-right" })] }))] }))] }));
34
+ return (_jsxs("div", { className: classes, children: [label && (_jsx(Label, { htmlFor: id, children: label })), fieldDescription && (_jsx("span", { id: `${id}-description`, className: "ds-form-field__description", children: fieldDescription })), inputType === 'text' && (_jsx(TextInput, { ...sharedProps, ...inputProps })), inputType === 'textarea' && (_jsx(TextArea, { ...sharedProps, ...inputProps })), inputType === 'number' && (_jsx(NumberInput, { ...sharedProps, ...inputProps })), inputType === 'time' && (_jsx(TimeInput, { ...sharedProps, ...inputProps })), inputType === 'colourPicker' && (_jsx(ColourPickerDropdown, { ...sharedProps, ...inputProps })), inputType === 'selectDropdown' && (_jsx(SelectDropdown, { ...sharedProps, ...inputProps })), inputType === 'datePicker' && (_jsx(DatePicker, { ...sharedProps, ...inputProps })), inputType === 'dateTimePicker' && (_jsx(DateTimePicker, { ...sharedProps, ...inputProps })), inputType === 'combobox' && (_jsx(Combobox, { ...sharedProps, ...inputProps })), inputType === 'checkbox' && (_jsx(CheckboxInput, { ...sharedProps, ...inputProps })), inputType === 'checkboxGroup' && (_jsx(CheckboxGroup, { ...sharedProps, ...inputProps })), inputType === 'toggle' && (_jsx(Toggle, { ...sharedProps, ...inputProps })), inputType === 'radio' && (_jsx(RadioButtonGroup, { ...sharedProps, ...inputProps })), ((helperLinkText && helperLinkUrl) || errorText) && (_jsxs("div", { className: "ds-form-field__message", children: [errorText && (_jsxs("span", { className: "ds-form-field__message--error", id: `${id}-error`, children: [_jsx(Icon, { size: 12, name: "triangle-alert" }), errorText] })), helperLinkText && helperLinkUrl && (_jsxs("a", { href: helperLinkUrl, "aria-label": `${label} helper link`, className: "ds-form-field__message--helper", children: [helperLinkText, ' ', _jsx(Icon, { size: 12, name: "arrow-up-right" })] }))] }))] }));
31
35
  };
32
36
  //# sourceMappingURL=FormField.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormField.js","sourceRoot":"","sources":["../../../src/components/formField/FormField.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FormField.js","sourceRoot":"","sources":["../../../src/components/formField/FormField.tsx"],"names":[],"mappings":"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"}
@@ -116,4 +116,8 @@ export declare const WithDatePicker: Story;
116
116
  export declare const OptionalAndRequiredFields: Story;
117
117
  export declare const WithColourPicker: Story;
118
118
  export declare const CompleteStudentForm: Story;
119
+ export declare const WithCheckbox: Story;
120
+ export declare const WithCheckboxGroup: Story;
121
+ export declare const WithToggle: Story;
122
+ export declare const WithRadio: Story;
119
123
  //# sourceMappingURL=FormField.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormField.stories.d.ts","sourceRoot":"","sources":["../../../src/components/formField/FormField.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAY5D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAwI3C,iBAAS,iBAAiB,gCAmBzB;AAMD,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6HwB,CAAC;AAEnC,eAAe,IAAI,CAAC;AAIpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,SAAS,CAAC,CAAC;AAuBxC,eAAO,MAAM,OAAO,EAAE,KAarB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAgElC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KA0E5B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAqEvB,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,KAgD1C,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,KA+CpC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KA2DtB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KA2EtB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KA8GzB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAyEvB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAgHhC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAoE1B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAuE5B,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KA0FvC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAsE9B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAqMjC,CAAC"}
1
+ {"version":3,"file":"FormField.stories.d.ts","sourceRoot":"","sources":["../../../src/components/formField/FormField.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAY5D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAmK3C,iBAAS,iBAAiB,gCAmBzB;AAMD,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmIwB,CAAC;AAEnC,eAAe,IAAI,CAAC;AAIpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,SAAS,CAAC,CAAC;AAuBxC,eAAO,MAAM,OAAO,EAAE,KAarB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAgElC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KA0E5B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAqEvB,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,KAgD1C,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,KA+CpC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KA2DtB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KA2EtB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KA8GzB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAyEvB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAgHhC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAoE1B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAuE5B,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KA0FvC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAsE9B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAqMjC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KA+F1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAwF/B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KA+FxB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAwEvB,CAAC"}
@@ -8,7 +8,7 @@ import { FormField } from './FormField.js';
8
8
  // ---------------------------------------------------------------------------
9
9
  const DESCRIPTION_INTRO = [
10
10
  'FormField is the **complete form field assembly**: it wires together a label, an optional',
11
- 'description, any of eight input controls, an optional helper link, and an error message — all',
11
+ 'description, any of thirteen input controls, an optional helper link, and an error message — all',
12
12
  'with the correct accessibility connections built in automatically.',
13
13
  '',
14
14
  'Think of it as a filing cabinet drawer with everything pre-labelled: you tell it what kind of',
@@ -34,7 +34,7 @@ const USAGE_GUIDANCE = [
34
34
  '',
35
35
  '---',
36
36
  '',
37
- '### The eight input types',
37
+ '### The thirteen input types',
38
38
  '',
39
39
  '| `inputType` | Renders | Typical use |',
40
40
  '|---|---|---|',
@@ -45,7 +45,12 @@ const USAGE_GUIDANCE = [
45
45
  '| `"colourPicker"` | `ColourPickerDropdown` | Form group or subject colour |',
46
46
  '| `"selectDropdown"` | `SelectDropdown` | Year group, term, single or multi select |',
47
47
  '| `"datePicker"` | `DatePicker` | Date of birth, enrolment date |',
48
+ '| `"dateTimePicker"` | `DateTimePicker` | Event date and time together |',
48
49
  '| `"combobox"` | `Combobox` | Searchable people picker, tutor assignment |',
50
+ '| `"checkbox"` | `CheckboxInput` | Single opt-in, consent, acknowledgement |',
51
+ '| `"checkboxGroup"` | `CheckboxGroup` | Several independent selections (support needs, alert recipients) |',
52
+ '| `"toggle"` | `Toggle` | Instant on/off settings embedded in a form |',
53
+ '| `"radio"` | `RadioButtonGroup` | One choice from a short, mutually-exclusive list |',
49
54
  ].join('\n');
50
55
  const DEVELOPER_NOTES = [
51
56
  '### Critical gotchas — read before using',
@@ -91,6 +96,25 @@ const DEVELOPER_NOTES = [
91
96
  'This is a known limitation — Confluence guidance says it should open a new tab, but the current',
92
97
  'implementation does not do this. Bear it in mind when linking to external documentation.',
93
98
  '',
99
+ '**12. `"checkbox"`, `"checkboxGroup"`, `"toggle"`, and `"radio"` all require `inputProps`.** Every',
100
+ 'other `inputType` has optional `inputProps`; these four do not — the union marks them as required',
101
+ 'because each underlying component needs at least `checked`/`checkedValue` and an `onChange`',
102
+ '(or `onCheckedChange`) to be usable at all.',
103
+ '',
104
+ '**13. `"checkbox"` and `"checkboxGroup"` name themselves via `inputProps`, not the top-level',
105
+ '`label`.** `CheckboxInput` renders its own inline `label` beside the box; `CheckboxGroup` renders',
106
+ 'a `<legend>` via `inputProps.legend`. Providing FormField\'s top-level `label` as well produces a',
107
+ 'second, redundant heading — pick one.',
108
+ '',
109
+ '**14. `"toggle"` is the one case where the top-level `label` prop is doing real work.** Standalone',
110
+ '`Toggle` has no visible label and needs one hand-rolled; inside FormField, the top-level `label`',
111
+ 'renders the `<Label htmlFor={id}>` for you, so `Toggle` gets a proper accessible label for free.',
112
+ '',
113
+ '**15. `"radio"` matches `checkedValue` against `option.value`, not `option.id`.** `id` only',
114
+ 'supplies the React key. Also note `RadioButtonGroup` is controlled from one `checkedValue` +',
115
+ '`onChange` at the group level, unlike `CheckboxGroup` where every option carries its own',
116
+ '`checked` + `onChange`.',
117
+ '',
94
118
  '---',
95
119
  '',
96
120
  '### Accessibility',
@@ -128,7 +152,10 @@ const RELATED_COMPONENTS = [
128
152
  '[DatePicker](?path=/docs/components-datepicker--docs) · ',
129
153
  '[Combobox](?path=/docs/components-combobox--docs) · ',
130
154
  '[Fieldset](?path=/docs/components-formfield-fieldset--docs) · ',
131
- '[Label](?path=/docs/components-formfield-inputs-label--docs)',
155
+ '[Label](?path=/docs/components-formfield-inputs-label--docs) · ',
156
+ '[CheckboxInput](?path=/docs/components-formfield-inputs-checkbox--docs) · ',
157
+ '[RadioButtonInput](?path=/docs/components-formfield-inputs-radiobutton--docs) · ',
158
+ '[Toggle](?path=/docs/components-toggle--docs)',
132
159
  ].join('\n');
133
160
  const PROPS_INTRO = 'The preview below is wired to the **Controls** panel — tweak any prop to see the story update in real time.';
134
161
  function FormFieldDocsPage() {
@@ -172,7 +199,7 @@ const meta = {
172
199
  },
173
200
  inputType: {
174
201
  control: 'select',
175
- options: ['text', 'textarea', 'number', 'time', 'colourPicker', 'selectDropdown', 'datePicker', 'combobox'],
202
+ options: ['text', 'textarea', 'number', 'time', 'colourPicker', 'selectDropdown', 'datePicker', 'combobox', 'checkbox', 'checkboxGroup', 'toggle', 'radio'],
176
203
  description: [
177
204
  'Determines which input component is rendered.',
178
205
  'Defaults to `"text"` (renders `TextInput`).',
@@ -181,10 +208,15 @@ const meta = {
181
208
  '`"colourPicker"` → `ColourPickerDropdown` (hex colour sketch picker in a dropdown);',
182
209
  '`"selectDropdown"` → `SelectDropdown` (single or multi select with grouping);',
183
210
  '`"datePicker"` → `DatePicker` (calendar popover);',
184
- '`"combobox"` → `Combobox` (searchable, type-ahead).',
211
+ '`"combobox"` → `Combobox` (searchable, type-ahead);',
212
+ '`"checkbox"` → `CheckboxInput` (single opt-in/consent);',
213
+ '`"checkboxGroup"` → `CheckboxGroup` (several independent selections);',
214
+ '`"toggle"` → `Toggle` (instant on/off switch);',
215
+ '`"radio"` → `RadioButtonGroup` (one choice from a short list).',
216
+ 'The last four require `inputProps` — see the developer notes.',
185
217
  ].join(' '),
186
218
  table: {
187
- type: { summary: "'text' | 'textarea' | 'number' | 'time' | 'colourPicker' | 'selectDropdown' | 'datePicker' | 'combobox'" },
219
+ type: { summary: "'text' | 'textarea' | 'number' | 'time' | 'colourPicker' | 'selectDropdown' | 'datePicker' | 'combobox' | 'checkbox' | 'checkboxGroup' | 'toggle' | 'radio'" },
188
220
  defaultValue: { summary: "'text'" },
189
221
  },
190
222
  },
@@ -256,9 +288,10 @@ const meta = {
256
288
  '**Do NOT set `hasError`, `aria-invalid`, or `aria-describedby` here** — FormField builds',
257
289
  'these automatically. They are spread BEFORE `inputProps` and will be overridden.',
258
290
  'The Controls panel cannot represent this discriminated union — configure it in the story code.',
291
+ '**Required, not optional, for `"checkbox"`, `"checkboxGroup"`, `"toggle"`, and `"radio"`.**',
259
292
  ].join(' '),
260
293
  table: {
261
- type: { summary: 'TextInputProps | TextAreaProps | NumberInputProps | TimeInputProps | ColourPickerDropdownProps | SelectDropdownInputProps | DatePickerProps | ComboboxProps' },
294
+ type: { summary: 'TextInputProps | TextAreaProps | NumberInputProps | TimeInputProps | ColourPickerDropdownProps | SelectDropdownInputProps | DatePickerProps | DateTimePickerProps | ComboboxProps | CheckboxInputProps | CheckboxGroupProps | Toggle.Props | RadioButtonGroupProps' },
262
295
  },
263
296
  },
264
297
  },
@@ -1199,4 +1232,278 @@ export default CompleteStudentFormExample;
1199
1232
  '',
1200
1233
  'This replaces the old `FormExample` story which used `"1rem"` gaps and non-school copy.',
1201
1234
  ].join('\n'));
1235
+ export const WithCheckbox = withDescription({
1236
+ parameters: {
1237
+ docs: {
1238
+ source: {
1239
+ language: 'tsx',
1240
+ code: `
1241
+ import { FormField } from '@arbor-education/design-system.components';
1242
+
1243
+ function WithCheckboxExample() {
1244
+ return (
1245
+ <div style={{ maxWidth: '28rem', display: 'flex', flexDirection: 'column', gap: 'var(--spacing-large)' }}>
1246
+ <FormField
1247
+ id="sms-alerts-opt-in"
1248
+ inputType="checkbox"
1249
+ fieldDescription="Sent for unexplained absences and behaviour incidents"
1250
+ inputProps={{
1251
+ label: 'Notify parents by SMS',
1252
+ checked: true,
1253
+ onChange: (event) => console.log(event.target.checked),
1254
+ }}
1255
+ />
1256
+ <FormField
1257
+ id="data-accuracy-ack"
1258
+ inputType="checkbox"
1259
+ inputProps={{
1260
+ label: 'I confirm this record is accurate and up to date',
1261
+ checked: false,
1262
+ onChange: (event) => console.log(event.target.checked),
1263
+ }}
1264
+ />
1265
+ <FormField
1266
+ id="parental-consent"
1267
+ inputType="checkbox"
1268
+ errorText="You must confirm parental consent before submitting"
1269
+ inputProps={{
1270
+ label: 'I have obtained parental consent',
1271
+ checked: false,
1272
+ onChange: (event) => console.log(event.target.checked),
1273
+ }}
1274
+ />
1275
+ </div>
1276
+ );
1277
+ }
1278
+ export default WithCheckboxExample;
1279
+ `.trim(),
1280
+ },
1281
+ },
1282
+ },
1283
+ render: () => (_jsxs("div", { style: { maxWidth: '28rem', padding: 'var(--spacing-xlarge)', display: 'flex', flexDirection: 'column', gap: 'var(--spacing-large)' }, children: [_jsx(FormField, { id: "sms-alerts-opt-in", inputType: "checkbox", fieldDescription: "Sent for unexplained absences and behaviour incidents", inputProps: {
1284
+ label: 'Notify parents by SMS',
1285
+ checked: true,
1286
+ onChange: fn(),
1287
+ } }), _jsx(FormField, { id: "data-accuracy-ack", inputType: "checkbox", inputProps: {
1288
+ label: 'I confirm this record is accurate and up to date',
1289
+ checked: false,
1290
+ onChange: fn(),
1291
+ } }), _jsx(FormField, { id: "parental-consent", inputType: "checkbox", errorText: "You must confirm parental consent before submitting", inputProps: {
1292
+ label: 'I have obtained parental consent',
1293
+ checked: false,
1294
+ onChange: fn(),
1295
+ } })] })),
1296
+ }, [
1297
+ '`inputType="checkbox"` renders a `CheckboxInput` and, unlike most other `inputType`s, its',
1298
+ '`inputProps` are **required** — `CheckboxInput.Props` has no optional variant in the union.',
1299
+ '',
1300
+ '**Skip the top-level `label` prop for checkboxes.** `CheckboxInput` renders its own inline',
1301
+ '`label` next to the box, inside the same `<label>` element as the input. Setting FormField\'s',
1302
+ 'top-level `label` as well produces two separate label texts stacked above and beside the box.',
1303
+ 'Use `fieldDescription` for supporting copy instead — it still renders above the input.',
1304
+ '',
1305
+ '**`checked` has no default and must be controlled.** There is no `defaultChecked` escape hatch',
1306
+ 'the way there is on `Toggle` — pair `checked` with `onChange` or the box will never update.',
1307
+ ].join('\n'));
1308
+ export const WithCheckboxGroup = withDescription({
1309
+ parameters: {
1310
+ docs: {
1311
+ source: {
1312
+ language: 'tsx',
1313
+ code: `
1314
+ import { FormField } from '@arbor-education/design-system.components';
1315
+
1316
+ function WithCheckboxGroupExample() {
1317
+ return (
1318
+ <div style={{ maxWidth: '28rem', display: 'flex', flexDirection: 'column', gap: 'var(--spacing-large)' }}>
1319
+ <FormField
1320
+ id="support-needs"
1321
+ inputType="checkboxGroup"
1322
+ fieldDescription="Select all that currently apply — this can be updated at any time"
1323
+ inputProps={{
1324
+ legend: 'Support needs',
1325
+ options: [
1326
+ { id: 'autism', label: 'Autism spectrum', checked: true, onChange: (event) => console.log(event.target.checked) },
1327
+ { id: 'dyslexia', label: 'Dyslexia', checked: false, onChange: (event) => console.log(event.target.checked) },
1328
+ { id: 'eal', label: 'EAL support', checked: false, onChange: (event) => console.log(event.target.checked) },
1329
+ ],
1330
+ }}
1331
+ />
1332
+ <FormField
1333
+ id="consent-forms"
1334
+ inputType="checkboxGroup"
1335
+ errorText="Select at least one consent option before continuing"
1336
+ inputProps={{
1337
+ legend: 'Consent forms received',
1338
+ options: [
1339
+ { id: 'medical', label: 'Medical consent', checked: false, onChange: (event) => console.log(event.target.checked) },
1340
+ { id: 'photo', label: 'Photo consent', checked: false, onChange: (event) => console.log(event.target.checked) },
1341
+ ],
1342
+ }}
1343
+ />
1344
+ </div>
1345
+ );
1346
+ }
1347
+ export default WithCheckboxGroupExample;
1348
+ `.trim(),
1349
+ },
1350
+ },
1351
+ },
1352
+ render: () => (_jsxs("div", { style: { maxWidth: '28rem', padding: 'var(--spacing-xlarge)', display: 'flex', flexDirection: 'column', gap: 'var(--spacing-large)' }, children: [_jsx(FormField, { id: "support-needs", inputType: "checkboxGroup", fieldDescription: "Select all that currently apply \u2014 this can be updated at any time", inputProps: {
1353
+ legend: 'Support needs',
1354
+ options: [
1355
+ { id: 'autism', label: 'Autism spectrum', checked: true, onChange: fn() },
1356
+ { id: 'dyslexia', label: 'Dyslexia', checked: false, onChange: fn() },
1357
+ { id: 'eal', label: 'EAL support', checked: false, onChange: fn() },
1358
+ ],
1359
+ } }), _jsx(FormField, { id: "consent-forms", inputType: "checkboxGroup", errorText: "Select at least one consent option before continuing", inputProps: {
1360
+ legend: 'Consent forms received',
1361
+ options: [
1362
+ { id: 'medical', label: 'Medical consent', checked: false, onChange: fn() },
1363
+ { id: 'photo', label: 'Photo consent', checked: false, onChange: fn() },
1364
+ ],
1365
+ } })] })),
1366
+ }, [
1367
+ '`inputType="checkboxGroup"` renders a `CheckboxGroup` — a `Fieldset` wrapping one `CheckboxInput`',
1368
+ 'per entry in `inputProps.options`. Like `"checkbox"`, `inputProps` is **required**.',
1369
+ '',
1370
+ '**Use `inputProps.legend`, not FormField\'s top-level `label`, to name the group.** `Fieldset`',
1371
+ 'renders its own `<legend>` — set it via `legend` inside `inputProps`. FormField\'s top-level',
1372
+ '`label` still renders (as a standalone `<Label>` above the fieldset) if you provide one, so pick',
1373
+ 'one or the other to avoid two headings for the same group.',
1374
+ '',
1375
+ '**Each option manages its own `checked` and `onChange`.** Unlike `RadioButtonGroup`, there is no',
1376
+ 'single group-level value — every entry in `options` needs its own `checked` boolean and `onChange`',
1377
+ 'handler. `option.id` doubles as the React key.',
1378
+ ].join('\n'));
1379
+ export const WithToggle = withDescription({
1380
+ parameters: {
1381
+ docs: {
1382
+ source: {
1383
+ language: 'tsx',
1384
+ code: `
1385
+ import { FormField } from '@arbor-education/design-system.components';
1386
+
1387
+ function WithToggleExample() {
1388
+ return (
1389
+ <div style={{ maxWidth: '28rem', display: 'flex', flexDirection: 'column', gap: 'var(--spacing-large)' }}>
1390
+ <FormField
1391
+ id="weekly-summary-emails"
1392
+ label="Weekly summary emails"
1393
+ inputType="toggle"
1394
+ fieldDescription="Sent every Friday afternoon with attendance and behaviour highlights"
1395
+ inputProps={{
1396
+ defaultChecked: true,
1397
+ onCheckedChange: (checked) => console.log(checked),
1398
+ }}
1399
+ />
1400
+ <FormField
1401
+ id="two-factor-auth"
1402
+ label="Require two-factor authentication"
1403
+ inputType="toggle"
1404
+ inputProps={{
1405
+ defaultChecked: false,
1406
+ onCheckedChange: (checked) => console.log(checked),
1407
+ }}
1408
+ />
1409
+ <FormField
1410
+ id="marketing-emails"
1411
+ label="Marketing emails"
1412
+ inputType="toggle"
1413
+ errorText="You must accept the updated marketing preferences to continue"
1414
+ inputProps={{
1415
+ defaultChecked: false,
1416
+ onCheckedChange: (checked) => console.log(checked),
1417
+ }}
1418
+ />
1419
+ </div>
1420
+ );
1421
+ }
1422
+ export default WithToggleExample;
1423
+ `.trim(),
1424
+ },
1425
+ },
1426
+ },
1427
+ render: () => (_jsxs("div", { style: { maxWidth: '28rem', padding: 'var(--spacing-xlarge)', display: 'flex', flexDirection: 'column', gap: 'var(--spacing-large)' }, children: [_jsx(FormField, { id: "weekly-summary-emails", label: "Weekly summary emails", inputType: "toggle", fieldDescription: "Sent every Friday afternoon with attendance and behaviour highlights", inputProps: {
1428
+ defaultChecked: true,
1429
+ onCheckedChange: fn(),
1430
+ } }), _jsx(FormField, { id: "two-factor-auth", label: "Require two-factor authentication", inputType: "toggle", inputProps: {
1431
+ defaultChecked: false,
1432
+ onCheckedChange: fn(),
1433
+ } }), _jsx(FormField, { id: "marketing-emails", label: "Marketing emails", inputType: "toggle", errorText: "You must accept the updated marketing preferences to continue", inputProps: {
1434
+ defaultChecked: false,
1435
+ onCheckedChange: fn(),
1436
+ } })] })),
1437
+ }, [
1438
+ '`inputType="toggle"` renders a `Toggle` (`inputProps` is `Toggle.Props` — Radix UI\'s `Switch.SwitchProps` plus `hasError` — and',
1439
+ '— like the other three new types — it is **required**).',
1440
+ '',
1441
+ '**FormField solves Toggle\'s biggest standalone gotcha for you.** Used on its own, `Toggle` has',
1442
+ 'no visible label and needs a hand-rolled `<label htmlFor={id}>` (see the `Toggle` stories\' `WithLabel`',
1443
+ 'example). Inside FormField, the top-level `label` prop renders that `<Label htmlFor={id}>` for you',
1444
+ 'automatically — just provide `label` and `id` as normal, no manual pairing required.',
1445
+ '',
1446
+ '**`onCheckedChange` receives a boolean, not an event.** `(checked: boolean) => void` — there is',
1447
+ 'no `event.target.checked` to unwrap, unlike the native-input-backed `checkbox` and `radio` types.',
1448
+ ].join('\n'));
1449
+ export const WithRadio = withDescription({
1450
+ parameters: {
1451
+ docs: {
1452
+ source: {
1453
+ language: 'tsx',
1454
+ code: `
1455
+ import { FormField } from '@arbor-education/design-system.components';
1456
+
1457
+ function WithRadioExample() {
1458
+ return (
1459
+ <FormField
1460
+ id="contact-method"
1461
+ inputType="radio"
1462
+ fieldDescription="Used for attendance and behaviour notifications only"
1463
+ errorText="Please select a contact method"
1464
+ inputProps={{
1465
+ legend: 'Preferred contact method',
1466
+ name: 'contact-method',
1467
+ checkedValue: 'sms',
1468
+ options: [
1469
+ { id: 'phone', value: 'phone', label: 'Phone call' },
1470
+ { id: 'email', value: 'email', label: 'Email' },
1471
+ { id: 'sms', value: 'sms', label: 'SMS' },
1472
+ ],
1473
+ onChange: (event) => console.log(event.target.value),
1474
+ }}
1475
+ />
1476
+ );
1477
+ }
1478
+ export default WithRadioExample;
1479
+ `.trim(),
1480
+ },
1481
+ },
1482
+ },
1483
+ render: () => (_jsx("div", { style: { maxWidth: '28rem', padding: 'var(--spacing-xlarge)' }, children: _jsx(FormField, { id: "contact-method", inputType: "radio", fieldDescription: "Used for attendance and behaviour notifications only", errorText: "Please select a contact method", inputProps: {
1484
+ legend: 'Preferred contact method',
1485
+ name: 'contact-method',
1486
+ checkedValue: 'sms',
1487
+ options: [
1488
+ { id: 'phone', value: 'phone', label: 'Phone call' },
1489
+ { id: 'email', value: 'email', label: 'Email' },
1490
+ { id: 'sms', value: 'sms', label: 'SMS' },
1491
+ ],
1492
+ onChange: fn(),
1493
+ } }) })),
1494
+ }, [
1495
+ '`inputType="radio"` renders a `RadioButtonGroup` — a `Fieldset` wrapping one radio per entry in',
1496
+ '`inputProps.options`. `inputProps` is **required** and, unlike `CheckboxGroup`, the group is',
1497
+ 'controlled from a single place: `checkedValue` + one `onChange`, not per-option state.',
1498
+ '',
1499
+ '**`checkedValue` is compared against each `option.value`, not `option.id`.** `id` only supplies',
1500
+ 'the React key — set `value` on every option and match it against `checkedValue` to control which',
1501
+ 'radio is selected.',
1502
+ '',
1503
+ '**`name` is required by the type, and functionally mandatory** — without a shared `name`, the',
1504
+ 'native radios do not group and multiple can appear selected at once.',
1505
+ '',
1506
+ '**Use `inputProps.legend`, not FormField\'s top-level `label`,** to name the group — the same',
1507
+ 'convention as `checkboxGroup`.',
1508
+ ].join('\n'));
1202
1509
  //# sourceMappingURL=FormField.stories.js.map