@squadbase/vantage-template 0.0.1

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 (99) hide show
  1. package/README.md +112 -0
  2. package/base-template/.squadbase/skills/vantage-add-feature/SKILL.md +162 -0
  3. package/base-template/.squadbase/skills/vantage-app/SKILL.md +120 -0
  4. package/base-template/.squadbase/skills/vantage-pitfalls/SKILL.md +137 -0
  5. package/base-template/AGENTS.md +339 -0
  6. package/base-template/_404.tsx +18 -0
  7. package/base-template/_error.tsx +14 -0
  8. package/base-template/_gitignore +5 -0
  9. package/base-template/_layout.tsx +60 -0
  10. package/base-template/components/user-card.tsx +132 -0
  11. package/base-template/index.tsx +59 -0
  12. package/base-template/package.json +27 -0
  13. package/base-template/server/api/health.ts +12 -0
  14. package/base-template/squadbase.yml +5 -0
  15. package/base-template/styles.css +18 -0
  16. package/base-template/tsconfig.json +28 -0
  17. package/chart-presets/berry.css +16 -0
  18. package/chart-presets/blue.css +16 -0
  19. package/chart-presets/forest.css +16 -0
  20. package/chart-presets/mono.css +16 -0
  21. package/chart-presets/ocean.css +16 -0
  22. package/chart-presets/sunset.css +16 -0
  23. package/dist/index.js +1157 -0
  24. package/package.json +55 -0
  25. package/ui-templates/CLAUDE.md +200 -0
  26. package/ui-templates/blank/manifest.json +8 -0
  27. package/ui-templates/blank/pages/index.tsx +33 -0
  28. package/ui-templates/blank-ja/manifest.json +8 -0
  29. package/ui-templates/blank-ja/pages/index.tsx +33 -0
  30. package/ui-templates/chart-grid/lib/mock-data.ts +139 -0
  31. package/ui-templates/chart-grid/lib/types.ts +31 -0
  32. package/ui-templates/chart-grid/manifest.json +10 -0
  33. package/ui-templates/chart-grid/pages/index.tsx +331 -0
  34. package/ui-templates/chart-grid/preview-square.png +0 -0
  35. package/ui-templates/chart-grid/preview-wide.png +0 -0
  36. package/ui-templates/chart-grid-ja/lib/mock-data.ts +139 -0
  37. package/ui-templates/chart-grid-ja/lib/types.ts +31 -0
  38. package/ui-templates/chart-grid-ja/manifest.json +10 -0
  39. package/ui-templates/chart-grid-ja/pages/index.tsx +331 -0
  40. package/ui-templates/chart-grid-ja/preview-square.png +0 -0
  41. package/ui-templates/chart-grid-ja/preview-wide.png +0 -0
  42. package/ui-templates/funnel/components/chart-helpers.ts +11 -0
  43. package/ui-templates/funnel/components/stage-table.tsx +63 -0
  44. package/ui-templates/funnel/lib/mock-data.ts +22 -0
  45. package/ui-templates/funnel/lib/types.ts +11 -0
  46. package/ui-templates/funnel/manifest.json +12 -0
  47. package/ui-templates/funnel/pages/index.tsx +252 -0
  48. package/ui-templates/funnel/preview-square.png +0 -0
  49. package/ui-templates/funnel/preview-wide.png +0 -0
  50. package/ui-templates/funnel-ja/components/chart-helpers.ts +11 -0
  51. package/ui-templates/funnel-ja/components/stage-table.tsx +63 -0
  52. package/ui-templates/funnel-ja/lib/mock-data.ts +22 -0
  53. package/ui-templates/funnel-ja/lib/types.ts +11 -0
  54. package/ui-templates/funnel-ja/manifest.json +12 -0
  55. package/ui-templates/funnel-ja/pages/index.tsx +251 -0
  56. package/ui-templates/funnel-ja/preview-square.png +0 -0
  57. package/ui-templates/funnel-ja/preview-wide.png +0 -0
  58. package/ui-templates/kpi-chart-advanced/components/campaign-table.tsx +69 -0
  59. package/ui-templates/kpi-chart-advanced/lib/mock-data.ts +109 -0
  60. package/ui-templates/kpi-chart-advanced/lib/types.ts +38 -0
  61. package/ui-templates/kpi-chart-advanced/manifest.json +11 -0
  62. package/ui-templates/kpi-chart-advanced/pages/index.tsx +339 -0
  63. package/ui-templates/kpi-chart-advanced/preview-square.png +0 -0
  64. package/ui-templates/kpi-chart-advanced/preview-wide.png +0 -0
  65. package/ui-templates/kpi-chart-advanced-ja/components/campaign-table.tsx +69 -0
  66. package/ui-templates/kpi-chart-advanced-ja/lib/mock-data.ts +109 -0
  67. package/ui-templates/kpi-chart-advanced-ja/lib/types.ts +38 -0
  68. package/ui-templates/kpi-chart-advanced-ja/manifest.json +11 -0
  69. package/ui-templates/kpi-chart-advanced-ja/pages/index.tsx +333 -0
  70. package/ui-templates/kpi-chart-advanced-ja/preview-square.png +0 -0
  71. package/ui-templates/kpi-chart-advanced-ja/preview-wide.png +0 -0
  72. package/ui-templates/kpi-chart-simple/components/top-items-table.tsx +73 -0
  73. package/ui-templates/kpi-chart-simple/lib/types.ts +44 -0
  74. package/ui-templates/kpi-chart-simple/manifest.json +11 -0
  75. package/ui-templates/kpi-chart-simple/pages/index.tsx +200 -0
  76. package/ui-templates/kpi-chart-simple/preview-square.png +0 -0
  77. package/ui-templates/kpi-chart-simple/preview-wide.png +0 -0
  78. package/ui-templates/kpi-chart-simple/server/kpi-summary.ts +141 -0
  79. package/ui-templates/kpi-chart-simple-ja/components/top-items-table.tsx +73 -0
  80. package/ui-templates/kpi-chart-simple-ja/lib/types.ts +44 -0
  81. package/ui-templates/kpi-chart-simple-ja/manifest.json +11 -0
  82. package/ui-templates/kpi-chart-simple-ja/pages/index.tsx +200 -0
  83. package/ui-templates/kpi-chart-simple-ja/preview-square.png +0 -0
  84. package/ui-templates/kpi-chart-simple-ja/preview-wide.png +0 -0
  85. package/ui-templates/kpi-chart-simple-ja/server/kpi-summary.ts +141 -0
  86. package/ui-templates/table-focus/components/detail-table.tsx +88 -0
  87. package/ui-templates/table-focus/lib/mock-data.ts +69 -0
  88. package/ui-templates/table-focus/lib/types.ts +24 -0
  89. package/ui-templates/table-focus/manifest.json +11 -0
  90. package/ui-templates/table-focus/pages/index.tsx +180 -0
  91. package/ui-templates/table-focus/preview-square.png +0 -0
  92. package/ui-templates/table-focus/preview-wide.png +0 -0
  93. package/ui-templates/table-focus-ja/components/detail-table.tsx +95 -0
  94. package/ui-templates/table-focus-ja/lib/mock-data.ts +69 -0
  95. package/ui-templates/table-focus-ja/lib/types.ts +24 -0
  96. package/ui-templates/table-focus-ja/manifest.json +11 -0
  97. package/ui-templates/table-focus-ja/pages/index.tsx +180 -0
  98. package/ui-templates/table-focus-ja/preview-square.png +0 -0
  99. package/ui-templates/table-focus-ja/preview-wide.png +0 -0
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@squadbase/vantage-template",
3
+ "version": "0.0.1",
4
+ "description": "CLI tool for initializing and customizing Squadbase Vantage projects.",
5
+ "keywords": [
6
+ "squadbase",
7
+ "vantage",
8
+ "dashboard",
9
+ "template",
10
+ "scaffolding",
11
+ "react"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/squadbase/squadbase-templates.git",
16
+ "directory": "vantage-template"
17
+ },
18
+ "homepage": "https://github.com/squadbase/squadbase-templates/tree/main/vantage-template#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/squadbase/squadbase-templates/issues"
21
+ },
22
+ "type": "module",
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "bin": {
27
+ "squadbase-vantage-template": "./dist/index.js"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "ui-templates",
32
+ "base-template",
33
+ "chart-presets"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "scripts": {
39
+ "sync-base": "rsync -a --delete --exclude='node_modules' --exclude='dist' --exclude='.vantage' --exclude='package-lock.json' --exclude='*.tsbuildinfo' --exclude='*.log' ../vantage/ base-template/ && mv base-template/.gitignore base-template/_gitignore",
40
+ "build": "npm run sync-base && tsup",
41
+ "prepublishOnly": "npm run build",
42
+ "release": "npm publish --@squadbase:registry=https://registry.npmjs.org"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^22.15.0",
46
+ "tsup": "^8.4.0",
47
+ "typescript": "~5.7.0"
48
+ },
49
+ "optionalDependencies": {
50
+ "@ai-sdk/anthropic": "^1.0.0",
51
+ "@ai-sdk/google": "^1.0.0",
52
+ "@ai-sdk/openai": "^1.0.0",
53
+ "ai": "^4.0.0"
54
+ }
55
+ }
@@ -0,0 +1,200 @@
1
+ # CLAUDE.md — ui-templates (Vantage)
2
+
3
+ UIパターン別テンプレート(KPI重視・チャート格子・テーブル重視・ファネル など)。ユースケース非依存の **UI 骨格の見本市**。コーディングエージェントがこれを起点にユーザー要望のダッシュボードを実装する。
4
+
5
+ **画面として重複するテンプレは置かない。** 追加を検討する際は、既存テンプレのプレビュー画像と並べて「別の絵になるか」で判断する。`tabbed-dashboard` は Tab 1 が `kpi-chart-simple`、Tab 2 が `table-focus` の再掲でサムネイルが見分けられなかったため削除した(タブは既存テンプレに `<Tabs>` を巻けば作れる)。
6
+
7
+ このファイルは `vantage-template/ui-templates/` 配下のファイル構成ルールを定義する。デザイン要件・AI relabel・EN/JA・CLI の挙動は親 [`../CLAUDE.md`](../CLAUDE.md) に従う。
8
+
9
+ > **Vite 版との差分**: 適用先が Vantage アプリ(`@squadbase/vantage`)になったため、(1) エントリは `src/pages/home.tsx` ではなく **ルートの `index.tsx`**、(2) テンプレ固有ファイルは `src/templates/<slug>/` ではなく **`components/<slug>/`**、(3) 全ての building block を `@squadbase/vantage/*` から import する(ローカルコピーは持たない)。
10
+
11
+ ## 設計目標
12
+
13
+ テンプレートは「出発点」であり、適用後にエージェントが本実装を被せていく。そのため次の3点を最優先する:
14
+
15
+ 1. **探索コスト最小** — テンプレ由来のコードが一目で分かること
16
+ 2. **デッドコード/削除コスト最小** — 不要になったら迷わず一掃できること
17
+ 3. **indirection 最小** — エージェントが編集対象に最短で到達できること
18
+
19
+ ## ファイル構成の原則
20
+
21
+ ### 1. 1テンプレ = 1ディレクトリ(コロケーション)
22
+
23
+ 適用先では、`index.tsx`(エントリ)以外のテンプレ固有ファイルを **`components/<slug>/` 1ディレクトリに集約** する。
24
+
25
+ ```
26
+ # 適用先(dest)レイアウト
27
+ index.tsx # エントリ(ルート "/")
28
+ components/<slug>/
29
+ mock-data.ts # データ層(relabel:false / 差し替え対象)
30
+ types.ts # 型(index と data で共有)
31
+ ...(分割した場合のみ追加ファイル)
32
+ ```
33
+
34
+ - **探索**: `components/<slug>/` を見ればテンプレ由来が一覧完結
35
+ - **削除**: `rm -rf components/<slug>/` で一掃
36
+
37
+ **`components/` を使う理由(重要)**: Vantage は**ファイルベースルーティング**で、`.tsx` ファイルは原則すべてページ扱いになる。`components/` / `hooks/` / `lib/` / `server/` / `public/` だけがルート走査から除外される(`NON_ROUTE_DIRS`)ため、`templates/<slug>/` のようなディレクトリに `.tsx` を置くと **`/templates/<slug>/...` という意図しないルートが生え、`vantage check` が `MISSING_DEFAULT_EXPORT` で落ちる**。データファイル(`.ts`)も同じディレクトリに置いてコロケーションを保つ。
38
+
39
+ ### 2. インライン優先 — 薄いラッパ component を作らない
40
+
41
+ **`data → EChartsOption → <EChart>` だけの薄いチャート component は作らず、`index.tsx` 内のオプションビルダ関数にする。**
42
+
43
+ ```tsx
44
+ // ✅ 推奨: index.tsx 内のオプションビルダ関数 + EChart 直レンダ
45
+ function areaOption(data: TimePoint[]): EChartsOption {
46
+ return { /* ... */ }
47
+ }
48
+ // JSX 内:
49
+ <EChart option={areaOption(timeSeries)} height="280px" />
50
+ ```
51
+
52
+ チャート整形ヘルパ(`getBaseGrid` / `formatNumber` 等)も同様に `index.tsx` 内へ inline する。
53
+
54
+ **チャートに色をハードコードしない。** `@squadbase/vantage` v0.2.1 以降、`EChart` は init 時に `--chart-1..5`(系列色)と文字色/境界色トークン(軸・凡例・ツールチップ)を読み、light / dark の切り替えにも追従する。v0.2.2 からはスタイルシートの差し替え(`chart <preset>` の適用や `styles.css` の HMR)も拾い、トークンの実値が変わった時だけ再描画する。`option.color` / `itemStyle.color` / ラベルの `color` を書くと、その分だけテンプレがテーマ差し替え(`vantage-template chart <preset>` や `styles.css` の override)から外れる。**ui-templates では書かない**のが既定 — 意味色(成功=緑・失敗=赤など)を出したいときだけ、その series に限って指定する。`theme` プロップは使わない(渡した時点でトークン追従が完全に止まる)。
55
+
56
+ ### 3. データ層(mock-data / types)は分離する
57
+
58
+ `mock-data.ts` と `types.ts` は `index.tsx` に inline せず、`components/<slug>/` の別ファイルに保つ。表示ラベル(KPI名・軸名・stage名など)は描画側(`index.tsx`)の literal/const に置き、データ配列には値・id・generic な sample text のみ置く。
59
+
60
+ ### 3-b. API 版テンプレ(`server/api` から配信する場合)
61
+
62
+ `kpi-chart-simple` はモック配列を直読みせず、**`server/api` から `useApiQuery` で取る**構成になっている。実データ接続までの導線を1本コードで示すためのもので、この構成を採るテンプレは dest の置き場が変わる:
63
+
64
+ ```
65
+ index.tsx # useApiQuery + useSearchParam
66
+ components/<slug>/*.tsx # 表示コンポーネント
67
+ lib/<slug>/types.ts # ★ client と server が共有する型(relabel:false)
68
+ server/api/<endpoint>.ts # ★ サンプルデータ + GET ハンドラ(relabel:false)
69
+ ```
70
+
71
+ - **共有型は `components/` ではなく `lib/`** に置く。クライアントは `server/` を import できない(`CLIENT_IMPORTS_SERVER`)ので、両者が参照できる中立な場所が要る。`lib/` もルート走査対象外なので安全。
72
+ - **サンプルデータはサーバー側に置く。** 「実装者が差し替える場所」がハンドラ1箇所に集約され、`KpiSummary` のような payload 型さえ保てばページを触らずに実データへ移行できる。
73
+ - **絞り込みは `useSearchParam` + `useApiQuery` の `search`** で組む。`search` はクエリ文字列とキャッシュキーの両方に入るので、URL を変えれば再取得される。
74
+ - クライアントに見せたいエラーは `HttpError(status, msg)` を throw する。`useApiQuery` の `error` は `ApiError` なのでキャスト不要で `.message` が読める。
75
+
76
+ 新しくテンプレを足すときにこの構成を必須にはしない(UI 骨格の見本市なのでモックのままでよい)。ただし**モックを使うテンプレでも絞り込み状態は `useState` のままでよい** — URL 化は実データに繋ぐ段階の話で、`kpi-chart-simple` がその見本になっている。
77
+
78
+ ### 4. デッドコードを残さない
79
+
80
+ テンプレに未使用の関数・型・import を残さない。
81
+
82
+ ### 分割してよい例外
83
+
84
+ **再利用される** / **内部 state・interaction を持つ** / **`index.tsx` が 400〜500 行を超える** のいずれかに当てはまる UI のみ、`components/<slug>/` 配下に切り出してよい。迷ったら inline。
85
+
86
+ ## import 規約(Vantage)
87
+
88
+ すべての building block は `@squadbase/vantage/*` から import する。`@/` エイリアスは**存在しない**。
89
+
90
+ | 用途 | import 元 |
91
+ | --- | --- |
92
+ | `PageShell*` / `DashboardCard*` / `EChart` / `EChartsOption` / `DataTable*` / `ColumnDef` / `DateRangePicker` / `FilterBar*` / `FunnelSteps` / `MetricValue` / `TrendIndicator` / `StatusBadge` / `SegmentedControl` / `MultiSelect` / `SearchableSelect` / `SectionHeader` / `AppShell` / `Placeholder` / `Sparkline` | `@squadbase/vantage/components` |
93
+ | `Button` / `Input` / `Badge` / `Tabs*` / `ToggleGroup*` / `Table*` / `Select*` / `Dialog*` / `cn` ほか shadcn プリミティブ | `@squadbase/vantage/ui` |
94
+ | `definePage` | `@squadbase/vantage` |
95
+ | `Link` / `Outlet` / `useParams` / `useSearch` / `useNavigate` / `useRoutes` / `useCurrentRoute` / `useSearchParam` / `useSearchState` | `@squadbase/vantage/router` |
96
+ | `useApiQuery` / `useApiMutation` / `useQuery` / `useMutation` / `apiFetch` | `@squadbase/vantage/query` |
97
+ | `MarkdownRenderer` | `@squadbase/vantage/markdown` |
98
+
99
+ **禁止**: `echarts` / `@tanstack/*` / `@base-ui/react` / `hono` / `vite` / `tailwindcss` の直接 import。`EChartsOption` は `@squadbase/vantage/components` から、`ColumnDef` も同じくそこから取る。`lucide-react` と `date-fns` の直接 import は可(ベーステンプレートの dependencies に入っている)。
100
+
101
+ **相対 import は拡張子なしで書く**(`@squadbase/vantage` v0.2.0 で `.js` 指定子の規約は廃止。既存の `.js` 付き import も動くが、新規テンプレでは付けない)。
102
+
103
+ ```tsx
104
+ // index.tsx から
105
+ import { MOCK_SERIES } from "./components/<slug>/mock-data"
106
+
107
+ // components/<slug>/detail-table.tsx から
108
+ import type { Row } from "./types"
109
+ ```
110
+
111
+ `Placeholder` / `Sparkline` はローカルコピーではなく `@squadbase/vantage/components` から取る(v0.1.1 でフレームワークに入った)。
112
+
113
+ ### Base UI と Radix の差分(`vantage-pitfalls` skill も参照)
114
+
115
+ Vantage の UI キットは Radix ではなく **Base UI** ベース。移植時に踏みやすい差分:
116
+
117
+ - `asChild` は**無い** → `render` prop を使う(`<DialogTrigger render={<button />}>`)
118
+ - `ToggleGroup` の `value` は**配列**(単一選択でも `string[]`)
119
+ - `Select` の `onValueChange` は `string | null` を返す
120
+ - `Checkbox` の中間状態は `indeterminate` prop
121
+
122
+ `Select` の value/label は v0.2.1 で Vantage 側が `SelectItem` の children から集めるようになったので、`items` は書かなくてよい(`SelectItem` を別コンポーネントが返している場合だけ明示する)。
123
+
124
+ ## エントリの必須要件
125
+
126
+ `index.tsx` は **default export の React component** が必須(無いと `vantage check` が `MISSING_DEFAULT_EXPORT`)。加えてタイトル/説明を `definePage` で宣言する:
127
+
128
+ ```tsx
129
+ import { definePage } from "@squadbase/vantage"
130
+
131
+ export const page = definePage({
132
+ title: "KPI + Chart",
133
+ description: "...",
134
+ // ナビの表示名。省略時は title が使われる
135
+ navLabel: "KPI",
136
+ })
137
+
138
+ export default function Home() { /* ... */ }
139
+ ```
140
+
141
+ `definePage` の値は**ビルド時に静的抽出される**ため、変数・関数呼び出し・テンプレート補間は使えない(リテラルのみ)。
142
+
143
+ ## ソースのオーサリング構造(このリポジトリ側)
144
+
145
+ ```
146
+ ui-templates/<slug>/
147
+ manifest.json
148
+ preview-square.png / preview-wide.png
149
+ pages/index.tsx → dest: index.tsx (replace)
150
+ lib/mock-data.ts → dest: components/<slug>/mock-data.ts (add, relabel:false)
151
+ lib/types.ts → dest: components/<slug>/types.ts (add, relabel:false)
152
+ components/*.tsx → dest: components/<slug>/*.tsx (add) ※分割した場合のみ
153
+ server/*.ts → dest: server/api/*.ts (add, relabel:false) ※API 版のみ
154
+ ```
155
+
156
+ API 版(`kpi-chart-simple`)では `lib/types.ts` の dest が `lib/<slug>/types.ts` になり、`lib/mock-data.ts` は無く、代わりに `server/*.ts` を持つ。上の「3-b」を参照。
157
+
158
+ ## manifest.json
159
+
160
+ ```json
161
+ {
162
+ "name": "<slug>",
163
+ "description": "...",
164
+ "version": "0.1.0",
165
+ "files": [
166
+ { "src": "pages/index.tsx", "dest": "index.tsx", "action": "replace" },
167
+ { "src": "lib/mock-data.ts", "dest": "components/<slug>/mock-data.ts", "action": "add", "relabel": false },
168
+ { "src": "lib/types.ts", "dest": "components/<slug>/types.ts", "action": "add", "relabel": false }
169
+ ]
170
+ }
171
+ ```
172
+
173
+ - `files[]` が manifest の全て(`nav[]` は無い)。ベーステンプレートのナビは `useRoutes()` からルート一覧を組むので、ページファイルをコピーすればナビにも載る
174
+ - データファイルには `"relabel": false` を必ず付ける
175
+
176
+ ## 見本市の例外ルール
177
+
178
+ `ui-templates/` は「UI 構造の見本市」として、レイアウトの幅を意図的に出す。以下の default は意図的に崩してよい:
179
+
180
+ - **PageShellSummary(insight cards)は必須ではない** — KPI 重視のテンプレ(`kpi-chart-advanced`)のみに残し、他では省く
181
+ - **本体最初の行を KPI カードで始める必要はない** — テーブル中心 / チャート中心 / ファネル中心など、テーマに合わせて開始要素を変える
182
+ - **PageShellHeaderEnd の中身は DateRangePicker 限定ではない** — 検索ボックス、Export ボタン、Filter chips、ステージ選択など
183
+ - **2 カラム(本体 + サイドバー)のレイアウトを使ってよい**
184
+
185
+ ただし以下は維持する(テンプレ群としての一貫性のため):
186
+ - `PageShell` / `PageShellHeader` / `PageShellHeading` / `PageShellTitle` の使用
187
+ - `DashboardCard` / `DashboardCardPreset` の使用(raw `Card` ではなく)
188
+ - `EChart` の使用(生の `echarts` を触らない)
189
+
190
+ ## チェックリスト(テンプレ追加・改修時)
191
+
192
+ 1. テンプレ固有ファイルの `dest` は `components/<slug>/` 配下か(`templates/` に `.tsx` を置いていないか)
193
+ 2. `@/` エイリアスや `echarts` / `@tanstack/*` の直接 import、`Placeholder` / `Sparkline` のローカル import が残っていないか
194
+ 3. 相対 import に `.js` 拡張子が残っていないか(v0.2.0 で規約廃止)
195
+ 4. 薄いチャートラッパ component を作っていないか。チャートに色をハードコードしていないか(`option.color` / `itemStyle.color` / `theme`)
196
+ 5. `mock-data.ts` / `types.ts` / `server/*.ts` は分離され `relabel:false` が付いているか
197
+ 6. 未使用の関数・型・import が残っていないか
198
+ 7. 適用先で `npx vantage check` と `npx tsc --noEmit` が通るか
199
+ 8. EN/JA 両方を同じ構成に揃えたか
200
+ 9. レイアウトを変えたなら `preview-wide.png` (1600x900) / `preview-square.png` (1200x1200) を撮り直したか
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "blank",
3
+ "description": "Blank — Empty PageShell with title and description. The minimal scaffold for building a dashboard from scratch.",
4
+ "version": "0.1.0",
5
+ "files": [
6
+ { "src": "pages/index.tsx", "dest": "index.tsx", "action": "replace" }
7
+ ]
8
+ }
@@ -0,0 +1,33 @@
1
+ import { definePage } from "@squadbase/vantage"
2
+ import {
3
+ PageShell,
4
+ PageShellContent,
5
+ PageShellDescription,
6
+ PageShellHeader,
7
+ PageShellHeading,
8
+ PageShellTitle,
9
+ } from "@squadbase/vantage/components"
10
+
11
+ export const page = definePage({
12
+ title: "Blank",
13
+ description:
14
+ "Empty PageShell with title and description. The minimal scaffold for building a dashboard from scratch.",
15
+ })
16
+
17
+ export default function HomePage() {
18
+ return (
19
+ <PageShell>
20
+ <PageShellHeader>
21
+ <PageShellHeading>
22
+ <PageShellTitle>[Template] Blank</PageShellTitle>
23
+ <PageShellDescription>
24
+ Start building your dashboard here.
25
+ </PageShellDescription>
26
+ </PageShellHeading>
27
+ </PageShellHeader>
28
+ <PageShellContent>
29
+ {/* Add content */}
30
+ </PageShellContent>
31
+ </PageShell>
32
+ )
33
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "blank-ja",
3
+ "description": "[日本語] ブランク — タイトルと説明のみの PageShell。ダッシュボードをゼロから構築するための最小骨格",
4
+ "version": "0.1.0",
5
+ "files": [
6
+ { "src": "pages/index.tsx", "dest": "index.tsx", "action": "replace" }
7
+ ]
8
+ }
@@ -0,0 +1,33 @@
1
+ import { definePage } from "@squadbase/vantage"
2
+ import {
3
+ PageShell,
4
+ PageShellContent,
5
+ PageShellDescription,
6
+ PageShellHeader,
7
+ PageShellHeading,
8
+ PageShellTitle,
9
+ } from "@squadbase/vantage/components"
10
+
11
+ export const page = definePage({
12
+ title: "ブランク",
13
+ description:
14
+ "タイトルと説明のみの PageShell。ダッシュボードをゼロから構築するための最小骨格",
15
+ })
16
+
17
+ export default function HomePage() {
18
+ return (
19
+ <PageShell>
20
+ <PageShellHeader>
21
+ <PageShellHeading>
22
+ <PageShellTitle>[テンプレート] ブランク</PageShellTitle>
23
+ <PageShellDescription>
24
+ ここからダッシュボードの構築を始めましょう。
25
+ </PageShellDescription>
26
+ </PageShellHeading>
27
+ </PageShellHeader>
28
+ <PageShellContent>
29
+ {/* コンテンツを追加 */}
30
+ </PageShellContent>
31
+ </PageShell>
32
+ )
33
+ }
@@ -0,0 +1,139 @@
1
+ import type {
2
+ TimePoint,
3
+ BarPoint,
4
+ ScatterPoint,
5
+ RadarPoint,
6
+ HeatmapCell,
7
+ } from "./types"
8
+
9
+ export const timeSeries: TimePoint[] = [
10
+ { date: "2024-03-02", series1: 16462, series2: 12092 },
11
+ { date: "2024-03-03", series1: 17807, series2: 11084 },
12
+ { date: "2024-03-04", series1: 17272, series2: 13572 },
13
+ { date: "2024-03-05", series1: 18462, series2: 13897 },
14
+ { date: "2024-03-06", series1: 19943, series2: 12100 },
15
+ { date: "2024-03-07", series1: 21026, series2: 13152 },
16
+ { date: "2024-03-08", series1: 18203, series2: 14502 },
17
+ { date: "2024-03-09", series1: 20265, series2: 13472 },
18
+ { date: "2024-03-10", series1: 18075, series2: 13476 },
19
+ { date: "2024-03-11", series1: 21018, series2: 15075 },
20
+ { date: "2024-03-12", series1: 20104, series2: 12868 },
21
+ { date: "2024-03-13", series1: 21755, series2: 15713 },
22
+ { date: "2024-03-14", series1: 20240, series2: 13282 },
23
+ { date: "2024-03-15", series1: 20796, series2: 14953 },
24
+ { date: "2024-03-16", series1: 21397, series2: 14028 },
25
+ { date: "2024-03-17", series1: 21203, series2: 13791 },
26
+ { date: "2024-03-18", series1: 19673, series2: 13895 },
27
+ { date: "2024-03-19", series1: 22335, series2: 16589 },
28
+ { date: "2024-03-20", series1: 21241, series2: 14266 },
29
+ { date: "2024-03-21", series1: 22068, series2: 14360 },
30
+ { date: "2024-03-22", series1: 21903, series2: 14062 },
31
+ { date: "2024-03-23", series1: 21685, series2: 15876 },
32
+ { date: "2024-03-24", series1: 21315, series2: 17515 },
33
+ { date: "2024-03-25", series1: 21435, series2: 14613 },
34
+ { date: "2024-03-26", series1: 23871, series2: 16287 },
35
+ { date: "2024-03-27", series1: 22747, series2: 17526 },
36
+ { date: "2024-03-28", series1: 22262, series2: 15910 },
37
+ { date: "2024-03-29", series1: 25130, series2: 16666 },
38
+ { date: "2024-03-30", series1: 23698, series2: 15561 },
39
+ { date: "2024-03-31", series1: 25719, series2: 15619 },
40
+ ]
41
+
42
+ export const barSeries: BarPoint[] = [
43
+ { value: 184_320 },
44
+ { value: 162_480 },
45
+ { value: 138_750 },
46
+ { value: 121_900 },
47
+ { value: 98_640 },
48
+ { value: 87_220 },
49
+ { value: 72_410 },
50
+ { value: 54_220 },
51
+ ]
52
+
53
+ export const scatterPoints: ScatterPoint[] = [
54
+ { x: 24, y: 750, size: 23, label: "Item 1" },
55
+ { x: 30, y: 572, size: 23, label: "Item 2" },
56
+ { x: 79, y: 692, size: 19, label: "Item 3" },
57
+ { x: 43, y: 585, size: 20, label: "Item 4" },
58
+ { x: 35, y: 626, size: 13, label: "Item 5" },
59
+ { x: 90, y: 289, size: 29, label: "Item 6" },
60
+ { x: 80, y: 851, size: 11, label: "Item 7" },
61
+ { x: 39, y: 885, size: 13, label: "Item 8" },
62
+ { x: 79, y: 768, size: 21, label: "Item 9" },
63
+ { x: 75, y: 873, size: 24, label: "Item 10" },
64
+ { x: 60, y: 676, size: 29, label: "Item 11" },
65
+ { x: 67, y: 552, size: 25, label: "Item 12" },
66
+ { x: 49, y: 876, size: 20, label: "Item 13" },
67
+ { x: 40, y: 223, size: 23, label: "Item 14" },
68
+ { x: 73, y: 768, size: 22, label: "Item 15" },
69
+ { x: 21, y: 186, size: 26, label: "Item 16" },
70
+ { x: 78, y: 652, size: 22, label: "Item 17" },
71
+ { x: 37, y: 740, size: 19, label: "Item 18" },
72
+ { x: 92, y: 827, size: 26, label: "Item 19" },
73
+ { x: 35, y: 386, size: 9, label: "Item 20" },
74
+ { x: 60, y: 694, size: 21, label: "Item 21" },
75
+ { x: 41, y: 324, size: 26, label: "Item 22" },
76
+ { x: 90, y: 552, size: 12, label: "Item 23" },
77
+ { x: 81, y: 853, size: 11, label: "Item 24" },
78
+ { x: 48, y: 702, size: 9, label: "Item 25" },
79
+ { x: 23, y: 474, size: 15, label: "Item 26" },
80
+ { x: 41, y: 544, size: 17, label: "Item 27" },
81
+ { x: 53, y: 387, size: 24, label: "Item 28" },
82
+ ]
83
+
84
+ export const radarAxes: RadarPoint[] = [
85
+ { current: 82, benchmark: 70 },
86
+ { current: 91, benchmark: 78 },
87
+ { current: 64, benchmark: 75 },
88
+ { current: 88, benchmark: 80 },
89
+ { current: 73, benchmark: 65 },
90
+ { current: 79, benchmark: 70 },
91
+ ]
92
+
93
+ export const HEATMAP_X_AXIS = ["0", "1", "2", "3", "4", "5"]
94
+ export const HEATMAP_Y_AXIS = ["Row 1", "Row 2", "Row 3", "Row 4", "Row 5", "Row 6", "Row 7"]
95
+
96
+ export const heatmapCells: HeatmapCell[] = [
97
+ { x: "0", y: "Row 1", value: 57 },
98
+ { x: "1", y: "Row 1", value: 25 },
99
+ { x: "2", y: "Row 1", value: 91 },
100
+ { x: "3", y: "Row 1", value: 77 },
101
+ { x: "4", y: "Row 1", value: 96 },
102
+ { x: "5", y: "Row 1", value: 45 },
103
+ { x: "0", y: "Row 2", value: 46 },
104
+ { x: "1", y: "Row 2", value: 32 },
105
+ { x: "2", y: "Row 2", value: 75 },
106
+ { x: "3", y: "Row 2", value: 94 },
107
+ { x: "4", y: "Row 2", value: 83 },
108
+ { x: "5", y: "Row 2", value: 37 },
109
+ { x: "0", y: "Row 3", value: 56 },
110
+ { x: "1", y: "Row 3", value: 22 },
111
+ { x: "2", y: "Row 3", value: 76 },
112
+ { x: "3", y: "Row 3", value: 85 },
113
+ { x: "4", y: "Row 3", value: 79 },
114
+ { x: "5", y: "Row 3", value: 39 },
115
+ { x: "0", y: "Row 4", value: 56 },
116
+ { x: "1", y: "Row 4", value: 12 },
117
+ { x: "2", y: "Row 4", value: 73 },
118
+ { x: "3", y: "Row 4", value: 88 },
119
+ { x: "4", y: "Row 4", value: 95 },
120
+ { x: "5", y: "Row 4", value: 19 },
121
+ { x: "0", y: "Row 5", value: 60 },
122
+ { x: "1", y: "Row 5", value: 17 },
123
+ { x: "2", y: "Row 5", value: 77 },
124
+ { x: "3", y: "Row 5", value: 85 },
125
+ { x: "4", y: "Row 5", value: 81 },
126
+ { x: "5", y: "Row 5", value: 43 },
127
+ { x: "0", y: "Row 6", value: 36 },
128
+ { x: "1", y: "Row 6", value: 56 },
129
+ { x: "2", y: "Row 6", value: 55 },
130
+ { x: "3", y: "Row 6", value: 34 },
131
+ { x: "4", y: "Row 6", value: 20 },
132
+ { x: "5", y: "Row 6", value: 27 },
133
+ { x: "0", y: "Row 7", value: 50 },
134
+ { x: "1", y: "Row 7", value: 44 },
135
+ { x: "2", y: "Row 7", value: 32 },
136
+ { x: "3", y: "Row 7", value: 55 },
137
+ { x: "4", y: "Row 7", value: 46 },
138
+ { x: "5", y: "Row 7", value: 39 },
139
+ ]
@@ -0,0 +1,31 @@
1
+ export interface TimePoint {
2
+ date: string
3
+ series1: number
4
+ series2: number
5
+ }
6
+
7
+ export interface BarPoint {
8
+ value: number
9
+ }
10
+
11
+ export interface ScatterPoint {
12
+ x: number
13
+ y: number
14
+ size: number
15
+ label: string
16
+ }
17
+
18
+ export interface RadarPoint {
19
+ current: number
20
+ benchmark: number
21
+ }
22
+
23
+ export interface HeatmapCell {
24
+ x: string
25
+ y: string
26
+ value: number
27
+ }
28
+
29
+ export interface DashboardFilters {
30
+ dateRange: { from: Date | undefined; to: Date | undefined }
31
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "chart-grid",
3
+ "description": "Chart Grid — Six-chart grid (area, line, bar, scatter, radar, heatmap) with category filter chips in the header. Visualization-only layout that puts charts in the spotlight.",
4
+ "version": "0.1.0",
5
+ "files": [
6
+ { "src": "pages/index.tsx", "dest": "index.tsx", "action": "replace" },
7
+ { "src": "lib/mock-data.ts", "dest": "components/chart-grid/mock-data.ts", "action": "add", "relabel": false },
8
+ { "src": "lib/types.ts", "dest": "components/chart-grid/types.ts", "action": "add", "relabel": false }
9
+ ]
10
+ }