企業ソフトウェア · 新しいリソース

TDesign デザインシステム.

TDesign Reactを使って、コンパクトなAPIポリシーエディターを構築します。具体的なテーマの役割、2ピクセル刻みのサイズスケール、Formフィールドの登録、型付けされたTableの構成を確認できます。

OpenDesign ガイド8章43件のリファレンス項目オリジナルアプリケーションガイド
01

TDesign デザインシステムのインターフェースプレビュー

ルールを検証し、その適用範囲を確認してから削除します。ポリシーはデプロイされません。

API ルールエディター完全な例を開く
TDesign のライトトークンと Form/Table の構成をHTML/CSSで独立して再現したものです。ネイティブのReactランタイムではありません。· 実装リファレンス
02

TDesign デザインシステムのデザインリファレンス

現在公開されている develop ブランチのテーマおよびコンポーネントのソースを使用したTDesign React。テーマ値はソースのスナップショットであり、特定バージョンのパッケージとの互換性を保証するものではありません。独立したプレビューは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スペーシングのエイリアスは 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 と Table の仕様

ソース
名前 / ルール値 / 設定用途
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この例ではルールごとに1回だけ 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 には、フレームワークごとに個別の実装があります。この例では、似た名前の Vue パッケージやモバイル向けコンポーネントセットではなく、意図的に tdesign-react を使用しています。グローバルスタイルシートも統合に必要です。コンポーネントをインポートするだけでは、ここに示すレイアウトやテーマのルールは適用されません。

この OpenDesign ガイドから

実用上の基本単位は、構造化された Table と並べて配置した、登録済みの Form です。名前、リソースパス、有効状態はデータフィールドで、行の削除はテーブルのアクションです。この例には認可バックエンドがないため、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 デザインシステム:フィールドの意味を保ちながら、情報密度の高いタイポグラフィを実現

フォントの役割をすべて指定する

Body mediumはフォントサイズ14px、行の高さ22pxです。Title mediumは16/24でウェイト600、small headlineは24/32です。それぞれ用途が異なります。テーブルのデータ、パネルのラベル、ページタイトルをすべて太字の本文にするべきではありません。

ソースでは、利用可能なシステムフォントの名前を指定しています。アプリケーション側のタイポグラフィには適切なsans-serifフォールバックを追加し、中国語とラテン文字の両方で確認してください。リソースパスにアプリケーション側の等幅フォントスタイルを適用しても、それがTDesignのタイポグラフィトークンであるとは限りません。

関連する仕様を確認する

TDesign デザインシステム:サイズのエイリアスを実際の領域に対応させる

スペーシングの名前を同じものとして扱わない

コンポーネントの水平方向のパディング「Medium」は12pxですが、コンポーネントのマージン「Extra Large」は20pxです。意味上の接尾辞を、推測した単一のスケールで一律に変換しないでください。エディターでは、コントロールをまとまりよく配置するため、外側に24pxのパディングを設け、フィールド間隔はそれより小さくしています。

単独プレビューでは、幅が狭い場合、エディターの下にルール一覧が配置されます。このブレークポイントはアプリケーション側の判断であり、フレームワークが保証するものではありません。長いAPIパスは一覧内で折り返されるため、ページ全体がビューポートより広くなることはありません。

関連する仕様を確認する

TDesign デザインシステム:登録、検証してからルールを追加する

フィールドのエラーを対応するキーに紐付ける

FormインスタンスをFormコンポーネントに渡し、各FormItemでフィールド名を指定します。送信ハンドラーはまずvalidateResultを確認し、その後に収集されたフィールドを読み取ります。アプリケーション側の検証では文字列を正規化し、パスの重複を拒否するため、同じサンプルエンドポイントが異なるラベルで誤って設定されることはありません。

  1. FormItemのキーを使って、name、path、enabledを登録します。
  2. データを追加する前に、nameが空でないこと、pathが/で始まることを検証します。
  3. 同じフィールドキーでsetFieldsを使ってエラーを表示し、入力済みの値は修正できるように残します。
  4. 検証に通った後でのみ安定したidを追加し、結果がローカルに保存されることを伝えます。

関連する仕様を確認する

TDesign デザインシステム:編集や削除後も行の識別情報を維持する

表示データと操作用セルを分ける

テーブルではrowKeyを使ってidフィールドを指定します。enabled列は、ラベルのない色付きドットではなく、Boolean値を読み取りやすいテキストで表示します。操作列のボタンには行名を含めることで、支援技術から「削除」という区別のつかないボタンが3つあるように認識されるのを避けます。

ルールが少ない場合は、テーブル全体をページネーションなしで表示できます。ページネーションを導入する場合は、disableDataPageを設定する前に、組み込みのローカルデータ分割とサーバー駆動のデータを区別してください。配列のインデックスを識別子として使うと、削除後に順序が変わるため安全ではありません。

  • nameはユーザーに表示するラベル、pathはリソースの識別情報です。
  • enabledはアプリケーションのデータであり、明示的なテキストで表示します。
  • actionsはカスタム列のため、対応する保存済みプロパティは必要ありません。

関連する仕様を確認する

TDesign デザインシステム:ローカル状態はデプロイ済みのポリシーではありません

ポリシーエディターをエディターとしてテストする

オフラインプレビューでは、ラベル付きのネイティブコントロール、ライブステータス領域、キーボード操作で確認できるフォーカス表示を使用しています。nameが空、またはpathが重複した状態で送信した場合、フォームは開いたまま具体的な問題を示す必要があります。ルールを削除しても、変更されるのはローカルの一覧だけです。

本番サービスでは、サーバー側の検証、認可、競合処理、監査ログ、保存拒否からの復旧も必要です。デプロイ済みであるかのように伝える成功トーストを表示して済ませるのではなく、こうした要件を踏まえてこのエディターを設計してください。

関連する仕様を確認する

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で別途説明しています。

登録済みルールのエディターと、行ごとの削除

Formではname、リソースパス、enabledの状態を収集します。アプリケーション側で空のname、不正なパス、リソースの重複を検証し、問題がなければローカルの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のルールエディターには、tdesign-reactのFormとTableを使用してください。意味上の役割を持つ--td-*、登録済みのフィールドキー、安定した行ID、明示的な検証、ローカル状態であることを正確に伝えるメッセージを維持します。
05

TDesign デザインシステムの情報源と対象範囲

独立したOpenDesignのリファレンスです。プレビューはオフラインでの再現であり、Tencentのソフトウェアでも、デプロイ済みの認可サービスでもありません。