Skip to content

Commit

Permalink
[sparkle] - refacto: rename NewDialog -> Dialog (#10162)
Browse files Browse the repository at this point in the history
* [sparkle] - refactor: remove Dialog component and associated story

 - The Dialog component along with its story has been deleted from the codebase
 - The reference to the Dialog component in the components index has been removed

* [sparkle] - refactor: rename NewDialog components to Dialog

 - Renamed all instances of "NewDialog" to simply "Dialog" to standardize component naming
 - Updated associated file names and import paths to reflect the new component names
 - Adjusted internal variable and component names within the Dialog components for consistency

* [sparkle] - feature: bump package version to 0.2.372

 - Increment the package version in package-lock and package.json for new release
 - Ensure consistency across package definition files for dependency management

* fix: lint/format

* [sparkle] - refactor: update dialog component usage in DataTable stories

 - Replaced deprecated 'NewDialog' components with the updated 'Dialog' components
 - Adjusted component props and children to match the new Dialog API structure

* [sparkle] - refactor: remove ElementDialog component and its story

 - Deleted the ElementDialog component as it is no longer in use
 - Removed the ElementDialog story from Storybook to reflect changes in components
 - Updated components index to exclude ElementDialog from exports
  • Loading branch information
JulesBelveze authored Jan 23, 2025
1 parent b0fecb9 commit 1420303
Show file tree
Hide file tree
Showing 10 changed files with 382 additions and 706 deletions.
4 changes: 2 additions & 2 deletions sparkle/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sparkle/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dust-tt/sparkle",
"version": "0.2.371",
"version": "0.2.372",
"scripts": {
"build": "rm -rf dist && npm run tailwind && npm run build:esm && npm run build:cjs",
"tailwind": "tailwindcss -i ./src/styles/tailwind.css -o dist/sparkle.css",
Expand Down
313 changes: 192 additions & 121 deletions sparkle/src/components/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,128 +1,199 @@
import { Dialog as HeadlessDialog, Transition } from "@headlessui/react";
import React, { Fragment, useRef } from "react";

import ConfettiBackground from "@sparkle/components/ConfettiBackground";
import Spinner from "@sparkle/components/Spinner";
import { classNames } from "@sparkle/lib/utils";

import { Button } from "./Button";

export type BaseDialogProps = {
backgroundType?: "confetti" | "snow" | "none";
children: React.ReactNode;
disabled?: boolean;
isOpen: boolean;
isSaving?: boolean;
onValidate: () => void;
title: string;
validateLabel?: string;
validateVariant?: React.ComponentProps<typeof Button>["variant"];
cancelLabel?: string;
};
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { FocusScope } from "@radix-ui/react-focus-scope";
import { cva } from "class-variance-authority";
import * as React from "react";

export type DialogProps = BaseDialogProps & {
alertDialog?: false;
onCancel: () => void;
};
import { Button, ScrollArea } from "@sparkle/components";
import { XMarkIcon } from "@sparkle/icons";
import { cn } from "@sparkle/lib/utils";

const Dialog = DialogPrimitive.Root;
const DialogTrigger = DialogPrimitive.Trigger;
const DialogClose = DialogPrimitive.Close;
const DialogPortal = DialogPrimitive.Portal;

export type AlertDialogProps = BaseDialogProps & {
alertDialog: true;
onCancel?: () => void;
const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Overlay
className={cn(
"s-fixed s-inset-0 s-z-50 s-bg-muted-foreground/75 data-[state=open]:s-animate-in data-[state=closed]:s-animate-out data-[state=closed]:s-fade-out-0 data-[state=open]:s-fade-in-0",
className
)}
{...props}
ref={ref}
/>
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;

const DIALOG_SIZES = ["md", "lg", "xl"] as const;
type DialogSizeType = (typeof DIALOG_SIZES)[number];

const sizeClasses: Record<DialogSizeType, string> = {
md: "sm:s-max-w-md",
lg: "sm:s-max-w-xl",
xl: "sm:s-max-w-3xl",
};

export function Dialog({
backgroundType = "none",
const dialogVariants = cva(
"s-fixed s-left-[50%] s-top-[50%] s-z-50 s-grid s-w-full s-overflow-hidden s-rounded-2xl s-border s-border-border s-translate-x-[-50%] s-translate-y-[-50%] s-border s-bg-background s-p-2 s-shadow-lg s-duration-200 data-[state=open]:s-animate-in data-[state=closed]:s-animate-out data-[state=closed]:s-fade-out-0 data-[state=open]:s-fade-in-0 data-[state=closed]:s-zoom-out-95 data-[state=open]:s-zoom-in-95 data-[state=closed]:s-slide-out-to-left-1/2 data-[state=closed]:s-slide-out-to-top-[48%] data-[state=open]:s-slide-in-from-left-1/2 data-[state=open]:s-slide-in-from-top-[48%] s-sm:rounded-lg",
{
variants: {
size: sizeClasses,
},
defaultVariants: {
size: "md",
},
}
);

interface DialogContentProps
extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
size?: DialogSizeType;
trapFocusScope?: boolean;
isAlertDialog?: boolean;
}

const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
DialogContentProps
>(
(
{ className, children, size, trapFocusScope, isAlertDialog, ...props },
ref
) => (
<DialogPortal>
<DialogOverlay />
<FocusScope trapped={trapFocusScope} asChild>
<DialogPrimitive.Content
ref={ref}
className={cn(dialogVariants({ size }), className)}
onInteractOutside={
isAlertDialog ? (e) => e.preventDefault() : props.onInteractOutside
}
{...props}
>
{children}
</DialogPrimitive.Content>
</FocusScope>
</DialogPortal>
)
);
DialogContent.displayName = DialogPrimitive.Content.displayName;

interface NewDialogHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
hideButton?: boolean;
}

const DialogHeader = ({
className,
children,
disabled,
isOpen,
isSaving,
title,
validateLabel = "Ok",
validateVariant = "primary",
onValidate,
hideButton = false,
...props
}: AlertDialogProps | DialogProps) {
const referentRef = useRef<HTMLDivElement>(null);

return (
<Transition show={isOpen} as={Fragment} appear={true}>
<HeadlessDialog
as="div"
className="s-relative s-z-50"
// If it's an alert dialog, we don't want to close it when clicking outside.
onClose={props.alertDialog ? () => {} : props.onCancel}
role={props.alertDialog ? "alertdialog" : "dialog"}
>
<Transition.Child
as={Fragment}
enter="s-ease-out s-duration-150"
enterFrom="s-opacity-0"
enterTo="s-opacity-100"
leave="s-ease-in s-duration-150"
leaveFrom="s-opacity-100"
leaveTo="s-opacity-0"
>
<div className="s-fixed s-inset-0 s-bg-structure-50/80 s-backdrop-blur-sm s-transition-opacity" />
</Transition.Child>

<div className="s-fixed s-inset-0 s-z-50">
<div className="s-flex s-min-h-full s-items-center s-justify-center">
<Transition.Child
as={Fragment}
enter="s-ease-out s-duration-300"
enterFrom="s-opacity-0 s-translate-y-4 s-scale-95"
enterTo="s-opacity-100 s-translate-y-0 s-scale-100"
leave="s-ease-in s-duration-200"
leaveFrom="s-opacity-100 s-translate-y-0 s-scale-100"
leaveTo="s-opacity-0 s-translate-y-4 s-scale-95"
>
<HeadlessDialog.Panel
className={classNames(
"s-relative s-rounded-xl s-border s-border-structure-100 s-bg-structure-0 s-p-4 s-shadow-xl s-transition-all",
"s-w-full sm:s-w-[448px]",
"s-flex s-flex-col s-gap-6"
)}
ref={referentRef}
>
<HeadlessDialog.Title className="s-truncate s-text-lg s-font-medium s-text-element-950">
{title}
</HeadlessDialog.Title>
<div className="s-text-base s-text-element-700">{children}</div>
<div className="s-flex s-w-full s-justify-end">
<div className="s-flex s-gap-2">
{!isSaving && (
<>
{props.onCancel && (
<Button
label={props.cancelLabel ?? "Cancel"}
variant="outline"
onClick={props.onCancel}
/>
)}
<Button
disabled={disabled}
label={validateLabel}
variant={validateVariant}
onClick={onValidate}
/>
</>
)}
{isSaving && <Spinner variant="color" />}
</div>
</div>
{backgroundType !== "none" && (
<div className="s-absolute s-bottom-0 s-left-0 s-right-0 s-top-0 s-z-0">
<ConfettiBackground
variant={backgroundType}
referentSize={referentRef}
/>
</div>
)}
</HeadlessDialog.Panel>
</Transition.Child>
</div>
</div>
</HeadlessDialog>
</Transition>
);
}: NewDialogHeaderProps) => (
<div
className={cn(
"s-z-50 s-flex s-flex-none s-flex-col s-gap-0 s-p-5 s-text-left",
className
)}
{...props}
>
{children}
<DialogClose asChild className="s-absolute s-right-3 s-top-3">
{!hideButton && <Button icon={XMarkIcon} variant="ghost" size="sm" />}
</DialogClose>
</div>
);
DialogHeader.displayName = "DialogHeader";

const DialogContainer = ({
children,
}: React.HTMLAttributes<HTMLDivElement>) => (
<ScrollArea className="s-w-full s-flex-grow">
<div className="s-relative s-flex s-flex-col s-gap-2 s-p-5 s-text-left s-text-sm s-text-foreground">
{children}
</div>
</ScrollArea>
);
DialogContainer.displayName = "DialogContainer";

interface DialogFooterProps extends React.HTMLAttributes<HTMLDivElement> {
leftButtonProps?: React.ComponentProps<typeof Button>;
rightButtonProps?: React.ComponentProps<typeof Button>;
dialogCloseClassName?: string;
}

const DialogFooter = ({
className,
children,
leftButtonProps,
rightButtonProps,
dialogCloseClassName,
...props
}: DialogFooterProps) => (
<div
className={cn(
"s-flex s-flex-none s-flex-row s-justify-end s-gap-2 s-px-3 s-py-3",
className
)}
{...props}
>
{leftButtonProps &&
(leftButtonProps.disabled ? (
<Button {...leftButtonProps} />
) : (
<DialogClose className={dialogCloseClassName} asChild>
<Button {...leftButtonProps} />
</DialogClose>
))}
{rightButtonProps &&
(rightButtonProps.disabled ? (
<Button {...rightButtonProps} />
) : (
<DialogClose className={dialogCloseClassName} asChild>
<Button {...rightButtonProps} />
</DialogClose>
))}
{children}
</div>
);
DialogFooter.displayName = "DialogFooter";

const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn("s-text-lg s-font-semibold s-text-foreground", className)}
{...props}
/>
));
DialogTitle.displayName = DialogPrimitive.Title.displayName;

const DialogDescription = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("s-text-sm s-text-muted-foreground", className)}
{...props}
/>
));
DialogDescription.displayName = DialogPrimitive.Description.displayName;

export {
Dialog,
DialogClose,
DialogContainer,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogOverlay,
DialogPortal,
DialogTitle,
DialogTrigger,
};
41 changes: 0 additions & 41 deletions sparkle/src/components/ElementDialog.tsx

This file was deleted.

Loading

0 comments on commit 1420303

Please sign in to comment.