Корпоративное ПО · Новый ресурс

Дизайн-система TDesign.

Создайте компактный редактор политики API на основе TDesign React: конкретные роли тем, двухпиксельная шкала размеров, регистрация полей Form и типизированная композиция Table.

Руководство OpenDesign8 глав43 справочные записиАвторское руководство по приложению
01

Предпросмотр интерфейса дизайн-системы TDesign

Проверьте правило, изучите его локальное действие и удалите. Политика не развёртывается.

Редактор правил APIОткрыть полный пример
Автономная интерпретация TDesign светлых токенов и сочетания Form/Table на HTML/CSS; это не нативная среда выполнения React. · Справочник по реализации
02

Справочник по дизайну системы дизайн-система TDesign

TDesign React с текущей темой из открытой ветки develop и исходным кодом компонентов. Значения темы — снимки исходного кода, а не гарантия совместимости с закреплённой версией пакета. Автономный предпросмотр — интерпретация HTML; в примере React используется настоящий пакет API.

Роли светлой темы

Источник
Название / правилоЗначение / конфигурацияПрименение
--td-brand-color#0052d9 Основное действие, определяемое седьмым шагом палитры бренда.
--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Псевдоним интервала отличается от padding 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: семантические цвета, включая реальные различия тёмного режима

Седьмой шаг палитры бренда подходит не для всех режимов

В светлой теме роль бренда определяется седьмым шагом, а в тёмной — восьмым. В приложении сохраняйте семантическую переменную 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. Средний заголовок добавляет начертание 600 при размере 16/24; для небольшого заголовка используется 24/32. Это разные задачи: данные таблицы, подписи панелей и заголовок страницы не должны превращаться в полужирный основной текст.

В названии гарнитуры перечислены системные шрифты. Добавьте в типографику приложения подходящий резервный шрифт без засечек и одновременно проверьте китайские и латинские строки. Для пути к ресурсу можно задать моноширинный стиль приложения, не выдавая его за типографический токен TDesign.

Прочитать вспомогательную спецификацию

Дизайн-система TDesign: соотносите псевдонимы размеров с реальной областью

Названия интервалов не взаимозаменяемы

Средний горизонтальный внутренний отступ компонента равен 12px, а внешний отступ компонента extra-large — 20px. Не переводите все семантические суффиксы, опираясь на единую предположительную шкалу. В редакторе используется внешний отступ 24px и меньшие интервалы между полями, чтобы элементы управления оставались сгруппированными.

В автономном предпросмотре при узкой ширине редактор располагается над списком правил. Эта контрольная точка — решение приложения, а не гарантия фреймворка. Длинные пути API переносятся в списке, а не растягивают всю страницу за пределы области просмотра.

Прочитать вспомогательную спецификацию

Дизайн-система TDesign: зарегистрируйте форму, выполните проверку, затем добавьте правило

Связывайте ошибку поля с его ключом

Экземпляр Form передаётся компоненту Form; каждый FormItem задаёт имя поля. Обработчик отправки сначала проверяет validateResult, затем считывает собранные поля. Проверки приложения нормализуют строки и отклоняют повторяющиеся пути, чтобы две метки не могли незаметно настроить одну и ту же тестовую конечную точку.

  1. Зарегистрируйте имя, путь и состояние активности с помощью ключей FormItem.
  2. Отклоняйте записи без имени и пути, который начинается не с /, прежде чем добавлять данные.
  3. Используйте setFields с тем же ключом поля, чтобы показать ошибку, сохранив введённые значения для исправления.
  4. Добавляйте стабильный id только после успешной проверки; сообщайте, что результат локальный.

Прочитать вспомогательную спецификацию

Дизайн-система TDesign: сохраняйте идентичность строки при редактировании и удалении

Отделяйте отображаемые данные от ячеек действий

Таблица получает поле id через rowKey. В столбце enabled логическое значение преобразуется в понятный текст, а не отображается цветной точкой без подписи. В столбце действий выводится кнопка с именем строки — так вспомогательные технологии не воспринимают три одинаковых элемента «Удалить».

Для небольшого набора правил таблицу можно оставить без пагинации. Если вы добавляете пагинацию, прежде чем задавать disableDataPage, определите, используется ли встроенное разбиение локальных данных или данные поступают с сервера. Использовать позиции элементов массива как идентификаторы небезопасно: после удаления элемента их порядок меняется.

  • name — понятное пользователю название, а path — идентификатор ресурса.
  • enabled — данные приложения, которые отображаются в виде явного текста.
  • actions — пользовательский столбец, которому не требуется соответствующее сохранённое свойство.

Прочитать вспомогательную спецификацию

Дизайн-система TDesign. Локальное состояние не является развернутой политикой

Проверьте редактор политик как редактор

В автономном предпросмотре используются нативные подписанные элементы управления, область динамического статуса и видимый при навигации с клавиатуры фокус. При отправке формы с пустым именем или повторяющимся путём форма должна остаться открытой и указать конкретную проблему. Удаление правила изменяет только локальный список.

Для рабочего сервиса по-прежнему необходимы серверная проверка, авторизация, обработка конфликтов, журнал аудита и восстановление после отклонённого сохранения. Эти задачи нужно продумать для редактора, а не имитировать уведомлением об успехе, которое утверждает, что политика развернута.

Прочитать вспомогательную спецификацию

Дизайн-система TDesign. Подключите пакет и точно опишите возможности примера

Используйте нативный пример в коде приложения

В примере React импортируются настоящие компоненты TDesign Form, Input, Switch, Button и Table. Встроенный предпросмотр — автономная интерпретация HTML/CSS, работающая без загрузки пакета и доступа к сети. Проверка взаимодействий не доказывает, что все зависимости библиотеки скомпилированы в вашем проекте.

Связанные файлы темы — актуальные исходники для разработки. Определите версию установленного релиза по lock-файлу и сравните её токены, прежде чем копировать пользовательские переопределения. На этой странице намеренно указаны названия ролей и происхождение исходников: так изменения темы можно будет оценить, а не скрыть за иллюстративной палитрой.

Прочитать вспомогательную спецификацию

Дизайн-система TDesign. Примеры компонентов

Полноценный автономный интерактивный пример

Сохраните весь документ как index.html и откройте его в браузере. Автономная интерпретация HTML/CSS светлых токенов TDesign и сочетания Form/Table; это не нативная среда выполнения 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.

Зарегистрированный редактор правил и удаление строк по отдельности

Form собирает имя, путь к ресурсу и состояние enabled. Проверка на уровне приложения обнаруживает пустые имена, некорректные пути и повторяющиеся ресурсы до добавления локальной строки в 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; метка enabled не является решением об авторизации.
  • Пример установки/API сверялся с официальным исходным кодом; компиляция пакета не относится к проверке автономного предпросмотра.
04

Дизайн-система TDesign. Настройка ИИ-агента

Отправная точка для реализации

Используйте полный пример клиентской точки входа выше с корневым элементом HTML. Импортируйте tdesign-react/es/style/index.css один раз. Перед выпуском зафиксируйте версии и проверьте их совместимость с вашим инструментом сборки.

bash
npm install tdesign-react react react-dom

Запрос для вашего проекта

Промпт для AI-агента
Создайте редактор правил API с помощью Form и Table из tdesign-react. Сохраняйте семантические роли --td-*, зарегистрированные ключи полей, стабильные идентификаторы строк, явную проверку и точные сообщения о локальном состоянии.
05

Дизайн-система TDesign. Источники и область применения

Независимый справочник OpenDesign. Предпросмотр — автономная интерпретация, а не программное обеспечение Tencent или развернутый сервис авторизации.