1- import React , { Fragment } from 'react' ;
2- import { Dialog as HeadlessDialog , Transition } from '@headlessui/react' ;
1+ import React from 'react' ;
2+ import { Dialog as HDialog } from '@headlessui/react' ;
33import { Button } from '@/components/elements/button/index' ;
4- import styles from './style.module.css' ;
54import { XIcon } from '@heroicons/react/solid' ;
6- import { CheckIcon , ExclamationIcon , InformationCircleIcon , ShieldExclamationIcon } from '@heroicons/react/outline' ;
5+ import DialogIcon from '@/components/elements/dialog/DialogIcon' ;
6+ import { AnimatePresence , motion } from 'framer-motion' ;
77import classNames from 'classnames' ;
88
99interface Props {
10- visible : boolean ;
11- onDismissed : ( ) => void ;
10+ open : boolean ;
11+ onClose : ( ) => void ;
12+ hideCloseIcon ?: boolean ;
1213 title ?: string ;
14+ description ?: string ;
1315 children ?: React . ReactNode ;
1416}
1517
16- interface DialogIconProps {
17- type : 'danger' | 'info' | 'success' | 'warning' ;
18- className ?: string ;
19- }
20-
21- const DialogIcon = ( { type, className } : DialogIconProps ) => {
22- const [ Component , styles ] = ( function ( ) : [ ( props : React . ComponentProps < 'svg' > ) => JSX . Element , string ] {
23- switch ( type ) {
24- case 'danger' :
25- return [ ShieldExclamationIcon , 'bg-red-500 text-red-50' ] ;
26- case 'warning' :
27- return [ ExclamationIcon , 'bg-yellow-600 text-yellow-50' ] ;
28- case 'success' :
29- return [ CheckIcon , 'bg-green-600 text-green-50' ] ;
30- case 'info' :
31- return [ InformationCircleIcon , 'bg-primary-500 text-primary-50' ] ;
32- }
33- } ) ( ) ;
34-
35- return (
36- < div className = { classNames ( 'flex items-center justify-center w-10 h-10 rounded-full' , styles , className ) } >
37- < Component className = { 'w-6 h-6' } />
38- </ div >
39- ) ;
40- } ;
41-
4218const DialogButtons = ( { children } : { children : React . ReactNode } ) => (
4319 < > { children } </ >
4420) ;
4521
46- const Dialog = ( { visible , title, onDismissed , children } : Props ) => {
22+ const Dialog = ( { open , title, description , onClose , hideCloseIcon , children } : Props ) => {
4723 const items = React . Children . toArray ( children || [ ] ) ;
4824 const [ buttons , icon , content ] = [
4925 // @ts -expect-error
@@ -55,55 +31,63 @@ const Dialog = ({ visible, title, onDismissed, children }: Props) => {
5531 ] ;
5632
5733 return (
58- < Transition show = { visible } as = { Fragment } >
59- < HeadlessDialog onClose = { ( ) => onDismissed ( ) } className = { styles . wrapper } >
60- < div className = { 'flex items-center justify-center min-h-screen' } >
61- < Transition . Child
62- as = { Fragment }
63- enter = { 'ease-out duration-200' }
64- enterFrom = { 'opacity-0' }
65- enterTo = { 'opacity-100' }
66- leave = { 'ease-in duration-100' }
67- leaveFrom = { 'opacity-100' }
68- leaveTo = { 'opacity-0' }
69- >
70- < HeadlessDialog . Overlay className = { styles . overlay } />
71- </ Transition . Child >
72- < Transition . Child
73- as = { Fragment }
74- enter = { 'ease-out duration-200' }
75- enterFrom = { 'opacity-0 scale-95' }
76- enterTo = { 'opacity-100 scale-100' }
77- leave = { 'ease-in duration-100' }
78- leaveFrom = { 'opacity-100 scale-100' }
79- leaveTo = { 'opacity-0 scale-95' }
80- >
81- < div className = { styles . container } >
82- < div className = { 'flex p-6' } >
83- { icon && < div className = { 'mr-4' } > { icon } </ div > }
84- < div className = { 'flex-1' } >
85- { title &&
86- < HeadlessDialog . Title className = { styles . title } >
87- { title }
88- </ HeadlessDialog . Title >
89- }
90- < HeadlessDialog . Description className = { 'pr-4' } >
34+ < AnimatePresence >
35+ { open && (
36+ < HDialog
37+ static
38+ as = { motion . div }
39+ initial = { { opacity : 0 } }
40+ animate = { { opacity : 1 } }
41+ exit = { { opacity : 0 } }
42+ transition = { { duration : 0.15 } }
43+ open = { open }
44+ onClose = { onClose }
45+ >
46+ < div className = { 'fixed inset-0 bg-gray-900/50' } />
47+ < div className = { 'fixed inset-0 overflow-y-auto' } >
48+ < div className = { 'flex min-h-full items-center justify-center p-4 text-center' } >
49+ < HDialog . Panel
50+ as = { motion . div }
51+ initial = { { opacity : 0 , scale : 0.85 } }
52+ animate = { { opacity : 1 , scale : 1 } }
53+ exit = { { opacity : 0 } }
54+ transition = { { type : 'spring' , damping : 15 , stiffness : 300 , duration : 0.15 } }
55+ className = { classNames ( [
56+ 'relative bg-gray-600 rounded max-w-xl w-full mx-auto shadow-lg text-left' ,
57+ 'ring-4 ring-gray-800 ring-opacity-80' ,
58+ ] ) }
59+ >
60+ < div className = { 'flex p-6' } >
61+ { icon && < div className = { 'mr-4' } > { icon } </ div > }
62+ < div className = { 'flex-1 max-h-[70vh] overflow-y-scroll overflow-x-hidden' } >
63+ { title &&
64+ < HDialog . Title className = { 'font-header text-xl font-medium mb-2 text-white pr-4' } >
65+ { title }
66+ </ HDialog . Title >
67+ }
68+ { description && < HDialog . Description > { description } </ HDialog . Description > }
9169 { content }
92- </ HeadlessDialog . Description >
70+ </ div >
9371 </ div >
94- </ div >
95- { buttons && < div className = { styles . button_bar } > { buttons } </ div > }
96- { /* Keep this below the other buttons so that it isn't the default focus if they're present. */ }
97- < div className = { 'absolute right-0 top-0 m-4' } >
98- < Button . Text square small onClick = { ( ) => onDismissed ( ) } className = { 'hover:rotate-90' } >
99- < XIcon className = { 'w-5 h-5' } />
100- </ Button . Text >
101- </ div >
72+ { buttons &&
73+ < div className = { 'px-6 py-3 bg-gray-700 flex items-center justify-end space-x-3 rounded-b' } >
74+ { buttons }
75+ </ div >
76+ }
77+ { /* Keep this below the other buttons so that it isn't the default focus if they're present. */ }
78+ { ! hideCloseIcon &&
79+ < div className = { 'absolute right-0 top-0 m-4' } >
80+ < Button . Text square small onClick = { onClose } className = { 'hover:rotate-90' } >
81+ < XIcon className = { 'w-5 h-5' } />
82+ </ Button . Text >
83+ </ div >
84+ }
85+ </ HDialog . Panel >
10286 </ div >
103- </ Transition . Child >
104- </ div >
105- </ HeadlessDialog >
106- </ Transition >
87+ </ div >
88+ </ HDialog >
89+ ) }
90+ </ AnimatePresence >
10791 ) ;
10892} ;
10993
0 commit comments