diff --git a/.storybook/visual-testing.md b/.storybook/visual-testing.md index cc291d0..1bf6a54 100644 --- a/.storybook/visual-testing.md +++ b/.storybook/visual-testing.md @@ -35,6 +35,9 @@ pnpm test -u # 基準画像を撮り直す(意図して見た目を変え 2. **画面が 0.8 倍に縮む。** ストーリーを描く枠(1200×900)が窓(既定 1280×720)に収まらないと、Vitest が枠ごと縮めます。縮むと 1px のずれがふちのぼかしになり、pixelmatch がふちのぼかしを数えないので見のがします。`contextOptions.viewport` を枠より大きく取りました(`browser.viewport` は provider 側で無効化されていて効きません) 3. **許す幅は割合で持たない。** `allowedMismatchedPixelRatio: 0.002` では、全ボタンの角を 12px から 0px にしても 4 本中 3 本が通りました。`allowedMismatchedPixels: 0` にしています 4. **基準画像の置き場が Storybook を壊す。** 既定の置き場は `__screenshots__/Button.stories.tsx/` で、この**ディレクトリ名**が `../src/**/*.stories.tsx` に一致し、Storybook の索引作りが EISDIR で落ちて画面が真っ白になります。`screenshotDirectory` は何を渡してもテストファイルの隣に継ぎ足されるので(絶対パスも先頭の `/` が落ちる)、Storybook 側の指定を `**` から `*` に変えて、ディレクトリに降りないようにしました +5. **`:not(:focus)` で隠す書き方は、pseudo-states で固定すると出てこない。** 「ふだんは隠れ、フォーカスしたときだけ見せる」を `not-focus:sr-only`(`:not(:focus)`)で書くと、`storybook-addon-pseudo-states` が `:not()` の中身を `:not(:focus), :not(.pseudo-focus)` に書き換えます。`.pseudo-focus` クラスを当てても `:not(:focus)` はまだ真のままなので、フォーカスした状態に固定したストーリーでも隠れたままになります。「フォーカスしたときだけ現す」ものは、`focus:` 側に見せる指定を書く形にします(SkipLink) +6. **Controls で props を切り替えても、pseudo-states は前のクラスを外さない。** `storybook-addon-pseudo-states` が要素に付けた `.pseudo-focus` などのクラスは、Controls で props を変えても残ったままで、状態の見た目が消えません。切り替えるたびに要素を作り直す(切り替える値を `key` にする)と直ります(Accordion の `indicator`・focusRing の切り替え) +7. **`pnpm test -u` は、パスを渡しても範囲を絞らないことがあります。** ディレクトリのパスだけでは全体の基準画像を撮り直すことがあります。範囲を絞るには、パスの後ろに `--update` を続けて書くか、ファイルを直接指定します(`pnpm vitest run --project=storybook <パス>` も使えます) ## 撮影の条件(`vitest.config.ts`) diff --git a/README.md b/README.md index bb4ae29..b399342 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,27 @@ ## つくりたいコンポーネント +### 土台 + +- [x] Icon +- [x] VisuallyHidden +- [x] ThemeProvider +- [x] Collapsible +- [x] ScrollArea +- [x] AspectRatio +- [x] Portal +- [x] Transition + ### 文字 - [x] Heading - [x] Text - [x] Code - [x] Kbd +- [x] Mark +- [ ] Ruby +- [ ] Highlight +- [x] NumberFormat ### 本文 @@ -37,13 +52,26 @@ - [x] Footnote - [ ] Steps - [ ] FileTree +- [ ] CodeGroup +- [ ] Embed +- [ ] Gallery +- [ ] ImageZoom +- [x] Bleed +- [ ] Spoiler +- [ ] TypeTable +- [ ] Mermaid +- [ ] Math ### ページの枠 -- [ ] Container +- [x] Container - [ ] Navbar - [ ] Footer - [ ] Sidebar +- [ ] Stack +- [x] SkipLink +- [ ] Affix +- [ ] Splitter ### ナビゲーション @@ -54,6 +82,14 @@ - [ ] Pagination - [ ] Menu - [ ] Stepper +- [ ] NavigationMenu +- [ ] ContextMenu +- [ ] Toolbar +- [ ] CommandPalette +- [ ] BackToTop +- [ ] Menubar +- [ ] Tree +- [ ] Tour ### 表示 @@ -62,17 +98,29 @@ - [x] List - [x] Table - [x] Divider -- [ ] Time +- [x] Time +- [x] RelativeTime - [ ] Avatar - [x] Badge - [ ] Chip - [ ] Timeline -- [ ] Accordion +- [x] Accordion +- [x] Image +- [ ] AvatarGroup +- [ ] DescriptionList +- [ ] Stat +- [ ] Meter +- [ ] Carousel +- [ ] Indicator ### 操作 - [x] Button - [x] Link +- [ ] Toggle +- [ ] ToggleGroup +- [ ] ButtonGroup +- [x] CopyButton ### 入力 @@ -80,7 +128,7 @@ - [x] Select - [x] Switch - [x] Form -- [ ] Textarea +- [x] Textarea - [x] Checkbox - [x] Radio - [ ] Fieldset @@ -90,6 +138,20 @@ - [ ] NumberField - [ ] DatePicker - [ ] Dropzone +- [ ] SearchField +- [ ] PasswordField +- [ ] Autocomplete +- [ ] PinField +- [ ] TagsInput +- [ ] TimePicker +- [ ] ColorPicker +- [ ] Rating +- [ ] Calendar +- [ ] DateRangePicker +- [x] CheckboxGroup +- [ ] MaskInput +- [ ] Editable +- [ ] FileInput ### 通知 @@ -97,8 +159,9 @@ - [x] Loading - [ ] Toast - [ ] Progress -- [ ] Skeleton -- [ ] Empty +- [x] Skeleton +- [ ] StatusPanel +- [ ] LoadingOverlay ### 重なるもの @@ -106,6 +169,32 @@ - [x] Drawer - [x] Popover - [x] Tooltip +- [x] AlertDialog +- [ ] PreviewCard + +### アプリの画面 + +Web アプリで使うものです。ポートフォリオのあとに作ります。土台は外のヘッドレス(TanStack Table・TanStack Virtual・dnd-kit)に peer dependency で乗り、ここでは見た目とトークンを持ちます。 + +- [ ] DataTable +- [ ] VirtualList +- [ ] Sortable +- [ ] Kanban +- [ ] Popconfirm +- [ ] ActionBar +- [ ] Mentions +- [ ] Cascader +- [ ] TreeSelect +- [ ] Transfer + +### チャット + +- [ ] Composer +- [ ] MessageList +- [ ] Bubble +- [ ] TypingIndicator +- [ ] Attachment +- [ ] StreamingText ## Figma diff --git a/design/adr/0102-overlay-components.md b/design/adr/0102-overlay-components.md index 558d81b..1508f8c 100644 --- a/design/adr/0102-overlay-components.md +++ b/design/adr/0102-overlay-components.md @@ -107,7 +107,7 @@ - つまみを押しても、Select のシートのように半分と高さいっぱいを切り替えません。はじいたとみなす速さも Base UI の値です - Tooltip の長押し(500ms)は実機で確かめていません。iOS の Safari で文字の選択や端末のメニューが出ないか、スクロールの始まりと取り違えないかを見ます - 構造を固定する Provider(原則11 の「使う側が固定できる」)は、まだ部品ごとの `presentation` だけです - - AlertDialog(外を押しても Esc でも閉じない確かめ)は部品として持たず、`dismissible`・`closeOnEscape`・`closeButton` の組み合わせで作ります + - AlertDialog(外を押しても Esc でも閉じない確かめ)は部品として持たず、`dismissible`・`closeOnEscape`・`closeButton` の組み合わせで作ります(2026-09-19: この記述は [ADR-0123](./0123-alert-dialog.md) で覆しました。組み合わせを間違えないことと、読み上げの役割を確実に切り替えるため、AlertDialog を部品として作りました) ## 原則への反映 diff --git a/design/adr/0121-reading-datetime-number.md b/design/adr/0121-reading-datetime-number.md new file mode 100644 index 0000000..ed16a10 --- /dev/null +++ b/design/adr/0121-reading-datetime-number.md @@ -0,0 +1,68 @@ +# 0121. 文字の部品(Mark・Time・RelativeTime・NumberFormat)と、ThemeProvider の言語・タイムゾーンの既定 + +- ステータス: Accepted +- 日付: 2026-09-19 +- ラウンド: 後半(ループ外) + +## 背景 + +記事の外でも使える、文字まわりの小さな部品を作ります。目立たせたい言葉(Mark)は、これまで Prose が素の HTML の `` に当てる見た目だけを持ち([ADR-0091](./0091-mark.md))、部品としては存在していませんでした。日付・時刻(Time)、「3 日前」のような相対の日時(RelativeTime)、数・通貨・割合・単位(NumberFormat)は、どれも作っていませんでした。 + +見た目の比較ではなく、書き方(どんな文字列になるか)と、日時の既定の言語・タイムゾーンをどう持つかという設計の判断なので、比較のストーリーは作っていません。 + +## 候補 + +比較ではなく、ユーザーへの問いと答えです(ほかの軸とまとめて質問しました)。 + +| 問い | 答え | +| -------------------------------------- | ------------------------------------------------------------------------ | +| Time の既定の書き方 | `YYYY/MM/DD` | +| 言語・タイムゾーンの既定と、上書きの口 | 既定は ja-JP・Asia/Tokyo にしつつ、Provider などで上書きできるようにする | +| 相対の日時は別の部品にするか | 相対日付のコンポーネントとして作る | +| 通貨(JPY)の書き方 | Intl の既定でよい | + +## 決定 + +- **Mark**: `` を描く部品にしました。見た目のクラス列は `src/internal/reading/mark.ts` に出し、Prose の `` と共有します。見た目そのものは [ADR-0091](./0091-mark.md) のままです +- **Time**: `