Skip to content

Commit 123f017

Browse files
committed
Create custom ImagePreviewDialog
1 parent 4b81399 commit 123f017

3 files changed

Lines changed: 59 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { FC } from 'react'
2+
import * as DialogPrimitive from '@radix-ui/react-dialog'
3+
import { XIcon } from 'lucide-react'
4+
import { cn } from '../../lib/utils'
5+
import { Dialog, DialogPortal, DialogOverlay, DialogHeader, DialogTitle, DialogClose } from '../ui/dialog'
6+
7+
type ImagePreviewDialogProps = {
8+
className?: string
9+
onClose: () => void
10+
open: boolean
11+
src: string
12+
title?: string
13+
}
14+
15+
export const ImagePreviewDialog: FC<ImagePreviewDialogProps> = ({ className, onClose, open, src, title }) => {
16+
return (
17+
<Dialog open={open} onOpenChange={onClose}>
18+
<DialogPortal>
19+
<DialogOverlay className="z-9999 bg-black/90" />
20+
<DialogPrimitive.Content
21+
data-slot="dialog-content"
22+
className={cn(
23+
'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 fixed top-[50%] left-[50%] z-50 grid translate-x-[-50%] translate-y-[-50%] gap-4 duration-200 z-9999',
24+
className
25+
)}
26+
>
27+
<DialogHeader className="flex flex-row items-center justify-between">
28+
<DialogTitle className="text-md md:text-2xl font-bold text-white">{title}</DialogTitle>
29+
<DialogClose className="opacity-80 transition-opacity hover:opacity-100 text-white">
30+
<XIcon />
31+
<span className="sr-only">Close</span>
32+
</DialogClose>
33+
</DialogHeader>
34+
<img src={src} alt={title} className="max-w-[80dvw] max-h-[80dvh] object-contain" />
35+
</DialogPrimitive.Content>
36+
</DialogPortal>
37+
</Dialog>
38+
)
39+
}

src/components/dialog/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { ImagePreviewDialog } from './image-preview-dialog'

src/stories/Dialog/Dialog.stories.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
import { Button } from '../../components/ui/button.tsx'
1313
import { expect, userEvent, within } from 'storybook/test'
1414
import { useState } from 'react'
15+
import { ImagePreviewDialog } from '../../components/dialog'
1516

1617
const meta: Meta<typeof Dialog> = {
1718
title: 'Components/Dialog',
@@ -120,3 +121,21 @@ export const AlertDialog: Story = {
120121
)
121122
},
122123
}
124+
125+
export const ImagePreview: Story = {
126+
render: function ImagePreviewDialogExample() {
127+
const [open, setOpen] = useState(false)
128+
129+
return (
130+
<>
131+
<Button onClick={() => setOpen(true)}>Open Image Preview</Button>
132+
<ImagePreviewDialog
133+
src="https://explorer.dev.oasis.io/Oasis%20Explorer%20-%20OpenGraph%20Banner.png"
134+
title="Oasis Network"
135+
open={open}
136+
onClose={() => setOpen(false)}
137+
/>
138+
</>
139+
)
140+
},
141+
}

0 commit comments

Comments
 (0)