diff --git a/.changeset/cuddly-taxis-behave.md b/.changeset/cuddly-taxis-behave.md new file mode 100644 index 0000000000..babeb66c72 --- /dev/null +++ b/.changeset/cuddly-taxis-behave.md @@ -0,0 +1,5 @@ +--- +'@sumup/circuit-ui': major +--- + +Made the `as` prop required in the `Headline` and `SubHeadline` components. Intentionally setting the heading level ensures a consistent and accessible page structure. diff --git a/packages/circuit-ui/components/Headline/Headline.docs.mdx b/packages/circuit-ui/components/Headline/Headline.docs.mdx index b227d21fa2..b6c549c78a 100644 --- a/packages/circuit-ui/components/Headline/Headline.docs.mdx +++ b/packages/circuit-ui/components/Headline/Headline.docs.mdx @@ -14,6 +14,16 @@ Headlines are used for titling major sections of the interface. They help better - **Do** position the heading above the content - **Do** use the `four` size for titling cards and `three` for pages +## Content guidelines + +Nest headings by their rank (or level). The most important heading has rank 1 (`h1`), the least important heading rank 6 (`h6`). Headings with an equal or higher rank start a new section, headings with a lower rank start new subsections that are part of the higher-ranked section. + +Skipping heading ranks can be confusing and should be avoided where possible: Ensure that an `h2` is not followed directly by an `h4`, for example. It is ok to skip ranks when closing subsections, for instance, an `h2` beginning a new section can follow an `h4` as it closes the previous section. + +[Learn more about a proper page structure](https://www.w3.org/WAI/tutorials/page-structure/headings/). + +## Component variations + ### Sizes diff --git a/packages/circuit-ui/components/Headline/Headline.spec.tsx b/packages/circuit-ui/components/Headline/Headline.spec.tsx index 7675aeacf3..a8b797ff62 100644 --- a/packages/circuit-ui/components/Headline/Headline.spec.tsx +++ b/packages/circuit-ui/components/Headline/Headline.spec.tsx @@ -32,7 +32,7 @@ describe('Headline', () => { const sizes = ['one', 'two', 'three', 'four'] as const; it.each(sizes)(`should render with size %s`, (size) => { const headline = create( - {`${size} headline`}, + {`${size} headline`}, ); expect(headline).toMatchSnapshot(); }); @@ -41,7 +41,7 @@ describe('Headline', () => { * Accessibility tests. */ it('should meet accessibility guidelines', async () => { - const wrapper = renderToHtml(Headline); + const wrapper = renderToHtml(Headline); const actual = await axe(wrapper); expect(actual).toHaveNoViolations(); }); diff --git a/packages/circuit-ui/components/Headline/Headline.tsx b/packages/circuit-ui/components/Headline/Headline.tsx index 5cd9e32f66..f3c1cd07fb 100644 --- a/packages/circuit-ui/components/Headline/Headline.tsx +++ b/packages/circuit-ui/components/Headline/Headline.tsx @@ -28,9 +28,11 @@ export interface HeadlineProps */ size?: Size; /** - * The HTML headline element to render. + * The HTML heading element to render. Headings should be nested sequentially + * without skipping any levels. Learn more at + * https://www.w3.org/WAI/tutorials/page-structure/headings/. */ - as?: string; + as: string; } const baseStyles = ({ theme }: StyleProps) => css` diff --git a/packages/circuit-ui/components/SubHeadline/SubHeadline.docs.mdx b/packages/circuit-ui/components/SubHeadline/SubHeadline.docs.mdx index 46594702e2..5311f5b004 100644 --- a/packages/circuit-ui/components/SubHeadline/SubHeadline.docs.mdx +++ b/packages/circuit-ui/components/SubHeadline/SubHeadline.docs.mdx @@ -4,13 +4,20 @@ import { Status, Props, Story } from '../../../../.storybook/components'; -Subheadings help users break through larger related contents in the same section. -They are usually used to separate sections within a card. +Subheadlines help to break up larger related chunks of content in the same section. They are usually used to separate sections within a card. ## Usage guidelines -- **Do** use subheadings to break complex and longer contents in a page or card -- **Do not** use a subheading without a heading title for the same section +- **Do** use subheadlines to break complex and longer chunks of content in a page or card +- **Do not** use a subheadline without a heading title for the same section + +## Content guidelines + +Nest headings by their rank (or level). The most important heading has rank 1 (`h1`), the least important heading rank 6 (`h6`). Headings with an equal or higher rank start a new section, headings with a lower rank start new subsections that are part of the higher-ranked section. + +Skipping heading ranks can be confusing and should be avoided where possible: Ensure that an `h2` is not followed directly by an `h4`, for example. It is ok to skip ranks when closing subsections, for instance, an `h2` beginning a new section can follow an `h4` as it closes the previous section. + +[Learn more about a proper page structure](https://www.w3.org/WAI/tutorials/page-structure/headings/). diff --git a/packages/circuit-ui/components/SubHeadline/SubHeadline.spec.tsx b/packages/circuit-ui/components/SubHeadline/SubHeadline.spec.tsx index 50fe6393f6..ebf915a464 100644 --- a/packages/circuit-ui/components/SubHeadline/SubHeadline.spec.tsx +++ b/packages/circuit-ui/components/SubHeadline/SubHeadline.spec.tsx @@ -30,7 +30,7 @@ describe('SubHeadline', () => { }); it('should render with no margin styles when passed the prop', () => { - const actual = create(); + const actual = create(); expect(actual).toMatchSnapshot(); }); @@ -38,7 +38,7 @@ describe('SubHeadline', () => { * Accessibility tests. */ it('should meet accessibility guidelines', async () => { - const wrapper = renderToHtml(Subheading); + const wrapper = renderToHtml(Subheading); const actual = await axe(wrapper); expect(actual).toHaveNoViolations(); }); diff --git a/packages/circuit-ui/components/SubHeadline/SubHeadline.tsx b/packages/circuit-ui/components/SubHeadline/SubHeadline.tsx index 3648661f9f..94f4e2c93b 100644 --- a/packages/circuit-ui/components/SubHeadline/SubHeadline.tsx +++ b/packages/circuit-ui/components/SubHeadline/SubHeadline.tsx @@ -22,9 +22,11 @@ import styled, { StyleProps } from '../../styles/styled'; export interface SubHeadlineProps extends Omit, 'size'> { /** - * The HTML subheading element to render. + * The HTML heading element to render. Headings should be nested sequentially + * without skipping any levels. Learn more at + * https://www.w3.org/WAI/tutorials/page-structure/headings/. */ - as?: string; + as: string; } const baseStyles = ({ theme }: StyleProps) => css`