# TDesign 设计系统

## TDesign 设计系统界面预览

验证规则、检查其局部效果并将其移除。不会部署任何策略。

## TDesign 设计系统设计参考

TDesign React，使用当前公开 develop 分支中的主题和组件源码。主题值是源码快照，不代表对固定版本软件包兼容性的承诺。独立预览是对 HTML 的诠释；React 示例使用真实的软件包 API。

### 浅色主题角色

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --td-brand-color | #0052d9 | 主要操作色，取自品牌色阶第 7 级。 |
| --td-brand-color-hover | #366ef4 | 主要操作悬停态。 |
| --td-brand-color-active | #003cab | 操作按下态。 |
| --td-brand-color-light | #f2f3ff | 微妙的选中背景层。 |
| --td-bg-color-page | #eee | 外层画布。 |
| --td-bg-color-container | #fff | 编辑器和表格面板。 |
| --td-text-color-primary | rgba(0,0,0,.9) | 正文。 |
| --td-text-color-secondary | rgba(0,0,0,.6) | 辅助说明文字。 |
| --td-border-level-1-color | #e8e8e8 | 分隔线。 |
| --td-border-level-2-color | #ddd | 控件边框。 |
| --td-error-color | #d54941 | 字段错误角色。 |
| --td-success-color | #2ba471 | 正向语义角色；不要仅凭颜色推断对比度。 |
### 字体角色

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --td-font-family | PingFang SC, Microsoft YaHei, Arial Regular | 面向系统的字体栈；此声明不会下载字体。 |
| --td-font-body-small | 12px / 20px | 次要紧凑标签。 |
| --td-font-body-medium | 14px / 22px | 控制台正文。 |
| --td-font-body-large | 16px / 24px | 较大的阅读文本。 |
| --td-font-title-medium | 600 16px / 24px | 面板标题。 |
| --td-font-headline-small | 600 24px / 32px | 页面标题。 |
| --td-font-display-medium | 600 48px / 56px | 展示文字角色，策略编辑器中并非必需。 |
### 尺寸与语义间距

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --td-size-1 … --td-size-8 | 2, 4, 6, 8, 12, 16, 20, 24px | 非线性的基础比例。 |
| --td-size-9 … --td-size-16 | 28, 32, 36, 40, 48, 56, 64, 72px | 较大的比例值。 |
| --td-comp-size-m | 32px | 中等组件高度别名。 |
| --td-comp-paddingLR-m | 12px | 中等水平内边距别名。 |
| --td-comp-paddingTB-l | 16px | 大号垂直内边距别名。 |
| --td-comp-margin-xl | 20px | 间距别名与内边距 xl 不同。 |
| --td-pop-padding-xxl | 16px | 弹出层内边距别名。 |
### 圆角样式

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --td-radius-small | 2px | 小圆角。 |
| --td-radius-default | 3px | 默认圆角。 |
| --td-radius-medium | 6px | 中圆角。 |
| --td-radius-large | 9px | 大圆角。 |
| --td-radius-extraLarge | 12px | 超大圆角。 |
| --td-radius-round | 999px | 胶囊形样式。 |
| --td-radius-circle | 50% | 圆形样式要求尺寸相等。 |
### 表单与表格约定

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| Form.useForm() | [form] | 将实例传给 Form。 |
| FormItem name | Registered field key | 必须与提交的字段及 setFields 错误保持一致。 |
| Form onSubmit | event.validateResult === true | 仅在验证成功后才执行应用更新。 |
| form.setFields | name + status + validateMessage | 设置具体字段的错误。 |
| FormItem for | Input association | 官方 Switch 示例使用 for="status"。 |
### 数据表格配置

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| rowKey | Stable unique data property | 示例为每条规则生成一次 id。 |
| columns[].colKey | Data key or custom cell key | 使用专用操作列。 |
| columns[].cell | ({row,col,rowIndex,colIndex}) | 渲染针对各行的控件。 |
| tableLayout | fixed by default; auto available | 根据较长的资源路径确定列宽。 |
| disableDataPage | false by default | 除非明确禁用，否则由 Table 处理本地分页。 |
## TDesign 设计系统完整指南

实用指南，介绍如何为真实界面选择、应用和评审此系统。

完整指导、实现起点和源代码链接。

## TDesign 设计系统：明确区分实现体系的控制台系统

### 选择 React 的实现方案

> TDesign 有独立的框架实现。此示例特意使用 tdesign-react，而不是名称相似的 Vue 软件包或移动端组件集。全局样式表是集成的一部分：仅导入组件并不会提供示例中的布局和主题规则。

实用的组合是一个已注册的 Form 与一个结构化 Table 并排使用。名称、资源路径和启用状态是数据字段；移除行则是表格操作。若声称整个页面现在已受到 API 保护，那是不准确的，因为此示例没有授权后端。

阅读配套规范

## TDesign 设计系统语义色，包括深色模式下的实际差异

### 品牌色阶第 7 级并非适用于所有模式

浅色主题通过第 7 级解析品牌角色，而深色主题则通过第 8 级解析。在应用 CSS 中保留语义变量，而不要在每个组件中都复制浅蓝色。深色画布为 #181818，容器为 #242424；它们属于不同的界面表面。

预览特意保持浅色模式。在原生实现中，在文档根节点设置 theme-mode="dark" 以启用已发布的深色规则；应单独限定任何自定义策略示意图的作用范围，不要用滤镜给所有图像重新着色。

```
document.documentElement.setAttribute('theme-mode', 'dark');
// Restore the published light theme:
document.documentElement.setAttribute('theme-mode', 'light');
```

代码参考

阅读配套规范

## TDesign 设计系统：排版紧凑，同时保留字段含义

### 使用完整的字体角色

正文中号提供 14px 字号和 22px 行高。标题中号采用 16/24 的尺寸和 600 字重；小号标题使用 24/32。这些样式各有用途：表格数据、面板标签和页面标题不应全都变成加粗的正文。

源字体系列名称会使用系统中可用的字体。在应用自有的排版样式中添加合适的无衬线回退字体，并同时检查中文和拉丁字符。资源路径可以在应用中使用等宽样式，但不要因此声称它是 TDesign 的字体令牌。

阅读配套规范

## TDesign 设计系统：将尺寸别名映射到实际区域

### 间距名称不可互换

组件中号水平内边距对应 12px，而组件超大号外边距对应 20px。不要通过猜测的单一比例尺转换所有语义后缀。编辑器使用 24px 外边距和更小的字段间距，让控件保持分组。

独立预览在窄屏时会将编辑器置于规则列表上方。这个断点由应用决定，并非框架保证。列表中的长 API 路径会自动换行，不会迫使整个页面宽于视口。

阅读配套规范

## TDesign 设计系统：先注册并验证，再添加规则

### 将字段错误关联到对应的键

将 Form 实例传给 Form 组件；每个 FormItem 提供字段名称。提交处理程序会先检查 validateResult，再读取已收集的字段。应用层检查会规范化字符串并拒绝重复路径，避免两个标签悄然配置同一个示例端点。

1. 使用 FormItem 的键注册 name、path 和 enabled。

2. 添加数据前，拒绝缺少名称或路径不以 / 开头的情况。

3. 使用相同的字段键调用 setFields 来显示错误，并保留已输入的值以便修正。

4. 只有通过检查后才追加稳定的 id，并说明结果仅保存在本地。

阅读配套规范

## TDesign 设计系统：编辑和删除时保留行标识

### 将显示数据与操作单元格分开

表格通过 rowKey 获取 id 字段。enabled 列会将布尔值映射为易读文本，而不是显示没有标签的彩色圆点。操作列会渲染带有行名称的按钮，避免辅助技术将三个无法区分的“删除”控件读成相同内容。

规则数量较少时，可以不对完整表格进行分页。如果要引入分页，请先区分内置的本地切片和服务器驱动的数据，再设置 disableDataPage。将数组位置复用为标识并不安全，因为删除操作会改变元素顺序。

- name 是面向用户的标签；path 是资源标识。

- enabled 是应用数据，并以明确的文本呈现。

- actions 是自定义列，不需要对应的存储属性。

阅读配套规范

## TDesign 设计系统：本地状态不代表已部署的策略

### 像真正的编辑器一样测试策略编辑器

离线预览使用带原生标签的控件、实时状态区域，以及键盘可见的焦点样式。提交空名称或重复路径时，表单必须保持打开，并指出具体问题。删除规则只会更改本地列表。

生产服务仍需进行服务器端验证、授权、冲突处理、审计日志记录，并能从保存遭拒的情况中恢复。应围绕此编辑器设计这些机制，而不是用声称已完成部署的成功提示来模拟。

阅读配套规范

## TDesign 设计系统：集成软件包，并如实呈现示例

### 应用代码使用原生示例

React 示例导入实际的 TDesign Form、Input、Switch、Button 和 Table 组件。嵌入式预览采用自包含的 HTML/CSS 实现，因此无需下载安装软件包或访问网络即可运行。预览中的交互检查并不能证明你的项目已成功编译所有库依赖。

链接的主题文件是当前开发源码。请在锁文件中确认已安装的版本，并在复制自定义覆盖项之前对比其令牌。本页面特意记录了角色名称和源码来源，以便评估后续主题变更，而不是将变更隐藏在示意性色板之下。

阅读配套规范

## TDesign 设计系统组件示例

### 完整的独立交互示例

将完整文档保存为 index.html，然后在浏览器中打开。这是对 TDesign 浅色令牌和 Form/Table 组合的独立 HTML/CSS 实现；并非原生的 React 运行时。

```
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>TDesign API rule editor</title><style>
*{box-sizing:border-box}body{margin:0;background:#eee;color:rgba(0,0,0,.9);font:14px/22px Arial,sans-serif}header{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;background:#fff;border-bottom:1px solid #ddd}.mark{font-weight:700;color:#0052d9;font-size:20px}.tag{background:#f2f3ff;color:#003cab;padding:4px 8px;border-radius:3px}main{padding:24px;max-width:1100px;margin:auto}h1{font-size:24px;line-height:32px;margin:0 0 8px}h2{font-size:16px;line-height:24px;margin:0 0 20px}.sub{color:rgba(0,0,0,.6);margin:0 0 24px}.layout{display:grid;grid-template-columns:310px minmax(0,1fr);gap:16px}.panel{background:white;border:1px solid #e8e8e8;border-radius:6px;padding:24px}label{display:block;margin-bottom:6px}input[type=text]{width:100%;height:36px;border:1px solid #ddd;border-radius:3px;padding:0 12px;font:inherit;margin-bottom:4px}input:focus,button:focus-visible{outline:2px solid #0052d9;outline-offset:3px}.hint{font-size:12px;color:#666;margin:0 0 20px}.toggle{display:flex;gap:8px;align-items:center;margin:18px 0 24px}.toggle input{accent-color:#0052d9;width:18px;height:18px}.toggle label{margin:0}button{font:inherit;border:1px solid #ddd;border-radius:3px;padding:5px 12px;background:white;color:#0052d9;cursor:pointer}button:hover{background:#f2f3ff}.primary{background:#0052d9;color:white;border-color:#0052d9;width:100%;margin-top:8px}.primary:hover{background:#366ef4}.error{color:#ad352f;min-height:22px;margin:0}.listhead{display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #e8e8e8;padding-bottom:16px;margin-bottom:0}.listhead h2{margin:0}.row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;padding:20px 0;border-bottom:1px solid #e8e8e8}.row strong{display:block;font-weight:600}.path{display:block;overflow-wrap:anywhere;font:12px/20px monospace;color:#666}.state{font-size:12px;color:#003cab}.row button{align-self:center;font-size:12px}.diagram{margin-top:24px;padding:16px;background:#f2f3ff;border-radius:3px;display:flex;align-items:center;gap:12px}.node{padding:8px 12px;background:white;border:1px solid #b5c7ff;border-radius:3px}.diagram span{color:#0052d9}.status{font-size:12px;color:#555;min-height:20px;margin:20px 0 0}.foot{font-size:12px;color:#666;margin:20px 0 0}#empty{padding:24px 0;color:#666}@media(max-width:680px){header{padding:16px}.layout{grid-template-columns:1fr}main{padding:20px 16px}.panel{padding:20px}.diagram{flex-wrap:wrap}.tag{font-size:12px}}
</style><header><span class="mark">T / Console</span><span class="tag">Local policy workspace</span></header><main><h1>API access rules</h1><p class="sub">Define which resources belong in your draft policy.</p><div class="layout"><section class="panel"><h2>Create a rule</h2><form id="editor" novalidate><label for="name">Rule name</label><input type="text" id="name" aria-describedby="error"><p class="hint">A short label your team can recognize.</p><label for="path">Resource path</label><input type="text" id="path" placeholder="/reports" aria-describedby="path-help error"><p class="hint" id="path-help">Start with /. Each path must be unique.</p><div class="toggle"><input id="enabled" type="checkbox" checked><label for="enabled">Enabled in this draft</label></div><p class="error" id="error" role="alert"></p><button class="primary">Add local rule</button></form><p class="foot">This editor does not connect to an API gateway.</p></section><section class="panel"><div class="listhead"><h2>Policy rules</h2><span id="count" class="tag"></span></div><div id="rules"></div><div class="diagram" aria-label="Illustrative policy flow"><div class="node">Client</div><span aria-hidden="true">→</span><div class="node">Policy draft</div><span aria-hidden="true">→</span><div class="node">Resource</div></div><p class="status" id="status" role="status">Two example rules are loaded locally.</p></section></div><p class="foot">HTML interpretation of TDesign light theme roles · Native React integration is provided in the guide.</p></main><script>
const $=id=>document.getElementById(id);let rules=[{id:1,name:'Reports read access',path:'/reports',enabled:true},{id:2,name:'Billing export',path:'/billing/export',enabled:false}];let next=3;
function render(){const host=$('rules');host.replaceChildren();$('count').textContent=rules.length+' rules';if(!rules.length){const p=document.createElement('p');p.id='empty';p.textContent='No rules in this draft. Add a resource to begin.';host.append(p)}for(const rule of rules){const row=document.createElement('div');row.className='row';const copy=document.createElement('div'),name=document.createElement('strong'),path=document.createElement('code'),state=document.createElement('span'),remove=document.createElement('button');name.textContent=rule.name;path.textContent=rule.path;path.className='path';state.textContent=rule.enabled?'Enabled':'Disabled';state.className='state';copy.append(name,path,state);remove.textContent='Remove';remove.setAttribute('aria-label','Remove '+rule.name);remove.onclick=()=>{rules=rules.filter(x=>x.id!==rule.id);render();$('status').textContent='Removed '+rule.name+' from this local draft.';$('name').focus()};row.append(copy,remove);host.append(row)}}
$('editor').onsubmit=e=>{e.preventDefault();$('error').textContent='';for(const id of ['name','path'])$(id).removeAttribute('aria-invalid');const name=$('name').value.trim(),path=$('path').value.trim();const fail=!name?['name','Enter a rule name.']:!path.startsWith('/')?['path','Start the resource path with /.']:rules.some(r=>r.path===path)?['path','This path already has a rule.']:null;if(fail){$('error').textContent=fail[1];$(fail[0]).setAttribute('aria-invalid','true');$(fail[0]).focus();return}rules.push({id:next++,name,path,enabled:$('enabled').checked});render();$('status').textContent='Added '+name+' locally. No policy was deployed.';$('name').value='';$('path').value='';$('name').focus()};render();
</script></html>
```

代码参考

- 规则仅存在于可见的示例集合中。原生 Form 注册、验证回调和 Table 渲染会在 React 中单独演示。

### 已注册的规则编辑器及针对单行的删除功能

表单会收集名称、资源路径和启用状态。在添加本地 Table 行之前，应用层验证会检查名称是否为空、路径格式是否正确，以及资源是否重复。

```
// npm install tdesign-react react react-dom
// main.jsx — a client-side React entry point
import React, {useState} from 'react';
import {createRoot} from 'react-dom/client';
import {Button, Form, Input, Switch, Table} from 'tdesign-react';
import 'tdesign-react/es/style/index.css';
const {FormItem} = Form;
function AccessRules() {
  const [form] = Form.useForm();
  const [rules, setRules] = useState([]);
  const [notice, setNotice] = useState('No local rules yet.');
  const addRule = ({validateResult, fields}) => {
    if (validateResult !== true) return;
    const name = String(fields.name || '').trim();
    const path = String(fields.path || '').trim();
    const invalid = !name ? ['name','Enter a rule name.'] :
      !path.startsWith('/') ? ['path','Start the resource path with /.'] :
      rules.some(rule => rule.path === path) ? ['path','This path already has a rule.'] : null;
    if (invalid) {
      form.setFields([{name:invalid[0],status:'error',validateMessage:{type:'error',message:invalid[1]}}]);
      setNotice(invalid[1]); return;
    }
    setRules(previous => [...previous, {id:crypto.randomUUID(),name,path,enabled:!!fields.enabled}]);
    setNotice(`Added ${name} to this browser session. No access policy was deployed.`);
  };
  const columns = [
    {colKey:'name', title:'Rule'}, {colKey:'path', title:'Resource'},
    {colKey:'enabled', title:'State', cell:({row}) => row.enabled ? 'Enabled' : 'Disabled'},
    {colKey:'actions', title:'Action', cell:({row}) => <Button variant="text" onClick={() => {
      setRules(previous => previous.filter(item => item.id !== row.id));
      setNotice(`Removed ${row.name} locally.`);
    }}>Remove {row.name}</Button>}
  ];
  return <main style={{padding:24,maxWidth:960,margin:'auto',font:'var(--td-font-body-medium)'}}>
    <h1>API access rules</h1>
    <Form form={form} onSubmit={addRule} labelWidth={100}>
      <FormItem name="name" label="Rule name"><Input /></FormItem>
      <FormItem name="path" label="Resource path"><Input placeholder="/reports" /></FormItem>
      <FormItem name="enabled" label="Enabled" for="enabled"><Switch /></FormItem>
      <FormItem><Button type="submit" theme="primary">Add local rule</Button></FormItem>
    </Form>
    <p role="status">{notice}</p>
    <Table rowKey="id" data={rules} columns={columns} bordered hover />
  </main>;
}
createRoot(document.getElementById('root')).render(<AccessRules />);
```

代码参考

- 上方规范中关联了 Table 的列和 rowKey 契约。

- 此示例仅修改本地 React 状态；启用标签不代表授权决策。

- 安装/API 示例已根据官方源代码核验；软件包编译与经过测试的离线预览是分开的。

## TDesign 设计系统 AI Agent 设置

### 实现起点

请使用上方完整的客户端入口示例，并提供一个 HTML 根元素。只需导入一次 tdesign-react/es/style/index.css。发布前请固定版本，并使用你的构建工具进行测试。

```
npm install tdesign-react react react-dom
```

### 适用于你项目的提示词

```
使用 tdesign-react Form 和 Table 构建 API 规则编辑器。保留语义化的 --td-* 角色、已注册的字段键、稳定的行 ID、明确的校验，以及准确描述本地状态的提示。
```

## TDesign 设计系统来源与适用范围

独立的 OpenDesign 参考资料。此预览是离线演绎，并非腾讯软件，也不是已部署的授权服务。

- TDesign React 软件包安装与实现方案。

- 浅色主题 浅色模式下的语义化颜色映射。

- 深色主题 深色根选择器与角色映射。

- 排版 字体、字号和行高定义。

- 尺寸令牌 基础间距与语义化间距别名。

- 圆角 已发布的圆角值。

- 表单示例 注册、提交和字段错误 API。

- Table 类型 行标识与列渲染契约。

## TDesign 设计系统相关资源

### Thumbtack Thumbprint

使用 Thumbprint 文档中记录的 v2 基础组件，构建服务发现界面：紧凑的服务提供方卡片、清晰易读的对比详情、明确的选择状态，以及常驻的候选清单。

### Twilio Paste

使用 Paste 的主题与按钮规范撰写通知草稿，采用经过验证的间距比例，并清楚区分编辑、审核和实际发送消息的状态。

### Visa Product 设计系统

使用 Visa 的 Nova CSS，通过原生单选控件、替代色标题栏和确认摘要，打造清晰的账单格式偏好设置。查看精确的 1.6.5 主题值、可缩放间距和完整的样式表集成。


- [实现参考](https://raw.githubusercontent.com/Tencent/tdesign-react/develop/packages/components/form/_example/base.tsx)
- [来源](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_light.less)
- [来源](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_font.less)
- [来源](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_size.less)
- [来源](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_radius.less)
- [来源](https://raw.githubusercontent.com/Tencent/tdesign-react/develop/packages/components/form/_example/base.tsx)
- [来源](https://raw.githubusercontent.com/Tencent/tdesign-react/develop/packages/components/table/type.ts)
- [阅读配套规范](https://github.com/Tencent/tdesign-react)
- [代码参考](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_dark.less)
- [阅读配套规范](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_dark.less)
- [阅读配套规范](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_font.less)
- [阅读配套规范](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_size.less)
- [阅读配套规范](https://raw.githubusercontent.com/Tencent/tdesign-react/develop/packages/components/form/_example/base.tsx)
- [阅读配套规范](https://raw.githubusercontent.com/Tencent/tdesign-react/develop/packages/components/table/type.ts)
- [代码参考](https://raw.githubusercontent.com/Tencent/tdesign-react/develop/packages/components/form/_example/base.tsx)
- [TDesign React 软件包安装与实现方案。](https://github.com/Tencent/tdesign-react)
- [浅色主题 浅色模式下的语义化颜色映射。](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_light.less)
- [深色主题 深色根选择器与角色映射。](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_dark.less)
- [排版 字体、字号和行高定义。](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_font.less)
- [尺寸令牌 基础间距与语义化间距别名。](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_size.less)
- [圆角 已发布的圆角值。](https://raw.githubusercontent.com/Tencent/tdesign-common/develop/style/web/theme/_radius.less)
- [表单示例 注册、提交和字段错误 API。](https://raw.githubusercontent.com/Tencent/tdesign-react/develop/packages/components/form/_example/base.tsx)
- [Table 类型 行标识与列渲染契约。](https://raw.githubusercontent.com/Tencent/tdesign-react/develop/packages/components/table/type.ts)
