Alune 组件
AluneModal
保留 L0 / L1 / L2 的键盘、焦点、确认门槛与异步等待行为。
使用方式
open 由宿主控制。onOk 返回 Promise 时锁定重复提交,拒绝后恢复操作并保留正文;提交成功后的关闭由宿主完成。L0 优先聚焦字段,L1 聚焦确认,L2 聚焦取消。
import { AluneModal } from '@alune/ui'; 运行示例
运行与复制源码来自同一 TSX 文件。浮层、状态和主题独立于文档;所有回调只更新本地模拟数据。
正在加载示例…
查看运行源码
import { useState } from 'react';
import { AluneModal, Button, Input, Radio, Switch, DialogNote } from '@alune/ui';
export default function Example() {
const [open, setOpen] = useState(false);
const [level, setLevel] = useState<0 | 1 | 2>(0);
const [failure, setFailure] = useState(false);
const [error, setError] = useState('');
const [result, setResult] = useState('');
return (
<div className="example example--narrow">
<h2 className="example-title">风险等级与提交状态</h2>
<Radio.Group
aria-label="风险等级"
value={level}
onChange={(e) => setLevel(e.target.value)}
options={[0, 1, 2].map((value) => ({ value, label: `L${value}` }))}
/>
<label className="example-row">
<Switch aria-label="模拟异步失败" checked={failure} onChange={setFailure} /> 模拟异步失败
</label>
<div className="example-row">
<Button
onClick={() => {
setError('');
setOpen(true);
}}
>
打开弹窗
</Button>
</div>
<p className="example-status" role="status">
{result}
</p>
<AluneModal
open={open}
title={level === 2 ? '放弃示例更改?' : '保存示例配置'}
level={level}
size="md"
okText={level === 2 ? '放弃更改' : '保存配置'}
description="只操作本地模拟状态。"
typedConfirm={level === 2 ? { value: 'main', label: '输入 main 确认' } : undefined}
acknowledge={level === 2 ? '我了解此操作无法撤销' : undefined}
onCancel={() => setOpen(false)}
onOk={async () => {
await new Promise((resolve) => setTimeout(resolve, 600));
if (failure) {
setError('保存失败,输入已保留。');
throw new Error('模拟失败');
}
setResult('操作已完成');
setOpen(false);
}}
>
<Input aria-label="配置名称" defaultValue="示例配置" />
{error && (
<DialogNote tone="danger" title="提交失败">
{error}
</DialogNote>
)}
</AluneModal>
</div>
);
}
API
AluneModal
open 由宿主控制。onOk 返回 Promise 时锁定重复提交,拒绝后恢复操作并保留正文;提交成功后的关闭由宿主完成。L0 优先聚焦字段,L1 聚焦确认,L2 聚焦取消。
AluneModalProps
| 属性 / 方法 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
level | DialogLevel | 0 | 否 | 风险等级:0 普通表单,1 提醒,2 不可撤销。 |
tone | DialogTone | danger 为 true 或 L2 时 danger,否则 default;弹窗反馈可覆盖 | 否 | 语义色调。 |
size | number | DialogSize | 'md' | 否 | 预设尺寸或数字宽度。 |
glyph | ReactNode | 不显示 | 否 | 标题图标,false 隐藏。 |
eyebrow | DialogEyebrow | — | 否 | 标题上方的上下文。 |
levelLabel | ReactNode | L2: 不可撤销;其他等级不显示 | 否 | 风险标签,false 隐藏。 |
title | ReactNode | — | 是 | 标题或主文案。 |
description | ReactNode | — | 否 | 辅助说明。 |
hints | ReactNode | 按 level 生成键盘提示,窄屏隐藏 | 否 | 页脚提示,false 隐藏。 |
hintVerb | ReactNode | 确认 | 否 | 默认 Enter 提示中的操作动词。 |
danger | boolean | level === 2 | 否 | 危险操作样式。 |
okIcon | false | "warning" | "info" | "x" | "arrow-right" | "arrow-up-right" | "check" | "caret" | "trash" | "lock" | "key" | "server" | "folder" | "folder-open" | "branch" | "merge" | "pr" | "archive" | "cloud-up" | "cloud-down" | "globe" | "user" | "mail" | "terminal" | "laptop" | "search" | "bell" | "copy" | "eye" | "eye-off" | "link" | "sparkle" | "sliders" | "columns" | "download" | "moon" | "sun" | "wave" | "file" | "file-plus" | "refresh" | "plus" | "pencil" | "swap" | "shield" | "plug" | "tree" | "commit" | "chat" | "dots" | "clock" | "undo" | 'arrow-right' | 否 | 确认按钮图标,false 隐藏。 |
okDisabled | boolean | — | 否 | 锁定确认按钮。 |
busyText | ReactNode | — | 否 | 等待状态文案。 |
hideCancel | boolean | — | 否 | 隐藏取消按钮。 |
footer | ReactNode | — | 否 | 替换操作行,null 移除整个页脚。 |
extra | ReactNode | — | 否 | 额外内容或操作。 |
acknowledge | ReactNode | — | 否 | 必须勾选的确认说明;不传时没有此门槛。 |
typedConfirm | { value: string; label?: ReactNode; placeholder?: string; icon?: DialogIconName; mismatch?: ReactNode; match?: ReactNode; } | — | 否 | 必须输入的目标文字与匹配说明。 |
body | "default" | "flush" | "tight" | "scroll" | 'default' | 否 | 正文内边距或滚动方式。 |
initialFocus | "ok" | "cancel" | "field" | L0: field;L1: ok;L2: cancel | 否 | 初始焦点目标;默认由风险等级决定。 |
onOk | (() => unknown) | — | 否 | 确认回调;返回 Promise 时进入等待,拒绝后恢复操作并保留弹窗。关闭由宿主控制。 |
onCancel | (() => void) | — | 否 | 取消回调,宿主更新受控状态。 |
DialogLevel
export type DialogLevel = 0 | 1 | 2; DialogTone
export type DialogTone = 'default' | 'info' | 'success' | 'warning' | 'danger'; DialogSize
export type DialogSize = 'sm' | 'md' | 'lg' | 'xl'; DialogEyebrow
| 属性 / 方法 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
label | ReactNode | — | 是 | 可访问名称或展示文案。 |
detail | ReactNode | — | 否 | 参见类型定义及对应实现。 |
其余继承的 ModalProps(包括 open、okText、cancelText、confirmLoading、afterClose、okButtonProps 等)保持原行为。已重定义或排除的字段以本页 AluneModalProps 为准。 继承属性完整 API ↗
交互与使用限制
为每个操作提供可访问名称,为输入关联 label;使用语义化组件和清晰焦点。不要只靠颜色传达状态,禁用与等待时避免重复执行。
open 由宿主控制。onOk 返回 Promise 时锁定重复提交,拒绝后恢复操作并保留正文;提交成功后的关闭由宿主完成。L0 优先聚焦字段,L1 聚焦确认,L2 聚焦取消。
键盘、焦点、风险确认与通知策略的完整约定见交互规范。