Skip to content

Commit 855dfe9

Browse files
authored
update destroyOnClose to destroyOnHidden (#475)
* update destroyOnClose to destroyOnHidden * update destroyOnClose to destroyOnHidden * update destroyOnClose to destroyOnHidden * update destroyOnClose to destroyOnHidden
1 parent afb8649 commit 855dfe9

File tree

12 files changed

+84
-77
lines changed

12 files changed

+84
-77
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ coverage
3434
/android/
3535
yarn.lock
3636
package-lock.json
37+
pnpm-lock.yaml
3738
.storybook
3839
.doc
3940

@@ -48,4 +49,4 @@ package-lock.json
4849
.dumi/tmp
4950
.dumi/tmp-production
5051

51-
bun.lockb
52+
bun.lockb

README.md

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -49,34 +49,34 @@ ReactDOM.render(
4949

5050
### rc-dialog
5151

52-
| Name | Type | Default | Description | Version |
53-
| ---------------------- | ------------------------------ | --------- | ------------------------------------------------------------------------------- | ------- |
54-
| prefixCls | String | rc-dialog | The dialog dom node's prefixCls | |
55-
| className | String | | additional className for dialog | |
56-
| classNames | { header?: string; body?: string; footer?: string; mask?: string; content?: string; wrapper?: string; } | | pass className to target area | |
57-
| styles | { header?: CSSProperties; body?: CSSProperties; footer?: CSSProperties; mask?: CSSProperties; content?: CSSProperties; wrapper?: CSSProperties; } | | pass styles to target area | |
58-
| style | Object | {} | Root style for dialog element.Such as width, height | |
59-
| zIndex | Number | | | |
60-
| visible | Boolean | false | current dialog's visible status | |
61-
| animation | String | | part of dialog animation css class name | |
62-
| maskAnimation | String | | part of dialog's mask animation css class name | |
63-
| transitionName | String | | dialog animation css class name | |
64-
| maskTransitionName | String | | mask animation css class name | |
65-
| title | String\|React.Element | | Title of the dialog | |
66-
| footer | React.Element | | footer of the dialog | |
67-
| closable | Boolean \| ({ closeIcon?: React.ReactNode; disabled?: boolean } & React.AriaAttributes | true | whether show close button | |
68-
| mask | Boolean | true | whether show mask | |
69-
| maskClosable | Boolean | true | whether click mask to close | |
70-
| keyboard | Boolean | true | whether support press esc to close | |
71-
| mousePosition | {x:number,y:number} | | set pageX and pageY of current mouse(it will cause transform origin to be set). | |
72-
| onClose | function() | | called when click close button or mask | |
73-
| afterClose | function() | | called when close animation end | |
74-
| getContainer | function(): HTMLElement | | to determine where Dialog will be mounted | |
75-
| destroyOnClose | Boolean | false | to unmount child compenents on onClose | |
76-
| closeIcon | ReactNode | | specific the close icon. | |
77-
| forceRender | Boolean | false | Create dialog dom node before dialog first show | |
78-
| focusTriggerAfterClose | Boolean | true | focus trigger element when dialog closed | |
79-
| modalRender | (node: ReactNode) => ReactNode | | Custom modal content render | 8.3.0 |
52+
| Name | Type | Default | Description | Version |
53+
| --- | --- | --- | --- | --- |
54+
| prefixCls | String | rc-dialog | The dialog dom node's prefixCls | |
55+
| className | String | | additional className for dialog | |
56+
| classNames | { header?: string; body?: string; footer?: string; mask?: string; content?: string; wrapper?: string; } | | pass className to target area | |
57+
| styles | { header?: CSSProperties; body?: CSSProperties; footer?: CSSProperties; mask?: CSSProperties; content?: CSSProperties; wrapper?: CSSProperties; } | | pass styles to target area | |
58+
| style | Object | {} | Root style for dialog element.Such as width, height | |
59+
| zIndex | Number | | | |
60+
| visible | Boolean | false | current dialog's visible status | |
61+
| animation | String | | part of dialog animation css class name | |
62+
| maskAnimation | String | | part of dialog's mask animation css class name | |
63+
| transitionName | String | | dialog animation css class name | |
64+
| maskTransitionName | String | | mask animation css class name | |
65+
| title | String\|React.Element | | Title of the dialog | |
66+
| footer | React.Element | | footer of the dialog | |
67+
| closable | Boolean \| ({ closeIcon?: React.ReactNode; disabled?: boolean } & React.AriaAttributes | true | whether show close button | |
68+
| mask | Boolean | true | whether show mask | |
69+
| maskClosable | Boolean | true | whether click mask to close | |
70+
| keyboard | Boolean | true | whether support press esc to close | |
71+
| mousePosition | {x:number,y:number} | | set pageX and pageY of current mouse(it will cause transform origin to be set). | |
72+
| onClose | function() | | called when click close button or mask | |
73+
| afterClose | function() | | called when close animation end | |
74+
| getContainer | function(): HTMLElement | | to determine where Dialog will be mounted | |
75+
| destroyOnHidden | Boolean | false | to unmount child compenents on onClose | |
76+
| closeIcon | ReactNode | | specific the close icon. | |
77+
| forceRender | Boolean | false | Create dialog dom node before dialog first show | |
78+
| focusTriggerAfterClose | Boolean | true | focus trigger element when dialog closed | |
79+
| modalRender | (node: ReactNode) => ReactNode | | Custom modal content render | 8.3.0 |
8080

8181
## Development
8282

@@ -85,8 +85,6 @@ npm install
8585
npm start
8686
```
8787

88-
89-
9088
## Test Case
9189

9290
```
@@ -102,7 +100,6 @@ npm run coverage
102100

103101
open coverage/ dir
104102

105-
106103
## License
107104

108105
rc-dialog is released under the MIT license.

docs/examples/ant-design.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const MyControl: React.FC = () => {
3131
const [visible2, setVisible2] = React.useState(false);
3232
const [visible3, setVisible3] = React.useState(false);
3333
const [width, setWidth] = React.useState(600);
34-
const [destroyOnClose, setDestroyOnClose] = React.useState(false);
34+
const [destroyOnHidden, setDestroyOnHidden] = React.useState(false);
3535
const [center, setCenter] = React.useState(false);
3636
const [mousePosition, setMousePosition] = React.useState({ x: null, y: null });
3737
const [useIcon, setUseIcon] = React.useState(false);
@@ -60,8 +60,8 @@ const MyControl: React.FC = () => {
6060
setVisible3(false);
6161
};
6262

63-
const onDestroyOnCloseChange = (e: React.ChangeEvent<HTMLInputElement>) => {
64-
setDestroyOnClose(e.target.checked);
63+
const onDestroyOnHiddenChange = (e: React.ChangeEvent<HTMLInputElement>) => {
64+
setDestroyOnHidden(e.target.checked);
6565
};
6666

6767
const onForceRenderChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -97,7 +97,7 @@ const MyControl: React.FC = () => {
9797
style={style}
9898
title="dialog1"
9999
mousePosition={mousePosition}
100-
destroyOnClose={destroyOnClose}
100+
destroyOnHidden={destroyOnHidden}
101101
closeIcon={useIcon ? getSvg(clearPath, {}, true) : undefined}
102102
forceRender={forceRender}
103103
focusTriggerAfterClose={false}
@@ -210,8 +210,8 @@ const MyControl: React.FC = () => {
210210
</button>
211211
&nbsp;
212212
<label>
213-
destroy on close:
214-
<input type="checkbox" checked={destroyOnClose} onChange={onDestroyOnCloseChange} />
213+
destroy on hidden:
214+
<input type="checkbox" checked={destroyOnHidden} onChange={onDestroyOnHiddenChange} />
215215
</label>
216216
&nbsp;
217217
<label>

docs/examples/bootstrap.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const InnerRender: React.FC = () => {
1111

1212
const MyControl: React.FC = () => {
1313
const [visible, setVisible] = React.useState(false);
14-
const [destroyOnClose, setDestroyOnClose] = React.useState(false);
14+
const [destroyOnHidden, setDestroyOnHidden] = React.useState(false);
1515

1616
const onClick = () => {
1717
setVisible(true);
@@ -21,14 +21,14 @@ const MyControl: React.FC = () => {
2121
setVisible(false);
2222
};
2323

24-
const onDestroyOnCloseChange = (e: React.ChangeEvent<HTMLInputElement>) => {
25-
setDestroyOnClose(e.target.checked);
24+
const onDestroyOnHiddenChange = (e: React.ChangeEvent<HTMLInputElement>) => {
25+
setDestroyOnHidden(e.target.checked);
2626
};
2727

2828
const dialog = (
2929
<Dialog
3030
visible={visible}
31-
destroyOnClose={destroyOnClose}
31+
destroyOnHidden={destroyOnHidden}
3232
animation="slide-fade"
3333
maskAnimation="fade"
3434
onClose={onClose}
@@ -120,8 +120,8 @@ const MyControl: React.FC = () => {
120120
</button>
121121
&nbsp;
122122
<label>
123-
destroy on close:
124-
<input type="checkbox" checked={destroyOnClose} onChange={onDestroyOnCloseChange} />
123+
destroy on hidden:
124+
<input type="checkbox" checked={destroyOnHidden} onChange={onDestroyOnHiddenChange} />
125125
</label>
126126
</p>
127127
{dialog}

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,16 @@
5757
},
5858
"devDependencies": {
5959
"@rc-component/drawer": "^1.0.0",
60-
"@rc-component/select": "^1.0.0",
6160
"@rc-component/father-plugin": "^2.0.2",
6261
"@rc-component/np": "^1.0.3",
62+
"@rc-component/select": "^1.0.0",
6363
"@testing-library/jest-dom": "^6.1.6",
6464
"@testing-library/react": "^13.0.0",
6565
"@types/jest": "^29.4.0",
6666
"@types/keyv": "3.1.4",
67-
"@types/react": "^18.0.24",
68-
"@types/react-dom": "^18.0.8",
67+
"@types/node": "^22.15.18",
68+
"@types/react": "^19.1.4",
69+
"@types/react-dom": "^19.1.5",
6970
"@umijs/fabric": "^3.0.0",
7071
"bootstrap": "^4.3.1",
7172
"cheerio": "1.0.0-rc.12",

src/Dialog/Content/MemoChildren.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ export type MemoChildrenProps = {
66
};
77

88
export default React.memo(
9-
({ children }: MemoChildrenProps) => children as React.ReactElement,
9+
({ children }: MemoChildrenProps) => children as React.ReactElement<any>,
1010
(_, { shouldUpdate }) => !shouldUpdate,
1111
);

src/Dialog/Content/Panel.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,16 @@ import type { IDialogPropTypes } from '../../IDialogPropTypes';
66
import MemoChildren from './MemoChildren';
77
import pickAttrs from '@rc-component/util/lib/pickAttrs';
88

9-
const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' };
10-
const entityStyle = { outline: 'none' };
9+
const sentinelStyle: React.CSSProperties = {
10+
width: 0,
11+
height: 0,
12+
overflow: 'hidden',
13+
outline: 'none',
14+
};
15+
16+
const entityStyle: React.CSSProperties = {
17+
outline: 'none',
18+
};
1119

1220
export interface PanelProps extends Omit<IDialogPropTypes, 'getOpenCount'> {
1321
prefixCls: string;
@@ -53,8 +61,8 @@ const Panel = React.forwardRef<PanelRef, PanelProps>((props, ref) => {
5361

5462
const mergedRef = useComposeRef(holderRef, panelRef);
5563

56-
const sentinelStartRef = useRef<HTMLDivElement>();
57-
const sentinelEndRef = useRef<HTMLDivElement>();
64+
const sentinelStartRef = useRef<HTMLDivElement>(null);
65+
const sentinelEndRef = useRef<HTMLDivElement>(null);
5866

5967
React.useImperativeHandle(ref, () => ({
6068
focus: () => {

src/Dialog/Content/index.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,16 @@ const Content = React.forwardRef<ContentRef, ContentProps>((props, ref) => {
2525
className,
2626
visible,
2727
forceRender,
28-
destroyOnClose,
28+
destroyOnHidden,
2929
motionName,
3030
ariaId,
3131
onVisibleChanged,
3232
mousePosition,
3333
} = props;
3434

35-
const dialogRef = useRef<
36-
{
37-
nativeElement: HTMLElement;
38-
} & CSSMotionStateRef
39-
>();
35+
const dialogRef = useRef<{ nativeElement: HTMLElement } & CSSMotionStateRef>(null);
4036

41-
const panelRef = useRef<PanelRef>();
37+
const panelRef = useRef<PanelRef>(null);
4238

4339
// ============================== Refs ==============================
4440
React.useImperativeHandle(ref, () => ({
@@ -74,7 +70,7 @@ const Content = React.forwardRef<ContentRef, ContentProps>((props, ref) => {
7470
onEnterPrepare={onPrepare}
7571
forceRender={forceRender}
7672
motionName={motionName}
77-
removeOnLeave={destroyOnClose}
73+
removeOnLeave={destroyOnHidden}
7874
ref={dialogRef}
7975
>
8076
{({ className: motionClassName, style: motionStyle }, motionRef) => (
@@ -93,6 +89,8 @@ const Content = React.forwardRef<ContentRef, ContentProps>((props, ref) => {
9389
);
9490
});
9591

96-
Content.displayName = 'Content';
92+
if (process.env.NODE_ENV !== 'production') {
93+
Content.displayName = 'Content';
94+
}
9795

9896
export default Content;

src/Dialog/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ const Dialog: React.FC<IDialogPropTypes> = (props) => {
5555
}
5656
}
5757

58-
const lastOutSideActiveElementRef = useRef<HTMLElement>();
59-
const wrapperRef = useRef<HTMLDivElement>();
60-
const contentRef = useRef<ContentRef>();
58+
const lastOutSideActiveElementRef = useRef<HTMLElement>(null);
59+
const wrapperRef = useRef<HTMLDivElement>(null);
60+
const contentRef = useRef<ContentRef>(null);
6161

6262
const [animatedVisible, setAnimatedVisible] = React.useState(visible);
6363

@@ -115,7 +115,7 @@ const Dialog: React.FC<IDialogPropTypes> = (props) => {
115115

116116
// >>> Content
117117
const contentClickRef = useRef(false);
118-
const contentTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
118+
const contentTimeoutRef = useRef<ReturnType<typeof setTimeout>>(null);
119119

120120
// We need record content click incase content popup out of dialog
121121
const onContentMouseDown: React.MouseEventHandler = () => {

src/DialogWrap.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const DialogWrap: React.FC<IDialogPropTypes> = (props) => {
1818
visible,
1919
getContainer,
2020
forceRender,
21-
destroyOnClose = false,
21+
destroyOnHidden = false,
2222
afterClose,
2323
panelRef,
2424
} = props;
@@ -33,7 +33,7 @@ const DialogWrap: React.FC<IDialogPropTypes> = (props) => {
3333
}, [visible]);
3434

3535
// Destroy on close will remove wrapped div
36-
if (!forceRender && destroyOnClose && !animatedVisible) {
36+
if (!forceRender && destroyOnHidden && !animatedVisible) {
3737
return null;
3838
}
3939

@@ -47,7 +47,7 @@ const DialogWrap: React.FC<IDialogPropTypes> = (props) => {
4747
>
4848
<Dialog
4949
{...props}
50-
destroyOnClose={destroyOnClose}
50+
destroyOnHidden={destroyOnHidden}
5151
afterClose={() => {
5252
afterClose?.();
5353
setAnimatedVisible(false);
@@ -58,6 +58,8 @@ const DialogWrap: React.FC<IDialogPropTypes> = (props) => {
5858
);
5959
};
6060

61-
DialogWrap.displayName = 'Dialog';
61+
if (process.env.NODE_ENV !== 'production') {
62+
DialogWrap.displayName = 'Dialog';
63+
}
6264

6365
export default DialogWrap;

src/IDialogPropTypes.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export type IDialogPropTypes = {
2020
closable?: boolean | ({ closeIcon?: React.ReactNode; disabled?: boolean } & React.AriaAttributes);
2121
maskClosable?: boolean;
2222
visible?: boolean;
23-
destroyOnClose?: boolean;
23+
destroyOnHidden?: boolean;
2424
mousePosition?: {
2525
x: number;
2626
y: number;

tests/index.spec.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ describe('dialog', () => {
113113
expect(onClose).toHaveBeenCalledTimes(1);
114114
});
115115

116-
describe('destroyOnClose', () => {
116+
describe('destroyOnHidden', () => {
117117
it('default is false', () => {
118118
const { rerender } = render(
119119
<Dialog visible>
@@ -128,8 +128,8 @@ describe('dialog', () => {
128128
});
129129

130130
it('destroy on hide should unmount child components on close', () => {
131-
const Demo = (props?: Partial<DialogProps>) => (
132-
<Dialog destroyOnClose {...props}>
131+
const Demo: React.FC<Partial<DialogProps>> = (props) => (
132+
<Dialog destroyOnHidden {...props}>
133133
<input className="test-input" />
134134
</Dialog>
135135
);
@@ -384,7 +384,7 @@ describe('dialog', () => {
384384
render(
385385
<Dialog
386386
visible
387-
modalRender={(node: React.ReactElement) =>
387+
modalRender={(node: React.ReactElement<any>) =>
388388
cloneElement(node, { ...node.props, style: { background: '#1890ff' } })
389389
}
390390
/>,
@@ -394,7 +394,7 @@ describe('dialog', () => {
394394

395395
describe('focusTriggerAfterClose', () => {
396396
it('should focus trigger after close dialog', () => {
397-
const Demo = () => {
397+
const Demo: React.FC = () => {
398398
const [visible, setVisible] = React.useState(false);
399399
return (
400400
<>
@@ -417,9 +417,9 @@ describe('dialog', () => {
417417
});
418418

419419
it('should focus trigger after close dialog when contains focusable element', () => {
420-
const Demo = () => {
420+
const Demo: React.FC = () => {
421421
const [visible, setVisible] = React.useState(false);
422-
const inputRef = React.useRef(null);
422+
const inputRef = React.useRef<HTMLInputElement>(null);
423423
useEffect(() => {
424424
inputRef.current?.focus();
425425
}, []);

0 commit comments

Comments
 (0)