# Nord デザインシステム

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

5種類の会議室定員から選び、タイトルを検証して、ローカルでリクエストの概要を作成します。

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

Nordのトークン9.0.4と、現行のコンポーネントドキュメントを参照しています。以下の値はデフォルトのTherapyテーマを示すもので、Nordhealthのすべてのブランドに当てはまるわけではありません。公開ドキュメントを参照できることは、Nordを本来のNordhealthの用途以外で使用する許可を意味しません。

### Therapyの役割別の値

| 名前 / ルール | 値 / 設定 | 用途 |
| --- | --- | --- |
| --n-color-accent | #3559c7 | 主なアクション。 |
| --n-color-text | #0c1a3d | メインコンテンツ。 |
| --n-color-text-weak | #36434a | 補助テキスト。 |
| --n-color-background | #fafbfb | ページ。 |
| --n-color-surface | #ffffff | パネル。 |
| --n-color-border | #d8dee4 | 区切り線。 |
| --n-color-border-strong | #bcc5cc | コントロールの境界線。 |
| --n-color-text-error | #d24023 | エラーメッセージ。 |
### スペーシング

| 名前 / ルール | 値 / 設定 | 用途 |
| --- | --- | --- |
| --n-space-xs | 4px | 狭い間隔。 |
| --n-space-s | 8px | 関連要素。 |
| --n-space-m | 16px | グループ。 |
| --n-space-l | 24px | セクション。 |
| --n-space-xl | 36px | 大。 |
| --n-space-xxl | 72px | 特大。 |
### 文字と形状

| 名前 / ルール | 値 / 設定 | 用途 |
| --- | --- | --- |
| --n-font-size-m | 0.875rem | 本文。 |
| --n-font-size-l | 1rem | 大きなテキスト。 |
| --n-font-size-xl | 1.25rem | セクションタイトル。 |
| --n-font-size-xxl | 1.5rem | タイトル。 |
| --n-line-height | 1.5 | 本文の倍率。 |
| --n-line-height-form | 20px | コントロールの行の高さ。 |
| --n-font-weight-heading | 600 | 見出し。 |
| --n-border-radius-s | 3px | コントロール。 |
| --n-border-radius | 5px | 背景面。 |
### 入力の仕様

| 名前 / ルール | 値 / 設定 | 用途 |
| --- | --- | --- |
| label / hint / error | Built-in field text | スタンドアロンの入力にはラベルを付ける。 |
| expand | Boolean, default false | 親要素の幅いっぱいに広げる。 |
| size | s / m / l | デフォルトは中。 |
| readonly versus disabled | Submitted versus excluded | 読み取り専用でもフォーカス可能にする。 |
| --n-input-inline-size | 240px | デフォルトでは幅が固定される。レスポンシブフォームではexpandを優先する。 |
### Selectの仕様

| 名前 / ルール | 値 / 設定 | 用途 |
| --- | --- | --- |
| Default slot | Native option elements | nord-optionを独自に作らない。 |
| value | String | 選択状態を制御する。 |
| required | Boolean | novalidateを使い、エラーはアプリケーション側で表示する。 |
| change | User selection event | component.valueを読み取る。 |
| focus() | Component method | 呼び出す前に定義の完了を待つ。 |
### ボタンの仕様

| 名前 / ルール | 値 / 設定 | 用途 |
| --- | --- | --- |
| type | submit by default | 送信以外の操作にはbuttonを指定する。 |
| variant | default / primary / dashed / plain / danger | 各セクションでプライマリは1つにする。 |
| href | Creates anchor semantics | ナビゲーションに使う。 |
| size | s / m / l | デフォルトは中。 |
| loading | Busy presentation | 通知されるステータスと組み合わせる。 |
## Nord デザインシステム完全ガイド

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

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

## Nord デザインシステム Nordは、公開リファレンスを備えた社内向けプロダクトシステムです

### 想定される用途を明示する

> Nordのドキュメントでは、Nordhealthの体験向けに構築されたシステムと説明されています。公開されているコンポーネントは参考になりますが、ブランドやコンポーネントの利用条件が、任意の商用利用を許可するという意味ではありません。ここで使う会議室名とリクエストのワークフローは、説明用に独自に作成したデータです。

デフォルトのトークン表はTherapyを示しています。獣医療または医療のアプリケーションでは、青いアクセントがNordhealthのすべての製品に使われると決めつけず、用途に合ったテーマを選んでください。テーマの選択はアプリケーション側で管理します。

関連する仕様を確認する

## Nord デザインシステム Therapyの役割別の値で、ワークスペースを落ち着いた印象にする

### テキスト、境界線、背景面の役割を分ける

このサンプルでは、依頼内容にメインのテキストロール、説明には控えめなロールを使用しています。オフホワイトのページ背景に白いパネルを重ね、編集可能なフィールドはより目立つボーダーで示しています。エラーテキストはインターフェース全体を赤く染めるのではなく、無効なタイトルの横に表示されます。プレビューには臨床情報や患者情報は含まれていません。

関連する仕様を確認する

## Nord デザインシステム コンパクトなテキストにも十分な行間を

### サイズと行間は、仕様どおり組み合わせて使う

このトークンでは、本文サイズの0.875remと本文の行の高さ1.5が組み合わされています。一方、フォームのテキストには独立した20pxの行ボックスがあります。これは別々のルールです。フォーム用の値を長い段落に適用すると、必要以上に詰まってしまいます。実際のリファレンスではNordhealth Sansファミリーのトークンを使用しています。このオフライン版では、ライセンス済みフォントが提供されていると誤解させないよう、利用可能なシステムフォントを使用しています。

関連する仕様を確認する

## Nord デザインシステム アプリケーションのグリッド内でコントロールを広げる

### コンポーネントはページのブレークポイントを決めない

Inputのインラインサイズは、初期値として240pxの変数が設定されています。利用可能なフィールド列全体に広げるには、仕様で定められたexpandを使います。このサンプルでは、デスクトップでは部屋の一覧をエディターの横に配置し、モバイルでは縦に並べています。このブレークポイントはアプリケーション側の判断であり、Nordのトークンではありません。行を選択しても、部屋名、収容人数、空き状況のラベルは表示されたままです。

オフライン版の部屋選択リストには、ネイティブのラジオグループを使用しています。別途提供されているライブラリの例では、5つの選択肢を持つSelectを使用しています。どちらも部屋を1つ選ぶためのものですが、レイアウトは異なります。同一のコンポーネント実装として示しているわけではありません。

関連する仕様を確認する

## Nord デザインシステム ラベルとエラーメッセージの責任範囲を明確にする

### このフォームには単独のフィールドで十分

InputやSelectは、それぞれラベル、ヒント、エラーを設定できます。新しいFieldのコンポジションを使う場合は、これらの役割をFieldが担います。そのため、両方に設定すると案内が重複します。この例では単独のフィールドを使い、タイトルの前後の空白を取り除いた結果が空の場合に、短いエラーメッセージを1つ表示します。

無効化されたフィールドはフォーム送信から除外されますが、読み取り専用のフィールドは、フォーカスでき、送信時にも値が保持されます。依頼に含める必要がある部屋IDを、編集させないという理由だけで無効化しないでください。

- 依頼タイトルのラベルは常に表示する。

- ヒントは入力内容の説明に使い、ラベルの代わりにしない。

- 検証メッセージを無効なコントロールに関連付ける。

関連する仕様を確認する

## Nord デザインシステム Selectには通常のoption要素を使う

### 値はホストコンポーネントから取得する

デフォルトスロットにはネイティブのoption要素を指定できます。各部屋には固定の値を設定し、収容人数を含む説明的なラベルを表示します。changeイベントを受け取ったアプリケーションは、ホストの値をもとにサマリーを再計算します。この構成では、独自のnord-optionタグは使いません。

Nordでは、選択肢が多い場合はSelect、少数の選択肢をそのまま表示するのが有用な場合はラジオボタンを推奨しています。この例には5つの部屋があります。オフライン版のラジオボタンを使った表示では、収容人数の違いを視覚的に確認できます。

関連する仕様を確認する

## Nord デザインシステム Buttonのデフォルト設定はフォームの構成に影響する

### アクション、リンク、読み込みのセマンティクスを明示する

Nord Buttonのtypeのデフォルト値は"submit"です。そのため、フォーム内のプレビューやリセットのような副次的なアクションを送信させたくない場合は、typeを明示する必要があります。コンポーネントにhrefを指定すると、リンクとしてのセマンティクスに切り替わります。アンカーをクリックハンドラーで模倣するのではなく、ナビゲーションにはこの方法を使ってください。

読み込み中もボタンはフォーカス可能な状態に保たれ、連続した操作は防止されます。スピナーは支援技術から隠されるため、アプリケーション側で進行状況を言葉で伝える必要があります。安易にdisabledに置き換えないでください。利用できないアクションと、処理中のアクションでは、フォーカスやフィードバックに求められることが異なります。

部屋の依頼の例では下書きを同期的に計算するため、読み込み時間は必要ありません。メインボタンはタイトルを検証し、選択された部屋を読み取ります。どちらかを編集すると、以前の下書き文は削除されます。各入力を制御するNord APIについては、上のフィールドとSelectのセクションで説明しています。

関連する仕様を確認する

## Nord デザインシステム コンポーネントのメソッドを呼び出す前に、必要なCSSを読み込む

### プロトタイプの読み込みと本番用のバンドルは異なる

公式のクイックスタートでは、コンポーネントモジュールとCSSフレームワークを組み合わせています。後者は共有トークンと基盤スタイルを提供します。バンドルするアプリケーションでは、@nordhealth/cssと@nordhealth/componentsをインストールし、CSSを一度だけインポートして、使用するコンポーネントモジュールのみをインポートしてください。パッケージモジュールは副作用として要素を登録します。

React 19では、これらのカスタム要素を直接使用できます。旧式の@nordhealth/reactラッパーは、現行のガイダンスでは非推奨です。サーバーサイドレンダリングではコンポーネントのShadow DOMは出力されません。Next.jsでインポートする場合は、クライアント境界が必要です。こうした連携上の制約は、ライブラリなしでインタラクションを実行できるオフライン版のHTMLプレビューとは分けて考えてください。

1. コンポーネントモジュールの前にフレームワークCSSを読み込む。

2. 初期化時にfocusを呼び出す前に、customElements.whenDefinedを待つ。

3. 検証とローカル状態のハンドラーを設定する。

4. CDNへの多数のモジュールリクエストに頼らず、本番用の依存関係をバンドルする。

関連する仕様を確認する

## Nord デザインシステムのコンポーネント例

### 完全なスタンドアロンのインタラクティブ見本

ドキュメント全体をindex.htmlとして保存し、ブラウザーで開いてください。Nord TherapyのトークンをHTML/CSSでオフライン解釈した例です。ネイティブのWeb Component連携は別途示しています。

```
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Nord room request interpretation</title><style>*{box-sizing:border-box}body{margin:0;background:#fafbfb;color:#0c1a3d;font:14px/1.5 system-ui,sans-serif}button,input{font:inherit}header{height:52px;background:white;border-bottom:1px solid #d8dee4;padding:0 24px;display:flex;align-items:center;justify-content:space-between}header small{color:#36434a}main{max-width:960px;margin:36px auto;padding:0 24px}h1{font-size:24px;line-height:1.2;margin:0 0 8px}h2{font-size:20px;line-height:1.2;margin:0 0 16px}p{margin:0 0 24px}.muted{color:#36434a}.layout{display:grid;grid-template-columns:310px 1fr;gap:24px}.panel{background:white;border:1px solid #d8dee4;border-radius:5px;padding:24px}fieldset{margin:0;padding:0;border:0;min-width:0}legend{font-weight:600;margin-bottom:16px}.room{display:flex;gap:12px;padding:12px;border:1px solid #d8dee4;border-radius:3px;margin-bottom:8px;cursor:pointer;align-items:center}.room:has(:checked){border-color:#3559c7;background:#f0f4ff}.room input{accent-color:#3559c7}.room span{flex:1}.room small{display:block;color:#36434a}.room b{font-size:12px;font-weight:500}.diagram{height:120px;background:#f6f8f8;display:grid;place-items:center;margin:-24px -24px 24px;border-radius:5px 5px 0 0;border-bottom:1px solid #d8dee4}.table{height:50px;border:2px solid #bcc5cc;border-radius:5px;background:#fff;position:relative;transition:width .2s ease}.chair{position:absolute;width:12px;height:10px;border:1px solid #bcc5cc;background:white;border-radius:3px;top:-16px}.chair.bottom{top:auto;bottom:-16px}label.field{display:block;font-weight:600;margin:16px 0 8px}#title{width:100%;border:1px solid #bcc5cc;border-radius:3px;height:36px;padding:7px 12px;color:inherit;background:white}#title[aria-invalid=true]{border-color:#d24023}.error{color:#d24023;min-height:20px;font-size:12px;margin:4px 0 12px}button{background:#3559c7;color:white;border:1px solid transparent;box-shadow:0 1px 3px #0c0c0c17;border-radius:3px;padding:7px 16px;cursor:pointer}button:focus-visible,input:focus-visible{outline:2px solid #3559c7;outline-offset:3px}.summary{margin-top:24px;background:#f0f4ff;border:1px solid #c6d4f9;padding:16px;border-radius:5px;overflow-wrap:anywhere}.summary:empty{display:none}.boundary{font-size:12px;color:#36434a;margin-top:24px}#selected{font-weight:600}.facts{display:flex;gap:24px;margin-bottom:24px}.facts strong{font-size:20px;display:block}.facts span{font-size:12px;color:#36434a}@media(max-width:650px){main{margin:24px auto;padding:0 16px}.layout{grid-template-columns:1fr;gap:16px}.panel{padding:16px}.diagram{margin:-16px -16px 16px}.room{padding:8px 12px}header{padding:0 16px}header small{display:none}}</style><header><strong>◈ Workplace</strong><small>Room request workspace</small></header><main><h1>A room for your next conversation</h1><p class="muted">Choose a room and prepare a request draft.</p><div class="layout"><section class="panel"><fieldset><legend>Choose a room</legend><div id="rooms"></div></fieldset></section><section class="panel"><div class="diagram" aria-hidden="true"><div class="table" id="table"></div></div><h2 id="selected">Birch</h2><div class="facts"><div><strong id="capacity">4</strong><span>Seats</span></div><div><strong>Draft</strong><span>Request status</span></div></div><form novalidate><label class="field" for="title">Request title</label><input id="title" type="text" aria-describedby="hint error" placeholder="e.g. Design review"><div id="error" class="error" role="alert"></div><p id="hint" class="muted">Use a non-sensitive meeting title. Availability is not checked in this example.</p><button type="submit">Prepare request</button></form><div class="summary" id="result" role="status"></div></section></div><p class="boundary">Independent HTML interpretation of Nord Therapy tokens. Nord is intended for Nordhealth products. This example creates a local draft only; it does not reserve a room.</p></main><script>const rooms=[['Birch',4],['Cedar',6],['Elm',8],['Maple',10],['Pine',12]],field=document.querySelector('#title'),result=document.querySelector('#result');let selected=0;document.querySelector('#rooms').innerHTML=rooms.map(([name,n],i)=>`<label class="room"><input type="radio" name="room" value="${i}" ${i===0?'checked':''}><span>${name}<small>Meeting room</small></span><b>${n} seats</b></label>`).join('');function update(){let [name,n]=rooms[selected];document.querySelector('#selected').textContent=name;document.querySelector('#capacity').textContent=n;let table=document.querySelector('#table');table.style.width=(n*12+44)+'px';table.innerHTML=Array.from({length:n},(_,i)=>`<i class="chair ${i>=n/2?'bottom':''}" style="left:${12+(i%(n/2))*24}px"></i>`).join('');result.textContent=''}document.querySelectorAll('[name=room]').forEach(input=>input.onchange=()=>{selected=Number(input.value);update()});document.querySelector('form').onsubmit=e=>{e.preventDefault();if(!field.value.trim()){document.querySelector('#error').textContent='Enter a request title.';field.setAttribute('aria-invalid','true');field.focus();return}result.textContent='Draft prepared: '+field.value.trim()+' · '+rooms[selected][0]+' · '+rooms[selected][1]+' seats. No room is reserved.'};field.oninput=()=>{field.removeAttribute('aria-invalid');document.querySelector('#error').textContent='';result.textContent=''};update();</script></html>
```

コードリファレンス

- このサンプルでは部屋の選択肢をラジオボタンで表示しています。ネイティブのNordの例では、通常のoption要素を使うSelectを使用しています。どちらも実際の部屋を予約するものではありません。

### 明示的な検証を備えた、ラベル付きの部屋依頼

単独のnord-inputとnord-selectは、オプションのFieldファミリーを使わずにラベルを提供します。送信時にはコンポーネントの値を読み取り、Inputのerrorプロパティを設定します。

```
<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Room request draft</title>
<link rel="stylesheet" href="https://nordcdn.net/ds/css/5.2.4/nord.min.css">
<script type="module" src="https://nordcdn.net/ds/components/5.3.0/index.js"></script>
<style>main{max-width:560px;margin:auto;padding:var(--n-space-l)}form{display:grid;gap:var(--n-space-l)}</style>
<main><h1>Prepare a room request</h1><p>For an authorized Nordhealth product. Local demonstration only.</p>
<form novalidate>
<nord-input id="request" name="request" label="Request title" hint="Use a non-sensitive meeting title." required expand></nord-input>
<nord-select id="room" name="room" label="Room" value="Birch" expand>
<option value="Birch">Birch · 4 seats</option><option value="Cedar">Cedar · 6 seats</option>
<option value="Elm">Elm · 8 seats</option><option value="Maple">Maple · 10 seats</option><option value="Pine">Pine · 12 seats</option>
</nord-select>
<nord-button type="submit" variant="primary">Prepare request</nord-button>
</form><p id="result" role="status"></p></main>
<script type="module">
await Promise.all(['nord-input','nord-select','nord-button'].map(name=>customElements.whenDefined(name)));
const form=document.querySelector('form'), title=document.querySelector('#request'),room=document.querySelector('#room'),result=document.querySelector('#result');
form.addEventListener('submit',event=>{
 event.preventDefault();title.error=title.value.trim()?'':'Enter a request title.';
 if(title.error){title.focus();return;}
 result.textContent=`Draft: ${title.value.trim()} in ${room.value}. No room is reserved.`;
});
form.addEventListener('input',()=>{result.textContent='';title.error='';});
form.addEventListener('change',()=>{result.textContent='';});
</script></html>
```

コードリファレンス

- 5つの部屋の選択肢があるため、コンパクトに選べるSelectが便利です。

- Buttonのデフォルト値はsubmitです。この例ではtypeを明示しています。

- メソッドを使う前にカスタム要素の定義完了を待ちます。予約サービスは呼び出しません。

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

### 実装の出発点

Nordhealthでの使用を許可された方向けの、公開CDNを利用した完全なプロトタイプです。ドキュメントでは現在、CSS 5.2.4およびコンポーネント5.3.0が指定されています。本番環境ではnpmパッケージをバンドルしてください。以下のオフラインでのビジュアル表現では、これらのリモートパッケージを読み込みません。

```
<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Room request draft</title>
<link rel="stylesheet" href="https://nordcdn.net/ds/css/5.2.4/nord.min.css">
<script type="module" src="https://nordcdn.net/ds/components/5.3.0/index.js"></script>
<style>main{max-width:560px;margin:auto;padding:var(--n-space-l)}form{display:grid;gap:var(--n-space-l)}</style>
<main><h1>Prepare a room request</h1><p>For an authorized Nordhealth product. Local demonstration only.</p>
<form novalidate>
<nord-input id="request" name="request" label="Request title" hint="Use a non-sensitive meeting title." required expand></nord-input>
<nord-select id="room" name="room" label="Room" value="Birch" expand>
<option value="Birch">Birch · 4 seats</option><option value="Cedar">Cedar · 6 seats</option>
<option value="Elm">Elm · 8 seats</option><option value="Maple">Maple · 10 seats</option><option value="Pine">Pine · 12 seats</option>
</nord-select>
<nord-button type="submit" variant="primary">Prepare request</nord-button>
</form><p id="result" role="status"></p></main>
<script type="module">
await Promise.all(['nord-input','nord-select','nord-button'].map(name=>customElements.whenDefined(name)));
const form=document.querySelector('form'), title=document.querySelector('#request'),room=document.querySelector('#room'),result=document.querySelector('#result');
form.addEventListener('submit',event=>{
 event.preventDefault();title.error=title.value.trim()?'':'Enter a request title.';
 if(title.error){title.focus();return;}
 result.textContent=`Draft: ${title.value.trim()} in ${room.value}. No room is reserved.`;
});
form.addEventListener('input',()=>{result.textContent='';title.error='';});
form.addEventListener('change',()=>{result.textContent='';});
</script></html>
```

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

```
Nord Therapyのセマンティックロールを、ラベル付きのコントロールとともに使用します。レスポンシブなアプリケーションレイアウト内にフィールドを展開します。リクエストのタイトルは前後の空白を除いて検証し、選択できる部屋は1つに限定して、ローカルの下書き結果のみを表示します。実際にNordhealth向けに実装する場合は、ドキュメントに記載されたパッケージとテーマの使用許可に従ってください。
```

## Nord デザインシステム 参照元と対象範囲

独自のOpenDesignリファレンスです。Nordが想定する用途はNordhealth製品です。この独自のHTML解釈は、部屋の予約を行うものでも、ブランドやコンポーネントの使用権を付与するものでもありません。

- トークンリファレンス Therapyの値、余白、タイポグラフィ。

- Web Componentsのセットアップ 必須のCSS、インポート、フレームワークの境界。

- 入力 ラベル、エラー、レスポンシブなサイズ設定。

- Select 選択肢と値の扱い。

- Button 送信のセマンティクスとアクションのバリエーション。

## Nord デザインシステム 関連リソース

### Oracle Redwood

Oracle JET 19 Redwoodの実際の配色、セマンティックな役割、スペーシング、密度の境界を、編集可能な独自の株式レビューシートを通して詳しく確認できます。

### Orange OUDS Web

Orange OUDS 1.4の実際のセマンティックトークン、テーマパッケージ、ネイティブのOffcanvasの挙動を、レスポンシブ対応の比較調査一式で確認できます。

### Palantir Blueprint

Blueprintを使って、密度の高いデータワークスペースを構築します。検証済みのタイポグラフィと意図のトークン、選択可能なデータセットテーブル、レビュー用インスペクター、完全なReactソースを備えています。


- [実装リファレンス](https://nordhealth.design/core/tokens/)
- [ソース](https://nordhealth.design/core/tokens/)
- [ソース](https://nordhealth.design/components/input/)
- [ソース](https://nordhealth.design/components/select/)
- [ソース](https://nordhealth.design/components/button/)
- [関連する仕様を確認する](https://nordhealth.design/docs/developer/web-components/)
- [関連する仕様を確認する](https://nordhealth.design/core/tokens/)
- [関連する仕様を確認する](https://nordhealth.design/components/input/)
- [関連する仕様を確認する](https://nordhealth.design/components/select/)
- [関連する仕様を確認する](https://nordhealth.design/components/button/)
- [コードリファレンス](https://nordhealth.design/core/tokens/)
- [コードリファレンス](https://nordhealth.design/components/input/)
- [トークンリファレンス Therapyの値、余白、タイポグラフィ。](https://nordhealth.design/core/tokens/)
- [Web Componentsのセットアップ 必須のCSS、インポート、フレームワークの境界。](https://nordhealth.design/docs/developer/web-components/)
- [入力 ラベル、エラー、レスポンシブなサイズ設定。](https://nordhealth.design/components/input/)
- [Select 選択肢と値の扱い。](https://nordhealth.design/components/select/)
- [Button 送信のセマンティクスとアクションのバリエーション。](https://nordhealth.design/components/button/)
