mirror of
https://github.com/hanzoai/gui.git
synced 2026-10-25 02:31:41 +00:00
186 lines
4.5 KiB
TypeScript
186 lines
4.5 KiB
TypeScript
import { X } from '@hanzogui/lucide-icons-2'
|
|
import { memo } from 'react'
|
|
import { useWindowDimensions } from 'react-native'
|
|
import type { DialogCloseProps } from '@hanzo/gui'
|
|
import {
|
|
Button,
|
|
Dialog,
|
|
Fieldset,
|
|
Input,
|
|
Label,
|
|
Unspaced,
|
|
XStack,
|
|
YStack,
|
|
} from '@hanzo/gui'
|
|
import { rootStore } from '../state/RootStore'
|
|
import type {
|
|
ConfirmDeleteDialogProps,
|
|
CreateThemeDialogProps,
|
|
DialogTypes,
|
|
StudioAlertDialogProps,
|
|
} from '../state/types'
|
|
import { useGlobalState } from '../state/useGlobalState'
|
|
|
|
const DialogCloseButton = () => (
|
|
<Unspaced>
|
|
<Dialog.Close asChild="except-style">
|
|
<Button size="$3" position="absolute" t="$3" r="$3" circular icon={X} z={1000} />
|
|
</Dialog.Close>
|
|
</Unspaced>
|
|
)
|
|
|
|
export const Dialogs = memo(() => {
|
|
const state = useGlobalState()
|
|
const DialogContents = dialogs[state.dialog]
|
|
const dialogProps = state.dialogProps as any
|
|
const dimensions = useWindowDimensions()
|
|
|
|
if (!DialogContents) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<Dialog
|
|
modal
|
|
open={state.dialog !== 'none'}
|
|
onOpenChange={(val) => {
|
|
if (val === false) {
|
|
rootStore.hideDialog()
|
|
}
|
|
}}
|
|
>
|
|
<Dialog.Portal zIndex={10000000000}>
|
|
<Dialog.Overlay
|
|
transition="quick"
|
|
opacity={0.5}
|
|
enterStyle={{ opacity: 0 }}
|
|
exitStyle={{ opacity: 0 }}
|
|
/>
|
|
<Dialog.Content
|
|
onPointerDownOutside={() => {
|
|
rootStore.hideDialog()
|
|
}}
|
|
elevate
|
|
key="content"
|
|
transition={[
|
|
'quickest',
|
|
{
|
|
opacity: {
|
|
overshootClamping: true,
|
|
},
|
|
},
|
|
]}
|
|
enterStyle={{ x: 0, y: -20, opacity: 0, scale: 0.9 }}
|
|
exitStyle={{ x: 0, y: 10, opacity: 0, scale: 0.95 }}
|
|
x={0}
|
|
scale={1}
|
|
opacity={1}
|
|
y={0}
|
|
maxW={dimensions.width * 75}
|
|
p="$5"
|
|
>
|
|
<DialogContents {...dialogProps} />
|
|
</Dialog.Content>
|
|
</Dialog.Portal>
|
|
</Dialog>
|
|
)
|
|
})
|
|
|
|
const DialogClose = (props: DialogCloseProps) => {
|
|
return (
|
|
<Dialog.Close
|
|
asChild
|
|
{...props}
|
|
onPress={() => {
|
|
rootStore.setConfirmationStatus(true)
|
|
}}
|
|
/>
|
|
)
|
|
}
|
|
|
|
const CreateThemeDialog = (props: CreateThemeDialogProps) => {
|
|
return (
|
|
<>
|
|
<DialogCloseButton />
|
|
<YStack gap="$4">
|
|
<YStack gap="$2">
|
|
<Dialog.Title size="$7">Create Theme</Dialog.Title>
|
|
<Dialog.Description size="$3" color="$color9">
|
|
Create a new theme in scope {props.category}.
|
|
</Dialog.Description>
|
|
</YStack>
|
|
|
|
<Fieldset gap="$4" horizontal>
|
|
<Label size="$3" width={160} justify="flex-end" htmlFor="theme-name">
|
|
Name
|
|
</Label>
|
|
<Input size="$3" flex={1} id="theme-name" />
|
|
</Fieldset>
|
|
<DialogClose>
|
|
<Button aria-label="Close">Create</Button>
|
|
</DialogClose>
|
|
</YStack>
|
|
</>
|
|
)
|
|
}
|
|
|
|
const ConfirmDeleteDialog = (props: ConfirmDeleteDialogProps) => {
|
|
return (
|
|
<>
|
|
<DialogCloseButton />
|
|
<YStack gap="$6" p="$2">
|
|
<YStack gap="$2">
|
|
<Dialog.Title size="$7">Delete {props.thingName}?</Dialog.Title>
|
|
<Dialog.Description size="$3" color="$color9">
|
|
Are you sure you want to delete {props.thingName}?
|
|
</Dialog.Description>
|
|
</YStack>
|
|
|
|
<XStack justify="flex-end" gap="$4">
|
|
<Dialog.Close asChild>
|
|
<Button>Cancel</Button>
|
|
</Dialog.Close>
|
|
<DialogClose>
|
|
<Button theme="red" aria-label="Close">
|
|
Delete
|
|
</Button>
|
|
</DialogClose>
|
|
</XStack>
|
|
</YStack>
|
|
</>
|
|
)
|
|
}
|
|
|
|
const AlertDialog = (props: StudioAlertDialogProps) => {
|
|
return (
|
|
<>
|
|
<DialogCloseButton />
|
|
<YStack gap="$6" p="$2">
|
|
<YStack gap="$2">
|
|
<Dialog.Title size="$7">{props.title}</Dialog.Title>
|
|
<Dialog.Description size="$3" color="$color9">
|
|
{props.message}
|
|
</Dialog.Description>
|
|
</YStack>
|
|
|
|
<XStack justify="flex-end" gap="$4">
|
|
<DialogClose>
|
|
<Button theme="accent" aria-label="Ok">
|
|
Ok
|
|
</Button>
|
|
</DialogClose>
|
|
</XStack>
|
|
</YStack>
|
|
</>
|
|
)
|
|
}
|
|
|
|
const dialogs: {
|
|
[Key in keyof DialogTypes]: (props: DialogTypes[Key]) => any
|
|
} = {
|
|
none: AlertDialog,
|
|
'create-theme': CreateThemeDialog,
|
|
'confirm-delete': ConfirmDeleteDialog,
|
|
alert: AlertDialog,
|
|
}
|