Skip to content

Commit 5273538

Browse files
committed
chore: demo update
1 parent 91b66bd commit 5273538

2 files changed

Lines changed: 59 additions & 24 deletions

File tree

docs/examples/two-buttons.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ const MovingPopupDemo = () => {
2727
const [useUniqueProvider, setUseUniqueProvider] = useState(true);
2828
const [triggerControl, setTriggerControl] = useState('none'); // 'button1', 'button2', 'none'
2929

30+
const getVisible = (name: string) => {
31+
if (triggerControl === 'none') {
32+
return undefined;
33+
}
34+
if (triggerControl === name) {
35+
return true;
36+
}
37+
return false;
38+
};
39+
3040
const content = (
3141
<div style={{ margin: 100 }}>
3242
<div style={{ display: 'flex', gap: 20 }}>
@@ -35,7 +45,7 @@ const MovingPopupDemo = () => {
3545
action={['hover']}
3646
popupPlacement="top"
3747
builtinPlacements={builtinPlacements}
38-
popupVisible={triggerControl === 'button1' || undefined}
48+
popupVisible={getVisible('button1')}
3949
popupMotion={{
4050
motionName: 'rc-trigger-popup-zoom',
4151
}}
@@ -55,7 +65,7 @@ const MovingPopupDemo = () => {
5565
action={['hover']}
5666
popupPlacement="top"
5767
builtinPlacements={builtinPlacements}
58-
popupVisible={triggerControl === 'button2' || undefined}
68+
popupVisible={getVisible('button2')}
5969
popupMotion={{
6070
motionName: 'rc-trigger-popup-zoom',
6171
}}

src/index.tsx

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ export function generateTrigger(
193193
} = props;
194194

195195
const mergedAutoDestroy = autoDestroy || false;
196+
const openUncontrolled = popupVisible === undefined;
196197

197198
// =========================== Mobile ===========================
198199
const isMobile = !!mobile;
@@ -289,7 +290,7 @@ export function generateTrigger(
289290

290291
// We use effect sync here in case `popupVisible` back to `undefined`
291292
const setMergedOpen = useEvent((nextOpen: boolean) => {
292-
if (popupVisible === undefined) {
293+
if (openUncontrolled) {
293294
setInternalOpen(nextOpen);
294295
}
295296
});
@@ -298,6 +299,38 @@ export function generateTrigger(
298299
setInternalOpen(popupVisible || false);
299300
}, [popupVisible]);
300301

302+
// Extract common options for UniqueProvider
303+
const getUniqueOptions = useEvent((delay: number = 0) => ({
304+
popup,
305+
target: targetEle,
306+
delay,
307+
prefixCls,
308+
popupClassName,
309+
popupStyle,
310+
popupPlacement,
311+
builtinPlacements,
312+
popupAlign,
313+
zIndex,
314+
mask,
315+
maskClosable,
316+
popupMotion,
317+
maskMotion,
318+
arrow,
319+
getPopupContainer,
320+
}));
321+
322+
// Handle controlled state changes for UniqueProvider
323+
// Only sync to UniqueProvider when it's controlled mode
324+
useLayoutEffect(() => {
325+
if (uniqueContext && targetEle && !openUncontrolled) {
326+
if (mergedOpen) {
327+
uniqueContext.show(getUniqueOptions(0));
328+
} else {
329+
uniqueContext.hide(0);
330+
}
331+
}
332+
}, [mergedOpen]);
333+
301334
const openRef = React.useRef(mergedOpen);
302335
openRef.current = mergedOpen;
303336

@@ -324,27 +357,19 @@ export function generateTrigger(
324357
const delayInvoke = useDelay();
325358

326359
const triggerOpen = (nextOpen: boolean, delay = 0) => {
327-
// If UniqueContext exists, pass delay to Provider instead of handling it internally
328-
if (uniqueContext) {
329-
if (nextOpen && targetEle) {
330-
uniqueContext.show({
331-
popup,
332-
target: targetEle,
333-
delay,
334-
prefixCls,
335-
popupClassName,
336-
popupStyle,
337-
popupPlacement,
338-
builtinPlacements,
339-
popupAlign,
340-
zIndex,
341-
mask,
342-
maskClosable,
343-
popupMotion,
344-
maskMotion,
345-
arrow,
346-
getPopupContainer,
347-
});
360+
// If it's controlled mode, always use internal trigger logic
361+
// UniqueProvider will be synced through useLayoutEffect
362+
if (popupVisible !== undefined) {
363+
delayInvoke(() => {
364+
internalTriggerOpen(nextOpen);
365+
}, delay);
366+
return;
367+
}
368+
369+
// If UniqueContext exists and not controlled, pass delay to Provider instead of handling it internally
370+
if (uniqueContext && openUncontrolled) {
371+
if (nextOpen) {
372+
uniqueContext.show(getUniqueOptions(delay));
348373
} else {
349374
uniqueContext.hide(delay);
350375
}

0 commit comments

Comments
 (0)