Skip to content

Commit

Permalink
feat: Dialog support aria-* in closable (#403)
Browse files Browse the repository at this point in the history
* feat: Dialog support aria-* in closable

* feat: Dialog support aria-* in closable

* feat: Dialog support aria-* in closable

* feat: Dialog support aria-* in closable

* feat: optimize code

* feat: optimize code
  • Loading branch information
kiner-tang committed Feb 29, 2024
1 parent 7a3bb93 commit 94dcda5
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 4 deletions.
20 changes: 17 additions & 3 deletions src/Dialog/Content/Panel.tsx
@@ -1,9 +1,10 @@
import classNames from 'classnames';
import { useComposeRef } from 'rc-util/lib/ref';
import React, { useRef } from 'react';
import React, { useMemo, useRef } from 'react';
import { RefContext } from '../../context';
import type { IDialogPropTypes } from '../../IDialogPropTypes';
import MemoChildren from './MemoChildren';
import pickAttrs from 'rc-util/lib/pickAttrs';

const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' };
const entityStyle = { outline: 'none' };
Expand Down Expand Up @@ -96,11 +97,24 @@ const Panel = React.forwardRef<ContentRef, PanelProps>((props, ref) => {
);
}


const closableObj = useMemo(() => {
if (typeof closable === 'object' && closable !== null) {
return closable;
}
if (closable) {
return { closeIcon: closeIcon ?? <span className={`${prefixCls}-close-x`} /> };
}
return {};
}, [closable, closeIcon]);

const ariaProps = pickAttrs(closableObj, true);

let closer: React.ReactNode;
if (closable) {
closer = (
<button type="button" onClick={onClose} aria-label="Close" className={`${prefixCls}-close`}>
{closeIcon || <span className={`${prefixCls}-close-x`} />}
<button type="button" onClick={onClose} aria-label="Close" {...ariaProps} className={`${prefixCls}-close`}>
{closableObj.closeIcon}
</button>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/IDialogPropTypes.tsx
Expand Up @@ -28,7 +28,7 @@ export type IDialogPropTypes = {
afterClose?: () => any;
afterOpenChange?: (open: boolean) => void;
onClose?: (e: SyntheticEvent) => any;
closable?: boolean;
closable?: boolean | ({ closeIcon?: React.ReactNode } & React.AriaAttributes);
maskClosable?: boolean;
visible?: boolean;
destroyOnClose?: boolean;
Expand Down
40 changes: 40 additions & 0 deletions tests/index.spec.tsx
Expand Up @@ -640,4 +640,44 @@ describe('dialog', () => {
);
spy.mockRestore();
});

it('support aria-* in closable', () => {
const onClose = jest.fn();
const wrapper = mount(
<Dialog
closable={{
closeIcon:"test",
'aria-label': 'test aria-label',
}}
visible
onClose={onClose}
/>
);
jest.runAllTimers();
wrapper.update();

const btn = wrapper.find('.rc-dialog-close');
expect(btn.text()).toBe('test');
expect(btn.getDOMNode().getAttribute('aria-label')).toBe('test aria-label');
btn.simulate('click');

jest.runAllTimers();
wrapper.update();
expect(onClose).toHaveBeenCalledTimes(1);
});
it('should not display closeIcon when closable is false', () => {
const onClose = jest.fn();
const wrapper = mount(
<Dialog
closable={false}
visible
onClose={onClose}
/>
);
jest.runAllTimers();
wrapper.update();

const btn = wrapper.find('.rc-dialog-close');
expect(btn.find('.rc-dialog-close-x')).not.toBeNull();
});
});

0 comments on commit 94dcda5

Please sign in to comment.