@ubie/vitals-ui-business 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +117 -1
  2. package/DESIGN.md +75 -0
  3. package/dist/index.cjs +358 -1
  4. package/dist/index.d.cts +364 -3
  5. package/dist/index.d.cts.map +1 -1
  6. package/dist/index.d.mts +364 -3
  7. package/dist/index.d.mts.map +1 -1
  8. package/dist/index.mjs +318 -5
  9. package/dist/index.mjs.map +1 -1
  10. package/docs/components/chat.md +81 -0
  11. package/docs/components/drawer.md +48 -0
  12. package/docs/components/icon.md +101 -0
  13. package/docs/components/layout.md +33 -0
  14. package/docs/components/modal.md +49 -0
  15. package/docs/components/table.md +158 -0
  16. package/docs/patterns/disclosure.md +114 -0
  17. package/docs/patterns/list-detail.md +71 -0
  18. package/docs/patterns/skeleton.md +48 -0
  19. package/docs/principles/README.md +21 -0
  20. package/docs/principles/information-design.md +94 -0
  21. package/docs/principles/scorecard.md +56 -0
  22. package/docs/principles/ux-principles.md +68 -0
  23. package/docs/tokens.md +53 -0
  24. package/package.json +13 -3
  25. package/src/UbieConfigProvider.tsx +7 -2
  26. package/src/components/ChatBubble/index.tsx +150 -0
  27. package/src/components/ChatConversations/index.tsx +38 -0
  28. package/src/components/Table/index.tsx +167 -0
  29. package/src/index.ts +17 -0
  30. package/src/reference/driftCheck.ts +145 -0
  31. package/src/stories/business/Chat.stories.tsx +119 -0
  32. package/src/stories/business/Icon.stories.tsx +153 -0
  33. package/src/stories/business/Table.stories.tsx +437 -0
  34. package/src/stories/business/Typography.stories.tsx +133 -0
  35. package/src/stories/components/Table.stories.tsx +4 -1
  36. package/src/stories/components/UbieConfigProvider.stories.tsx +1 -1
  37. package/src/stories/patterns/Disclosure.stories.tsx +192 -0
  38. package/src/stories/patterns/ListDetail.stories.tsx +259 -0
  39. package/src/stories/patterns/Skeleton.stories.tsx +147 -0
  40. package/src/theme/businessTheme.ts +89 -0
  41. package/src/theme/businessTypography.ts +69 -0
  42. package/.storybook/main.ts +0 -23
  43. package/.storybook/preview.tsx +0 -37
  44. package/.storybook/vitest.setup.ts +0 -6
  45. package/tsconfig.json +0 -9
  46. package/vite.config.ts +0 -32
package/CHANGELOG.md CHANGED
@@ -1,5 +1,121 @@
1
1
  # @ubie/vitals-ui-business
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 990c270: Table の行クリック遷移を廃止し、行内アクションを常時表示既定にする(**破壊的変更**)
8
+
9
+ - **削除**: `onRowClick`。行全体をクリックの的にすると、どこがクリッカブルかが見た目に現れない。遷移は識別列のリンク(実装は `next/link` / `<a>` / `Button type="link"` / `Typography.Link` のいずれでもよい)か、行内アクションの遷移ボタンで示す。行全体クリックがどうしても要る場合は antd の `onRow` を自分で書く
10
+ - **削除**: `data-row-action` 属性による行クリック除外機構。行クリックが無くなったので不要
11
+ - **リネーム + 挙動変更**: `hoverActions` → `rowActions`。**既定が常時表示に変わる**。hover 中だけ見せたい場合は `revealOnHover` を足す
12
+ - **追加**: `revealOnHover`。行内アクションを hover / フォーカス中の行だけに見せる(`disableHoverEffect` と併用したときは常時表示に倒れる)
13
+ - **追加**: `Table` のセルの文字サイズを **14px に固定**した(`businessTheme` の `Table.cellFontSize` /
14
+ `cellFontSizeMD` / `cellFontSizeSM`)。ToB の本文は 16px(main の `businessTypography`)だが、一覧は多くの行を
15
+ 見比べる面なので密度を優先し、本文と切り離す
16
+ - **注意**: 表の中のリンク・ボタン(`Button`)は antd のグローバル `fontSize` から文字サイズを取るため、
17
+ 何もしないと 16px のままになる。表の中では `style={{ fontSize: "inherit" }}` を当てて表の文字サイズを継がせる
18
+ (`Tag` は `fontSizeSM` を自前で持つため対象外)
19
+ - ルール(遷移手段の選び方・`revealOnHover` を使ってよい 3 条件・セル最低幅の目安)は `docs/components/table.md` に書いた
20
+
21
+ 移行:
22
+
23
+ | before | after |
24
+ | ----------------------------- | ------------------------------------------------------------------------------------------ |
25
+ | `onRowClick={r => open(r)}` | 識別列を `render` でリンクにする、または `rowActions` に遷移ボタンを置く |
26
+ | `hoverActions={r => ...}` | `rowActions={r => ...}`(常時表示に変わる)。hover のままにするなら `revealOnHover` を足す |
27
+ | セル内の `data-row-action=""` | 削除する |
28
+
29
+ - aee9c7e: ToB 共通の文字設定 `businessTypography` を追加し、`businessTheme.token` に展開する。
30
+
31
+ これまで `businessTheme` は `@ubie/vitals-antd-theme` の色だけを引き継ぎ、文字は antd 既定(14px 基準・欧文フォント優先)のままだった。文字の正本は toC(`@ubie/vitals-token-consumer`)と ToB で分かれるため、ToB の値はこのパッケージが持つ。
32
+
33
+ | キー | 値 |
34
+ | --------------------- | ------------------------------------------------------------------------------------------- |
35
+ | `fontFamily` | システム UI フォント → Hiragino → Noto Sans JP → Meiryo の順の和文対応スタック |
36
+ | `fontSize` | `16`(antd 既定 14 から変更。`fontSizeSM` 14 / `fontSizeLG` 18 / `fontSizeXL` 22 は派生) |
37
+ | `fontSizeHeading1〜5` | `24` / `20` / `18` / `16` / `14`(antd の自動派生 42〜18 は業務画面には大きすぎるため明示) |
38
+ | `lineHeight` 系 | 本文 `1.6`(SM / LG 含む)、見出し `1.5` |
39
+
40
+ 見出しの上限を 24px にした根拠は aimon-genius-fe(MedG)main の調査による。画面 UI に 28px 以上の見出しは無く(font-size 28px は印刷帳票の CSS 直書き 3 箇所のみ)、`Typography.Title` level 1 は 1 箇所で自前 20px 上書き、画面タイトルは level 2 が主流(9 箇所)だった。
41
+
42
+ 利用側への影響: `UbieConfigProvider` 配下のすべての antd コンポーネントの文字が 14px → 16px 基準になる。`Typography.Title` は antd 既定の 38 / 30 / 24 / 20 / 16 から 24 / 20 / 18 / 16 / 14 になり、level 2 を画面タイトルに使っている画面は 30px → 20px と小さくなる。個別に `fontSize` を上書きしている箇所は、この既定で足りるなら削除できる。値を戻したい場合は `ConfigProvider` の `theme.token` で差分だけ上書きする。
43
+
44
+ 新規 export: `businessTypography` / `businessFontFamily` / `businessFontSizes` / `businessLineHeights`。Storybook に `Business/Typography`(スケール・コントロール内・Table 内)を追加。
45
+
46
+ - d72f499: `@ant-design/icons` を再エクスポートし、ToB の既定のアイコンセットにする
47
+
48
+ - アイコンは `@ubie/vitals-ui-business` から import する(`@ant-design/icons` を利用側の依存に足さない)
49
+ - 自前 SVG を渡す基底コンポーネントは `Icon` として公開(`@ant-design/icons` の default export)
50
+ - 原則 `*Outlined` のみを使う。塗りが要るときは Outlined を容器に載せるか `Icon` + 自前 SVG で作る(線と塗りを別の色として持てるため)。`*Filled` は Outlined + 容器で表現できないときだけ、`*TwoTone` は使わない
51
+ - `@ubie/vitals-icon`(ubie-icons)は `@ant-design/icons` に絵柄が無いときの受け皿。UI Business の依存には入らないので、必要なプロダクトが個別に足す
52
+ - 用法: `docs/components/icon.md`(Storybook `Business/Icon`)。決定: ADR 0004
53
+
54
+ 追加した export: `@ant-design/icons` の全アイコンと `Icon` / `IconProvider` / `createFromIconfontCN` / `setTwoToneColor` / `getTwoToneColor`。削除・リネームは無し。
55
+
56
+ ### Patch Changes
57
+
58
+ - Updated dependencies [25d839c]
59
+ - @ubie/vitals-antd-theme@0.0.11
60
+
61
+ ## 0.3.0
62
+
63
+ ### Minor Changes
64
+
65
+ - 81fe319: ToB プロダクト共通のテーマ `businessTheme` を追加し、`UbieConfigProvider` が既定で適用するようになります。
66
+
67
+ - `businessTheme`: `@ubie/vitals-antd-theme` の `antdTheme` を基底に、`Layout`(`bodyBg` / `footerBg` / `headerBg`)と `Table`(`rowHoverBg` / `cellPaddingBlockSM`)の共通既定を足したもの。公開 API として export します
68
+ - `UbieConfigProvider` を使っている画面では、Layout の背景色と Table の行 hover 色・small 密度の余白が変わります。差分は従来どおり `theme` prop で上書きできます
69
+ - `ConfigProvider` を直接使っている場合は `{ ...businessTheme, components: { ...businessTheme.components, ... } }` のように差分だけを重ねてください
70
+ - 入口となる `DESIGN.md` と `docs/tokens.md`、Storybook の stories(カードの実演)を配布物に含めます。`.storybook/` とテストファイルは配布物から外れます
71
+
72
+ 背景と判断の根拠は https://github.com/ubie-inc/ubie-vitals/blob/main/docs/adr/0003-reference-layer-and-business-components-in-ui-business.md を参照してください。
73
+
74
+ - ea58c27: チャット部品 `ChatBubble` / `ChatConversations` を追加します。`ChatBubble` は `@ant-design/x` の `Bubble` の superset で、`evidence` / `timestamp` / `timestampFormat` / `onRetry` / `retryLabel` を利用側の `footer` / `extra` を潰さず合成します。`ChatConversations` は `Conversations` の superset で、`items` が空のときの `emptyState`(既定は antd の `Empty`)を足します。
75
+
76
+ どちらも `ref` を宣言して `Bubble` / `Conversations` に明示的に渡します(`BubbleProps` / `ConversationsProps` に `ref` の宣言が無く、そのままでは型で受け付けられないため)。`emptyState` は `evidence.node` と同じ契約で、未指定なら既定の `Empty`、`null` なら何も描かない、`0` や `""` のような falsy な `ReactNode` はそのまま描きます。
77
+
78
+ これに伴い、未 publish(`private: true`)だった `@ubie/vitals-antd-chat` パッケージを削除しました。固有の挙動を持っていた `UbieChatBubble` / `UbieChatConversations` は上記のとおり `ui-business` に移し、素通しラッパーだった `UbieChatSender` と専用の `UbieChatProvider` は移送せず、`Sender` の再 export と `UbieConfigProvider` + `XProvider` の組み合わせに委ねます。未 publish のため利用側への影響はありません。
79
+
80
+ `docs/components/chat.md` と Storybook の `Business/Chat` を追加しました。
81
+
82
+ - 8037ee0: `Table` を追加します。`@ubie/vitals-ui-business` の `Table` は antd `Table` の superset で、`onRowClick`(行内の `data-row-action` 要素からのクリックは除外)・`hoverActions`(hover 中の行だけに描く行内アクション)・`disableHoverEffect` を足し、`size` の既定を `small` にします。antd の `Table` をそのまま使いたい場合は `size` を明示してください。
83
+
84
+ Table / Layout のコンポーネントカード(`docs/components/`)と画面骨格 5 型のパターンカード(`docs/patterns/skeleton.md`)、Storybook の `Business/Table` と `Patterns/Skeleton` を追加します。
85
+
86
+ `TableProps` 型も同名でシャドウされます(antd の `TableProps` と同じく型引数を省略できます)。
87
+
88
+ ### Patch Changes
89
+
90
+ - 7eb8a58: publish される `package.json` から `development` export 条件を除外する。
91
+
92
+ これまで publish 後の `exports` は `development` 条件が先頭にあり、TS ソース(`./src/index.ts`)を直接指していた。条件付き exports はキーの順に評価されるため、この条件を有効にするツール(Next.js の dev ビルドなど)では常に `src/index.ts` が解決される。consumer が bundler 側で transpile を設定していないと、素の TS を parse できずに落ちる。
93
+
94
+ ```
95
+ Module parse failed: Unexpected token
96
+ > export type { UbieConfigProviderProps } from "./UbieConfigProvider";
97
+ ```
98
+
99
+ 本番ビルドは `require` / `import` 条件から `dist` を読むため再現せず、CI の Build も通る。結果として consumer のローカル開発でだけ壊れる。
100
+
101
+ `publishConfig.exports` で publish 時のみ `development` を落とす。リポジトリ内の `exports` はそのままなので、`examples/*` と Storybook が `src` を直接読む開発体験は変わらない。
102
+
103
+ consumer 側では、この 3 パッケージのために入れていた `transpilePackages`(Next.js)や同等の transpile 設定が不要になる。
104
+
105
+ - 420df47: 開示パターンのカードと Modal / Drawer のカードを追加しました。docs のみの変更で、実装・公開 API に変更はありません。
106
+ - 19e5920: 情報設計の原則を追加。8 原則の P2 / P6 を、名詞 → 動詞・モードレス既定・ナビは地面などの語彙で具体化する。
107
+ - ecc18ae: 一覧と詳細のパターンカードと Storybook の実演(`Patterns/ListDetail`)を追加し、DESIGN.md の索引を仕上げました。公開 API に変更はありません。
108
+ - 68adaa5: 体験設計原則(P1〜P8)と採点の枠を `docs/principles/` に追加
109
+ - ef5dc06: `DESIGN.md` の書き方を見直しました。docs のみの変更で、実装・公開 API に変更はありません。
110
+
111
+ - 「参照層」「素材層」「業務版」「同名シャドウ」「別名複合」「相」といった、設計議論で作った語を `DESIGN.md` から外しました。これらを読んだ人とエージェントがその語で喋りはじめ、語を知らない相手が戸惑うためです
112
+ - 語彙を「業務」から「ToB」に寄せました。コード側の識別子(`ui-business` / `businessTheme` / Storybook の `Business/`)は `business` のままです
113
+ - コンポーネントを索引に載せる手順・ADR の扱いといった維持する側の情報を `DESIGN.md` から `CONTRIBUTING.md` に移しました(`CONTRIBUTING.md` は配布物に含まれません)
114
+ - ADR へのリンクを `DESIGN.md` の索引から外しました。決定の経緯は利用時に必要ないためです
115
+
116
+ - Updated dependencies [7eb8a58]
117
+ - @ubie/vitals-antd-theme@0.0.10
118
+
3
119
  ## 0.2.1
4
120
 
5
121
  ### Patch Changes
@@ -10,7 +126,7 @@
10
126
 
11
127
  影響は `UbieConfigProvider` を適用している範囲に閉じます。`@ubie/vitals-token` の `color.primary` / `--color-primary` は変更していないため、`@ubie/vitals-token-consumer` や `@ubie/vitals-shadcn-theme` を利用しているプロダクトには影響しません。
12
128
 
13
- 背景と判断の根拠は `docs/adr/0002-business-primary-color-seed.md` を参照してください。0.0.1 から上げる場合は `docs/migration/from-0.0.1.md` も必ず読んでください。
129
+ 背景と判断の根拠は https://github.com/ubie-inc/ubie-vitals/blob/main/docs/adr/0002-business-primary-color-seed.md を参照してください。0.0.1 から上げる場合は https://github.com/ubie-inc/ubie-vitals/blob/main/docs/migration/from-0.0.1.md も必ず読んでください。
14
130
 
15
131
  - Updated dependencies [b425e42]
16
132
  - Updated dependencies [4b6b9bb]
package/DESIGN.md ADDED
@@ -0,0 +1,75 @@
1
+ # @ubie/vitals-ui-business
2
+
3
+ Ubie の ToB プロダクトを antd で組み立てるためのパッケージ。
4
+ antd と Ant Design X の公開 API をそのまま再 export し、共通のテーマと、既定を足したコンポーネントを加える。
5
+ この文書は最初に読む索引で、原則・パターン・部品・トークンの在処を指す。
6
+
7
+ ## 使うときの約束
8
+
9
+ - `antd` から直接ではなく `@ubie/vitals-ui-business` から import する
10
+ - アイコンは `@ant-design/icons` の `*Outlined` から選ぶ。`@ant-design/icons` を直接 import しない。塗りが要るときと、antd に絵柄が無いとき(`@ubie/vitals-icon`)の落とし方は `docs/components/icon.md`
11
+ - 色・寸法の値をプロダクトのコードに書かない。正本はトークンとテーマにある(`docs/tokens.md`)
12
+ - アプリ固有の逸脱は、そのプロダクトのリポジトリに書く
13
+
14
+ ## 何をするときに何を読むか
15
+
16
+ | したいこと | 読むもの |
17
+ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
18
+ | プロダクトを立ち上げる | 下の「立ち上げ」 |
19
+ | 画面を 1 枚足す | 骨格は `docs/patterns/skeleton.md` → 一覧と詳細の関係は `docs/patterns/list-detail.md` → 情報の出し方は `docs/patterns/disclosure.md` |
20
+ | 部品の使い方を確かめる | `docs/components/`(Table / Layout / Modal / Drawer / チャット / アイコン) |
21
+ | アイコンを選ぶ | `docs/components/icon.md` |
22
+ | 色・寸法を決める | `docs/tokens.md` |
23
+ | 設計や実装を見直す・採点する | `docs/principles/` |
24
+
25
+ ## 索引
26
+
27
+ ### テーマ
28
+
29
+ | 名前 | 場所 | 役割 |
30
+ | -------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
31
+ | `businessTheme` | `src/theme/businessTheme.ts` | ToB プロダクト共通の antd テーマ。`antdTheme` の token 層(色)+ `businessTypography`(文字)+ Layout / Table の components 既定 |
32
+ | `businessTypography` | `src/theme/businessTypography.ts` | ToB の文字の正本。書体スタック・本文 16px 基準の見出しスケール・行間。toC の `@ubie/vitals-token-consumer` とは正本が別 |
33
+ | `UbieConfigProvider` | `src/UbieConfigProvider.tsx` | `businessTheme` を既定で当てる ConfigProvider。利用側の `theme` は差分として重なる |
34
+
35
+ ### コンポーネント
36
+
37
+ antd の同名コンポーネントに既定を足したもの、および antd に対応物がない部品。
38
+
39
+ | 名前 | 場所 | antd との差分 | カード |
40
+ | ------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------- |
41
+ | `Table` | `src/components/Table/index.tsx` | `rowActions` / `revealOnHover` / `disableHoverEffect`、`size="small"` 既定 | `docs/components/table.md` |
42
+ | `ChatBubble` | `src/components/ChatBubble/index.tsx` | `evidence` / `timestamp` / `timestampFormat` / `onRetry` / `retryLabel` を `footer` / `extra` に合成 | `docs/components/chat.md` |
43
+ | `ChatConversations` | `src/components/ChatConversations/index.tsx` | `emptyState`(未指定なら antd の `Empty`) | `docs/components/chat.md` |
44
+
45
+ ### 文書
46
+
47
+ | 文書 | 場所 |
48
+ | --------------------------- | --------------------------------------- |
49
+ | 体験設計の 8 原則と採点の枠 | `docs/principles/README.md` |
50
+ | 情報設計の原則 | `docs/principles/information-design.md` |
51
+ | トークンの優先順位 | `docs/tokens.md` |
52
+ | Table カード | `docs/components/table.md` |
53
+ | 画面骨格 5 型 | `docs/patterns/skeleton.md` |
54
+ | 情報の開示パターン | `docs/patterns/disclosure.md` |
55
+ | 一覧と詳細 | `docs/patterns/list-detail.md` |
56
+ | Layout カード | `docs/components/layout.md` |
57
+ | Modal カード | `docs/components/modal.md` |
58
+ | Drawer カード | `docs/components/drawer.md` |
59
+ | チャット | `docs/components/chat.md` |
60
+ | Icon カード | `docs/components/icon.md` |
61
+
62
+ ### 描画カタログ
63
+
64
+ Storybook: https://ubie-inc.github.io/ubie-vitals/ui-business (main への push で更新)
65
+ コンポーネントは Storybook の "Business/" グループ、パターンの実演は "Patterns/" グループにある。
66
+
67
+ - コンポーネント: `src/stories/business/Table.stories.tsx`・`src/stories/business/Chat.stories.tsx`・`src/stories/business/Icon.stories.tsx`
68
+ - パターンの実演: `src/stories/patterns/Skeleton.stories.tsx`・`src/stories/patterns/Disclosure.stories.tsx`・`src/stories/patterns/ListDetail.stories.tsx`
69
+
70
+ ## 立ち上げ
71
+
72
+ 1. 依存を入れる: `pnpm add @ubie/vitals-ui-business react react-dom`
73
+ 2. アプリの最上位を `UbieConfigProvider` で包む。`antd` ではなく `@ubie/vitals-ui-business` から import する
74
+ 3. アプリ固有のテーマ差分(ヘッダー高さなど)は `UbieConfigProvider` の `theme` に差分だけ渡す。書き方は `docs/tokens.md`
75
+ 4. 骨格は `docs/patterns/skeleton.md` の 5 型から選ぶ。一覧と詳細の組み立ては `docs/patterns/list-detail.md`、情報の出し方は `docs/patterns/disclosure.md`、部品の用法は `docs/components/` にある
package/dist/index.cjs CHANGED
@@ -1,12 +1,168 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let _ant_design_icons = require("@ant-design/icons");
25
+ _ant_design_icons = __toESM(_ant_design_icons);
2
26
  let _ant_design_x = require("@ant-design/x");
3
27
  let antd = require("antd");
4
28
  let _ubie_vitals_antd_theme = require("@ubie/vitals-antd-theme");
5
29
  let react_jsx_runtime = require("react/jsx-runtime");
30
+ let react = require("react");
31
+ //#region ../token/dist/js/tokens.js
32
+ /**
33
+ * Do not edit directly, this file was auto-generated.
34
+ */
35
+ const ColorUbieBlue100 = "#f0f2fdff";
36
+ const ColorSurfaceContainer = "#ffffffff";
37
+ //#endregion
38
+ //#region src/theme/businessTypography.ts
39
+ /**
40
+ * ToB プロダクト共通の書体スタック。
41
+ *
42
+ * 欧文はシステム UI フォント(San Francisco / Segoe UI)に任せ、和文は Hiragino → Noto Sans JP → Meiryo の順で
43
+ * 拾う。toC の `@ubie/vitals-token-consumer` にも同趣旨の `text.base-family` があるが、あちらは toC の正本なので
44
+ * 依存せず、ToB の正本としてここに持つ。ブランド共通に昇格させる判断が出たら `@ubie/vitals-token` へ移す。
45
+ */
46
+ const businessFontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Hiragino Kaku Gothic ProN', 'Hiragino Sans', 'Noto Sans JP', Meiryo, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'";
47
+ /**
48
+ * ToB の文字スケール(px)。
49
+ *
50
+ * 基準は本文 16px(2026-09-09 デザイナー決定)。antd の既定 14px から基準を上げると、antd は見出しを
51
+ * 42 / 34 / 28 / 22 / 18 に自動で派生させるが、業務画面ではヘッダー・見出しが大きすぎるため
52
+ * 見出しはここで明示する。Figma 側に ToB の文字定義はまだ無く、この値が正本(Figma に定義ができたら差し替える)。
53
+ *
54
+ * 見出しの上限を 24px にした根拠(2026-09-09 aimon-genius-fe main を調査):
55
+ * - 画面 UI に 28px 以上の見出しは無い。font-size 28px は印刷帳票の CSS 直書き 3 箇所のみ
56
+ * - `Typography.Title` level 1 は 1 箇所だけで、しかも自前で 20px に上書きしている
57
+ * - 画面タイトルは level 2 が主流(9 箇所)。level 3 が 22、level 4 が 19、level 5 が 10 箇所
58
+ * よって H1 は「画面タイトルの最大」として 24px に置き、以下を 1 段ずつ詰める。
59
+ */
60
+ const businessFontSizes = {
61
+ /** 本文。antd はこの値から fontSizeSM (14) / fontSizeLG (18) / fontSizeXL (22) を派生させる */
62
+ fontSize: 16,
63
+ /** 画面タイトル。1 画面に 1 つ */
64
+ fontSizeHeading1: 24,
65
+ /** セクション見出し。現行 MedG の画面タイトルはこの level を使っている */
66
+ fontSizeHeading2: 20,
67
+ /** カード・パネルの見出し */
68
+ fontSizeHeading3: 18,
69
+ /** 本文と同サイズの見出し。太さだけで本文と区別する */
70
+ fontSizeHeading4: 16,
71
+ /** 表の中の小見出しなど。補足文字(fontSizeSM)と同サイズ */
72
+ fontSizeHeading5: 14
73
+ };
74
+ /**
75
+ * 行間(倍率)。
76
+ *
77
+ * 本文は和文の読みやすさで 1.6 を採る。toC は 1.7 だが、業務画面は 32px の入力欄・ボタンに 16px の文字を収めるため
78
+ * 1.7 では上下の余白が 2px 台まで詰まる。1.6 なら 25.6px で 3px 強の余白が残る。
79
+ * 見出しは行送りを詰めて塊として読めるよう 1.5 を採る。
80
+ */
81
+ const businessLineHeights = {
82
+ lineHeight: 1.6,
83
+ lineHeightSM: 1.6,
84
+ lineHeightLG: 1.6,
85
+ lineHeightHeading1: 1.5,
86
+ lineHeightHeading2: 1.5,
87
+ lineHeightHeading3: 1.5,
88
+ lineHeightHeading4: 1.5,
89
+ lineHeightHeading5: 1.5
90
+ };
91
+ /**
92
+ * ToB プロダクト共通の文字設定。`businessTheme.token` に展開される。
93
+ *
94
+ * `@ubie/vitals-antd-theme` は色だけを持ち、文字は持たない。文字は ToB / toC で正本が分かれるため
95
+ * antd-theme ではなくこのパッケージが持つ。
96
+ */
97
+ const businessTypography = {
98
+ fontFamily: businessFontFamily,
99
+ ...businessFontSizes,
100
+ ...businessLineHeights
101
+ };
102
+ //#endregion
103
+ //#region src/theme/businessTheme.ts
104
+ /**
105
+ * DS semantic をそのまま採る層。
106
+ *
107
+ * business 判断による上書きはここに置かず `businessComponentOverrides` に置く。
108
+ */
109
+ const semanticComponentTokens = { Layout: { headerBg: ColorSurfaceContainer } };
110
+ /**
111
+ * business 判断で DS semantic を採らない層。
112
+ *
113
+ * ここに置くものは必ず「なぜ DS semantic を使わないか」を書き、置き換えた semantic 候補を
114
+ * `overriddenSemanticCandidates` に登録する(登録漏れと陳腐化は businessTheme.test.ts が検知する)。
115
+ */
116
+ const businessComponentOverrides = {
117
+ Layout: {
118
+ bodyBg: ColorUbieBlue100,
119
+ footerBg: ColorUbieBlue100
120
+ },
121
+ Table: { rowHoverBg: ColorUbieBlue100 }
122
+ };
123
+ /**
124
+ * 色ではなく寸法・密度の既定。一覧画面は行数が多いため small 密度を共通既定にする。
125
+ */
126
+ const businessComponentMetrics = { Table: {
127
+ cellPaddingBlockSM: 6,
128
+ cellFontSize: 14,
129
+ cellFontSizeMD: 14,
130
+ cellFontSizeSM: 14
131
+ } };
132
+ /**
133
+ * ToB プロダクト共通の antd テーマ。
134
+ *
135
+ * token 層は `@ubie/vitals-antd-theme` の `antdTheme`(色)をそのまま引き継ぎ、
136
+ * ToB の文字設定(`businessTypography`)と business 共通の components 既定をここで足す。アプリ側は
137
+ * `{ ...businessTheme, components: { ...businessTheme.components, Layout: { ...businessTheme.components.Layout, headerHeight: 64 } } }`
138
+ * のように差分だけを上書きする。
139
+ */
140
+ const businessTheme = {
141
+ ..._ubie_vitals_antd_theme.antdTheme,
142
+ token: {
143
+ ..._ubie_vitals_antd_theme.antdTheme.token,
144
+ ...businessTypography
145
+ },
146
+ components: {
147
+ Layout: {
148
+ ...semanticComponentTokens.Layout,
149
+ ...businessComponentOverrides.Layout
150
+ },
151
+ Table: {
152
+ ...businessComponentOverrides.Table,
153
+ ...businessComponentMetrics.Table
154
+ }
155
+ }
156
+ };
157
+ //#endregion
6
158
  //#region src/UbieConfigProvider.tsx
159
+ /**
160
+ * ToB プロダクト共通のテーマ(businessTheme)を適用したうえで、利用側の ConfigProvider 設定を重ねる。
161
+ * 外側で businessTheme を当て、内側で利用側 props を渡すため、利用側の `theme` は差分として上書きされる。
162
+ */
7
163
  function UbieConfigProvider({ children, ...configProviderProps }) {
8
164
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.ConfigProvider, {
9
- theme: _ubie_vitals_antd_theme.antdTheme,
165
+ theme: businessTheme,
10
166
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.ConfigProvider, {
11
167
  ...configProviderProps,
12
168
  children
@@ -14,7 +170,200 @@ function UbieConfigProvider({ children, ...configProviderProps }) {
14
170
  });
15
171
  }
16
172
  //#endregion
173
+ //#region src/components/Table/index.tsx
174
+ const ROW_ACTIONS_COLUMN_KEY = "__rowActions";
175
+ function resolveRowKey(rowKey, record, index) {
176
+ if (typeof rowKey === "function") return rowKey(record, index);
177
+ const value = record[rowKey ?? "key"];
178
+ return typeof value === "string" || typeof value === "number" ? value : index;
179
+ }
180
+ /**
181
+ * ToB プロダクト共通の Table。antd Table の superset。
182
+ *
183
+ * - `size` の既定は `small`(`businessTheme` の `Table.cellPaddingBlockSM` と組で一覧画面の密度にする)
184
+ * - `rowActions` / `revealOnHover` / `disableHoverEffect` を足す。それ以外の props は antd にそのまま渡す
185
+ * - hover 状態は React state で持つ(CSS に依存しないので描画テストで検査できる)
186
+ *
187
+ * @displayName Table
188
+ */
189
+ function InternalTable(props) {
190
+ const { rowActions, revealOnHover = false, disableHoverEffect = false, onRow, columns, rowKey, size = "small", ref, ...rest } = props;
191
+ const [hoveredKey, setHoveredKey] = (0, react.useState)(null);
192
+ const revealEnabled = revealOnHover && !disableHoverEffect;
193
+ const trackHover = Boolean(rowActions) && revealEnabled;
194
+ const mergedColumns = (0, react.useMemo)(() => {
195
+ if (!rowActions) return columns;
196
+ const actionColumn = {
197
+ align: "right",
198
+ key: ROW_ACTIONS_COLUMN_KEY,
199
+ render: (_value, record, index) => {
200
+ return !revealEnabled || hoveredKey !== null && hoveredKey === resolveRowKey(rowKey, record, index) ? rowActions(record) : null;
201
+ },
202
+ title: ""
203
+ };
204
+ return [...columns ?? [], actionColumn];
205
+ }, [
206
+ columns,
207
+ hoveredKey,
208
+ revealEnabled,
209
+ rowActions,
210
+ rowKey
211
+ ]);
212
+ const mergedOnRow = (0, react.useCallback)((record, index) => {
213
+ const user = onRow?.(record, index) ?? {};
214
+ const rowIndex = index ?? 0;
215
+ return {
216
+ ...user,
217
+ onMouseEnter: (event) => {
218
+ user.onMouseEnter?.(event);
219
+ if (trackHover) setHoveredKey(resolveRowKey(rowKey, record, rowIndex));
220
+ },
221
+ onMouseLeave: (event) => {
222
+ user.onMouseLeave?.(event);
223
+ if (trackHover) setHoveredKey(null);
224
+ },
225
+ onFocus: (event) => {
226
+ user.onFocus?.(event);
227
+ if (trackHover) setHoveredKey(resolveRowKey(rowKey, record, rowIndex));
228
+ },
229
+ onBlur: (event) => {
230
+ user.onBlur?.(event);
231
+ if (!trackHover) return;
232
+ const related = event.relatedTarget;
233
+ if (related === null || !event.currentTarget.contains(related)) setHoveredKey(null);
234
+ },
235
+ style: user.style
236
+ };
237
+ }, [
238
+ trackHover,
239
+ onRow,
240
+ rowKey
241
+ ]);
242
+ const columnsProp = mergedColumns === void 0 ? {} : { columns: mergedColumns };
243
+ const rowKeyProp = rowKey === void 0 ? {} : { rowKey };
244
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Table, {
245
+ ...rest,
246
+ ...columnsProp,
247
+ ...rowKeyProp,
248
+ onRow: mergedOnRow,
249
+ ref,
250
+ size
251
+ });
252
+ }
253
+ const Table = Object.assign(InternalTable, {
254
+ Column: antd.Table.Column,
255
+ ColumnGroup: antd.Table.ColumnGroup,
256
+ Summary: antd.Table.Summary,
257
+ SELECTION_COLUMN: antd.Table.SELECTION_COLUMN,
258
+ EXPAND_COLUMN: antd.Table.EXPAND_COLUMN,
259
+ SELECTION_ALL: antd.Table.SELECTION_ALL,
260
+ SELECTION_INVERT: antd.Table.SELECTION_INVERT,
261
+ SELECTION_NONE: antd.Table.SELECTION_NONE
262
+ });
263
+ //#endregion
264
+ //#region src/components/ChatBubble/index.tsx
265
+ function defaultTimestampFormat(date) {
266
+ return `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
267
+ }
268
+ function renderEvidence(evidence) {
269
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Space, {
270
+ size: "small",
271
+ wrap: true,
272
+ children: (Array.isArray(evidence) ? evidence : [evidence]).map((e, i) => {
273
+ const key = `${e.label}-${i}`;
274
+ if (e.node !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: e.node }, key);
275
+ if (e.href) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
276
+ href: e.href,
277
+ target: "_blank",
278
+ rel: "noreferrer",
279
+ children: e.label
280
+ }, key);
281
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: e.label }, key);
282
+ })
283
+ });
284
+ }
285
+ /**
286
+ * ToB プロダクト共通の ChatBubble。`@ant-design/x` の Bubble の superset。
287
+ *
288
+ * - `evidence` / `onRetry` を footer に、`timestamp` を extra に足す。それぞれ利用側の
289
+ * `footer` / `extra` を潰さず合成する(`footer` / `extra` が関数形でも解決してから合成する)
290
+ * - timestamp の表示はテーマの `token.fontSizeSM` と `Typography.Text type="secondary"` の色を使う
291
+ * (値のコピーをしない)
292
+ */
293
+ function ChatBubble({ evidence, timestamp, timestampFormat = defaultTimestampFormat, onRetry, retryLabel = "リトライ", footer, extra, ref, ...rest }) {
294
+ const { token } = antd.theme.useToken();
295
+ const hasEvidence = Array.isArray(evidence) ? evidence.length > 0 : evidence !== void 0;
296
+ const composedFooter = hasEvidence || onRetry !== void 0 ? (content, info) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Space, {
297
+ size: "small",
298
+ wrap: true,
299
+ children: [
300
+ typeof footer === "function" ? footer(content, info) : footer,
301
+ hasEvidence && evidence !== void 0 && renderEvidence(evidence),
302
+ onRetry !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
303
+ onClick: onRetry,
304
+ size: "small",
305
+ type: "link",
306
+ children: retryLabel
307
+ })
308
+ ]
309
+ }) : footer;
310
+ const parsed = timestamp === void 0 ? void 0 : new Date(timestamp);
311
+ const timestampDate = parsed !== void 0 && !Number.isNaN(parsed.getTime()) ? parsed : void 0;
312
+ const composedExtra = timestampDate !== void 0 ? (content, info) => {
313
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Space, {
314
+ size: "small",
315
+ wrap: true,
316
+ children: [typeof extra === "function" ? extra(content, info) : extra, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Typography.Text, {
317
+ style: { fontSize: token.fontSizeSM },
318
+ type: "secondary",
319
+ children: timestampFormat(timestampDate)
320
+ })]
321
+ });
322
+ } : extra;
323
+ const refProp = ref === void 0 ? {} : { ref };
324
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_x.Bubble, {
325
+ ...rest,
326
+ ...refProp,
327
+ extra: composedExtra,
328
+ footer: composedFooter
329
+ });
330
+ }
331
+ //#endregion
332
+ //#region src/components/ChatConversations/index.tsx
333
+ /**
334
+ * ToB プロダクト共通の ChatConversations。`@ant-design/x` の Conversations の superset。
335
+ *
336
+ * - `items` が空(未指定または長さ 0)のときも `Conversations` は常に描く(`style` / `className` /
337
+ * `creation`(新規会話ボタン)/ `groupable` / `ref` など利用側の props を落とさないため)
338
+ * - 空のときは `Conversations`(中身は空リスト)に加えて `emptyState`(既定は `<Empty />`)を描く
339
+ * - `emptyState` の契約は `ChatBubbleEvidence.node` と揃える。未指定(`undefined`)なら既定の
340
+ * `<Empty />`、`null` なら何も描かない、`0` や `""` のような falsy な `ReactNode` はそのまま描く
341
+ */
342
+ function ChatConversations({ emptyState, items, ref, ...rest }) {
343
+ const isEmpty = !items || items.length === 0;
344
+ const emptyContent = emptyState !== void 0 ? emptyState : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Empty, {});
345
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_x.Conversations, {
346
+ items: items ?? [],
347
+ ref,
348
+ ...rest
349
+ }), isEmpty ? emptyContent : null] });
350
+ }
351
+ //#endregion
352
+ exports.ChatBubble = ChatBubble;
353
+ exports.ChatConversations = ChatConversations;
354
+ Object.defineProperty(exports, "Icon", {
355
+ enumerable: true,
356
+ get: function() {
357
+ return _ant_design_icons.default;
358
+ }
359
+ });
360
+ exports.Table = Table;
17
361
  exports.UbieConfigProvider = UbieConfigProvider;
362
+ exports.businessFontFamily = businessFontFamily;
363
+ exports.businessFontSizes = businessFontSizes;
364
+ exports.businessLineHeights = businessLineHeights;
365
+ exports.businessTheme = businessTheme;
366
+ exports.businessTypography = businessTypography;
18
367
  Object.defineProperty(exports, "notification", {
19
368
  enumerable: true,
20
369
  get: function() {
@@ -39,6 +388,14 @@ Object.defineProperty(exports, "xVersion", {
39
388
  return _ant_design_x.version;
40
389
  }
41
390
  });
391
+ Object.keys(_ant_design_icons).forEach(function(k) {
392
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
393
+ enumerable: true,
394
+ get: function() {
395
+ return _ant_design_icons[k];
396
+ }
397
+ });
398
+ });
42
399
  Object.keys(_ant_design_x).forEach(function(k) {
43
400
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
44
401
  enumerable: true,