Skip to content

Commit e29ad57

Browse files
zombieJkiner-tang
andauthored
feat: support ref track of dom node (#172)
* chore: support ref * test: add test case * Update src/SingleObserver/index.tsx Co-authored-by: kiner-tang(文辉) <[email protected]> * Update src/index.tsx Co-authored-by: kiner-tang(文辉) <[email protected]> --------- Co-authored-by: kiner-tang(文辉) <[email protected]>
1 parent 3cb0e05 commit e29ad57

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

src/SingleObserver/index.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface SingleObserverProps extends ResizeObserverProps {
1010
children: React.ReactElement | ((ref: React.RefObject<Element>) => React.ReactElement);
1111
}
1212

13-
export default function SingleObserver(props: SingleObserverProps) {
13+
function SingleObserver(props: SingleObserverProps, ref: React.Ref<HTMLElement>) {
1414
const { children, disabled } = props;
1515
const elementRef = React.useRef<Element>(null);
1616
const wrapperRef = React.useRef<DomWrapper>(null);
@@ -39,6 +39,11 @@ export default function SingleObserver(props: SingleObserverProps) {
3939
[originRef, elementRef],
4040
);
4141

42+
const getDom = () =>
43+
findDOMNode<HTMLElement>(elementRef.current) || findDOMNode<HTMLElement>(wrapperRef.current);
44+
45+
React.useImperativeHandle(ref, () => getDom());
46+
4247
// =========================== Observe ============================
4348
const propsRef = React.useRef<SingleObserverProps>(props);
4449
propsRef.current = props;
@@ -91,8 +96,7 @@ export default function SingleObserver(props: SingleObserverProps) {
9196

9297
// Dynamic observe
9398
React.useEffect(() => {
94-
const currentElement: HTMLElement =
95-
findDOMNode(elementRef.current) || findDOMNode(wrapperRef.current);
99+
const currentElement: HTMLElement = getDom();
96100

97101
if (currentElement && !disabled) {
98102
observe(currentElement, onInternalResize);
@@ -112,3 +116,11 @@ export default function SingleObserver(props: SingleObserverProps) {
112116
</DomWrapper>
113117
);
114118
}
119+
120+
const RefSingleObserver = React.forwardRef(SingleObserver);
121+
122+
if (process.env.NODE_ENV !== 'production') {
123+
RefSingleObserver.displayName = 'SingleObserver';
124+
}
125+
126+
export default RefSingleObserver;

src/index.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export interface ResizeObserverProps {
2424
onResize?: OnResize;
2525
}
2626

27-
function ResizeObserver(props: ResizeObserverProps) {
27+
function ResizeObserver(props: ResizeObserverProps, ref: React.Ref<HTMLElement>) {
2828
const { children } = props;
2929
const childNodes = typeof children === 'function' ? [children] : toArray(children);
3030

@@ -42,13 +42,23 @@ function ResizeObserver(props: ResizeObserverProps) {
4242
return childNodes.map((child, index) => {
4343
const key = child?.key || `${INTERNAL_PREFIX_KEY}-${index}`;
4444
return (
45-
<SingleObserver {...props} key={key}>
45+
<SingleObserver {...props} key={key} ref={index === 0 ? ref : undefined}>
4646
{child}
4747
</SingleObserver>
4848
);
4949
}) as any as React.ReactElement;
5050
}
5151

52-
ResizeObserver.Collection = Collection;
52+
const RefResizeObserver = React.forwardRef(ResizeObserver) as React.ForwardRefExoticComponent<
53+
React.PropsWithoutRef<ResizeObserverProps> & React.RefAttributes<any>
54+
> & {
55+
Collection: typeof Collection;
56+
};
5357

54-
export default ResizeObserver;
58+
if (process.env.NODE_ENV !== 'production') {
59+
RefResizeObserver.displayName = 'ResizeObserver';
60+
}
61+
62+
RefResizeObserver.Collection = Collection;
63+
64+
export default RefResizeObserver;

tests/index.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,17 @@ describe('ResizeObserver', () => {
245245

246246
expect(wrapper.exists('.block')).toBeTruthy();
247247
});
248+
249+
it('ref-able', () => {
250+
const domRef = React.createRef();
251+
252+
const wrapper = mount(
253+
<ResizeObserver ref={domRef}>
254+
<div className="block" />
255+
</ResizeObserver>,
256+
);
257+
258+
expect(domRef.current instanceof HTMLDivElement).toBeTruthy();
259+
expect(domRef.current).toBe(wrapper.find('div.block').getDOMNode());
260+
});
248261
});

0 commit comments

Comments
 (0)