From fe925792e03dae2d5c9b611a8d15f5fbebd115f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 27 Nov 2025 15:18:25 +0800 Subject: [PATCH 1/2] feat: support render props --- src/index.tsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 68bced35..18671095 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -50,7 +50,9 @@ export interface TriggerRef { // New version will not wrap popup with `rc-trigger-popup-content` when multiple children export interface TriggerProps { - children: React.ReactElement; + children: + | React.ReactElement + | ((info: { open: boolean }) => React.ReactElement); action?: ActionType | ActionType[]; showAction?: ActionType[]; hideAction?: ActionType[]; @@ -261,9 +263,6 @@ export function generateTrigger( } }); - // ========================== Children ========================== - const child = React.Children.only(children); - const originChildProps = child?.props || {}; const cloneProps: Pick< React.HTMLAttributes, | 'onClick' @@ -311,6 +310,17 @@ export function generateTrigger( // Render still use props as first priority const mergedOpen = popupVisible ?? internalOpen; + // ========================== Children ========================== + const child = React.useMemo(() => { + const nextChild = + typeof children === 'function' + ? children({ open: mergedOpen }) + : children; + return React.Children.only(nextChild); + }, [children, mergedOpen]); + + const originChildProps = child?.props || {}; + // We use effect sync here in case `popupVisible` back to `undefined` const setMergedOpen = useEvent((nextOpen: boolean) => { if (openUncontrolled) { From 907e79854d809534931b7ece2a2f1d3cfaa76086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 27 Nov 2025 15:21:17 +0800 Subject: [PATCH 2/2] test: add test case --- tests/basic.test.jsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/basic.test.jsx b/tests/basic.test.jsx index 04d274b3..c42f155d 100644 --- a/tests/basic.test.jsx +++ b/tests/basic.test.jsx @@ -368,6 +368,22 @@ describe('Trigger.Basic', () => { }); }); + describe('children renderProps', () => { + it('should get current open', () => { + const { container } = render( + Hello!} + > + {({ open }) => } + , + ); + + const button = container.querySelector('button'); + expect(button.textContent).toBe('true'); + }); + }); + describe('destroyPopupOnHide', () => { it('defaults to false', () => { const { container } = render(