From 128def033b7ece89949c70021d269ca74cc5dea6 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, 15 Jan 2026 14:58:42 +0800 Subject: [PATCH 1/3] chore: init --- package.json | 2 +- src/index.tsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5416c8ce..da20cf94 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "dependencies": { "@rc-component/motion": "^1.1.4", "@rc-component/portal": "^2.2.0", - "@rc-component/resize-observer": "^1.0.0", + "@rc-component/resize-observer": "^1.1.0", "@rc-component/util": "^1.2.1", "clsx": "^2.1.1" }, diff --git a/src/index.tsx b/src/index.tsx index 027f882a..7b500c8c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,7 +1,8 @@ import Portal from '@rc-component/portal'; import { clsx } from 'clsx'; import type { CSSMotionProps } from '@rc-component/motion'; -import ResizeObserver from '@rc-component/resize-observer'; +// TODO: Replace ResizeObserver with useResizeObserver +import ResizeObserver, { useResizeObserver } from '@rc-component/resize-observer'; import { isDOM } from '@rc-component/util/lib/Dom/findDOMNode'; import { getShadowRoot } from '@rc-component/util/lib/Dom/shadow'; import useEvent from '@rc-component/util/lib/hooks/useEvent'; From e49ff2d29bb8cec26f8122dfbefa4052bf9c1b24 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, 15 Jan 2026 15:13:03 +0800 Subject: [PATCH 2/3] chore: refactor --- package.json | 2 +- src/index.tsx | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index da20cf94..72fddc49 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "dependencies": { "@rc-component/motion": "^1.1.4", "@rc-component/portal": "^2.2.0", - "@rc-component/resize-observer": "^1.1.0", + "@rc-component/resize-observer": "^1.1.1", "@rc-component/util": "^1.2.1", "clsx": "^2.1.1" }, diff --git a/src/index.tsx b/src/index.tsx index 7b500c8c..61cf3ddb 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,10 +1,10 @@ import Portal from '@rc-component/portal'; import { clsx } from 'clsx'; import type { CSSMotionProps } from '@rc-component/motion'; -// TODO: Replace ResizeObserver with useResizeObserver -import ResizeObserver, { useResizeObserver } from '@rc-component/resize-observer'; +import { useResizeObserver } from '@rc-component/resize-observer'; import { isDOM } from '@rc-component/util/lib/Dom/findDOMNode'; import { getShadowRoot } from '@rc-component/util/lib/Dom/shadow'; +import { useComposeRef } from '@rc-component/util/lib/ref'; import useEvent from '@rc-component/util/lib/hooks/useEvent'; import useId from '@rc-component/util/lib/hooks/useId'; import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect'; @@ -783,8 +783,17 @@ export function generateTrigger( y: arrowY, }; + // =================== Resize Observer =================== + // Use hook to observe target element resize + // Pass targetEle directly instead of a function so the hook will re-observe when target changes + useResizeObserver(mergedOpen, targetEle, onTargetResize); + + // Compose refs + const mergedRef = useComposeRef(setTargetRef, (child as any).ref); + // Child Node const triggerNode = React.cloneElement(child, { + ref: mergedRef, ...mergedChildrenProps, ...passedProps, }); @@ -792,13 +801,7 @@ export function generateTrigger( // Render return ( <> - - {triggerNode} - + {triggerNode} {rendedRef.current && (!uniqueContext || !unique) && ( Date: Thu, 15 Jan 2026 15:30:39 +0800 Subject: [PATCH 3/3] chore: get dom --- src/index.tsx | 16 +++++++++------- tests/ref.test.tsx | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 61cf3ddb..4cad2655 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,9 +2,9 @@ import Portal from '@rc-component/portal'; import { clsx } from 'clsx'; import type { CSSMotionProps } from '@rc-component/motion'; import { useResizeObserver } from '@rc-component/resize-observer'; -import { isDOM } from '@rc-component/util/lib/Dom/findDOMNode'; +import { getDOM, isDOM } from '@rc-component/util/lib/Dom/findDOMNode'; import { getShadowRoot } from '@rc-component/util/lib/Dom/shadow'; -import { useComposeRef } from '@rc-component/util/lib/ref'; +import { getNodeRef, useComposeRef } from '@rc-component/util/lib/ref'; import useEvent from '@rc-component/util/lib/hooks/useEvent'; import useId from '@rc-component/util/lib/hooks/useId'; import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect'; @@ -262,9 +262,11 @@ export function generateTrigger( const externalForwardRef = React.useRef(null); const setTargetRef = useEvent((node: HTMLElement) => { - if (isDOM(node) && targetEle !== node) { - setTargetEle(node); - externalForwardRef.current = node; + const domNode = getDOM(node) as HTMLElement; + + if (isDOM(domNode) && targetEle !== domNode) { + setTargetEle(domNode); + externalForwardRef.current = domNode; } }); @@ -789,13 +791,13 @@ export function generateTrigger( useResizeObserver(mergedOpen, targetEle, onTargetResize); // Compose refs - const mergedRef = useComposeRef(setTargetRef, (child as any).ref); + const mergedRef = useComposeRef(setTargetRef, getNodeRef(child)); // Child Node const triggerNode = React.cloneElement(child, { - ref: mergedRef, ...mergedChildrenProps, ...passedProps, + ref: mergedRef, }); // Render diff --git a/tests/ref.test.tsx b/tests/ref.test.tsx index bdea4570..2cff5977 100644 --- a/tests/ref.test.tsx +++ b/tests/ref.test.tsx @@ -50,4 +50,36 @@ describe('Trigger.Ref', () => { document.querySelector('.rc-trigger-popup'), ); }); + + it('should support ref.nativeElement', () => { + const ChildComponent = React.forwardRef< + { nativeElement: HTMLElement }, + React.PropsWithChildren + >((props, ref) => { + const buttonRef = React.useRef(null); + + React.useImperativeHandle(ref, () => ({ + nativeElement: buttonRef.current, + })); + + return