@squadbase/vantage 0.6.2-dev1.ac99e02 → 0.6.2-dev1.d7c0911

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 (141) hide show
  1. package/dist/{build-MFWRPYKW.js → build-X5NVCQKT.js} +4 -4
  2. package/dist/{build-MFWRPYKW.js.map → build-X5NVCQKT.js.map} +1 -1
  3. package/dist/{chunk-IBGOCWJB.js → chunk-2ICNHUG6.js} +186 -82
  4. package/dist/chunk-2ICNHUG6.js.map +1 -0
  5. package/dist/{chunk-5ZOP4SQR.js → chunk-2N72FKLB.js} +12 -7
  6. package/dist/chunk-2N72FKLB.js.map +1 -0
  7. package/dist/{chunk-PXRX5PEC.js → chunk-PDOBHMUQ.js} +3 -3
  8. package/dist/chunk-PDOBHMUQ.js.map +1 -0
  9. package/dist/{chunk-A2UUGASH.js → chunk-U736PVHY.js} +2 -2
  10. package/dist/chunk-U736PVHY.js.map +1 -0
  11. package/dist/{chunk-QEWCYW3I.js → chunk-WAMZWZJB.js} +13 -3
  12. package/dist/chunk-WAMZWZJB.js.map +1 -0
  13. package/dist/chunk-WRSX2MDK.js +7866 -0
  14. package/dist/chunk-WRSX2MDK.js.map +1 -0
  15. package/dist/{chunk-OB6UBJXF.js → chunk-XPQSTZUU.js} +125 -35
  16. package/dist/chunk-XPQSTZUU.js.map +1 -0
  17. package/dist/cli.js +3 -3
  18. package/dist/components/index.d.ts +1831 -99
  19. package/dist/components/index.js +4 -4
  20. package/dist/{dev-DCTOHQ6W.js → dev-4XEDTELV.js} +4 -4
  21. package/dist/{dev-DCTOHQ6W.js.map → dev-4XEDTELV.js.map} +1 -1
  22. package/dist/doc/index.js +2 -2
  23. package/dist/doc/index.js.map +1 -1
  24. package/dist/markdown/index.js +1 -1
  25. package/dist/markdown/index.js.map +1 -1
  26. package/dist/table/index.js +5 -5
  27. package/dist/table/index.js.map +1 -1
  28. package/dist/ui/index.d.ts +4 -1
  29. package/dist/ui/index.js +21 -111
  30. package/dist/ui/index.js.map +1 -1
  31. package/dist/{upgrade-DBBE6GIR.js → upgrade-JHXZBGQS.js} +3 -3
  32. package/dist/{upgrade-DBBE6GIR.js.map → upgrade-JHXZBGQS.js.map} +1 -1
  33. package/dist/vite/index.js +2 -2
  34. package/docs/en/components.md +29 -15
  35. package/docs/en/parts/data-table.md +22 -0
  36. package/docs/en/parts/delta.md +50 -0
  37. package/docs/en/parts/format.md +43 -0
  38. package/docs/en/parts/kpi-card.md +57 -0
  39. package/docs/en/parts/metric-value.md +3 -2
  40. package/docs/en/parts/sparkline.md +1 -1
  41. package/docs/en/parts/trend-indicator.md +17 -1
  42. package/docs/en/ui-and-theming.md +1 -1
  43. package/docs/index.json +92 -32
  44. package/docs/ja/changelog.md +5 -0
  45. package/docs/ja/components.md +27 -15
  46. package/docs/ja/parts/data-table.md +22 -0
  47. package/docs/ja/parts/delta.md +50 -0
  48. package/docs/ja/parts/format.md +44 -0
  49. package/docs/ja/parts/kpi-card.md +55 -0
  50. package/docs/ja/parts/metric-value.md +3 -2
  51. package/docs/ja/parts/sparkline.md +1 -1
  52. package/docs/ja/parts/trend-indicator.md +17 -1
  53. package/docs/ja/ui-and-theming.md +2 -2
  54. package/package.json +2 -1
  55. package/registry/ui/accordion.tsx +4 -2
  56. package/registry/ui/alert-dialog.tsx +3 -3
  57. package/registry/ui/alert.tsx +3 -1
  58. package/registry/ui/app-shell.tsx +7 -1
  59. package/registry/ui/area-chart.tsx +2781 -157
  60. package/registry/ui/avatar.tsx +1 -1
  61. package/registry/ui/badge.tsx +3 -1
  62. package/registry/ui/bar-chart.tsx +2780 -157
  63. package/registry/ui/bar-list.tsx +3471 -93
  64. package/registry/ui/breadcrumb.tsx +3 -1
  65. package/registry/ui/button.tsx +3 -1
  66. package/registry/ui/calendar.tsx +3 -1
  67. package/registry/ui/card.tsx +4 -2
  68. package/registry/ui/category-bar.tsx +990 -16
  69. package/registry/ui/chart-frame.tsx +1358 -0
  70. package/registry/ui/checkbox.tsx +3 -1
  71. package/registry/ui/collapsible.tsx +3 -1
  72. package/registry/ui/combobox.tsx +2 -2
  73. package/registry/ui/command.tsx +3 -1
  74. package/registry/ui/dashboard-card.tsx +69 -26
  75. package/registry/ui/data-table.tsx +678 -56
  76. package/registry/ui/date-range-picker.tsx +245 -64
  77. package/registry/ui/delta.tsx +188 -0
  78. package/registry/ui/dialog.tsx +5 -3
  79. package/registry/ui/donut-chart.tsx +2857 -173
  80. package/registry/ui/drawer.tsx +1 -1
  81. package/registry/ui/dropdown-menu.tsx +5 -3
  82. package/registry/ui/echart.tsx +448 -44
  83. package/registry/ui/field.tsx +1 -1
  84. package/registry/ui/filter-bar.tsx +33 -6
  85. package/registry/ui/funnel-steps.tsx +3316 -49
  86. package/registry/ui/heatmap.tsx +1752 -0
  87. package/registry/ui/hover-card.tsx +2 -2
  88. package/registry/ui/input-group.tsx +3 -1
  89. package/registry/ui/input.tsx +3 -1
  90. package/registry/ui/kbd.tsx +3 -1
  91. package/registry/ui/kpi-card.tsx +677 -0
  92. package/registry/ui/label.tsx +3 -1
  93. package/registry/ui/legend.tsx +3500 -0
  94. package/registry/ui/line-chart.tsx +2781 -151
  95. package/registry/ui/metric-value.tsx +9 -1
  96. package/registry/ui/multi-select.tsx +11 -5
  97. package/registry/ui/page-shell.tsx +104 -49
  98. package/registry/ui/pagination.tsx +3 -1
  99. package/registry/ui/placeholder.tsx +8 -2
  100. package/registry/ui/popover.tsx +4 -2
  101. package/registry/ui/progress-circle.tsx +607 -12
  102. package/registry/ui/progress.tsx +3 -1
  103. package/registry/ui/radio-group.tsx +1 -1
  104. package/registry/ui/sample-data.tsx +86 -0
  105. package/registry/ui/scatter-chart.tsx +4150 -0
  106. package/registry/ui/scroll-area.tsx +3 -2
  107. package/registry/ui/searchable-select.tsx +8 -3
  108. package/registry/ui/section-header.tsx +4 -2
  109. package/registry/ui/segmented-control.tsx +7 -2
  110. package/registry/ui/select.tsx +4 -2
  111. package/registry/ui/separator.tsx +3 -1
  112. package/registry/ui/sheet.tsx +4 -2
  113. package/registry/ui/sidebar.tsx +4 -2
  114. package/registry/ui/skeleton.tsx +4 -2
  115. package/registry/ui/slider.tsx +3 -1
  116. package/registry/ui/sparkline.tsx +84 -9
  117. package/registry/ui/spinner.tsx +3 -1
  118. package/registry/ui/states.tsx +34 -5
  119. package/registry/ui/status-badge.tsx +81 -39
  120. package/registry/ui/switch.tsx +3 -1
  121. package/registry/ui/table.tsx +4 -2
  122. package/registry/ui/tabs.tsx +5 -3
  123. package/registry/ui/textarea.tsx +3 -1
  124. package/registry/ui/toast.tsx +2 -2
  125. package/registry/ui/toggle-group.tsx +3 -1
  126. package/registry/ui/toggle.tsx +3 -1
  127. package/registry/ui/tooltip.tsx +4 -2
  128. package/registry/ui/tracker.tsx +624 -17
  129. package/registry/ui/trend-indicator.tsx +13 -1
  130. package/registry/ui/updated-at.tsx +122 -0
  131. package/registry/ui/waterfall-chart.tsx +4186 -0
  132. package/templates/AGENTS.md +13 -1
  133. package/theme.css +237 -136
  134. package/dist/chunk-5ZOP4SQR.js.map +0 -1
  135. package/dist/chunk-A2UUGASH.js.map +0 -1
  136. package/dist/chunk-AG6RZ2RR.js +0 -3208
  137. package/dist/chunk-AG6RZ2RR.js.map +0 -1
  138. package/dist/chunk-IBGOCWJB.js.map +0 -1
  139. package/dist/chunk-OB6UBJXF.js.map +0 -1
  140. package/dist/chunk-PXRX5PEC.js.map +0 -1
  141. package/dist/chunk-QEWCYW3I.js.map +0 -1
@@ -46,6 +46,11 @@ Vantage のリリースごとの変更点です。新しいものが上に来ま
46
46
  持たないのに、ブラウザのタイムゾーンで表示していたため、UTC より西(アメリカなど)では
47
47
  `2026-06-02` が `6/1` と前日に、時刻付きのセルは UTC より東(日本など)でも夜の時刻が翌日に
48
48
  ずれていました。いまはどのタイムゾーンでもファイルに書かれた日付・時刻のまま表示します。
49
+ - **ドキュメント(`.doc.tsx`)を画面で見るとき、本文が画面の端に付かなくなりました。** 画面表示用の
50
+ 余白が無かったため、表示幅が本文の幅(`--doc-max-width`、既定 48rem)より狭いと本文が左右の端に
51
+ 付き、見出しもヘッダーのすぐ下から始まっていました。いまは左右に 1.5rem、上に 3rem、下に 5rem の
52
+ 余白を取ります。下を広めにしているのは、右下の「PDF として保存」ボタンに最後の行が隠れないように
53
+ するためです。広い画面での本文の幅と、印刷の見た目は変わりません。
49
54
 
50
55
  ## v0.6.2
51
56
 
@@ -30,6 +30,7 @@ import { MarkdownRenderer } from "@squadbase/vantage/markdown";
30
30
  | [`Badge`](ui/badge) / [`StatusBadge`](parts/status-badge) | 件数やタグなど**ただのラベル**は `Badge`。`active` / `failed` のような**レコードの状態**を色付きドットで示すなら `StatusBadge`(色は状態名から自動で決まる)。 |
31
31
  | [`ToggleGroup`](ui/toggle-group) / [`SegmentedControl`](parts/segmented-control) | 表示期間やビューの切り替えのような**単一選択**は `SegmentedControl`(値は `string`)。複数を同時に押せる**トグルの束**が要るときだけ `ToggleGroup`(値は常に配列)。 |
32
32
  | [`Select`](ui/select) / [`SearchableSelect`](parts/searchable-select) / [`MultiSelect`](parts/multi-select) / [`FilterBar`](parts/filter-bar) | 候補が**数個**なら `Select`。**多くて探したい**なら `SearchableSelect`、**複数選ぶ**なら `MultiSelect`。ページ上部に並ぶ**絞り込み一式**は、個別に置かず `FilterBar`(`FilterBarSelect` / `FilterBarMultiSelect`)でまとめて 1 つの値として扱う。 |
33
+ | [`KpiCard`](parts/kpi-card) / [`Delta`](parts/delta) / [`MetricValue`](parts/metric-value) | KPI のタイル 1 枚なら `KpiCard`(値・増減・前期実績・結論の 1 文まで出る)。表のセルや見出しの横に**増減だけ**を置くなら `Delta`。`MetricValue` は書式を自分で決めた数値を大きく見せたいときだけ。`TrendIndicator` は非推奨。 |
33
34
  | [`Sparkline`](parts/sparkline) / [`EChart`](parts/echart) | 表のセルや KPI タイルの隅に置く、**軸も凡例もない小さな推移**は `Sparkline`。軸・ツールチップ・凡例のある**本格的なグラフ**は `EChart`。 |
34
35
  | [`Skeleton`](ui/skeleton) / [`DashboardCardSkeleton`](parts/dashboard-card) / [`Placeholder`](parts/placeholder) | **読み込み中**の任意の形は `Skeleton`、ダッシュボードのタイル 1 枚分なら `DashboardCardSkeleton`。`Placeholder` は読み込み中ではなく、**中身が仮データであること**を示す目印。 |
35
36
  | [`Loading`](ui/loading) / [`Empty`](ui/empty) / [`ErrorState`](ui/error-state) | データ取得の 3 状態に 1 つずつ対応する。**取得中**は `Loading`、**0 件**は `Empty`、**失敗**は `ErrorState`(`action` に再試行ボタンを置ける)。 |
@@ -77,8 +78,12 @@ shadcn/ui のプリミティブです。名前も props も shadcn/ui のもの
77
78
 
78
79
  `ui/` を組み上げた、ダッシュボード向けの複合部品です。ページ枠(`PageShell` / `AppShell`)、
79
80
  タイル(`DashboardCard`)、表(`DataTable`)、グラフ(`EChart` / `Sparkline` / `FunnelSteps`)、
80
- フィルタ(`FilterBar` / `DateRangePicker` など)、KPI 表示(`MetricValue` / `TrendIndicator`)が
81
- 入っています。
81
+ フィルタ(`FilterBar` / `DateRangePicker` など)、KPI 表示が入っています。部品の正本は SquadKit で、
82
+ Vantage はそれを再エクスポートしています。
83
+
84
+ KPI は [`KpiCard`](parts/kpi-card)、増減は [`Delta`](parts/delta)(`comparison` と
85
+ `polarity` を渡す)で示します。[`TrendIndicator`](parts/trend-indicator) は非推奨です。数値の
86
+ 書式と増減の計算は [format / comparison](parts/format) にまとまっています。
82
87
 
83
88
  ## `@squadbase/vantage/markdown`
84
89
 
@@ -99,9 +104,8 @@ import {
99
104
  PageShellHeaderEnd,
100
105
  PageShellActions,
101
106
  PageShellContent,
107
+ KpiCard,
102
108
  DashboardCardPreset,
103
- MetricValue,
104
- TrendIndicator,
105
109
  EChart,
106
110
  type EChartsOption,
107
111
  } from "@squadbase/vantage/components";
@@ -129,17 +133,25 @@ export default function Overview() {
129
133
 
130
134
  <PageShellContent>
131
135
  <div className="grid gap-4 md:grid-cols-3">
132
- <DashboardCardPreset title="売上">
133
- <MetricValue className="my-0">¥1,240,000</MetricValue>
134
- <TrendIndicator value={12.4} direction="up" />
135
- </DashboardCardPreset>
136
- <DashboardCardPreset title="新規顧客">
137
- <MetricValue className="my-0">128</MetricValue>
138
- <TrendIndicator value={3.1} direction="down" />
139
- </DashboardCardPreset>
140
- <DashboardCardPreset title="解約率">
141
- <MetricValue className="my-0">2.1%</MetricValue>
142
- </DashboardCardPreset>
136
+ <KpiCard
137
+ label="売上"
138
+ value={1_240_000}
139
+ format="currency"
140
+ comparison={{ previous: 1_103_000, vs: "prior-period" }}
141
+ />
142
+ <KpiCard
143
+ label="新規顧客"
144
+ value={128}
145
+ format="number"
146
+ comparison={{ previous: 132, vs: "prior-period" }}
147
+ />
148
+ <KpiCard
149
+ label="解約率"
150
+ value={0.021}
151
+ format={{ type: "percent", digits: 1 }}
152
+ comparison={{ previous: 0.026, vs: "prior-period" }}
153
+ polarity="lower-is-better"
154
+ />
143
155
  </div>
144
156
 
145
157
  <DashboardCardPreset title="月次売上" className="mt-4">
@@ -55,6 +55,28 @@ import type { ColumnDef, SortingState, PaginationState } from "@squadbase/vantag
55
55
 
56
56
  `useDataTable()` を使うと、子コンポーネントから TanStack の `table` インスタンスを直接触れます。
57
57
 
58
+ ## 列の書式と CSV 書き出し
59
+
60
+ `cell` を書かない列は `meta.format` で数値を整形できます(右寄せ・tabular-nums、null は `meta.nullLabel`、既定 `—`)。行ごとに通貨が変わるときは関数で渡します。`DataTableExport` は画面と同じ並べ替え・絞り込み後の順で、BOM 付き UTF-8 の CSV を書き出します。`DataTablePreset` なら `exportable` だけで toolbar に置けます。
61
+
62
+ ```tsx
63
+ const columns: ColumnDef<Row>[] = [
64
+ { accessorKey: "month", header: "月" },
65
+ {
66
+ accessorKey: "revenue",
67
+ header: "売上",
68
+ meta: { format: (row) => ({ type: "currency", currency: row.currency, notation: "standard" }) },
69
+ },
70
+ ];
71
+
72
+ <DataTable columns={columns} data={rows}>
73
+ <DataTableToolbar toolbar={<DataTableExport fileName="sales.csv" />} />
74
+ <DataTableContent />
75
+ </DataTable>;
76
+ ```
77
+
78
+ `values="raw"` で生の値、`scope="page"` で表示中のページだけを書き出せます。サーバー側でページングするときは `rowCount`(総件数)・`manualSorting`・`manualFiltering`・`isLoading` も使えます。
79
+
58
80
  ## サーバー側でページングする
59
81
 
60
82
  `pagination` と `onPaginationChange` を自分で持ち、`pageCount` に総ページ数を渡します。
@@ -0,0 +1,50 @@
1
+ # Delta
2
+
3
+ > 比較相手に対する増減。矢印・符号付きの率・比較ラベルを値から導く。
4
+
5
+ 値の変化を「↑ +12.4% 前期比」の 1 行で示します。**向き・率・色・文言はすべて `value` と `comparison`
6
+ から計算**され、外から渡すことはできません — そのため矢印と色が食い違うことがありません。色だけに
7
+ 頼らず、矢印と符号が必ず付きます。解約率のように上がると悪い指標は `polarity="lower-is-better"` を
8
+ 渡してください。
9
+
10
+ 非推奨の [`TrendIndicator`](parts/trend-indicator) の置き換えです。
11
+
12
+ ```tsx
13
+ import { Delta } from "@squadbase/vantage/components";
14
+ import type { DeltaProps, Comparison, Polarity } from "@squadbase/vantage/components";
15
+ ```
16
+
17
+ | Prop | Type | Default | 説明 |
18
+ | --- | --- | --- | --- |
19
+ | `value` | `number \| null \| undefined` | | 現在の値。**必須**。前の値は `comparison` から取る。 |
20
+ | `comparison` | `Comparison` | | 比較の相手。**必須**(増減に必ずラベルが付くように)。下の表を参照。 |
21
+ | `polarity` | `"higher-is-better" \| "lower-is-better"` | `"higher-is-better"` | 上がることが良いか。 |
22
+ | `neutralBand` | `number` | `0.01` | 変化率の絶対値がこれ未満なら横ばい(–)として扱う。既定は 1%。 |
23
+ | `variant` | `"badge" \| "inline"` | `"badge"` | 枠付きのバッジか、文中に置く素の文字か。 |
24
+ | `locale` | `string` | `"ja-JP"` | 率の書式のロケール。 |
25
+ | `showLabel` | `boolean` | `true` | 率のあとに比較ラベル(「前期比」)を出すか。 |
26
+ | `className` | `string` | | 足すクラス。 |
27
+
28
+ ## Comparison
29
+
30
+ | Prop | Type | 説明 |
31
+ | --- | --- | --- |
32
+ | `previous` | `number \| null \| undefined` | 比較相手の値。`null` や `0` のときは率が出せないので「—」になる。 |
33
+ | `vs` | `"prior-period" \| "prior-year" \| "target"` | 比較の種類。ラベルは順に「前期比」「前年同期比」「目標比」。 |
34
+ | `label` | `string` | ラベルを差し替える(「先週比」など)。 |
35
+
36
+ ## TrendIndicator からの置き換え
37
+
38
+ ```tsx
39
+ // 旧: 向きと色を手で決めていた
40
+ <TrendIndicator value={12.4} direction="up" />
41
+
42
+ // 新: 今期と前期の値を渡すだけ
43
+ <Delta value={1_240_000} comparison={{ previous: 1_103_000, vs: "prior-period" }} />
44
+
45
+ // 下がる方が良い指標
46
+ <Delta value={0.021} comparison={{ previous: 0.026, vs: "prior-period" }} polarity="lower-is-better" />
47
+ ```
48
+
49
+ 色は `--positive` / `--negative` / `--neutral` のトークンで決まります。KPI を 1 枚のカードで見せる
50
+ なら [`KpiCard`](parts/kpi-card) が中で `Delta` を使います。
@@ -0,0 +1,44 @@
1
+ # format / comparison
2
+
3
+ > KPI・表・グラフで共有する数値の書式(formatValue)と、増減の計算(computeComparison)。
4
+
5
+ `KpiCard` / `Delta` が内部で使っている数値の書式と比較の計算を、そのまま関数として使えます。表の
6
+ セルやグラフの `valueFormatter` を KPI と同じ書式に揃えたいときに使ってください。短縮(「4.8億」
7
+ など)は `Intl.NumberFormat` に任せており、単位の文字列を自前で持ちません。
8
+
9
+ ```tsx
10
+ import {
11
+ formatValue,
12
+ formatDelta,
13
+ toValueFormatter,
14
+ computeComparison,
15
+ } from "@squadbase/vantage/components";
16
+ import type { ValueFormat, Comparison, ComparisonResult } from "@squadbase/vantage/components";
17
+ ```
18
+
19
+ ## ValueFormat
20
+
21
+ `"number" | "compact" | "currency" | "percent" | "multiple"` のどれか、または
22
+ `{ type, digits?, currency? }`。既定は `"compact"`、通貨の既定は `JPY`、ロケールの既定は `"ja-JP"`。
23
+ `percent` は比率(`0.124` → 12.4%)を受け取ります。値が `null` / `undefined` / `NaN` のときは「—」を
24
+ 返します。
25
+
26
+ | Prop | Type | 説明 |
27
+ | --- | --- | --- |
28
+ | `formatValue(value, format?, locale?)` | `string` | 値を書式化する。 |
29
+ | `formatDelta(value, format?, locale?)` | `string` | 差分用。0 以外は常に符号が付く(`+12.4%`)。 |
30
+ | `toValueFormatter(format?, locale?)` | `(value) => string` | 書式とロケールを束ねた 1 引数の関数。グラフの `valueFormatter` に渡せる。 |
31
+
32
+ ```tsx
33
+ formatValue(48_200_000, "currency"); // "¥48,200,000"
34
+ formatValue(0.021, { type: "percent", digits: 1 }); // "2.1%"
35
+ <LineChart valueFormatter={toValueFormatter("compact")} … />
36
+ ```
37
+
38
+ ## computeComparison
39
+
40
+ `computeComparison(current, comparison, { polarity?, neutralBand? })` が
41
+ `{ current, previous, difference, ratio, direction, sentiment, label, vs }` を返します。率は前の値が
42
+ 0 でない数のときだけ出し、`neutralBand`(既定 0.01)未満の変化は `direction: "flat"` になります。
43
+ `sentiment`(`"positive" | "negative" | "neutral"`)は `polarity` で決まります。表示は
44
+ [`Delta`](parts/delta) に任せ、自前で矢印や色を組まないでください。
@@ -0,0 +1,55 @@
1
+ # KpiCard
2
+
3
+ > KPI 1 つ分のカード。値・増減・前期実績・結論の 1 文までを数値から組み立てる。
4
+
5
+ KPI を 1 つ見せるカードです。**数値と列挙値だけを渡せば**、上から「指標名 → 値 → 増減
6
+ ([`Delta`](parts/delta))→ 前期の実績 → 結論の 1 文」の順に組み立てます。増減の向き・率・
7
+ 色・目標までの残り・達成率・記録更新はすべてカードの中で計算するので、props どうしが食い違うことは
8
+ ありません。KPI タイルは `DashboardCardPreset` + `MetricValue` で組むより、まずこれを使ってください。
9
+
10
+ ```tsx
11
+ import { KpiCard } from "@squadbase/vantage/components";
12
+ import type { KpiCardProps, KpiCardSource, Comparison, Polarity, ValueFormat } from "@squadbase/vantage/components";
13
+ ```
14
+
15
+ | Prop | Type | Default | 説明 |
16
+ | --- | --- | --- | --- |
17
+ | `label` | `string` | | 指標名。**必須**。 |
18
+ | `value` | `number \| null \| undefined` | | 現在の値。**必須**。`null` / `undefined` は「—」と表示する。 |
19
+ | `format` | `ValueFormat` | `"compact"` | 値の書式(→ format / comparison のページ)。前期実績・目標・残りにも同じ書式を使う。 |
20
+ | `locale` | `string` | `"ja-JP"` | 書式のロケール。 |
21
+ | `comparison` | `Comparison` | | 比較の相手(`{ previous, vs, label? }`)。渡すと増減と前期実績の行が出る。 |
22
+ | `polarity` | `"higher-is-better" \| "lower-is-better"` | `"higher-is-better"` | 上がることが良いか。解約率のように下がる方が良い指標は `"lower-is-better"`。 |
23
+ | `neutralBand` | `number` | `0.01` | 変化率の絶対値がこれ未満なら横ばいとして扱う。 |
24
+ | `showPrevious` | `boolean` | `true` | 前期の実績(「前期 400」)を出すか。`comparison` が要る。 |
25
+ | `summary` | `string` | | 結論の 1 文の**テンプレート**。下のプレースホルダをカードが埋める。 |
26
+ | `target` | `number` | | 今期の目標。「目標まであと …(… 達成)」の行が出る。 |
27
+ | `period` | `{ start: Date \| string \| number; end: Date \| string \| number }` | | 今期の期間。`target` と一緒に渡すと、期間中は「見込み」(このペースなら期末いくつ)が出る。 |
28
+ | `history` | `ReadonlyArray<number \| null \| undefined>` | | 今期で終わる系列(最後の点 = `value`)。記録更新のバッジが出る。 |
29
+ | `historyGrain` | `"day" \| "week" \| "month" \| "quarter" \| "year"` | `"month"` | `history` の粒度。 |
30
+ | `source` | `{ period?: string; count?: number; name?: string }` | | データの出所の注記(「2023-04 以降・48,210 件から集計・Snowflake」)。 |
31
+ | `updatedAt` | `Date \| string \| number` | | 最終更新時刻。「3 分前に更新」と出る。 |
32
+ | `now` | `Date \| number` | | 見込みと相対時刻の基準時刻(表示を固定したいとき)。 |
33
+ | `isLoading` | `boolean` | `false` | 値の代わりに、完成形と同じ形のスケルトンを出す。 |
34
+ | `className` | `string` | | 足すクラス。 |
35
+
36
+ ## summary のプレースホルダ
37
+
38
+ `{value}` `{delta}` `{difference}` `{previous}` `{label}` `{target}` `{achievement}` `{remaining}` が
39
+ 使えます。知らない名前はそのまま残り、値が無いものは「—」になります。
40
+
41
+ > [!WARNING]
42
+ > **テンプレートに数値を直接書かないでください。** 数値はすべてプレースホルダで差し込みます —
43
+ > 値が変わっても文が古くならないようにするためです。
44
+
45
+ ```tsx
46
+ <KpiCard
47
+ label="売上"
48
+ value={48_200_000}
49
+ format="currency"
50
+ comparison={{ previous: 42_900_000, vs: "prior-period" }}
51
+ summary="{label}は前月から {difference}({delta})伸びています。"
52
+ />
53
+ ```
54
+
55
+ 増減だけを表やタイルの中に置きたいときは [`Delta`](parts/delta) を単体で使います。
@@ -2,7 +2,8 @@
2
2
 
3
3
  > KPI の数値。単位は MetricUnit で。
4
4
 
5
- KPI の数値を大きく見せるための、字送りを詰めた表示です。単位や補助的な文字は `MetricUnit` で
5
+ KPI の数値を大きく見せるための、字送りを詰めた表示です。KPI のタイルを 1 枚作るなら、増減や前期実績まで
6
+ 出せる [`KpiCard`](parts/kpi-card) を先に検討してください。単位や補助的な文字は `MetricUnit` で
6
7
  添えます。
7
8
 
8
9
  ```tsx
@@ -20,6 +21,6 @@ import { MetricValue, MetricUnit, metricValueVariants } from "@squadbase/vantage
20
21
  ```tsx
21
22
  <DashboardCardPreset title="売上">
22
23
  <MetricValue className="my-0">¥1,240,000</MetricValue>
23
- <TrendIndicator value={12.4} direction="up" />
24
+ <Delta value={1_240_000} comparison={{ previous: 1_103_000, vs: "prior-period" }} />
24
25
  </DashboardCardPreset>
25
26
  ```
@@ -44,4 +44,4 @@ import type { SparklineDataPoint, SparklineVariant } from "@squadbase/vantage/co
44
44
  > [!NOTE]
45
45
  > `aria-hidden="true"` が付いているため、スクリーンリーダーには読まれません。実際の数値は
46
46
  > [`MetricValue`](parts/metric-value) や
47
- > [`TrendIndicator`](parts/trend-indicator) など、テキストとして隣に置いてください。
47
+ > [`Delta`](parts/delta) など、テキストとして隣に置いてください。
@@ -1,6 +1,22 @@
1
1
  # TrendIndicator
2
2
 
3
- > 増減の矢印と変化率。良し悪しは positiveIsGood で決まる。
3
+ > 非推奨。新規は Delta を使う。増減の矢印と変化率。
4
+
5
+ > [!WARNING]
6
+ > **非推奨です。新規のコードでは [`Delta`](parts/delta) を使ってください。**
7
+ > `TrendIndicator` は向き(`direction`)と色を手で渡すため、値と矢印が食い違うことがあります。`Delta` は今期と
8
+ > 比較相手の値から向き・率・色・ラベルを計算します。KPI をカードで見せるなら
9
+ > [`KpiCard`](parts/kpi-card) を使います。
10
+
11
+ ```tsx
12
+ // 旧
13
+ <TrendIndicator value={12.4} direction="up" />
14
+ <TrendIndicator value={0.4} direction="down" positiveIsGood={false} />
15
+
16
+ // 新
17
+ <Delta value={1_240_000} comparison={{ previous: 1_103_000, vs: "prior-period" }} />
18
+ <Delta value={0.021} comparison={{ previous: 0.026, vs: "prior-period" }} polarity="lower-is-better" />
19
+ ```
4
20
 
5
21
  前期比などの変化を、矢印と変化率で示します。**「上がった=良い」とは限らない**ので、色は
6
22
  `direction` と `positiveIsGood` の組み合わせで決まります — 解約率のように下がる方が良い指標では
@@ -39,8 +39,8 @@ export default function Overview() {
39
39
 
40
40
  `/components` にあるもの(抜粋): `PageShell`、`AppShell`、`DashboardCard`、`DataTable`、
41
41
  型付きチャート(`LineChart` / `AreaChart` / `BarChart` / `DonutChart` / `BarList` / `CategoryBar` /
42
- `ProgressCircle` / `Tracker`)、`EChart`、`FunnelSteps`、`FilterBar`、`DateRangePicker`、`MetricValue`、
43
- `TrendIndicator`。グラフはまず型付きチャートで描き、その props で表せない図(二軸・散布図・
42
+ `ProgressCircle` / `Tracker`)、`EChart`、`FunnelSteps`、`FilterBar`、`DateRangePicker`、`KpiCard`、
43
+ `Delta`。グラフはまず型付きチャートで描き、その props で表せない図(二軸・散布図・
44
44
  ヒートマップなど)だけ `EChart` に `EChartsOption` を渡します。
45
45
 
46
46
  各コンポーネントの props と使い方は [コンポーネント](components) タブにまとめてあります。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squadbase/vantage",
3
- "version": "0.6.2-dev1.ac99e02",
3
+ "version": "0.6.2-dev1.d7c0911",
4
4
  "description": "Data dashboard framework for Squadbase Editor. Vite-powered, config-free, one-file first.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -158,6 +158,7 @@
158
158
  }
159
159
  },
160
160
  "devDependencies": {
161
+ "@squadbase/squadkit": "*",
161
162
  "@types/node": "^22.10.0",
162
163
  "@types/papaparse": "^5.5.2",
163
164
  "@types/react": "^19.2.0",
@@ -1,5 +1,7 @@
1
1
  // Copied by `vantage add ui accordion`. This file is yours to edit.
2
- // Generated from @squadbase/vantage src/ui/accordion.tsx by `npm run registry` (in Vantage, edit src/, not registry/).
2
+ // Generated from @squadbase/squadkit registry/ui/accordion.tsx by `npm run registry` (in Vantage, edit packages/squadkit, not registry/).
3
+ "use client"
4
+
3
5
  import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion"
4
6
 
5
7
  import { cn } from "@squadbase/vantage/ui"
@@ -56,7 +58,7 @@ function AccordionContent({
56
58
  return (
57
59
  <AccordionPrimitive.Panel
58
60
  data-slot="accordion-content"
59
- className="overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
61
+ className="overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up motion-reduce:animate-none"
60
62
  {...props}
61
63
  >
62
64
  <div
@@ -1,5 +1,5 @@
1
1
  // Copied by `vantage add ui alert-dialog`. This file is yours to edit.
2
- // Generated from @squadbase/vantage src/ui/alert-dialog.tsx by `npm run registry` (in Vantage, edit src/, not registry/).
2
+ // Generated from @squadbase/squadkit registry/ui/alert-dialog.tsx by `npm run registry` (in Vantage, edit packages/squadkit, not registry/).
3
3
  "use client"
4
4
 
5
5
  import * as React from "react"
@@ -32,7 +32,7 @@ function AlertDialogOverlay({
32
32
  <AlertDialogPrimitive.Backdrop
33
33
  data-slot="alert-dialog-overlay"
34
34
  className={cn(
35
- "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
35
+ "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in motion-reduce:animate-none! data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
36
36
  className
37
37
  )}
38
38
  {...props}
@@ -54,7 +54,7 @@ function AlertDialogContent({
54
54
  data-slot="alert-dialog-content"
55
55
  data-size={size}
56
56
  className={cn(
57
- "group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
57
+ "group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in motion-reduce:animate-none! data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
58
58
  className
59
59
  )}
60
60
  {...props}
@@ -1,5 +1,7 @@
1
1
  // Copied by `vantage add ui alert`. This file is yours to edit.
2
- // Generated from @squadbase/vantage src/ui/alert.tsx by `npm run registry` (in Vantage, edit src/, not registry/).
2
+ // Generated from @squadbase/squadkit registry/ui/alert.tsx by `npm run registry` (in Vantage, edit packages/squadkit, not registry/).
3
+ "use client"
4
+
3
5
  import * as React from "react"
4
6
  import { cva, type VariantProps } from "class-variance-authority"
5
7
 
@@ -1,5 +1,7 @@
1
1
  // Copied by `vantage add ui app-shell`. This file is yours to edit.
2
- // Generated from @squadbase/vantage src/components/app-shell.tsx by `npm run registry` (in Vantage, edit src/, not registry/).
2
+ // Generated from @squadbase/squadkit registry/components/app-shell.tsx by `npm run registry` (in Vantage, edit packages/squadkit, not registry/).
3
+ "use client"
4
+
3
5
  /**
4
6
  * AppShell — the outermost application frame. `variant="sidebar"` (default)
5
7
  * renders a collapsible sidebar with nested nav groups; `variant="header"`
@@ -85,9 +87,13 @@ function NavSelect({
85
87
  }) {
86
88
  const allItems = groups.flatMap((g) => g.items.flatMap(flattenItems))
87
89
  const currentValue = allItems.find((item) => item.isActive)?.href ?? ""
90
+ // Base UI's SelectValue renders the raw value (the href) unless `items` maps
91
+ // it to a label, so pass the page names explicitly.
92
+ const selectItems = allItems.map((item) => ({ value: item.href, label: item.label }))
88
93
 
89
94
  return (
90
95
  <Select
96
+ items={selectItems}
91
97
  value={currentValue}
92
98
  onValueChange={(href) => {
93
99
  // Base UI reports `null` when the selection is cleared; there is no