From c5797a8a116ddc20cf27d90b7ae033695f3cca31 Mon Sep 17 00:00:00 2001 From: kcwww Date: Mon, 23 Sep 2024 13:52:54 +0900 Subject: [PATCH] feat: add useModal custom hook --- .../_components/IntroButtonSection.tsx | 13 +++++++-- components/ui/dialog.tsx | 5 ---- package.json | 3 ++- pnpm-lock.yaml | 27 +++++++++++++++++++ .../{testModal.tsx => IntroduceModal.tsx} | 26 +++++++++++------- shared/components/ui/UISection.tsx | 3 +++ shared/hooks/useModal.ts | 25 +++++++++++++++++ shared/provider/ModalProvider.tsx | 20 ++++++++++++++ 8 files changed, 104 insertions(+), 18 deletions(-) rename shared/components/modals/{testModal.tsx => IntroduceModal.tsx} (57%) create mode 100644 shared/hooks/useModal.ts create mode 100644 shared/provider/ModalProvider.tsx diff --git a/app/(landing)/_components/IntroButtonSection.tsx b/app/(landing)/_components/IntroButtonSection.tsx index d261eeb..84cb7d5 100644 --- a/app/(landing)/_components/IntroButtonSection.tsx +++ b/app/(landing)/_components/IntroButtonSection.tsx @@ -1,7 +1,16 @@ -import TestModal from '@/shared/components/modals/testModal'; +'use client'; + +import { Button } from '@/components/ui/button'; +import useModal from '@/shared/hooks/useModal'; const IntroButtonSection = () => { - return ; + const { onOpen } = useModal(); + + return ( + + ); }; export default IntroButtonSection; diff --git a/components/ui/dialog.tsx b/components/ui/dialog.tsx index b552952..d737a8d 100644 --- a/components/ui/dialog.tsx +++ b/components/ui/dialog.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import * as DialogPrimitive from '@radix-ui/react-dialog'; -import { X } from 'lucide-react'; import { cn } from '@/lib/utils'; @@ -44,10 +43,6 @@ const DialogContent = React.forwardRef< {...props} > {children} - - - Close - )); diff --git a/package.json b/package.json index dc2aa2c..803b7ab 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", "three": "^0.164.1", - "vaul": "^0.9.4" + "vaul": "^0.9.4", + "zustand": "5.0.0-rc.2" }, "devDependencies": { "@storybook/addon-essentials": "^8.1.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 648cd33..5fa901f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,6 +56,9 @@ importers: vaul: specifier: ^0.9.4 version: 0.9.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + zustand: + specifier: 5.0.0-rc.2 + version: 5.0.0-rc.2(@types/react@18.3.3)(react@18.3.1)(use-sync-external-store@1.2.2(react@18.3.1)) devDependencies: '@storybook/addon-essentials': specifier: ^8.1.5 @@ -6673,6 +6676,24 @@ packages: react: optional: true + zustand@5.0.0-rc.2: + resolution: {integrity: sha512-o2Nwuvnk8vQBX7CcHL8WfFkZNJdxB/VKeWw0tNglw8p4cypsZ3tRT7rTRTDNeUPFS0qaMBRSKe+fVwL5xpcE3A==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + snapshots: '@adobe/css-tools@4.3.3': {} @@ -14600,3 +14621,9 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 react: 18.3.1 + + zustand@5.0.0-rc.2(@types/react@18.3.3)(react@18.3.1)(use-sync-external-store@1.2.2(react@18.3.1)): + optionalDependencies: + '@types/react': 18.3.3 + react: 18.3.1 + use-sync-external-store: 1.2.2(react@18.3.1) diff --git a/shared/components/modals/testModal.tsx b/shared/components/modals/IntroduceModal.tsx similarity index 57% rename from shared/components/modals/testModal.tsx rename to shared/components/modals/IntroduceModal.tsx index a4dada6..da7f900 100644 --- a/shared/components/modals/testModal.tsx +++ b/shared/components/modals/IntroduceModal.tsx @@ -1,23 +1,26 @@ 'use client'; +import useModal from '@/shared/hooks/useModal'; + import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, - DialogTrigger, + DialogFooter, } from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; + +const IntroduceModal = () => { + const { isOpen, onClose } = useModal(); + + if (!isOpen) { + return null; + } -const TestModal = () => { return ( - - - Open - + Are you absolutely sure? @@ -26,9 +29,12 @@ const TestModal = () => { account and remove your data from our servers. + + + ); }; -export default TestModal; +export default IntroduceModal; diff --git a/shared/components/ui/UISection.tsx b/shared/components/ui/UISection.tsx index e7c7c02..e1e073b 100644 --- a/shared/components/ui/UISection.tsx +++ b/shared/components/ui/UISection.tsx @@ -1,3 +1,5 @@ +import ModalProvider from '@/shared/provider/ModalProvider'; + const UISection = ({ children }: { children: React.ReactNode }) => { return (
{ }} > {children} +
); }; diff --git a/shared/hooks/useModal.ts b/shared/hooks/useModal.ts new file mode 100644 index 0000000..e75af15 --- /dev/null +++ b/shared/hooks/useModal.ts @@ -0,0 +1,25 @@ +import { create } from 'zustand'; + +export type ModalType = 'Intro'; + +export interface ModalProps { + data?: null; // temp +} + +interface ModalStore { + type: ModalType | null; + props: ModalProps; + isOpen: boolean; + onOpen: (type: ModalType, props?: ModalProps) => void; + onClose: () => void; +} + +const useModal = create((set) => ({ + type: null, + props: {}, + isOpen: false, + onOpen: (type, props) => set({ type, props, isOpen: true }), + onClose: () => set({ type: null, props: {}, isOpen: false }), +})); + +export default useModal; diff --git a/shared/provider/ModalProvider.tsx b/shared/provider/ModalProvider.tsx new file mode 100644 index 0000000..e643f97 --- /dev/null +++ b/shared/provider/ModalProvider.tsx @@ -0,0 +1,20 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import IntroduceModal from '@/shared/components/modals/IntroduceModal'; + +const ModalProvider = () => { + const [isMounted, setIsMounted] = useState(false); + + useEffect(() => { + setIsMounted(true); + }, []); + + if (!isMounted) { + return null; + } + + return ; +}; + +export default ModalProvider;