diff --git a/app/_components/atoms/Modal.tsx b/app/_components/atoms/Modal.tsx new file mode 100644 index 0000000..df0bf5f --- /dev/null +++ b/app/_components/atoms/Modal.tsx @@ -0,0 +1,28 @@ +"use client"; +import { Modal as AntModal, ModalProps } from "antd"; +import { useAtom } from "jotai"; +import { modalReducerAtom } from "@/app/_data/modalState"; + +interface IModalProps extends ModalProps {} + +const Modal: React.FunctionComponent = ({}) => { + // reducer sample for jotai uses dispatch instead of setModal + const [modal, dispatch] = useAtom(modalReducerAtom); + + const handleCancel = () => { + dispatch({ type: "close" }); + }; + + return ( + + {modal?.content} + + ); +}; + +export default Modal; diff --git a/app/_components/atoms/index.ts b/app/_components/atoms/index.ts index 5607ff8..72211bb 100644 --- a/app/_components/atoms/index.ts +++ b/app/_components/atoms/index.ts @@ -3,6 +3,7 @@ import Card from "./Card"; import Logo from "./Logo"; import Button from "./Button"; import GitHub from "./GitHub"; +import Modal from "./Modal"; const Atom = { Visibility, @@ -10,6 +11,7 @@ const Atom = { Logo, Button, GitHub, -} + Modal, +}; export default Atom; diff --git a/app/_components/templates/Default.tsx b/app/_components/templates/Default.tsx index 124b1f2..44c2de1 100644 --- a/app/_components/templates/Default.tsx +++ b/app/_components/templates/Default.tsx @@ -1,12 +1,9 @@ -import Head from 'next/head'; +import Head from "next/head"; import Organism from "@organism"; import "../../_styles/globals.css"; +import Atom from "@atom"; -const Default = ({ - children, -}: { - children: React.ReactNode -}) => { +const Default = ({ children }: { children: React.ReactNode }) => { return ( @@ -18,12 +15,13 @@ const Default = ({ +
{children}
); -} +}; export default Default; diff --git a/app/_data/modalState.ts b/app/_data/modalState.ts new file mode 100644 index 0000000..c975892 --- /dev/null +++ b/app/_data/modalState.ts @@ -0,0 +1,31 @@ +"use client"; +import { ReactNode } from "react"; + +import { atomWithReducer } from "jotai/utils"; + +interface IModalState { + open: boolean; + content: ReactNode | null; +} + +const modalState: IModalState = { + open: false, + content: null, +}; + +const modalReducer = (prev: any, action: any) => { + // content is the content of the modal, for ex, a login form + // this will be passed on reducer action.payload + if (action.type == "open") + return { + open: true, + content: action.payload, + }; + if (action.type == "close") + return { + open: false, + content: null, + }; +}; + +export const modalReducerAtom = atomWithReducer(modalState, modalReducer); diff --git a/app/jotai-example/page.tsx b/app/jotai-example/page.tsx index c4e66a8..64f3a97 100644 --- a/app/jotai-example/page.tsx +++ b/app/jotai-example/page.tsx @@ -2,10 +2,18 @@ import { useAtom } from "jotai"; import { msgAtom } from "../_data/atoms"; import { useState } from "react"; +import { modalReducerAtom } from "../_data/modalState"; +import Atom from "@atom"; export default function JotaiExamplePage() { const [msg, setMsg] = useAtom(msgAtom); const [input, setInput] = useState(""); + const [modal, dispatch] = useAtom(modalReducerAtom); + + const open = () => { + // open a modal, payload will be the content of the modal + dispatch({ type: "open", payload:

TEST: This is a Modal

}); + }; return (
@@ -25,6 +33,7 @@ export default function JotaiExamplePage() { /> + Test Open Modal
); }