Skip to content

Commit aec1440

Browse files
committed
feat: add custom useResizeObserver hook
The `use-resize-observer` library is not much maintained and doesn't support React 19.
1 parent 6e89bea commit aec1440

File tree

5 files changed

+43
-9
lines changed

5 files changed

+43
-9
lines changed

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@
5050
},
5151
"dependencies": {
5252
"@types/d3-scale": "^4.0.8",
53-
"d3-scale": "^4.0.2",
54-
"use-resize-observer": "^9.1.0"
53+
"d3-scale": "^4.0.2"
5554
},
5655
"volta": {
5756
"node": "22.9.0"

src/components/ResponsiveChart.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ReactNode } from 'react';
2-
import useResizeObserver from 'use-resize-observer';
2+
3+
import { useResizeObserver } from '../hooks/use_resize_observer.js';
34

45
export interface ResponsiveChartProps {
56
width?: number | `${number}%`;
@@ -15,12 +16,11 @@ export function ResponsiveChart(props: ResponsiveChartProps) {
1516
const { width, height, minWidth, minHeight, maxWidth, maxHeight, children } =
1617
props;
1718

18-
// @ts-expect-error Default import is correct.
19-
const observed = useResizeObserver<HTMLDivElement>();
19+
const [observedRef, observedSize] = useResizeObserver();
2020

2121
return (
2222
<div
23-
ref={observed.ref}
23+
ref={observedRef}
2424
style={{
2525
position: 'relative',
2626
flex: 1,
@@ -35,8 +35,8 @@ export function ResponsiveChart(props: ResponsiveChartProps) {
3535
<div
3636
style={{ position: 'absolute', top: 0, right: 0, bottom: 0, left: 0 }}
3737
>
38-
{observed.width && observed.height
39-
? children({ width: observed.width, height: observed.height })
38+
{observedSize
39+
? children({ width: observedSize.width, height: observedSize.height })
4040
: null}
4141
</div>
4242
</div>

src/hooks/use_resize_observer.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useCallback, useRef, useState } from 'react';
2+
3+
export function useResizeObserver() {
4+
const [size, setSize] = useState<DOMRect>();
5+
const observerRef = useRef<ResizeObserver | null>(null);
6+
7+
const refCallback = useCallback((node: HTMLElement | null) => {
8+
if (observerRef.current) {
9+
observerRef.current.disconnect();
10+
observerRef.current = null;
11+
}
12+
13+
if (node) {
14+
const updateSize = () => {
15+
const rect = node.getBoundingClientRect();
16+
17+
setSize(rect);
18+
};
19+
20+
updateSize();
21+
22+
const observer = new ResizeObserver(() => {
23+
updateSize();
24+
});
25+
26+
observer.observe(node);
27+
observerRef.current = observer;
28+
}
29+
}, []);
30+
31+
return [refCallback, size] as const;
32+
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from './components/AlignGroup.js';
22
export * from './components/ResponsiveChart.js';
33

44
export * from './hooks/useBBoxObserver.js';
5+
export * from './hooks/use_resize_observer.js';
56
export * from './hooks/useLinearPrimaryTicks.js';
67
export * from './hooks/useLogTicks.js';
78
export * from './hooks/useTimeTicks.js';

stories/components/ResponsiveChart.stories.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ export function SiblingVariable() {
115115
>
116116
<div style={{ flex: 2, height: 100, backgroundColor: 'yellow' }} />
117117
<ResponsiveChart>
118-
{({ width, height }) => <TestChart width={width} height={height} />}
118+
{({ width, height }) => (
119+
<TestChart width={Math.round(width)} height={Math.round(height)} />
120+
)}
119121
</ResponsiveChart>
120122
<VariableDiv>
121123
<div style={{ backgroundColor: 'red', height: '100%', color: 'white' }}>

0 commit comments

Comments
 (0)