From abe8162d82da0d3776b099d5f3235c49bbb564da Mon Sep 17 00:00:00 2001 From: Nikita Mashchenko Date: Mon, 9 Oct 2023 20:39:49 -0500 Subject: [PATCH] feat: added drawer, sonner --- client/package.json | 3 +- client/src/app/layout.tsx | 7 +-- client/src/app/page.tsx | 24 +++++++- .../shared/lib/react-query/query-client.ts | 2 +- .../src/shared/ui/drawer/drawer.stories.tsx | 49 +++++++++++++++ client/src/shared/ui/drawer/drawer.tsx | 60 +++++++++++++++++++ client/src/shared/ui/drawer/index.ts | 1 + client/src/shared/ui/index.ts | 1 + client/yarn.lock | 43 +++++++------ 9 files changed, 160 insertions(+), 30 deletions(-) create mode 100644 client/src/shared/ui/drawer/drawer.stories.tsx create mode 100644 client/src/shared/ui/drawer/drawer.tsx create mode 100644 client/src/shared/ui/drawer/index.ts diff --git a/client/package.json b/client/package.json index 89c92a07d..d6408d7a8 100644 --- a/client/package.json +++ b/client/package.json @@ -37,12 +37,13 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-hook-form": "^7.45.4", - "react-hot-toast": "^2.4.1", "react-modal": "^3.16.1", + "react-modern-drawer": "^1.2.2", "react-particles": "^2.12.2", "react-select": "^5.7.4", "react-tooltip": "^5.21.3", "sass": "^1.64.2", + "sonner": "^1.0.3", "teameights-types": "^1.0.1", "tsparticles": "^2.12.0", "typescript": "5.1.6", diff --git a/client/src/app/layout.tsx b/client/src/app/layout.tsx index 9bd856d3f..2f4a7eb6b 100644 --- a/client/src/app/layout.tsx +++ b/client/src/app/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from 'next'; import { Rubik } from 'next/font/google'; -import { Toaster } from 'react-hot-toast'; +import { Toaster } from 'sonner'; import { ReactQueryProvider } from './providers'; import './styles/globals.scss'; import { ReactNode } from 'react'; @@ -19,10 +19,9 @@ export default function RootLayout({ children }: { children: ReactNode }) { {/* */} {children} diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx index 033668475..2a189ec5a 100644 --- a/client/src/app/page.tsx +++ b/client/src/app/page.tsx @@ -1,14 +1,17 @@ 'use client'; -import { Flex, Typography, Skeleton } from '@/shared/ui'; +import { Flex, Typography, Skeleton, Button, Drawer } from '@/shared/ui'; import { useGetScreenWidth } from '@/shared/lib'; import { Crown } from '@/shared/assets'; import { IUserRequest } from 'teameights-types'; -import { NewtonsCradle, RaceBy } from '@uiball/loaders'; +import { NewtonsCradle, RaceBy, Ring } from '@uiball/loaders'; +import { toast } from 'sonner'; +import { useState } from 'react'; export default function Home() { const width = useGetScreenWidth(); const user: IUserRequest = { username: 'nmashchenko' }; + const [open, setOpen] = useState(false); return ( <> @@ -33,11 +36,28 @@ export default function Home() { + + + + + setOpen(false)}> + + ); } diff --git a/client/src/shared/lib/react-query/query-client.ts b/client/src/shared/lib/react-query/query-client.ts index eb2254e17..ba1d9dda3 100644 --- a/client/src/shared/lib/react-query/query-client.ts +++ b/client/src/shared/lib/react-query/query-client.ts @@ -1,7 +1,7 @@ 'use client'; import { QueryCache, QueryClient } from '@tanstack/react-query'; -import { toast } from 'react-hot-toast'; +import { toast } from 'sonner'; export const queryClient = new QueryClient({ defaultOptions: { diff --git a/client/src/shared/ui/drawer/drawer.stories.tsx b/client/src/shared/ui/drawer/drawer.stories.tsx new file mode 100644 index 000000000..a9e9bc7c4 --- /dev/null +++ b/client/src/shared/ui/drawer/drawer.stories.tsx @@ -0,0 +1,49 @@ +import type { Meta } from '@storybook/react'; +import { useState } from 'react'; +import { Button } from '@/shared/ui'; +import { Drawer } from './drawer'; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: 'shared/Drawer', + component: Drawer, + tags: ['autodocs'], + argTypes: {}, +}; + +export default meta; + +// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args +export const Drawer_Default = () => { + const [open, setOpen] = useState(false); + + return ( +
+ setOpen(false)}> + Some Text + + + +
+ ); +}; + +export const Drawer_Fullheight = () => { + const [open, setOpen] = useState(false); + + return ( +
+ setOpen(false)} isFullHeight> + + + + +
+ ); +}; diff --git a/client/src/shared/ui/drawer/drawer.tsx b/client/src/shared/ui/drawer/drawer.tsx new file mode 100644 index 000000000..d3f7ddee8 --- /dev/null +++ b/client/src/shared/ui/drawer/drawer.tsx @@ -0,0 +1,60 @@ +'use client'; + +/** + * Drawer Component + * + * A customizable drawer component powered by `react-modern-drawer`. It provides a sliding drawer that can be utilized for additional navigation or content display, overlaying it on the current screen without navigating away. + * + * Props: + * + * @prop {boolean} open - Determines whether the drawer is visible (open) or not. + * @prop {function} onClose - Callback function that gets triggered when the drawer is requested to be closed. + * @prop {boolean} [isFullHeight=false] - Specifies whether the drawer should cover full height of the viewport. Default is `false`. + * @prop {ReactNode} [children] - Content to be displayed inside the drawer. + * + * Usage: + * + * ```tsx + * import { Drawer } from '@/shared/ui'; + * + * setIsDrawerOpen(false)} isFullHeight> + *

Drawer content here

+ *
+ * ``` + * + * Note: + * - The component is designed to slide from the bottom towards the top. This is hardcoded and not customizable via props. + * - Styling for the drawer can be adjusted through CSS variables or directly modifying inline styles in the component. Particularly, the `--cards-color` CSS variable is used for the background color. + * - Ensure proper installation and import of `react-modern-drawer` and its CSS file as shown in the component code snippet. + * - Conditional styling is applied based on `isFullHeight` prop for the `borderRadius` and `height` CSS properties. + * + * Styling: + * To further customize the drawer's appearance, consider adjusting the CSS variables or modifying the styles directly in the component's `style` object. Be mindful of the UI/UX impact that may come with stylistic changes. + */ + +import React, { FC, PropsWithChildren } from 'react'; +import DrawerComponent from 'react-modern-drawer'; +import 'react-modern-drawer/dist/index.css'; + +interface DrawerProps { + open: boolean; + onClose: () => void; + isFullHeight?: boolean; + // direction: "left" | "right" | "top" | "bottom"; +} +export const Drawer: FC> = props => { + const { open, onClose, children, isFullHeight } = props; + + const style = { + borderRadius: isFullHeight ? '0' : '15px 15px 0 0', + minHeight: '250px', + height: isFullHeight ? '100dvh' : 'auto', + background: 'var(--cards-color)', + } as React.CSSProperties; + + return ( + + {children} + + ); +}; diff --git a/client/src/shared/ui/drawer/index.ts b/client/src/shared/ui/drawer/index.ts new file mode 100644 index 000000000..8827142e8 --- /dev/null +++ b/client/src/shared/ui/drawer/index.ts @@ -0,0 +1 @@ +export { Drawer } from './drawer'; diff --git a/client/src/shared/ui/index.ts b/client/src/shared/ui/index.ts index 6ee6f928c..e66d46416 100644 --- a/client/src/shared/ui/index.ts +++ b/client/src/shared/ui/index.ts @@ -11,3 +11,4 @@ export * from './portal'; export * from './flex'; export * from './skeleton'; export * from './icon-wrapper'; +export * from './drawer'; diff --git a/client/yarn.lock b/client/yarn.lock index ebed312e3..d2f5e56e8 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -7641,12 +7641,13 @@ __metadata: react: 18.2.0 react-dom: 18.2.0 react-hook-form: ^7.45.4 - react-hot-toast: ^2.4.1 react-modal: ^3.16.1 + react-modern-drawer: ^1.2.2 react-particles: ^2.12.2 react-select: ^5.7.4 react-tooltip: ^5.21.3 sass: ^1.64.2 + sonner: ^1.0.3 storybook: 7.2.1 teameights-types: ^1.0.1 tsparticles: ^2.12.0 @@ -10274,15 +10275,6 @@ __metadata: languageName: node linkType: hard -"goober@npm:^2.1.10": - version: 2.1.13 - resolution: "goober@npm:2.1.13" - peerDependencies: - csstype: ^3.0.10 - checksum: 0c00b90d26d1a2fad432e311fd4f47bc9fef1eee2a733158d9e2c72a89cf76d414090d063a8d20fe378f2b2b8087df0a83b0f00a3244d1466b97a0d3b14344a7 - languageName: node - linkType: hard - "gopd@npm:^1.0.1": version: 1.0.1 resolution: "gopd@npm:1.0.1" @@ -14674,18 +14666,6 @@ __metadata: languageName: node linkType: hard -"react-hot-toast@npm:^2.4.1": - version: 2.4.1 - resolution: "react-hot-toast@npm:2.4.1" - dependencies: - goober: ^2.1.10 - peerDependencies: - react: ">=16" - react-dom: ">=16" - checksum: 3e337816db574782454bf09c63a8aca546bf9c5be3f83d0494d24bdcfd97ca2db64d4c151c4ab0184d2342d7a7226403e6812e70caf03c8b55a07787bb4ad0f2 - languageName: node - linkType: hard - "react-inspector@npm:^6.0.0": version: 6.0.2 resolution: "react-inspector@npm:6.0.2" @@ -14745,6 +14725,15 @@ __metadata: languageName: node linkType: hard +"react-modern-drawer@npm:^1.2.2": + version: 1.2.2 + resolution: "react-modern-drawer@npm:1.2.2" + peerDependencies: + react: ">16.0.0" + checksum: 379ad55a02b6c6d647448e5670ae99fc3d7bff70c43a07a978ac0ac18dbd40b055c2ca8f764627f4252451fa3d2125b2d90271eaaaf6a0048baa2ec6e577b756 + languageName: node + linkType: hard + "react-particles@npm:^2.12.2": version: 2.12.2 resolution: "react-particles@npm:2.12.2" @@ -15757,6 +15746,16 @@ __metadata: languageName: node linkType: hard +"sonner@npm:^1.0.3": + version: 1.0.3 + resolution: "sonner@npm:1.0.3" + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + checksum: e7233c9982c05413e24c7ee14af4439c734c713f5a4e4d5f2c4ca9425615f96e9c560d0053af3ff0555dc70aaff49079d05a0bdf90457e551bd2641925bd08fd + languageName: node + linkType: hard + "source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.2": version: 1.0.2 resolution: "source-map-js@npm:1.0.2"