Skip to content

Commit e36769d

Browse files
[IRN-5693][BpkModal] Support dialog a11y label when no header (#3767)
* [IRN-5693][BpkModal] Support dialog a11y label when no header * Add test case * Add test case
1 parent 75cc187 commit e36769d

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed

examples/bpk-component-modal/examples.tsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ const content = [
106106
pulvinar erat dignissim vitae.
107107
</Paragraph>,
108108
];
109-
type ContainerProps = {
109+
type ContainerProps = {
110110
title?: string;
111111
buttonLabel?: string;
112112
id?: string;
113113
wrapperProps?: Object;
114114
isOpen?: boolean;
115-
} & Omit<BpkModalProps, 'getApplicationElement'| 'id' | 'isOpen'>;
115+
} & Omit<BpkModalProps, 'getApplicationElement' | 'id' | 'isOpen'>;
116116

117117
const ModalContainer = (props: ContainerProps) => {
118118
const [isOpen, setIsOpen] = useState(props.isOpen || false);
@@ -230,8 +230,7 @@ const NestedExample = (isOpen: boolean) => (
230230

231231
const NoHeaderExample = (isOpen: boolean) => (
232232
<ModalContainer
233-
title="Modal title"
234-
closeLabel="Close modal"
233+
ariaLabel="Modal title"
235234
showHeader={false}
236235
isOpen={isOpen}
237236
>
@@ -252,7 +251,7 @@ const WithAccessoryViewExample = (isOpen: boolean) => (
252251
accessoryView={
253252
<BpkNavigationBarButtonLink
254253
label="Close"
255-
onClick={() => {}}
254+
onClick={() => { }}
256255
className={getClassName('bpk-modal__leading-button')}
257256
>
258257
<div>

packages/bpk-component-modal/src/BpkModalInner-test.tsx

+36-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* limitations under the License.
1717
*/
1818

19-
import { render } from '@testing-library/react';
19+
import { render, screen } from '@testing-library/react';
2020

2121
import { BpkNavigationBarButtonLink } from '../../bpk-component-navigation-bar';
2222

@@ -198,4 +198,39 @@ describe('BpkModalInner', () => {
198198
);
199199
expect(asFragment()).toMatchSnapshot();
200200
});
201+
202+
it('should render correctly with showHeader false', () => {
203+
render(
204+
<BpkModalInner
205+
id="my-modal"
206+
ariaLabel="Modal title"
207+
showHeader={false}
208+
dialogRef={jest.fn()}
209+
isIphone={false}
210+
>
211+
Modal content
212+
</BpkModalInner>,
213+
);
214+
215+
expect(screen.queryAllByRole('heading')).toHaveLength(0);
216+
expect(screen.getByRole('dialog')).toHaveAttribute('aria-label', 'Modal title');
217+
});
218+
219+
it('should render with a11y labelled-by when showHeader true', () => {
220+
render(
221+
<BpkModalInner
222+
id="my-modal"
223+
title="Actual title"
224+
ariaLabel="Ignored title"
225+
showHeader
226+
dialogRef={jest.fn()}
227+
isIphone={false}
228+
>
229+
Modal content
230+
</BpkModalInner>,
231+
);
232+
233+
expect(screen.getByRole('heading')).toHaveTextContent('Actual title');
234+
expect(screen.getByRole('dialog')).toHaveAccessibleName('Actual title');
235+
});
201236
});

packages/bpk-component-modal/src/BpkModalInner.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export type Props = {
5252
* The accessory view allows for icons and actions to be placed in front of the main title inside the modal header. To be used with `BpkNavigationBarButtonLink`
5353
*/
5454
accessoryView?: ReactNode;
55+
ariaLabel?: string // optional aria label for scenario when header is disabled
5556
};
5657

5758
export const MODAL_STYLING = {
@@ -62,6 +63,7 @@ export type ModalStyle = (typeof MODAL_STYLING)[keyof typeof MODAL_STYLING];
6263

6364
const BpkModalInner = ({
6465
accessoryView = null,
66+
ariaLabel,
6567
children,
6668
className = null,
6769
closeLabel = '',
@@ -125,6 +127,7 @@ const BpkModalInner = ({
125127
tabIndex={-1}
126128
role="dialog"
127129
aria-labelledby={showHeader ? headingId : undefined}
130+
aria-label={!showHeader ? ariaLabel : undefined}
128131
className={classNames.join(' ')}
129132
ref={dialogRef}
130133
>

0 commit comments

Comments
 (0)