Skip to content

Commit 1a39d8a

Browse files
authored
Merge eb51c83 into 76f3e5d
2 parents 76f3e5d + eb51c83 commit 1a39d8a

File tree

5 files changed

+76
-30
lines changed

5 files changed

+76
-30
lines changed

src/Dialog/Content/Panel.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import React, { useRef } from 'react';
21
import classNames from 'classnames';
3-
import MemoChildren from './MemoChildren';
2+
import { useComposeRef } from 'rc-util/lib/ref';
3+
import React, { useRef } from 'react';
4+
import { RefContext } from '../../context';
45
import type { IDialogPropTypes } from '../../IDialogPropTypes';
6+
import MemoChildren from './MemoChildren';
57

68
const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' };
79

@@ -43,6 +45,10 @@ const Panel = React.forwardRef<ContentRef, PanelProps>((props, ref) => {
4345
} = props;
4446

4547
// ================================= Refs =================================
48+
const { panel: panelRef } = React.useContext(RefContext);
49+
50+
const mergedRef = useComposeRef(holderRef, panelRef);
51+
4652
const sentinelStartRef = useRef<HTMLDivElement>();
4753
const sentinelEndRef = useRef<HTMLDivElement>();
4854

@@ -112,7 +118,7 @@ const Panel = React.forwardRef<ContentRef, PanelProps>((props, ref) => {
112118
role="dialog"
113119
aria-labelledby={title ? ariaId : null}
114120
aria-modal="true"
115-
ref={holderRef}
121+
ref={mergedRef}
116122
style={{
117123
...style,
118124
...contentStyle,

src/DialogWrap.tsx

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import * as React from 'react';
21
import Portal from '@rc-component/portal';
2+
import * as React from 'react';
3+
import { RefContext } from './context';
34
import Dialog from './Dialog';
45
import type { IDialogPropTypes } from './IDialogPropTypes';
56

@@ -13,46 +14,47 @@ import type { IDialogPropTypes } from './IDialogPropTypes';
1314
* */
1415

1516
const DialogWrap: React.FC<IDialogPropTypes> = (props: IDialogPropTypes) => {
16-
const { visible, getContainer, forceRender, destroyOnClose = false, afterClose } = props;
17+
const {
18+
visible,
19+
getContainer,
20+
forceRender,
21+
destroyOnClose = false,
22+
afterClose,
23+
panelRef,
24+
} = props;
1725
const [animatedVisible, setAnimatedVisible] = React.useState<boolean>(visible);
1826

27+
const refContext = React.useMemo(() => ({ panel: panelRef }), [panelRef]);
28+
1929
React.useEffect(() => {
2030
if (visible) {
2131
setAnimatedVisible(true);
2232
}
2333
}, [visible]);
2434

25-
// // 渲染在当前 dom 里;
26-
// if (getContainer === false) {
27-
// return (
28-
// <Dialog
29-
// {...props}
30-
// getOpenCount={() => 2} // 不对 body 做任何操作。。
31-
// />
32-
// );
33-
// }
34-
3535
// Destroy on close will remove wrapped div
3636
if (!forceRender && destroyOnClose && !animatedVisible) {
3737
return null;
3838
}
3939

4040
return (
41-
<Portal
42-
open={visible || forceRender || animatedVisible}
43-
autoDestroy={false}
44-
getContainer={getContainer}
45-
autoLock={visible || animatedVisible}
46-
>
47-
<Dialog
48-
{...props}
49-
destroyOnClose={destroyOnClose}
50-
afterClose={() => {
51-
afterClose?.();
52-
setAnimatedVisible(false);
53-
}}
54-
/>
55-
</Portal>
41+
<RefContext.Provider value={refContext}>
42+
<Portal
43+
open={visible || forceRender || animatedVisible}
44+
autoDestroy={false}
45+
getContainer={getContainer}
46+
autoLock={visible || animatedVisible}
47+
>
48+
<Dialog
49+
{...props}
50+
destroyOnClose={destroyOnClose}
51+
afterClose={() => {
52+
afterClose?.();
53+
setAnimatedVisible(false);
54+
}}
55+
/>
56+
</Portal>
57+
</RefContext.Provider>
5658
);
5759
};
5860

src/IDialogPropTypes.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,7 @@ export type IDialogPropTypes = {
4343
// https://github.com/ant-design/ant-design/issues/19771
4444
// https://github.com/react-component/dialog/issues/95
4545
focusTriggerAfterClose?: boolean;
46+
47+
// Refs
48+
panelRef?: React.Ref<HTMLDivElement>;
4649
};

src/context.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as React from 'react';
2+
3+
export interface RefContextProps {
4+
panel?: React.Ref<HTMLDivElement>;
5+
}
6+
7+
export const RefContext = React.createContext<RefContextProps>({});

tests/ref.spec.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* eslint-disable react/no-render-return-value, max-classes-per-file, func-names, no-console */
2+
import { render } from '@testing-library/react';
3+
import { Provider } from 'rc-motion';
4+
import React from 'react';
5+
import Dialog from '../src';
6+
7+
describe('Dialog.ref', () => {
8+
beforeEach(() => {
9+
jest.useFakeTimers();
10+
});
11+
12+
afterEach(() => {
13+
jest.clearAllTimers();
14+
jest.useRealTimers();
15+
});
16+
17+
it('support panelRef', () => {
18+
const panelRef = React.createRef<HTMLDivElement>();
19+
20+
render(
21+
<Provider motion={false}>
22+
<Dialog panelRef={panelRef} visible />
23+
</Provider>,
24+
);
25+
26+
expect(panelRef.current).toHaveClass('rc-dialog');
27+
});
28+
});

0 commit comments

Comments
 (0)