From e26d821f738525477472e631d170d9ed218c1603 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 25 Feb 2022 19:17:09 +0100 Subject: chore: combine input/textarea/select in a single component --- .../FormElements/Field/Field.module.scss | 48 ++++++++++ src/components/FormElements/Field/Field.tsx | 106 +++++++++++++++++++++ src/components/FormElements/Form/Form.module.scss | 37 +++++++ src/components/FormElements/Form/Form.tsx | 27 ++++++ .../FormElements/FormItem/FormItem.module.scss | 4 + src/components/FormElements/FormItem/FormItem.tsx | 7 ++ .../FormElements/Label/Label.module.scss | 22 +++++ src/components/FormElements/Label/Label.tsx | 24 +++++ .../FormElements/Toggle/Toggle.module.scss | 75 +++++++++++++++ src/components/FormElements/Toggle/Toggle.tsx | 46 +++++++++ src/components/FormElements/index.tsx | 7 ++ 11 files changed, 403 insertions(+) create mode 100644 src/components/FormElements/Field/Field.module.scss create mode 100644 src/components/FormElements/Field/Field.tsx create mode 100644 src/components/FormElements/Form/Form.module.scss create mode 100644 src/components/FormElements/Form/Form.tsx create mode 100644 src/components/FormElements/FormItem/FormItem.module.scss create mode 100644 src/components/FormElements/FormItem/FormItem.tsx create mode 100644 src/components/FormElements/Label/Label.module.scss create mode 100644 src/components/FormElements/Label/Label.tsx create mode 100644 src/components/FormElements/Toggle/Toggle.module.scss create mode 100644 src/components/FormElements/Toggle/Toggle.tsx create mode 100644 src/components/FormElements/index.tsx (limited to 'src/components/FormElements') diff --git a/src/components/FormElements/Field/Field.module.scss b/src/components/FormElements/Field/Field.module.scss new file mode 100644 index 0000000..3836856 --- /dev/null +++ b/src/components/FormElements/Field/Field.module.scss @@ -0,0 +1,48 @@ +@use "@styles/abstracts/functions" as fun; + +.field { + background: var(--color-bg-tertiary); + border: fun.convert-px(2) solid var(--color-border); + box-shadow: fun.convert-px(3) fun.convert-px(3) 0 0 var(--color-shadow); + transition: all 0.25s linear 0s; + + &:not(.select) { + width: 100%; + padding: var(--spacing-2xs) var(--spacing-xs); + } + + &:hover { + box-shadow: fun.convert-px(5) fun.convert-px(5) 0 fun.convert-px(1) + var(--color-shadow); + transform: translate(#{fun.convert-px(-3)}, #{fun.convert-px(-3)}); + } + + &:focus { + background: var(--color-bg); + border-color: var(--color-primary); + box-shadow: 0 0 0 0 var(--color-shadow); + transform: translate(#{fun.convert-px(3)}, #{fun.convert-px(3)}); + outline: none; + transition: all 0.2s ease-in-out 0s, transform 0.3s ease-out 0s; + } +} + +.select { + padding: fun.convert-px(3) var(--spacing-xs); + cursor: pointer; + + &:hover { + box-shadow: fun.convert-px(4) fun.convert-px(4) 0 fun.convert-px(1) + var(--color-shadow); + transform: translate(#{fun.convert-px(-2)}, #{fun.convert-px(-2)}); + } + + &:focus { + box-shadow: 0 0 0 0 var(--color-shadow); + transform: translate(#{fun.convert-px(3)}, #{fun.convert-px(3)}); + } +} + +.textarea { + min-height: fun.convert-px(200); +} 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) => void; + required?: boolean; + kind?: FieldType; + label?: ReactElement; + options?: SelectOptions[]; + }, + ref: ForwardedRef +) => { + const updateValue = ( + e: ChangeEvent + ) => { + setValue(e.target.value); + }; + + const getOptions = () => { + return options + ? options.map((option) => ( + + )) + : ''; + }; + + const getField = () => { + switch (kind) { + case 'select': + return ( + + ); + case 'textarea': + return ( +