Skip to content

Commit

Permalink
Merge 0c4afe9 into dcefc94
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandrzavalii authored Apr 20, 2020
2 parents dcefc94 + 0c4afe9 commit c9b703e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 24 deletions.
12 changes: 12 additions & 0 deletions cypress/integration/Modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ describe('Modal', () => {
h.modal.get().should('have.attr', 'aria-labelledby');
});

it('should have an aria-modal=true', () => {
h.modal.get().should('have.attr', 'aria-modal', 'true');
});

it('should contain the title', () => {
h.modal
.get()
Expand Down Expand Up @@ -235,6 +239,10 @@ describe('Modal', () => {
h.modal.get().should('have.attr', 'aria-labelledby');
});

it('should have an aria-modal=true', () => {
h.modal.get().should('have.attr', 'aria-modal', 'true');
});

it('should contain the title', () => {
h.modal
.get()
Expand Down Expand Up @@ -332,6 +340,10 @@ describe('Modal', () => {
h.modal.get().should('have.attr', 'aria-labelledby');
});

it('should have an aria-modal=true', () => {
h.modal.get().should('have.attr', 'aria-modal', 'true');
});

it('should contain the title', () => {
h.modal
.get()
Expand Down
7 changes: 7 additions & 0 deletions modules/modal/react/lib/ModalContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import Popup, {PopupPadding} from '@workday/canvas-kit-react-popup';
import {ModalWidth} from './Modal';

export interface ModalContentProps extends React.HTMLAttributes<HTMLDivElement> {
/**
* Aria label will override aria-labelledby, it is used if there is no heading or we need custom label for popup
*/
ariaLabel?: string;
/**
* The padding of the Modal. Accepts `zero`, `s`, or `l`.
* @default PopupPadding.l
Expand Down Expand Up @@ -152,6 +156,7 @@ const useInitialFocus = (
};

const ModalContent = ({
ariaLabel,
closeOnEscape = true,
width = ModalWidth.s,
padding = PopupPadding.l,
Expand Down Expand Up @@ -215,6 +220,8 @@ const ModalContent = ({
handleClose={handleClose}
padding={padding}
transformOrigin={transformOrigin}
aria-modal={true}
ariaLabel={ariaLabel}
>
{children}
</Popup>
Expand Down
33 changes: 18 additions & 15 deletions modules/modal/react/spec/Modal.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,29 @@ import {render, fireEvent} from '@testing-library/react';

import Modal from '../lib/Modal';

const renderModal = (props?: any) =>
render(
<Modal open={true} handleClose={jest.fn()} heading="Test" {...props}>
Hello World
</Modal>
);

describe('Modal', () => {
test('should call a callback function', async () => {
const cb = jest.fn();
const {findByLabelText} = render(
<Modal open={true} handleClose={cb} heading="Test">
Hello World
</Modal>
);

const handleClose = jest.fn();
const {findByLabelText} = renderModal({handleClose});
fireEvent.click(await findByLabelText('Close'));

expect(cb).toHaveBeenCalledTimes(1);
expect(handleClose).toHaveBeenCalledTimes(1);
});

test('Modal should spread extra props', async () => {
const cb = jest.fn();
const {getByRole} = render(
<Modal handleClose={cb} heading="Test" open={true} data-propspread="test" />
);

test('Modal should spread extra props', () => {
const {getByRole} = renderModal({['data-propspread']: 'test'});
expect(getByRole('dialog').parentElement).toHaveAttribute('data-propspread', 'test');
});

test('Modal should replace aria-labeldBy with custom aria-label', () => {
const customAriaLabel = 'custom aria label';
const {getByRole} = renderModal({ariaLabel: customAriaLabel});
expect(getByRole('dialog')).toHaveAttribute('aria-label', customAriaLabel);
});
});
32 changes: 23 additions & 9 deletions modules/popup/react/lib/Popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export enum PopupPadding {
}

export interface PopupProps extends React.HTMLAttributes<HTMLDivElement> {
/**
* Aria label will override aria-labelledby, it is used if there is no heading or we need custom label for popup
*/
ariaLabel?: string;
/**
* The padding of the Popup. Accepts `zero`, `s`, or `l`.
* @default PopupPadding.l
Expand Down Expand Up @@ -98,6 +102,21 @@ const Container = styled('div', {
})
);

const getHeadingId = (heading: React.ReactNode, id: string) => (heading ? id : undefined);

const getAriaLabel = (
ariaLabel: string | undefined,
headingId: string | undefined
): object | undefined => {
if (ariaLabel) {
return {['aria-label']: ariaLabel};
}
if (headingId) {
return {['aria-labelledby']: headingId};
}
return undefined;
};

const CloseIconContainer = styled('div')<Pick<PopupProps, 'closeIconSize'>>(
{
position: 'absolute',
Expand Down Expand Up @@ -128,16 +147,17 @@ export default class Popup extends React.Component<PopupProps> {
width,
heading,
popupRef,
ariaLabel,
...elemProps
} = this.props;

const headingId = getHeadingId(heading, this.id);
return (
<Container
transformOrigin={transformOrigin}
width={width}
role="dialog"
aria-labelledby={heading ? this.id : undefined}
ref={popupRef}
{...getAriaLabel(ariaLabel, headingId)}
{...elemProps}
>
{handleClose && (
Expand All @@ -153,13 +173,7 @@ export default class Popup extends React.Component<PopupProps> {
/>
</CloseIconContainer>
)}
<Card
depth={depth}
heading={heading}
headingId={heading ? this.id : undefined}
width="100%"
padding={padding}
>
<Card depth={depth} heading={heading} headingId={headingId} width="100%" padding={padding}>
{this.props.children}
</Card>
</Container>
Expand Down

0 comments on commit c9b703e

Please sign in to comment.