行政・公共サービス · 新しいリソース

B.C. デザインシステム.

実際のセマンティックトークン、ネイティブのReact Ariaコントロール、条件に応じて表示される連絡先項目、完全なバリデーション動作を備えた、B.C.風のリマインダー設定フォームを作成します。

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

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

メールと電話を切り替えても入力内容を保持し、検証後にローカルの設定を確認できます。

連絡方法を選択して確認完全な例を開く
ネイティブの@bcgov/design-system-react-components 0.8.1、トークン5.0.0、BC Sans 2.1.2。· 実装リファレンス
02

B.C. デザインシステムデザインリファレンス

ネイティブの@bcgov/design-system-react-components 0.8.1、トークン5.0.0、BC Sans 2.1.2。

界面表面とテキストの役割

ソース
名前 / ルール値 / 設定用途
--surface-color-primary-button-default#013366 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--surface-color-primary-button-hover#1e5189 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--surface-color-primary-button-disabled#edebe9 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--surface-color-background-white#ffffff 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--surface-color-background-light-gray#faf9f8 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--surface-color-background-light-blue#f1f8fe 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--surface-color-border-default#d8d8d8 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--surface-color-border-medium#898785 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--surface-color-border-active#2e5dd7 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-color-primary#2d2d2d 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-color-secondary#474543 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-color-link#255a90 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-color-danger#ce3e39 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-color-primary-invert#ffffff 公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。

レイアウトのリズム

ソース
名前 / ルール値 / 設定用途
--layout-padding-hair0.125rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-padding-xsmall0.25rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-padding-small0.5rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-padding-medium1rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-padding-large1.5rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-padding-xlarge2rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-margin-medium1rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-margin-large1.5rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-margin-xlarge2rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-margin-xxxlarge3rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-border-radius-small2px公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-border-radius-medium4px公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--layout-border-radius-large6px公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。

文字のサイズ階層

ソース
名前 / ルール値 / 設定用途
--typography-font-size-small-body0.875rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-font-size-body1rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-font-size-large-body1.125rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-font-size-h51.25rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-font-size-h41.5rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-font-size-h31.75rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-font-size-h22rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-font-size-h12.25rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
--typography-font-size-display3rem公開されているB.C.の役割です。値を生の色や寸法に置き換えず、用途に応じて使用してください。
03

B.C. デザインシステム完全ガイド

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

DESIGN-british-columbia.md

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

ガイドをダウンロード

B.C. デザインシステムの現在のReactライブラリとトークン

メンテナンスされている実装を選ぶ

現在のB.C. Design Systemは、React Ariaを基盤とするReactコンポーネントを提供します。この例では、react-components 0.8.1と、その依存関係であるdesign-tokens 5.0.0をバージョン固定しています。旧B.C. Web Componentsリポジトリは、別のレガシー実装です。これをインポートしても、現在のReactライブラリと同じものにはなりません。例をコピーする前に、ドキュメントと実装が一致していることを確認してください。

この OpenDesign ガイドから

実際のフォントフェイスをインポートする

コンポーネントが想定するフォントファミリー名は、スペースを含むBC Sansです。バージョン2.1.2ではcss/BC_Sans.cssが提供されています。旧形式のBCSans.cssは非推奨とされており、異なるフォントファミリー名が宣言されています。開発者のマシンにBC Sansがインストールされていると、フォントのインポート漏れに気づかないことがあります。この実例には公開済みフォントが含まれているため、ローカルへのインストールに依存せずに表示できます。

B.C. デザインシステム セマンティックカラーとスペーシングの役割

値を選ぶ前に役割を確認する

プライマリボタンにはダークブルーの塗り色を使い、補足コンテンツには typography-color-secondary を使います。エラーメッセージには typography-color-danger を使います。この表には現在の CSS のエクスポート名を記載しています。将来テーマによって値が変わっても、名前が安定した用途を示します。非アクティブなコントロールの色を、通常の補足テキストと混同しないでください。

意図をもってレイアウトを設計する

フォームではフィールド間に 24px の間隔を設け、メインタスクと補足説明の間にはより広い 48px の余白を取っています。これらの値はライブラリのリズムに対応していますが、2 カラム全体の構成はこのサンプル用に作成したものです。モバイルレイアウトではカラムを 1 列にし、フォームラベルを縮小したり、説明テキストをツールチップにしたりしません。

B.C. デザインシステム 条件付きフィールドと入力値の保持

選択した連絡方法だけを検証する

ネイティブの RadioGroup で、Email address または Phone number の TextField の表示を切り替えます。連絡方法を切り替えても、どちらの値も React の state に保持されますが、レビュー時の検証対象になるのは選択中のフィールドだけです。これにより、入力済みの情報を保ちながら、非表示のフィールドが現在のタスクを妨げることを防げます。

その場で役立つエラーを表示する

メールアドレスのフィールドでは基本的な形式を確認し、電話番号の例では 10 桁以上の数字を必須とします。これらはサンプル用のルールであり、国際的な連絡先を網羅的に検証するものではありません。レビューで無効と判定された場合は isInvalid を設定し、フィールドに固有の errorMessage を表示します。同意がない場合はメッセージを表示し、最初に無効となったコントロールにフォーカスを移します。

B.C. デザインシステム React Aria コンポーネントの契約

制御された値とドキュメントに記載されたハンドラーを使う

TextField には value と onChange を、RadioGroup には value と onChange を指定します。Checkbox では isSelected と onChange を使います。これらのハンドラーが受け取るのは、ドキュメントに記載された値であり、常に event.target から値を読み取らなければならないブラウザーイベントオブジェクトではありません。Button には type=submit を指定し、ネイティブフォームの submit イベントを使うことで、キーボードからの送信でも同じ検証処理を実行します。

レビュー結果を常に最新の状態に保つ

B.C. デザインシステム アクセシブルな名前とレスポンシブな構成

ラベル、説明、エラーを関連付ける

ネイティブコンポーネントは、ラベル、ヘルプテキスト、エラーメッセージに対する React Aria の関連付けを提供します。アプリケーション側では、意味のあるラベル、明確なグループの説明、理解しやすい検証メッセージを用意する必要があります。テストでは、表示されているラベルをクリックし、キーボードで操作してください。内部で視覚的に隠されている input は、表示上の操作対象ではありません。

補足情報をフォームと分けて配置する

隣接するコールアウトでは、ローカルでの操作手順を説明し、実装の補足情報をネイティブの details 開示要素に含めています。画面幅が狭い場合は、読み上げ順でフォームの後に配置されます。情報アイコンは装飾用です。意味は見出しで伝えます。コンポーネントを検討するうえで、公式の B.C. ロゴや政府サービスであることを示す表記は必要ありません。

B.C. デザインシステム完全なReact実装

検証済みのソースを再現する

Vite React プロジェクトを作成し、バージョンを固定したコンポーネント、トークン、フォントのパッケージをインストールします。提供された main.jsx と bc.css を、ルートのマウント要素とともに使用してください。バンドルには、ネイティブのラジオボタン、フィールド、チェックボックス、ボタンの動作に加え、ローカルでの検証と状態遷移がすべて含まれています。非公開の API や認証情報は必要ありません。

  1. バージョンを固定したパッケージをインストールし、css/BC_Sans.css を読み込みます。
  2. ルートのマウント要素を維持したまま、main.jsx と bc.css を保存します。
  3. 空のフォームを送信してから、表示されたフィールドを修正します。
  4. 連絡方法を切り替え、以前の入力値が保持されることを確認します。

条件付き検証を選択中の連絡方法に合わせる

RadioGroup と TextField の onChange ハンドラーは値を受け取り、Checkbox の onChange ハンドラーは選択状態を示すブール値を受け取ります。すべてのコンポーネントに汎用的な event.target.value ハンドラーを適用するのではなく、受け取った値をそのまま保存してください。React Aria によってネイティブの input が視覚的に隠されていても、表示されているラベルが操作対象になります。

連絡方法を変更したときは、両方の入力途中の値を保持しつつ、以前のレビュー結果を消去して、選択中の方法だけを検証します。送信後は、最初に無効となった表示中のコントロールにフォーカスを移します。これにより、メールアドレスを失ったり、非表示の電話番号フィールドに妨げられたりすることなく、連絡方法を比較できます。このサンプルの 10 桁という電話番号のルールは、意図的にローカルなものです。実際のサービスで必要となる国際電話番号の要件に置き換えてください。

  • 検証されるのは、選択中の連絡先フィールドだけです。
  • 選択肢を変更すると、以前のレビュー結果が消去されます。
  • リマインダーを設定したとは表示しません。

B.C. デザインシステムのコンポーネント例

main.jsx — 動作するサンプル一式

連絡方法を選び、内容を確認します。以下のソースは React の完全なエントリで、すべての状態管理と検証を含みます。

jsx
import React, { useState, useRef } from "react";
import { createRoot } from "react-dom/client";
import {
  Button,
  Radio,
  RadioGroup,
  TextField,
  Checkbox,
} from "@bcgov/design-system-react-components";
import "@bcgov/bc-sans/css/BC_Sans.css";
import "./bc.css";
function App() {
  const [method, setMethod] = useState("email"),
    [email, setEmail] = useState(""),
    [phone, setPhone] = useState(""),
    [consent, setConsent] = useState(false),
    [submitted, setSubmitted] = useState(false),
    [result, setResult] = useState("");
  const panel = useRef(null);
  const invalidEmail = !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email),
    invalidPhone = phone.replace(/\D/g, "").length < 10;
  function change(fn, value) {
    fn(value);
    setResult("");
    setSubmitted(false);
  }
  function review(e) {
    e.preventDefault();
    setSubmitted(true);
    if ((method === "email" ? invalidEmail : invalidPhone) || !consent) {
      requestAnimationFrame(() =>
        panel.current
          .querySelector(
            '[aria-invalid="true"] input,input[aria-invalid="true"],input[type=checkbox]:not(:checked)',
          )
          ?.focus(),
      );
      return;
    }
    setResult(
      `Local preference ready: ${method === "email" ? "Email to " + email : "Phone call to " + phone}. No reminder has been scheduled.`,
    );
  }
  return (
    <main>
      <header>
        <div className="eyebrow">
          SERVICE REMINDER / ORIGINAL APPLICATION STUDY
        </div>
        <h1>Choose how to hear from us</h1>
        <p>
          Set a sample reminder preference. Use fictional contact details in
          this local example.
        </p>
      </header>
      <div className="columns">
        <form onSubmit={review} noValidate ref={panel}>
          <RadioGroup
            label="Contact method"
            value={method}
            onChange={(v) => change(setMethod, v)}
            description="Choose one way to receive a reminder."
          >
            <Radio value="email">Email</Radio>
            <Radio value="phone">Phone call</Radio>
          </RadioGroup>
          <div className="field">
            {method === "email" ? (
              <TextField
                label="Email address"
                type="email"
                value={email}
                onChange={(v) => change(setEmail, v)}
                isRequired
                isInvalid={submitted && invalidEmail}
                errorMessage="Enter an email address in the format [email protected]."
                description="Use a sample address, such as [email protected]."
              />
            ) : (
              <TextField
                label="Phone number"
                type="tel"
                value={phone}
                onChange={(v) => change(setPhone, v)}
                isRequired
                isInvalid={submitted && invalidPhone}
                errorMessage="Enter a phone number with at least 10 digits."
                description="Sample validation only; a real service needs a jurisdiction-aware phone rule."
              />
            )}
          </div>
          <div className="field">
            <Checkbox
              isSelected={consent}
              onChange={(v) => change(setConsent, v)}
              isInvalid={submitted && !consent}
            >
              I agree to use these details for this sample reminder
            </Checkbox>
            {submitted && !consent && (
              <p className="error" role="alert">
                Confirm the reminder preference before continuing.
              </p>
            )}
          </div>
          <Button type="submit" variant="primary">
            Review preference
          </Button>
          <p className="result" role="status">
            {result}
          </p>
        </form>
        <aside>
          <div className="status-mark" aria-hidden="true">
            i
          </div>
          <h2>What happens next</h2>
          <ol>
            <li>Choose a contact method.</li>
            <li>Review the sample details.</li>
            <li>Connect a real notification service before scheduling.</li>
          </ol>
          <p>
            This example keeps both fields while switching methods, but only
            reviews the selected method.
          </p>
          <details>
            <summary>About this specimen</summary>
            <p>
              Native B.C. React Aria components with BC Sans. The form is
              original and is not an official government service.
            </p>
          </details>
        </aside>
      </div>
    </main>
  );
}
createRoot(document.getElementById("root")).render(<App />);

コードリファレンス

  • Vite React プロジェクトを作成し、<div id="root"></div> を残したまま、これを src/main.jsx として読み込みます。

bc.css — オリジナルのレスポンシブ構成

ネイティブコンポーネントを基にしたアプリケーションレイアウト。

CSS
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  font:
    16px/1.5 "BC Sans",
    sans-serif;
  color: var(--typography-color-primary, #2d2d2d);
  background: white;
}
main {
  padding: 32px;
}
header {
  border-top: 6px solid #fcba19;
  border-bottom: 1px solid #d8d8d8;
  padding: 24px 0;
  margin-bottom: 32px;
}
.eyebrow {
  font-size: 13px;
  color: #474543;
}
h1 {
  font-size: 32px;
  line-height: 1.25;
  margin: 8px 0 16px;
}
h2 {
  font-size: 24px;
  margin: 0 0 16px;
}
p {
  margin: 8px 0 16px;
}
.columns {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 48px;
}
form {
  max-width: 620px;
}
.field {
  margin: 24px 0;
}
aside {
  padding: 24px;
  background: #f1f8fe;
  border-left: 4px solid #1a5a96;
  align-self: start;
}
.status-mark {
  background: #1a5a96;
  color: white;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  font-weight: bold;
  margin-bottom: 16px;
}
ol {
  padding-left: 24px;
}
li {
  padding-left: 4px;
  margin: 12px 0;
}
.error {
  color: #ce3e39;
  font-size: 14px;
}
.result {
  margin-top: 24px;
  color: #24613b;
}
summary {
  cursor: pointer;
  text-decoration: underline;
  color: #1a5a96;
}
details {
  margin-top: 24px;
}
details p {
  font-size: 14px;
}
@media (max-width: 767px) {
  main {
    padding: 16px;
  }
  .columns {
    grid-template-columns: 1fr;
    gap: 24px;
  }
  h1 {
    font-size: 28px;
  }
  aside {
    padding: 16px;
  }
}

コードリファレンス

  • main.jsx と同じ場所に保存します。ライブラリのトークンリファレンスとは異なる、カスタムの構成ルールです。
04

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

実装の出発点

バージョンを固定したネイティブのサンプルをバンドルし、ローカルのブラウザーで動作を確認しました。このサンプルでは、アプリケーションのローカルな状態だけを使用します。

シェル
npm create vite@latest bc-reminder -- --template react
cd bc-reminder
npm install
npm install @bcgov/[email protected] @bcgov/[email protected] @bcgov/[email protected]
# Replace src/main.jsx and add src/bc.css using the complete examples.
npm run dev

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

AI エージェント用プロンプト
B.C. React のコンポーネント 0.8.1 と BC Sans 2.1.2 を使って、リマインダーフォームを作成します。条件付き検証、入力値の保持、表示されるエラー、古い結果の消去を維持してください。最新のトークン名と、正しくスペースを入れたフォントファミリーを使います。実際の通知契約が整うまでは、この例をローカルにとどめてください。
05

B.C. デザインシステム 出典と対象範囲

現在公開されている B.C. React ライブラリを使った OpenDesign アプリケーションの検討例です。これは独自に作成したローカルフォームであり、公式の行政サービスではありません。架空の連絡先情報を使用してください。