Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,7 @@
},
"release": {
"branches": [
"main",
{
"name": "remove-unused-components",
"prerelease": true
},
{
"name": "refactor-simpler-build",
"prerelease": true
},
{
"name": "dark-mode-selector-css",
"prerelease": true
}
"main"
]
},
"publishConfig": {
Expand Down
112 changes: 82 additions & 30 deletions src/shadcn/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,93 @@ const DialogClose = DialogPrimitive.Close

const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
/>
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>>(({className, ...props}, ref) => (
<>
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed",
"inset-0 z-50",
"bg-black/40",
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
/>
</>
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName

const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className
)}
{...props}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<Cross2Icon className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
))
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
isDismissable?: boolean
isBottomDialog?: boolean
}
>(({
className,
children,
isDismissable = true,
isBottomDialog = false,
...props },
ref) => {
const base = [
"z-50",
"fixed",
"grid gap-4 p-6",
"border",
"bg-background",
"duration-200",
"data-[state=open]:animate-in data-[state=closed]:animate-out",
]

const centerStyles = [
"max-w-lg",
"left-[50%] top-[50%]",
"translate-x-[-50%] translate-y-[-50%]",
"sm:rounded-lg",
"shadow-lg",
"data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0",
"data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95",
"data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
"data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
].join(" ")

const bottomStyles = [
"left-0 bottom-0",
"w-full max-w-none",
"data-[state=open]:slide-in-from-bottom data-[state=closed]:slide-out-to-bottom",
].join(" ")

return (
<DialogPortal>
<DialogOverlay/>
<DialogPrimitive.Content
ref={ref}
className={cn(base, isBottomDialog ? bottomStyles : centerStyles, className)}

// By default dialog will close on outside click OR on escape key.
// We can use radix's primitive events to prevent this behavior when isDismissable is false
onInteractOutside={(e) => {
if (!isDismissable) e.preventDefault()
}}
onEscapeKeyDown={(e) => {
if (!isDismissable) e.preventDefault()
}}
{...props}
>
{children}

{isDismissable && (
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<Cross2Icon className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
)}
</DialogPrimitive.Content>
</DialogPortal>
)
})
DialogContent.displayName = DialogPrimitive.Content.displayName

const DialogHeader = ({
Expand Down
2 changes: 1 addition & 1 deletion src/shadcn/ui/sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const SheetOverlay = React.forwardRef<
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
"fixed inset-0 z-50 bg-black/20 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
Expand Down
70 changes: 54 additions & 16 deletions stories/shadcn/dialog.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,73 @@
import type { Meta, StoryObj } from "@storybook/react-vite";

import {
Dialog,
Button, Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
DialogTrigger
} from "src";

const DialogDemo = () => {
const DialogDemo = (props: {isOpen: boolean, isBottomDialog: boolean, isDismissable: boolean}) => {
return (
<Dialog>
<DialogTrigger>Open</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure absolutely sure?</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently delete your
account and remove your data from our servers.
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
<Dialog open={props.isOpen} >
<DialogContent
isDismissable={props.isDismissable}
isBottomDialog={props.isBottomDialog}
>
<DialogHeader className="mx-auto">
<DialogTitle>Privacy Notice</DialogTitle>
<DialogDescription>
<div className="flex gap-6 mx-auto">
<p className="flex-col-3">
We use cookies and similar technologies to improve your experience on our site, to analyze our traffic, and to understand where our audience is coming from.
</p>
<div className="flex-col-3">
<Button className="w-full">Accept</Button>
<div className="mt-2 flex">
<Button variant="outline" >Decline</Button>
<Button variant="outline" className="ml-2">Preferences</Button>
</div>
</div>
</div>
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
</div>
);
};

const meta: Meta<typeof DialogDemo> = {
component: DialogDemo,
argTypes: {
isBottomDialog: {
control: 'boolean',
description: 'Positions the dialog at the bottom of the screen.',
defaultValue: false,
},
isDismissable: {
control: 'boolean',
description: 'Whether the dialog can be dismissed.',
defaultValue: true,
},
isOpen: {
control: 'boolean',
description: 'Controls whether the dialog is open or closed.',
defaultValue: true,
}
}
};

export default meta;

export const Default: StoryObj<typeof DialogDemo> = {
args: {},
args: {
isOpen: true,
isBottomDialog: false,
isDismissable: true,
},
};