Skip to content

Commit b6d9be8

Browse files
committed
fix: rc-motion ref issue
1 parent 0c71552 commit b6d9be8

File tree

2 files changed

+137
-127
lines changed

2 files changed

+137
-127
lines changed

docs/examples/container.tsx

Lines changed: 81 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -71,96 +71,98 @@ export default () => {
7171
}, []);
7272

7373
return (
74-
<div
75-
id="demo-root"
76-
ref={rootRef}
77-
style={{ background: 'rgba(0, 0, 255, 0.1)', padding: 16 }}
78-
>
79-
<input
80-
type="number"
81-
value={scale}
82-
onChange={(e) => setScale(e.target.value)}
83-
style={{
84-
position: 'fixed',
85-
left: 0,
86-
top: 0,
87-
zIndex: 9999,
88-
}}
89-
/>
74+
<React.StrictMode>
9075
<div
91-
id="demo-holder"
92-
ref={popHolderRef}
93-
style={{
94-
position: 'relative',
95-
width: 0,
96-
height: 0,
97-
zIndex: 999,
98-
// Transform
99-
transform: `scale(${scale})`,
100-
transformOrigin: 'top left',
101-
}}
102-
/>
103-
<div
104-
ref={scrollRef}
105-
style={{
106-
border: '1px solid red',
107-
padding: 10,
108-
height: '100vh',
109-
background: '#FFF',
110-
position: 'relative',
111-
overflow: 'auto',
112-
}}
76+
id="demo-root"
77+
ref={rootRef}
78+
style={{ background: 'rgba(0, 0, 255, 0.1)', padding: 16 }}
11379
>
80+
<input
81+
type="number"
82+
value={scale}
83+
onChange={(e) => setScale(e.target.value)}
84+
style={{
85+
position: 'fixed',
86+
left: 0,
87+
top: 0,
88+
zIndex: 9999,
89+
}}
90+
/>
91+
<div
92+
id="demo-holder"
93+
ref={popHolderRef}
94+
style={{
95+
position: 'relative',
96+
width: 0,
97+
height: 0,
98+
zIndex: 999,
99+
// Transform
100+
transform: `scale(${scale})`,
101+
transformOrigin: 'top left',
102+
}}
103+
/>
114104
<div
105+
ref={scrollRef}
115106
style={{
116-
height: '200vh',
117-
paddingTop: `100vh`,
118-
width: 'calc(300vw)',
119-
display: 'flex',
120-
justifyContent: 'center',
121-
alignItems: 'start',
107+
border: '1px solid red',
108+
padding: 10,
109+
height: '100vh',
110+
background: '#FFF',
111+
position: 'relative',
112+
overflow: 'auto',
122113
}}
123114
>
124-
<Trigger
125-
arrow
126-
forceRender
127-
action="click"
128-
popup={
129-
<div
115+
<div
116+
style={{
117+
height: '200vh',
118+
paddingTop: `100vh`,
119+
width: 'calc(300vw)',
120+
display: 'flex',
121+
justifyContent: 'center',
122+
alignItems: 'start',
123+
}}
124+
>
125+
<Trigger
126+
arrow
127+
// forceRender
128+
action="click"
129+
popup={
130+
<div
131+
style={{
132+
background: 'yellow',
133+
border: '1px solid blue',
134+
width: 200,
135+
height: 60,
136+
opacity: 0.9,
137+
}}
138+
>
139+
Popup
140+
</div>
141+
}
142+
popupStyle={{ boxShadow: '0 0 5px red' }}
143+
// popupVisible
144+
// getPopupContainer={() => popHolderRef.current}
145+
popupPlacement={popupPlacement}
146+
builtinPlacements={builtinPlacements}
147+
stretch="minWidth"
148+
>
149+
<span
130150
style={{
131-
background: 'yellow',
132-
border: '1px solid blue',
133-
width: 200,
134-
height: 60,
151+
display: 'inline-block',
152+
background: 'green',
153+
color: '#FFF',
154+
paddingBlock: 30,
155+
paddingInline: 70,
135156
opacity: 0.9,
157+
transform: 'scale(0.6)',
136158
}}
137159
>
138-
Popup
139-
</div>
140-
}
141-
popupStyle={{ boxShadow: '0 0 5px red' }}
142-
popupVisible
143-
getPopupContainer={() => popHolderRef.current}
144-
popupPlacement={popupPlacement}
145-
builtinPlacements={builtinPlacements}
146-
stretch="minWidth"
147-
>
148-
<span
149-
style={{
150-
display: 'inline-block',
151-
background: 'green',
152-
color: '#FFF',
153-
paddingBlock: 30,
154-
paddingInline: 70,
155-
opacity: 0.9,
156-
transform: 'scale(0.6)',
157-
}}
158-
>
159-
Target
160-
</span>
161-
</Trigger>
160+
Target
161+
</span>
162+
</Trigger>
163+
</div>
162164
</div>
163165
</div>
164-
</div>
166+
</React.StrictMode>
165167
);
166168
};

src/Popup/index.tsx

Lines changed: 56 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { CSSMotionProps } from 'rc-motion';
33
import CSSMotion from 'rc-motion';
44
import ResizeObserver from 'rc-resize-observer';
55
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
6+
import { composeRef } from 'rc-util/lib/ref';
67
import * as React from 'react';
78
import type { TriggerProps } from '../';
89
import type { AlignType } from '../interface';
@@ -180,54 +181,61 @@ const Popup = React.forwardRef<HTMLDivElement, PopupProps>((props, ref) => {
180181
motion={maskMotion}
181182
/>
182183
<ResizeObserver onResize={onAlign} disabled={!open}>
183-
<CSSMotion
184-
motionAppear
185-
motionEnter
186-
motionLeave
187-
removeOnLeave={false}
188-
forceRender={forceRender}
189-
leavedClassName={`${prefixCls}-hidden`}
190-
{...motion}
191-
onAppearPrepare={onPrepare}
192-
onEnterPrepare={onPrepare}
193-
visible={open}
194-
onVisibleChanged={(nextVisible) => {
195-
motion?.onVisibleChanged?.(nextVisible);
196-
onVisibleChanged(nextVisible);
197-
}}
198-
>
199-
{({ className: motionClassName, style: motionStyle }) => {
200-
const cls = classNames(prefixCls, motionClassName, className);
201-
202-
return (
203-
<div
204-
ref={ref}
205-
className={cls}
206-
style={{
207-
...offsetStyle,
208-
...miscStyle,
209-
...motionStyle,
210-
boxSizing: 'border-box',
211-
zIndex,
212-
...style,
213-
}}
214-
onMouseEnter={onMouseEnter}
215-
onMouseLeave={onMouseLeave}
216-
onClick={onClick}
217-
>
218-
{arrow && (
219-
<Arrow
220-
prefixCls={prefixCls}
221-
align={align}
222-
arrowX={arrowX}
223-
arrowY={arrowY}
224-
/>
225-
)}
226-
{childNode}
227-
</div>
228-
);
229-
}}
230-
</CSSMotion>
184+
{(resizeObserverRef) => {
185+
return (
186+
<CSSMotion
187+
motionAppear
188+
motionEnter
189+
motionLeave
190+
removeOnLeave={false}
191+
forceRender={forceRender}
192+
leavedClassName={`${prefixCls}-hidden`}
193+
{...motion}
194+
onAppearPrepare={onPrepare}
195+
onEnterPrepare={onPrepare}
196+
visible={open}
197+
onVisibleChanged={(nextVisible) => {
198+
motion?.onVisibleChanged?.(nextVisible);
199+
onVisibleChanged(nextVisible);
200+
}}
201+
>
202+
{(
203+
{ className: motionClassName, style: motionStyle },
204+
motionRef,
205+
) => {
206+
const cls = classNames(prefixCls, motionClassName, className);
207+
208+
return (
209+
<div
210+
ref={composeRef(resizeObserverRef, ref, motionRef)}
211+
className={cls}
212+
style={{
213+
...offsetStyle,
214+
...miscStyle,
215+
...motionStyle,
216+
boxSizing: 'border-box',
217+
zIndex,
218+
...style,
219+
}}
220+
onMouseEnter={onMouseEnter}
221+
onMouseLeave={onMouseLeave}
222+
onClick={onClick}
223+
>
224+
{arrow && (
225+
<Arrow
226+
prefixCls={prefixCls}
227+
align={align}
228+
arrowX={arrowX}
229+
arrowY={arrowY}
230+
/>
231+
)}
232+
{childNode}
233+
</div>
234+
);
235+
}}
236+
</CSSMotion>
237+
);
238+
}}
231239
</ResizeObserver>
232240
</Portal>
233241
);

0 commit comments

Comments
 (0)