From b145ed4492de834f5cea9437e9772c4f7fbe90ec Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Thu, 31 Mar 2022 17:57:39 +0200
Subject: chore: add a Field component

---
 src/components/atoms/forms/field.tsx | 94 ++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100644 src/components/atoms/forms/field.tsx

(limited to 'src/components/atoms/forms/field.tsx')

diff --git a/src/components/atoms/forms/field.tsx b/src/components/atoms/forms/field.tsx
new file mode 100644
index 0000000..7d1ac93
--- /dev/null
+++ b/src/components/atoms/forms/field.tsx
@@ -0,0 +1,94 @@
+import { ChangeEvent, FC, SetStateAction } from 'react';
+import styles from './forms.module.scss';
+
+type FieldType =
+  | 'datetime-local'
+  | 'email'
+  | 'number'
+  | 'search'
+  | 'tel'
+  | 'text'
+  | 'textarea'
+  | 'time'
+  | 'url';
+
+type FieldProps = {
+  /**
+   * Field state. Either enabled (false) or disabled (true).
+   */
+  disabled?: boolean;
+  /**
+   * Field id attribute.
+   */
+  id?: string;
+  /**
+   * Field maximum value.
+   */
+  max?: number | string;
+  /**
+   * Field minimum value.
+   */
+  min?: number | string;
+  /**
+   * Field name attribute.
+   */
+  name?: string;
+  /**
+   * Placeholder value.
+   */
+  placeholder?: string;
+  /**
+   * True if the field is required. Default: false.
+   */
+  required?: boolean;
+  /**
+   * Callback function to set field value.
+   */
+  setValue: (value: SetStateAction<string>) => void;
+  /**
+   * Field incremental values that are valid.
+   */
+  step?: number | string;
+  /**
+   * Field type. Default: text.
+   */
+  type: FieldType;
+  /**
+   * Field value.
+   */
+  value: string;
+};
+
+/**
+ * Field component.
+ *
+ * Render either an input or a textarea.
+ */
+const Field: FC<FieldProps> = ({ setValue, type, ...props }) => {
+  /**
+   * Update select value when an option is selected.
+   * @param e - The option change event.
+   */
+  const updateValue = (
+    e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
+  ) => {
+    setValue(e.target.value);
+  };
+
+  return type === 'textarea' ? (
+    <textarea
+      onChange={updateValue}
+      className={`${styles.field} ${styles['field--textarea']}`}
+      {...props}
+    />
+  ) : (
+    <input
+      type={type}
+      onChange={updateValue}
+      className={styles.field}
+      {...props}
+    />
+  );
+};
+
+export default Field;
-- 
cgit v1.2.3

