開発者ツール · 新しいリソース

GitLab Pajamas デザインシステム.

技術ワークフロー向けの Pajamas ガイド。実際のセマンティックトークン、可変のタイポグラフィと間隔、段階的なパイプラインインスペクター、読みやすいエラー出力、そしてローカル限定のリトライシミュレーションを紹介します。

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

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

状態でジョブを絞り込み、ジョブを選択して出力を確認します。失敗したリンクチェックが成功するケースをシミュレートし、元のフィクスチャにリセットできます。

パイプラインの失敗を調べ、復旧をシミュレート完全な例を開く
ネイティブの @gitlab/ui 138.0.0 CSS、元のステージ配置、HTML、ローカルの状態ロジックを使用。実際のCI処理は行いません。· 実装リファレンス
02

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

@gitlab/ui 138.0.0 が公開しているライトテーマのトークンエクスポートとネイティブの CSS。GL_* 名は JavaScript のエクスポートで、コンパイル済みの CSS では小文字の --gl-* 形式に対応します。この例では、元の HTML と状態ロジックを組み合わせたネイティブのスタイルシートを使用しており、Vue コンポーネントはマウントしていません。

セマンティックなサーフェス、テキスト、境界線

ソース
名前 / ルール値 / 設定用途
GL_BACKGROUND_COLOR_DEFAULT#fffトークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_BACKGROUND_COLOR_SUBTLE#f7f7f5 トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_BACKGROUND_COLOR_STRONG#ecebea トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_TEXT_COLOR_DEFAULT#3a383d トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_TEXT_COLOR_SUBTLE#646163 トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_TEXT_COLOR_STRONG#18171d トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_TEXT_COLOR_HEADING#18171d トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_TEXT_COLOR_LINK#27599f トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_BORDER_COLOR_DEFAULT#dcdbd9 トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_BORDER_COLOR_SUBTLE#ecebea トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。
GL_BORDER_COLOR_STRONG#c1bfbe トークン名が示す役割に沿って使います。これはライトテーマのリファレンスエクスポートです。

インターフェースの間隔

ソース
名前 / ルール値 / 設定用途
GL_SPACING_SCALE_00px間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。
GL_SPACING_SCALE_10.125rem間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。
GL_SPACING_SCALE_20.25rem間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。
GL_SPACING_SCALE_30.5rem間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。
GL_SPACING_SCALE_40.75rem間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。
GL_SPACING_SCALE_51rem間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。
GL_SPACING_SCALE_61.5rem間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。
GL_SPACING_SCALE_72rem間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。
GL_SPACING_SCALE_82.5rem間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。
GL_SPACING_SCALE_93rem間隔スケールの値は、インデックスに一定の数値を掛けたものではありません。

レスポンシブな文字サイズスケール

ソース
名前 / ルール値 / 設定用途
GL_FONT_SIZE_1000.75rem大きな役割には clamp を使用します。可変フォントサイズを意図している場合は、式をそのまま維持してください。
GL_FONT_SIZE_2000.8125rem大きな役割には clamp を使用します。可変フォントサイズを意図している場合は、式をそのまま維持してください。
GL_FONT_SIZE_3000.875rem大きな役割には clamp を使用します。可変フォントサイズを意図している場合は、式をそのまま維持してください。
GL_FONT_SIZE_4001rem大きな役割には clamp を使用します。可変フォントサイズを意図している場合は、式をそのまま維持してください。
GL_FONT_SIZE_500clamp(1.125rem, 0.9027777778rem + 0.462962963vw, 1.25rem)大きな役割には clamp を使用します。可変フォントサイズを意図している場合は、式をそのまま維持してください。
GL_FONT_SIZE_600clamp(1.3125rem, 0.8680555556rem + 0.9259259259vw, 1.5625rem)大きな役割には clamp を使用します。可変フォントサイズを意図している場合は、式をそのまま維持してください。
GL_FONT_SIZE_700clamp(1.5rem, 0.8333333333rem + 1.3888888889vw, 1.875rem)大きな役割には clamp を使用します。可変フォントサイズを意図している場合は、式をそのまま維持してください。
GL_FONT_SIZE_800clamp(1.75rem, 0.8611111111rem + 1.8518518519vw, 2.25rem)大きな役割には clamp を使用します。可変フォントサイズを意図している場合は、式をそのまま維持してください。

コントロールとサーフェスの角丸

ソース
名前 / ルール値 / 設定用途
GL_BORDER_RADIUS_NONE0px角丸はコンポーネントの形状を表すもので、アクションの重要度を示すものではありません。
GL_BORDER_RADIUS_XS1px角丸はコンポーネントの形状を表すもので、アクションの重要度を示すものではありません。
GL_BORDER_RADIUS_SM0.125rem角丸はコンポーネントの形状を表すもので、アクションの重要度を示すものではありません。
GL_BORDER_RADIUS_MD0.25rem角丸はコンポーネントの形状を表すもので、アクションの重要度を示すものではありません。
GL_BORDER_RADIUS_LG0.5rem角丸はコンポーネントの形状を表すもので、アクションの重要度を示すものではありません。
GL_BORDER_RADIUS_XL0.75rem角丸はコンポーネントの形状を表すもので、アクションの重要度を示すものではありません。
GL_BORDER_RADIUS_FULL9999px角丸はコンポーネントの形状を表すもので、アクションの重要度を示すものではありません。
GL_BORDER_RADIUS_DEFAULT0.25rem角丸はコンポーネントの形状を表すもので、アクションの重要度を示すものではありません。

ステータスカラーのリファレンス

ソース
名前 / ルール値 / 設定用途
GL_COLOR_GREEN_50#e6f5ea 成功状態に使う控えめなサーフェス。
GL_COLOR_GREEN_800#075048 ライトテーマのサーフェス上に表示する成功状態の前景色。
GL_COLOR_RED_50#feeef0 失敗状態に使う控えめなサーフェス。
GL_COLOR_RED_800#891c2f ライトテーマのサーフェス上に表示する失敗状態の前景色。
GL_COLOR_BLUE_50#e8f2fd 選択中のジョブのサーフェス。
GL_COLOR_BLUE_700#27599f 選択状態の境界線と、視認可能なフォーカスのリファレンス。
03

GitLab Pajamas デザインシステム完全ガイド

実際のインターフェースで、このデザインシステムを選び、適用し、レビューするための実践ガイドです。

DESIGN-gitlab-pajamas.md

詳しいガイダンス、実装の出発点、ソースへのリンクをまとめています。

ガイドをダウンロード

GitLab Pajamas デザインシステムのパイプライン情報アーキテクチャ

復旧方法より先に失敗の状況を伝える

ヘッダーには架空のパイプライン、ブランチ、コミットを記載し、ジョブインスペクターで状況を把握できるようにしています。Build、Test、Publish はそれぞれグループとして表示され、選択したジョブを開くと、その出力が表示されます。リンクチェックに失敗した場合は、再試行アクションを提示する前に、失敗の理由となるルートと終了条件を示します。

この OpenDesign ガイドから

簡潔なグラフを読みやすく保つ

このサンプルでは、完全な依存関係グラフを実装しているかのように見せるのではなく、ステージ列とボタンを使っています。画面が狭い場合は、ステージを文書の順序に沿って縦に並べます。本番用のパイプラインでは、並列ジョブ、依存関係、待機中、手動、キャンセル済みの状態が必要になる場合があります。これらは3つのサンプル見出しから推測させず、明示的にモデル化してください。

GitLab Pajamas デザインシステムのセマンティックカラーとステータス

作業領域にはセマンティックなUIロールを使う

ライトテーマのエクスポートには、暖かみのあるニュートラルなサーフェス、明確に区別されたテキストの強弱、控えめな境界線が用意されています。このサンプルでは、ジョブカードにデフォルトのサーフェス、選択中の状態に青いサーフェス、ログ領域に暗いサーフェスを使っています。ガイドにはパッケージの正確な値が記載されているため、スクリーンショットからピクセルを抽出しなくても、ユーザーは各要素の関係を再現できます。

状態ラベルで意味を伝える

各ジョブの行とバッジには「Passed」または「Failed」と表示しています。チェックマークやバツ印はテキストを補足するもので、色付きバッジだけでは状態が曖昧になるためです。ブランドカラーの紫は、汎用的な成功表示には使いません。表内のステータス表示は、選択状態を示す青とは意図的に分けています。

GitLab Pajamas デザインシステムの文字サイズと技術情報向けテキスト

該当する箇所では、可変幅の式をそのまま維持する

パッケージには、小サイズ向けの固定ロールと、clampベースの大サイズ向けロールが用意されています。clampを最大値に置き換えると、レスポンシブ時の挙動が変わります。元のサンプルでは、アプリケーションのタイトルに24px、補助テキストに12~14pxを使用しています。これらはパッケージのトークンを追加したものではなく、レイアウト上の選択として示しています。

識別子と出力には等幅フォントを使う

ブランチ名とコミット名にはコード用のスタイルを適用し、ジョブ名は読みやすいインターフェーステキストとして表示します。出力は、キーボードでフォーカスできる折り返し対応の等幅フォントブロックに表示します。長いパスも折り返されるため、ページ全体がスマートフォンの画面幅を超えて広がりません。選択を変更するとテキストが置き換わり、HTMLがそのまま挿入されることはありません。

GitLab Pajamas デザインシステムのスペーシングと境界のリズム

トークンの値を番号から計算しない

GL_SPACING_SCALE_3は0.5rem、scale_5は1remです。インデックスはキーであり、単純な乗数ではありません。実装では、エクスポートされた値を使用してください。参照表には、0ピクセルのステップも含め、正確な単位を記載しています。

境界線で領域を明確にする

GitLab Pajamas デザインシステムにおけるジョブの選択とフィルタリング

選択中のジョブを、フィルター内の位置とは切り離して管理する

スクリプトでは、linksやaccessibilityなど、変わらない文字列IDを使用します。フィルターを変更すると表示するジョブが切り替わり、該当するジョブがあればそれを選択します。ジョブをクリックすると、押下状態、ステージ、ステータスバッジ、ログがまとめて更新されます。これにより、あるジョブのタイトルと別のジョブの出力が組み合わさって表示されることを防ぎます。

結果が一覧から消えても、確認に必要な情報を残す

失敗したジョブを成功した状態にシミュレートすると、「Failed jobs」フィルターには結果が表示されなくなります。空の状態を示すメッセージで一覧を戻す方法を案内し、インスペクターには直前に完了した結果を残します。一覧から行が消えた理由をユーザーが把握できるようにし、完了の確認まで失われないようにするための意図的な設計です。

GitLab Pajamas デザインシステムにおける再試行とリセットの動作

シミュレーションであることを明確に伝える

アクション名は「成功する再試行をシミュレート」とし、ローカルのテストデータだけを変更して、ログをシミュレーション結果のテキストに置き換えます。ランナーへのジョブ登録、ジョブの作成、リポジトリの検査は行いません。パイプライン全体のバッジは、クリック後に一律で成功へ切り替えるのではなく、すべてのジョブの状態から再計算します。

初期状態のデータ一式を復元する

リセットすると、初期状態のジョブデータを新たに作成し、失敗したlinkジョブを選択して、「All jobs」に戻し、両方のパネルを再描画します。再読み込みせずにシミュレーション結果を消去できます。これにより、サンプルを繰り返し利用でき、次に見る人が以前のシミュレーションによる成功状態を初期状態と誤認するのを防ぎます。

  1. 「Failed jobs」を選択し、失敗したルートを確認します。
  2. 成功をシミュレートし、結果が残ったインスペクターと、フィルター適用後の空の一覧を確認します。
  3. サンプルをリセットし、失敗状態と元の出力が復元されることを確認します。

GitLab Pajamas デザインシステムのアクセシブルなジョブ操作

ローカルでの選択操作にはボタンを使う

各ジョブはaria-pressedを持つ実際のボタンです。状態は所要時間の横にテキストで表示し、キーボードフォーカスの可視表示は選択状態の見た目と分けています。フィルターには視認できるラベルがあります。これらはシンプルな操作のため、キーボード専用の独自グラフナビゲーションには対応していません。

閲覧位置を移動させずに結果を伝える

再試行またはリセットの後、結果をステータス領域に表示します。ログは選択可能なテキストで、読み上げるためにキーボードでフォーカスできますが、選択のたびにアプリケーションが自動でログへフォーカスを移すことはありません。これにより、ジョブ間の比較を繰り返す際も操作が予測しやすくなります。

GitLab Pajamas デザインシステムとCSS、Vueの統合境界

統合レベルを明確に選ぶ

このソースは公開済みのCSS配布パッケージをインポートし、独自のHTML/JavaScriptの動作を実装しています。GlButton、GlFormSelectなどのVueエクスポートは使用しません。Vueアプリケーションでは、このDOM実装をVueの例として扱うのではなく、対応するネイティブコンポーネントとその現在のprops/eventsを使用してください。

  • CSS配布パッケージ:ネイティブの外観とセマンティック変数。
  • オリジナルのHTML:アクセシブルな操作要素と領域構造。
  • オリジナルのJavaScript:テストデータ、選択、フィルター、シミュレーション。

トークンをインポートしたリリースに対応させる

GitLab Pajamas デザインシステムのコンポーネント例

index.html — パイプラインのワークスペース

セマンティックなレイアウトと操作要素一式。

html
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Pipeline specimen</title>
<body>
<main class="pipeline-example">
  <header>
    <p class="eyebrow">sample-team / documentation</p>
    <div class="title-row">
      <div>
        <h1>Pipeline #1842</h1>
        <p>
          Preview build for <code>docs/update-navigation</code> ·
          <code>7c31a82</code>
        </p>
      </div>
      <span id="pipeline-state" class="state failed">Failed</span>
    </div>
  </header>
  <div class="toolbar">
    <label for="job-filter">Show jobs</label
    ><select id="job-filter" class="gl-form-select">
      <option value="all">All jobs</option>
      <option value="failed">Failed jobs</option>
      <option value="passed">Passed jobs</option></select
    ><button id="reset" class="btn btn-default gl-button">
      Reset specimen
    </button>
  </div>
  <div class="pipeline-layout">
    <section aria-label="Pipeline stages">
      <div id="stages" class="stages"></div>
      <p id="empty" hidden>
        No jobs match this filter. Choose All jobs to restore the pipeline.
      </p>
    </section>
    <section class="job-detail" aria-labelledby="job-title">
      <div class="detail-heading">
        <h2 id="job-title"></h2>
        <span id="job-state" class="state"></span>
      </div>
      <dl>
        <dt>Stage</dt>
        <dd id="job-stage"></dd>
        <dt>Runner</dt>
        <dd>local-example-runner</dd>
        <dt>Execution</dt>
        <dd>Simulated in this page</dd>
      </dl>
      <h3>Job output</h3>
      <pre id="job-log" tabindex="0" aria-label="Selected job output"></pre>
      <button id="retry" class="btn btn-confirm gl-button">
        Simulate successful retry
      </button>
      <p id="feedback" role="status"></p>
    </section>
  </div>
  <footer>
    Native @gitlab/ui 138.0.0 CSS with original HTML and state logic. Fictional
    pipeline; no runner, repository or CI job is started.
  </footer>
</main>

<script type="module" src="/src/main.js"></script>
</body></html>

コードリファレンス

  • Viteプロジェクトのルートに保存します。

main.js — テストデータと復旧ロジック

ネイティブのCSSインポートと、ステージ別ジョブの動作一式。

js
import "@gitlab/ui/dist/index.css";
import "./pajamas.css";
const initial = [
  {
    id: "lint",
    stage: "Build",
    state: "passed",
    time: "12s",
    log: "$ npm run lint\nNo lint errors.\nJob succeeded.",
  },
  {
    id: "bundle",
    stage: "Build",
    state: "passed",
    time: "31s",
    log: "$ npm run build\nStatic assets generated.\nJob succeeded.",
  },
  {
    id: "links",
    stage: "Test",
    state: "failed",
    time: "18s",
    log: "$ npm run check:links\n/docs/old-navigation returned 404\n1 broken internal link.\nJob failed: exit code 1.",
  },
  {
    id: "accessibility",
    stage: "Test",
    state: "passed",
    time: "24s",
    log: "$ npm run check:a11y\nExample fixture checks passed.\nJob succeeded.",
  },
  {
    id: "preview",
    stage: "Publish",
    state: "passed",
    time: "9s",
    log: "$ npm run package:preview\nLocal preview archive generated.\nJob succeeded.",
  },
];
let jobs = structuredClone(initial),
  selected = "links";
const filter = document.querySelector("#job-filter"),
  stages = document.querySelector("#stages"),
  retry = document.querySelector("#retry"),
  feedback = document.querySelector("#feedback");
function render() {
  stages.replaceChildren();
  let count = 0;
  for (const name of ["Build", "Test", "Publish"]) {
    const matches = jobs.filter(
      (j) =>
        j.stage === name &&
        (filter.value === "all" || j.state === filter.value),
    );
    if (!matches.length) continue;
    const section = document.createElement("div");
    section.className = "stage";
    const h = document.createElement("h2");
    h.textContent = name;
    section.append(h);
    for (const j of matches) {
      count++;
      const b = document.createElement("button");
      b.type = "button";
      b.className = "job";
      b.setAttribute("aria-pressed", String(j.id === selected));
      const strong = document.createElement("strong"),
        small = document.createElement("small");
      strong.textContent = j.id;
      small.textContent =
        (j.state === "passed" ? "✓ Passed" : "× Failed") + " · " + j.time;
      b.append(strong, small);
      b.onclick = () => {
        selected = j.id;
        feedback.textContent = "";
        render();
      };
      section.append(b);
    }
    stages.append(section);
  }
  document.querySelector("#empty").hidden = count !== 0;
  const j = jobs.find((j) => j.id === selected);
  document.querySelector("#job-title").textContent = j.id;
  document.querySelector("#job-stage").textContent = j.stage;
  document.querySelector("#job-log").textContent = j.log;
  const state = document.querySelector("#job-state");
  state.className = "state " + j.state;
  state.textContent = j.state === "passed" ? "Passed" : "Failed";
  retry.hidden = j.state !== "failed";
  const failed = jobs.some((j) => j.state === "failed"),
    overall = document.querySelector("#pipeline-state");
  overall.textContent = failed ? "Failed" : "Passed";
  overall.className = "state " + (failed ? "failed" : "passed");
}
filter.onchange = () => {
  const match = jobs.find(
    (j) => filter.value === "all" || j.state === filter.value,
  );
  if (match) selected = match.id;
  feedback.textContent = "";
  render();
};
retry.onclick = () => {
  const j = jobs.find((j) => j.id === selected);
  j.state = "passed";
  j.time = "15s";
  j.log =
    "$ npm run check:links\nSimulation: updated route found.\nNo broken internal links.\nJob succeeded (local simulation).";
  render();
  feedback.textContent =
    "Simulated retry completed locally. No CI job was started.";
};
document.querySelector("#reset").onclick = () => {
  jobs = structuredClone(initial);
  selected = "links";
  filter.value = "all";
  feedback.textContent = "Specimen restored.";
  render();
};
render();

コードリファレンス

  • src/main.jsとして保存します。CIへのリクエストはありません。

pajamas.css — オリジナルの構成

レスポンシブなステージ、選択カード、メタデータ、折り返し対応のログ出力。

CSS
[hidden] {
  display: none !important;
}
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  font-family: Arial, sans-serif;
  font-size: 14px;
  color: var(--gl-text-color-default, #3a383d);
  background: var(--gl-background-color-default, #fff);
}
.pipeline-example {
  padding: 28px;
}
.pipeline-example header {
  padding-bottom: 20px;
  border-bottom: 1px solid var(--gl-border-color-default);
}
.eyebrow {
  font-size: 12px;
  color: var(--gl-text-color-subtle);
  margin-bottom: 16px;
}
.title-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: flex-start;
}
h1 {
  font-size: 24px;
  font-weight: 600;
  margin: 0 0 8px;
}
h2 {
  font-size: 18px;
  font-weight: 600;
  margin: 0;
}
h3 {
  font-size: 14px;
  font-weight: 600;
}
.title-row p {
  margin: 0;
  color: var(--gl-text-color-subtle);
}
code {
  font: 12px monospace;
  background: #f7f7f5;
  color: #3a383d;
  padding: 2px 4px;
  overflow-wrap: anywhere;
}
.toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 20px 0;
}
.toolbar label {
  margin: 0;
  font-weight: 600;
}
.toolbar select {
  max-width: 180px;
}
.toolbar button {
  margin-left: auto;
}
.pipeline-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(300px, 1fr);
  gap: 24px;
}
.stages {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.stage h2 {
  font-size: 13px;
  margin-bottom: 12px;
  color: var(--gl-text-color-subtle);
}
.job {
  display: block;
  width: 100%;
  text-align: left;
  background: #fff;
  border: 1px solid var(--gl-border-color-default);
  border-radius: 4px;
  padding: 12px;
  margin-bottom: 8px;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.job[aria-pressed="true"] {
  border-color: #27599f;
  box-shadow: inset 0 0 0 1px #27599f;
  background: #e8f2fd;
}
.job strong {
  display: block;
  font-size: 13px;
  overflow-wrap: anywhere;
}
.job small {
  display: block;
  margin-top: 6px;
  color: var(--gl-text-color-subtle);
}
.job-detail {
  border: 1px solid var(--gl-border-color-default);
  border-radius: 4px;
  padding: 20px;
  min-width: 0;
}
.detail-heading {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: center;
}
.state {
  font-size: 12px;
  font-weight: 600;
  border-radius: 9999px;
  padding: 3px 9px;
  white-space: nowrap;
}
.state.failed {
  background: #feeef0;
  color: #891c2f;
}
.state.passed {
  background: #e6f5ea;
  color: #075048;
}
dl {
  display: grid;
  grid-template-columns: 90px minmax(0, 1fr);
  gap: 8px;
  margin: 20px 0;
  font-size: 12px;
}
dt {
  color: var(--gl-text-color-subtle);
  font-weight: 400;
}
dd {
  margin: 0;
  overflow-wrap: anywhere;
}
pre {
  background: #18171d;
  color: #ecebea;
  padding: 16px;
  border-radius: 4px;
  font: 12px/1.7 monospace;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  min-height: 160px;
  margin-bottom: 16px;
}
#feedback {
  font-size: 12px;
  margin: 12px 0 0;
}
footer {
  margin-top: 28px;
  padding-top: 16px;
  border-top: 1px solid var(--gl-border-color-subtle);
  font-size: 12px;
  color: var(--gl-text-color-subtle);
}
button:focus-visible,
select:focus-visible,
pre:focus-visible {
  outline: 2px solid #27599f;
  outline-offset: 3px;
}
@media (max-width: 1050px) {
  .pipeline-layout {
    grid-template-columns: 1fr;
  }
  .stages {
    gap: 16px;
  }
}
@media (max-width: 550px) {
  .pipeline-example {
    padding: 16px;
  }
  .toolbar {
    flex-wrap: wrap;
  }
  .toolbar button {
    margin-left: 0;
  }
  .stages {
    grid-template-columns: 1fr;
  }
  .stage {
    border-bottom: 1px solid var(--gl-border-color-subtle);
    padding-bottom: 8px;
  }
  .title-row {
    flex-wrap: wrap;
  }
  .job-detail {
    padding: 16px;
  }
}

コードリファレンス

  • src/pajamas.cssとして保存します。システムフォントのフォールバックを明示しており、GitLabブランドのフォントは同梱していません。
04

GitLab Pajamas デザインシステムのエージェント設定

実装の出発点

この統合でインポートするのは、ネイティブのCSS配布パッケージのみです。Vueコンポーネントを採用する場合は、GitLab UIのpeer依存関係の要件を別途確認してください。

シェル
npm create vite@latest pajamas-pipeline -- --template vanilla
cd pajamas-pipeline
npm install
npm install @gitlab/[email protected]
# Replace index.html; add src/main.js and src/pajamas.css from the complete examples.
npm run dev

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

AI エージェント用プロンプト
Pajamas のセマンティックな背景面、実際の余白・文字スタイルの参照、安定したジョブ ID、アクセシブルな選択機能を備えた、技術者向けのジョブインスペクターを構築します。フィクスチャの全ソースを使用し、失敗の状況を画面に表示したままにして、フィルター適用後に項目がない場合も分かりやすくし、すべてのローカルシミュレーションにラベルを付けます。CSSやリトライ例によって GitLab CI ジョブが作成されるような誤解を招かないでください。
05

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

OpenDesignによるGitLab Pajamasおよび@gitlab/ui 138.0.0のアプリケーションガイド。ネイティブパッケージCSSで、この独自のHTML/JavaScriptサンプルをスタイリングしています。パイプラインは架空のものであり、GitLabのAPI、Vueランタイム、CIランナー、リポジトリアクションはいずれも実行されません。