组合示例
组合示例
工具栏、带校验表单与危险操作确认。
三个真实组合展示如何使用同一套组件完成工具栏切换、带校验表单和危险操作确认。
工具栏以激活状态表达当前视图,图标按钮提供清晰名称。表单使用字段 label、必填规则和保留输入的失败反馈。危险确认使用 L2、取消焦点以及输入/勾选门槛,提交等待时不重复执行。
全部数据和回调在示例 iframe 内,不触发 Git、SSH 或业务后端。下方运行代码就是可以复制的 TSX 文件,Provider 与样式由预览宿主提供。
运行示例
运行与复制源码来自同一 TSX 文件。浮层、状态和主题独立于文档;所有回调只更新本地模拟数据。
正在加载示例…
查看运行源码
import { useState } from 'react';
import { ToolbarButton, StatusButton, CommandButton, DialogIcon, Space } from '@alune/ui';
export default function Example() {
const [active, setActive] = useState('files');
const [count, setCount] = useState(0);
return (
<div className="example">
<section className="example-group">
<h2 className="example-title">视图切换</h2>
<Space wrap size="middle">
<ToolbarButton
label="文件"
active={active === 'files'}
onClick={() => setActive('files')}
>
<DialogIcon name="folder" />
文件
</ToolbarButton>
<ToolbarButton
label="历史"
active={active === 'history'}
onClick={() => setActive('history')}
>
<DialogIcon name="clock" />
历史
</ToolbarButton>
</Space>
</section>
<section className="example-group">
<h2 className="example-title">操作与连接状态</h2>
<Space wrap size="middle">
<ToolbarButton
label="拉取"
variant="action"
text="拉取"
count={2}
countTone="behind"
onClick={() => setCount((n) => n + 1)}
>
<DialogIcon name="cloud-down" />
</ToolbarButton>
<ToolbarButton
label="运行示例"
variant="primary"
text="运行"
count={count || undefined}
onClick={() => setCount((n) => n + 1)}
/>
<ToolbarButton label="不可用操作" variant="action" disabled>
不可用
</ToolbarButton>
<StatusButton label="状态" active>
已连接
</StatusButton>
<CommandButton label="刷新示例" onClick={() => setCount((n) => n + 1)}>
<DialogIcon name="refresh" />
</CommandButton>
</Space>
</section>
<p className="example-status" role="status">
当前:{active} · 操作次数:{count}
</p>
</div>
);
}
正在加载示例…
查看运行源码
import { useState } from 'react';
import { Form, Input, Button, Switch } from '@alune/ui';
export default function Example() {
const [failure, setFailure] = useState(false);
const [result, setResult] = useState('');
const [busy, setBusy] = useState(false);
return (
<div className="example example--narrow">
<label className="example-row">
<Switch aria-label="模拟提交失败" checked={failure} onChange={setFailure} /> 模拟失败
</label>
<Form
layout="vertical"
disabled={busy}
onFinish={async (values) => {
if (busy) return;
setBusy(true);
setResult('正在保存…');
await new Promise((resolve) => setTimeout(resolve, 600));
setResult(failure ? '保存失败,请保留输入并重试。' : `已保存:${values.name}`);
setBusy(false);
}}
>
<Form.Item
name="name"
label="配置名称"
rules={[{ required: true, message: '请填写配置名称' }]}
extra="名称仅在此示例中使用"
>
<Input />
</Form.Item>
<Form.Item name="description" label="说明">
<Input.TextArea />
</Form.Item>
<Button type="primary" htmlType="submit" loading={busy}>
保存配置
</Button>
</Form>
<p className="example-status" role="status">
{result}
</p>
</div>
);
}
正在加载示例…
查看运行源码
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>
);
}