Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ props details:
</tr>
<tr>
<td>closable</td>
<td>Boolean</td>
<td>Boolean | { closeIcon: ReactNode, onClose: VoidFunction }</td>
<td></td>
<td>whether show close button</td>
</tr>
Expand Down
6 changes: 5 additions & 1 deletion src/Notifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ const Notifications = React.forwardRef<NotificationsRef, NotificationsProps>((pr
const onNoticeClose = (key: React.Key) => {
// Trigger close event
const config = configList.find((item) => item.key === key);
config?.onClose?.();
const onClose =
typeof config?.closable === 'object' && config?.closable !== null
? config.closable?.onClose
: config?.onClose;
onClose?.();

setConfigList((list) => list.filter((item) => item.key !== key));
};
Expand Down
4 changes: 3 additions & 1 deletion src/hooks/useNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export interface NotificationConfig {
getContainer?: () => HTMLElement | ShadowRoot;
motion?: CSSMotionProps | ((placement: Placement) => CSSMotionProps);

closable?: boolean | ({ closeIcon?: React.ReactNode } & React.AriaAttributes);
closable?:
| boolean
| ({ closeIcon?: React.ReactNode; onClose?: VoidFunction } & React.AriaAttributes);
maxCount?: number;
duration?: number;
showProgress?: boolean;
Expand Down
4 changes: 3 additions & 1 deletion src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export interface NoticeConfig {
showProgress?: boolean;
pauseOnHover?: boolean;

closable?: boolean | ({ closeIcon?: React.ReactNode } & React.AriaAttributes);
closable?:
| boolean
| ({ closeIcon?: React.ReactNode; onClose?: VoidFunction } & React.AriaAttributes);
className?: string;
style?: React.CSSProperties;
classNames?: {
Expand Down
98 changes: 98 additions & 0 deletions tests/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,104 @@ describe('Notification.Basic', () => {
unmount();
});

describe('onClose and closable.onClose', () => {
it('onClose', () => {
const onClose = vi.fn();
const Demo = () => {
const [api, holder] = useNotification();
return (
<>
<button
type="button"
onClick={() => {
api.open({
key: 'little',
duration: 1,
content: <div className="context-content">light</div>,
closable: { onClose },
});
}}
/>
{holder}
</>
);
};

const { container: demoContainer, unmount } = render(<Demo />);
fireEvent.click(demoContainer.querySelector('button'));
act(() => {
vi.runAllTimers();
});
expect(onClose).toHaveBeenCalled();

unmount();
});
it('onClose and closable.onClose', () => {
const onClose = vi.fn();
const closableOnClose = vi.fn();
const Demo = () => {
const [api, holder] = useNotification();
return (
<>
<button
type="button"
onClick={() => {
api.open({
key: 'little',
duration: 1,
content: <div className="context-content">light</div>,
onClose,
closable: { onClose: closableOnClose },
});
}}
/>
{holder}
</>
);
};

const { container: demoContainer, unmount } = render(<Demo />);
fireEvent.click(demoContainer.querySelector('button'));
act(() => {
vi.runAllTimers();
});
expect(closableOnClose).toHaveBeenCalled();
expect(onClose).not.toHaveBeenCalled();

unmount();
});
it('closable.onClose (config)', () => {
const onClose = vi.fn();
const Demo = () => {
const [api, holder] = useNotification({ closable: { onClose } });
return (
<>
<button
type="button"
onClick={() => {
api.open({
key: 'little',
duration: 1,
content: <div className="context-content">light</div>,
});
}}
/>
{holder}
</>
);
};

const { container: demoContainer, unmount } = render(<Demo />);
fireEvent.click(demoContainer.querySelector('button'));
act(() => {
vi.runAllTimers();
});
expect(onClose).toHaveBeenCalled();

unmount();
});
});

it('closes via keyboard Enter key', () => {
const { instance } = renderDemo();
let closeCount = 0;
Expand Down