Skip to content

Commit ad9b40e

Browse files
committed
initial migration for index.js
1 parent af3b700 commit ad9b40e

File tree

3 files changed

+101
-29
lines changed

3 files changed

+101
-29
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"@babel/preset-env": "^7.7.1",
5555
"@babel/preset-react": "^7.7.0",
5656
"@rollup/plugin-replace": "^2.2.1",
57+
"@types/react": "^18.3.12",
5758
"bundlesize": "^0.18.0",
5859
"escape-html": "^1.0.3",
5960
"eslint": "^6.6.0",
@@ -76,6 +77,6 @@
7677
"rollup-plugin-terser": "^5.1.2"
7778
},
7879
"dependencies": {
79-
"prop-types": "^15.7.2"
80+
"typescript": "^5.7.2"
8081
}
8182
}

src/index.js renamed to src/index.tsx

+64-28
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,73 @@
11
import React, {
2+
CSSProperties,
3+
MutableRefObject,
4+
ReactElement,
5+
ReactNode,
26
useContext,
37
useEffect,
48
useMemo,
59
useReducer,
610
useRef
711
} from 'react';
8-
import PropTypes from 'prop-types';
912

10-
const Context = React.createContext();
13+
enum Direction {
14+
up = 'up',
15+
left = 'left',
16+
right = 'right',
17+
down = 'down'
18+
};
19+
20+
interface CanScroll {
21+
[Direction.up]: boolean
22+
[Direction.left]: boolean
23+
[Direction.right]: boolean
24+
[Direction.down]: boolean
25+
}
26+
27+
interface Dispatch {
28+
type: string
29+
direction: keyof typeof Direction
30+
canScroll: boolean
31+
}
32+
33+
interface OverflowContext {
34+
tolerance?: number | string
35+
refs: { viewport: MutableRefObject<HTMLDivElement | null> }
36+
canScroll?: CanScroll
37+
state: {
38+
canScroll: CanScroll
39+
}
40+
dispatch: ({type, direction, canScroll}: Dispatch) => void
41+
}
42+
43+
const Context = React.createContext<OverflowContext>({});
1144

1245
export function useOverflow() {
1346
return useContext(Context);
1447
}
1548

16-
const containerStyle = {
49+
const containerStyle: CSSProperties = {
1750
display: 'flex',
1851
flexDirection: 'column',
1952
position: 'relative'
2053
};
2154

22-
const viewportStyle = {
55+
const viewportStyle: CSSProperties = {
2356
position: 'relative',
2457
flexBasis: '100%',
2558
flexShrink: 1,
2659
flexGrow: 0,
2760
overflow: 'auto'
2861
};
2962

30-
const contentStyle = {
63+
const contentStyle: CSSProperties = {
3164
display: 'inline-block',
3265
position: 'relative',
3366
minWidth: '100%',
3467
boxSizing: 'border-box'
3568
};
3669

37-
function reducer(state, action) {
70+
function reducer(state, action: PayloadAction<>) {
3871
switch (action.type) {
3972
case 'CHANGE': {
4073
const currentValue = state.canScroll[action.direction];
@@ -104,10 +137,10 @@ export default function Overflow({
104137
style: styleProp,
105138
tolerance = 0,
106139
...rest
107-
}) {
140+
}: Overflow) {
108141
const [state, dispatch] = useReducer(reducer, null, getInitialState);
109142
const hidden = rest.hidden;
110-
const viewportRef = useRef();
143+
const viewportRef = useRef<HTMLDivElement>(null);
111144

112145
const style = useMemo(
113146
() => ({
@@ -151,26 +184,28 @@ export default function Overflow({
151184
);
152185
}
153186

154-
Overflow.propTypes = {
187+
interface Overflow {
155188
/**
156189
* Elements to render inside the outer container. This should include an
157190
* `<Overflow.Content>` element at a minimum, but should also include your
158191
* scroll indicators if you’d like to overlay them on the scrollable viewport.
159192
*/
160-
children: PropTypes.node,
193+
children: ReactNode,
161194
/**
162195
* Callback that receives the latest overflow state and an object of refs, if
163196
* you’d like to react to overflow in a custom way.
164197
*/
165-
onStateChange: PropTypes.func,
198+
onStateChange: (state: string, refs: {viewport: MutableRefObject<HTMLDivElement | null>}) => void,
166199
/**
167200
* Distance (number of pixels or CSS length unit like `1em`) to the edge of
168201
* the content at which to consider the viewport fully scrolled. For example,
169202
* if set to 10, then it will consider scrolling to have reached the end as
170203
* long as it’s within 10 pixels of the border. You can use this when your
171204
* content has padding and scrolling close to the edge should be good enough.
172205
*/
173-
tolerance: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
206+
tolerance: number | string
207+
style: CSSProperties
208+
hidden: boolean
174209
};
175210

176211
// For Firefox, update on a threshold of 0 in addition to any intersection at
@@ -188,20 +223,20 @@ const threshold = [0, 1e-12];
188223
* own element inside `<Overflow.Content>` instead – otherwise you risk
189224
* interfering with the styles this component needs to function.
190225
*/
191-
function OverflowContent({ children, style: styleProp, ...rest }) {
226+
function OverflowContent({ children, style: styleProp, ...rest }: OverflowContent) {
192227
const { dispatch, tolerance, refs } = useOverflow();
193228
const { viewport: viewportRef } = refs;
194-
const contentRef = useRef();
195-
const toleranceRef = useRef();
229+
const contentRef = useRef<HTMLDivElement | null>(null);
230+
const toleranceRef = useRef<HTMLDivElement | null>(null);
196231
const watchRef = tolerance ? toleranceRef : contentRef;
197-
const observersRef = useRef();
232+
const observersRef = useRef<HTMLDivElement | null>(null);
198233

199234
useEffect(() => {
200235
let ignore = false;
201236

202237
const root = viewportRef.current;
203238

204-
const createObserver = (direction, rootMargin) => {
239+
const createObserver = (direction: Direction, rootMargin: string) => {
205240
return new IntersectionObserver(
206241
([entry]) => {
207242
if (ignore) {
@@ -230,10 +265,10 @@ function OverflowContent({ children, style: styleProp, ...rest }) {
230265
};
231266

232267
const observers = {
233-
up: createObserver('up', '100% 0px -100% 0px'),
234-
left: createObserver('left', '0px -100% 0px 100%'),
235-
right: createObserver('right', '0px 100% 0px -100%'),
236-
down: createObserver('down', '-100% 0px 100% 0px')
268+
up: createObserver(Direction.up, '100% 0px -100% 0px'),
269+
left: createObserver(Direction.left, '0px -100% 0px 100%'),
270+
right: createObserver(Direction.right, '0px 100% 0px -100%'),
271+
down: createObserver(Direction.down, '-100% 0px 100% 0px')
237272
};
238273

239274
observersRef.current = observers;
@@ -251,7 +286,7 @@ function OverflowContent({ children, style: styleProp, ...rest }) {
251286
const observers = observersRef.current;
252287
const watchNode = watchRef.current;
253288

254-
observers.up.observe(watchNode);
289+
observers?.up.observe(watchNode);
255290
observers.left.observe(watchNode);
256291
observers.right.observe(watchNode);
257292
observers.down.observe(watchNode);
@@ -304,11 +339,12 @@ function OverflowContent({ children, style: styleProp, ...rest }) {
304339

305340
OverflowContent.displayName = 'Overflow.Content';
306341

307-
OverflowContent.propTypes = {
342+
interface OverflowContent {
308343
/**
309344
* Content to render inside the scrollable viewport.
310345
*/
311-
children: PropTypes.node
346+
children: ReactNode
347+
style: CSSProperties
312348
};
313349

314350
/**
@@ -352,7 +388,7 @@ OverflowContent.propTypes = {
352388
* </Overflow>
353389
* ```
354390
*/
355-
function OverflowIndicator({ children, direction }) {
391+
function OverflowIndicator({ children, direction } : OverflowIndicator) {
356392
const { state, refs } = useOverflow();
357393
const { canScroll } = state;
358394
const isActive = direction
@@ -372,19 +408,19 @@ function OverflowIndicator({ children, direction }) {
372408

373409
OverflowIndicator.displayName = 'Overflow.Indicator';
374410

375-
OverflowIndicator.propTypes = {
411+
interface OverflowIndicator {
376412
/**
377413
* Indicator to render when scrolling is allowed in the requested direction.
378414
* If given a function, it will be passed the overflow state and an object
379415
* containing the `viewport` ref. You can use this `refs` parameter to render
380416
* an indicator that is also a button that scrolls the viewport (for example).
381417
*/
382-
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
418+
children: ReactElement | ((stateArg: boolean | CanScroll, refs: OverflowContext['refs']) => ReactElement)
383419
/**
384420
* The scrollabe direction to watch for. If not supplied, the indicator will
385421
* be active when scrolling is allowed in any direction.
386422
*/
387-
direction: PropTypes.oneOf(['up', 'down', 'left', 'right'])
423+
direction: keyof typeof Direction
388424
};
389425

390426
Overflow.Indicator = OverflowIndicator;

tsconfig.json

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"compilerOptions": {
3+
"target": "esnext",
4+
"lib": [
5+
"dom",
6+
"dom.iterable",
7+
"esnext"
8+
],
9+
"allowJs": true,
10+
"skipLibCheck": true,
11+
"esModuleInterop": true,
12+
"isolatedModules": true,
13+
"allowSyntheticDefaultImports": true,
14+
"strict": true,
15+
"strictNullChecks": true,
16+
"forceConsistentCasingInFileNames": true,
17+
"module": "es2020",
18+
"moduleResolution": "node",
19+
"resolveJsonModule": true,
20+
"noEmit": true,
21+
"experimentalDecorators": true,
22+
"jsx": "preserve",
23+
"baseUrl": "./src",
24+
"useUnknownInCatchVariables": false,
25+
"composite": true,
26+
"incremental": true
27+
},
28+
"include": [
29+
"./src/**/*",
30+
"./src/**/*.json"
31+
],
32+
"exclude": [
33+
"node_modules"
34+
]
35+
}

0 commit comments

Comments
 (0)