-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathScrollView.js
89 lines (79 loc) · 2.47 KB
/
ScrollView.js
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import React from 'react';
import ReactDOM from 'react-dom';
import cx from 'classnames';
import { skinnable, props, t } from '../utils';
import GeminiScrollbar from 'gemini-scrollbar';
import FlexView from 'react-flexview';
export const Props = {
children: t.ReactChildren,
autoshow: t.maybe(t.Boolean),
forceGemini: t.maybe(t.Boolean),
componentProps: t.maybe(t.Object),
className: t.maybe(t.String),
style: t.maybe(t.Object)
};
/** A scrollable view
* @param children - what to render inside the scroll view
* @param autoshow - whether to automatically show scrollbars
* @param forceGemini - force ScrollView to use `gemini-scrollbar`s
* @param componentProps - props to pass to the wrapper component
* @param className - className to pass to the wrapper component
* @param style - style to pass to the wrapper component
*/
@skinnable()
@props(Props)
export default class ScrollView extends React.PureComponent {
static defaultProps = {
forceGemini: true
}
/**
* Holds the reference to the GeminiScrollbar instance.
* @property scrollbar <public> [Object]
*/
scrollbar: null
componentDidMount() {
const { autoshow, forceGemini } = this.props;
this.scrollbar = new GeminiScrollbar({
autoshow,
forceGemini,
element: ReactDOM.findDOMNode(this),
createElements: false
}).create();
}
componentDidUpdate() {
const scrollTop = this.scrollbar.getViewElement().scrollTop;
this.scrollbar.update();
this.scrollbar.getViewElement().scrollTop = scrollTop;
}
componentWillUnmount() {
this.scrollbar.destroy();
this.scrollbar = null;
}
wrapperRenderer = ({ children, ...wrapperProps }) => React.createElement(
this.props.component,
wrapperProps,
children
);
innerWrapperRenderer = ({ children, ...innerWrapperProps }) => React.createElement(
this.props.innerComponent,
innerWrapperProps,
children
);
template({ children, className, style, componentProps }) {
return (
<FlexView style={style} className={cx('scrollview', className)} {...componentProps}>
<FlexView className='gm-scrollbar -vertical'>
<FlexView className='thumb' />
</FlexView>
<FlexView className='gm-scrollbar -horizontal'>
<FlexView className='thumb' />
</FlexView>
<FlexView column className='gm-scroll-view'>
<FlexView column shrink={false}>
{children}
</FlexView>
</FlexView>
</FlexView>
);
}
}