refactor: dialog auto swap platform primitives (#14186)
* refactor: dialog auto swap platform primities * fixup! refactor: dialog auto swap platform primities * fixup! fixup! refactor: dialog auto swap platform primities
This commit is contained in:
@@ -13,15 +13,15 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { TimeRange, WorkingHours } from "@calcom/types/schedule";
|
||||
import {
|
||||
Button,
|
||||
ConfirmationDialogContent as WebConfirmationDialogContent,
|
||||
Dialog as WebDialog,
|
||||
DialogTrigger as WebDialogTrigger,
|
||||
ConfirmationDialogContent,
|
||||
EditableHeading,
|
||||
Form,
|
||||
SkeletonText,
|
||||
Dialog,
|
||||
DialogTrigger,
|
||||
Label,
|
||||
SelectSkeletonLoader,
|
||||
Skeleton,
|
||||
SkeletonText,
|
||||
Switch,
|
||||
TimezoneSelect as WebTimezoneSelect,
|
||||
Tooltip,
|
||||
@@ -29,11 +29,6 @@ import {
|
||||
} from "@calcom/ui";
|
||||
import { ArrowLeft, Info, MoreVertical, Plus, Trash } from "@calcom/ui/components/icon";
|
||||
|
||||
import { ConfirmationDialogContent as PlatformConfirmationDialogContent } from "../src/components/ui/confirmation-dialog-content";
|
||||
import {
|
||||
Dialog as PlatformDialog,
|
||||
DialogTrigger as PlatformDialogTrigger,
|
||||
} from "../src/components/ui/dialog";
|
||||
import { Shell as PlatformShell } from "../src/components/ui/shell";
|
||||
import { cn } from "../src/lib/utils";
|
||||
import { Timezone as PlatformTimzoneSelect } from "../timezone/index";
|
||||
@@ -96,22 +91,14 @@ const DeleteDialogButton = ({
|
||||
buttonClassName,
|
||||
isPending,
|
||||
onDeleteConfirmed,
|
||||
isPlatform,
|
||||
handleDelete,
|
||||
}: {
|
||||
disabled?: boolean;
|
||||
onDeleteConfirmed?: () => void;
|
||||
buttonClassName: string;
|
||||
isPlatform: boolean;
|
||||
handleDelete: () => void;
|
||||
isPending: boolean;
|
||||
}) => {
|
||||
const [Dialog, DialogTrigger, ConfirmationDialogContent] = useMemo(() => {
|
||||
return isPlatform
|
||||
? [PlatformDialog, PlatformDialogTrigger, PlatformConfirmationDialogContent]
|
||||
: [WebDialog, WebDialogTrigger, WebConfirmationDialogContent];
|
||||
}, [isPlatform]);
|
||||
|
||||
const { t } = useLocale();
|
||||
|
||||
return (
|
||||
@@ -318,7 +305,6 @@ export function AvailabilitySettings({
|
||||
disabled={schedule.isLastSchedule}
|
||||
isPending={isDeleting}
|
||||
handleDelete={handleDelete}
|
||||
isPlatform={isPlatform}
|
||||
/>
|
||||
<VerticalDivider className="hidden sm:inline" />
|
||||
<SmallScreenSideBar open={openSidebar}>
|
||||
@@ -342,7 +328,6 @@ export function AvailabilitySettings({
|
||||
disabled={schedule.isLastSchedule}
|
||||
isPending={isDeleting}
|
||||
handleDelete={handleDelete}
|
||||
isPlatform={isPlatform}
|
||||
onDeleteConfirmed={() => {
|
||||
setOpenSidebar(false);
|
||||
}}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
import type { PropsWithChildren } from "react";
|
||||
|
||||
import type { ConfirmationDialogContentProps } from "@calcom/ui";
|
||||
import { Button } from "@calcom/ui";
|
||||
import { AlertCircle, Check } from "@calcom/ui/components/icon";
|
||||
|
||||
import { DialogContent, DialogClose, DialogTitle, DialogDescription, DialogHeader } from "./dialog";
|
||||
|
||||
export function ConfirmationDialogContent(props: PropsWithChildren<ConfirmationDialogContentProps>) {
|
||||
const {
|
||||
title,
|
||||
variety,
|
||||
confirmBtn = null,
|
||||
confirmBtnText = "Confirm",
|
||||
cancelBtnText = "Cancel",
|
||||
loadingText = "Loading",
|
||||
isPending = false,
|
||||
onConfirm,
|
||||
children,
|
||||
} = props;
|
||||
return (
|
||||
<DialogContent>
|
||||
<>
|
||||
<div className="flex items-center">
|
||||
{variety && (
|
||||
<div className="mt-0.5 ltr:mr-3">
|
||||
{variety === "danger" && (
|
||||
<div className="bg-error mx-auto rounded-full p-2 text-center">
|
||||
<AlertCircle className="h-5 w-5 text-red-600 dark:text-red-100" />
|
||||
</div>
|
||||
)}
|
||||
{variety === "warning" && (
|
||||
<div className="bg-attention mx-auto rounded-full p-2 text-center">
|
||||
<AlertCircle className="h-5 w-5 text-orange-600" />
|
||||
</div>
|
||||
)}
|
||||
{variety === "success" && (
|
||||
<div className="bg-success mx-auto rounded-full p-2 text-center">
|
||||
<Check className="h-5 w-5 text-green-600" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<DialogHeader>
|
||||
<DialogTitle className="font-cal text-emphasis mt-2 text-xl">{title}</DialogTitle>
|
||||
<DialogDescription className="text-subtle text-sm">{children}</DialogDescription>
|
||||
</DialogHeader>
|
||||
</div>
|
||||
<div className="my-5 flex flex-row-reverse gap-x-2 sm:my-8">
|
||||
{confirmBtn ? (
|
||||
confirmBtn
|
||||
) : (
|
||||
<DialogClose asChild>
|
||||
<Button
|
||||
color="primary"
|
||||
onClick={(e) => onConfirm && onConfirm(e)}
|
||||
data-testid="dialog-confirmation">
|
||||
{isPending ? loadingText : confirmBtnText}
|
||||
</Button>
|
||||
</DialogClose>
|
||||
)}
|
||||
<DialogClose asChild>
|
||||
<Button disabled={isPending}>{cancelBtnText}</Button>
|
||||
</DialogClose>
|
||||
</div>
|
||||
</>
|
||||
</DialogContent>
|
||||
);
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import type { ReactNode } from "react";
|
||||
import { useMemo } from "react";
|
||||
import type { ReactNode, ForwardRefExoticComponent, ReactElement } from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { useIsPlatform, Dialog as PlatformDialogPrimitives } from "@calcom/atoms/monorepo";
|
||||
import classNames from "@calcom/lib/classNames";
|
||||
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
@@ -26,6 +28,11 @@ const enum DIALOG_STATE {
|
||||
}
|
||||
|
||||
export function Dialog(props: DialogProps) {
|
||||
const isPlatform = useIsPlatform();
|
||||
return !isPlatform ? <WebDialog {...props} /> : <PlatformDialogPrimitives.Dialog {...props} />;
|
||||
}
|
||||
|
||||
function WebDialog(props: DialogProps) {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const searchParams = useCompatSearchParams();
|
||||
@@ -70,6 +77,7 @@ export function Dialog(props: DialogProps) {
|
||||
|
||||
return <DialogPrimitive.Root {...dialogProps}>{children}</DialogPrimitive.Root>;
|
||||
}
|
||||
|
||||
type DialogContentProps = React.ComponentProps<(typeof DialogPrimitive)["Content"]> & {
|
||||
size?: "xl" | "lg" | "md";
|
||||
type?: "creation" | "confirmation";
|
||||
@@ -84,10 +92,22 @@ type DialogContentProps = React.ComponentProps<(typeof DialogPrimitive)["Content
|
||||
// enableOverflow:- use this prop whenever content inside DialogContent could overflow and require scrollbar
|
||||
export const DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps>(
|
||||
({ children, title, Icon, enableOverflow, type = "creation", ...props }, forwardedRef) => {
|
||||
const isPlatform = useIsPlatform();
|
||||
const [Portal, Overlay, Content] = useMemo(
|
||||
() =>
|
||||
isPlatform
|
||||
? [
|
||||
({ children }: { children: ReactElement | ReactElement[] }) => <>{children}</>,
|
||||
PlatformDialogPrimitives.DialogOverlay,
|
||||
PlatformDialogPrimitives.DialogContent,
|
||||
]
|
||||
: [DialogPrimitive.Portal, DialogPrimitive.Overlay, DialogPrimitive.Content],
|
||||
[isPlatform]
|
||||
);
|
||||
return (
|
||||
<DialogPrimitive.Portal>
|
||||
<DialogPrimitive.Overlay className="fadeIn fixed inset-0 z-50 bg-neutral-800 bg-opacity-70 transition-opacity dark:bg-opacity-70 " />
|
||||
<DialogPrimitive.Content
|
||||
<Portal>
|
||||
<Overlay className="fadeIn fixed inset-0 z-50 bg-neutral-800 bg-opacity-70 transition-opacity dark:bg-opacity-70 " />
|
||||
<Content
|
||||
{...props}
|
||||
className={classNames(
|
||||
"fadeIn bg-default scroll-bar fixed left-1/2 top-1/2 z-50 w-full max-w-[22rem] -translate-x-1/2 -translate-y-1/2 rounded-md text-left shadow-xl focus-visible:outline-none sm:align-middle",
|
||||
@@ -125,8 +145,8 @@ export const DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps
|
||||
</div>
|
||||
)}
|
||||
{!type && children}
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPrimitive.Portal>
|
||||
</Content>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -134,7 +154,7 @@ export const DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps
|
||||
type DialogHeaderProps = {
|
||||
title: React.ReactNode;
|
||||
subtitle?: React.ReactNode;
|
||||
};
|
||||
} & React.HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
export function DialogHeader(props: DialogHeaderProps) {
|
||||
if (!props.title) return null;
|
||||
@@ -152,7 +172,12 @@ export function DialogHeader(props: DialogHeaderProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export function DialogFooter(props: { children: ReactNode; className?: string; showDivider?: boolean }) {
|
||||
type DialogFooterProps = {
|
||||
children: React.ReactNode;
|
||||
showDivider?: boolean;
|
||||
} & React.HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
export function DialogFooter(props: DialogFooterProps) {
|
||||
return (
|
||||
<div className={classNames("bg-default sticky bottom-0", props.className)}>
|
||||
{props.showDivider && (
|
||||
@@ -172,8 +197,27 @@ export function DialogFooter(props: { children: ReactNode; className?: string; s
|
||||
|
||||
DialogContent.displayName = "DialogContent";
|
||||
|
||||
export const DialogTrigger = DialogPrimitive.Trigger;
|
||||
// export const DialogClose = DialogPrimitive.Close;
|
||||
export const DialogTrigger: ForwardRefExoticComponent<
|
||||
DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>
|
||||
> = React.forwardRef((props, ref) => {
|
||||
const isPlatform = useIsPlatform();
|
||||
return !isPlatform ? (
|
||||
<DialogPrimitive.Trigger {...props} ref={ref} />
|
||||
) : (
|
||||
<PlatformDialogPrimitives.DialogTrigger {...props} ref={ref} />
|
||||
);
|
||||
});
|
||||
|
||||
DialogTrigger.displayName = "DialogTrigger";
|
||||
|
||||
type DialogCloseProps = {
|
||||
"data-testid"?: string;
|
||||
dialogCloseProps?: React.ComponentProps<(typeof DialogPrimitive)["Close"]>;
|
||||
children?: ReactNode;
|
||||
onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
||||
disabled?: boolean;
|
||||
color?: ButtonProps["color"];
|
||||
} & React.ComponentProps<typeof Button>;
|
||||
|
||||
export function DialogClose(
|
||||
props: {
|
||||
@@ -186,8 +230,14 @@ export function DialogClose(
|
||||
} & React.ComponentProps<typeof Button>
|
||||
) {
|
||||
const { t } = useLocale();
|
||||
const isPlatform = useIsPlatform();
|
||||
const Close = useMemo(
|
||||
() => (isPlatform ? PlatformDialogPrimitives.DialogClose : DialogPrimitive.Close),
|
||||
[isPlatform]
|
||||
);
|
||||
|
||||
return (
|
||||
<DialogPrimitive.Close asChild {...props.dialogCloseProps}>
|
||||
<Close asChild {...props.dialogCloseProps}>
|
||||
{/* This will require the i18n string passed in */}
|
||||
<Button
|
||||
data-testid={props["data-testid"] || "dialog-rejection"}
|
||||
@@ -195,6 +245,8 @@ export function DialogClose(
|
||||
{...props}>
|
||||
{props.children ? props.children : t("Close")}
|
||||
</Button>
|
||||
</DialogPrimitive.Close>
|
||||
</Close>
|
||||
);
|
||||
}
|
||||
|
||||
DialogClose.displayName = "WebDialogClose";
|
||||
|
||||
Reference in New Issue
Block a user