cloudaxe-opencode/packages/tui/src/ui/dialog-alert.tsx

67 lines
1.8 KiB
TypeScript

import { TextAttributes } from "@opentui/core"
import { Keymap } from "../context/keymap"
import { useTheme } from "../context/theme"
import { useDialog, type DialogContext } from "./dialog"
export type DialogAlertProps = {
title: string
message: string
onConfirm?: () => void
}
export function DialogAlert(props: DialogAlertProps) {
const dialog = useDialog()
const theme = useTheme("elevated")
Keymap.createLayer(() => ({
mode: "modal",
commands: [
{
bind: "return",
title: "Confirm alert",
group: "Dialog",
run: () => {
props.onConfirm?.()
dialog.clear()
},
},
],
}))
return (
<box paddingLeft={2} paddingRight={2} gap={1}>
<box flexDirection="row" justifyContent="space-between">
<text attributes={TextAttributes.BOLD} fg={theme.text.default}>
{props.title}
</text>
<text fg={theme.text.subdued} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
<box paddingBottom={1}>
<text fg={theme.text.subdued}>{props.message}</text>
</box>
<box flexDirection="row" justifyContent="flex-end" paddingBottom={1}>
<box
paddingLeft={3}
paddingRight={3}
backgroundColor={theme.background.action.primary.focused}
onMouseUp={() => {
props.onConfirm?.()
dialog.clear()
}}
>
<text fg={theme.text.action.primary.focused}>ok</text>
</box>
</box>
</box>
)
}
DialogAlert.show = (dialog: DialogContext, title: string, message: string) => {
return new Promise<void>((resolve) => {
dialog.replace(
() => <DialogAlert title={title} message={message} onConfirm={() => resolve()} />,
() => resolve(),
)
})
}