69 lines
1.9 KiB
TypeScript
69 lines
1.9 KiB
TypeScript
import { TextAttributes } from "@opentui/core"
|
|
import { useTheme } from "../context/theme"
|
|
import { useDialog, type DialogContext } from "./dialog"
|
|
import { useKeyboard } from "@opentui/solid"
|
|
import { createSignal } from "solid-js"
|
|
|
|
export type DialogAlertProps = {
|
|
title: string
|
|
message: string
|
|
onConfirm?: () => void
|
|
}
|
|
|
|
export function DialogAlert(props: DialogAlertProps) {
|
|
const dialog = useDialog()
|
|
const { theme } = useTheme()
|
|
const [hover, setHover] = createSignal(false)
|
|
|
|
useKeyboard((evt) => {
|
|
if (evt.name === "return") {
|
|
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}>
|
|
{props.title}
|
|
</text>
|
|
<box
|
|
paddingLeft={1}
|
|
paddingRight={1}
|
|
backgroundColor={hover() ? theme.primary : undefined}
|
|
onMouseOver={() => setHover(true)}
|
|
onMouseOut={() => setHover(false)}
|
|
onMouseUp={() => dialog.clear()}
|
|
>
|
|
<text fg={hover() ? theme.selectedListItemText : theme.textMuted}>esc</text>
|
|
</box>
|
|
</box>
|
|
<box paddingBottom={1}>
|
|
<text fg={theme.textMuted}>{props.message}</text>
|
|
</box>
|
|
<box flexDirection="row" justifyContent="flex-end" paddingBottom={1}>
|
|
<box
|
|
paddingLeft={3}
|
|
paddingRight={3}
|
|
backgroundColor={theme.primary}
|
|
onMouseUp={() => {
|
|
props.onConfirm?.()
|
|
dialog.clear()
|
|
}}
|
|
>
|
|
<text fg={theme.selectedListItemText}>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(),
|
|
)
|
|
})
|
|
}
|