mirror of
https://github.com/gosticks/plane.git
synced 2025-10-16 12:45:33 +00:00
[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
This commit is contained in:
parent
b8a88fe89c
commit
03479cf6b3
@ -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",
|
||||
}
|
||||
@ -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<typeof BaseDialog.Portal>) {
|
||||
return <BaseDialog.Portal data-slot="dialog-portal" {...props} />;
|
||||
// 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<typeof BaseDialog.Backdrop>) {
|
||||
return (
|
||||
<BaseDialog.Backdrop
|
||||
data-slot="dialog-overlay"
|
||||
className={cn(
|
||||
"fixed inset-0 z-30 bg-custom-backdrop transition-all duration-200 [&[data-ending-style]]:opacity-0 [&[data-starting-style]]:opacity-0",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
// Types
|
||||
export type DialogPosition = "center" | "top";
|
||||
|
||||
export interface DialogProps extends React.ComponentProps<typeof BaseDialog.Root> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function Dialog({ ...props }: React.ComponentProps<typeof BaseDialog.Root>) {
|
||||
return <BaseDialog.Root data-slot="dialog" {...props} />;
|
||||
export interface DialogPanelProps extends React.ComponentProps<typeof BaseDialog.Popup> {
|
||||
width?: EDialogWidth;
|
||||
position?: DialogPosition;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function DialogTrigger({ ...props }: React.ComponentProps<typeof BaseDialog.Trigger>) {
|
||||
return <BaseDialog.Trigger data-slot="dialog-trigger" {...props} />;
|
||||
export interface DialogTitleProps extends React.ComponentProps<typeof BaseDialog.Title> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function DialogPanel({
|
||||
className,
|
||||
width = EDialogWidth.XXL,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof BaseDialog.Popup> & { width?: EDialogWidth }) {
|
||||
return (
|
||||
<DialogPortal data-slot="dialog-portal">
|
||||
<DialogOverlay />
|
||||
<BaseDialog.Popup
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
"fixed flex justify-center top-0 left-0 w-full z-30 px-4 sm:py-20 overflow-y-auto overflow-hidden outline-none"
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
"rounded-lg bg-custom-background-100 text-left shadow-custom-shadow-md transition-all w-full",
|
||||
width,
|
||||
className
|
||||
)}
|
||||
// Constants
|
||||
const OVERLAY_CLASSNAME = cn("fixed inset-0 z-backdrop bg-custom-backdrop");
|
||||
const BASE_CLASSNAME = "relative text-left bg-custom-background-100 rounded-lg shadow-md w-full z-modal";
|
||||
|
||||
// Utility functions
|
||||
const getPositionClassNames = React.useCallback(
|
||||
(position: DialogPosition) =>
|
||||
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<React.ComponentProps<typeof BaseDialog.Portal>>(({ children, ...props }) => (
|
||||
<BaseDialog.Portal data-slot="dialog-portal" {...props}>
|
||||
{children}
|
||||
</BaseDialog.Portal>
|
||||
));
|
||||
DialogPortal.displayName = "DialogPortal";
|
||||
|
||||
const DialogOverlay = React.memo<React.ComponentProps<typeof BaseDialog.Backdrop>>(({ className, ...props }) => (
|
||||
<BaseDialog.Backdrop data-slot="dialog-overlay" className={cn(OVERLAY_CLASSNAME, className)} {...props} />
|
||||
));
|
||||
DialogOverlay.displayName = "DialogOverlay";
|
||||
|
||||
const DialogComponent = React.memo<DialogProps>(({ children, ...props }) => (
|
||||
<BaseDialog.Root data-slot="dialog" {...props}>
|
||||
{children}
|
||||
</BaseDialog.Root>
|
||||
));
|
||||
DialogComponent.displayName = "Dialog";
|
||||
|
||||
const DialogTrigger = React.memo<React.ComponentProps<typeof BaseDialog.Trigger>>(({ children, ...props }) => (
|
||||
<BaseDialog.Trigger data-slot="dialog-trigger" {...props}>
|
||||
{children}
|
||||
</BaseDialog.Trigger>
|
||||
));
|
||||
DialogTrigger.displayName = "DialogTrigger";
|
||||
|
||||
const DialogPanel = React.forwardRef<React.ElementRef<typeof BaseDialog.Popup>, DialogPanelProps>(
|
||||
({ className, width = EDialogWidth.XXL, children, position = "center", ...props }, ref) => {
|
||||
const positionClassNames = React.useMemo(() => getPositionClassNames(position), [position]);
|
||||
return (
|
||||
<DialogPortal>
|
||||
<DialogOverlay />
|
||||
<BaseDialog.Popup
|
||||
ref={ref}
|
||||
data-slot="dialog-content"
|
||||
className={cn(BASE_CLASSNAME, positionClassNames, width, className)}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</BaseDialog.Popup>
|
||||
</DialogPortal>
|
||||
);
|
||||
}
|
||||
</BaseDialog.Popup>
|
||||
</DialogPortal>
|
||||
);
|
||||
}
|
||||
);
|
||||
DialogPanel.displayName = "DialogPanel";
|
||||
|
||||
function DialogTitle({ className, ...props }: React.ComponentProps<typeof BaseDialog.Title>) {
|
||||
return (
|
||||
<BaseDialog.Title
|
||||
data-slot="dialog-title"
|
||||
className={cn("text-lg leading-none font-semibold", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
// compound components
|
||||
Dialog.Trigger = DialogTrigger;
|
||||
Dialog.Panel = DialogPanel;
|
||||
Dialog.Title = DialogTitle;
|
||||
const DialogTitle = React.memo<DialogTitleProps>(({ className, children, ...props }) => (
|
||||
<BaseDialog.Title data-slot="dialog-title" className={cn("text-lg leading-none font-semibold", className)} {...props}>
|
||||
{children}
|
||||
</BaseDialog.Title>
|
||||
));
|
||||
|
||||
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 };
|
||||
|
||||
@ -1 +1 @@
|
||||
export * from "./root";
|
||||
export * from "./root";
|
||||
|
||||
@ -97,9 +97,11 @@ const PopoverPortal = React.memo<React.ComponentProps<typeof BasePopover.Portal>
|
||||
return <BasePopover.Portal data-slot="popover-portal" {...props} />;
|
||||
});
|
||||
|
||||
const PopoverPositioner = React.memo<React.ComponentProps<typeof BasePopover.Positioner>>(function PopoverPositioner(props) {
|
||||
return <BasePopover.Positioner data-slot="popover-positioner" {...props} />;
|
||||
});
|
||||
const PopoverPositioner = React.memo<React.ComponentProps<typeof BasePopover.Positioner>>(
|
||||
function PopoverPositioner(props) {
|
||||
return <BasePopover.Positioner data-slot="popover-positioner" {...props} />;
|
||||
}
|
||||
);
|
||||
|
||||
// compound components
|
||||
const Popover = Object.assign(
|
||||
@ -119,4 +121,4 @@ PopoverPortal.displayName = "PopoverPortal";
|
||||
PopoverTrigger.displayName = "PopoverTrigger";
|
||||
PopoverPositioner.displayName = "PopoverPositioner";
|
||||
|
||||
export { Popover};
|
||||
export { Popover };
|
||||
|
||||
@ -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: [
|
||||
|
||||
Loading…
Reference in New Issue
Block a user