# Atlassian 设计系统

## Atlassian 设计系统 界面预览

查看问题、按负责人筛选，并更改本地工作流状态。状态与选中状态彼此独立。

## Atlassian 设计系统 设计参考

在代码中使用准确的语义令牌名称。官方参考提供的颜色调色板别名会随浅色/深色主题变化，因此这些条目保留别名，不臆造固定的十六进制值。数值间距和圆角取自文档中的比例。预览中的十六进制颜色仅用于示意，并非令牌导出值。

### 基于八像素的间距

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| space.0 | 0px / 0rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.025 | 2px / 0.125rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.050 | 4px / 0.25rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.075 | 6px / 0.375rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.100 | 8px / 0.5rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.150 | 12px / 0.75rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.200 | 16px / 1rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.250 | 20px / 1.25rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.300 | 24px / 1.5rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.400 | 32px / 2rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.500 | 40px / 2.5rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.600 | 48px / 3rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.800 | 64px / 4rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
| space.1000 | 80px / 5rem | 间距令牌；后缀表示其占 8px 基准值的百分比。 |
### 语义化文本和界面表面角色

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| color.text | Neutral1000 / DarkNeutral1000 | 主要文本；此处展示浅色/深色调色板别名。 |
| color.text.subtle | Neutral800 / DarkNeutral800 | 次级标签。 |
| color.text.subtlest | Neutral700 / DarkNeutral700 | 元数据。 |
| color.text.selected | Blue700 / Blue400 | 选中状态，而非业务工作流状态。 |
| color.text.danger | Red800 / Red300 | 重要说明文本。 |
| color.text.inverse | Neutral0 / DarkNeutral100 | 适用于受支持的粗体填充色上的文本。 |
| elevation.surface | Neutral0 / DarkNeutral100 | 主要应用界面表面。 |
| elevation.surface.sunken | Neutral100 / DarkNeutral0 | 看板列分组。 |
| elevation.surface.raised | Neutral0 / DarkNeutral200 | 可移动的工作项卡片。 |
| elevation.surface.overlay | Neutral0 / DarkNeutral250 | 弹出层或覆盖层表面，搭配覆盖层阴影使用。 |
### 排版使用 CSS 字体简写

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| font.heading.large | heading role | 页面标题。 |
| font.heading.medium | heading role | 大型组件或详情标题。 |
| font.heading.small | heading role | 小型组件标题。 |
| font.body | body role | 默认的简短描述和组件文本。 |
| font.body.large | reading role | 较长的说明。 |
| font.body.small | secondary role | 仅用于少量元数据。 |
| font.code | code role | 技术标识符；不用于一般讨论。 |
| font.weight.regular / medium / bold | weight roles | 将字重作为对字体简写的刻意覆盖。 |
### 形状与深度

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| radius.xsmall | 2px | 复选框或徽章等小型细节。 |
| radius.small | 4px | 辅助标签和紧凑控件。 |
| radius.medium | 6px | 交互控件。 |
| elevation.shadow.raised | theme-resolved multi-layer shadow | 搭配 elevation.surface.raised 使用。 |
| elevation.shadow.overlay | theme-resolved multi-layer shadow | 搭配覆盖层表面使用；不要给每张卡片都加更粗的边框。 |
### 看板中使用的组件参数

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| Button appearance | primary / default / subtle / danger / warning | 根据操作含义选择。 |
| Button isSelected | boolean | 视觉选中状态；不会更改问题状态。 |
| Button isLoading | boolean | 显示进度时阻止重复交互。 |
| Button spacing | default / compact | 文档说明，Compact 适用于表格等密度较高的设置场景。 |
| Button shouldFitContainer | boolean | 允许操作控件占满其容器宽度。 |
### 状态与筛选器组合

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| Lozenge appearance="information" | In progress | 状态标记，不是可点击的状态变更控件。 |
| Lozenge appearance="danger" | Blocked | 使用文本标明具体情况。 |
| Lozenge appearance="success" | Completed | 此示例中的已确认本地状态。 |
| Toggle isChecked + onChange | controlled boolean | 此示例将其用于负责人筛选，而非工作流状态变更。 |
## Atlassian 设计系统 完整指南

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

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

## Atlassian 设计系统 公开的 ADS 软件包及实际样式要求

### 导入组件并不代表集成已完成

> Atlassian Design System 组件发布在 @atlaskit 下，但更广泛的 Atlaskit 目录还包含面向特定应用的软件包。此示例选用了三个有文档说明的基础组件：Button、Lozenge 和 Toggle，以及令牌和 CSS 重置样式。其数据模型有意保持在本地。这些导入均不提供 Jira 问题权限、迭代逻辑或后端。

当前的配置参考要求使用平台软件包的应用集成 Compiled，即使应用本身不编写 Compiled 样式也是如此。因此，示例中提供的 Parcel 配置也是必需部分。仅复制 Button 导入而不配置打包工具，可能导致样式不完整或加载顺序不正确；这是功能性集成问题，并非无关紧要的外观细节。

阅读配套规范

## Atlassian 设计系统 使用语义令牌，而不是猜测调色板颜色

### 令牌用于描述用途

token("color.text") 是主要前景色，token("color.text.subtle") 用于次要信息。选中文本和危险文本使用不同的角色。看板的主区域使用 elevation.surface，分组区域使用 elevation.surface.sunken。主题变化时，这些选择依然清晰易懂，因为名称表达了各自的用途。

官方目录为这些角色提供浅色和深色调色板别名。参考表保留了这些信息，而不会承诺某个固定的十六进制颜色值。内嵌示例使用说明为示意用途的调色板，并明确标注了这一点。这些颜色让本地示例清晰易读，但不能取代生产环境 Atlaskit 主题的权威来源。

阅读配套规范

## Atlassian 设计系统 以 8 像素为基准，采用经过设计的细分步进

### 后缀表示百分比

space.100 为 8px；space.200 为 16px；space.025 为 2px。该比例尺包含细分步进，因为较小的间距和视觉对齐需要比完整的 8 像素单位更高的精度。看板主要内容周围使用 space.300，局部项目之间使用 space.150。令牌调用会返回适配主题的 CSS 值，而不是一个可供任意进行 JavaScript 运算的数字。

相同的关系应使用相同的间距。事项键和标题之间的距离应小于事项列表与检查器之间的间隔。虽然存在负间距令牌，但普通看板布局并不需要它们。密集的工作界面应通过布局组合来增加空间，而不是让互不相关的元素相互覆盖。

阅读配套规范

## Atlassian 设计系统 字体令牌是完整的字体声明

### 不要将 font.body 用作 font-size

目录明确为 CSS font 属性定义了组合字体令牌。示例为页面标题指定 font.heading.large，为详情标题指定 font.heading.medium。将其中一个令牌用作 fontSize 会破坏其预期约定。正文角色适用于简短的事项摘要；如果周围布局适合阅读，较长的描述则可以使用 font.body.large。

当前应用字体为 Atlassian Sans 和 Atlassian Mono。Sans 衍生自 Inter Variable；Mono 衍生自 JetBrains Mono。介绍设计系统时，这些信息很重要，但此独立预览不会重新分发这些字体。它使用系统回退字体，并对此作出说明。生产环境中的接入应采用受支持的字体分发和许可途径，而不是给任意字体改名。

阅读配套规范

## Atlassian 设计系统 使用形状和层级说明工作界面

### 卡片因作为独立对象而凸起显示

参考内容区分了下沉式分组表面、凸起卡片和覆盖层表面。可移动的工作项在概念上属于凸起层，而看板列用于对这些工作项进行分组。作为常规页面一部分的检查器不一定需要覆盖层阴影。只有在层级确实重要时，才应搭配使用表面和阴影角色。

当前形状名称包括 radius.xsmall（2px）、radius.small（4px）和 radius.medium（6px）。它们不是开发者可能从其他设计系统中熟悉的旧式 border.radius 命名。表格保留了准确名称。原生控件应使用其自带样式；自定义外层容器可以采用相应角色，但不要覆盖私有生成类。

阅读配套规范

## Atlassian 设计系统 按钮选中状态与事项流转不同

### 有意选择外观和状态

已验证的 Button 导入路径为 @atlaskit/button/default/button。appearance="primary" 用于突出主要操作；在这个精简的原生示例中，isSelected 标记当前事项。点击它只会更改正在查看的事项。另一个独立控件用于编辑工作流状态。这样的区分可以避免选择某一行时悄然开始或完成工作。

API 还包括 isLoading、isDisabled、spacing="compact" 和 shouldFitContainer。加载状态表示操作正在进行，而不是永久的事项状态。禁用操作时应说明清楚原因，因为键盘导航可能会跳过禁用控件。因此，独立看板会保留可用的检查控件，并允许用户直接查看当前本地状态。

阅读配套规范

## Atlassian 设计系统 Lozenge 和 Toggle 用于表达不同类型的状态

### 状态不等于交互模式

Lozenge 的外观包括 information、danger 和 success，示例分别将它们用于「进行中」「受阻」和「已完成」。文字承载含义，颜色只是辅助信息。事项即使处于选中状态，仍保持受阻状态。所有者筛选器使用带有 isChecked 和 onChange 的 Toggle，因为这个布尔值会影响看板显示的内容，而不会更改任何事项。

本地状态选择器刻意保持简单，并不代表真实的权限模型。生产环境中的事项流转可能需要原因、角色或服务端响应。授权逻辑应放在 Lozenge 之外，并且只有在服务端确认后才显示已生效的结果。

- 选中状态表示当前正在查看的事项。

- 工作流状态描述工作项本身。

- 所有者筛选会更改可见项目，但不会更改所有权。

阅读配套规范

## Atlassian 设计系统 在渲染自定义令牌表面之前初始化主题

### 全局主题加载是异步的

setGlobalTheme 会更新文档主题属性并加载所选主题 CSS。入口会等待该操作完成后再渲染看板。它会显式选择浅色和深色主题，并默认启用浅色模式。实际的偏好设置控件可以通过同一个 API 更新 colorMode，而不必替换为随机的内联颜色。

当前自定义品牌选项标记为 alpha，并使用 UNSAFE API。本指南不会仅为更改示例颜色而采用这条不稳定途径。应先确保稳定的语义主题约定，再将实验性自定义作为单独的依赖决策进行评估。

阅读配套规范

## Atlassian 设计系统 验证实际的事项查看交互

### 配套使用提供的文件

原生示例需要 JSX 入口、CSS reset 导入，以及两个 Parcel 配置文件。示例包含问题集合、选择、负责人筛选、状态映射和实时结果消息。独立预览将组合扩展为多个列和检查器，但明确标注为 HTML 诠释。两者都不声称连接到 Jira。

筛选条件排除所选问题时，原生示例会有意保留其详情。读者仍可检查该对象，而不会在不知情的情况下跳转到其他条目。生产设计可以选择其他策略，但应说明该策略并保留有意义的焦点。请同时在窄视口和所有列均可见时验证此行为。

1. 检查 WEB-18，然后选择其他问题，但不要更改其工作流状态。

2. 启用负责人筛选，并检查哪些问题仍然可见。

3. 更改所选本地问题的状态，并确认其状态文本与所在列一致。

4. 恢复未筛选的看板，并确认问题标识和更新后的状态保持不变。

阅读配套规范

## Atlassian 设计系统组件示例

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

将完整文档保存为 index.html，然后在浏览器中打开。HTML/CSS 诠释，使用经过验证的间距和形状数值、示意性色彩方案及系统字体回退；并非 Jira 或 Atlaskit 原生运行时。

```
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Issue board — Atlassian interpretation</title><style>*{box-sizing:border-box}body{margin:0;background:#fff;color:#172b4d;font:14px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}button,select{font:inherit}button{cursor:pointer}header{padding:16px 24px;border-bottom:1px solid #dfe1e6;display:flex;align-items:center;justify-content:space-between;gap:16px}header strong{font-size:18px}.logo{color:#0c66e4;margin-right:12px}button{border:0;border-radius:4px;background:#f1f2f4;color:#172b4d;padding:8px 12px}button:hover{background:#dcdfe4}button:focus-visible,select:focus-visible{outline:3px solid #0c66e4;outline-offset:2px}.primary{background:#0c66e4;color:white}.primary:hover{background:#0055cc}main{padding:24px}.crumb{color:#626f86;font-size:12px}h1{font-size:24px;line-height:32px;margin:8px 0 16px}.tools{display:flex;align-items:center;gap:12px;margin-bottom:24px}.layout{display:grid;grid-template-columns:minmax(0,1fr) 270px;gap:24px}.board{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;align-items:start}.column{background:#f7f8f9;min-height:280px;padding:8px;border-radius:6px}.column h2{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:#626f86;margin:8px 4px 16px}.issue{text-align:left;background:white;box-shadow:0 1px 2px #091e4240;width:100%;margin-bottom:8px;padding:12px;display:block;border:2px solid transparent}.issue[aria-pressed=true]{border-color:#0c66e4}.issue:hover{background:#fff;border-color:#85b8ff}.issue strong{display:block;font-weight:500;min-height:46px}.meta{display:flex;justify-content:space-between;align-items:center;margin-top:20px;font-size:11px;color:#626f86}.avatar{display:inline-grid;place-items:center;width:24px;height:24px;background:#dfe1e6;border-radius:50%;font-weight:600}.tag{font-size:11px;line-height:18px;padding:1px 5px;font-weight:700;border-radius:3px;display:inline-block;background:#dfe1e6}.tag[data-status="In progress"]{background:#e9f2ff;color:#0055cc}.tag[data-status=Blocked]{background:#ffedeb;color:#ae2a19}.tag[data-status=Done]{background:#dcfff1;color:#216e4e}aside{border-left:1px solid #dfe1e6;padding-left:24px}aside h2{font-size:18px;line-height:26px;margin:12px 0 24px}dl{margin:0}dt{font-weight:600;margin:20px 0 8px}dd{margin:0}select{padding:8px;border:1px solid #8590a2;border-radius:4px;background:white;color:#172b4d;max-width:100%}.empty{padding:12px;color:#626f86;font-size:12px}footer{border-top:1px solid #dfe1e6;padding:16px 24px;color:#626f86;font-size:11px}#announcement{min-height:20px;color:#44546f;margin-top:16px}@media(max-width:720px){main{padding:16px}.layout{grid-template-columns:1fr}.board{grid-template-columns:1fr}.column{min-height:100px}aside{border-left:0;border-top:1px solid #dfe1e6;padding:16px 0 0}.issue strong{min-height:0}header{padding:16px}.tools{flex-wrap:wrap}}
</style><header><strong><span class="logo">▲</span>Product delivery</strong><span class="tag">LOCAL DEMO</span></header><main><div class="crumb">Projects / Website / Board</div><h1>Website release</h1><div class="tools"><label><input type="checkbox" id="mine"> Only Maya’s issues</label><button id="reset">Reset board</button></div><div class="layout"><section class="board" aria-label="Issues by status" id="board"></section><aside aria-label="Selected issue"><span id="key" class="crumb"></span><h2 id="title"></h2><span id="badge" class="tag"></span><dl><dt>Assignee</dt><dd id="owner"></dd><dt>Description</dt><dd id="description"></dd><dt><label for="status">Move issue to</label></dt><dd><select id="status"><option>To do</option><option>In progress</option><option>Blocked</option><option>Done</option></select></dd></dl><p id="announcement" role="status"></p></aside></div></main><footer>Independent HTML/CSS interpretation of Atlassian spacing, semantic status and persistent issue selection. System font and sample colors; no Jira connection.</footer><script>
const initial=[{id:'WEB-18',title:'Audit navigation labels',owner:'Maya Chen',status:'To do',description:'Review the wording of top-level links and check that each label describes its destination.'},{id:'WEB-21',title:'Connect locale switcher',owner:'Theo Park',status:'In progress',description:'Keep the current resource selected when a reader switches between supported languages.'},{id:'WEB-24',title:'Resolve missing image credits',owner:'Maya Chen',status:'Blocked',description:'The launch requires confirmation of the source and permitted use of two editorial images.'}];let issues=structuredClone(initial),selected='WEB-21';const board=document.querySelector('#board'),status=document.querySelector('#status');
function render(){board.replaceChildren();for(const state of ['To do','In progress','Blocked / Done']){const col=document.createElement('section');col.className='column';const entries=issues.filter(x=>(state==='Blocked / Done'?['Blocked','Done'].includes(x.status):x.status===state)&&(!document.querySelector('#mine').checked||x.owner==='Maya Chen'));const h=document.createElement('h2');h.textContent=state+' · '+entries.length;col.append(h);for(const issue of entries){const b=document.createElement('button');b.className='issue';b.setAttribute('aria-pressed',String(selected===issue.id));const t=document.createElement('strong');t.textContent=issue.title;const meta=document.createElement('span');meta.className='meta';meta.textContent=issue.id;const av=document.createElement('span');av.className='avatar';av.textContent=issue.owner.split(' ').map(x=>x[0]).join('');av.title=issue.owner;meta.append(av);b.append(t,meta);b.onclick=()=>{selected=issue.id;render();document.querySelector('#announcement').textContent='Selected '+issue.id};col.append(b)}if(!entries.length){const p=document.createElement('p');p.className='empty';p.textContent='No matching issues';col.append(p)}board.append(col)}const item=issues.find(x=>x.id===selected);document.querySelector('#key').textContent=item.id;document.querySelector('#title').textContent=item.title;document.querySelector('#owner').textContent=item.owner;document.querySelector('#description').textContent=item.description;const badge=document.querySelector('#badge');badge.textContent=item.status;badge.dataset.status=item.status;status.value=item.status}
status.onchange=()=>{const i=issues.find(x=>x.id===selected);i.status=status.value;render();document.querySelector('#announcement').textContent=i.id+' moved to '+i.status+' in this local board.'};document.querySelector('#mine').onchange=render;document.querySelector('#reset').onclick=()=>{issues=structuredClone(initial);selected='WEB-21';document.querySelector('#mine').checked=false;render();document.querySelector('#announcement').textContent='Board reset.'};render();
</script></html>
```

代码参考

- 问题转换仅影响示例看板。此 HTML 入口未使用独立 Atlaskit 实现所需的 Compiled 构建配置。

### 完整的原生实现入口

此处汇总了从设置到完整实现的内容，并附有重点说明 API。请按照设置中的文档说明，满足软件包和构建前置条件。

```
// Existing React 18 project; use the Parcel configuration examples below.
// npm install @atlaskit/css-reset @atlaskit/tokens @atlaskit/button @atlaskit/lozenge @atlaskit/toggle
// npm install --save-dev parcel @compiled/parcel-config
// src/main.jsx; HTML entry contains <div id="root"></div> and a module script pointing here.
import * as React from 'react';
import {createRoot} from 'react-dom/client';
import '@atlaskit/css-reset';
import {token, setGlobalTheme} from '@atlaskit/tokens';
import Button from '@atlaskit/button/default/button';
import Lozenge from '@atlaskit/lozenge/lozenge';
import Toggle from '@atlaskit/toggle';
const initial = [
  {id:'WEB-18',title:'Clarify first-project copy',owner:'Maya',status:'To do'},
  {id:'WEB-21',title:'Review keyboard path',owner:'Alex',status:'In progress'},
  {id:'WEB-24',title:'Resolve missing illustrations',owner:'Maya',status:'Blocked'}
];
const appearance = {'To do':'default','In progress':'information','Blocked':'danger','Done':'success'};
function Board() {
  const [issues,setIssues]=React.useState(initial);
  const [selected,setSelected]=React.useState('WEB-18');
  const [mine,setMine]=React.useState(false);
  const [notice,setNotice]=React.useState('');
  const issue=issues.find(i=>i.id===selected);
  return <main style={{padding:token('space.300'),color:token('color.text'),background:token('elevation.surface')}}>
    <h1 style={{font:token('font.heading.large')}}>Onboarding improvements</h1>
    <label htmlFor="mine">Assigned to Maya</label>
    <Toggle id="mine" isChecked={mine} onChange={e=>setMine(e.currentTarget.checked)}/>
    <div style={{display:'flex',flexWrap:'wrap',gap:token('space.300'),marginTop:token('space.200')}}>
      <ul style={{flex:'1 1 280px',listStyle:'none',padding:0}}>
        {issues.filter(i=>!mine||i.owner==='Maya').map(i=><li key={i.id} style={{marginBottom:token('space.150')}}>
          <Button isSelected={i.id===selected} onClick={()=>setSelected(i.id)}>{i.id}: {i.title}</Button>
          {' '}<Lozenge appearance={appearance[i.status]}>{i.status}</Lozenge>
        </li>)}
      </ul>
      <section aria-label="Issue details" style={{flex:'1 1 280px',padding:token('space.200'),background:token('elevation.surface.sunken')}}>
        <h2 style={{font:token('font.heading.medium')}}>{issue.id}: {issue.title}</h2>
        <p>Owner: {issue.owner}</p>
        <label htmlFor="status">Workflow state</label>{' '}
        <select id="status" value={issue.status} onChange={event=>{
          const status=event.target.value;
          setIssues(items=>items.map(i=>i.id===issue.id?{...i,status}:i));
          setNotice(`${issue.id} moved to ${status} in this local example.`);
        }}>{Object.keys(appearance).map(s=><option key={s}>{s}</option>)}</select>
        <p>This local demonstration has no Jira connection or permission rules.</p>
      </section>
    </div><p role="status">{notice}</p>
  </main>;
}
async function start(){
  await setGlobalTheme({light:'light',dark:'dark',colorMode:'light'});
  createRoot(document.getElementById('root')).render(<Board/>);
}
start();
```

代码参考

- 完整的 React 看板逻辑，以及下方所需的配置片段。使用集成了 Compiled 的 Parcel；对于当前软件包，仅导入 CSS reset 并不足够。此本地原型未声称已完成原生软件包编译。

### Parcel 必须处理已分发的 Compiled 样式

在项目根目录创建 .parcelrc。安装 setup 中列出的依赖项后，使用其 HTML 入口启动 Parcel。

```
{
  "extends": ["@parcel/config-default", "@compiled/parcel-config"]
}
```

代码参考

- 此处选择了文档说明的 Parcel 集成方式，而不是悄然将实验性的 Vite 路径当作推荐配置。

### 用于令牌转换的 Compiled 配置

在 .parcelrc 旁创建 .compiledcssrc。这属于使用方应用的配置，不是软件包发布脚本。

```
{
  "transformerBabelPlugins": [["@atlaskit/tokens/babel-plugin"]],
  "extract": true,
  "inlineCss": true,
  "sortShorthand": true
}
```

代码参考

- 可选的 strip-runtime 插件适用于分发提取后 CSS 的软件包；使用方应用无需使用它。

### lozenge 用于描述状态；控件用于更改状态

在问题详情中，显示状态与状态转换控件各司其职。

```
<Lozenge appearance="danger">Blocked</Lozenge>
<Button appearance="primary" onClick={openIssueDetail}>Review blocker</Button>
```

代码参考

- openIssueDetail 是应用处理程序；完整配置示例展示了选择状态。

- 除非状态标签确实提供状态转换交互，否则不要让它看起来像菜单。

## Atlassian 设计系统 Agent 设置

### 实现起点

完整的 React 看板逻辑，以及下方所需的配置片段。使用集成了 Compiled 的 Parcel；对于当前软件包，仅导入 CSS reset 并不足够。此本地原型未声称已完成原生软件包编译。

```
// Existing React 18 project; use the Parcel configuration examples below.
// npm install @atlaskit/css-reset @atlaskit/tokens @atlaskit/button @atlaskit/lozenge @atlaskit/toggle
// npm install --save-dev parcel @compiled/parcel-config
// src/main.jsx; HTML entry contains <div id="root"></div> and a module script pointing here.
import * as React from 'react';
import {createRoot} from 'react-dom/client';
import '@atlaskit/css-reset';
import {token, setGlobalTheme} from '@atlaskit/tokens';
import Button from '@atlaskit/button/default/button';
import Lozenge from '@atlaskit/lozenge/lozenge';
import Toggle from '@atlaskit/toggle';
const initial = [
  {id:'WEB-18',title:'Clarify first-project copy',owner:'Maya',status:'To do'},
  {id:'WEB-21',title:'Review keyboard path',owner:'Alex',status:'In progress'},
  {id:'WEB-24',title:'Resolve missing illustrations',owner:'Maya',status:'Blocked'}
];
const appearance = {'To do':'default','In progress':'information','Blocked':'danger','Done':'success'};
function Board() {
  const [issues,setIssues]=React.useState(initial);
  const [selected,setSelected]=React.useState('WEB-18');
  const [mine,setMine]=React.useState(false);
  const [notice,setNotice]=React.useState('');
  const issue=issues.find(i=>i.id===selected);
  return <main style={{padding:token('space.300'),color:token('color.text'),background:token('elevation.surface')}}>
    <h1 style={{font:token('font.heading.large')}}>Onboarding improvements</h1>
    <label htmlFor="mine">Assigned to Maya</label>
    <Toggle id="mine" isChecked={mine} onChange={e=>setMine(e.currentTarget.checked)}/>
    <div style={{display:'flex',flexWrap:'wrap',gap:token('space.300'),marginTop:token('space.200')}}>
      <ul style={{flex:'1 1 280px',listStyle:'none',padding:0}}>
        {issues.filter(i=>!mine||i.owner==='Maya').map(i=><li key={i.id} style={{marginBottom:token('space.150')}}>
          <Button isSelected={i.id===selected} onClick={()=>setSelected(i.id)}>{i.id}: {i.title}</Button>
          {' '}<Lozenge appearance={appearance[i.status]}>{i.status}</Lozenge>
        </li>)}
      </ul>
      <section aria-label="Issue details" style={{flex:'1 1 280px',padding:token('space.200'),background:token('elevation.surface.sunken')}}>
        <h2 style={{font:token('font.heading.medium')}}>{issue.id}: {issue.title}</h2>
        <p>Owner: {issue.owner}</p>
        <label htmlFor="status">Workflow state</label>{' '}
        <select id="status" value={issue.status} onChange={event=>{
          const status=event.target.value;
          setIssues(items=>items.map(i=>i.id===issue.id?{...i,status}:i));
          setNotice(`${issue.id} moved to ${status} in this local example.`);
        }}>{Object.keys(appearance).map(s=><option key={s}>{s}</option>)}</select>
        <p>This local demonstration has no Jira connection or permission rules.</p>
      </section>
    </div><p role="status">{notice}</p>
  </main>;
}
async function start(){
  await setGlobalTheme({light:'light',dark:'dark',colorMode:'light'});
  createRoot(document.getElementById('root')).render(<Board/>);
}
start();
```

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

```
使用 @atlaskit tokens、CSS reset 和有文档说明的 Compiled Parcel 集成，构建所提供的 React 18 个 Atlassian 问题示例。使用语义化令牌调用、字体简写角色，以及经过验证的 Button/Lozenge/Toggle 导入。让选择、负责人筛选和工作流状态彼此独立。保留所选问题的上下文，播报本地更改，并且不要声称连接了 Jira 或具备真实权限。
```

## Atlassian 设计系统 来源与范围

对公开 Atlassian Design System React 软件包进行的 OpenDesign 研究，并于 2026 年 10 月依据所链接的文档进行核查。嵌入式看板是采用示意性配色值和虚构问题的 HTML/CSS 诠释，并非 Jira 或 Atlaskit 原生运行时。公开访问软件包并不意味着对 Atlassian 品牌拥有不受限制的使用权，也不代表可获得与内部团队相同的支持。

- 令牌 关于本指南所述具体 API、比例或集成要求的官方来源。

- 主题 关于本指南所述具体 API、比例或集成要求的官方来源。

- 设置 关于本指南所述具体 API、比例或集成要求的官方来源。

- 间距 关于本指南所述具体 API、比例或集成要求的官方来源。

- 排版 关于本指南所述具体 API、比例或集成要求的官方来源。

- 字体 关于本指南所述具体 API、比例或集成要求的官方来源。

- 按钮 关于本指南所述具体 API、比例或集成要求的官方来源。

- lozenge 关于本指南所述具体 API、比例或集成要求的官方来源。

- 切换开关 关于本指南所述具体 API、比例或集成要求的官方来源。

## Atlassian 设计系统 相关资源

### AWS Cloudscape

一份 Cloudscape 配置指南，包含真实的可视化刷新令牌、感知密度的间距、受控表单 API，以及可运行的两步资源向导。

### Backbase 设计系统

使用 Backbase 的 Angular 模块、语义主题导出和明确的审核状态构建品牌银行审核流程。比较 Web API 与单独记录的原生尺寸。

### Dell 设计系统

使用 DDS v3 构建范围明确的设备搜索：采用语义化颜色、响应式字号比例和令牌间距，并组合 InputGroup；筛选行为由应用负责。


- [实现参考](https://atlassian.design/components/button/examples)
- [来源](https://atlassian.design/foundations/spacing/)
- [来源](https://atlassian.design/components/tokens/all-tokens)
- [来源](https://atlassian.design/foundations/typography/applying-typography)
- [来源](https://atlassian.design/components/button/examples)
- [来源](https://atlassian.design/components/lozenge/examples)
- [阅读配套规范](https://atlassian.design/get-started/develop/atlassians)
- [阅读配套规范](https://atlassian.design/components/tokens/all-tokens)
- [阅读配套规范](https://atlassian.design/foundations/spacing/)
- [阅读配套规范](https://atlassian.design/foundations/typography/product-typefaces-and-scale)
- [阅读配套规范](https://atlassian.design/components/button/examples)
- [阅读配套规范](https://atlassian.design/components/lozenge/examples)
- [阅读配套规范](https://atlassian.design/components/tokens/code)
- [阅读配套规范](https://atlassian.design/components/toggle/examples)
- [代码参考](https://atlassian.design/components/button/examples)
- [代码参考](https://atlassian.design/get-started/develop/atlassians)
- [代码参考](https://atlassian.design/components/lozenge/examples)
- [令牌 关于本指南所述具体 API、比例或集成要求的官方来源。](https://atlassian.design/components/tokens/all-tokens)
- [主题 关于本指南所述具体 API、比例或集成要求的官方来源。](https://atlassian.design/components/tokens/code)
- [设置 关于本指南所述具体 API、比例或集成要求的官方来源。](https://atlassian.design/get-started/develop/atlassians)
- [间距 关于本指南所述具体 API、比例或集成要求的官方来源。](https://atlassian.design/foundations/spacing/)
- [排版 关于本指南所述具体 API、比例或集成要求的官方来源。](https://atlassian.design/foundations/typography/applying-typography)
- [字体 关于本指南所述具体 API、比例或集成要求的官方来源。](https://atlassian.design/foundations/typography/product-typefaces-and-scale)
- [按钮 关于本指南所述具体 API、比例或集成要求的官方来源。](https://atlassian.design/components/button/examples)
- [lozenge 关于本指南所述具体 API、比例或集成要求的官方来源。](https://atlassian.design/components/lozenge/examples)
- [切换开关 关于本指南所述具体 API、比例或集成要求的官方来源。](https://atlassian.design/components/toggle/examples)
