From c382b8f9cd85f0a8482d64adc23ea11a9d326d76 Mon Sep 17 00:00:00 2001 From: Inomdzhon Mirdzhamolov Date: Tue, 26 Mar 2024 14:15:09 +0300 Subject: [PATCH] feat: create ModalPageV2 --- .../src/components/AppRoot/ScrollContext.tsx | 6 + .../CustomScrollView.module.css | 4 + .../components/ModalPage/ModalPageContext.tsx | 4 +- .../ModalPageBackdrop.module.css | 28 +++ .../ModalPageBackdrop/ModalPageBackdrop.tsx | 22 ++ .../ModalPageContent.module.css | 6 + .../ModalPageContent/ModalPageContent.tsx | 15 ++ .../ModalPageFooter.module.css | 14 ++ .../ModalPageFooter/ModalPageFooter.tsx | 21 ++ .../ModalPageHeader.module.css | 5 + .../ModalPageV2/ModalPageV2.module.css | 150 +++++++++++++ .../ModalPageV2/ModalPageV2.stories.tsx | 175 +++++++++++++++ .../components/ModalPageV2/ModalPageV2.tsx | 212 ++++++++++++++++++ .../src/components/ModalPageV2/checklist.md | 29 +++ .../vkui/src/components/ModalPageV2/index.ts | 2 + .../vkui/src/components/ModalPageV2/types.ts | 73 ++++++ packages/vkui/src/lib/adaptivity/functions.ts | 9 +- .../lib/animation/CSSAnimationController.ts | 12 + packages/vkui/src/lib/animation/index.ts | 8 +- .../lib/bottomSheet/BottomSheetController.ts | 148 ++++++++++++ .../CSSAnimationBackdropController.ts | 67 ++++++ .../CSSAnimationTargetController.ts | 48 ++++ .../UIScrollableChildrenObserver.ts | 101 +++++++++ packages/vkui/src/lib/bottomSheet/index.ts | 1 + packages/vkui/src/lib/dom.tsx | 6 + 25 files changed, 1162 insertions(+), 4 deletions(-) create mode 100644 packages/vkui/src/components/ModalPageBackdrop/ModalPageBackdrop.module.css create mode 100644 packages/vkui/src/components/ModalPageBackdrop/ModalPageBackdrop.tsx create mode 100644 packages/vkui/src/components/ModalPageContent/ModalPageContent.module.css create mode 100644 packages/vkui/src/components/ModalPageContent/ModalPageContent.tsx create mode 100644 packages/vkui/src/components/ModalPageFooter/ModalPageFooter.module.css create mode 100644 packages/vkui/src/components/ModalPageFooter/ModalPageFooter.tsx create mode 100644 packages/vkui/src/components/ModalPageV2/ModalPageV2.module.css create mode 100644 packages/vkui/src/components/ModalPageV2/ModalPageV2.stories.tsx create mode 100644 packages/vkui/src/components/ModalPageV2/ModalPageV2.tsx create mode 100644 packages/vkui/src/components/ModalPageV2/checklist.md create mode 100644 packages/vkui/src/components/ModalPageV2/index.ts create mode 100644 packages/vkui/src/components/ModalPageV2/types.ts create mode 100644 packages/vkui/src/lib/animation/CSSAnimationController.ts create mode 100644 packages/vkui/src/lib/bottomSheet/BottomSheetController.ts create mode 100644 packages/vkui/src/lib/bottomSheet/CSSAnimationBackdropController.ts create mode 100644 packages/vkui/src/lib/bottomSheet/CSSAnimationTargetController.ts create mode 100644 packages/vkui/src/lib/bottomSheet/UIScrollableChildrenObserver.ts create mode 100644 packages/vkui/src/lib/bottomSheet/index.ts diff --git a/packages/vkui/src/components/AppRoot/ScrollContext.tsx b/packages/vkui/src/components/AppRoot/ScrollContext.tsx index 3da20f9954..04ecd0839c 100644 --- a/packages/vkui/src/components/AppRoot/ScrollContext.tsx +++ b/packages/vkui/src/components/AppRoot/ScrollContext.tsx @@ -11,6 +11,7 @@ const clearDisableScrollStyle = (node: HTMLElement) => { top: '', left: '', right: '', + overscrollBehavior: '', overflowY: '', overflowX: '', }); @@ -93,9 +94,12 @@ export const GlobalScrollController = ({ children }: ScrollControllerProps): Rea top: `-${scrollY}px`, left: `-${scrollX}px`, right: '0', + overscrollBehavior: 'none', overflowY, overflowX, }); + // eslint-disable-next-line no-restricted-properties + document!.documentElement.classList.add('vkui--disable-overscroll-behavior'); setScrollLock(true); }, [document, window]); @@ -104,6 +108,8 @@ export const GlobalScrollController = ({ children }: ScrollControllerProps): Rea const scrollX = document!.body.style.left; clearDisableScrollStyle(document!.body); + // eslint-disable-next-line no-restricted-properties + document!.documentElement.classList.remove('vkui--disable-overscroll-behavior'); window!.scrollTo(-parseInt(scrollX || '0'), -parseInt(scrollY || '0')); setScrollLock(false); }, [document, window]); diff --git a/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css b/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css index 6b4412460c..49e6f862a1 100644 --- a/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css +++ b/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css @@ -3,6 +3,10 @@ block-size: 100%; overflow: hidden; position: relative; + + /* Для срабатывания `height: 100%` у `.CustomScrollView__box`, когда не во всех родителях есть `height: 100%`. */ + display: flex; + flex-direction: column; } .CustomScrollView__box { diff --git a/packages/vkui/src/components/ModalPage/ModalPageContext.tsx b/packages/vkui/src/components/ModalPage/ModalPageContext.tsx index 113dcc20a8..34b4f16e23 100644 --- a/packages/vkui/src/components/ModalPage/ModalPageContext.tsx +++ b/packages/vkui/src/components/ModalPage/ModalPageContext.tsx @@ -1,8 +1,8 @@ -import * as React from 'react'; +import { createContext } from 'react'; export interface ModalPageContextInterface { labelId?: string; } export const ModalPageContext: React.Context = - React.createContext({}); + createContext({}); diff --git a/packages/vkui/src/components/ModalPageBackdrop/ModalPageBackdrop.module.css b/packages/vkui/src/components/ModalPageBackdrop/ModalPageBackdrop.module.css new file mode 100644 index 0000000000..23644de52b --- /dev/null +++ b/packages/vkui/src/components/ModalPageBackdrop/ModalPageBackdrop.module.css @@ -0,0 +1,28 @@ +.ModalPageBackdrop { + position: absolute; + inset: 0; + z-index: -1; + background-color: rgba(0, 0, 0); + opacity: 0.4; + user-select: none; + -webkit-tap-highlight-color: transparent; +} + +.ModalPageBackdrop--visible { + animation: modal-page-backdrop-fade-in 0.2s ease-in; +} + +.ModalPageBackdrop--invisible { + animation: modal-page-backdrop-fade-out 0.1s ease-out forwards; +} + +@keyframes modal-page-backdrop-fade-in { + from { + opacity: 0; + } +} +@keyframes modal-page-backdrop-fade-out { + to { + opacity: 0; + } +} diff --git a/packages/vkui/src/components/ModalPageBackdrop/ModalPageBackdrop.tsx b/packages/vkui/src/components/ModalPageBackdrop/ModalPageBackdrop.tsx new file mode 100644 index 0000000000..70f91b3cf0 --- /dev/null +++ b/packages/vkui/src/components/ModalPageBackdrop/ModalPageBackdrop.tsx @@ -0,0 +1,22 @@ +import { classNames } from '@vkontakte/vkjs'; +import type { HasRootRef } from '../../types'; +import styles from './ModalPageBackdrop.module.css'; + +export interface ModalPageBackdropProps extends HasRootRef { + visible: boolean; + onClick?: (event: React.MouseEvent) => void; +} + +export const ModalPageBackdrop = ({ visible, getRootRef, onClick }: ModalPageBackdropProps) => { + return ( +