Skip to content

Commit 4bfdc2b

Browse files
Prevent duplicate initialisation
1 parent 0921239 commit 4bfdc2b

File tree

4 files changed

+62
-18
lines changed

4 files changed

+62
-18
lines changed

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
'use client';
22
import classNames from 'classnames';
3-
import React, { FC, HTMLAttributes, useEffect } from 'react';
3+
import React, { FC, HTMLAttributes, useEffect, useRef, useState } from 'react';
44
import HeadingLevel, { HeadingLevelType } from '@components/utils/HeadingLevel';
55
// @ts-expect-error -- No types available
6-
import TabsJs from 'nhsuk-frontend/packages/components/tabs/tabs';
6+
import initTabs from 'nhsuk-frontend/packages/components/tabs/tabs';
77

88
type TabsProps = HTMLAttributes<HTMLDivElement>;
99

@@ -55,12 +55,25 @@ interface Tabs extends FC<TabsProps> {
5555
}
5656

5757
const Tabs: Tabs = ({ className, children, ...rest }) => {
58+
const moduleRef = useRef<HTMLDivElement>(null);
59+
const [isInitialised, setIsInitialised] = useState<boolean>(false);
60+
5861
useEffect(() => {
59-
TabsJs();
60-
}, []);
62+
if (isInitialised || !moduleRef.current?.parentElement) {
63+
return;
64+
}
65+
66+
initTabs({ scope: moduleRef.current.parentElement });
67+
setIsInitialised(true);
68+
}, [isInitialised, moduleRef]);
6169

6270
return (
63-
<div className={classNames('nhsuk-tabs', className)} data-module="nhsuk-tabs" {...rest}>
71+
<div
72+
className={classNames('nhsuk-tabs', className)}
73+
data-module="nhsuk-tabs"
74+
ref={moduleRef}
75+
{...rest}
76+
>
6477
{children}
6578
</div>
6679
);

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
2-
import React, { FC, useEffect } from 'react';
2+
import React, { FC, useEffect, useRef, useState } from 'react';
33
// @ts-expect-error -- No types available
4-
import CharacterCountJs from 'nhsuk-frontend/packages/components/character-count/character-count';
4+
import initCharacterCounts from 'nhsuk-frontend/packages/components/character-count/character-count';
55
import { HTMLAttributesWithData } from '@util/types/NHSUKTypes';
66

77
export enum CharacterCountType {
@@ -25,9 +25,17 @@ const CharacterCount: FC<CharacterCountProps> = ({
2525
thresholdPercent,
2626
...rest
2727
}) => {
28+
const moduleRef = useRef<HTMLDivElement>(null);
29+
const [isInitialised, setIsInitialised] = useState<boolean>(false);
30+
2831
useEffect(() => {
29-
CharacterCountJs();
30-
}, []);
32+
if (isInitialised || !moduleRef.current?.parentElement) {
33+
return;
34+
}
35+
36+
initCharacterCounts({ scope: moduleRef.current.parentElement });
37+
setIsInitialised(true);
38+
}, [isInitialised, moduleRef]);
3139

3240
const characterCountProps: HTMLAttributesWithData<HTMLDivElement> =
3341
countType === CharacterCountType.Characters
@@ -42,6 +50,7 @@ const CharacterCount: FC<CharacterCountProps> = ({
4250
<div
4351
className="nhsuk-character-count"
4452
data-module="nhsuk-character-count"
53+
ref={moduleRef}
4554
{...characterCountProps}
4655
>
4756
<div className="nhsuk-form-group">{children}</div>

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import React, { HTMLProps, useEffect } from 'react';
3+
import React, { HTMLProps, useEffect, useRef, useState } from 'react';
44
import classNames from 'classnames';
55
import { FormElementProps } from '@util/types/FormTypes';
66
import SingleInputFormGroup from '@components/utils/SingleInputFormGroup';
@@ -9,20 +9,28 @@ import Box from './components/Box';
99
import Divider from './components/Divider';
1010
import { generateRandomName } from '@util/RandomID';
1111
// @ts-expect-error -- No types available
12-
import CheckboxesJs from 'nhsuk-frontend/packages/components/checkboxes/checkboxes';
12+
import initCheckboxes from 'nhsuk-frontend/packages/components/checkboxes/checkboxes';
1313

1414
interface CheckboxesProps extends HTMLProps<HTMLDivElement>, FormElementProps {
1515
idPrefix?: string;
1616
}
1717

1818
const Checkboxes = ({ children, idPrefix, ...rest }: CheckboxesProps) => {
19+
const moduleRef = useRef<HTMLDivElement>(null);
20+
const [isInitialised, setIsInitialised] = useState<boolean>(false);
21+
1922
const _boxReferences: string[] = [];
2023
let _boxCount: number = 0;
2124
let _boxIds: Record<string, string> = {};
2225

2326
useEffect(() => {
24-
CheckboxJs();
25-
}, []);
27+
if (isInitialised || !moduleRef.current?.parentElement) {
28+
return;
29+
}
30+
31+
initCheckboxes({ scope: moduleRef.current.parentElement });
32+
setIsInitialised(true);
33+
}, [isInitialised, moduleRef]);
2634

2735
const getBoxId = (id: string, reference: string): string => {
2836
if (reference in _boxIds) {
@@ -65,7 +73,12 @@ const Checkboxes = ({ children, idPrefix, ...rest }: CheckboxesProps) => {
6573
unleaseReference,
6674
};
6775
return (
68-
<div className={classNames('nhsuk-checkboxes', className)} id={id} {...restRenderProps}>
76+
<div
77+
className={classNames('nhsuk-checkboxes', className)}
78+
id={id}
79+
ref={moduleRef}
80+
{...restRenderProps}
81+
>
6982
<CheckboxContext.Provider value={contextValue}>{children}</CheckboxContext.Provider>
7083
</div>
7184
);

src/components/navigation/header/Header.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use client';
2-
import React, { FC, HTMLProps, useContext, useState, useEffect, useMemo } from 'react';
2+
import React, { FC, HTMLProps, useContext, useState, useEffect, useMemo, useRef } from 'react';
33
import classNames from 'classnames';
44
import NHSLogo, { NHSLogoNavProps } from './components/NHSLogo';
55
import OrganisationalLogo, { OrganisationalLogoProps } from './components/OrganisationalLogo';
@@ -12,7 +12,7 @@ import { Container } from '@components/layout';
1212
import Content from './components/Content';
1313
import TransactionalServiceName from './components/TransactionalServiceName';
1414
// @ts-expect-error -- No types available
15-
import HeaderJs from 'nhsuk-frontend/packages/components/header/header';
15+
import initHeader from 'nhsuk-frontend/packages/components/header/header';
1616

1717
const BaseHeaderLogo: FC<OrganisationalLogoProps & NHSLogoNavProps> = (props) => {
1818
const { orgName } = useContext<IHeaderContext>(HeaderContext);
@@ -47,14 +47,22 @@ const Header = ({
4747
white,
4848
...rest
4949
}: HeaderProps) => {
50+
const moduleRef = useRef<HTMLElement>(null);
51+
5052
const [hasMenuToggle, setHasMenuToggle] = useState(false);
5153
const [hasSearch, setHasSearch] = useState(false);
5254
const [hasServiceName, setHasServiceName] = useState(false);
55+
const [isInitialised, setIsInitialised] = useState<boolean>(false);
5356
const [menuOpen, setMenuOpen] = useState(false);
5457

5558
useEffect(() => {
56-
HeaderJs();
57-
}, []);
59+
if (isInitialised || !moduleRef.current?.parentElement) {
60+
return;
61+
}
62+
63+
initHeader({ scope: moduleRef.current.parentElement });
64+
setIsInitialised(true);
65+
}, [isInitialised, moduleRef]);
5866

5967
const setMenuToggle = (toggle: boolean): void => {
6068
setHasMenuToggle(toggle);
@@ -114,6 +122,7 @@ const Header = ({
114122
className,
115123
)}
116124
role={role}
125+
ref={moduleRef}
117126
{...rest}
118127
>
119128
<HeaderContext.Provider value={contextValue}>{children}</HeaderContext.Provider>

0 commit comments

Comments
 (0)