Skip to content

Commit ed9bb2f

Browse files
authored
fix: Improve typing in @visx/responsive enhancers (#1783)
* improve responsive enhancers typing * review changes * add useParentSize and useScreenSize hooks * revert resize observer changes, add initialSize props, review window properties usage
1 parent 9bedf07 commit ed9bb2f

File tree

10 files changed

+460
-203
lines changed

10 files changed

+460
-203
lines changed

packages/visx-responsive/Readme.md

Lines changed: 142 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,71 +4,161 @@
44
<img src="https://img.shields.io/npm/dm/@visx/responsive.svg?style=flat-square" />
55
</a>
66

7-
The `@visx/responsive` package is here to help you make responsive graphs.
7+
The `@visx/responsive` package is here to help you make responsive graphs by providing a collection
8+
of hooks, enhancers and components.
89

9-
**Enhancers**
10+
## Installation
11+
12+
```
13+
npm install --save @visx/responsive
14+
```
15+
16+
## Hooks
1017

11-
`withScreenSize`
18+
### `useScreenSize`
1219

13-
`withParentSize`
20+
If you would like your graph to adapt to the screen size, you can use the `useScreenSize()` hook. It
21+
returns current screen width and height and updates the value automatically on browser window
22+
resize. You can optionally pass a config object as an argument to the hook. Config object attributes
23+
are:
1424

15-
**Components**
25+
- `initialSize` - initial size before measuring the screen, defaults to `{ width: 0, height: 0 }`.
26+
- `debounceTime` - determines how often the size is updated in milliseconds, defaults to `300`.
27+
- `enableDebounceLeadingCall` - determines whether the size is updated immediately on first render,
28+
defaults to `true`. This is essentially the value of
29+
[`options.leading` in Lodash's `debounce`](https://lodash.com/docs/4.17.15#debounce).
1630

17-
`ParentSize`
31+
#### Example
32+
33+
```tsx
34+
import { useScreenSize } from '@visx/responsive';
35+
36+
const ChartToRender = () => {
37+
const { width, height } = useScreenSize({ debounceTime: 150 });
38+
39+
return (
40+
<svg width={width} height={height}>
41+
{/* content */}
42+
</svg>
43+
);
44+
};
1845

19-
`ScaleSVG`
46+
const chartToRender = <ChartToRender myProp="string" />;
47+
```
48+
49+
### `useParentSize`
50+
51+
If you want your graph to adapt to its parent size, you can use `useParentSize()` hook.
52+
`<ParentSize>` uses this hook internally. The hook returns `width`, `height`, `left`, `top`
53+
properties which describe dimensions of the container which received `parentRef` ref. You can
54+
optionally pass a config object as an argument to the hook. Config object attributes are:
55+
56+
- `initialSize` - initial size before measuring the parent, defaults to
57+
`{ width: 0, height: 0, left: 0, top: 0 }`.
58+
- `debounceTime` - determines how often the size is updated in miliseconds, defaults to `300`.
59+
- `enableDebounceLeadingCall` - determines whether the size is updated immediately on first render,
60+
defaults to `true`. This is essentially the value of
61+
[`options.leading` in Lodash's `debounce`](https://lodash.com/docs/4.17.15#debounce).
62+
- `ignoreDimensions` - array of dimensions for which an update should be skipped. For example, if
63+
you pass `['width']`, width changes of the component that received `parentRef` won't be
64+
propagated. Defaults to `[]` (all dimensions changes trigger updates).
65+
66+
#### Example
67+
68+
```tsx
69+
import { useParentSize } from '@visx/responsive';
70+
71+
const ChartToRender = () => {
72+
const { parentRef, width, height } = useParentSize({ debounceTime: 150 });
73+
74+
return (
75+
<div ref={parentRef}>
76+
<svg width={width} height={height}>
77+
{/* content */}
78+
</svg>
79+
</div>
80+
);
81+
};
82+
83+
const chartToRender = <ChartToRender myProp="string" />;
84+
```
85+
86+
## Enhancers / (HOCs)
2087

2188
### `withScreenSize`
2289

23-
If you would like your graph to adapt to the screen size, you can use `withScreenSize()`. The
24-
resulting component will pass `screenWidth` and `screenHeight` props to the wrapped component
25-
containing the respective screen dimensions.
90+
If you prefer to use an enhancer, you can use the `withScreenSize()`. The resulting component will
91+
pass `screenWidth` and `screenHeight` props to the wrapped component containing the respective
92+
screen dimensions. You can also optionally pass config props to the wrapped component:
2693

27-
### Example:
94+
- `debounceTime` - determines how often the size is updated in milliseconds, defaults to `300`.
95+
- `windowResizeDebounceTime` - deprecated, equivalent to the above, kept for backwards compatibility
96+
- `enableDebounceLeadingCall` - determines whether the size is updated immediately on first render,
97+
defaults to `true`. This is essentially the value of
98+
[`options.leading` in Lodash's `debounce`](https://lodash.com/docs/4.17.15#debounce).
99+
100+
#### Example
101+
102+
```tsx
103+
import { withScreenSize, WithScreenSizeProvidedProps } from '@visx/responsive';
28104

29-
```js
30-
import { withScreenSize } from '@visx/responsive';
31-
// or
32-
// import * as Responsive from '@visx/responsive';
33-
// Responsive.withScreenSize(...);
105+
interface Props extends WithScreenSizeProvidedProps {
106+
myProp: string;
107+
}
34108

35-
let chartToRender = withScreenSize(MySuperCoolVisxChart);
109+
const MySuperCoolVisxChart = ({ myProp, screenWidth, screenHeight }: Props) => {
110+
// ...
111+
};
36112

37-
// ... Render the chartToRender somewhere
113+
const ChartToRender = withScreenSize(MySuperCoolVisxChart);
114+
115+
const chartToRender = <ChartToRender myProp="string" />;
38116
```
39117

40-
## `withParentSize`
118+
### `withParentSize`
41119

42-
If you would like your graph to adapt to it's parent component's size, you can use
120+
If you prefer to use an enhancer to adapt your graph to its parent component's size, you can use
43121
`withParentSize()`. The resulting component will pass `parentWidth` and `parentHeight` props to the
44-
wrapped component containing the respective parent's dimensions.
122+
wrapped component containing the respective parent's dimensions. You can also optionally pass config
123+
props to the wrapped component:
124+
125+
- `initialWidth` - initial chart width used before the parent size is determined.
126+
- `initialHeight` - initial chart height used before the parent size is determined.
127+
- `debounceTime` - determines how often the size is updated in miliseconds, defaults to `300`.
128+
- `enableDebounceLeadingCall` - determines whether the size is updated immediately on first render,
129+
defaults to `true`. This is essentially the value of
130+
[`options.leading` in Lodash's `debounce`](https://lodash.com/docs/4.17.15#debounce).
131+
132+
#### Example
133+
134+
```tsx
135+
import { withParentSize, WithParentSizeProvidedProps } from '@visx/responsive';
45136

46-
### Example:
137+
interface Props extends WithParentSizeProvidedProps {
138+
myProp: string;
139+
}
47140

48-
```js
49-
import { withParentSize } from '@visx/responsive';
50-
// or
51-
// import * as Responsive from '@visx/responsive';
52-
// Responsive.withParentSize(...);
141+
const MySuperCoolVisxChart = ({ myProp, parentWidth, parentHeight }: Props) => {
142+
// ...
143+
};
53144

54-
let chartToRender = withParentSize(MySuperCoolVisxChart);
145+
const ChartWithParentSize = withParentSize(MySuperCoolVisxChart);
55146

56-
// ... Render the chartToRender somewhere
147+
const chartToRender = <ChartWithParentSize myProp="string" initialWidth={400} />;
57148
```
58149

59-
## `ParentSize`
150+
## Components
60151

61-
You might do the same thing using the `ParentSize` component.
152+
### `ParentSize`
62153

63-
### Example:
154+
You might do the same thing as `useParentSize` or `withParentSize` using the `ParentSize` component.
64155

65-
```js
156+
#### Example
157+
158+
```tsx
66159
import { ParentSize } from '@visx/responsive';
67-
// or
68-
// import * as Responsive from '@visx/responsive';
69-
// <Responsive.ParentSize />;
70160

71-
let chartToRender = (
161+
const chartToRender = (
72162
<ParentSize>
73163
{(parent) => (
74164
<MySuperCoolVisxChart
@@ -84,50 +174,40 @@ let chartToRender = (
84174
)}
85175
</ParentSize>
86176
);
87-
88-
// ... Render the chartToRender somewhere
89177
```
90178

91-
## `ScaleSVG`
179+
### `ScaleSVG`
92180

93181
You can also create a responsive chart with a specific viewBox with the `ScaleSVG` component.
94182

95-
### Example:
183+
#### Example
96184

97-
```js
185+
```tsx
98186
import { ScaleSVG } from '@visx/responsive';
99-
// or
100-
// import * as Responsive from '@visx/responsive';
101-
// <Responsive.ScaleSVG />
102187

103-
let chartToRender = (
188+
const chartToRender = (
104189
<ScaleSVG width={400} height={400}>
105190
<MySuperCoolVXChart />
106191
</ScaleSVG>
107192
);
108-
109-
// ... Render the chartToRender somewhere
110193
```
111194

112-
### ⚠️ `ResizeObserver` dependency
195+
## ⚠️ `ResizeObserver` dependency
113196

114-
The `ParentSize` component and `withParentSize` enhancer rely on `ResizeObserver`s for auto-sizing.
115-
If you need a polyfill, you can either polute the `window` object or inject it cleanly through
116-
props:
197+
`useParentSize`, `ParentSize` and `withParentSize` rely on `ResizeObserver`s for auto-sizing. If you
198+
need a polyfill, you can either pollute the `window` object or inject it cleanly like this:
117199

118200
```tsx
119201
import { ResizeObserver } from 'your-favorite-polyfill';
120202

121-
function App() {
122-
return (
123-
<ParentSize resizeObserverPolyfill={ResizeObserver} {...}>
124-
{() => {...}}
125-
</ParentSize>
126-
);
127-
```
203+
// hook
204+
useParentSize({ resizeObserverPolyfill: ResizeObserver });
128205

129-
## Installation
206+
// component
207+
<ParentSize resizeObserverPolyfill={ResizeObserver} {...}>
208+
{() => {...}}
209+
</ParentSize>
130210

131-
```
132-
npm install --save @visx/responsive
211+
// enhancer
212+
withParentSize(MyComponent, ResizeObserver);
133213
```

0 commit comments

Comments
 (0)