import React, {
forwardRef,
ElementRef,
ComponentProps,
ReactNode,
Fragment,
useRef,
useState,
useEffect,
} from 'react'
import { styled } from '~/theme'
import { Text, Button, ScrollArea } from '~/components'
import { useDialog } from './useDialog'
import { useHotkeys } from '~/hooks'
const Container = styled('div', {
width: 632, // 520
maxHeight: 'calc(100vh - 30px)',
display: 'flex',
flexDirection: 'column',
borderRadius: 4,
boxShadow: '0px 8px 20px rgba(0, 0, 0, 0.12)',
backgroundColor: '$Background2dp',
variants: {
mode: {
dialog: {
width: 520,
},
},
},
})
const ScrollBody = styled('div', {
paddingTop: '$$dialogPadding',
paddingLeft: '$$dialogPadding',
paddingRight: '$$dialogPadding',
width: '100%',
'&>:last-child': {
paddingBottom: 24,
},
})
const StyledButtons = styled('div', {
position: 'sticky',
bottom: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
paddingTop: '$$dialogPadding',
backgroundColor: '$Background2dp',
paddingBottom: '$$dialogPadding',
})
const ButtonsWithBorder = styled(StyledButtons, {
borderTop: '1px solid $OtherDivider',
marginTop: 48,
paddingTop: 20,
paddingLeft: 24,
paddingRight: 24,
marginLeft: 'calc(-1 * $$dialogPadding)',
marginRight: 'calc(-1 * $$dialogPadding)',
})
const ButtonSpacer = styled('div', {
width: 16,
})
const BodySpacer = styled('div', {
height: 24,
'&:first-child': {
display: 'none',
},
})
const Title = (props) => {
return
}
const Body = ({ children }) => {
if (typeof children === 'string') {
return {children}
} else if (Array.isArray(children)) {
return (
<>
{children.map((child, index) => (
{child}
))}
>
)
} else {
return (
<>
{children}
>
)
}
}
const Buttons = ({ children, border = null }) => {
if (Array.isArray(children)) {
children = children.map((child, index) => {
return index ? (
{child}
) : (
child
)
})
}
return border ? (
{children}
) : (
{children}
)
}
const Confirm = ({ children = 'OK', onConfirm = () => {}, ...props }) => {
const dialog = useDialog()
const { current: myId } = useRef(dialog._id)
const onClick = onConfirm
? async () => {
if (!props.disabled && myId === dialog._id) {
await onConfirm()
dialog.close(myId)
}
}
: () => {
if (!props.disabled && myId === dialog._id) {
dialog.close(myId)
}
}
useHotkeys([['enter', onClick]])
return (
)
}
const Cancel = ({ children = 'Cancel', onCancel = null, ...props }) => {
const dialog = useDialog()
const { current: myId } = useRef(dialog._id)
const onClick = onCancel
? async () => {
if (!props.disabled && myId === dialog._id) {
await onCancel()
dialog.close(myId)
}
}
: () => {
if (!props.disabled && myId === dialog._id) {
dialog.close(myId)
}
}
useHotkeys([['escape', onClick]])
return (
)
}
export interface DialogProps extends ComponentProps {
children?: ReactNode
title?: string
padding?: number
}
export const Dialog = Object.assign(
forwardRef, DialogProps>(
({ children, title, padding = 24, style, ...props }, forwardedRef) => {
if (typeof children === 'string') {
if (!title) {
title = children
children = null
} else {
children = {children}
}
}
const [go, setgo] = useState(false)
useEffect(() => {
const x = requestAnimationFrame(() => {
setgo(true)
})
return () => {
cancelAnimationFrame(x)
}
}, [])
return (
{title}
{children}
)
}
),
{
Title,
Body,
Buttons,
Confirm,
Cancel,
}
)
Dialog.displayName = 'Dialog'