2018-01-23 15:58:30 +03:00
|
|
|
import * as React from 'react';
|
|
|
|
|
2018-03-26 21:56:39 +03:00
|
|
|
import PerfectScrollbarType, * as PerfectScrollbarNamespace from 'perfect-scrollbar';
|
2018-01-23 15:58:30 +03:00
|
|
|
import psStyles from 'perfect-scrollbar/css/perfect-scrollbar.css';
|
2018-08-16 09:56:47 +03:00
|
|
|
|
|
|
|
import { OptionsContext } from '../components/OptionsProvider';
|
2018-10-18 11:48:17 +03:00
|
|
|
import styled, { createGlobalStyle } from '../styled-components';
|
2018-01-23 15:58:30 +03:00
|
|
|
|
2018-03-26 21:56:39 +03:00
|
|
|
/*
|
|
|
|
* perfect scrollbar umd bundle uses exports assignment while module uses default export
|
|
|
|
* so when bundled with webpack default export works but with jest it crashes
|
|
|
|
* That's why the following ugly fix is required
|
|
|
|
*/
|
|
|
|
const PerfectScrollbarConstructor =
|
|
|
|
PerfectScrollbarNamespace.default || ((PerfectScrollbarNamespace as any) as PerfectScrollbarType);
|
|
|
|
|
2018-10-18 11:48:17 +03:00
|
|
|
const PSStyling = createGlobalStyle`${psStyles && psStyles.toString()}`;
|
2018-01-23 15:58:30 +03:00
|
|
|
|
|
|
|
const StyledScrollWrapper = styled.div`
|
|
|
|
position: relative;
|
|
|
|
`;
|
|
|
|
|
2018-08-16 09:56:47 +03:00
|
|
|
export interface PerfectScrollbarProps {
|
2018-03-26 21:56:39 +03:00
|
|
|
options?: PerfectScrollbarType.Options;
|
2018-01-23 15:58:30 +03:00
|
|
|
className?: string;
|
2018-08-16 09:56:47 +03:00
|
|
|
updateFn?: (fn) => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class PerfectScrollbar extends React.Component<PerfectScrollbarProps> {
|
2018-01-23 15:58:30 +03:00
|
|
|
private _container: HTMLElement;
|
2018-03-26 21:56:39 +03:00
|
|
|
private inst: PerfectScrollbarType;
|
2018-01-23 15:58:30 +03:00
|
|
|
|
|
|
|
componentDidMount() {
|
2018-07-31 15:36:30 +03:00
|
|
|
const offset = (this._container.parentElement && this._container.parentElement.scrollTop) || 0;
|
2018-01-23 15:58:30 +03:00
|
|
|
this.inst = new PerfectScrollbarConstructor(this._container, this.props.options || {});
|
2018-07-31 16:58:44 +03:00
|
|
|
if (this._container.scrollTo) {
|
|
|
|
this._container.scrollTo(0, offset);
|
|
|
|
}
|
2018-01-23 15:58:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
componentDidUpdate() {
|
|
|
|
this.inst.update();
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
this.inst.destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
handleRef = ref => {
|
|
|
|
this._container = ref;
|
|
|
|
};
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const { children, className, updateFn } = this.props;
|
|
|
|
|
2018-08-16 09:56:47 +03:00
|
|
|
if (updateFn) {
|
|
|
|
updateFn(this.componentDidUpdate.bind(this));
|
|
|
|
}
|
2018-01-23 15:58:30 +03:00
|
|
|
|
|
|
|
return (
|
2018-10-18 11:48:17 +03:00
|
|
|
<>
|
|
|
|
<PSStyling />
|
|
|
|
<StyledScrollWrapper className={`scrollbar-container ${className}`} ref={this.handleRef}>
|
|
|
|
{children}
|
|
|
|
</StyledScrollWrapper>
|
|
|
|
</>
|
2018-01-23 15:58:30 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2018-08-16 09:56:47 +03:00
|
|
|
|
|
|
|
export function PerfectScrollbarWrap(
|
|
|
|
props: PerfectScrollbarProps & { children: JSX.Element[] | JSX.Element },
|
|
|
|
) {
|
|
|
|
return (
|
|
|
|
<OptionsContext.Consumer>
|
|
|
|
{options =>
|
|
|
|
!options.nativeScrollbars ? (
|
|
|
|
<PerfectScrollbar {...props}>{props.children}</PerfectScrollbar>
|
|
|
|
) : (
|
|
|
|
<div
|
|
|
|
style={{
|
|
|
|
overflow: 'auto',
|
2020-06-23 11:53:00 +03:00
|
|
|
overscrollBehavior: 'contain',
|
2018-08-16 09:56:47 +03:00
|
|
|
msOverflowStyle: '-ms-autohiding-scrollbar',
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{props.children}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
</OptionsContext.Consumer>
|
|
|
|
);
|
|
|
|
}
|