From ac24b8e35733cdd22484bf0503bcf35cacf2b8fb Mon Sep 17 00:00:00 2001 From: Taya Leutina Date: Wed, 24 Jan 2024 11:31:31 +0300 Subject: [PATCH] refactor(Sheet): refactor Sheet from class component to function (#1268) --- src/components/Sheet/Sheet.tsx | 135 +++++++++------------------------ 1 file changed, 37 insertions(+), 98 deletions(-) diff --git a/src/components/Sheet/Sheet.tsx b/src/components/Sheet/Sheet.tsx index 4b3de6befc..e2ecad0d93 100644 --- a/src/components/Sheet/Sheet.tsx +++ b/src/components/Sheet/Sheet.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import ReactDOM from 'react-dom'; - +import {useBodyScrollLock} from '../../hooks'; +import {Portal} from '../Portal/Portal'; import type {QAProps} from '../types'; import {SheetContentContainer} from './SheetContent'; @@ -30,91 +30,45 @@ export interface SheetProps extends QAProps { hideTopBar?: boolean; } -interface SheetState { - visible: boolean; -} - -export class Sheet extends React.Component { - private static bodyScrollLocksCount = 0; - private static bodyInitialOverflow: string | undefined = undefined; - - static lockBodyScroll() { - if (++Sheet.bodyScrollLocksCount === 1) { - Sheet.bodyInitialOverflow = document.body.style.overflow; - document.body.style.overflow = 'hidden'; - } +export const Sheet = ({ + children, + onClose, + visible, + id, + title, + className, + contentClassName, + swipeAreaClassName, + allowHideOnContentScroll, + hideTopBar, + qa, +}: SheetProps) => { + const [open, setOpen] = React.useState(visible); + const [prevVisible, setPrevVisible] = React.useState(visible); + + useBodyScrollLock({enabled: open}); + + if (!prevVisible && visible) { + setOpen(true); } - static restoreBodyScroll() { - if (Sheet.bodyScrollLocksCount === 0) { - return; - } - - if (--Sheet.bodyScrollLocksCount === 0) { - document.body.style.overflow = Sheet.bodyInitialOverflow || ''; - Sheet.bodyInitialOverflow = undefined; - } + if (visible !== prevVisible) { + setPrevVisible(visible); } - bodyScrollLocked = false; - - state: SheetState = { - visible: false, - }; - - componentDidMount() { - if (this.props.visible) { - this.showSheet(); - } - } - - componentDidUpdate(prevProps: SheetProps) { - if (!prevProps.visible && this.props.visible) { - this.showSheet(); + const hideSheet = () => { + if (onClose) { + onClose(); } - } - - componentWillUnmount() { - this.restoreBodyScroll(); - } - - render() { - if (!this.state.visible) { - return null; - } - - return ReactDOM.createPortal(this.renderSheet(), document.body); - } - - restoreBodyScroll() { - if (!this.bodyScrollLocked) { - return; - } - - Sheet.restoreBodyScroll(); - this.bodyScrollLocked = false; - } + setOpen(false); + }; - lockBodyScroll() { - Sheet.lockBodyScroll(); - this.bodyScrollLocked = true; + if (!open) { + return null; } - private renderSheet() { - const { - id, - children, - className, - contentClassName, - swipeAreaClassName, - title, - visible, - allowHideOnContentScroll, - hideTopBar, - qa, - } = this.props; - - return ( + return ( +
{ visible={visible} allowHideOnContentScroll={allowHideOnContentScroll} hideTopBar={hideTopBar} - hideSheet={this.hideSheet} + hideSheet={hideSheet} />
- ); - } - - private showSheet = () => { - this.lockBodyScroll(); - this.setState({visible: true}); - }; - - private hideSheet = () => { - this.restoreBodyScroll(); - - if (this.props.onClose) { - this.props.onClose(); - } - - this.setState({visible: false}); - }; -} +
+ ); +};