Skip to content

Commit

Permalink
feat(Modal): add WAI-ARIA state and support keyboard event
Browse files Browse the repository at this point in the history
  • Loading branch information
shervinchen committed May 5, 2024
1 parent e04e518 commit a4d981e
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 2 deletions.
6 changes: 6 additions & 0 deletions packages/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React, { FC, PropsWithChildren, useCallback, useMemo } from 'react';
import { createPortal } from 'react-dom';
import classNames from 'classnames';
import { useKeyPressEvent } from 'react-use';
import { ModalProps } from './Modal.types';
import { useControlled, usePortal } from '../utils/hooks';
import Overlay from '../Overlay';
import ModalWrapper from './ModalWrapper';
import { ModalConfig, ModalContext } from './modal-context';
import ModalCloseButton from './ModalCloseButton';
import { KeyCode } from '../utils/constant';

const Modal: FC<PropsWithChildren<ModalProps>> = ({
visible,
Expand Down Expand Up @@ -39,6 +41,10 @@ const Modal: FC<PropsWithChildren<ModalProps>> = ({
[internalVisible, closeModal, width, closeOnOverlayClick]
);

useKeyPressEvent(KeyCode.Escape, () => {
closeModal();
});

if (!portal) return null;

return createPortal(
Expand Down
2 changes: 1 addition & 1 deletion packages/Modal/ModalBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { FC, PropsWithChildren } from 'react';

const ModalBody: FC<PropsWithChildren> = ({ children, ...restProps }) => {
return (
<div className="raw-modal-body" {...restProps}>
<div id="raw-modal-body" className="raw-modal-body" {...restProps}>
{children}
<style jsx>{`
.raw-modal-body {
Expand Down
8 changes: 7 additions & 1 deletion packages/Modal/ModalHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ import React, { FC, PropsWithChildren } from 'react';
const ModalHeader: FC<PropsWithChildren> = ({ children, ...restProps }) => {
return (
<header className="raw-modal-header" {...restProps}>
{children}
<h4 id="raw-modal-title" className="raw-modal-title">
{children}
</h4>
<style jsx>{`
.raw-modal-header {
flex: 0 1 0%;
padding: 16px 24px;
}
.raw-modal-title {
font-weight: 600;
font-size: 24px;
margin-top: 0;
margin-bottom: 0;
}
`}</style>
</header>
Expand Down
4 changes: 4 additions & 0 deletions packages/Modal/ModalWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ const ModalWrapper: FC<PropsWithChildren<ModalWrapperProps>> = ({
return shouldMount ? (
<RemoveScroll>
<div
role="dialog"
aria-modal="true"
aria-labelledby="raw-modal-title"
aria-describedby="raw-modal-body"
className="raw-modal-container"
onClick={clickModalContainerHandler}
data-testid="modalContainer"
Expand Down
10 changes: 10 additions & 0 deletions packages/Modal/__tests__/Modal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState } from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { Button, Modal, ModalProps } from '../..';
import userEvent from '@testing-library/user-event';
import { KeyCode } from '../../utils/constant';

const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });

Expand Down Expand Up @@ -118,4 +119,13 @@ describe('Modal', () => {
expect(await screen.findByTestId('modalContainer')).toBeInTheDocument();
expect(closeHandler).toHaveBeenCalledTimes(0);
});

test('should close modal when press the Escape key', async () => {
render(<Component />);
await user.click(screen.getByTestId('openModal'));
await user.keyboard(`[${KeyCode.Escape}]`);
await waitFor(() => {
expect(screen.queryByTestId('modalContainer')).not.toBeInTheDocument();
});
});
});
3 changes: 3 additions & 0 deletions packages/utils/constant/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { KeyCode } from './keyCode';

export { KeyCode };
3 changes: 3 additions & 0 deletions packages/utils/constant/keyCode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum KeyCode {
Escape = 'Escape',
}

0 comments on commit a4d981e

Please sign in to comment.