Skip to content

Commit f1871ab

Browse files
Allow NHS.UK frontend errors to be caught
1 parent 9e1cafd commit f1871ab

File tree

8 files changed

+72
-45
lines changed

8 files changed

+72
-45
lines changed

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,23 @@ const TabsComponent = forwardRef<HTMLDivElement, TabsProps>((props, forwardedRef
5656
const { children, className, ...rest } = props;
5757

5858
const [moduleRef] = useState(() => forwardedRef || createRef<HTMLDivElement>());
59+
const [instanceError, setInstanceError] = useState<Error>();
5960
const [instance, setInstance] = useState<TabsModule>();
6061

6162
useEffect(() => {
6263
if (!('current' in moduleRef) || !moduleRef.current || instance) {
6364
return;
6465
}
6566

66-
const { current: $root } = moduleRef;
67-
68-
import('nhsuk-frontend').then(({ Tabs }) => {
69-
setInstance(new Tabs($root));
70-
});
67+
import('nhsuk-frontend')
68+
.then(({ Tabs }) => setInstance(new Tabs(moduleRef.current)))
69+
.catch(setInstanceError);
7170
}, [moduleRef, instance]);
7271

72+
if (instanceError) {
73+
throw instanceError;
74+
}
75+
7376
return (
7477
<div
7578
className={classNames('nhsuk-tabs', className)}

src/components/form-elements/button/Button.tsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,23 @@ const ButtonComponent = forwardRef<HTMLButtonElement, ButtonProps>((props, forwa
4646
} = props;
4747

4848
const [moduleRef] = useState(() => forwardedRef || createRef<HTMLButtonElement>());
49+
const [instanceError, setInstanceError] = useState<Error>();
4950
const [instance, setInstance] = useState<ButtonModule>();
5051

5152
useEffect(() => {
5253
if (!('current' in moduleRef) || !moduleRef.current || instance) {
5354
return;
5455
}
5556

56-
const { current: $root } = moduleRef;
57-
58-
import('nhsuk-frontend').then(({ Button }) => {
59-
setInstance(new Button($root));
60-
});
57+
import('nhsuk-frontend')
58+
.then(({ Button }) => setInstance(new Button(moduleRef.current)))
59+
.catch(setInstanceError);
6160
}, [moduleRef, instance]);
6261

62+
if (instanceError) {
63+
throw instanceError;
64+
}
65+
6366
return (
6467
<Element
6568
className={classNames(
@@ -102,20 +105,23 @@ const ButtonLinkComponent = forwardRef<HTMLAnchorElement, ButtonLinkProps>(
102105
} = props;
103106

104107
const [moduleRef] = useState(() => forwardedRef || createRef<HTMLAnchorElement>());
108+
const [instanceError, setInstanceError] = useState<Error>();
105109
const [instance, setInstance] = useState<ButtonModule>();
106110

107111
useEffect(() => {
108112
if (!('current' in moduleRef) || !moduleRef.current || instance) {
109113
return;
110114
}
111115

112-
const { current: $root } = moduleRef;
113-
114-
import('nhsuk-frontend').then(({ Button }) => {
115-
setInstance(new Button($root));
116-
});
116+
import('nhsuk-frontend')
117+
.then(({ Button }) => setInstance(new Button(moduleRef.current)))
118+
.catch(setInstanceError);
117119
}, [moduleRef, instance]);
118120

121+
if (instanceError) {
122+
throw instanceError;
123+
}
124+
119125
return (
120126
<Element
121127
className={classNames(

src/components/form-elements/character-count/CharacterCount.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,23 @@ export interface CharacterCountProps
1717
export const CharacterCount = forwardRef<HTMLTextAreaElement, CharacterCountProps>(
1818
({ maxLength, maxWords, threshold, formGroupProps, ...rest }, forwardedRef) => {
1919
const [moduleRef] = useState(() => formGroupProps?.ref || createRef<HTMLDivElement>());
20+
const [instanceError, setInstanceError] = useState<Error>();
2021
const [instance, setInstance] = useState<CharacterCountModule>();
2122

2223
useEffect(() => {
2324
if (!('current' in moduleRef) || !moduleRef.current || instance) {
2425
return;
2526
}
2627

27-
const { current: $root } = moduleRef;
28-
29-
import('nhsuk-frontend').then(({ CharacterCount }) => {
30-
setInstance(new CharacterCount($root));
31-
});
28+
import('nhsuk-frontend')
29+
.then(({ CharacterCount }) => setInstance(new CharacterCount(moduleRef.current)))
30+
.catch(setInstanceError);
3231
}, [moduleRef, instance]);
3332

33+
if (instanceError) {
34+
throw instanceError;
35+
}
36+
3437
return (
3538
<FormGroup<CharacterCountProps>
3639
inputType="textarea"

src/components/form-elements/checkboxes/Checkboxes.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const CheckboxesComponent = forwardRef<HTMLDivElement, CheckboxesProps>((props,
1919
const { children, idPrefix, ...rest } = props;
2020

2121
const [moduleRef] = useState(() => forwardedRef || createRef<HTMLDivElement>());
22+
const [instanceError, setInstanceError] = useState<Error>();
2223
const [instance, setInstance] = useState<CheckboxesModule>();
2324

2425
const _boxReferences: string[] = [];
@@ -30,11 +31,9 @@ const CheckboxesComponent = forwardRef<HTMLDivElement, CheckboxesProps>((props,
3031
return;
3132
}
3233

33-
const { current: $root } = moduleRef;
34-
35-
import('nhsuk-frontend').then(({ Checkboxes }) => {
36-
setInstance(new Checkboxes($root));
37-
});
34+
import('nhsuk-frontend')
35+
.then(({ Checkboxes }) => setInstance(new Checkboxes(moduleRef.current)))
36+
.catch(setInstanceError);
3837
}, [moduleRef, instance]);
3938

4039
const getBoxId = (id: string, reference: string): string => {
@@ -66,6 +65,10 @@ const CheckboxesComponent = forwardRef<HTMLDivElement, CheckboxesProps>((props,
6665
_boxIds = {};
6766
};
6867

68+
if (instanceError) {
69+
throw instanceError;
70+
}
71+
6972
return (
7073
<FormGroup<CheckboxesProps> inputType="checkboxes" {...rest}>
7174
{/* eslint-disable-next-line @typescript-eslint/no-unused-vars */}

src/components/form-elements/error-summary/ErrorSummary.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,27 @@ export interface ErrorSummaryProps extends ComponentPropsWithoutRef<'div'> {
2020
const ErrorSummaryComponent = forwardRef<HTMLDivElement, ErrorSummaryProps>(
2121
({ children, className, disableAutoFocus, ...rest }, forwardedRef) => {
2222
const [moduleRef] = useState(() => forwardedRef || createRef<HTMLDivElement>());
23+
const [instanceError, setInstanceError] = useState<Error>();
2324
const [instance, setInstance] = useState<ErrorSummaryModule>();
2425

2526
useEffect(() => {
2627
if (!('current' in moduleRef) || !moduleRef.current || instance) {
2728
return;
2829
}
2930

30-
const { current: $root } = moduleRef;
31-
32-
import('nhsuk-frontend').then(({ ErrorSummary }) => {
33-
setInstance(new ErrorSummary($root));
34-
});
31+
import('nhsuk-frontend')
32+
.then(({ ErrorSummary }) => setInstance(new ErrorSummary(moduleRef.current)))
33+
.catch(setInstanceError);
3534
}, [moduleRef, instance]);
3635

3736
const items = Children.toArray(children);
3837
const title = items.find((child) => childIsOfComponentType(child, ErrorSummaryTitle));
3938
const bodyItems = items.filter((child) => !childIsOfComponentType(child, ErrorSummaryTitle));
4039

40+
if (instanceError) {
41+
throw instanceError;
42+
}
43+
4144
return (
4245
<div
4346
className={classNames('nhsuk-error-summary', className)}

src/components/form-elements/radios/Radios.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const RadiosComponent = forwardRef<HTMLDivElement, RadiosProps>((props, forwarde
2020
const { children, idPrefix, ...rest } = props;
2121

2222
const [moduleRef] = useState(() => forwardedRef || createRef<HTMLDivElement>());
23+
const [instanceError, setInstanceError] = useState<Error>();
2324
const [instance, setInstance] = useState<RadiosModule>();
2425
const [selectedRadio, setSelectedRadio] = useState<string>();
2526

@@ -32,11 +33,9 @@ const RadiosComponent = forwardRef<HTMLDivElement, RadiosProps>((props, forwarde
3233
return;
3334
}
3435

35-
const { current: $root } = moduleRef;
36-
37-
import('nhsuk-frontend').then(({ Radios }) => {
38-
setInstance(new Radios($root));
39-
});
36+
import('nhsuk-frontend')
37+
.then(({ Radios }) => setInstance(new Radios(moduleRef.current)))
38+
.catch(setInstanceError);
4039
}, [moduleRef, instance]);
4140

4241
const getRadioId = (id: string, reference: string): string => {
@@ -73,6 +72,10 @@ const RadiosComponent = forwardRef<HTMLDivElement, RadiosProps>((props, forwarde
7372
_radioIds = {};
7473
};
7574

75+
if (instanceError) {
76+
throw instanceError;
77+
}
78+
7679
return (
7780
<FormGroup<RadiosProps> inputType="radios" {...rest}>
7881
{/* eslint-disable-next-line @typescript-eslint/no-unused-vars */}

src/components/navigation/header/Header.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const HeaderComponent = forwardRef<HTMLElement, HeaderProps>((props, forwardedRe
4141
const [logoProps, setLogoProps] = useState(logo);
4242
const [serviceProps, setServiceProps] = useState(service);
4343
const [organisationProps, setOrganisationProps] = useState(organisation);
44+
const [instanceError, setInstanceError] = useState<Error>();
4445
const [instance, setInstance] = useState<HeaderModule>();
4546
const [menuOpen, setMenuOpen] = useState(false);
4647

@@ -90,11 +91,9 @@ const HeaderComponent = forwardRef<HTMLElement, HeaderProps>((props, forwardedRe
9091
return;
9192
}
9293

93-
const { current: $root } = moduleRef;
94-
95-
import('nhsuk-frontend').then(({ Header }) => {
96-
setInstance(new Header($root));
97-
});
94+
import('nhsuk-frontend')
95+
.then(({ Header }) => setInstance(new Header(moduleRef.current)))
96+
.catch(setInstanceError);
9897
}, [moduleRef, instance, menuOpen]);
9998

10099
const contextValue: IHeaderContext = useMemo(() => {
@@ -116,6 +115,10 @@ const HeaderComponent = forwardRef<HTMLElement, HeaderProps>((props, forwardedRe
116115
const childNavigation = items.find((child) => childIsOfComponentType(child, HeaderNavigation));
117116
const childAccount = items.find((child) => childIsOfComponentType(child, HeaderAccount));
118117

118+
if (instanceError) {
119+
throw instanceError;
120+
}
121+
119122
return (
120123
<header
121124
className={classNames(

src/components/navigation/skip-link/SkipLink.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,23 @@ export const SkipLink = forwardRef<HTMLAnchorElement, SkipLinkProps>((props, for
1010
const { children = 'Skip to main content', className, href = '#maincontent', ...rest } = props;
1111

1212
const [moduleRef] = useState(() => forwardedRef || createRef<HTMLAnchorElement>());
13+
const [instanceError, setInstanceError] = useState<Error>();
1314
const [instance, setInstance] = useState<SkipLinkModule>();
1415

1516
useEffect(() => {
1617
if (!('current' in moduleRef) || !moduleRef.current || instance) {
1718
return;
1819
}
1920

20-
const { current: $root } = moduleRef;
21-
22-
import('nhsuk-frontend').then(({ SkipLink }) => {
23-
setInstance(new SkipLink($root));
24-
});
21+
import('nhsuk-frontend')
22+
.then(({ SkipLink }) => setInstance(new SkipLink(moduleRef.current)))
23+
.catch(setInstanceError);
2524
}, [moduleRef, instance]);
2625

26+
if (instanceError) {
27+
throw instanceError;
28+
}
29+
2730
return (
2831
<a
2932
href={href}

0 commit comments

Comments
 (0)