diff options
Diffstat (limited to 'src/components/atoms/forms')
| -rw-r--r-- | src/components/atoms/forms/boolean-field.stories.tsx | 10 | ||||
| -rw-r--r-- | src/components/atoms/forms/boolean-field.test.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/forms/boolean-field.tsx | 34 | ||||
| -rw-r--r-- | src/components/atoms/forms/field.stories.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/forms/field.test.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/forms/field.tsx | 20 | ||||
| -rw-r--r-- | src/components/atoms/forms/form.test.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/forms/form.tsx | 32 | ||||
| -rw-r--r-- | src/components/atoms/forms/index.ts | 5 | ||||
| -rw-r--r-- | src/components/atoms/forms/label.stories.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/forms/label.test.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/forms/label.tsx | 23 | ||||
| -rw-r--r-- | src/components/atoms/forms/select.stories.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/forms/select.test.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/forms/select.tsx | 32 |
15 files changed, 61 insertions, 111 deletions
diff --git a/src/components/atoms/forms/boolean-field.stories.tsx b/src/components/atoms/forms/boolean-field.stories.tsx index 8b6136b..3d6f8c3 100644 --- a/src/components/atoms/forms/boolean-field.stories.tsx +++ b/src/components/atoms/forms/boolean-field.stories.tsx @@ -1,13 +1,13 @@ import { ComponentMeta, ComponentStory } from '@storybook/react'; import { useState } from 'react'; -import BooleanFieldComponent from './boolean-field'; +import { BooleanField } from './boolean-field'; /** * BooleanField - Storybook Meta */ export default { title: 'Atoms/Forms', - component: BooleanFieldComponent, + component: BooleanField, args: { hidden: false, }, @@ -130,9 +130,9 @@ export default { }, }, }, -} as ComponentMeta<typeof BooleanFieldComponent>; +} as ComponentMeta<typeof BooleanField>; -const Template: ComponentStory<typeof BooleanFieldComponent> = ({ +const Template: ComponentStory<typeof BooleanField> = ({ checked, onChange: _onChange, ...args @@ -140,7 +140,7 @@ const Template: ComponentStory<typeof BooleanFieldComponent> = ({ const [isChecked, setIsChecked] = useState<boolean>(checked); return ( - <BooleanFieldComponent + <BooleanField checked={isChecked} onChange={() => { setIsChecked(!isChecked); diff --git a/src/components/atoms/forms/boolean-field.test.tsx b/src/components/atoms/forms/boolean-field.test.tsx index b6fa625..503d1ce 100644 --- a/src/components/atoms/forms/boolean-field.test.tsx +++ b/src/components/atoms/forms/boolean-field.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '../../../../tests/utils'; -import BooleanField from './boolean-field'; +import { BooleanField } from './boolean-field'; describe('BooleanField', () => { it('renders an unchecked checkbox', () => { diff --git a/src/components/atoms/forms/boolean-field.tsx b/src/components/atoms/forms/boolean-field.tsx index 946e375..8f33a42 100644 --- a/src/components/atoms/forms/boolean-field.tsx +++ b/src/components/atoms/forms/boolean-field.tsx @@ -1,24 +1,15 @@ -import { ChangeEventHandler, FC, MouseEventHandler } from 'react'; +import { FC, InputHTMLAttributes } from 'react'; import styles from './boolean-field.module.scss'; -export type BooleanFieldProps = { - /** - * One or more ids that refers to the checkbox name. - */ - 'aria-labelledby'?: string; +export type BooleanFieldProps = Omit< + InputHTMLAttributes<HTMLInputElement>, + 'checked' | 'hidden' | 'name' | 'type' | 'value' +> & { /** * True if the field should be checked. */ checked: boolean; /** - * Add classnames to the checkbox. - */ - className?: string; - /** - * Field id attribute. - */ - id: string; - /** * True if the field should be visually hidden. Default: false. */ hidden?: boolean; @@ -27,14 +18,6 @@ export type BooleanFieldProps = { */ name: string; /** - * Callback function to handle state change. - */ - onChange: ChangeEventHandler<HTMLInputElement>; - /** - * A callback function to handle click. - */ - onClick?: MouseEventHandler<HTMLInputElement>; - /** * The input type. */ type: 'checkbox' | 'radio'; @@ -49,14 +32,13 @@ export type BooleanFieldProps = { * * Render a checkbox or a radio input type. */ -const BooleanField: FC<BooleanFieldProps> = ({ +export const BooleanField: FC<BooleanFieldProps> = ({ className = '', hidden = false, ...props }) => { const modifier = hidden ? 'hidden' : ''; + const inputClass = `${styles[modifier]} ${className}`; - return <input className={`${styles[modifier]} ${className}`} {...props} />; + return <input {...props} className={inputClass} />; }; - -export default BooleanField; diff --git a/src/components/atoms/forms/field.stories.tsx b/src/components/atoms/forms/field.stories.tsx index 00a183d..27fd3be 100644 --- a/src/components/atoms/forms/field.stories.tsx +++ b/src/components/atoms/forms/field.stories.tsx @@ -1,6 +1,6 @@ import { ComponentMeta, ComponentStory } from '@storybook/react'; import { useState } from 'react'; -import Field from './field'; +import { Field } from './field'; /** * Field - Storybook Meta diff --git a/src/components/atoms/forms/field.test.tsx b/src/components/atoms/forms/field.test.tsx index 26ad764..492aa48 100644 --- a/src/components/atoms/forms/field.test.tsx +++ b/src/components/atoms/forms/field.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '../../../../tests/utils'; -import Field from './field'; +import { Field } from './field'; describe('Field', () => { it('renders a text input', () => { diff --git a/src/components/atoms/forms/field.tsx b/src/components/atoms/forms/field.tsx index 377e1b0..a4553e3 100644 --- a/src/components/atoms/forms/field.tsx +++ b/src/components/atoms/forms/field.tsx @@ -72,12 +72,7 @@ export type FieldProps = { value: string; }; -/** - * Field component. - * - * Render either an input or a textarea. - */ -const Field: ForwardRefRenderFunction<HTMLInputElement, FieldProps> = ( +const FieldWithRef: ForwardRefRenderFunction<HTMLInputElement, FieldProps> = ( { className = '', setValue, type, ...props }, ref ) => { @@ -93,19 +88,24 @@ const Field: ForwardRefRenderFunction<HTMLInputElement, FieldProps> = ( return type === 'textarea' ? ( <textarea - onChange={updateValue} - className={`${styles.field} ${styles['field--textarea']} ${className}`} {...props} + className={`${styles.field} ${styles['field--textarea']} ${className}`} + onChange={updateValue} /> ) : ( <input + {...props} className={`${styles.field} ${className}`} onChange={updateValue} ref={ref} type={type} - {...props} /> ); }; -export default forwardRef(Field); +/** + * Field component. + * + * Render either an input or a textarea. + */ +export const Field = forwardRef(FieldWithRef); diff --git a/src/components/atoms/forms/form.test.tsx b/src/components/atoms/forms/form.test.tsx index 3a055ed..b040665 100644 --- a/src/components/atoms/forms/form.test.tsx +++ b/src/components/atoms/forms/form.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '../../../../tests/utils'; -import Form from './form'; +import { Form } from './form'; describe('Form', () => { it('renders a form', () => { diff --git a/src/components/atoms/forms/form.tsx b/src/components/atoms/forms/form.tsx index 3307153..85ff8fd 100644 --- a/src/components/atoms/forms/form.tsx +++ b/src/components/atoms/forms/form.tsx @@ -1,24 +1,22 @@ -import { Children, FC, FormEvent, Fragment, ReactNode } from 'react'; +import { + Children, + FC, + FormEvent, + FormHTMLAttributes, + 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; +export type FormProps = Omit< + FormHTMLAttributes<HTMLFormElement>, + 'onSubmit' +> & { /** * The form body. */ children: ReactNode; /** - * Set additional classnames to the form wrapper. - */ - className?: string; - /** * Wrap each items with a div. Default: true. */ grouped?: boolean; @@ -37,7 +35,7 @@ export type FormProps = { * * Render children wrapped in a form element. */ -const Form: FC<FormProps> = ({ +export const Form: FC<FormProps> = ({ children, grouped = true, itemsClassName = '', @@ -75,10 +73,8 @@ const Form: FC<FormProps> = ({ }; return ( - <form onSubmit={handleSubmit} {...props}> + <form {...props} onSubmit={handleSubmit}> {getFormItems()} </form> ); }; - -export default Form; diff --git a/src/components/atoms/forms/index.ts b/src/components/atoms/forms/index.ts new file mode 100644 index 0000000..0af138f --- /dev/null +++ b/src/components/atoms/forms/index.ts @@ -0,0 +1,5 @@ +export * from './boolean-field'; +export * from './field'; +export * from './form'; +export * from './label'; +export * from './select'; diff --git a/src/components/atoms/forms/label.stories.tsx b/src/components/atoms/forms/label.stories.tsx index f66aa13..3adc92a 100644 --- a/src/components/atoms/forms/label.stories.tsx +++ b/src/components/atoms/forms/label.stories.tsx @@ -1,5 +1,5 @@ import { ComponentMeta, ComponentStory } from '@storybook/react'; -import LabelComponent from './label'; +import { Label as LabelComponent } from './label'; /** * Label - Storybook Meta diff --git a/src/components/atoms/forms/label.test.tsx b/src/components/atoms/forms/label.test.tsx index 761d3b4..091737b 100644 --- a/src/components/atoms/forms/label.test.tsx +++ b/src/components/atoms/forms/label.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '../../../../tests/utils'; -import Label from './label'; +import { Label } from './label'; describe('Label', () => { it('renders a field label', () => { diff --git a/src/components/atoms/forms/label.tsx b/src/components/atoms/forms/label.tsx index 2ec614f..6764579 100644 --- a/src/components/atoms/forms/label.tsx +++ b/src/components/atoms/forms/label.tsx @@ -1,24 +1,12 @@ -import { FC, ReactNode } from 'react'; +import { FC, LabelHTMLAttributes, ReactNode } from 'react'; import styles from './label.module.scss'; -export type LabelProps = { - /** - * An accessible name for the label. - */ - 'aria-label'?: string; +export type LabelProps = LabelHTMLAttributes<HTMLLabelElement> & { /** * The label body. */ children: ReactNode; /** - * Add classnames to the label. - */ - className?: string; - /** - * The field id. - */ - htmlFor?: string; - /** * Is the field required? Default: false. */ required?: boolean; @@ -33,7 +21,7 @@ export type LabelProps = { * * Render a HTML label element. */ -const Label: FC<LabelProps> = ({ +export const Label: FC<LabelProps> = ({ children, className = '', required = false, @@ -41,13 +29,12 @@ const Label: FC<LabelProps> = ({ ...props }) => { const sizeClass = styles[`label--${size}`]; + const labelClass = `${styles.label} ${sizeClass} ${className}`; return ( - <label className={`${styles.label} ${sizeClass} ${className}`} {...props}> + <label {...props} className={labelClass}> {children} {required && <span className={styles.required}> *</span>} </label> ); }; - -export default Label; diff --git a/src/components/atoms/forms/select.stories.tsx b/src/components/atoms/forms/select.stories.tsx index 7127597..b98ebed 100644 --- a/src/components/atoms/forms/select.stories.tsx +++ b/src/components/atoms/forms/select.stories.tsx @@ -1,6 +1,6 @@ import { ComponentMeta, ComponentStory } from '@storybook/react'; import { useState } from 'react'; -import SelectComponent from './select'; +import { Select as SelectComponent } from './select'; const selectOptions = [ { id: 'option1', name: 'Option 1', value: 'option1' }, diff --git a/src/components/atoms/forms/select.test.tsx b/src/components/atoms/forms/select.test.tsx index ca9f6d3..53d9b1f 100644 --- a/src/components/atoms/forms/select.test.tsx +++ b/src/components/atoms/forms/select.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '../../../../tests/utils'; -import Select from './select'; +import { Select } from './select'; const selectOptions = [ { id: 'option1', name: 'Option 1', value: 'option1' }, diff --git a/src/components/atoms/forms/select.tsx b/src/components/atoms/forms/select.tsx index dbe9b37..14f85dc 100644 --- a/src/components/atoms/forms/select.tsx +++ b/src/components/atoms/forms/select.tsx @@ -1,4 +1,4 @@ -import { ChangeEvent, FC, SetStateAction } from 'react'; +import { ChangeEvent, FC, SelectHTMLAttributes, SetStateAction } from 'react'; import styles from './forms.module.scss'; export type SelectOptions = { @@ -16,19 +16,7 @@ export type SelectOptions = { value: string; }; -export type SelectProps = { - /** - * One or more ids that refers to the select field name. - */ - 'aria-labelledby'?: string; - /** - * Add classnames to the select field. - */ - className?: string; - /** - * Field state. Either enabled (false) or disabled (true). - */ - disabled?: boolean; +export type SelectProps = SelectHTMLAttributes<HTMLSelectElement> & { /** * Field id attribute. */ @@ -42,10 +30,6 @@ export type SelectProps = { */ options: SelectOptions[]; /** - * True if the field is required. Default: false. - */ - required?: boolean; - /** * Callback function to set field value. */ setValue: (value: SetStateAction<string>) => void; @@ -60,12 +44,14 @@ export type SelectProps = { * * Render a HTML select element. */ -const Select: FC<SelectProps> = ({ +export const Select: FC<SelectProps> = ({ className = '', options, setValue, ...props }) => { + const selectClass = `${styles.field} ${styles['field--select']} ${className}`; + /** * Update select value when an option is selected. * @param e - The option change event. @@ -86,14 +72,8 @@ const Select: FC<SelectProps> = ({ )); return ( - <select - className={`${styles.field} ${styles['field--select']} ${className}`} - onChange={updateValue} - {...props} - > + <select {...props} className={selectClass} onChange={updateValue}> {getOptions()} </select> ); }; - -export default Select; |
