diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-03-31 15:39:55 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-03-31 15:46:54 +0200 |
| commit | 8370602f37ad6aa02485d85e5b179b76c3f15701 (patch) | |
| tree | 5a92ac70db1f791aae19a67b92da356c9ed4ed5a /src | |
| parent | 351532e9906e32c862bf6810a3871993cde13ba2 (diff) | |
chore: add a Heading component
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/atoms/headings/heading.stories.tsx | 37 | ||||
| -rw-r--r-- | src/components/atoms/headings/heading.test.tsx | 46 | ||||
| -rw-r--r-- | src/components/atoms/headings/heading.tsx | 21 |
3 files changed, 104 insertions, 0 deletions
diff --git a/src/components/atoms/headings/heading.stories.tsx b/src/components/atoms/headings/heading.stories.tsx new file mode 100644 index 0000000..9958af9 --- /dev/null +++ b/src/components/atoms/headings/heading.stories.tsx @@ -0,0 +1,37 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import HeadingComponent from './heading'; + +export default { + title: 'Atoms/Headings', + component: HeadingComponent, + argTypes: { + children: { + description: 'Heading body.', + type: { + name: 'string', + required: true, + }, + }, + level: { + control: { + type: 'select', + }, + description: 'Heading level.', + options: [1, 2, 3, 4, 5, 6], + type: { + name: 'number', + required: true, + }, + }, + }, +} as ComponentMeta<typeof HeadingComponent>; + +const Template: ComponentStory<typeof HeadingComponent> = (args) => { + const { level, ...props } = args; + return <HeadingComponent level={level || 1} {...props} />; +}; + +export const Heading = Template.bind({}); +Heading.args = { + children: 'Your title', +}; diff --git a/src/components/atoms/headings/heading.test.tsx b/src/components/atoms/headings/heading.test.tsx new file mode 100644 index 0000000..b83f7cd --- /dev/null +++ b/src/components/atoms/headings/heading.test.tsx @@ -0,0 +1,46 @@ +import { render, screen } from '@test-utils'; +import Heading from './heading'; + +describe('Heading', () => { + it('renders a h1', () => { + render(<Heading level={1}>Level 1</Heading>); + expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent( + 'Level 1' + ); + }); + + it('renders a h2', () => { + render(<Heading level={2}>Level 2</Heading>); + expect(screen.getByRole('heading', { level: 2 })).toHaveTextContent( + 'Level 2' + ); + }); + + it('renders a h3', () => { + render(<Heading level={3}>Level 3</Heading>); + expect(screen.getByRole('heading', { level: 3 })).toHaveTextContent( + 'Level 3' + ); + }); + + it('renders a h4', () => { + render(<Heading level={4}>Level 4</Heading>); + expect(screen.getByRole('heading', { level: 4 })).toHaveTextContent( + 'Level 4' + ); + }); + + it('renders a h5', () => { + render(<Heading level={5}>Level 5</Heading>); + expect(screen.getByRole('heading', { level: 5 })).toHaveTextContent( + 'Level 5' + ); + }); + + it('renders a h6', () => { + render(<Heading level={6}>Level 6</Heading>); + expect(screen.getByRole('heading', { level: 6 })).toHaveTextContent( + 'Level 6' + ); + }); +}); diff --git a/src/components/atoms/headings/heading.tsx b/src/components/atoms/headings/heading.tsx new file mode 100644 index 0000000..1535140 --- /dev/null +++ b/src/components/atoms/headings/heading.tsx @@ -0,0 +1,21 @@ +import { FC } from 'react'; + +type HeadingProps = { + /** + * HTML heading level: 'h1', 'h2', 'h3', 'h4', 'h5' or 'h6'. + */ + level: 1 | 2 | 3 | 4 | 5 | 6; +}; + +/** + * Heading component. + * + * Render an HTML heading element. + */ +const Heading: FC<HeadingProps> = ({ children, level }) => { + const TitleTag = `h${level}` as keyof JSX.IntrinsicElements; + + return <TitleTag>{children}</TitleTag>; +}; + +export default Heading; |
