aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/molecules/forms/radio-group/radio-group.tsx
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-09-22 19:34:01 +0200
committerArmand Philippot <git@armandphilippot.com>2023-10-24 12:23:48 +0200
commita6ff5eee45215effb3344cb5d631a27a7c0369aa (patch)
tree5051747acf72318b4fc5c18d603e3757fbefdfdb /src/components/molecules/forms/radio-group/radio-group.tsx
parent651ea4fc992e77d2f36b3c68f8e7a70644246067 (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.tsx110
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);