diff --git a/src/__tests__/drawer-test.tsx b/src/__tests__/drawer-test.tsx
new file mode 100644
index 000000000..f6dca5f14
--- /dev/null
+++ b/src/__tests__/drawer-test.tsx
@@ -0,0 +1,115 @@
+import * as React from 'react';
+import {makeTheme} from './test-utils';
+import {render, screen, waitFor} from '@testing-library/react';
+import ThemeContextProvider from '../theme-context-provider';
+import Drawer from '../drawer';
+import userEvent from '@testing-library/user-event';
+
+const DrawerTest = ({
+ onDismiss,
+ onButtonPrimaryPress,
+ onButtonSecondaryPress,
+ onButtonLinkPress,
+}: {
+ onDismiss?: () => void;
+ onButtonPrimaryPress?: () => void;
+ onButtonSecondaryPress?: () => void;
+ onButtonLinkPress?: () => void;
+}) => {
+ const [isOpen, setIsOpen] = React.useState(false);
+ return (
+
+
+ {isOpen && (
+ setIsOpen(false)}
+ button={{text: 'Primary', onPress: onButtonPrimaryPress}}
+ secondaryButton={{text: 'Secondary', onPress: onButtonSecondaryPress}}
+ buttonLink={{text: 'Link', onPress: onButtonLinkPress}}
+ />
+ )}
+
+ );
+};
+
+test.each(['esc', 'overlay', 'x'])('Drawer dismiss: %s', async (dismissMethod: string) => {
+ const onDismissSpy = jest.fn();
+ render();
+
+ const openButton = screen.getByRole('button', {name: 'open'});
+ await userEvent.click(openButton);
+
+ const drawer = await screen.findByRole('dialog');
+
+ switch (dismissMethod) {
+ case 'esc':
+ await userEvent.keyboard('{Escape}');
+ break;
+ case 'overlay':
+ await userEvent.click(screen.getByTestId('drawerOverlay'));
+ break;
+ case 'x':
+ await userEvent.click(screen.getByRole('button', {name: 'CustomDismissLabel'}));
+ break;
+ default:
+ throw new Error('unexpected dismiss method');
+ }
+
+ await waitFor(() => {
+ expect(onDismissSpy).toHaveBeenCalledTimes(1);
+ expect(drawer).not.toBeInTheDocument();
+ });
+});
+
+test.each(['primary', 'secondary', 'link'])('Drawer close: %s', async (closeMethod: string) => {
+ const onButtonPrimaryPress = jest.fn();
+ const onButtonSecondaryPress = jest.fn();
+ const onButtonLinkPress = jest.fn();
+
+ render(
+
+ );
+
+ const openButton = screen.getByRole('button', {name: 'open'});
+ await userEvent.click(openButton);
+
+ const drawer = await screen.findByRole('dialog');
+
+ switch (closeMethod) {
+ case 'primary':
+ await userEvent.click(screen.getByRole('button', {name: 'Primary'}));
+ break;
+ case 'secondary':
+ await userEvent.click(screen.getByRole('button', {name: 'Secondary'}));
+ break;
+ case 'link':
+ await userEvent.click(screen.getByRole('button', {name: 'Link'}));
+ break;
+ default:
+ throw new Error('unexpected dismiss method');
+ }
+
+ await waitFor(() => {
+ expect(drawer).not.toBeInTheDocument();
+ });
+
+ switch (closeMethod) {
+ case 'primary':
+ expect(onButtonPrimaryPress).toHaveBeenCalledTimes(1);
+ break;
+ case 'secondary':
+ expect(onButtonSecondaryPress).toHaveBeenCalledTimes(1);
+ break;
+ case 'link':
+ expect(onButtonLinkPress).toHaveBeenCalledTimes(1);
+ break;
+ default:
+ throw new Error('unexpected dismiss method');
+ }
+});
diff --git a/src/__tests__/testid-test.tsx b/src/__tests__/testid-test.tsx
index 63c981c76..8f2e6f359 100644
--- a/src/__tests__/testid-test.tsx
+++ b/src/__tests__/testid-test.tsx
@@ -22,6 +22,7 @@ import {
CoverHero,
Header,
MainSectionHeader,
+ Drawer,
} from '..';
import {makeTheme} from './test-utils';
@@ -288,3 +289,12 @@ test('Meter test ids', () => {
},
]);
});
+
+test('Drawer test ids', () => {
+ checkTestIds( {}} />, [
+ {
+ componentName: 'Drawer',
+ internalTestIds: ['title', 'subtitle', 'description'],
+ },
+ ]);
+});
diff --git a/src/drawer.tsx b/src/drawer.tsx
index 2fb6629f4..97fe526ac 100644
--- a/src/drawer.tsx
+++ b/src/drawer.tsx
@@ -19,7 +19,7 @@ import Divider from './divider';
import {getPrefixedDataAttributes} from './utils/dom';
import * as tokens from './text-tokens';
-import type {DataAttributes, TrackingEvent} from './utils/types';
+import type {DataAttributes, HeadingType, TrackingEvent} from './utils/types';
const PADDING_X_DESKTOP = 40;
const PADDING_X_MOBILE = 16;
@@ -131,13 +131,15 @@ type ButtonProps = {
text: string;
trackingEvent?: TrackingEvent | ReadonlyArray;
trackEvent?: boolean;
- onPress: () => unknown;
+ onPress?: () => unknown;
};
type DrawerProps = {
title?: string;
subtitle?: string;
description?: string;
+ titleAs?: HeadingType;
+ dismissLabel?: string;
/**
* this handler is mandatory. You should unmount the Drawer component on close.
*/
@@ -164,6 +166,8 @@ const Drawer = ({
title,
subtitle,
description,
+ titleAs = 'h2',
+ dismissLabel,
width,
onClose,
onDismiss,
@@ -186,8 +190,8 @@ const Drawer = ({
desktop: PADDING_X_DESKTOP,
} as const;
- const handleButtonPress = (pressHandlerFromProps: () => unknown) => {
- layoutRef.current?.close().then(pressHandlerFromProps);
+ const handleButtonPress = (pressHandlerFromProps?: () => unknown) => {
+ layoutRef.current?.close().then(() => pressHandlerFromProps?.());
};
const showTitleDivider = !useIsInViewport(topScrollSignalRef, true, {
@@ -214,7 +218,7 @@ const Drawer = ({
dataAttributes={{testid: 'dismissButton'}}
onPress={() => layoutRef.current?.dismiss()}
Icon={IconCloseRegular}
- aria-label={texts.modalClose || t(tokens.modalClose)}
+ aria-label={dismissLabel || texts.modalClose || t(tokens.modalClose)}
type="neutral"
backgroundType="transparent"
/>
@@ -223,7 +227,9 @@ const Drawer = ({
{title && (
- {title}
+
+ {title}
+
)}