diff options
Diffstat (limited to 'src/components')
| -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; | 
