@arbor-education/design-system.components 3.0.2 → 3.1.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 (41) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/components/formField/FormField.d.ts +34 -18
  3. package/dist/components/formField/FormField.d.ts.map +1 -1
  4. package/dist/components/formField/FormField.js +5 -1
  5. package/dist/components/formField/FormField.js.map +1 -1
  6. package/dist/components/formField/FormField.stories.d.ts +4 -0
  7. package/dist/components/formField/FormField.stories.d.ts.map +1 -1
  8. package/dist/components/formField/FormField.stories.js +314 -7
  9. package/dist/components/formField/FormField.stories.js.map +1 -1
  10. package/dist/components/formField/FormField.test.js +66 -0
  11. package/dist/components/formField/FormField.test.js.map +1 -1
  12. package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts +1 -0
  13. package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts.map +1 -1
  14. package/dist/components/formField/inputs/checkbox/CheckboxGroup.js +2 -2
  15. package/dist/components/formField/inputs/checkbox/CheckboxGroup.js.map +1 -1
  16. package/dist/components/formField/inputs/checkbox/CheckboxInput.d.ts +1 -0
  17. package/dist/components/formField/inputs/checkbox/CheckboxInput.d.ts.map +1 -1
  18. package/dist/components/formField/inputs/checkbox/CheckboxInput.js +2 -2
  19. package/dist/components/formField/inputs/checkbox/CheckboxInput.js.map +1 -1
  20. package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts +1 -0
  21. package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts.map +1 -1
  22. package/dist/components/formField/inputs/radio/RadioButtonGroup.js +2 -2
  23. package/dist/components/formField/inputs/radio/RadioButtonGroup.js.map +1 -1
  24. package/dist/components/toggle/Toggle.d.ts +7 -1
  25. package/dist/components/toggle/Toggle.d.ts.map +1 -1
  26. package/dist/components/toggle/Toggle.js +2 -2
  27. package/dist/components/toggle/Toggle.js.map +1 -1
  28. package/dist/components/toggle/Toggle.stories.d.ts +1 -1
  29. package/dist/index.css +21 -0
  30. package/dist/index.css.map +1 -1
  31. package/package.json +1 -1
  32. package/src/components/formField/FormField.stories.tsx +398 -7
  33. package/src/components/formField/FormField.test.tsx +100 -0
  34. package/src/components/formField/FormField.tsx +46 -27
  35. package/src/components/formField/inputs/checkbox/CheckboxGroup.tsx +3 -2
  36. package/src/components/formField/inputs/checkbox/CheckboxInput.tsx +3 -0
  37. package/src/components/formField/inputs/checkbox/checkboxInput.scss +4 -0
  38. package/src/components/formField/inputs/radio/RadioButtonGroup.tsx +11 -1
  39. package/src/components/formField/inputs/radio/radioButtonInput.scss +8 -0
  40. package/src/components/toggle/Toggle.tsx +13 -3
  41. package/src/components/toggle/toggle.scss +22 -0
@@ -1,16 +1,19 @@
1
1
  import classNames from 'classnames';
2
2
  import { Combobox } from 'Components/combobox/Combobox';
3
- import type { ComboboxProps } from 'Components/combobox/types';
4
- import { DatePicker, type DatePickerProps } from 'Components/datePicker/DatePicker';
5
- import { DateTimePicker, type DateTimePickerProps } from 'Components/dateTimePicker/DateTimePicker';
3
+ import { DatePicker } from 'Components/datePicker/DatePicker';
4
+ import { DateTimePicker } from 'Components/dateTimePicker/DateTimePicker';
6
5
  import { Icon } from '../icon/Icon.js';
7
- import { ColourPickerDropdown, type ColourPickerDropdownProps } from './inputs/colourPickerDropdown/ColourPickerDropdown.js';
8
- import { NumberInput, type NumberInputProps } from './inputs/number/NumberInput.js';
9
- import { SelectDropdown, type SelectDropdownInputProps } from './inputs/selectDropdown/SelectDropdown.js';
10
- import { TextInput, type TextInputProps } from './inputs/text/TextInput.js';
11
- import { TimeInput, type TimeInputProps } from './inputs/time/TimeInput.js';
12
- import { TextArea, type TextAreaProps } from './inputs/textArea/TextArea.js';
6
+ import { ColourPickerDropdown } from './inputs/colourPickerDropdown/ColourPickerDropdown.js';
7
+ import { NumberInput } from './inputs/number/NumberInput.js';
8
+ import { SelectDropdown } from './inputs/selectDropdown/SelectDropdown.js';
9
+ import { TextInput } from './inputs/text/TextInput.js';
10
+ import { TimeInput } from './inputs/time/TimeInput.js';
11
+ import { TextArea } from './inputs/textArea/TextArea.js';
13
12
  import { Label } from './label/Label.js';
13
+ import { CheckboxInput } from './inputs/checkbox/CheckboxInput.js';
14
+ import { CheckboxGroup } from './inputs/checkbox/CheckboxGroup.js';
15
+ import { RadioButtonGroup } from './inputs/radio/RadioButtonGroup.js';
16
+ import { Toggle } from 'Components/toggle/Toggle.js';
14
17
 
15
18
  export type FormFieldProps = {
16
19
  className?: string;
@@ -21,15 +24,19 @@ export type FormFieldProps = {
21
24
  helperLinkUrl?: string;
22
25
  errorText?: string;
23
26
  } & (
24
- | { inputType?: 'text'; inputProps?: TextInputProps }
25
- | { inputType?: 'textarea'; inputProps?: TextAreaProps }
26
- | { inputType?: 'number'; inputProps?: NumberInputProps }
27
- | { inputType?: 'time'; inputProps?: TimeInputProps }
28
- | { inputType?: 'colourPicker'; inputProps?: ColourPickerDropdownProps }
29
- | { inputType?: 'selectDropdown'; inputProps?: SelectDropdownInputProps }
30
- | { inputType?: 'datePicker'; inputProps?: DatePickerProps }
31
- | { inputType?: 'dateTimePicker'; inputProps?: DateTimePickerProps }
32
- | { inputType?: 'combobox'; inputProps?: ComboboxProps }
27
+ | { inputType?: 'text'; inputProps?: TextInput.Props }
28
+ | { inputType?: 'textarea'; inputProps?: TextArea.Props }
29
+ | { inputType?: 'number'; inputProps?: NumberInput.Props }
30
+ | { inputType?: 'time'; inputProps?: TimeInput.Props }
31
+ | { inputType?: 'colourPicker'; inputProps?: ColourPickerDropdown.Props }
32
+ | { inputType?: 'selectDropdown'; inputProps?: SelectDropdown.Props }
33
+ | { inputType?: 'datePicker'; inputProps?: DatePicker.Props }
34
+ | { inputType?: 'dateTimePicker'; inputProps?: DateTimePicker.Props }
35
+ | { inputType?: 'combobox'; inputProps?: Combobox.Props }
36
+ | { inputType?: 'checkbox'; inputProps: CheckboxInput.Props }
37
+ | { inputType?: 'checkboxGroup'; inputProps: CheckboxGroup.Props }
38
+ | { inputType?: 'toggle'; inputProps: Toggle.Props }
39
+ | { inputType?: 'radio'; inputProps: RadioButtonGroup.Props }
33
40
  );
34
41
 
35
42
  export const FormField = (props: FormFieldProps) => {
@@ -61,31 +68,43 @@ export const FormField = (props: FormFieldProps) => {
61
68
  <span id={`${id}-description`} className="ds-form-field__description">{fieldDescription}</span>
62
69
  )}
63
70
  {inputType === 'text' && (
64
- <TextInput {...sharedProps} {...(inputProps as TextInputProps)} />
71
+ <TextInput {...sharedProps} {...(inputProps as TextInput.Props)} />
65
72
  )}
66
73
  {inputType === 'textarea' && (
67
- <TextArea {...sharedProps} {...(inputProps as TextAreaProps)} />
74
+ <TextArea {...sharedProps} {...(inputProps as TextArea.Props)} />
68
75
  )}
69
76
  {inputType === 'number' && (
70
- <NumberInput {...sharedProps} {...(inputProps as NumberInputProps)} />
77
+ <NumberInput {...sharedProps} {...(inputProps as NumberInput.Props)} />
71
78
  )}
72
79
  {inputType === 'time' && (
73
- <TimeInput {...sharedProps} {...(inputProps as TimeInputProps)} />
80
+ <TimeInput {...sharedProps} {...(inputProps as TimeInput.Props)} />
74
81
  )}
75
82
  {inputType === 'colourPicker' && (
76
- <ColourPickerDropdown {...sharedProps} {...(inputProps as ColourPickerDropdownProps)} />
83
+ <ColourPickerDropdown {...sharedProps} {...(inputProps as ColourPickerDropdown.Props)} />
77
84
  )}
78
85
  {inputType === 'selectDropdown' && (
79
- <SelectDropdown {...sharedProps} {...(inputProps as SelectDropdownInputProps)} />
86
+ <SelectDropdown {...sharedProps} {...(inputProps as SelectDropdown.Props)} />
80
87
  )}
81
88
  {inputType === 'datePicker' && (
82
- <DatePicker {...sharedProps} {...(inputProps as DatePickerProps)} />
89
+ <DatePicker {...sharedProps} {...(inputProps as DatePicker.Props)} />
83
90
  )}
84
91
  {inputType === 'dateTimePicker' && (
85
- <DateTimePicker {...sharedProps} {...(inputProps as DateTimePickerProps)} />
92
+ <DateTimePicker {...sharedProps} {...(inputProps as DateTimePicker.Props)} />
86
93
  )}
87
94
  {inputType === 'combobox' && (
88
- <Combobox {...sharedProps} {...(inputProps as ComboboxProps)} />
95
+ <Combobox {...sharedProps} {...(inputProps as Combobox.Props)} />
96
+ )}
97
+ {inputType === 'checkbox' && (
98
+ <CheckboxInput {...sharedProps} {...(inputProps as CheckboxInput.Props)} />
99
+ )}
100
+ {inputType === 'checkboxGroup' && (
101
+ <CheckboxGroup {...sharedProps} {...(inputProps as CheckboxGroup.Props)} />
102
+ )}
103
+ {inputType === 'toggle' && (
104
+ <Toggle {...sharedProps} {...(inputProps as Toggle.Props)} />
105
+ )}
106
+ {inputType === 'radio' && (
107
+ <RadioButtonGroup {...sharedProps} {...(inputProps as RadioButtonGroup.Props)} />
89
108
  )}
90
109
  {((helperLinkText && helperLinkUrl) || errorText) && (
91
110
  <div className="ds-form-field__message">
@@ -3,14 +3,15 @@ import { CheckboxInput, type CheckboxInputProps } from './CheckboxInput.js';
3
3
 
4
4
  export type CheckboxGroupProps = {
5
5
  options: (CheckboxInputProps & { id: string })[];
6
+ hasError?: boolean;
6
7
  } & FieldsetProps;
7
8
 
8
9
  export const CheckboxGroup = (props: CheckboxGroupProps) => {
9
- const { options, ...rest } = props;
10
+ const { options, hasError, ...rest } = props;
10
11
  return (
11
12
  <Fieldset {...rest}>
12
13
  {options.map((option: CheckboxInputProps) => (
13
- <CheckboxInput key={option.id} {...option} />
14
+ <CheckboxInput key={option.id} hasError={hasError} {...option} />
14
15
  ))}
15
16
  </Fieldset>
16
17
  );
@@ -5,6 +5,7 @@ import { Icon } from 'Components/icon/Icon';
5
5
  export type CheckboxInputProps = {
6
6
  indeterminate?: boolean;
7
7
  label?: string;
8
+ hasError?: boolean;
8
9
  } & InputHTMLAttributes<HTMLInputElement>;
9
10
 
10
11
  export const CheckboxInput = (props: CheckboxInputProps) => {
@@ -15,6 +16,7 @@ export const CheckboxInput = (props: CheckboxInputProps) => {
15
16
  checked = false,
16
17
  indeterminate = false,
17
18
  label,
19
+ hasError,
18
20
  ...rest
19
21
  } = props;
20
22
 
@@ -57,6 +59,7 @@ export const CheckboxInput = (props: CheckboxInputProps) => {
57
59
  checked={checked}
58
60
  onChange={onChange}
59
61
  aria-checked={indeterminate ? 'mixed' : checked}
62
+ aria-invalid={hasError}
60
63
  {...rest}
61
64
  />
62
65
  <span
@@ -64,6 +64,10 @@
64
64
  box-shadow: inset 0 0 0 var(--checkbox-input-control-unchecked-weight-border) var(--checkbox-input-control-unchecked-disabled-color-border);
65
65
  }
66
66
 
67
+ input[aria-invalid='true'] + .ds-checkbox-input {
68
+ box-shadow: inset 0 0 0 var(--checkbox-input-control-unchecked-weight-border) var(--form-field-text-error-color-border);
69
+ }
70
+
67
71
  input:checked:disabled + .ds-checkbox-input {
68
72
  background-color: var(--checkbox-input-control-checked-disabled-color-background);
69
73
  }
@@ -13,10 +13,19 @@ export type RadioButtonGroupProps = {
13
13
  options: RadioGroupOption[];
14
14
  checkedValue: string;
15
15
  onChange: (event: ChangeEvent<HTMLInputElement>) => void;
16
+ hasError?: boolean;
16
17
  } & Omit<FieldsetProps, 'onChange'>;
17
18
 
18
19
  export const RadioButtonGroup = (props: RadioButtonGroupProps) => {
19
- const { legend, name, options, checkedValue, onChange, ...rest } = props;
20
+ const {
21
+ legend,
22
+ name,
23
+ options,
24
+ checkedValue,
25
+ onChange,
26
+ hasError,
27
+ ...rest
28
+ } = props;
20
29
 
21
30
  return (
22
31
  <Fieldset legend={legend} {...rest}>
@@ -28,6 +37,7 @@ export const RadioButtonGroup = (props: RadioButtonGroupProps) => {
28
37
  label={option.label}
29
38
  checked={checkedValue === option.value}
30
39
  onChange={onChange}
40
+ hasError={hasError}
31
41
  />
32
42
  ))}
33
43
  </Fieldset>
@@ -75,6 +75,10 @@
75
75
  }
76
76
  }
77
77
 
78
+ .ds-radio-button-input__input[aria-invalid='true'] + .ds-radio-button-input__indicator {
79
+ border-color: var(--form-field-text-error-color-border);
80
+ }
81
+
78
82
  &:hover:not(:has(.ds-radio-button-input__input:disabled)) {
79
83
  .ds-radio-button-input__indicator {
80
84
  border-color: var(--checkbox-or-radio-button-group-hover-color-border);
@@ -93,6 +97,10 @@
93
97
  background-color: var(--checkbox-or-radio-button-group-selected-hover-color-check);
94
98
  }
95
99
  }
100
+
101
+ .ds-radio-button-input__input[aria-invalid='true'] + .ds-radio-button-input__indicator {
102
+ border-color: var(--form-field-text-error-color-border);
103
+ }
96
104
  }
97
105
  }
98
106
 
@@ -1,12 +1,22 @@
1
1
  import classNames from 'classnames';
2
2
  import { Switch } from 'radix-ui';
3
3
 
4
- export const Toggle = (props: Switch.SwitchProps) => {
5
- const { className, ...rest } = props;
4
+ export type ToggleProps = Switch.SwitchProps & { hasError?: boolean };
5
+
6
+ export const Toggle = (props: ToggleProps) => {
7
+ const { className, hasError, ...rest } = props;
6
8
 
7
9
  return (
8
- <Switch.Root className={classNames('ds-toggle', className)} {...rest}>
10
+ <Switch.Root
11
+ className={classNames('ds-toggle', { 'ds-toggle--error': hasError }, className)}
12
+ aria-invalid={hasError}
13
+ {...rest}
14
+ >
9
15
  <Switch.Thumb className="ds-toggle__thumb" />
10
16
  </Switch.Root>
11
17
  );
12
18
  };
19
+
20
+ export namespace Toggle {
21
+ export type Props = ToggleProps;
22
+ }
@@ -36,6 +36,28 @@
36
36
  }
37
37
  }
38
38
 
39
+ &--error {
40
+ border-color: var(--form-field-text-error-color-border);
41
+ }
42
+
43
+ &.ds-toggle--error:not(:disabled) {
44
+ &:focus,
45
+ &:hover,
46
+ &:active {
47
+ border-color: var(--form-field-text-error-color-border);
48
+ }
49
+
50
+ &[data-state="checked"] {
51
+ border-color: var(--form-field-text-error-color-border);
52
+
53
+ &:focus,
54
+ &:hover,
55
+ &:active {
56
+ border-color: var(--form-field-text-error-color-border);
57
+ }
58
+ }
59
+ }
60
+
39
61
  &[data-state="checked"] {
40
62
  background-color: var(--toggle-on-default-color-background);
41
63
  border-color: var(--toggle-on-default-color-border);