committed by
GitHub
7 changed files with 74 additions and 122 deletions
@ -1,116 +1,79 @@ |
|||||
// @flow
|
// @flow
|
||||
|
|
||||
/* eslint-disable class-methods-use-this */ |
|
||||
|
|
||||
import React, { PureComponent } from 'react' |
import React, { PureComponent } from 'react' |
||||
import Scrollbar from 'react-smooth-scrollbar' |
|
||||
import SmoothScrollbar, { ScrollbarPlugin } from 'smooth-scrollbar' |
|
||||
|
|
||||
import Box from 'components/base/Box' |
import Box from 'components/base/Box' |
||||
|
|
||||
type Props = { |
type Props = { |
||||
children: any, |
children: any, |
||||
full: boolean, |
full: boolean, |
||||
maxHeight?: number, |
maxHeight?: number, |
||||
onUpdate?: (*) => void, |
|
||||
onScroll?: () => void, |
|
||||
} |
} |
||||
|
|
||||
// TODO this component is the source of junky scroll experience. need better solution ASAP
|
export const GrowScrollContext = React.createContext() |
||||
|
|
||||
class GrowScroll extends PureComponent<Props> { |
class GrowScroll extends PureComponent<Props> { |
||||
static defaultProps = { |
static defaultProps = { |
||||
full: false, |
full: false, |
||||
} |
} |
||||
|
|
||||
componentDidMount() { |
scrollContainer: ?HTMLDivElement |
||||
const { onUpdate, onScroll } = this.props |
|
||||
const { _scrollbar } = this |
|
||||
if (_scrollbar) { |
|
||||
if (onUpdate) { |
|
||||
onUpdate(_scrollbar) |
|
||||
} |
|
||||
if (onScroll) { |
|
||||
_scrollbar.addListener(this.onScroll) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
componentWillUnmount() { |
|
||||
const { onScroll } = this.props |
|
||||
const { _scrollbar } = this |
|
||||
if (_scrollbar && onScroll) { |
|
||||
_scrollbar.removeListener(this.onScroll) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
componenDidUpdate() { |
onScrollContainerRef = (scrollContainer: ?HTMLDivElement) => { |
||||
const { onUpdate } = this.props |
this.scrollContainer = scrollContainer |
||||
const { _scrollbar } = this |
|
||||
if (_scrollbar && onUpdate) { |
|
||||
onUpdate(_scrollbar) |
|
||||
} |
|
||||
} |
} |
||||
|
|
||||
onScroll = () => { |
valueProvider = () => ({ |
||||
const { onScroll } = this.props |
scrollContainer: this.scrollContainer, |
||||
if (onScroll) onScroll() |
}) |
||||
} |
|
||||
|
|
||||
onRef = (ref: ?Scrollbar) => { |
|
||||
this._scrollbar = ref && ref.scrollbar |
|
||||
} |
|
||||
|
|
||||
_scrollbar: * |
|
||||
|
|
||||
render() { |
render() { |
||||
const { onUpdate, children, maxHeight, full, ...props } = this.props |
const { children, maxHeight, full, ...props } = this.props |
||||
|
|
||||
|
const rootStyles = { |
||||
|
overflow: 'hidden', |
||||
|
...(full |
||||
|
? { |
||||
|
top: 0, |
||||
|
left: 0, |
||||
|
right: 0, |
||||
|
bottom: 0, |
||||
|
} |
||||
|
: { |
||||
|
display: 'flex', |
||||
|
flex: 1, |
||||
|
positoin: 'relative', |
||||
|
}), |
||||
|
} |
||||
|
|
||||
|
const scrollContainerStyles = { |
||||
|
overflowY: 'auto', |
||||
|
marginRight: `-80px`, |
||||
|
paddingRight: `80px`, |
||||
|
...(maxHeight |
||||
|
? { |
||||
|
maxHeight, |
||||
|
} |
||||
|
: { |
||||
|
bottom: 0, |
||||
|
left: 0, |
||||
|
position: 'absolute', |
||||
|
right: 0, |
||||
|
top: 0, |
||||
|
}), |
||||
|
} |
||||
|
|
||||
return ( |
return ( |
||||
<Box |
<div style={rootStyles}> |
||||
{...(full |
<div style={scrollContainerStyles} ref={this.onScrollContainerRef}> |
||||
? { |
<Box {...props}> |
||||
sticky: true, |
<GrowScrollContext.Provider value={this.valueProvider}> |
||||
} |
{children} |
||||
: { |
</GrowScrollContext.Provider> |
||||
grow: true, |
</Box> |
||||
relative: true, |
</div> |
||||
})} |
</div> |
||||
> |
|
||||
<Scrollbar |
|
||||
damping={1} |
|
||||
style={{ |
|
||||
...(maxHeight |
|
||||
? { |
|
||||
maxHeight, |
|
||||
} |
|
||||
: { |
|
||||
bottom: 0, |
|
||||
left: 0, |
|
||||
position: 'absolute', |
|
||||
right: 0, |
|
||||
top: 0, |
|
||||
}), |
|
||||
}} |
|
||||
ref={this.onRef} |
|
||||
> |
|
||||
<Box {...props}>{children}</Box> |
|
||||
</Scrollbar> |
|
||||
</Box> |
|
||||
) |
) |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
SmoothScrollbar.use( |
|
||||
class DisableXScroll extends ScrollbarPlugin { |
|
||||
static pluginName = 'disableXScroll' |
|
||||
|
|
||||
transformDelta(delta) { |
|
||||
return { |
|
||||
x: 0, |
|
||||
y: delta.y, |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
) |
|
||||
|
|
||||
export default GrowScroll |
export default GrowScroll |
||||
|
Loading…
Reference in new issue