Skip to content

Commit

Permalink
feat: support aria-labelledby and aria-describedby for dialog in Panel (
Browse files Browse the repository at this point in the history
#425)

* feat: support aria-labelledby and aria-describedby for dialog

The DrawerPanel has a dialog role which should support aria-labelledby and aria-describedby attributes.

* Allowing all aria-* props

* Removing custom method to pick aria props
  • Loading branch information
kapiljaveri authored Feb 7, 2024
1 parent 4629910 commit dddc45c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 7 deletions.
8 changes: 6 additions & 2 deletions src/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import Portal from '@rc-component/portal';
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
import * as React from 'react';
import { RefContext } from './context';
import type { DrawerPanelEvents } from './DrawerPanel';
import type {
DrawerPanelAccessibility,
DrawerPanelEvents,
} from './DrawerPanel';
import type { DrawerPopupProps } from './DrawerPopup';
import DrawerPopup from './DrawerPopup';
import { warnCheck } from './util';
Expand All @@ -13,7 +16,8 @@ export type Placement = 'left' | 'top' | 'right' | 'bottom';

export interface DrawerProps
extends Omit<DrawerPopupProps, 'prefixCls' | 'inline' | 'scrollLocker'>,
DrawerPanelEvents {
DrawerPanelEvents,
DrawerPanelAccessibility {
prefixCls?: string;
open?: boolean;
onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void;
Expand Down
13 changes: 11 additions & 2 deletions src/DrawerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import classNames from 'classnames';
import { useComposeRef } from 'rc-util';
import * as React from 'react';
import { RefContext } from './context';
import pickAttrs from 'rc-util/lib/pickAttrs';

export interface DrawerPanelRef {
focus: VoidFunction;
Expand All @@ -16,7 +17,14 @@ export interface DrawerPanelEvents {
onKeyUp?: React.KeyboardEventHandler<HTMLDivElement>;
}

export interface DrawerPanelProps extends DrawerPanelEvents {
export type DrawerPanelAccessibility = Pick<
React.DialogHTMLAttributes<HTMLDivElement>,
keyof React.AriaAttributes
>;

export interface DrawerPanelProps
extends DrawerPanelEvents,
DrawerPanelAccessibility {
prefixCls: string;
className?: string;
id?: string;
Expand Down Expand Up @@ -63,9 +71,10 @@ const DrawerPanel = (props: DrawerPanelProps) => {
style={{
...style,
}}
aria-modal="true"
role="dialog"
ref={mergedRef}
{...pickAttrs(props, { aria: true })}
aria-modal="true"
{...eventHandlers}
>
{children}
Expand Down
10 changes: 8 additions & 2 deletions src/DrawerPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import pickAttrs from 'rc-util/lib/pickAttrs';
import * as React from 'react';
import type { DrawerContextProps } from './context';
import DrawerContext from './context';
import type { DrawerPanelEvents } from './DrawerPanel';
import type {
DrawerPanelAccessibility,
DrawerPanelEvents,
} from './DrawerPanel';
import DrawerPanel from './DrawerPanel';
import { parseWidthHeight } from './util';
import type { DrawerClassNames, DrawerStyles } from './inter';
Expand All @@ -25,7 +28,9 @@ export interface PushConfig {
distance?: number | string;
}

export interface DrawerPopupProps extends DrawerPanelEvents {
export interface DrawerPopupProps
extends DrawerPanelEvents,
DrawerPanelAccessibility {
prefixCls: string;
open?: boolean;
inline?: boolean;
Expand Down Expand Up @@ -315,6 +320,7 @@ function DrawerPopup(props: DrawerPopupProps, ref: React.Ref<HTMLDivElement>) {
...style,
...styles?.content,
}}
{...pickAttrs(props, { aria: true })}
{...eventHandlers}
>
{children}
Expand Down
2 changes: 1 addition & 1 deletion src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ export function warnCheck(props: DrawerProps) {
canUseDom() || !props.open,
`Drawer with 'open' in SSR is not work since no place to createPortal. Please move to 'useEffect' instead.`,
);
}
}
21 changes: 21 additions & 0 deletions tests/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,27 @@ describe('rc-drawer-menu', () => {
unmount();
});

it('passes aria-describedby to the Panel', () => {
const description = 'some meaningful description';
const { unmount, getByRole } = render(<Drawer open aria-describedby={description} />);
expect(getByRole('dialog')).toHaveAttribute('aria-describedby', description);
unmount();
});

it('passes aria-labelledby to the Panel', () => {
const titleId = 'some-id';
const { unmount, getByRole } = render(
<Drawer open aria-labelledby={titleId}>
<h1 id={titleId}>Some Title</h1>
</Drawer>
);
expect(getByRole('dialog')).toHaveAttribute('aria-labelledby', titleId);
expect(getByRole('dialog', {
name: 'Some Title'
})).toBeVisible();
unmount();
});

it('should support classNames', () => {
const { unmount } = render(
<Drawer classNames={{
Expand Down

0 comments on commit dddc45c

Please sign in to comment.