From 03479cf6b38d0518b616ee2954627aec85cec9d2 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Wed, 20 Aug 2025 22:17:26 +0530 Subject: [PATCH] [WEB-4684] chore: dialog component enhancements (#7606) * chore: z-index tokens added * chore: dialog component code refactor * chore: dialog component improvements * fix: lint error * fix: lint error * fix: format error --- packages/propel/src/dialog/constants.ts | 17 --- packages/propel/src/dialog/root.tsx | 159 ++++++++++++-------- packages/propel/src/popover/index.ts | 2 +- packages/propel/src/popover/root.tsx | 10 +- packages/tailwind-config/tailwind.config.js | 14 ++ 5 files changed, 121 insertions(+), 81 deletions(-) delete mode 100644 packages/propel/src/dialog/constants.ts diff --git a/packages/propel/src/dialog/constants.ts b/packages/propel/src/dialog/constants.ts deleted file mode 100644 index d08202534a..0000000000 --- a/packages/propel/src/dialog/constants.ts +++ /dev/null @@ -1,17 +0,0 @@ -export enum EDialogPosition { - TOP = "flex items-center justify-center text-center mx-4 my-10 md:my-20", - CENTER = "flex items-end sm:items-center justify-center p-4 min-h-full", -} - -export enum EDialogWidth { - SM = "sm:max-w-sm", - MD = "sm:max-w-md", - LG = "sm:max-w-lg", - XL = "sm:max-w-xl", - XXL = "sm:max-w-2xl", - XXXL = "sm:max-w-3xl", - XXXXL = "sm:max-w-4xl", - VXL = "sm:max-w-5xl", - VIXL = "sm:max-w-6xl", - VIIXL = "sm:max-w-7xl", -} diff --git a/packages/propel/src/dialog/root.tsx b/packages/propel/src/dialog/root.tsx index 9e781a9b45..f981c19fb5 100644 --- a/packages/propel/src/dialog/root.tsx +++ b/packages/propel/src/dialog/root.tsx @@ -3,75 +3,116 @@ import * as React from "react"; import { Dialog as BaseDialog } from "@base-ui-components/react"; import { cn } from "@plane/utils"; -import { EDialogWidth } from "./constants"; -function DialogPortal({ ...props }: React.ComponentProps) { - return ; +// enums + +export enum EDialogWidth { + SM = "sm:max-w-sm", + MD = "sm:max-w-md", + LG = "sm:max-w-lg", + XL = "sm:max-w-xl", + XXL = "sm:max-w-2xl", + XXXL = "sm:max-w-3xl", + XXXXL = "sm:max-w-4xl", + VXL = "sm:max-w-5xl", + VIXL = "sm:max-w-6xl", + VIIXL = "sm:max-w-7xl", } -function DialogOverlay({ className, ...props }: React.ComponentProps) { - return ( - - ); +// Types +export type DialogPosition = "center" | "top"; + +export interface DialogProps extends React.ComponentProps { + children: React.ReactNode; } -function Dialog({ ...props }: React.ComponentProps) { - return ; +export interface DialogPanelProps extends React.ComponentProps { + width?: EDialogWidth; + position?: DialogPosition; + children: React.ReactNode; } -function DialogTrigger({ ...props }: React.ComponentProps) { - return ; +export interface DialogTitleProps extends React.ComponentProps { + children: React.ReactNode; } -function DialogPanel({ - className, - width = EDialogWidth.XXL, - children, - ...props -}: React.ComponentProps & { width?: EDialogWidth }) { - return ( - - - -
+ cn("isolate fixed z-modal", { + "top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2": position === "center", + "top-8 left-1/2 -translate-x-1/2": position === "top", + }), + [] +); + +const DialogPortal = React.memo>(({ children, ...props }) => ( + + {children} + +)); +DialogPortal.displayName = "DialogPortal"; + +const DialogOverlay = React.memo>(({ className, ...props }) => ( + +)); +DialogOverlay.displayName = "DialogOverlay"; + +const DialogComponent = React.memo(({ children, ...props }) => ( + + {children} + +)); +DialogComponent.displayName = "Dialog"; + +const DialogTrigger = React.memo>(({ children, ...props }) => ( + + {children} + +)); +DialogTrigger.displayName = "DialogTrigger"; + +const DialogPanel = React.forwardRef, DialogPanelProps>( + ({ className, width = EDialogWidth.XXL, children, position = "center", ...props }, ref) => { + const positionClassNames = React.useMemo(() => getPositionClassNames(position), [position]); + return ( + + + {children} -
-
-
- ); -} + + + ); + } +); +DialogPanel.displayName = "DialogPanel"; -function DialogTitle({ className, ...props }: React.ComponentProps) { - return ( - - ); -} -// compound components -Dialog.Trigger = DialogTrigger; -Dialog.Panel = DialogPanel; -Dialog.Title = DialogTitle; +const DialogTitle = React.memo(({ className, children, ...props }) => ( + + {children} + +)); -export { Dialog, DialogTitle, DialogTrigger, DialogPanel }; +DialogTitle.displayName = "DialogTitle"; + +// Create the compound Dialog component with proper typing +const Dialog = Object.assign(DialogComponent, { + Panel: DialogPanel, + Title: DialogTitle, +}) as typeof DialogComponent & { + Panel: typeof DialogPanel; + Title: typeof DialogTitle; +}; + +export { Dialog, DialogTitle, DialogPanel }; diff --git a/packages/propel/src/popover/index.ts b/packages/propel/src/popover/index.ts index 50a9c47c01..1efe34c51e 100644 --- a/packages/propel/src/popover/index.ts +++ b/packages/propel/src/popover/index.ts @@ -1 +1 @@ -export * from "./root"; \ No newline at end of file +export * from "./root"; diff --git a/packages/propel/src/popover/root.tsx b/packages/propel/src/popover/root.tsx index 15ff23df67..4509b1c40f 100644 --- a/packages/propel/src/popover/root.tsx +++ b/packages/propel/src/popover/root.tsx @@ -97,9 +97,11 @@ const PopoverPortal = React.memo return ; }); -const PopoverPositioner = React.memo>(function PopoverPositioner(props) { - return ; -}); +const PopoverPositioner = React.memo>( + function PopoverPositioner(props) { + return ; + } +); // compound components const Popover = Object.assign( @@ -119,4 +121,4 @@ PopoverPortal.displayName = "PopoverPortal"; PopoverTrigger.displayName = "PopoverTrigger"; PopoverPositioner.displayName = "PopoverPositioner"; -export { Popover}; +export { Popover }; diff --git a/packages/tailwind-config/tailwind.config.js b/packages/tailwind-config/tailwind.config.js index cf6b574aa4..cc8c113922 100644 --- a/packages/tailwind-config/tailwind.config.js +++ b/packages/tailwind-config/tailwind.config.js @@ -442,6 +442,20 @@ module.exports = { fontFamily: { custom: ["Inter", "sans-serif"], }, + zIndex: { + base: 0 /* default content */, + header: 10 /* sticky headers, navbars */, + sidebar: 20 /* sidebars, drawers */, + dropdown: 30 /* dropdowns, select menus */, + popover: 40 /* popovers, hovercards */, + tooltip: 50 /* tooltips, hints */, + sticky: 60 /* sticky UI */, + backdrop: 90 /* backdrop / overlay */, + modal: 100 /* dialogs, modals */, + toast: 110 /* toast, alerts */, + loader: 120 /* blocking loader/spinner */, + max: 9999 /* emergency override (rare use) */, + }, }, }, plugins: [