diff --git a/components/watermark/__tests__/index.test.tsx b/components/watermark/__tests__/index.test.tsx index ca5b465650..0a26083ffe 100644 --- a/components/watermark/__tests__/index.test.tsx +++ b/components/watermark/__tests__/index.test.tsx @@ -192,4 +192,25 @@ describe('Watermark', () => { expect(spy).not.toHaveBeenCalledWith(expect.anything(), 0, -0); spy.mockRestore(); }); + + it('should call onRemove when watermark is hard removed', async () => { + const onRemove = jest.fn(); + const { container } = render(); + await waitFakeTimer(); + + const watermarkEle = container.querySelector('[style*="background-image"]'); + watermarkEle?.remove(); + await waitFakeTimer(); + + expect(onRemove).toHaveBeenCalledTimes(1); + }); + + it('should not call onRemove when unmount', async () => { + const onRemove = jest.fn(); + const { unmount } = render(); + await waitFakeTimer(); + unmount(); + await waitFakeTimer(); + expect(onRemove).not.toHaveBeenCalled(); + }); }); diff --git a/components/watermark/index.en-US.md b/components/watermark/index.en-US.md index 5fe416fe72..c8a81d40fc 100644 --- a/components/watermark/index.en-US.md +++ b/components/watermark/index.en-US.md @@ -44,6 +44,7 @@ Common props ref:[Common props](/docs/react/common-props) | font | Text style | [Font](#font) | [Font](#font) | | | gap | The spacing between watermarks | \[number, number\] | \[100, 100\] | | | offset | The offset of the watermark from the upper left corner of the container. The default is `gap/2` | \[number, number\] | \[gap\[0\]/2, gap\[1\]/2\] | | +| onRemove | Callback when the watermark is removed by DOM mutation | `() => void` | - | | ### Font diff --git a/components/watermark/index.tsx b/components/watermark/index.tsx index a1552173ed..ebc784f9f8 100644 --- a/components/watermark/index.tsx +++ b/components/watermark/index.tsx @@ -36,6 +36,7 @@ export interface WatermarkProps { offset?: [number, number]; children?: React.ReactNode; inherit?: boolean; + onRemove?: () => void; } /** @@ -74,6 +75,7 @@ const Watermark: React.FC = (props) => { offset, children, inherit = true, + onRemove, } = props; const { className: contextClassName, style: contextStyle } = useComponentConfig('watermark'); @@ -222,7 +224,7 @@ const Watermark: React.FC = (props) => { // ============================= Effect ============================= // Append watermark to the container - const [appendWatermark, removeWatermark, isWatermarkEle] = useWatermark(markStyle); + const [appendWatermark, removeWatermark, isWatermarkEle] = useWatermark(markStyle, onRemove); useEffect(() => { if (watermarkInfo) { diff --git a/components/watermark/index.zh-CN.md b/components/watermark/index.zh-CN.md index 87c1341348..b401e70704 100644 --- a/components/watermark/index.zh-CN.md +++ b/components/watermark/index.zh-CN.md @@ -45,6 +45,7 @@ tag: 5.1.0 | font | 文字样式 | [Font](#font) | [Font](#font) | | | gap | 水印之间的间距 | \[number, number\] | \[100, 100\] | | | offset | 水印距离容器左上角的偏移量,默认为 `gap/2` | \[number, number\] | \[gap\[0\]/2, gap\[1\]/2\] | | +| onRemove | 水印因 DOM 变更被移除时触发的回调 | `() => void` | - | | ### Font diff --git a/components/watermark/useWatermark.ts b/components/watermark/useWatermark.ts index 7e21c0c6b5..1820fb7809 100644 --- a/components/watermark/useWatermark.ts +++ b/components/watermark/useWatermark.ts @@ -1,4 +1,5 @@ import * as React from 'react'; +import { useEvent } from '@rc-component/util'; import { getStyleStr } from './utils'; @@ -22,16 +23,20 @@ export type AppendWatermark = ( export default function useWatermark( markStyle: React.CSSProperties, + onRemove?: () => void, ): [ appendWatermark: AppendWatermark, removeWatermark: (container: HTMLElement) => void, isWatermarkEle: (ele: Node) => boolean, ] { const watermarkMap = React.useRef(new Map()); + const onRemoveEvent = useEvent(onRemove); const appendWatermark = (base64Url: string, markWidth: number, container: HTMLElement) => { if (container) { - if (!watermarkMap.current.get(container)) { + const exist = watermarkMap.current.get(container); + + if (!exist) { const newWatermarkEle = document.createElement('div'); watermarkMap.current.set(container, newWatermarkEle); } @@ -52,6 +57,9 @@ export default function useWatermark( watermarkEle.removeAttribute('hidden'); if (watermarkEle.parentElement !== container) { + if (exist && onRemove) { + onRemoveEvent(); + } container.append(watermarkEle); } } diff --git a/package.json b/package.json index 1126b1bfac..864a17cfd8 100644 --- a/package.json +++ b/package.json @@ -151,7 +151,7 @@ "@rc-component/tree-select": "~1.3.0", "@rc-component/trigger": "^3.6.15", "@rc-component/upload": "~1.1.0", - "@rc-component/util": "^1.3.0", + "@rc-component/util": "^1.3.1", "clsx": "^2.1.1", "dayjs": "^1.11.11", "scroll-into-view-if-needed": "^3.1.0",