@ubie/vitals-ui-business 0.2.0 → 0.3.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 (43) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/DESIGN.md +71 -0
  3. package/dist/index.cjs +275 -1
  4. package/dist/index.d.cts +269 -3
  5. package/dist/index.d.cts.map +1 -1
  6. package/dist/index.d.mts +269 -3
  7. package/dist/index.d.mts.map +1 -1
  8. package/dist/index.mjs +275 -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/layout.md +33 -0
  13. package/docs/components/modal.md +49 -0
  14. package/docs/components/table.md +60 -0
  15. package/docs/patterns/disclosure.md +114 -0
  16. package/docs/patterns/list-detail.md +71 -0
  17. package/docs/patterns/skeleton.md +48 -0
  18. package/docs/principles/README.md +21 -0
  19. package/docs/principles/information-design.md +94 -0
  20. package/docs/principles/scorecard.md +56 -0
  21. package/docs/principles/ux-principles.md +68 -0
  22. package/docs/tokens.md +48 -0
  23. package/package.json +12 -3
  24. package/src/UbieConfigProvider.tsx +7 -2
  25. package/src/components/ChatBubble/index.tsx +150 -0
  26. package/src/components/ChatConversations/index.tsx +38 -0
  27. package/src/components/Table/index.tsx +180 -0
  28. package/src/components/Table/rowAction.ts +25 -0
  29. package/src/index.ts +7 -0
  30. package/src/reference/driftCheck.ts +145 -0
  31. package/src/stories/business/Chat.stories.tsx +119 -0
  32. package/src/stories/business/Table.stories.tsx +236 -0
  33. package/src/stories/components/Table.stories.tsx +4 -1
  34. package/src/stories/components/UbieConfigProvider.stories.tsx +1 -1
  35. package/src/stories/patterns/Disclosure.stories.tsx +192 -0
  36. package/src/stories/patterns/ListDetail.stories.tsx +250 -0
  37. package/src/stories/patterns/Skeleton.stories.tsx +147 -0
  38. package/src/theme/businessTheme.ts +76 -0
  39. package/.storybook/main.ts +0 -23
  40. package/.storybook/preview.tsx +0 -37
  41. package/.storybook/vitest.setup.ts +0 -6
  42. package/tsconfig.json +0 -9
  43. package/vite.config.ts +0 -32
package/CHANGELOG.md CHANGED
@@ -1,5 +1,79 @@
1
1
  # @ubie/vitals-ui-business
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 81fe319: ToB プロダクト共通のテーマ `businessTheme` を追加し、`UbieConfigProvider` が既定で適用するようになります。
8
+
9
+ - `businessTheme`: `@ubie/vitals-antd-theme` の `antdTheme` を基底に、`Layout`(`bodyBg` / `footerBg` / `headerBg`)と `Table`(`rowHoverBg` / `cellPaddingBlockSM`)の共通既定を足したもの。公開 API として export します
10
+ - `UbieConfigProvider` を使っている画面では、Layout の背景色と Table の行 hover 色・small 密度の余白が変わります。差分は従来どおり `theme` prop で上書きできます
11
+ - `ConfigProvider` を直接使っている場合は `{ ...businessTheme, components: { ...businessTheme.components, ... } }` のように差分だけを重ねてください
12
+ - 入口となる `DESIGN.md` と `docs/tokens.md`、Storybook の stories(カードの実演)を配布物に含めます。`.storybook/` とテストファイルは配布物から外れます
13
+
14
+ 背景と判断の根拠は https://github.com/ubie-inc/ubie-vitals/blob/main/docs/adr/0003-reference-layer-and-business-components-in-ui-business.md を参照してください。
15
+
16
+ - ea58c27: チャット部品 `ChatBubble` / `ChatConversations` を追加します。`ChatBubble` は `@ant-design/x` の `Bubble` の superset で、`evidence` / `timestamp` / `timestampFormat` / `onRetry` / `retryLabel` を利用側の `footer` / `extra` を潰さず合成します。`ChatConversations` は `Conversations` の superset で、`items` が空のときの `emptyState`(既定は antd の `Empty`)を足します。
17
+
18
+ どちらも `ref` を宣言して `Bubble` / `Conversations` に明示的に渡します(`BubbleProps` / `ConversationsProps` に `ref` の宣言が無く、そのままでは型で受け付けられないため)。`emptyState` は `evidence.node` と同じ契約で、未指定なら既定の `Empty`、`null` なら何も描かない、`0` や `""` のような falsy な `ReactNode` はそのまま描きます。
19
+
20
+ これに伴い、未 publish(`private: true`)だった `@ubie/vitals-antd-chat` パッケージを削除しました。固有の挙動を持っていた `UbieChatBubble` / `UbieChatConversations` は上記のとおり `ui-business` に移し、素通しラッパーだった `UbieChatSender` と専用の `UbieChatProvider` は移送せず、`Sender` の再 export と `UbieConfigProvider` + `XProvider` の組み合わせに委ねます。未 publish のため利用側への影響はありません。
21
+
22
+ `docs/components/chat.md` と Storybook の `Business/Chat` を追加しました。
23
+
24
+ - 8037ee0: `Table` を追加します。`@ubie/vitals-ui-business` の `Table` は antd `Table` の superset で、`onRowClick`(行内の `data-row-action` 要素からのクリックは除外)・`hoverActions`(hover 中の行だけに描く行内アクション)・`disableHoverEffect` を足し、`size` の既定を `small` にします。antd の `Table` をそのまま使いたい場合は `size` を明示してください。
25
+
26
+ Table / Layout のコンポーネントカード(`docs/components/`)と画面骨格 5 型のパターンカード(`docs/patterns/skeleton.md`)、Storybook の `Business/Table` と `Patterns/Skeleton` を追加します。
27
+
28
+ `TableProps` 型も同名でシャドウされます(antd の `TableProps` と同じく型引数を省略できます)。
29
+
30
+ ### Patch Changes
31
+
32
+ - 7eb8a58: publish される `package.json` から `development` export 条件を除外する。
33
+
34
+ これまで publish 後の `exports` は `development` 条件が先頭にあり、TS ソース(`./src/index.ts`)を直接指していた。条件付き exports はキーの順に評価されるため、この条件を有効にするツール(Next.js の dev ビルドなど)では常に `src/index.ts` が解決される。consumer が bundler 側で transpile を設定していないと、素の TS を parse できずに落ちる。
35
+
36
+ ```
37
+ Module parse failed: Unexpected token
38
+ > export type { UbieConfigProviderProps } from "./UbieConfigProvider";
39
+ ```
40
+
41
+ 本番ビルドは `require` / `import` 条件から `dist` を読むため再現せず、CI の Build も通る。結果として consumer のローカル開発でだけ壊れる。
42
+
43
+ `publishConfig.exports` で publish 時のみ `development` を落とす。リポジトリ内の `exports` はそのままなので、`examples/*` と Storybook が `src` を直接読む開発体験は変わらない。
44
+
45
+ consumer 側では、この 3 パッケージのために入れていた `transpilePackages`(Next.js)や同等の transpile 設定が不要になる。
46
+
47
+ - 420df47: 開示パターンのカードと Modal / Drawer のカードを追加しました。docs のみの変更で、実装・公開 API に変更はありません。
48
+ - 19e5920: 情報設計の原則を追加。8 原則の P2 / P6 を、名詞 → 動詞・モードレス既定・ナビは地面などの語彙で具体化する。
49
+ - ecc18ae: 一覧と詳細のパターンカードと Storybook の実演(`Patterns/ListDetail`)を追加し、DESIGN.md の索引を仕上げました。公開 API に変更はありません。
50
+ - 68adaa5: 体験設計原則(P1〜P8)と採点の枠を `docs/principles/` に追加
51
+ - ef5dc06: `DESIGN.md` の書き方を見直しました。docs のみの変更で、実装・公開 API に変更はありません。
52
+
53
+ - 「参照層」「素材層」「業務版」「同名シャドウ」「別名複合」「相」といった、設計議論で作った語を `DESIGN.md` から外しました。これらを読んだ人とエージェントがその語で喋りはじめ、語を知らない相手が戸惑うためです
54
+ - 語彙を「業務」から「ToB」に寄せました。コード側の識別子(`ui-business` / `businessTheme` / Storybook の `Business/`)は `business` のままです
55
+ - コンポーネントを索引に載せる手順・ADR の扱いといった維持する側の情報を `DESIGN.md` から `CONTRIBUTING.md` に移しました(`CONTRIBUTING.md` は配布物に含まれません)
56
+ - ADR へのリンクを `DESIGN.md` の索引から外しました。決定の経緯は利用時に必要ないためです
57
+
58
+ - Updated dependencies [7eb8a58]
59
+ - @ubie/vitals-antd-theme@0.0.10
60
+
61
+ ## 0.2.1
62
+
63
+ ### Patch Changes
64
+
65
+ - 64f9d68: `UbieConfigProvider` が適用する primary 色が変わります(依存する `@ubie/vitals-antd-theme` の変更に追随したものです)。
66
+
67
+ primary を使うすべてのコンポーネント(Button / Switch / Radio / Checkbox / Table の選択行 / Tag / Menu の選択状態など)の色が影響を受けます。とくに、これまで灰色に潰れていた `colorPrimaryBg` 相当の淡色が、青みを持つ色に変わります。
68
+
69
+ 影響は `UbieConfigProvider` を適用している範囲に閉じます。`@ubie/vitals-token` の `color.primary` / `--color-primary` は変更していないため、`@ubie/vitals-token-consumer` や `@ubie/vitals-shadcn-theme` を利用しているプロダクトには影響しません。
70
+
71
+ 背景と判断の根拠は 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 も必ず読んでください。
72
+
73
+ - Updated dependencies [b425e42]
74
+ - Updated dependencies [4b6b9bb]
75
+ - @ubie/vitals-antd-theme@0.0.9
76
+
3
77
  ## 0.2.0
4
78
 
5
79
  ### Minor Changes
package/DESIGN.md ADDED
@@ -0,0 +1,71 @@
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
+ - 色・寸法の値をプロダクトのコードに書かない。正本はトークンとテーマにある(`docs/tokens.md`)
11
+ - アプリ固有の逸脱は、そのプロダクトのリポジトリに書く
12
+
13
+ ## 何をするときに何を読むか
14
+
15
+ | したいこと | 読むもの |
16
+ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
17
+ | プロダクトを立ち上げる | 下の「立ち上げ」 |
18
+ | 画面を 1 枚足す | 骨格は `docs/patterns/skeleton.md` → 一覧と詳細の関係は `docs/patterns/list-detail.md` → 情報の出し方は `docs/patterns/disclosure.md` |
19
+ | 部品の使い方を確かめる | `docs/components/`(Table / Layout / Modal / Drawer / チャット) |
20
+ | 色・寸法を決める | `docs/tokens.md` |
21
+ | 設計や実装を見直す・採点する | `docs/principles/` |
22
+
23
+ ## 索引
24
+
25
+ ### テーマ
26
+
27
+ | 名前 | 場所 | 役割 |
28
+ | -------------------- | ---------------------------- | --------------------------------------------------------------------------------------------- |
29
+ | `businessTheme` | `src/theme/businessTheme.ts` | ToB プロダクト共通の antd テーマ。`antdTheme` の token 層 + Layout / Table の components 既定 |
30
+ | `UbieConfigProvider` | `src/UbieConfigProvider.tsx` | `businessTheme` を既定で当てる ConfigProvider。利用側の `theme` は差分として重なる |
31
+
32
+ ### コンポーネント
33
+
34
+ antd の同名コンポーネントに既定を足したもの、および antd に対応物がない部品。
35
+
36
+ | 名前 | 場所 | antd との差分 | カード |
37
+ | ------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------- |
38
+ | `Table` | `src/components/Table/index.tsx` | `onRowClick` / `hoverActions` / `disableHoverEffect`、`size="small"` 既定 | `docs/components/table.md` |
39
+ | `ChatBubble` | `src/components/ChatBubble/index.tsx` | `evidence` / `timestamp` / `timestampFormat` / `onRetry` / `retryLabel` を `footer` / `extra` に合成 | `docs/components/chat.md` |
40
+ | `ChatConversations` | `src/components/ChatConversations/index.tsx` | `emptyState`(未指定なら antd の `Empty`) | `docs/components/chat.md` |
41
+
42
+ ### 文書
43
+
44
+ | 文書 | 場所 |
45
+ | --------------------------- | --------------------------------------- |
46
+ | 体験設計の 8 原則と採点の枠 | `docs/principles/README.md` |
47
+ | 情報設計の原則 | `docs/principles/information-design.md` |
48
+ | トークンの優先順位 | `docs/tokens.md` |
49
+ | Table カード | `docs/components/table.md` |
50
+ | 画面骨格 5 型 | `docs/patterns/skeleton.md` |
51
+ | 情報の開示パターン | `docs/patterns/disclosure.md` |
52
+ | 一覧と詳細 | `docs/patterns/list-detail.md` |
53
+ | Layout カード | `docs/components/layout.md` |
54
+ | Modal カード | `docs/components/modal.md` |
55
+ | Drawer カード | `docs/components/drawer.md` |
56
+ | チャット | `docs/components/chat.md` |
57
+
58
+ ### 描画カタログ
59
+
60
+ Storybook: https://ubie-inc.github.io/ubie-vitals/ui-business (main への push で更新)
61
+ コンポーネントは Storybook の "Business/" グループ、パターンの実演は "Patterns/" グループにある。
62
+
63
+ - コンポーネント: `src/stories/business/Table.stories.tsx`・`src/stories/business/Chat.stories.tsx`
64
+ - パターンの実演: `src/stories/patterns/Skeleton.stories.tsx`・`src/stories/patterns/Disclosure.stories.tsx`・`src/stories/patterns/ListDetail.stories.tsx`
65
+
66
+ ## 立ち上げ
67
+
68
+ 1. 依存を入れる: `pnpm add @ubie/vitals-ui-business react react-dom`
69
+ 2. アプリの最上位を `UbieConfigProvider` で包む。`antd` ではなく `@ubie/vitals-ui-business` から import する
70
+ 3. アプリ固有のテーマ差分(ヘッダー高さなど)は `UbieConfigProvider` の `theme` に差分だけ渡す。書き方は `docs/tokens.md`
71
+ 4. 骨格は `docs/patterns/skeleton.md` の 5 型から選ぶ。一覧と詳細の組み立ては `docs/patterns/list-detail.md`、情報の出し方は `docs/patterns/disclosure.md`、部品の用法は `docs/components/` にある
package/dist/index.cjs CHANGED
@@ -3,10 +3,67 @@ let _ant_design_x = require("@ant-design/x");
3
3
  let antd = require("antd");
4
4
  let _ubie_vitals_antd_theme = require("@ubie/vitals-antd-theme");
5
5
  let react_jsx_runtime = require("react/jsx-runtime");
6
+ let react = require("react");
7
+ //#region ../token/dist/js/tokens.js
8
+ /**
9
+ * Do not edit directly, this file was auto-generated.
10
+ */
11
+ const ColorUbieBlue100 = "#f0f2fdff";
12
+ //#endregion
13
+ //#region src/theme/businessTheme.ts
14
+ /**
15
+ * DS semantic をそのまま採る層。
16
+ *
17
+ * business 判断による上書きはここに置かず `businessComponentOverrides` に置く。
18
+ */
19
+ const semanticComponentTokens = { Layout: { headerBg: "#ffffffff" } };
20
+ /**
21
+ * business 判断で DS semantic を採らない層。
22
+ *
23
+ * ここに置くものは必ず「なぜ DS semantic を使わないか」を書き、置き換えた semantic 候補を
24
+ * `overriddenSemanticCandidates` に登録する(登録漏れと陳腐化は businessTheme.test.ts が検知する)。
25
+ */
26
+ const businessComponentOverrides = {
27
+ Layout: {
28
+ bodyBg: ColorUbieBlue100,
29
+ footerBg: ColorUbieBlue100
30
+ },
31
+ Table: { rowHoverBg: ColorUbieBlue100 }
32
+ };
33
+ /**
34
+ * 色ではなく寸法・密度の既定。一覧画面は行数が多いため small 密度を共通既定にする。
35
+ */
36
+ const businessComponentMetrics = { Table: { cellPaddingBlockSM: 6 } };
37
+ /**
38
+ * ToB プロダクト共通の antd テーマ。
39
+ *
40
+ * token 層は `@ubie/vitals-antd-theme` の `antdTheme` をそのまま引き継ぎ、
41
+ * business 共通の components 既定だけをここで足す。アプリ側は
42
+ * `{ ...businessTheme, components: { ...businessTheme.components, Layout: { ...businessTheme.components.Layout, headerHeight: 64 } } }`
43
+ * のように差分だけを上書きする。
44
+ */
45
+ const businessTheme = {
46
+ ..._ubie_vitals_antd_theme.antdTheme,
47
+ components: {
48
+ Layout: {
49
+ ...semanticComponentTokens.Layout,
50
+ ...businessComponentOverrides.Layout
51
+ },
52
+ Table: {
53
+ ...businessComponentOverrides.Table,
54
+ ...businessComponentMetrics.Table
55
+ }
56
+ }
57
+ };
58
+ //#endregion
6
59
  //#region src/UbieConfigProvider.tsx
60
+ /**
61
+ * ToB プロダクト共通のテーマ(businessTheme)を適用したうえで、利用側の ConfigProvider 設定を重ねる。
62
+ * 外側で businessTheme を当て、内側で利用側 props を渡すため、利用側の `theme` は差分として上書きされる。
63
+ */
7
64
  function UbieConfigProvider({ children, ...configProviderProps }) {
8
65
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.ConfigProvider, {
9
- theme: _ubie_vitals_antd_theme.antdTheme,
66
+ theme: businessTheme,
10
67
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.ConfigProvider, {
11
68
  ...configProviderProps,
12
69
  children
@@ -14,7 +71,224 @@ function UbieConfigProvider({ children, ...configProviderProps }) {
14
71
  });
15
72
  }
16
73
  //#endregion
74
+ //#region src/components/Table/rowAction.ts
75
+ /** 行内アクションであることを示す属性。この属性を持つ要素(とその子孫)のクリックは行クリックにしない。 */
76
+ const ROW_ACTION_ATTRIBUTE = "data-row-action";
77
+ /** クリック要素から行までの経路のどこかに行内アクションの印があるか。 */
78
+ function isRowActionTarget(path) {
79
+ return path.some((element) => element.hasAttribute(ROW_ACTION_ATTRIBUTE));
80
+ }
81
+ /**
82
+ * `target` から `boundary`(含まない)までの祖先列。
83
+ * `target` が `boundary` の外にあるときは空配列(イベントの再ターゲットや detached node に備える)。
84
+ */
85
+ function elementPath(target, boundary) {
86
+ const path = [];
87
+ let current = target;
88
+ while (current && current !== boundary) {
89
+ path.push(current);
90
+ current = current.parentElement;
91
+ }
92
+ return current === boundary ? path : [];
93
+ }
94
+ //#endregion
95
+ //#region src/components/Table/index.tsx
96
+ const HOVER_ACTIONS_COLUMN_KEY = "__hoverActions";
97
+ function resolveRowKey(rowKey, record, index) {
98
+ if (typeof rowKey === "function") return rowKey(record, index);
99
+ const value = record[rowKey ?? "key"];
100
+ return typeof value === "string" || typeof value === "number" ? value : index;
101
+ }
102
+ /**
103
+ * ToB プロダクト共通の Table。antd Table の superset。
104
+ *
105
+ * - `size` の既定は `small`(`businessTheme` の `Table.cellPaddingBlockSM` と組で一覧画面の密度にする)
106
+ * - `onRowClick` / `hoverActions` / `disableHoverEffect` を足す。それ以外の props は antd にそのまま渡す
107
+ * - hover 状態は React state で持つ(CSS に依存しないので描画テストで検査できる)
108
+ *
109
+ * @displayName Table
110
+ */
111
+ function InternalTable(props) {
112
+ const { onRowClick, hoverActions, disableHoverEffect = false, onRow, columns, rowKey, size = "small", ref, ...rest } = props;
113
+ const [hoveredKey, setHoveredKey] = (0, react.useState)(null);
114
+ const hoverEnabled = Boolean(hoverActions) && !disableHoverEffect;
115
+ const mergedColumns = (0, react.useMemo)(() => {
116
+ if (!hoverEnabled) return columns;
117
+ const hoverColumn = {
118
+ align: "right",
119
+ key: HOVER_ACTIONS_COLUMN_KEY,
120
+ render: (_value, record, index) => {
121
+ return hoverEnabled && hoveredKey !== null && hoveredKey === resolveRowKey(rowKey, record, index) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
122
+ [ROW_ACTION_ATTRIBUTE]: "",
123
+ children: hoverActions?.(record)
124
+ }) : null;
125
+ },
126
+ title: ""
127
+ };
128
+ return [...columns ?? [], hoverColumn];
129
+ }, [
130
+ columns,
131
+ hoverActions,
132
+ hoverEnabled,
133
+ hoveredKey,
134
+ rowKey
135
+ ]);
136
+ const mergedOnRow = (0, react.useCallback)((record, index) => {
137
+ const user = onRow?.(record, index) ?? {};
138
+ const rowIndex = index ?? 0;
139
+ return {
140
+ ...user,
141
+ onClick: (event) => {
142
+ user.onClick?.(event);
143
+ if (!onRowClick) return;
144
+ if (!event.currentTarget.contains(event.target)) return;
145
+ if (isRowActionTarget(elementPath(event.target, event.currentTarget))) return;
146
+ onRowClick(record, event);
147
+ },
148
+ onMouseEnter: (event) => {
149
+ user.onMouseEnter?.(event);
150
+ if (hoverEnabled) setHoveredKey(resolveRowKey(rowKey, record, rowIndex));
151
+ },
152
+ onMouseLeave: (event) => {
153
+ user.onMouseLeave?.(event);
154
+ if (hoverEnabled) setHoveredKey(null);
155
+ },
156
+ onFocus: (event) => {
157
+ user.onFocus?.(event);
158
+ if (hoverEnabled) setHoveredKey(resolveRowKey(rowKey, record, rowIndex));
159
+ },
160
+ onBlur: (event) => {
161
+ user.onBlur?.(event);
162
+ if (!hoverEnabled) return;
163
+ const related = event.relatedTarget;
164
+ if (related === null || !event.currentTarget.contains(related)) setHoveredKey(null);
165
+ },
166
+ style: onRowClick ? {
167
+ cursor: "pointer",
168
+ ...user.style
169
+ } : user.style
170
+ };
171
+ }, [
172
+ hoverEnabled,
173
+ onRow,
174
+ onRowClick,
175
+ rowKey
176
+ ]);
177
+ const columnsProp = mergedColumns === void 0 ? {} : { columns: mergedColumns };
178
+ const rowKeyProp = rowKey === void 0 ? {} : { rowKey };
179
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Table, {
180
+ ...rest,
181
+ ...columnsProp,
182
+ ...rowKeyProp,
183
+ onRow: mergedOnRow,
184
+ ref,
185
+ size
186
+ });
187
+ }
188
+ const Table = Object.assign(InternalTable, {
189
+ Column: antd.Table.Column,
190
+ ColumnGroup: antd.Table.ColumnGroup,
191
+ Summary: antd.Table.Summary,
192
+ SELECTION_COLUMN: antd.Table.SELECTION_COLUMN,
193
+ EXPAND_COLUMN: antd.Table.EXPAND_COLUMN,
194
+ SELECTION_ALL: antd.Table.SELECTION_ALL,
195
+ SELECTION_INVERT: antd.Table.SELECTION_INVERT,
196
+ SELECTION_NONE: antd.Table.SELECTION_NONE
197
+ });
198
+ //#endregion
199
+ //#region src/components/ChatBubble/index.tsx
200
+ function defaultTimestampFormat(date) {
201
+ return `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
202
+ }
203
+ function renderEvidence(evidence) {
204
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Space, {
205
+ size: "small",
206
+ wrap: true,
207
+ children: (Array.isArray(evidence) ? evidence : [evidence]).map((e, i) => {
208
+ const key = `${e.label}-${i}`;
209
+ if (e.node !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: e.node }, key);
210
+ if (e.href) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
211
+ href: e.href,
212
+ target: "_blank",
213
+ rel: "noreferrer",
214
+ children: e.label
215
+ }, key);
216
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: e.label }, key);
217
+ })
218
+ });
219
+ }
220
+ /**
221
+ * ToB プロダクト共通の ChatBubble。`@ant-design/x` の Bubble の superset。
222
+ *
223
+ * - `evidence` / `onRetry` を footer に、`timestamp` を extra に足す。それぞれ利用側の
224
+ * `footer` / `extra` を潰さず合成する(`footer` / `extra` が関数形でも解決してから合成する)
225
+ * - timestamp の表示はテーマの `token.fontSizeSM` と `Typography.Text type="secondary"` の色を使う
226
+ * (値のコピーをしない)
227
+ */
228
+ function ChatBubble({ evidence, timestamp, timestampFormat = defaultTimestampFormat, onRetry, retryLabel = "リトライ", footer, extra, ref, ...rest }) {
229
+ const { token } = antd.theme.useToken();
230
+ const hasEvidence = Array.isArray(evidence) ? evidence.length > 0 : evidence !== void 0;
231
+ const composedFooter = hasEvidence || onRetry !== void 0 ? (content, info) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Space, {
232
+ size: "small",
233
+ wrap: true,
234
+ children: [
235
+ typeof footer === "function" ? footer(content, info) : footer,
236
+ hasEvidence && evidence !== void 0 && renderEvidence(evidence),
237
+ onRetry !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
238
+ onClick: onRetry,
239
+ size: "small",
240
+ type: "link",
241
+ children: retryLabel
242
+ })
243
+ ]
244
+ }) : footer;
245
+ const parsed = timestamp === void 0 ? void 0 : new Date(timestamp);
246
+ const timestampDate = parsed !== void 0 && !Number.isNaN(parsed.getTime()) ? parsed : void 0;
247
+ const composedExtra = timestampDate !== void 0 ? (content, info) => {
248
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Space, {
249
+ size: "small",
250
+ wrap: true,
251
+ children: [typeof extra === "function" ? extra(content, info) : extra, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Typography.Text, {
252
+ style: { fontSize: token.fontSizeSM },
253
+ type: "secondary",
254
+ children: timestampFormat(timestampDate)
255
+ })]
256
+ });
257
+ } : extra;
258
+ const refProp = ref === void 0 ? {} : { ref };
259
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_x.Bubble, {
260
+ ...rest,
261
+ ...refProp,
262
+ extra: composedExtra,
263
+ footer: composedFooter
264
+ });
265
+ }
266
+ //#endregion
267
+ //#region src/components/ChatConversations/index.tsx
268
+ /**
269
+ * ToB プロダクト共通の ChatConversations。`@ant-design/x` の Conversations の superset。
270
+ *
271
+ * - `items` が空(未指定または長さ 0)のときも `Conversations` は常に描く(`style` / `className` /
272
+ * `creation`(新規会話ボタン)/ `groupable` / `ref` など利用側の props を落とさないため)
273
+ * - 空のときは `Conversations`(中身は空リスト)に加えて `emptyState`(既定は `<Empty />`)を描く
274
+ * - `emptyState` の契約は `ChatBubbleEvidence.node` と揃える。未指定(`undefined`)なら既定の
275
+ * `<Empty />`、`null` なら何も描かない、`0` や `""` のような falsy な `ReactNode` はそのまま描く
276
+ */
277
+ function ChatConversations({ emptyState, items, ref, ...rest }) {
278
+ const isEmpty = !items || items.length === 0;
279
+ const emptyContent = emptyState !== void 0 ? emptyState : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Empty, {});
280
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_x.Conversations, {
281
+ items: items ?? [],
282
+ ref,
283
+ ...rest
284
+ }), isEmpty ? emptyContent : null] });
285
+ }
286
+ //#endregion
287
+ exports.ChatBubble = ChatBubble;
288
+ exports.ChatConversations = ChatConversations;
289
+ exports.Table = Table;
17
290
  exports.UbieConfigProvider = UbieConfigProvider;
291
+ exports.businessTheme = businessTheme;
18
292
  Object.defineProperty(exports, "notification", {
19
293
  enumerable: true,
20
294
  get: function() {