Skip to content

Commit 6c6da53

Browse files
authored
feat: children support renderProps (#591)
* feat: support render props * test: add test case
1 parent ff89971 commit 6c6da53

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/index.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ export interface TriggerRef {
5050
// New version will not wrap popup with `rc-trigger-popup-content` when multiple children
5151

5252
export interface TriggerProps {
53-
children: React.ReactElement<any>;
53+
children:
54+
| React.ReactElement<any>
55+
| ((info: { open: boolean }) => React.ReactElement<any>);
5456
action?: ActionType | ActionType[];
5557
showAction?: ActionType[];
5658
hideAction?: ActionType[];
@@ -261,9 +263,6 @@ export function generateTrigger(
261263
}
262264
});
263265

264-
// ========================== Children ==========================
265-
const child = React.Children.only(children);
266-
const originChildProps = child?.props || {};
267266
const cloneProps: Pick<
268267
React.HTMLAttributes<HTMLElement>,
269268
| 'onClick'
@@ -311,6 +310,17 @@ export function generateTrigger(
311310
// Render still use props as first priority
312311
const mergedOpen = popupVisible ?? internalOpen;
313312

313+
// ========================== Children ==========================
314+
const child = React.useMemo(() => {
315+
const nextChild =
316+
typeof children === 'function'
317+
? children({ open: mergedOpen })
318+
: children;
319+
return React.Children.only(nextChild);
320+
}, [children, mergedOpen]);
321+
322+
const originChildProps = child?.props || {};
323+
314324
// We use effect sync here in case `popupVisible` back to `undefined`
315325
const setMergedOpen = useEvent((nextOpen: boolean) => {
316326
if (openUncontrolled) {

tests/basic.test.jsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,22 @@ describe('Trigger.Basic', () => {
368368
});
369369
});
370370

371+
describe('children renderProps', () => {
372+
it('should get current open', () => {
373+
const { container } = render(
374+
<Trigger
375+
popupVisible={true}
376+
popup={<span>Hello!</span>}
377+
>
378+
{({ open }) => <button>{String(open)}</button>}
379+
</Trigger>,
380+
);
381+
382+
const button = container.querySelector('button');
383+
expect(button.textContent).toBe('true');
384+
});
385+
});
386+
371387
describe('destroyPopupOnHide', () => {
372388
it('defaults to false', () => {
373389
const { container } = render(

0 commit comments

Comments
 (0)