Skip to content

Dialog widget (HTML <dialog> equivalent) #45

Description

@AlphaFoxz

Summary

Add a DialogWidget for modal overlays — the TUI equivalent of HTML <dialog>. Use cases: confirmation prompts ("Are you sure?"), alerts, modal input forms.

Expected API

type DialogWidgetOptions = {
  x?, y?, width?, height?: TuiSizeValue;
  open?: boolean;        // controlled open state
  modal?: boolean;       // default true — blocks input to widgets behind
  dismissable?: boolean; // default true — Escape / backdrop click closes
  // children: composable like Box (Dialog is a container)
};

Behavior

  • Modal overlay: when modal: true, widgets behind the dialog do not receive input events. The scene's painter's-algorithm zIndex already supports layering (see TuiScene); needs an input-blocking overlay layer on top.
  • Focus trap: Tab / Shift+Tab cycles within the dialog's children only. Builds on the focus infrastructure delivered in Focus infrastructure — focusable widget enumeration, tabIndex, and Tab/Shift+Tab navigation #32.
  • Dismiss: Escape closes when dismissable. Backdrop click closes when dismissable && modal.
  • Events: close event with {reason: 'escape' | 'backdrop' | 'programmatic'}.
  • Rendering: optional backdrop dim overlay; border + title from the Box pattern.

Open design questions

  • Does the scene need an explicit "overlay stack" to manage multiple stacked dialogs, or is zIndex sufficient?
  • Should modal: false (modeless panels) be supported in v1?

Context

Identified in the now-removed docs/missing-widgets.md as an important widget for TUI UX. Depends on the focus infrastructure from #32.

Affected directory: packages/core/src/widgets/dialog/ (new)


概要

新增 DialogWidget 模态覆盖层 —— HTML <dialog> 的 TUI 等价物。典型场景:确认提示("是否确定?")、警告框、模态输入表单。

期望 API

type DialogWidgetOptions = {
  x?, y?, width?, height?: TuiSizeValue;
  open?: boolean;        // 受控的打开状态
  modal?: boolean;       // 默认 true —— 拦截后方 widget 的输入
  dismissable?: boolean; // 默认 true —— Escape / 点击背景可关闭
  // 子节点:像 Box 一样可组合(Dialog 是容器)
};

行为

  • 模态覆盖:当 modal: true 时,对话框后方的 widget 不接收输入事件。Scene 的画家算法 zIndex 已支持分层(参见 TuiScene);需要在之上增加输入拦截层。
  • 焦点陷阱:Tab / Shift+Tab 仅在 Dialog 子节点之间循环。基于 Focus infrastructure — focusable widget enumeration, tabIndex, and Tab/Shift+Tab navigation #32 提供的焦点基础设施。
  • 关闭:当 dismissable 时按 Escape 关闭;当 dismissable && modal 时点击背景关闭。
  • 事件:close 事件携带 {reason: 'escape' | 'backdrop' | 'programmatic'}
  • 渲染:可选的背景遮罩;边框 + 标题沿用 Box 模式。

待定设计问题

  • Scene 是否需要显式 "overlay stack" 来管理多层堆叠 Dialog,还是 zIndex 已足够?
  • v1 是否支持 modal: false(非模态面板)?

背景

此项来自已移除的 docs/missing-widgets.md,识别为重要的 TUI UX widget。依赖 #32 提供的焦点基础设施。

受影响目录: packages/core/src/widgets/dialog/(新增)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Feature gap / DX improvementenhancementNew feature or requestlibTypeScript packages (core, compiler, extensions, playground, buntui)

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions