コラボレーションソフトウェア · 新しいリソース

Atlassian デザインシステム.

セマンティックな Atlassian トークン、8 ピクセルのスペーシングスケール、実際の Button、Lozenge、Toggle の API、そして必須の Compiled スタイリングのセットアップを使って、課題計画ボードを構築します。課題を検査し、ボードを絞り込み、選択とステータスを混同することなくローカルの作業項目を移動します。

OpenDesign ガイド9 章参考資料46件オリジナルアプリケーションガイド
01

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

課題を確認し、担当者で絞り込み、ローカルなワークフロー状態を変更できます。ステータスと選択状態はそれぞれ独立しています。

常時表示されるインスペクターを備えた課題ボード完全な例を開く
検証済みの間隔と形状の値を使ったHTML/CSSの解釈に、説明用のカラーパレットとシステムフォントのフォールバックを組み合わせています。JiraやネイティブのAtlaskitランタイムではありません。· 実装リファレンス
02

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

コードでは正確な意味トークン名を使ってください。公式リファレンスでは、ライト/ダークテーマによって異なるカラーパレットのエイリアスが公開されています。そのため、ここでは固定の16進数値を独自に設定せず、エイリアスをそのまま記載しています。間隔と角丸の数値は、ドキュメントに記載されたスケールに基づいています。プレビューの16進数カラーは説明用であり、トークンの出力値ではありません。

8ピクセルを基準にした間隔

ソース
名前 / ルール値 / 設定用途
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 shorthandを使用

ソース
名前 / ルール値 / 設定用途
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 rolesfont shorthandのウェイトを意図的に上書きします。

形状と奥行き

ソース
名前 / ルール値 / 設定用途
radius.xsmall2pxチェックボックスやバッジなどの小さなディテール。
radius.small4px補助ラベルやコンパクトなコントロール。
radius.medium6pxインタラクティブなコントロール。
elevation.shadow.raisedtheme-resolved multi-layer shadowelevation.surface.raisedと組み合わせます。
elevation.shadow.overlaytheme-resolved multi-layer shadowオーバーレイの背景面と組み合わせます。すべてのカードの境界を強調する用途ではありません。

ボードで使用するコンポーネントのパラメーター

ソース
名前 / ルール値 / 設定用途
Button appearanceprimary / default / subtle / danger / warningアクションの意味に合わせて選択します。
Button isSelectedboolean視覚的な選択状態。課題の状態は変更しません。
Button isLoadingboolean処理中であることを示しながら、連続した操作を防ぎます。
Button spacingdefault / compactcompactは、テーブルなど、より高密度な設定向けとしてドキュメントに記載されています。
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の広範なカタログにはアプリ固有のパッケージも含まれます。この例では、ドキュメントに記載された3つのプリミティブ、Button、Lozenge、Toggleに加え、トークンとCSSリセットを使用しています。データモデルは意図的にローカルなものにしています。これらをインポートしても、Jiraの課題へのアクセス権限、スプリントのロジック、バックエンドが提供されるわけではありません。

この OpenDesign ガイドから

現在のセットアップリファレンスでは、アプリケーションがCompiledのスタイルを作成しない場合でも、プラットフォームパッケージを利用するアプリケーションにはCompiledの統合が必要とされています。そのため、付属のParcel設定もこの例の一部です。バンドラーを設定せずにButtonのインポートだけをコピーすると、スタイルが一部適用されなかったり、順序が正しくならなかったりすることがあります。これは、見た目に関する小さな注記ではなく、機能上の統合に関わる問題です。

関連する仕様を確認する

Atlassian デザインシステム 色の推測ではなく、意味に基づくトークンを使う

トークンは役割を表す

token("color.text")は主となる前景色、token("color.text.subtle")は補助情報に使います。選択中のテキストには、危険を示すテキストとは別の役割を割り当てます。ボードのメイン領域にはelevation.surface、グループ化する領域にはelevation.surface.sunkenを使用します。名前が用途を表しているため、テーマが変わっても意味は明確です。

公式カタログには、これらの役割に対応するライト/ダークのカラーパレットエイリアスが記載されています。ここでは、単一の16進数値が常に使われると誤解されないよう、その情報をそのまま保持しています。埋め込みの例では説明用のパレットを使い、その旨を明記しています。色はローカルな例を見やすくするためのものであり、本番のAtlaskitテーマにおける信頼できる情報源ではありません。

関連する仕様を確認する

Atlassian デザインシステム 8ピクセルを基準にした、意図的な端数ステップ

接尾辞は割合として読み取ります

space.100 は 8px、space.200 は 16px、space.025 は 2px です。小さな隙間や視覚的な位置合わせには、8px 単位より細かな調整が必要なため、このスケールには小数刻みの段階があります。ボードでは主要なコンテンツの周囲に space.300、個々の項目の間に space.150 を使用します。トークンの呼び出しで返されるのは、任意のJavaScript算術演算に使う数値ではなく、テーマに対応したCSS値です。

同じ関係性には、同じ間隔を使います。課題キーとタイトルの間隔は、課題リストとインスペクターの間隔より小さくします。負のスペーシングトークンもありますが、通常のボードレイアウトでは必要ありません。密度の高い作業面に余白を設けるには、無関係な要素を重ねるのではなく、構成を工夫してください。

関連する仕様を確認する

Atlassian デザインシステム タイポグラフィトークンは、フォント宣言一式です

font.body を font-size に指定しない

カタログでは、CSS font プロパティ用の複合フォントトークンが明示的に定義されています。サンプルでは、ページタイトルに font.heading.large、詳細タイトルに font.heading.medium を割り当てています。これらのトークンを fontSize として使うと、本来の契約が失われます。短い課題の概要には body ロールが適しています。長い説明には、周囲のレイアウトが読書に適している場合、font.body.large を使用できます。

現在のアプリケーション書体は Atlassian Sans と Atlassian Mono です。Sans は Inter Variable、Mono は JetBrains Mono をベースにしています。システムを説明するうえでこの書体の情報は重要ですが、この単独のプレビューでそれらのフォントを再配布しているわけではありません。プレビューではシステムフォントを代替書体として使用していることを明示しています。本番環境で導入する際は、任意の書体に別の名前を付けるのではなく、サポートされているフォントの配信方法とライセンスに従ってください。

関連する仕様を確認する

Atlassian デザインシステム 形状とエレベーションで作業面の役割を示す

カードはオブジェクトなので、浮き上がって見える

このリファレンスでは、沈み込んだグループ化用の面、浮き上がったカード、オーバーレイ用の面を区別しています。移動可能な作業項目は概念上、浮き上がったレイヤーに属し、ボードの列はそれらの項目をまとめます。通常のページの一部であるインスペクターに、必ずしもオーバーレイのシャドウが必要とは限りません。エレベーションが重要な場合に、サーフェスとシャドウのロールを組み合わせてください。

現在の形状名には、2px の radius.xsmall、4px の radius.small、6px の radius.medium があります。これらは、別のシステムで開発者が見慣れているかもしれない旧式の border.radius という表記とは異なります。表では正確な名前を使用しています。ネイティブコントロールには提供されたスタイルを使用し、カスタムの外側コンテナーには、非公開の生成クラスを上書きせずに、該当するロールを適用できます。

関連する仕様を確認する

Atlassian デザインシステム ボタンの選択と課題の状態遷移は別のもの

外観と状態を意図的に選択する

確認済みの Button の import は @atlaskit/button/default/button です。appearance="primary" は主要なアクションを強調し、isSelected はこのコンパクトなネイティブ例で現在の課題を示します。クリックしても、インスペクターで確認中の課題が変わるだけです。ワークフローの状態を編集するには、別のコントロールを使います。こうすることで、行を選択しただけで作業が開始または完了してしまうのを防げます。

APIには、isLoading、isDisabled、spacing="compact"、shouldFitContainer も含まれます。読み込み中は処理の進行を表すものであり、課題の恒久的な状態ではありません。無効化されたコントロールはキーボード操作でスキップされる場合があるため、アクションを無効にする場合は理由を理解できるようにしてください。そのため、単独のボードでは確認用コントロールを常に利用できるようにし、ユーザーが現在のローカル状態を直接確認できるようにしています。

関連する仕様を確認する

Atlassian デザインシステム Lozenge と Toggle は異なる種類の状態を伝える

ステータスと操作モードは別のもの

Lozenge の外観には information、danger、success があり、サンプルではそれぞれ「進行中」「ブロック中」「完了」に対応付けています。意味を伝えるのは言葉であり、色は補助的な情報です。選択中になっても、ブロック中の項目はブロック中のままです。担当者フィルターには Toggle の isChecked と onChange を使用します。この真偽値はボードに表示する内容を変えるもので、課題の状態を変えるものではありません。

ローカルの状態セレクターは意図的にシンプルにしており、実際の権限モデルを示すものではありません。本番環境で課題の状態を遷移させる際は、理由、ロール、サービスからの応答が必要になる場合があります。認可のロジックは Lozenge の外部に置き、サービスで状態が確定してから、その結果を表示してください。

  • 選択状態は、現在インスペクターで確認している課題を示します。
  • ワークフローの状態は、作業項目自体の状態を表します。
  • 担当者フィルターは、所有者を変更せずに表示対象を絞り込みます。

関連する仕様を確認する

Atlassian デザインシステム カスタムトークンサーフェスを描画する前にテーマを初期化する

グローバルテーマの読み込みは非同期

setGlobalTheme はドキュメントのテーマ属性を更新し、選択したテーマCSSを読み込みます。エントリーポイントでは、その処理が完了してからボードを描画します。ライトテーマとダークテーマを明示的に選択し、初期状態ではライトモードを有効にしています。実際の設定コントロールでも、場当たり的なインラインカラーに置き換えるのではなく、同じAPIを使って colorMode を更新できます。

現在のカスタムブランド設定はアルファ版であり、UNSAFE APIを使用します。このガイドでは、例の色を変えるためだけに不安定な方法を採用しません。まず安定したセマンティックテーマの契約に従い、そのうえで実験的なカスタマイズを別個の依存関係に関する判断として検討してください。

関連する仕様を確認する

Atlassian デザインシステム 実際の課題確認の操作を検証する

提供されたファイルを組み合わせて使う

ネイティブの例には、JSX エントリー、CSSリセットの import、Parcel の設定ファイル 2 つが必要です。課題の一覧、選択、担当者フィルター、ステータスのマッピング、結果をリアルタイムで通知するメッセージが含まれています。単独のプレビューでは、列とインスペクターを加えて構成を広げていますが、あくまで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 のリセットのみをインポートしても、現行パッケージでは不十分です。このローカルプロトタイプで、ネイティブパッケージのコンパイルを行ったとは述べていません。

Parcel で配布済みの Compiled スタイルを処理する必要があります

プロジェクトのルートに .parcelrc を作成します。セットアップに記載された依存関係をインストールした後、HTML エントリを使って Parcel を起動します。

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

コードリファレンス

  • 実験的な Vite の手順を推奨セットアップとして扱うのではなく、ドキュメントに記載された Parcel 統合を選択します。

トークン変換用の Compiled 設定

.parcelrc と同じ場所に .compiledcssrc を作成します。これは利用側アプリケーションの設定であり、パッケージのリリーススクリプトではありません。

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

コードリファレンス

  • 省略可能な strip-runtime プラグインは、抽出済みの CSS を配布するパッケージ向けです。この利用側アプリケーションでは必要ありません。

ロゼンジは状態を示し、コントロールは状態を変更する

課題の詳細では、表示と状態遷移のコントロールにそれぞれ別の役割があります。

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

コードリファレンス

  • openIssueDetail はアプリケーションのハンドラーです。セットアップ全体では選択状態の扱いも示しています。
  • ステータスラベルは、実際に状態を切り替える操作を提供する場合を除き、メニューのように見せないでください。
04

Atlassian デザインシステム エージェントのセットアップ

実装の出発点

React のボードロジック全体と、以下の必須設定の断片を使用します。Compiled 統合には Parcel を使用してください。CSS のリセットのみをインポートしても、現行パッケージでは不十分です。このローカルプロトタイプで、ネイティブパッケージのコンパイルを行ったとは述べていません。

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

あなたのプロジェクト向けプロンプト

AI エージェント用プロンプト
提供されたReactの18件のAtlassian課題の例を、@atlaskit tokens、CSS reset、ドキュメントに記載されたCompiled Parcel統合を使って構築します。セマンティックトークンの呼び出し、フォントの省略記法による役割指定、検証済みの Button/Lozenge/Toggle のインポートを使用してください。選択状態、担当者フィルター、ワークフローの状態は独立して管理します。選択中の課題のコンテキストを維持し、ローカルでの変更をアナウンスしてください。Jiraとの接続や実際の権限があるとは述べないでください。
05

Atlassian デザインシステム 出典と対象範囲

公開されているOpenDesign Atlassian Design System Reactパッケージを調査し、2026年10月時点でリンク先のドキュメントと照合しています。埋め込みボードはHTML/CSSを参考にしたもので、パレットの値は説明用、課題は架空です。JiraやネイティブのAtlaskitランタイムではありません。公開パッケージにアクセスできることは、Atlassianのブランドを制限なく使用できることや、社内と同等のサポートを受けられることを意味しません。