JGuang

对话框

Dialog · Astryx

交互预览
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0

对话框 · Dialog

展示模态内容,并在打开和关闭时管理焦点。

安装与前置条件

npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0

需要 React 19+,按顺序导入基础 CSS 和主题,并设置 Theme Provider。参见开始使用。

示例与使用方式

  • 对话框 · 综合展示 1:首先体验这个示例,再查看代码理解组件的组合方式。
  • 对话框 · 综合展示 2:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
  • 对话框 · 交互示例 3:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
  • 对话框 · 交互示例 4:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
  • 对话框 · 交互示例 5:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
  • 对话框 · 交互示例 6:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
  • 对话框 · 基础用法 7:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
  • 对话框 · 交互示例 8:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
  • 对话框 · 交互示例 9:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。

API 与上游详细参考

优先使用 0.7.1 官方中文说明;上游尚未提供中文的条目保留英文。属性名、类型及默认值保持原生 API,不把示例状态名称当成组件属性。

Dialog

Dialog displays a modal overlay that blocks interaction with the page until the user responds. Use it for delete confirmations, edit forms, terms acceptance, or any decision that should not be skipped.

属性类型默认值说明
isOpen *booleanWhether the dialog is open.
onOpenChange *(isOpen: boolean) => unknownCallback when dialog visibility changes.
children *ReactNodeDialog content.
widthnumber | string400Preferred width of the dialog in pixels or any CSS value. Standard dialogs clamp to their container and the dynamic viewport with spacing-token gutters so narrow viewports keep content on screen.
maxHeightnumber | string'75dvh'Maximum height of the dialog. Defaults to a dynamic viewport value so browser UI changes are reflected where supported.
positionDialogPositionStatic position for the dialog; centered by default when omitted. Use logical start/end for inline offsets so positioned dialogs mirror correctly under RTL.
variant'standard' | 'fullscreen''standard'Dialog variant: fullscreen expands to fill the entire viewport.
purpose'required' | 'form' | 'info''info'Controls dismissal behavior: required disables Escape and backdrop click; form disables backdrop click after interaction; info allows both.
padding0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10Internal padding of the dialog using the spacing scale step.
isInlinebooleanfalseRenders dialog content inline without the <dialog> element, backdrop, or modal behavior. For documentation previews and showcases only.

使用建议

  • Choose the right purpose: info for dismissable content, form to prevent accidental backdrop dismissal, required when the user must respond.
  • Include a clear title in the header so users immediately understand what the dialog is asking.
  • Use purpose="form" for dialogs with inputs so the user can't accidentally lose data by clicking the backdrop.
  • Keep dialogs focused on a single task; if the content grows beyond what fits, consider a full page instead.
  • 避免:Use a dialog for simple messages that could be shown inline or as a toast notification.
  • 避免:Nest dialogs inside other dialogs; restructure the flow into steps within a single dialog instead.
  • 避免:Use the fullscreen variant for simple confirmations; it is meant for complex content like editors or long forms.

主题 API

{
  "container": true,
  "targets": [
    {
      "className": "astryx-dialog",
      "visualProps": [
        "variant"
      ]
    },
    {
      "className": "astryx-dialog-header"
    },
    {
      "className": "astryx-dialog-header-start-content"
    },
    {
      "className": "astryx-dialog-header-title-block"
    },
    {
      "className": "astryx-dialog-header-end-content"
    },
    {
      "className": "astryx-dialog-header-close-icon"
    }
  ],
  "vars": [
    {
      "name": "--_dialog-radius",
      "description": "Border radius of the dialog",
      "default": "var(--radius-container)",
      "private": true
    }
  ],
  "derived": [
    {
      "property": "borderRadius",
      "vars": [
        "--_dialog-radius"
      ]
    },
    {
      "property": "padding",
      "expand": "container"
    }
  ]
}

DialogHeader

useImperativeDialog

组件结构

  • Header: Title, optional subtitle, and close button. The title receives focus on open and labels the dialog via aria-labelledby.
  • Body: The main content area: text, forms, lists, or any layout.
  • Footer: Action buttons like Save/Cancel or Accept/Decline, aligned to the end.
  • Backdrop: Semi-transparent overlay behind the dialog that blocks page interaction.

Dialog Header

使用 DialogHeader 为对话框提供带标签的标题区和可选的关闭控件。

属性类型默认值说明
titleReactNode对话框标题,渲染在可聚焦的 h2 中(打开时获得焦点,其文本内容通过 aria-labelledby 为对话框命名)。请使用非空、非交互的行内内容。
subtitleReactNode标题下方的副标题,可包含链接等行内内容;避免使用块级元素。
onOpenChange(isOpen: boolean) => unknown关闭按钮的回调(省略时不显示按钮)。
startContentReactNode标题之前的内容(例如返回按钮)。
endContentReactNode标题之后、关闭按钮之前的内容。
endContentEdgeCompensation'inline' | 'block' | 'all'选择尾部内容插槽的补偿轴;省略时保留关闭操作的自动补偿。
hasDividerbooleantrue在底部边缘添加分隔线。

Basic

import {DialogHeader} from '@astryxdesign/core/Dialog';

<DialogHeader title="Delete file?" subtitle="This action cannot be undone." />;

With close button

import {useState} from 'react';
import {DialogHeader} from '@astryxdesign/core/Dialog';

function Header() {
  const [, setIsOpen] = useState(true);

  // Passing onOpenChange renders a close button that calls it with false.
  return <DialogHeader title="Settings" onOpenChange={setIsOpen} />;
}
import {DialogHeader} from '@astryxdesign/core/Dialog';
import {Link} from '@astryxdesign/core/Link';

<DialogHeader
  title="Share conversation"
  subtitle={
    <>
      Anyone with the link can view it. Review the{' '}
      <Link href="#sharing-policy">sharing policy</Link> first.
    </>
  }
/>;

With start and end content

import {DialogHeader} from '@astryxdesign/core/Dialog';
import {Icon} from '@astryxdesign/core/Icon';
import {Badge} from '@astryxdesign/core/Badge';

<DialogHeader
  title="Notifications"
  startContent={<Icon icon="chevronLeft" size="sm" />}
  endContent={<Badge label="3" />}
/>;

主题 API

{
  "targets": [
    {
      "className": "astryx-dialog-header"
    },
    {
      "className": "astryx-dialog-header-start-content"
    },
    {
      "className": "astryx-dialog-header-title-block"
    },
    {
      "className": "astryx-dialog-header-end-content"
    },
    {
      "className": "astryx-dialog-header-close-icon"
    }
  ]
}

组件结构

  • Header row: 排列标题区、可选的首尾内容和关闭控件。
  • Start content: 包装可选的首部内容。
  • Title block: 组合标题和可选副标题。
  • End content: 组合可选尾部内容和可选关闭控件。
  • Close icon: 关闭按钮内的关闭图标。

useImperativeDialog

Hook for showing a dialog without managing open state. Call dialog.show(content, options) to open and dialog.hide() to close. Render dialog.element in your JSX tree.

属性类型默认值说明
show(content: ReactNode, options?: DialogOptions) => voidShow the dialog with the given content. Options are the same as Dialog props minus isOpen/onOpenChange/children.
hide() => voidHide the dialog.
isOpenbooleanWhether the dialog is currently open.
elementReactNodeThe dialog element: render this in your JSX tree.