协作软件 · 新资源

Atlassian 设计系统.

使用语义化的 Atlassian 设计令牌、8 像素间距标尺、真实的 Button、Lozenge 与 Toggle API,以及必需的 Compiled 样式配置,构建一块议题规划看板。检视一条议题、筛选看板,并移动本地工作项,同时不把选中与状态混为一谈。

OpenDesign 指南9 个章节46 条参考条目原始应用指南
01

Atlassian 设计系统 界面预览

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

带有固定检查器的问题看板打开完整示例
HTML/CSS 解读:采用经验证的间距和形状值、示意性配色及系统字体回退;并非 Jira 或原生 Atlaskit 运行时。· 实现参考
02

Atlassian 设计系统 设计参考

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

基于八像素的间距

来源
名称 / 规则值 / 配置用途
space.00px / 0rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.0252px / 0.125rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.0504px / 0.25rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.0756px / 0.375rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.1008px / 0.5rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.15012px / 0.75rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.20016px / 1rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.25020px / 1.25rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.30024px / 1.5rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.40032px / 2rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.50040px / 2.5rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.60048px / 3rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.80064px / 4rem间距令牌;后缀表示其占 8px 基准值的百分比。
space.100080px / 5rem间距令牌;后缀表示其占 8px 基准值的百分比。

语义化文本和界面表面角色

来源
名称 / 规则值 / 配置用途
color.textNeutral1000 / DarkNeutral1000主要文本;此处展示浅色/深色调色板别名。
color.text.subtleNeutral800 / DarkNeutral800次级标签。
color.text.subtlestNeutral700 / DarkNeutral700元数据。
color.text.selectedBlue700 / Blue400选中状态,而非业务工作流状态。
color.text.dangerRed800 / Red300重要说明文本。
color.text.inverseNeutral0 / DarkNeutral100适用于受支持的粗体填充色上的文本。
elevation.surfaceNeutral0 / DarkNeutral100主要应用界面表面。
elevation.surface.sunkenNeutral100 / DarkNeutral0看板列分组。
elevation.surface.raisedNeutral0 / DarkNeutral200可移动的工作项卡片。
elevation.surface.overlayNeutral0 / DarkNeutral250弹出层或覆盖层表面,搭配覆盖层阴影使用。

排版使用 CSS 字体简写

来源
名称 / 规则值 / 配置用途
font.heading.largeheading role页面标题。
font.heading.mediumheading role大型组件或详情标题。
font.heading.smallheading role小型组件标题。
font.bodybody role默认的简短描述和组件文本。
font.body.largereading role较长的说明。
font.body.smallsecondary role仅用于少量元数据。
font.codecode role技术标识符;不用于一般讨论。
font.weight.regular / medium / boldweight roles将字重作为对字体简写的刻意覆盖。

形状与深度

来源
名称 / 规则值 / 配置用途
radius.xsmall2px复选框或徽章等小型细节。
radius.small4px辅助标签和紧凑控件。
radius.medium6px交互控件。
elevation.shadow.raisedtheme-resolved multi-layer shadow搭配 elevation.surface.raised 使用。
elevation.shadow.overlaytheme-resolved multi-layer shadow搭配覆盖层表面使用;不要给每张卡片都加更粗的边框。

看板中使用的组件参数

来源
名称 / 规则值 / 配置用途
Button appearanceprimary / default / subtle / danger / warning根据操作含义选择。
Button isSelectedboolean视觉选中状态;不会更改问题状态。
Button isLoadingboolean显示进度时阻止重复交互。
Button spacingdefault / compact文档说明,Compact 适用于表格等密度较高的设置场景。
Button shouldFitContainerboolean允许操作控件占满其容器宽度。

状态与筛选器组合

来源
名称 / 规则值 / 配置用途
Lozenge appearance="information"In progress状态标记,不是可点击的状态变更控件。
Lozenge appearance="danger"Blocked使用文本标明具体情况。
Lozenge appearance="success"Completed此示例中的已确认本地状态。
Toggle isChecked + onChangecontrolled boolean此示例将其用于负责人筛选,而非工作流状态变更。
03

Atlassian 设计系统 完整指南

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

DESIGN-atlassian.md

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

下载指南

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

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

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

摘自本 OpenDesign 指南

当前的配置参考要求使用平台软件包的应用集成 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 原生运行时。

html
<!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。请按照设置中的文档说明,满足软件包和构建前置条件。

jsx
// 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。

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

代码参考

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

用于令牌转换的 Compiled 配置

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

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

代码参考

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

lozenge 用于描述状态;控件用于更改状态

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

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

代码参考

  • openIssueDetail 是应用处理程序;完整配置示例展示了选择状态。
  • 除非状态标签确实提供状态转换交互,否则不要让它看起来像菜单。
04

Atlassian 设计系统 Agent 设置

实现起点

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

jsx
// 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();

适用于你项目的提示词

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

Atlassian 设计系统 来源与范围

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