From 782cc0a31a866519fb7c3e18a523b347d3e40238 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Mon, 30 May 2022 19:27:21 +0200
Subject: chore: replace Checkbox component with a BooleanField component

Checkbox and radio buttons are working the same way so I decided to
group them in a same component.
---
 .../molecules/forms/labelled-boolean-field.tsx     | 92 ++++++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 src/components/molecules/forms/labelled-boolean-field.tsx

(limited to 'src/components/molecules/forms/labelled-boolean-field.tsx')

diff --git a/src/components/molecules/forms/labelled-boolean-field.tsx b/src/components/molecules/forms/labelled-boolean-field.tsx
new file mode 100644
index 0000000..46eb080
--- /dev/null
+++ b/src/components/molecules/forms/labelled-boolean-field.tsx
@@ -0,0 +1,92 @@
+import BooleanField, {
+  type BooleanFieldProps,
+} from '@components/atoms/forms/boolean-field';
+import Label, { type LabelProps } from '@components/atoms/forms/label';
+import { FC } from 'react';
+import styles from './labelled-boolean-field.module.scss';
+
+export type LabelledBooleanFieldProps = Omit<
+  BooleanFieldProps,
+  'aria-labelledby' | 'className'
+> & {
+  /**
+   * Set additional classnames to the labelled field wrapper.
+   */
+  className?: string;
+  /**
+   * Set additional classnames to the field.
+   */
+  fieldClassName?: LabelledBooleanFieldProps['className'];
+  /**
+   * The field label.
+   */
+  label: LabelProps['children'];
+  /**
+   * Set additional classnames to the label.
+   */
+  labelClassName?: LabelProps['className'];
+  /**
+   * The label position. Default: left.
+   */
+  labelPosition?: 'left' | 'right';
+  /**
+   * The label size.
+   */
+  labelSize?: LabelProps['size'];
+};
+
+/**
+ * LabelledBooleanField component
+ *
+ * Render a checkbox or radio button with a label.
+ */
+const LabelledBooleanField: FC<LabelledBooleanFieldProps> = ({
+  className = '',
+  fieldClassName,
+  hidden,
+  id,
+  label,
+  labelClassName,
+  labelPosition = 'left',
+  labelSize,
+  ...props
+}) => {
+  const labelHiddenModifier = hidden ? 'label--hidden' : 'label--visible';
+  const labelPositionModifier = `label--${labelPosition}`;
+
+  return labelPosition === 'left' ? (
+    <span className={`${styles.wrapper} ${className}`}>
+      <Label
+        className={`${styles[labelPositionModifier]} ${styles[labelHiddenModifier]} ${labelClassName}`}
+        htmlFor={id}
+        size={labelSize}
+      >
+        {label}
+      </Label>
+      <BooleanField
+        className={fieldClassName}
+        hidden={hidden}
+        id={id}
+        {...props}
+      />
+    </span>
+  ) : (
+    <span className={`${styles.wrapper} ${className}`}>
+      <BooleanField
+        className={fieldClassName}
+        hidden={hidden}
+        id={id}
+        {...props}
+      />
+      <Label
+        className={`${styles[labelPositionModifier]} ${styles[labelHiddenModifier]} ${labelClassName}`}
+        htmlFor={id}
+        size={labelSize}
+      >
+        {label}
+      </Label>
+    </span>
+  );
+};
+
+export default LabelledBooleanField;
-- 
cgit v1.2.3

