diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-09-22 19:34:01 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-10-24 12:23:48 +0200 |
| commit | a6ff5eee45215effb3344cb5d631a27a7c0369aa (patch) | |
| tree | 5051747acf72318b4fc5c18d603e3757fbefdfdb /src/components/molecules/forms/radio-group/radio-group.tsx | |
| parent | 651ea4fc992e77d2f36b3c68f8e7a70644246067 (diff) | |
refactor(components): rewrite form components
Diffstat (limited to 'src/components/molecules/forms/radio-group/radio-group.tsx')
| -rw-r--r-- | src/components/molecules/forms/radio-group/radio-group.tsx | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/components/molecules/forms/radio-group/radio-group.tsx b/src/components/molecules/forms/radio-group/radio-group.tsx new file mode 100644 index 0000000..0ca4dac --- /dev/null +++ b/src/components/molecules/forms/radio-group/radio-group.tsx @@ -0,0 +1,110 @@ +import { ForwardRefRenderFunction, forwardRef } from 'react'; +import { + Fieldset, + FieldsetProps, + Label, + LabelProps, + Radio, + RadioProps, +} from '../../../atoms'; +import { LabelledField } from '../labelled-field'; +import styles from './radio-group.module.scss'; + +export type RadioGroupItem = { + /** + * The item id. + */ + id: string; + /** + * Should the item be disabled? + */ + isDisabled?: boolean; + /** + * The item label. + */ + label: LabelProps['children']; + /** + * The item value. + */ + value: string; +}; + +export type RadioGroupProps = Omit<FieldsetProps, 'children' | 'role'> & { + /** + * Should we display the radio buttons inlined? + * + * @default false + */ + isInline?: boolean; + /** + * The radio group name. + */ + name: string; + /** + * A function to handle selection change. + */ + onSwitch?: RadioProps['onChange']; + /** + * The options. + */ + options: RadioGroupItem[]; + /** + * The selected value. It should match a RadioGroupItem value or be undefined. + */ + value?: RadioGroupItem['value']; +}; + +const RadioGroupWithRef: ForwardRefRenderFunction< + HTMLFieldSetElement, + RadioGroupProps +> = ( + { + className = '', + isInline = false, + name, + onSwitch, + options, + value, + ...props + }, + ref +) => { + const layoutModifier = isInline ? styles['group--inline'] : ''; + const groupClass = `${layoutModifier} ${className}`; + + return ( + <Fieldset + {...props} + className={groupClass} + isInline={isInline} + ref={ref} + role="radiogroup" + > + {options.map((option) => ( + <LabelledField + className={styles.option} + field={ + <Radio + id={option.id} + isChecked={value === option.value} + name={name} + onChange={onSwitch} + value={option.value} + /> + } + isInline + isReversedOrder + key={option.id} + label={<Label htmlFor={option.id}>{option.label}</Label>} + /> + ))} + </Fieldset> + ); +}; + +/** + * RadioGroup component + * + * Render a group of labelled radio buttons. + */ +export const RadioGroup = forwardRef(RadioGroupWithRef); |
