企业软件 · 新资源

TDesign 设计系统.

使用 TDesign React 构建紧凑的 API 政策编辑器:设置具体的主题角色、两像素尺寸比例、Form 字段注册,以及带类型的 Table 组合。

OpenDesign 指南8 个章节43 个参考条目原始应用指南
01

TDesign 设计系统界面预览

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

API 规则编辑器打开完整示例
基于独立的 HTML/CSS 对 TDesign 浅色令牌和 Form/Table 组合进行诠释;并非原生的 React 运行时。· 实现参考
02

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-primaryrgba(0,0,0,.9)正文。
--td-text-color-secondaryrgba(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-familyPingFang SC, Microsoft YaHei, Arial Regular面向系统的字体栈;此声明不会下载字体。
--td-font-body-small12px / 20px次要紧凑标签。
--td-font-body-medium14px / 22px控制台正文。
--td-font-body-large16px / 24px较大的阅读文本。
--td-font-title-medium600 16px / 24px面板标题。
--td-font-headline-small600 24px / 32px页面标题。
--td-font-display-medium600 48px / 56px展示文字角色,策略编辑器中并非必需。

尺寸与语义间距

来源
名称 / 规则值 / 配置用途
--td-size-1 … --td-size-82, 4, 6, 8, 12, 16, 20, 24px非线性的基础比例。
--td-size-9 … --td-size-1628, 32, 36, 40, 48, 56, 64, 72px较大的比例值。
--td-comp-size-m32px中等组件高度别名。
--td-comp-paddingLR-m12px中等水平内边距别名。
--td-comp-paddingTB-l16px大号垂直内边距别名。
--td-comp-margin-xl20px间距别名与内边距 xl 不同。
--td-pop-padding-xxl16px弹出层内边距别名。

圆角样式

来源
名称 / 规则值 / 配置用途
--td-radius-small2px小圆角。
--td-radius-default3px默认圆角。
--td-radius-medium6px中圆角。
--td-radius-large9px大圆角。
--td-radius-extraLarge12px超大圆角。
--td-radius-round999px胶囊形样式。
--td-radius-circle50%圆形样式要求尺寸相等。

表单与表格约定

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

数据表格配置

来源
名称 / 规则值 / 配置用途
rowKeyStable unique data property示例为每条规则生成一次 id。
columns[].colKeyData key or custom cell key使用专用操作列。
columns[].cell({row,col,rowIndex,colIndex})渲染针对各行的控件。
tableLayoutfixed by default; auto available根据较长的资源路径确定列宽。
disableDataPagefalse by default除非明确禁用,否则由 Table 处理本地分页。
03

TDesign 设计系统完整指南

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

DESIGN-tdesign.md

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

下载指南

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

选择 React 的实现方案

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

摘自本 OpenDesign 指南

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

阅读配套规范

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

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

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

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

js
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 运行时。

html
<!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 行之前,应用层验证会检查名称是否为空、路径格式是否正确,以及资源是否重复。

jsx
// 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 示例已根据官方源代码核验;软件包编译与经过测试的离线预览是分开的。
04

TDesign 设计系统 AI Agent 设置

实现起点

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

bash
npm install tdesign-react react react-dom

适用于你项目的提示词

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

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

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