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,22 +122,17 @@ 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 <StyledStickySidebar
open={open} open={open}
className={this.props.className} className={this.props.className}
style={style(options)} style={{
top,
height: `calc(100vh - ${top})`,
}}
// tslint:disable-next-line // tslint:disable-next-line
ref={el => { ref={el => {
this.stickyElement = el as any; this.stickyElement = el as any;
@ -132,16 +144,10 @@ export class StickyResponsiveSidebar extends React.Component<StickySidebarProps>
<AnimatedChevronButton open={open} /> <AnimatedChevronButton open={open} />
</FloatingButton> </FloatingButton>
</> </>
)}
</OptionsContext.Consumer>
); );
} }
private toggleNavMenu = () => { private toggleNavMenu = () => {
this.props.menu.toggleSidebar(); this.props.menu.toggleSidebar();
}; };
// private closeNavMenu = () => {
// this.setState({ open: false });
// };
} }