Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/checkbox-indicator-center.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'8341-ui': patch
---

Checkbox の選択時のチェック(と一部選択の横線)が枠の中心から下にずれていたのを直しました。
11 changes: 11 additions & 0 deletions .changeset/yorozuya-components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'8341-ui': patch
---

コンポーネントを 5 つ追加しました(yorozuya で使っていた部品を、8341-ui のトークンと Base UI で作り直したもの)。

- `Switch`: 押した瞬間に反映するオン / オフ(Base UI の Switch。`npx shadcn add @8341/switch`)
- `Dialog`: 画面に重ねて入力させるダイアログ。`placement="side"` で先頭側からせり出し、裏の画面も操作できる(`@8341/dialog`)
- `Spinner`: 読み込みや保存の最中を `role="status"` で伝える(`@8341/spinner`)
- `Skeleton`: 読み込み中に中身の形だけを先に見せる(`@8341/skeleton`)
- `Truncate`: 1 行に収まらない文字を省略し、ホバーとフォーカスで全文を出す(`@8341/truncate`)
37 changes: 36 additions & 1 deletion DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ DTCG では `{"colorSpace": "oklch", "components": [L, C, H], "hex": "#..."}`
- `Button`(`@8341/button`)— `packages/ui/src/components/ui/Button/`
- `Card`(`@8341/card`)— `packages/ui/src/components/ui/Card/`
- `Checkbox`(`@8341/checkbox`)— `packages/ui/src/components/ui/Checkbox/`
- `Dialog`(`@8341/dialog`)— `packages/ui/src/components/ui/Dialog/`
- `Divider`(`@8341/divider`)— `packages/ui/src/components/ui/Divider/`
- `FormField`(`@8341/form-field`)— `packages/ui/src/components/ui/FormField/`
- `Heading`(`@8341/heading`)— `packages/ui/src/components/ui/Heading/`
Expand All @@ -168,11 +169,15 @@ DTCG では `{"colorSpace": "oklch", "components": [L, C, H], "hex": "#..."}`
- `NotificationBanner`(`@8341/notification-banner`)— `packages/ui/src/components/ui/NotificationBanner/`
- `RadioGroup`(`@8341/radio-group`)— `packages/ui/src/components/ui/RadioGroup/`
- `Select`(`@8341/select`)— `packages/ui/src/components/ui/Select/`
- `Skeleton`(`@8341/skeleton`)— `packages/ui/src/components/ui/Skeleton/`
- `Spinner`(`@8341/spinner`)— `packages/ui/src/components/ui/Spinner/`
- `Stack`(`@8341/stack`)— `packages/ui/src/components/ui/Stack/`
- `Switch`(`@8341/switch`)— `packages/ui/src/components/ui/Switch/`
- `Tag`(`@8341/tag`)— `packages/ui/src/components/ui/Tag/`
- `Text`(`@8341/text`)— `packages/ui/src/components/ui/Text/`
- `TextField`(`@8341/text-field`)— `packages/ui/src/components/ui/TextField/`
- `Textarea`(`@8341/textarea`)— `packages/ui/src/components/ui/Textarea/`
- `Truncate`(`@8341/truncate`)— `packages/ui/src/components/ui/Truncate/`
<!-- /auto:components -->

### 共通規約
Expand All @@ -184,7 +189,7 @@ DTCG では `{"colorSpace": "oklch", "components": [L, C, H], "hex": "#..."}`
- 見た目が 44px 未満の操作対象には `tap-target` クラスでタップ領域を足す
- `hover:` は Tailwind v4 では自動で `@media (hover: hover)` に入る。無効状態に効かせないよう `enabled:hover:` を使う
- 強制カラーモードは `forced-colors:` で補う
- `'use client'` はフック・コンテキスト・イベントハンドラを作るエントリだけに付ける(button / form-field / text-field / textarea / select)
- `'use client'` はフック・コンテキスト・イベントハンドラを作るエントリだけに付ける(button / form-field / text-field / textarea / select / truncate)

### Button

Expand Down Expand Up @@ -245,6 +250,36 @@ DTCG では `{"colorSpace": "oklch", "components": [L, C, H], "hex": "#..."}`
- 見出しの先頭に種別(「エラー: 」など)を視覚的に隠して読ませる
- 動的に挿入するときだけ `live`(danger は `role="alert"`、他は `role="status"`)

### Switch

- Base UI の Switch(`role="switch"`)。`label` 必須、`description` で補足。`size`: `md`(トラック 60×36px)/ `sm`(40×24px)。ラベル全体がタップ領域で行の高さ 44px を確保
- 押した瞬間に反映する設定に使う。送信して反映する選択(同意など)は Checkbox
- オフ: `border-border-input` の枠と同色のつまみ / オン: `bg-key` のトラックに `bg-surface` のつまみとチェック(色だけで伝えない)

### Dialog

```tsx
<Dialog title="経歴を追加" description="保存するまで反映されません" trigger={<Button>経歴を追加する</Button>}
footer={<><Button variant="tertiary">下書きに保存する</Button><Button>追加する</Button></>}>
…
</Dialog>
```

- Base UI の Dialog。`title` 必須(名前)、`description`(説明)。開くとフォーカスが中に移り、Esc か「閉じる」(`closeLabel`)で閉じて開いたボタンに戻る
- `open` / `onOpenChange` で開閉を管理するときは `trigger` を省く
- `placement`: `center`(既定。`bg-overlay` の背面、`rounded-xl`、最大幅 `max-w-prose`、本文だけスクロール)/ `side`(先頭側からせり出す。裏の画面も操作でき、フォーカスだけ閉じ込める)
- 取り消せない操作の確認には使わない(AlertDialog はバックログ)

### Spinner / Skeleton

- **Spinner**: `role="status"` の中に `label`(必須)を文字で持つ。既定は視覚的に隠し、`showLabel` で表示。`size`: `sm` / `md` / `lg`(アイコンの寸法)。`delay` で 300ms 遅れて表示。ボタンの中は Button の `loading`
- **Skeleton**: `aria-hidden` の `bg-muted` の箱(`animate-pulse`、動きを減らす設定では止まる)。`width` / `height`(既定 100% / 1em)、`radius`: `none` / `xs`(既定)/ `md` / `xl` / `full`。待っている領域に `aria-busy` を立て、状態は Spinner で伝える

### Truncate

- 1 行に収まらない文字を … で省略する(`children` は文字列)。省略されたときだけ Tab で止まり、ホバーかフォーカスで全文を Base UI の Tooltip(`bg-inverse`)で出す
- 読み上げは常に全文。本文には使わず、表の列や一覧の項目名など幅が限られる場所に使う

### Card

- `border-border`、`rounded-xl`、内側余白 `p-inset-xl`
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,16 @@ Tailwind を使わない場合は、ビルド済みの `import '8341-ui/styles.c

## コンポーネント

ヘッドレス UI の [Base UI](https://base-ui.com/) に、トークンの見た目を載せた 18 種類です。使い分けの規約は [04 コンポーネント](./docs/rulebook/04-components.md)、動く見本は [Storybook](https://tkc310.github.io/8341-ui/) にあります。
ヘッドレス UI の [Base UI](https://base-ui.com/) に、トークンの見た目を載せた 23 種類です。使い分けの規約は [04 コンポーネント](./docs/rulebook/04-components.md)、動く見本は [Storybook](https://tkc310.github.io/8341-ui/) にあります。

| 種類 | コンポーネント |
| --- | --- |
| 操作 | `Button` · `Link` |
| フォーム | `FormField` · `TextField` · `Textarea` · `Select` · `Checkbox` · `RadioGroup` |
| 表示 | `Heading` · `Text` · `Tag` · `Icon` · `Card` · `Divider` · `Stack` |
| フォーム | `FormField` · `TextField` · `Textarea` · `Select` · `Checkbox` · `RadioGroup` · `Switch` |
| 表示 | `Heading` · `Text` · `Truncate` · `Tag` · `Icon` · `Card` · `Divider` · `Stack` |
| ナビゲーション | `Breadcrumb` · `Accordion` |
| フィードバック | `NotificationBanner` |
| フィードバック | `NotificationBanner` · `Spinner` · `Skeleton` |
| オーバーレイ | `Dialog` |

## 技術スタック

Expand Down
8 changes: 4 additions & 4 deletions docs/improvement/backlog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
## コンポーネント

- [ ] Table(ソート・横スクロール時の見出し固定、識別子の等幅)— 特化ルール「管理画面」
- [ ] Dialog / AlertDialog(Base UI)— 原則「誤りと撤回」の確認の段
- [ ] AlertDialog(Base UI。取り消せない操作の確認)— 原則「誤りと撤回」の確認の段。入力用の Dialog は提供済み
- [ ] EmptyState(「データが無い」「条件に一致しない」「権限がない」の書き分け)— 特化ルール「管理画面」
- [ ] Progress / Toast(Base UI)/ Skeleton — 原則「状態と応答」
- [ ] Tooltip(Base UI。1.4.13 の解除・ホバー・持続を満たすか確認)・Combobox — 原則「再認」
- [ ] Tabs・Switch・Menu(Base UI)
- [ ] Progress / Toast(Base UI)— 原則「状態と応答」
- [ ] 汎用の Tooltip(Base UI。1.4.13 の解除・ホバー・持続を満たすか確認)・Combobox — 原則「再認」。Truncate は省略した全文の表示だけに使う
- [ ] Tabs・Menu(Base UI)
- [ ] SkipLink(本文へ移動)— WCAG 2.4.1
- [ ] ErrorSummary(送信時のエラー一覧と最初の誤りへのフォーカス移動。現在は NotificationBanner の組み合わせで代用)— WCAG 3.3.1
- [ ] Pagination
Expand Down
2 changes: 2 additions & 0 deletions docs/improvement/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

| 日付 | 種別 | 内容 | 再発防止 |
| ---------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| 2026-10-20 | 不具合 | Checkbox のチェックのアイコンが枠の中心から下にずれていた。Indicator(span)が本文の行の高さを引き継いだ行ボックスになり、`align-middle` の SVG がベースライン基準で置かれていたため。Indicator を flex にして行ボックスを作らない | 単体テストでアイコンが flex の中心に置かれていることを検査 |
| 2026-10-20 | 部品 | yorozuya で使っていた Switch・Dialog・Spinner・Skeleton・Truncate を、Base UI と semantic トークンで作り直して追加。Spinner は文言をライブリージョンの中の文字で持ち、Truncate は省略時だけフォーカスできるようにした | Switch のつまみとトラックの組み合わせを `contrast.rules.json` に追加。各部品の単体テスト(キーボード操作・名前・状態)とストーリーの play 関数 |
| 2026-10-19 | 文書 | principles.md が参照する外部の文書の要約を `docs/design-principles/sources/` に追加。読めなくなった Jakob's Law のリンクを Nielsen 本人の解説に差し替え | 要約に原文・確認日・経緯を記録し、リンク切れ時の手順を sources/README.md に記載 |
| 2026-10-19 | 構成 | コンポーネント構造規則(yorozuya)を取り込み、`src/components/ui/<PascalCase>/index.tsx` に本体・テスト・ストーリー・フックを置く形に変更。テストをコンポーネントごとに分け、useFormField を `FormField/useFormField.ts` に分けた | ADR-0016。`scripts/check-structure.ts` と dependency-cruiser で構造と import を検査 |
| 2026-10-19 | 文書 | アイコン画像(ICO・PNG。ホーム画面用と 1024px)を追加し、Storybook のファビコンとホーム画面のアイコンに設定 | 書き出し方と差し替えを `docs/assets/README.md` に記載。manager-head.html を置くと SVG のファビコンが自動で入らなくなるため明示し、e2e(`e2e/docs.spec.ts`)でリンクを検査 |
Expand Down
6 changes: 3 additions & 3 deletions docs/rulebook/01-principles.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ UI の方向性とサービス種別は、8341-ui を使う各プロダクトの
| 操作の幾何 | 最小タップ領域 `size.target-min` 44px(design-principles の必須 24px より厳しい)。Button sm は擬似要素で 44px を確保 | 続けて押す操作の配置 |
| 一度に出す数 | RadioGroup(2〜6 個)と Select(7 個以上)の使い分け規約 | ページ分割、絞り込み(バックログ) |
| 一貫性 | semantic カラーで色の意味を固定、Button の variant、アイコンセットを線の描き方で統一 | ナビゲーション部品(バックログ) |
| 状態と応答 | Button の `loading`(`aria-busy`)、NotificationBanner の `live`、Breadcrumb の `aria-current` | 進捗表示、トースト、スケルトン(バックログ) |
| 誤りと撤回 | FormField(Base UI の Field)の補足とエラー、Base UI の Form による送信時の検証とフォーカス移動、`validationMode="onBlur"`、送信ボタンを無効化しない規約、danger ボタン | 確認ダイアログ(Base UI の AlertDialog)、エラー一覧(バックログ) |
| 再認 | Select、RadioGroup、アイコン単体利用時の `label` 必須 | コンボボックス・ツールチップ(Base UI にあり、バックログ) |
| 状態と応答 | Button の `loading`(`aria-busy`)、NotificationBanner の `live`、Breadcrumb の `aria-current`、Spinner(`role="status"`)、Skeleton、Switch(押した瞬間に反映) | 進捗表示(Progress)、トースト(バックログ) |
| 誤りと撤回 | FormField(Base UI の Field)の補足とエラー、Base UI の Form による送信時の検証とフォーカス移動、`validationMode="onBlur"`、送信ボタンを無効化しない規約、danger ボタン | 確認ダイアログ(Base UI の AlertDialog)、エラー一覧(バックログ)。入力用の Dialog は提供済み |
| 再認 | Select、RadioGroup、アイコン単体利用時の `label` 必須、Truncate(省略した全文をホバーとフォーカスで出す) | コンボボックス・汎用のツールチップ(Base UI にあり、バックログ) |
| 文言 | [05 文言](./05-writing.md)、`label` / `legend` を必須 props にする契約 | — |
| 削る | 影は 3 段階・ボタンに使わない、`prefers-reduced-motion` で動きを止める | 画面ごとの要素の取捨 |
| 助けの場所 | — | ヘッダーの配置(プロダクト側) |
Expand Down
3 changes: 3 additions & 0 deletions docs/rulebook/02-accessibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@
| Button | Tab で移動、Enter / Space で実行 |
| Link | Tab で移動、Enter で遷移 |
| Checkbox | Space で切り替え |
| Switch | Space で切り替え(Base UI。`role="switch"`) |
| RadioGroup | Tab でグループに入り、矢印キーで選択(Base UI) |
| Accordion | Enter / Space で開閉(Base UI。見出しの中のボタン) |
| Select | Enter / Space で開き、矢印キーで移動、Enter で決定、Esc で閉じる(Base UI) |
| Dialog | 開くとフォーカスが中に移り、Tab は中で循環。Esc か「閉じる」で閉じ、開いたボタンに戻る(Base UI) |
| Truncate | 省略されたときだけ Tab で止まり、フォーカス中は全文のツールチップを出す |

独自のキーボード操作(ロービングタブインデックスなど)が必要な部品を作る場合は、
[WAI-ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/) のパターンに従い、ADR を書きます。
Expand Down
7 changes: 6 additions & 1 deletion docs/rulebook/04-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,14 @@ packages/ui/src/components/ui/Button/
| ページを移動する | Link(カード全体なら Card の `href`) | Button |
| 2〜6 個から 1 つ選ぶ | RadioGroup | Select |
| 7 個以上から 1 つ選ぶ | Select | RadioGroup |
| オン / オフ、複数選択 | Checkbox | トグルスイッチ(未提供) |
| 送信して反映するオン / オフ、複数選択 | Checkbox | Switch |
| 押した瞬間に反映する設定 | Switch | Checkbox |
| ページ上部の重要なお知らせ | NotificationBanner | Tag |
| 一覧の項目の状態 | Tag(アイコン付き) | 色だけの点 |
| よくある質問など折りたたみ | Accordion + AccordionItem | 独自のディスクロージャ |
| 要素の縦横の間隔 | Stack | 個別の margin |
| 画面に重ねて入力・確認させる | Dialog(`title` 必須) | 独自のモーダル |
| 読み込み・保存の最中 | Spinner(ボタンの中は Button の `loading`) | 文言の無い回転アイコン |
| 中身の形が分かる読み込み | Skeleton + 領域の `aria-busy` | 空白のまま待たせる |
| 幅が限られた 1 行の文字 | Truncate(表の列・一覧の項目名) | 本文の省略 |
| フォームの送信と検証 | Base UI の Form + FormField | 独自の検証の仕組み |
12 changes: 12 additions & 0 deletions packages/tokens/src/contrast.rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@
"min": 3,
"wcag": "1.4.11"
},
{
"id": "switch-thumb",
"$description": "Switch のつまみとトラック。オフのつまみは枠線の色、オンのつまみは面の色を key の上に置く(ホバー時を含む)",
"pairs": [
["color.border.input", "color.bg.muted"],
["color.border.strong", "color.bg.muted"],
["color.bg.surface", "color.bg.key"],
["color.bg.surface", "color.bg.key-hover"]
],
"min": 3,
"wcag": "1.4.11"
},
{
"id": "key-bg-as-boundary",
"fg": ["color.bg.key", "color.bg.danger"],
Expand Down
Loading
Loading