Skip to content

Commit f03cffe

Browse files
Remove support for uppercase heading levels
1 parent 51dbc7d commit f03cffe

File tree

3 files changed

+44
-71
lines changed

3 files changed

+44
-71
lines changed

src/components/content-presentation/tabs/__tests__/Tabs.test.tsx

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React from 'react';
22
import { fireEvent, render } from '@testing-library/react';
3-
import Tabs from '../Tabs';
4-
import { HeadingLevelType } from '@components/utils/HeadingLevel';
3+
import Tabs, { TabTitleProps } from '../Tabs';
54

65
describe('The tabs component', () => {
76
it('Matches the snapshot', () => {
@@ -71,25 +70,19 @@ describe('The tabs component', () => {
7170
});
7271

7372
describe('The tabs title', () => {
74-
it.each`
75-
headingLevel
76-
${undefined}
77-
${'H1'}
78-
${'H2'}
79-
${'H3'}
80-
${'H4'}
81-
`(
82-
'Renders the chosen heading level $headingLevel if specified',
83-
({ headingLevel }: { headingLevel: HeadingLevelType }) => {
84-
const { container } = render(
85-
<Tabs.Title headingLevel={headingLevel}>Test title</Tabs.Title>,
86-
);
87-
88-
const title = container.querySelector('.nhsuk-tabs__title');
89-
90-
expect(title?.nodeName).toEqual(headingLevel ?? 'H2');
91-
},
92-
);
73+
it.each<TabTitleProps | undefined>([
74+
undefined,
75+
{ headingLevel: 'h1' },
76+
{ headingLevel: 'h2' },
77+
{ headingLevel: 'h3' },
78+
{ headingLevel: 'h4' },
79+
])('Renders the chosen heading level $headingLevel if specified', (props) => {
80+
const { container } = render(<Tabs.Title {...props}>Test title</Tabs.Title>);
81+
82+
const title = container.querySelector('.nhsuk-tabs__title');
83+
84+
expect(title).toHaveProperty('tagName', props?.headingLevel?.toUpperCase() ?? 'H2');
85+
});
9386
});
9487

9588
describe('The tab list', () => {
Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,25 @@
1-
import React, { HTMLAttributes, FC } from 'react';
1+
import React, { ElementType, HTMLAttributes, forwardRef } from 'react';
22

33
export interface HeadingLevelProps extends HTMLAttributes<HTMLHeadingElement> {
4-
headingLevel?: HeadingLevelType;
4+
headingLevel?: Extract<ElementType, 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'>;
55
}
66

7-
export type HeadingLevelType =
8-
| 'h1'
9-
| 'h2'
10-
| 'h3'
11-
| 'h4'
12-
| 'h5'
13-
| 'h6'
14-
| 'H1'
15-
| 'H2'
16-
| 'H3'
17-
| 'H4'
18-
| 'H5'
19-
| 'H6';
7+
const HeadingLevel = forwardRef<HTMLHeadingElement, HeadingLevelProps>((props, ref) => {
8+
const { headingLevel = 'h3', children, ...rest } = props;
9+
let Element = headingLevel;
2010

21-
const HeadingLevel: FC<HeadingLevelProps> = ({ headingLevel = 'h3', children, ...rest }) => {
22-
switch (headingLevel.toLowerCase()) {
23-
case 'h1':
24-
return <h1 {...rest}>{children}</h1>;
25-
case 'h2':
26-
return <h2 {...rest}>{children}</h2>;
27-
case 'h3':
28-
return <h3 {...rest}>{children}</h3>;
29-
case 'h4':
30-
return <h4 {...rest}>{children}</h4>;
31-
case 'h5':
32-
return <h5 {...rest}>{children}</h5>;
33-
case 'h6':
34-
return <h6 {...rest}>{children}</h6>;
35-
default:
36-
console.error(`HeadingLevel: Invalid headingLevel prop: ${headingLevel}`);
37-
return <h3 {...rest}>{children}</h3>;
11+
if (!['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(Element.toLowerCase())) {
12+
console.error(`HeadingLevel: Invalid headingLevel prop: ${Element}`);
13+
Element = 'h3';
3814
}
39-
};
15+
16+
return (
17+
<Element ref={ref} {...rest}>
18+
{children}
19+
</Element>
20+
);
21+
});
22+
23+
HeadingLevel.displayName = 'HeadingLevel';
4024

4125
export default HeadingLevel;

src/components/utils/__tests__/HeadingLevel.test.tsx

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
import React from 'react';
22
import { render } from '@testing-library/react';
3-
import HeadingLevel, { HeadingLevelType } from '../HeadingLevel';
3+
import HeadingLevel, { HeadingLevelProps } from '../HeadingLevel';
44

55
describe('HeadingLevel', () => {
6-
it.each<HeadingLevelType>([
7-
'h1',
8-
'H1',
9-
'h2',
10-
'H2',
11-
'h3',
12-
'H3',
13-
'h4',
14-
'H4',
15-
'h5',
16-
'H5',
17-
'h6',
18-
'H6',
19-
])('renders the correct elements - %s', (headingLevel: HeadingLevelType) => {
20-
const { container } = render(<HeadingLevel headingLevel={headingLevel} />);
6+
it.each<HeadingLevelProps>([
7+
{ headingLevel: 'h1' },
8+
{ headingLevel: 'h2' },
9+
{ headingLevel: 'h3' },
10+
{ headingLevel: 'h4' },
11+
{ headingLevel: 'h5' },
12+
{ headingLevel: 'h6' },
13+
])('renders the correct elements - %s', (props) => {
14+
const { container } = render(<HeadingLevel {...props} />);
2115

22-
expect(container.querySelector(String(headingLevel).toLowerCase())).toBeTruthy();
16+
const headingEl = container.querySelector(props.headingLevel!);
17+
18+
expect(headingEl).toHaveProperty('tagName', props?.headingLevel?.toUpperCase());
2319
});
2420

2521
it('console.warn when headingLevel is invalid', () => {

0 commit comments

Comments
 (0)