import { TextareaRenderable, TextAttributes } from "@opentui/core" import { useTheme } from "../context/theme" import { useDialog, type DialogContext } from "./dialog" import { Show, createEffect, createSignal, onMount, type JSX } from "solid-js" import { Spinner } from "../component/spinner" import { useTuiConfig } from "../config" import { useBindings, useCommandShortcut } from "../keymap" export type DialogPromptProps = { title: string description?: () => JSX.Element placeholder?: string value?: string busy?: boolean busyText?: string onConfirm?: (value: string) => void onCancel?: () => void } export function DialogPrompt(props: DialogPromptProps) { const dialog = useDialog() const { theme } = useTheme() const tuiConfig = useTuiConfig() const submitShortcut = useCommandShortcut("dialog.prompt.submit") const [textareaTarget, setTextareaTarget] = createSignal() let textarea: TextareaRenderable function confirm() { if (props.busy) return props.onConfirm?.(textarea.plainText) } useBindings(() => ({ target: textareaTarget, enabled: textareaTarget() !== undefined && !props.busy, // Dialog form semantics must win over the global managed textarea input layer. priority: 1, commands: [ { name: "dialog.prompt.submit", title: "Submit dialog prompt", category: "Dialog", run: confirm, }, ], bindings: tuiConfig.keybinds.gather("dialog.prompt", ["dialog.prompt.submit"]), })) onMount(() => { dialog.setSize("medium") setTimeout(() => { if (!textarea || textarea.isDestroyed) return if (props.busy) return textarea.focus() }, 1) textarea.gotoLineEnd() }) createEffect(() => { if (!textarea || textarea.isDestroyed) return const traits = props.busy ? { suspend: true, status: "BUSY", } : {} textarea.traits = traits if (props.busy) { textarea.blur() return } textarea.focus() }) return ( {props.title} dialog.clear()}> esc {props.description}