fix: fix scrollYOffset when SSR

This commit is contained in:
Roman Hotsiy 2019-09-30 09:54:19 +03:00
parent 32a464aaa8
commit 21258a5b61
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0

View File

@ -19,6 +19,10 @@ export interface StickySidebarProps {
menu: MenuStore; menu: MenuStore;
} }
export interface StickySidebarState {
offsetTop?: string;
}
const stickyfill = Stickyfill && Stickyfill(); const stickyfill = Stickyfill && Stickyfill();
const StyledStickySidebar = styled.div<{ open?: boolean }>` const StyledStickySidebar = styled.div<{ open?: boolean }>`
@ -77,13 +81,26 @@ const FloatingButton = styled.div`
`; `;
@observer @observer
export class StickyResponsiveSidebar extends React.Component<StickySidebarProps> { export class StickyResponsiveSidebar extends React.Component<
StickySidebarProps,
StickySidebarState
> {
static contextType = OptionsContext;
context!: React.ContextType<typeof OptionsContext>;
state: StickySidebarState = {};
stickyElement: Element; stickyElement: Element;
componentDidMount() { componentDidMount() {
if (stickyfill) { if (stickyfill) {
stickyfill.add(this.stickyElement); stickyfill.add(this.stickyElement);
} }
// rerender when hydrating from SSR
// see https://github.com/facebook/react/issues/8017#issuecomment-256351955
this.setState({
offsetTop: this.getScrollYOffset(this.context),
});
} }
componentWillUnmount() { componentWillUnmount() {
@ -92,7 +109,7 @@ export class StickyResponsiveSidebar extends React.Component<StickySidebarProps>
} }
} }
getScrollYOffset(options) { getScrollYOffset(options: RedocNormalizedOptions) {
let top; let top;
if (this.props.scrollYOffset !== undefined) { if (this.props.scrollYOffset !== undefined) {
top = RedocNormalizedOptions.normalizeScrollYOffset(this.props.scrollYOffset)(); top = RedocNormalizedOptions.normalizeScrollYOffset(this.props.scrollYOffset)();
@ -105,43 +122,32 @@ export class StickyResponsiveSidebar extends React.Component<StickySidebarProps>
render() { render() {
const open = this.props.menu.sideBarOpened; const open = this.props.menu.sideBarOpened;
const style = options => { const top = this.state.offsetTop || this.getScrollYOffset(this.context);
const top = this.getScrollYOffset(options);
return {
top,
height: `calc(100vh - ${top})`,
};
};
return ( return (
<OptionsContext.Consumer> <>
{options => ( <StyledStickySidebar
<> open={open}
<StyledStickySidebar className={this.props.className}
open={open} style={{
className={this.props.className} top,
style={style(options)} height: `calc(100vh - ${top})`,
// tslint:disable-next-line }}
ref={el => { // tslint:disable-next-line
this.stickyElement = el as any; ref={el => {
}} this.stickyElement = el as any;
> }}
{this.props.children} >
</StyledStickySidebar> {this.props.children}
<FloatingButton onClick={this.toggleNavMenu}> </StyledStickySidebar>
<AnimatedChevronButton open={open} /> <FloatingButton onClick={this.toggleNavMenu}>
</FloatingButton> <AnimatedChevronButton open={open} />
</> </FloatingButton>
)} </>
</OptionsContext.Consumer>
); );
} }
private toggleNavMenu = () => { private toggleNavMenu = () => {
this.props.menu.toggleSidebar(); this.props.menu.toggleSidebar();
}; };
// private closeNavMenu = () => {
// this.setState({ open: false });
// };
} }