Skip to content

Commit f5db7a2

Browse files
EmilyyyLiu刘欢
andauthored
feat: Add onClose to Closable (#376)
* feat: Merge 'onClose' into Closable * docs: add closable describe * test: delete only * docs: closable describe * feat: config?.closable null * feat: Both closableOnllose and onClose are called --------- Co-authored-by: 刘欢 <lh01217311@antgroup.com>
1 parent 53d2483 commit f5db7a2

File tree

5 files changed

+109
-4
lines changed

5 files changed

+109
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ props details:
117117
</tr>
118118
<tr>
119119
<td>closable</td>
120-
<td>Boolean</td>
120+
<td>Boolean | { closeIcon: ReactNode, onClose: VoidFunction }</td>
121121
<td></td>
122122
<td>whether show close button</td>
123123
</tr>

src/Notifications.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,11 @@ const Notifications = React.forwardRef<NotificationsRef, NotificationsProps>((pr
4545
const onNoticeClose = (key: React.Key) => {
4646
// Trigger close event
4747
const config = configList.find((item) => item.key === key);
48+
const closable = config?.closable;
49+
const closableObj = closable && typeof closable === 'object' ? closable : {};
50+
const { onClose: closableOnClose } = closableObj;
51+
closableOnClose?.();
4852
config?.onClose?.();
49-
5053
setConfigList((list) => list.filter((item) => item.key !== key));
5154
};
5255

src/hooks/useNotification.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ export interface NotificationConfig {
1515
getContainer?: () => HTMLElement | ShadowRoot;
1616
motion?: CSSMotionProps | ((placement: Placement) => CSSMotionProps);
1717

18-
closable?: boolean | ({ closeIcon?: React.ReactNode } & React.AriaAttributes);
18+
closable?:
19+
| boolean
20+
| ({ closeIcon?: React.ReactNode; onClose?: VoidFunction } & React.AriaAttributes);
1921
maxCount?: number;
2022
duration?: number;
2123
showProgress?: boolean;

src/interface.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ export interface NoticeConfig {
1010
showProgress?: boolean;
1111
pauseOnHover?: boolean;
1212

13-
closable?: boolean | ({ closeIcon?: React.ReactNode } & React.AriaAttributes);
13+
closable?:
14+
| boolean
15+
| ({ closeIcon?: React.ReactNode; onClose?: VoidFunction } & React.AriaAttributes);
1416
className?: string;
1517
style?: React.CSSProperties;
1618
classNames?: {

tests/index.test.tsx

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,104 @@ describe('Notification.Basic', () => {
778778
unmount();
779779
});
780780

781+
describe('onClose and closable.onClose', () => {
782+
it('onClose', () => {
783+
const onClose = vi.fn();
784+
const Demo = () => {
785+
const [api, holder] = useNotification();
786+
return (
787+
<>
788+
<button
789+
type="button"
790+
onClick={() => {
791+
api.open({
792+
key: 'little',
793+
duration: 1,
794+
content: <div className="context-content">light</div>,
795+
closable: { onClose },
796+
});
797+
}}
798+
/>
799+
{holder}
800+
</>
801+
);
802+
};
803+
804+
const { container: demoContainer, unmount } = render(<Demo />);
805+
fireEvent.click(demoContainer.querySelector('button'));
806+
act(() => {
807+
vi.runAllTimers();
808+
});
809+
expect(onClose).toHaveBeenCalled();
810+
811+
unmount();
812+
});
813+
it('Both closableOnllose and onClose are called', () => {
814+
const onClose = vi.fn();
815+
const closableOnClose = vi.fn();
816+
const Demo = () => {
817+
const [api, holder] = useNotification();
818+
return (
819+
<>
820+
<button
821+
type="button"
822+
onClick={() => {
823+
api.open({
824+
key: 'little',
825+
duration: 1,
826+
content: <div className="context-content">light</div>,
827+
onClose,
828+
closable: { onClose: closableOnClose },
829+
});
830+
}}
831+
/>
832+
{holder}
833+
</>
834+
);
835+
};
836+
837+
const { container: demoContainer, unmount } = render(<Demo />);
838+
fireEvent.click(demoContainer.querySelector('button'));
839+
act(() => {
840+
vi.runAllTimers();
841+
});
842+
expect(closableOnClose).toHaveBeenCalled();
843+
expect(onClose).toHaveBeenCalled();
844+
845+
unmount();
846+
});
847+
it('closable.onClose (config)', () => {
848+
const onClose = vi.fn();
849+
const Demo = () => {
850+
const [api, holder] = useNotification({ closable: { onClose } });
851+
return (
852+
<>
853+
<button
854+
type="button"
855+
onClick={() => {
856+
api.open({
857+
key: 'little',
858+
duration: 1,
859+
content: <div className="context-content">light</div>,
860+
});
861+
}}
862+
/>
863+
{holder}
864+
</>
865+
);
866+
};
867+
868+
const { container: demoContainer, unmount } = render(<Demo />);
869+
fireEvent.click(demoContainer.querySelector('button'));
870+
act(() => {
871+
vi.runAllTimers();
872+
});
873+
expect(onClose).toHaveBeenCalled();
874+
875+
unmount();
876+
});
877+
});
878+
781879
it('closes via keyboard Enter key', () => {
782880
const { instance } = renderDemo();
783881
let closeCount = 0;

0 commit comments

Comments
 (0)