diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-02-25 19:17:09 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-02-25 19:17:09 +0100 |
| commit | e26d821f738525477472e631d170d9ed218c1603 (patch) | |
| tree | 70ec0c29d003d462de6926f1faa09354e3ff6d90 /src/components/FormElements/Field/Field.tsx | |
| parent | cb4764f8670f67627c407591c89b8d3637c190a7 (diff) | |
chore: combine input/textarea/select in a single component
Diffstat (limited to 'src/components/FormElements/Field/Field.tsx')
| -rw-r--r-- | src/components/FormElements/Field/Field.tsx | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/components/FormElements/Field/Field.tsx b/src/components/FormElements/Field/Field.tsx new file mode 100644 index 0000000..c8df0f9 --- /dev/null +++ b/src/components/FormElements/Field/Field.tsx @@ -0,0 +1,106 @@ +import { + ChangeEvent, + ForwardedRef, + forwardRef, + ReactElement, + SetStateAction, +} from 'react'; +import styles from './Field.module.scss'; + +type FieldType = 'email' | 'number' | 'search' | 'select' | 'text' | 'textarea'; +type SelectOptions = { + id: string; + name: string; + value: string; +}; + +const Field = ( + { + id, + name, + value, + setValue, + required = false, + kind = 'text', + label, + options, + }: { + id: string; + name: string; + value: string; + setValue: (value: SetStateAction<string>) => void; + required?: boolean; + kind?: FieldType; + label?: ReactElement; + options?: SelectOptions[]; + }, + ref: ForwardedRef<HTMLInputElement | HTMLTextAreaElement> +) => { + const updateValue = ( + e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement> + ) => { + setValue(e.target.value); + }; + + const getOptions = () => { + return options + ? options.map((option) => ( + <option key={option.id} value={option.value}> + {option.name} + </option> + )) + : ''; + }; + + const getField = () => { + switch (kind) { + case 'select': + return ( + <select + name={name} + id={id} + value={value} + onChange={updateValue} + required={required} + className={`${styles.field} ${styles.select}`} + > + {getOptions()} + </select> + ); + case 'textarea': + return ( + <textarea + ref={ref as ForwardedRef<HTMLTextAreaElement>} + id={id} + name={name} + value={value} + required={required} + onChange={updateValue} + className={`${styles.field} ${styles.textarea}`} + /> + ); + default: + return ( + <input + ref={ref as ForwardedRef<HTMLInputElement>} + type={kind} + id={id} + name={name} + value={value} + required={required} + onChange={updateValue} + className={styles.field} + /> + ); + } + }; + + return ( + <> + {label} + {getField()} + </> + ); +}; + +export default forwardRef(Field); |
