diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-10-05 18:58:30 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-11 18:14:41 +0100 |
| commit | fb860884857da73ee5b5e897745301cdf1d770a2 (patch) | |
| tree | 3aaf3c192b3375a7e1bf2dbf9daa866be357a2f5 /src/components/molecules/forms | |
| parent | e97325a2c174a87c29593d1b42b9a1cc1eaf11af (diff) | |
refactor(components): make form components compliant with Eslint rules
Diffstat (limited to 'src/components/molecules/forms')
| -rw-r--r-- | src/components/molecules/forms/labelled-field/labelled-field.stories.tsx | 8 | ||||
| -rw-r--r-- | src/components/molecules/forms/labelled-field/labelled-field.test.tsx | 6 | ||||
| -rw-r--r-- | src/components/molecules/forms/labelled-field/labelled-field.tsx | 43 | ||||
| -rw-r--r-- | src/components/molecules/forms/radio-group/radio-group.fixture.ts (renamed from src/components/molecules/forms/radio-group/radio-group.fixture.tsx) | 4 | ||||
| -rw-r--r-- | src/components/molecules/forms/radio-group/radio-group.stories.tsx | 4 | ||||
| -rw-r--r-- | src/components/molecules/forms/radio-group/radio-group.test.tsx | 8 | ||||
| -rw-r--r-- | src/components/molecules/forms/radio-group/radio-group.tsx | 9 | ||||
| -rw-r--r-- | src/components/molecules/forms/switch/switch.stories.tsx | 6 | ||||
| -rw-r--r-- | src/components/molecules/forms/switch/switch.test.tsx | 12 | ||||
| -rw-r--r-- | src/components/molecules/forms/switch/switch.tsx | 55 |
10 files changed, 94 insertions, 61 deletions
diff --git a/src/components/molecules/forms/labelled-field/labelled-field.stories.tsx b/src/components/molecules/forms/labelled-field/labelled-field.stories.tsx index 1f29830..1d1af70 100644 --- a/src/components/molecules/forms/labelled-field/labelled-field.stories.tsx +++ b/src/components/molecules/forms/labelled-field/labelled-field.stories.tsx @@ -1,5 +1,5 @@ -import { ComponentMeta, ComponentStory } from '@storybook/react'; -import { ChangeEvent, useState } from 'react'; +import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import { type ChangeEvent, useState, useCallback } from 'react'; import { Input, Label } from '../../../atoms'; import { LabelledField } from './labelled-field'; @@ -77,9 +77,9 @@ export default { const Template: ComponentStory<typeof LabelledField> = ({ ...args }) => { const id = 'sunt'; const [value, setValue] = useState<string>(''); - const updateValue = (e: ChangeEvent<HTMLInputElement>) => { + const updateValue = useCallback((e: ChangeEvent<HTMLInputElement>) => { setValue(e.target.value); - }; + }, []); return ( <LabelledField diff --git a/src/components/molecules/forms/labelled-field/labelled-field.test.tsx b/src/components/molecules/forms/labelled-field/labelled-field.test.tsx index 8bc7c39..0a91ccd 100644 --- a/src/components/molecules/forms/labelled-field/labelled-field.test.tsx +++ b/src/components/molecules/forms/labelled-field/labelled-field.test.tsx @@ -1,5 +1,5 @@ import { describe, expect, it } from '@jest/globals'; -import { render, screen } from '../../../../../tests/utils'; +import { render, screen as rtlScreen } from '@testing-library/react'; import { Input, Label } from '../../../atoms'; import { LabelledField } from './labelled-field'; @@ -27,7 +27,7 @@ describe('LabelledField', () => { label={<Label htmlFor={id}>{label}</Label>} /> ); - expect(screen.getByLabelText(label)).toBeInTheDocument(); - expect(screen.getByRole('textbox')).toHaveValue(value); + expect(rtlScreen.getByLabelText(label)).toBeInTheDocument(); + expect(rtlScreen.getByRole('textbox')).toHaveValue(value); }); }); diff --git a/src/components/molecules/forms/labelled-field/labelled-field.tsx b/src/components/molecules/forms/labelled-field/labelled-field.tsx index af492b3..ea0bd67 100644 --- a/src/components/molecules/forms/labelled-field/labelled-field.tsx +++ b/src/components/molecules/forms/labelled-field/labelled-field.tsx @@ -1,5 +1,10 @@ -import { FC, HTMLAttributes, ReactElement } from 'react'; import { + forwardRef, + type HTMLAttributes, + type ReactElement, + type ForwardRefRenderFunction, +} from 'react'; +import type { CheckboxProps, InputProps, LabelProps, @@ -37,27 +42,35 @@ export type LabelledFieldProps = Omit< label: ReactElement<LabelProps>; }; -/** - * LabelledField component - * - * Render a field tied to a label. - */ -export const LabelledField: FC<LabelledFieldProps> = ({ - className = '', - field, - isInline = false, - isReversedOrder = false, - label, - ...props -}) => { +const LabelledFieldWithRef: ForwardRefRenderFunction< + HTMLDivElement, + LabelledFieldProps +> = ( + { + className = '', + field, + isInline = false, + isReversedOrder = false, + label, + ...props + }, + ref +) => { const layoutClass = isInline ? 'wrapper--inline' : 'wrapper--stack'; const orderClass = isReversedOrder ? 'wrapper--reverse' : ''; const wrapperClass = `${styles.wrapper} ${styles[layoutClass]} ${styles[orderClass]} ${className}`; return ( - <div {...props} className={wrapperClass}> + <div {...props} className={wrapperClass} ref={ref}> {label} {field} </div> ); }; + +/** + * LabelledField component + * + * Render a field tied to a label. + */ +export const LabelledField = forwardRef(LabelledFieldWithRef); diff --git a/src/components/molecules/forms/radio-group/radio-group.fixture.tsx b/src/components/molecules/forms/radio-group/radio-group.fixture.ts index f1cbc05..618cde7 100644 --- a/src/components/molecules/forms/radio-group/radio-group.fixture.tsx +++ b/src/components/molecules/forms/radio-group/radio-group.fixture.ts @@ -1,6 +1,6 @@ -import { RadioGroupItem } from './radio-group'; +import type { RadioGroupItem } from './radio-group'; -export const getOptions = (name: string = 'group1') => { +export const getOptions = (name = 'group1') => { const value1 = 'option1'; const value2 = 'option2'; const value3 = 'option3'; diff --git a/src/components/molecules/forms/radio-group/radio-group.stories.tsx b/src/components/molecules/forms/radio-group/radio-group.stories.tsx index 8e77c6e..4b92c34 100644 --- a/src/components/molecules/forms/radio-group/radio-group.stories.tsx +++ b/src/components/molecules/forms/radio-group/radio-group.stories.tsx @@ -1,8 +1,8 @@ -import { ComponentMeta, ComponentStory } from '@storybook/react'; +import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import { type ChangeEventHandler, useCallback, useState } from 'react'; import { Legend } from '../../../atoms'; import { RadioGroup as RadioGroupComponent } from './radio-group'; import { getOptions, initialChoice } from './radio-group.fixture'; -import { ChangeEventHandler, useCallback, useState } from 'react'; /** * RadioGroup - Storybook Meta diff --git a/src/components/molecules/forms/radio-group/radio-group.test.tsx b/src/components/molecules/forms/radio-group/radio-group.test.tsx index ba68925..61f4af6 100644 --- a/src/components/molecules/forms/radio-group/radio-group.test.tsx +++ b/src/components/molecules/forms/radio-group/radio-group.test.tsx @@ -1,5 +1,5 @@ import { describe, expect, it } from '@jest/globals'; -import { render, screen } from '../../../../../tests/utils'; +import { render, screen as rtlScreen } from '@testing-library/react'; import { Legend } from '../../../atoms'; import { RadioGroup } from './radio-group'; import { getOptions, initialChoice } from './radio-group.fixture'; @@ -23,7 +23,7 @@ describe('RadioGroup', () => { ); expect( - screen.getByRole('radiogroup', { name: legend }) + rtlScreen.getByRole('radiogroup', { name: legend }) ).toBeInTheDocument(); }); @@ -39,7 +39,7 @@ describe('RadioGroup', () => { /> ); - expect(screen.getAllByRole('radio')).toHaveLength(options.length); + expect(rtlScreen.getAllByRole('radio')).toHaveLength(options.length); }); it('can render an inlined radio group', () => { @@ -55,6 +55,6 @@ describe('RadioGroup', () => { /> ); - expect(screen.getByRole('radiogroup')).toHaveClass('group--inline'); + expect(rtlScreen.getByRole('radiogroup')).toHaveClass('group--inline'); }); }); diff --git a/src/components/molecules/forms/radio-group/radio-group.tsx b/src/components/molecules/forms/radio-group/radio-group.tsx index 0ca4dac..29b719c 100644 --- a/src/components/molecules/forms/radio-group/radio-group.tsx +++ b/src/components/molecules/forms/radio-group/radio-group.tsx @@ -1,11 +1,11 @@ -import { ForwardRefRenderFunction, forwardRef } from 'react'; +import { type ForwardRefRenderFunction, forwardRef } from 'react'; import { Fieldset, - FieldsetProps, + type FieldsetProps, Label, - LabelProps, + type LabelProps, Radio, - RadioProps, + type RadioProps, } from '../../../atoms'; import { LabelledField } from '../labelled-field'; import styles from './radio-group.module.scss'; @@ -78,6 +78,7 @@ const RadioGroupWithRef: ForwardRefRenderFunction< className={groupClass} isInline={isInline} ref={ref} + // eslint-disable-next-line react/jsx-no-literals -- Role allowed role="radiogroup" > {options.map((option) => ( diff --git a/src/components/molecules/forms/switch/switch.stories.tsx b/src/components/molecules/forms/switch/switch.stories.tsx index eb169ad..a88e6ab 100644 --- a/src/components/molecules/forms/switch/switch.stories.tsx +++ b/src/components/molecules/forms/switch/switch.stories.tsx @@ -1,7 +1,7 @@ -import { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Switch as SwitchComponent, SwitchOption } from './switch'; -import { ChangeEventHandler, useCallback, useState } from 'react'; +import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import { type ChangeEventHandler, useCallback, useState } from 'react'; import { Legend } from '../../../atoms'; +import { Switch as SwitchComponent, type SwitchOption } from './switch'; /** * Switch - Storybook Meta diff --git a/src/components/molecules/forms/switch/switch.test.tsx b/src/components/molecules/forms/switch/switch.test.tsx index 3d091cb..e2e27be 100644 --- a/src/components/molecules/forms/switch/switch.test.tsx +++ b/src/components/molecules/forms/switch/switch.test.tsx @@ -1,7 +1,7 @@ import { describe, expect, it } from '@jest/globals'; -import { render, screen } from '../../../../../tests/utils'; +import { render, screen as rtlScreen } from '@testing-library/react'; import { Legend } from '../../../atoms'; -import { Switch, SwitchOption } from './switch'; +import { Switch, type SwitchOption } from './switch'; const doNothing = () => { /* Do nothing. */ @@ -27,9 +27,9 @@ describe('Switch', () => { ); expect( - screen.getByRole('radiogroup', { name: legend }) + rtlScreen.getByRole('radiogroup', { name: legend }) ).toBeInTheDocument(); - expect(screen.getAllByRole('radio')).toHaveLength(items.length); + expect(rtlScreen.getAllByRole('radio')).toHaveLength(items.length); }); it('can render a disabled switch', () => { @@ -43,8 +43,8 @@ describe('Switch', () => { /> ); - const radios = screen.getAllByRole<HTMLInputElement>('radio'); + const radios = rtlScreen.getAllByRole<HTMLInputElement>('radio'); expect(radios.every((radio) => radio.disabled)).toBe(true); - expect(screen.getByRole('radiogroup')).toBeDisabled(); + expect(rtlScreen.getByRole('radiogroup')).toBeDisabled(); }); }); diff --git a/src/components/molecules/forms/switch/switch.tsx b/src/components/molecules/forms/switch/switch.tsx index d340a0c..df2ba0c 100644 --- a/src/components/molecules/forms/switch/switch.tsx +++ b/src/components/molecules/forms/switch/switch.tsx @@ -1,14 +1,21 @@ -import type { FC, ChangeEventHandler, ReactNode, ReactElement } from 'react'; +import { + type FC, + type ChangeEventHandler, + type ReactNode, + type ReactElement, + forwardRef, + type ForwardRefRenderFunction, +} from 'react'; import { Fieldset, type FieldsetProps, - LabelProps, - RadioProps, + type LabelProps, + type RadioProps, Label, Radio, } from '../../../atoms'; +import type { TooltipProps } from '../../tooltip'; import styles from './switch.module.scss'; -import { TooltipProps } from '../../tooltip'; type SwitchItemProps = Omit<LabelProps, 'children' | 'htmlFor' | 'isRequired'> & Pick<RadioProps, 'isDisabled' | 'name'> & { @@ -94,24 +101,31 @@ export type SwitchProps = Omit<FieldsetProps, 'children'> & { value: SwitchOption['value']; }; -/** - * Switch component. - */ -export const Switch: FC<SwitchProps> = ({ - className = '', - isDisabled = false, - items, - name, - onSwitch, - tooltip, - value, - ...props -}) => { +const SwitchWithRef: ForwardRefRenderFunction< + HTMLFieldSetElement, + SwitchProps +> = ( + { + className = '', + isDisabled = false, + items, + name, + onSwitch, + tooltip, + value, + ...props + }, + ref +) => { + const fieldsetClass = `${styles.fieldset} ${className}`; + return ( <Fieldset {...props} - className={`${styles.fieldset} ${className}`} + className={fieldsetClass} isDisabled={isDisabled} + ref={ref} + // eslint-disable-next-line react/jsx-no-literals -- Role allowed role="radiogroup" > {tooltip} @@ -130,3 +144,8 @@ export const Switch: FC<SwitchProps> = ({ </Fieldset> ); }; + +/** + * Switch component. + */ +export const Switch = forwardRef(SwitchWithRef); |
