From ede480186c4b3f187c82e1d64e4d521ee59da31a Mon Sep 17 00:00:00 2001 From: MAZE Date: Mon, 8 Apr 2024 20:55:03 +0330 Subject: [PATCH] feat: add toolbar and portal --- src/components/app/app.tsx | 6 +-- src/components/container/container.module.css | 4 ++ src/components/container/container.tsx | 17 +++++- src/components/menu/menu.module.css | 9 ---- src/components/modal/modal.tsx | 54 ++++++++++--------- src/components/portal/index.ts | 1 + src/components/portal/portal.tsx | 14 +++++ .../scroll-to-top/scroll-to-top.module.css | 8 --- .../scroll-to-top/scroll-to-top.tsx | 4 +- src/components/toolbar/index.ts | 1 + src/components/toolbar/toolbar.module.css | 13 +++++ src/components/toolbar/toolbar.tsx | 16 ++++++ 12 files changed, 98 insertions(+), 49 deletions(-) create mode 100644 src/components/portal/index.ts create mode 100644 src/components/portal/portal.tsx create mode 100644 src/components/toolbar/index.ts create mode 100644 src/components/toolbar/toolbar.module.css create mode 100644 src/components/toolbar/toolbar.tsx diff --git a/src/components/app/app.tsx b/src/components/app/app.tsx index e398562..dbc5fdf 100644 --- a/src/components/app/app.tsx +++ b/src/components/app/app.tsx @@ -9,9 +9,8 @@ import { Container } from '@/components/container'; import { StoreConsumer } from '@/components/store-consumer'; import { Buttons } from '@/components/buttons'; import { Categories } from '@/components/categories'; -import { ScrollToTop } from '@/components/scroll-to-top'; import { SharedModal } from '@/components/modals/shared'; -import { Menu } from '@/components/menu/menu'; +import { Toolbar } from '@/components/toolbar'; import { SnackbarProvider } from '@/contexts/snackbar'; import { sounds } from '@/data/sounds'; @@ -77,8 +76,7 @@ export function App() { - - + diff --git a/src/components/container/container.module.css b/src/components/container/container.module.css index 6210e59..56c3f78 100644 --- a/src/components/container/container.module.css +++ b/src/components/container/container.module.css @@ -6,4 +6,8 @@ &.tight { max-width: 450px; } + + &.wide { + max-width: 720px; + } } diff --git a/src/components/container/container.tsx b/src/components/container/container.tsx index afa3fca..21f8b75 100644 --- a/src/components/container/container.tsx +++ b/src/components/container/container.tsx @@ -6,11 +6,24 @@ interface ContainerProps { children: React.ReactNode; className?: string; tight?: boolean; + wide?: boolean; } -export function Container({ children, className, tight }: ContainerProps) { +export function Container({ + children, + className, + tight, + wide, +}: ContainerProps) { return ( -
+
{children}
); diff --git a/src/components/menu/menu.module.css b/src/components/menu/menu.module.css index cd82cf9..d20181f 100644 --- a/src/components/menu/menu.module.css +++ b/src/components/menu/menu.module.css @@ -1,13 +1,4 @@ .wrapper { - position: fixed; - right: calc(50vw - 400px); - bottom: 20px; - z-index: 15; - - @media (width <= 850px) { - right: 5vw; - } - & .menuButton { display: flex; align-items: center; diff --git a/src/components/modal/modal.tsx b/src/components/modal/modal.tsx index a4538e6..0832ee9 100644 --- a/src/components/modal/modal.tsx +++ b/src/components/modal/modal.tsx @@ -2,6 +2,8 @@ import { useEffect } from 'react'; import { AnimatePresence, motion } from 'framer-motion'; import { IoClose } from 'react-icons/io5/index'; +import { Portal } from '@/components/portal'; + import { fade, mix, slideY } from '@/lib/motion'; import { cn } from '@/helpers/styles'; @@ -36,35 +38,37 @@ export function Modal({ }, [show, lockBody]); return ( - - {show && ( - <> - -
+ + + {show && ( + <> - + variants={variants.overlay} + onClick={onClose} + onKeyDown={onClose} + /> +
+ + - {children} - -
- - )} -
+ {children} + +
+ + )} +
+ ); } diff --git a/src/components/portal/index.ts b/src/components/portal/index.ts new file mode 100644 index 0000000..b15dcd3 --- /dev/null +++ b/src/components/portal/index.ts @@ -0,0 +1 @@ +export { Portal } from './portal'; diff --git a/src/components/portal/portal.tsx b/src/components/portal/portal.tsx new file mode 100644 index 0000000..da63c05 --- /dev/null +++ b/src/components/portal/portal.tsx @@ -0,0 +1,14 @@ +import { useState, useEffect } from 'react'; +import { createPortal } from 'react-dom'; + +interface PortalProps { + children: React.ReactNode; +} + +export function Portal({ children }: PortalProps) { + const [isClientSide, setIsClientSide] = useState(false); + + useEffect(() => setIsClientSide(true), []); + + return isClientSide ? createPortal(children, document.body) : null; +} diff --git a/src/components/scroll-to-top/scroll-to-top.module.css b/src/components/scroll-to-top/scroll-to-top.module.css index b134691..d535280 100644 --- a/src/components/scroll-to-top/scroll-to-top.module.css +++ b/src/components/scroll-to-top/scroll-to-top.module.css @@ -1,8 +1,4 @@ .button { - position: fixed; - bottom: 20px; - left: calc(50vw - 400px); - z-index: 10; display: flex; align-items: center; justify-content: center; @@ -16,10 +12,6 @@ border-radius: 50%; transition: 0.2s; - @media (width <= 850px) { - left: 5vw; - } - &:hover { background-color: var(--color-neutral-200); } diff --git a/src/components/scroll-to-top/scroll-to-top.tsx b/src/components/scroll-to-top/scroll-to-top.tsx index 1781282..4757f90 100644 --- a/src/components/scroll-to-top/scroll-to-top.tsx +++ b/src/components/scroll-to-top/scroll-to-top.tsx @@ -31,7 +31,7 @@ export function ScrollToTop() { return ( - {isVisible && ( + {isVisible ? ( + ) : ( +
)} ); diff --git a/src/components/toolbar/index.ts b/src/components/toolbar/index.ts new file mode 100644 index 0000000..dc5abb1 --- /dev/null +++ b/src/components/toolbar/index.ts @@ -0,0 +1 @@ +export { Toolbar } from './toolbar'; diff --git a/src/components/toolbar/toolbar.module.css b/src/components/toolbar/toolbar.module.css new file mode 100644 index 0000000..4543e0e --- /dev/null +++ b/src/components/toolbar/toolbar.module.css @@ -0,0 +1,13 @@ +.wrapper { + position: fixed; + bottom: 20px; + left: 0; + z-index: 15; + width: 100%; + + .container { + display: flex; + align-items: center; + justify-content: space-between; + } +} diff --git a/src/components/toolbar/toolbar.tsx b/src/components/toolbar/toolbar.tsx new file mode 100644 index 0000000..f4d7885 --- /dev/null +++ b/src/components/toolbar/toolbar.tsx @@ -0,0 +1,16 @@ +import { Container } from '@/components/container'; +import { Menu } from '@/components/menu'; +import { ScrollToTop } from '@/components/scroll-to-top'; + +import styles from './toolbar.module.css'; + +export function Toolbar() { + return ( +
+ + + + +
+ ); +}