-
Notifications
You must be signed in to change notification settings - Fork 182
/
adaptive-island-hoc.tsx
40 lines (31 loc) · 1.22 KB
/
adaptive-island-hoc.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import React, {Component, ComponentType, createContext} from 'react';
import {interpolateLinear} from '../global/linear-function';
const TITLE_RESIZE_END = 20;
const TITLE_RESIZE_THRESHOLD = 36;
export const PhaseContext = createContext<number | null>(null);
type ScrollHandler = (element: Element) => void
export const ScrollHandlerContext = createContext<ScrollHandler | null>(null);
export default function adaptiveIslandHOC<P>(ComposedComponent: ComponentType<P>) {
return class AdaptiveIsland extends Component<P> {
static propTypes = ComposedComponent.propTypes;
state = {
phase: null
};
onContentScroll = ({scrollTop, scrollHeight, clientHeight}: Element) => {
if (scrollHeight - clientHeight >=
interpolateLinear(TITLE_RESIZE_THRESHOLD, TITLE_RESIZE_END, this.state.phase ?? 0)) {
const phase = Math.min(1, scrollTop / TITLE_RESIZE_END);
this.setState({phase});
}
};
render() {
return (
<PhaseContext.Provider value={this.state.phase}>
<ScrollHandlerContext.Provider value={this.onContentScroll}>
<ComposedComponent {...this.props}/>
</ScrollHandlerContext.Provider>
</PhaseContext.Provider>
);
}
};
}