diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-05-24 19:35:12 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-24 19:35:12 +0200 |
| commit | c85ab5ad43ccf52881ee224672c41ec30021cf48 (patch) | |
| tree | 8058808d9bfca19383f120c46b34d99ff2f89f63 /src/components/atoms/forms/form.tsx | |
| parent | 52404177c07a2aab7fc894362fb3060dff2431a0 (diff) | |
| parent | 11b9de44a4b2f305a6a484187805e429b2767118 (diff) | |
refactor: use storybook and atomic design (#16)
BREAKING CHANGE: rewrite most of the Typescript types, so the content format (the meta in particular) needs to be updated.
Diffstat (limited to 'src/components/atoms/forms/form.tsx')
| -rw-r--r-- | src/components/atoms/forms/form.tsx | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/components/atoms/forms/form.tsx b/src/components/atoms/forms/form.tsx new file mode 100644 index 0000000..b819aea --- /dev/null +++ b/src/components/atoms/forms/form.tsx @@ -0,0 +1,76 @@ +import { Children, FC, FormEvent, Fragment, ReactNode } from 'react'; +import styles from './forms.module.scss'; + +export type FormProps = { + /** + * An accessible name. + */ + 'aria-label'?: string; + /** + * One or more ids that refers to the form name. + */ + 'aria-labelledby'?: string; + /** + * The form body. + */ + children: ReactNode; + /** + * Set additional classnames to the form wrapper. + */ + className?: string; + /** + * Wrap each items with a div. Default: true. + */ + grouped?: boolean; + /** + * A callback function to execute on submit. + */ + onSubmit: () => void; +}; + +/** + * Form component. + * + * Render children wrapped in a form element. + */ +const Form: FC<FormProps> = ({ + children, + grouped = true, + onSubmit, + ...props +}) => { + const arrayChildren = Children.toArray(children); + + /** + * Get the form items. + * @returns {JSX.Element[]} An array of child elements wrapped in a div. + */ + const getFormItems = (): JSX.Element[] => { + return arrayChildren.map((child, index) => + grouped ? ( + <div key={`item-${index}`} className={styles.item}> + {child} + </div> + ) : ( + <Fragment key={`item-${index}`}>{child}</Fragment> + ) + ); + }; + + /** + * Handle form submit. + * @param {FormEvent} e - The form event. + */ + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + onSubmit(); + }; + + return ( + <form onSubmit={handleSubmit} {...props}> + {getFormItems()} + </form> + ); +}; + +export default Form; |
