From 9098ebc29d236c2a6bff762b4caa7b70cdfe60e5 Mon Sep 17 00:00:00 2001 From: Innei Date: Wed, 26 Jun 2024 16:06:10 +0800 Subject: [PATCH] feat: modal Signed-off-by: Innei --- .../src/components/ui/modal/stacked/atom.ts | 5 ++ .../components/ui/modal/stacked/constants.ts | 2 + .../components/ui/modal/stacked/context.tsx | 10 +--- .../ui/modal/stacked/declarative-modal.tsx | 17 ++++--- .../src/components/ui/modal/stacked/hooks.tsx | 8 ++- .../src/components/ui/modal/stacked/index.ts | 1 + .../src/components/ui/modal/stacked/modal.tsx | 49 ++++++------------- .../components/ui/modal/stacked/overlay.tsx | 28 +++++++++++ .../components/ui/modal/stacked/provider.tsx | 5 +- 9 files changed, 71 insertions(+), 54 deletions(-) create mode 100644 src/renderer/src/components/ui/modal/stacked/atom.ts create mode 100644 src/renderer/src/components/ui/modal/stacked/overlay.tsx diff --git a/src/renderer/src/components/ui/modal/stacked/atom.ts b/src/renderer/src/components/ui/modal/stacked/atom.ts new file mode 100644 index 0000000000..63887799e4 --- /dev/null +++ b/src/renderer/src/components/ui/modal/stacked/atom.ts @@ -0,0 +1,5 @@ +import { atom } from "jotai" + +import type { ModalProps } from "./types" + +export const modalStackAtom = atom([] as (ModalProps & { id: string })[]) diff --git a/src/renderer/src/components/ui/modal/stacked/constants.ts b/src/renderer/src/components/ui/modal/stacked/constants.ts index 77eda61f82..631a9b304f 100644 --- a/src/renderer/src/components/ui/modal/stacked/constants.ts +++ b/src/renderer/src/components/ui/modal/stacked/constants.ts @@ -17,3 +17,5 @@ export const modalMontionConfig = { exit: initialStyle, transition: microReboundPreset, } + +export const MODAL_STACK_Z_INDEX = 100 diff --git a/src/renderer/src/components/ui/modal/stacked/context.tsx b/src/renderer/src/components/ui/modal/stacked/context.tsx index 19fa84e831..15ed315e4e 100644 --- a/src/renderer/src/components/ui/modal/stacked/context.tsx +++ b/src/renderer/src/components/ui/modal/stacked/context.tsx @@ -1,10 +1,5 @@ -import { atom } from "jotai" import type { FC, RefObject } from "react" -import { createContext, useContext } from "react" - -import type { ModalProps } from "./types" - -export const modalIdToPropsMap = {} as Record +import { createContext } from "react" export type CurrentModalContentProps = ModalContentPropsInternal & { ref: RefObject @@ -14,10 +9,7 @@ export const CurrentModalContext = createContext( null as any, ) -export const useCurrentModal = () => useContext(CurrentModalContext) - export type ModalContentComponent = FC export type ModalContentPropsInternal = { dismiss: () => void } -export const modalStackAtom = atom([] as (ModalProps & { id: string })[]) diff --git a/src/renderer/src/components/ui/modal/stacked/declarative-modal.tsx b/src/renderer/src/components/ui/modal/stacked/declarative-modal.tsx index 2d9da9d7b1..2ff00e17e2 100644 --- a/src/renderer/src/components/ui/modal/stacked/declarative-modal.tsx +++ b/src/renderer/src/components/ui/modal/stacked/declarative-modal.tsx @@ -4,8 +4,10 @@ import { AnimatePresence } from "framer-motion" import type { FC, ReactNode } from "react" import { useId, useMemo } from "react" -import { modalStackAtom } from "./context" +import { modalStackAtom } from "./atom" +import { MODAL_STACK_Z_INDEX } from "./constants" import { ModalInternal } from "./modal" +import { ModalOverlay } from "./overlay" import type { ModalProps } from "./types" export interface DeclarativeModalProps extends Omit { @@ -37,18 +39,19 @@ const DeclarativeModalImpl: FC = ({ return ( {open && ( - - {children} - + <> + + {children} + + + )} ) } const FooterAction: Component = ({ children, className }) => ( -
+
{children}
) diff --git a/src/renderer/src/components/ui/modal/stacked/hooks.tsx b/src/renderer/src/components/ui/modal/stacked/hooks.tsx index eb4c7b1553..8af9a12902 100644 --- a/src/renderer/src/components/ui/modal/stacked/hooks.tsx +++ b/src/renderer/src/components/ui/modal/stacked/hooks.tsx @@ -1,11 +1,13 @@ import { jotaiStore } from "@renderer/lib/jotai" import { useUIStore } from "@renderer/store" -import { useCallback, useEffect, useId, useRef } from "react" +import { useCallback, useContext, useEffect, useId, useRef } from "react" import { useLocation } from "react-router-dom" -import { modalIdToPropsMap, modalStackAtom } from "./context" +import { modalStackAtom } from "./atom" +import { CurrentModalContext } from "./context" import type { ModalProps, ModalStackOptions } from "./types" +export const modalIdToPropsMap = {} as Record export const useModalStack = (options?: ModalStackOptions) => { const id = useId() const currentCount = useRef(0) @@ -77,3 +79,5 @@ export const useDismissAllWhenRouterChange = () => { actions.dismissAll() }, [pathname]) } + +export const useCurrentModal = () => useContext(CurrentModalContext) diff --git a/src/renderer/src/components/ui/modal/stacked/index.ts b/src/renderer/src/components/ui/modal/stacked/index.ts index 6a1d3f5b9b..d1b95dde13 100644 --- a/src/renderer/src/components/ui/modal/stacked/index.ts +++ b/src/renderer/src/components/ui/modal/stacked/index.ts @@ -1,5 +1,6 @@ export * from "./context" export * from "./helper" +export * from "./hooks" export * from "./modal" export * from "./provider" export * from "./types" diff --git a/src/renderer/src/components/ui/modal/stacked/modal.tsx b/src/renderer/src/components/ui/modal/stacked/modal.tsx index e238011753..c11abf1ddf 100644 --- a/src/renderer/src/components/ui/modal/stacked/modal.tsx +++ b/src/renderer/src/components/ui/modal/stacked/modal.tsx @@ -15,36 +15,17 @@ import { useRef, } from "react" import { useEventCallback } from "usehooks-ts" -import { useShallow } from "zustand/react/shallow" import { Divider } from "../../divider" -import { modalMontionConfig } from "./constants" +import { modalStackAtom } from "./atom" +import { MODAL_STACK_Z_INDEX, modalMontionConfig } from "./constants" import type { CurrentModalContentProps, ModalContentPropsInternal, } from "./context" -import { CurrentModalContext, modalStackAtom } from "./context" +import { CurrentModalContext } from "./context" import type { ModalProps } from "./types" -const DialogOverlay = ({ - onClick, - zIndex, -}: { - onClick?: () => void - zIndex?: number -}) => ( - - - -) - export const ModalInternal: Component<{ item: ModalProps & { id: string } index: number @@ -73,12 +54,13 @@ export const ModalInternal: Component<{ [close], ) - const { opaque, overlay: defaultOverlay } = useUIStore( - useShallow((state) => ({ - overlay: state.modalOverlay, - opaque: state.modalOpaque, - })), - ) + // const { opaque, overlay: defaultOverlay } = useUIStore( + // useShallow((state) => ({ + // overlay: state.modalOverlay, + // opaque: state.modalOpaque, + // })), + // ) + const opaque = useUIStore((state) => state.modalOpaque) const { CustomModalComponent, @@ -90,10 +72,10 @@ export const ModalInternal: Component<{ wrapper: Wrapper = Fragment, max, icon, - overlay = defaultOverlay, + draggable = false, } = item - const modalStyle = useMemo(() => ({ zIndex: 99 + index }), [index]) + const zIndexStyle = useMemo(() => ({ zIndex: MODAL_STACK_Z_INDEX + index }), [index]) const dismiss = useCallback( (e: SyntheticEvent) => { e.stopPropagation() @@ -180,8 +162,6 @@ export const ModalInternal: Component<{ - {overlay && } - {title}
- {overlay && } -
void + zIndex?: number +}) => { + const modalSettingOverlay = useUIStore((state) => state.modalOverlay) + if (!modalSettingOverlay) return null + return ( + + + + ) +} diff --git a/src/renderer/src/components/ui/modal/stacked/provider.tsx b/src/renderer/src/components/ui/modal/stacked/provider.tsx index f97508e30e..3984df1153 100644 --- a/src/renderer/src/components/ui/modal/stacked/provider.tsx +++ b/src/renderer/src/components/ui/modal/stacked/provider.tsx @@ -2,9 +2,11 @@ import { AnimatePresence } from "framer-motion" import { useAtomValue } from "jotai" import type { FC, PropsWithChildren } from "react" -import { modalStackAtom } from "./context" +import { modalStackAtom } from "./atom" +import { MODAL_STACK_Z_INDEX } from "./constants" import { useDismissAllWhenRouterChange } from "./hooks" import { ModalInternal } from "./modal" +import { ModalOverlay } from "./overlay" export const ModalStackProvider: FC = ({ children }) => ( <> @@ -28,6 +30,7 @@ const ModalStack = () => { isTop={index === stack.length - 1} /> ))} + {stack.length > 0 && } ) }