@squadbase/vantage 0.0.1 → 0.1.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.
- package/README.md +24 -4
- package/dist/{chunk-ZGDU5YLH.js → chunk-5L2MH2NG.js} +16 -7
- package/dist/chunk-5L2MH2NG.js.map +1 -0
- package/dist/chunk-7IPAXPPY.js +51 -0
- package/dist/chunk-7IPAXPPY.js.map +1 -0
- package/dist/chunk-A2UUGASH.js +12 -0
- package/dist/chunk-A2UUGASH.js.map +1 -0
- package/dist/chunk-DTDVSFRY.js +29 -0
- package/dist/chunk-DTDVSFRY.js.map +1 -0
- package/dist/chunk-WQZYXXQW.js +2249 -0
- package/dist/chunk-WQZYXXQW.js.map +1 -0
- package/dist/{chunk-73J5ZD4C.js → chunk-YLAB6UQS.js} +17 -3
- package/dist/chunk-YLAB6UQS.js.map +1 -0
- package/dist/cli.js +607 -36
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/components/index.d.ts +575 -0
- package/dist/components/index.js +2097 -0
- package/dist/components/index.js.map +1 -0
- package/dist/{define-page-B6y9TOfZ.d.ts → define-page-BfhrK99G.d.ts} +5 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/markdown/index.d.ts +9 -0
- package/dist/markdown/index.js +26 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/query/index.d.ts +95 -2
- package/dist/query/index.js +102 -1
- package/dist/query/index.js.map +1 -1
- package/dist/router/index.d.ts +86 -1
- package/dist/router/index.js +71 -7
- package/dist/router/index.js.map +1 -1
- package/dist/server/node.js +6 -1
- package/dist/server/node.js.map +1 -1
- package/dist/ui/index.d.ts +316 -200
- package/dist/ui/index.js +566 -511
- package/dist/ui/index.js.map +1 -1
- package/dist/vite/index.js +2 -2
- package/docs/en/agent-skills.md +89 -0
- package/docs/en/api-and-server.md +84 -0
- package/docs/en/build-and-deploy.md +280 -0
- package/docs/en/cli-reference.md +311 -0
- package/docs/en/components.md +235 -0
- package/docs/en/data-fetching.md +142 -0
- package/docs/en/environment-variables.md +69 -0
- package/docs/en/getting-started.md +95 -0
- package/docs/en/index.md +65 -0
- package/docs/en/markdown/markdown-renderer.md +44 -0
- package/docs/en/pages-and-metadata.md +59 -0
- package/docs/en/parts/app-shell.md +54 -0
- package/docs/en/parts/dashboard-card.md +64 -0
- package/docs/en/parts/data-table.md +86 -0
- package/docs/en/parts/date-range-picker.md +41 -0
- package/docs/en/parts/echart.md +53 -0
- package/docs/en/parts/filter-bar.md +66 -0
- package/docs/en/parts/funnel-steps.md +33 -0
- package/docs/en/parts/metric-value.md +23 -0
- package/docs/en/parts/multi-select.md +27 -0
- package/docs/en/parts/page-shell.md +45 -0
- package/docs/en/parts/placeholder.md +38 -0
- package/docs/en/parts/searchable-select.md +47 -0
- package/docs/en/parts/section-header.md +20 -0
- package/docs/en/parts/segmented-control.md +25 -0
- package/docs/en/parts/sparkline.md +47 -0
- package/docs/en/parts/status-badge.md +44 -0
- package/docs/en/parts/trend-indicator.md +26 -0
- package/docs/en/routing.md +177 -0
- package/docs/en/ui/accordion.md +36 -0
- package/docs/en/ui/alert.md +31 -0
- package/docs/en/ui/badge.md +23 -0
- package/docs/en/ui/breadcrumb.md +38 -0
- package/docs/en/ui/button.md +39 -0
- package/docs/en/ui/calendar.md +28 -0
- package/docs/en/ui/card.md +35 -0
- package/docs/en/ui/checkbox.md +34 -0
- package/docs/en/ui/cn.md +34 -0
- package/docs/en/ui/collapsible.md +21 -0
- package/docs/en/ui/command.md +37 -0
- package/docs/en/ui/dialog.md +52 -0
- package/docs/en/ui/dropdown-menu.md +50 -0
- package/docs/en/ui/empty.md +22 -0
- package/docs/en/ui/error-state.md +50 -0
- package/docs/en/ui/input-group.md +30 -0
- package/docs/en/ui/input.md +28 -0
- package/docs/en/ui/label.md +19 -0
- package/docs/en/ui/loading.md +19 -0
- package/docs/en/ui/popover.md +34 -0
- package/docs/en/ui/progress.md +28 -0
- package/docs/en/ui/scroll-area.md +23 -0
- package/docs/en/ui/select.md +63 -0
- package/docs/en/ui/separator.md +15 -0
- package/docs/en/ui/sheet.md +28 -0
- package/docs/en/ui/sidebar.md +92 -0
- package/docs/en/ui/skeleton.md +16 -0
- package/docs/en/ui/slider.md +21 -0
- package/docs/en/ui/spinner.md +14 -0
- package/docs/en/ui/switch.md +19 -0
- package/docs/en/ui/table.md +24 -0
- package/docs/en/ui/tabs.md +23 -0
- package/docs/en/ui/textarea.md +15 -0
- package/docs/en/ui/toggle-group.md +26 -0
- package/docs/en/ui/toggle.md +19 -0
- package/docs/en/ui/tooltip.md +22 -0
- package/docs/en/ui/use-is-mobile.md +18 -0
- package/docs/en/ui-and-theming.md +95 -0
- package/docs/index.json +1346 -0
- package/docs/ja/agent-skills.md +87 -0
- package/docs/ja/api-and-server.md +84 -0
- package/docs/ja/build-and-deploy.md +279 -0
- package/docs/ja/cli-reference.md +305 -0
- package/docs/ja/components.md +231 -0
- package/docs/ja/data-fetching.md +142 -0
- package/docs/ja/environment-variables.md +68 -0
- package/docs/ja/getting-started.md +95 -0
- package/docs/ja/index.md +65 -0
- package/docs/ja/markdown/markdown-renderer.md +43 -0
- package/docs/ja/pages-and-metadata.md +59 -0
- package/docs/ja/parts/app-shell.md +54 -0
- package/docs/ja/parts/dashboard-card.md +64 -0
- package/docs/ja/parts/data-table.md +85 -0
- package/docs/ja/parts/date-range-picker.md +41 -0
- package/docs/ja/parts/echart.md +52 -0
- package/docs/ja/parts/filter-bar.md +64 -0
- package/docs/ja/parts/funnel-steps.md +33 -0
- package/docs/ja/parts/metric-value.md +25 -0
- package/docs/ja/parts/multi-select.md +27 -0
- package/docs/ja/parts/page-shell.md +45 -0
- package/docs/ja/parts/placeholder.md +37 -0
- package/docs/ja/parts/searchable-select.md +47 -0
- package/docs/ja/parts/section-header.md +20 -0
- package/docs/ja/parts/segmented-control.md +26 -0
- package/docs/ja/parts/sparkline.md +47 -0
- package/docs/ja/parts/status-badge.md +44 -0
- package/docs/ja/parts/trend-indicator.md +26 -0
- package/docs/ja/routing.md +175 -0
- package/docs/ja/ui/accordion.md +37 -0
- package/docs/ja/ui/alert.md +31 -0
- package/docs/ja/ui/badge.md +23 -0
- package/docs/ja/ui/breadcrumb.md +38 -0
- package/docs/ja/ui/button.md +39 -0
- package/docs/ja/ui/calendar.md +28 -0
- package/docs/ja/ui/card.md +35 -0
- package/docs/ja/ui/checkbox.md +34 -0
- package/docs/ja/ui/cn.md +34 -0
- package/docs/ja/ui/collapsible.md +21 -0
- package/docs/ja/ui/command.md +36 -0
- package/docs/ja/ui/dialog.md +51 -0
- package/docs/ja/ui/dropdown-menu.md +50 -0
- package/docs/ja/ui/empty.md +22 -0
- package/docs/ja/ui/error-state.md +50 -0
- package/docs/ja/ui/input-group.md +30 -0
- package/docs/ja/ui/input.md +28 -0
- package/docs/ja/ui/label.md +19 -0
- package/docs/ja/ui/loading.md +19 -0
- package/docs/ja/ui/popover.md +34 -0
- package/docs/ja/ui/progress.md +28 -0
- package/docs/ja/ui/scroll-area.md +24 -0
- package/docs/ja/ui/select.md +64 -0
- package/docs/ja/ui/separator.md +15 -0
- package/docs/ja/ui/sheet.md +28 -0
- package/docs/ja/ui/sidebar.md +92 -0
- package/docs/ja/ui/skeleton.md +16 -0
- package/docs/ja/ui/slider.md +21 -0
- package/docs/ja/ui/spinner.md +14 -0
- package/docs/ja/ui/switch.md +19 -0
- package/docs/ja/ui/table.md +24 -0
- package/docs/ja/ui/tabs.md +24 -0
- package/docs/ja/ui/textarea.md +15 -0
- package/docs/ja/ui/toggle-group.md +27 -0
- package/docs/ja/ui/toggle.md +19 -0
- package/docs/ja/ui/tooltip.md +22 -0
- package/docs/ja/ui/use-is-mobile.md +18 -0
- package/docs/ja/ui-and-theming.md +95 -0
- package/package.json +29 -4
- package/registry/blocks/sales-overview.tsx +43 -19
- package/registry/ui/data-table.tsx +702 -102
- package/skills/vantage-add-feature/SKILL.md +153 -0
- package/skills/vantage-app/SKILL.md +291 -0
- package/skills/vantage-pitfalls/SKILL.md +139 -0
- package/templates/AGENTS.md +313 -0
- package/theme.css +178 -40
- package/dist/chunk-73J5ZD4C.js.map +0 -1
- package/dist/chunk-ATYZ45XL.js +0 -19
- package/dist/chunk-ATYZ45XL.js.map +0 -1
- package/dist/chunk-ZGDU5YLH.js.map +0 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# 環境変数
|
|
2
|
+
|
|
3
|
+
> PUBLIC_ 接頭辞の env だけがクライアントに届く。シークレットはサーバーの env から読む。
|
|
4
|
+
|
|
5
|
+
Vantage は、環境変数を**クライアントに漏らさない**ことを既定にしています。境界は接頭辞で決まります。
|
|
6
|
+
|
|
7
|
+
## クライアントに届くのは `PUBLIC_` だけ
|
|
8
|
+
|
|
9
|
+
`PUBLIC_` で始まる変数だけがクライアントバンドルに入り、`import.meta.env` から読めます。
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
// クライアントコード
|
|
13
|
+
const analyticsId = import.meta.env.PUBLIC_ANALYTICS_ID;
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
クライアントで参照できるのは次だけです。
|
|
17
|
+
|
|
18
|
+
- `PUBLIC_*`(あなたが定義した公開値)
|
|
19
|
+
- `MODE` / `DEV` / `PROD` / `SSR` / `BASE_URL`(Vite の標準)
|
|
20
|
+
|
|
21
|
+
> [!WARNING]
|
|
22
|
+
> `PUBLIC_` 接頭辞の**付いていない** env をクライアントで読もうとすると、`vantage check` が
|
|
23
|
+
> `PUBLIC_ENV_MISUSE` 警告を出します。ユーザー向けの `VITE_` API は存在しません。
|
|
24
|
+
|
|
25
|
+
## シークレットはサーバーの `env` から
|
|
26
|
+
|
|
27
|
+
API キーやトークンなどの秘密情報は、**クライアントに出さず**サーバーの `ApiContext.env` から
|
|
28
|
+
読みます。これらは接頭辞を付けません。
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// server/api/report.ts
|
|
32
|
+
import type { ApiContext } from "@squadbase/vantage/server";
|
|
33
|
+
|
|
34
|
+
export async function GET({ env }: ApiContext) {
|
|
35
|
+
const apiKey = env.SECRET_API_KEY; // クライアントには決して届かない
|
|
36
|
+
// …外部サービスを呼ぶ
|
|
37
|
+
return Response.json({ ok: true });
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## `.env` の例
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# .env
|
|
45
|
+
PUBLIC_ANALYTICS_ID=UA-XXXX # クライアントに届く
|
|
46
|
+
SECRET_API_KEY=sk_live_xxx # サーバー専用(ApiContext.env)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
> [!NOTE]
|
|
50
|
+
> dev サーバーはリクエストごとに env を読み直します。本番の Node サーバーは起動時に一度だけ
|
|
51
|
+
> `process.env` をスナップショットします。
|
|
52
|
+
|
|
53
|
+
## デプロイで使う env
|
|
54
|
+
|
|
55
|
+
フロントとサーバーを別オリジンにデプロイするときは、次の env が関わります。
|
|
56
|
+
|
|
57
|
+
| 変数 | 側 | 役割 |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `PUBLIC_API_BASE_URL` | クライアント(公開) | クライアントが `/api` を呼ぶベースURL。`--api-base-url` でも上書き可 |
|
|
60
|
+
| `CORS_ORIGIN` | サーバー | `/api` に対して許可するオリジン。未設定なら CORS 無効 |
|
|
61
|
+
| `CORS_CREDENTIALS` | サーバー | `true` で資格情報(Cookie 等)を許可 |
|
|
62
|
+
|
|
63
|
+
使い方は[ビルドとデプロイ](build-and-deploy)で詳しく解説します。
|
|
64
|
+
|
|
65
|
+
## 次に読む
|
|
66
|
+
|
|
67
|
+
- [ビルドとデプロイ](build-and-deploy) — 本番の env と別オリジン構成
|
|
68
|
+
- [UI とテーマ](ui-and-theming) — 見た目を整える
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# はじめに
|
|
2
|
+
|
|
3
|
+
> インストールから最初の Vantage アプリを起動するまで。
|
|
4
|
+
|
|
5
|
+
## 前提
|
|
6
|
+
|
|
7
|
+
- **Node.js 20 以上**
|
|
8
|
+
- パッケージマネージャ(pnpm / npm / yarn のいずれか)
|
|
9
|
+
|
|
10
|
+
## 最小のアプリを作る
|
|
11
|
+
|
|
12
|
+
### Vantage を追加する
|
|
13
|
+
|
|
14
|
+
プロジェクトに `@squadbase/vantage` を追加します。
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @squadbase/vantage
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### index.tsx を書く
|
|
21
|
+
|
|
22
|
+
プロジェクトルートに `index.tsx` を 1 つ置きます。**default export されたコンポーネント**が
|
|
23
|
+
ルート `/` になります。
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// index.tsx
|
|
27
|
+
export default function Dashboard() {
|
|
28
|
+
return (
|
|
29
|
+
<main className="p-6">
|
|
30
|
+
<h1 className="text-2xl font-semibold">Dashboard</h1>
|
|
31
|
+
</main>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 開発サーバーを起動する
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pnpm exec vantage dev
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`http://localhost:5173` が立ち上がります。HMR(ホットリロード)が効き、ページを編集すると
|
|
43
|
+
React Fast Refresh がその場で反映します。
|
|
44
|
+
|
|
45
|
+
> [!TIP]
|
|
46
|
+
> 素の `pnpm add` 直後は `vantage` バイナリが PATH に無いため、`pnpm exec vantage`(または
|
|
47
|
+
> `npx vantage`)で起動します。`package.json` の `scripts` に `"dev": "vantage dev"` を足せば
|
|
48
|
+
> `pnpm dev` で起動できます。
|
|
49
|
+
|
|
50
|
+
## 開発ループ
|
|
51
|
+
|
|
52
|
+
| コマンド | 役割 |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `vantage dev` | 開発サーバー(HMR + オプションの API)。既定 `:5173` |
|
|
55
|
+
| `vantage build` | 本番ビルド → `dist/`(クライアント + オプションのサーバー) |
|
|
56
|
+
| `vantage preview` | 本番ビルドをローカルで起動 |
|
|
57
|
+
| `vantage check` | 静的検査(ルート・境界・禁止ファイル)。エラー時は exit 1 |
|
|
58
|
+
| `vantage routes` | ページ + API の URL マップを表示 |
|
|
59
|
+
|
|
60
|
+
> [!TIP]
|
|
61
|
+
> `vantage dev` の実行中は、ブラウザの `console.*` と未捕捉のエラーが開発ターミナルへ
|
|
62
|
+
> `[browser:…]` として転送されます。多くの不具合はブラウザを開かずに診断できます。
|
|
63
|
+
|
|
64
|
+
## クイックモード(パスを直接渡す)
|
|
65
|
+
|
|
66
|
+
`cd` せずに、**プロジェクトのパスを直接**渡して開発サーバーを起動できます。手元のフォルダや
|
|
67
|
+
エントリファイルをそのまま指すだけで `dev` が立ち上がります。
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
vantage ./demo # フォルダ → その中で dev を起動
|
|
71
|
+
vantage ./demo/index.tsx # ページファイル → 親フォルダを root にして dev
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
第 1 引数が既知コマンドでなくパスを指すとき、Vantage はそれを root として `dev` を起動します
|
|
75
|
+
(`quick dev → <path>` と表示)。詳しい解決ルールは
|
|
76
|
+
[CLI リファレンス](cli-reference)を参照してください。
|
|
77
|
+
|
|
78
|
+
## 設定ファイルは書かない
|
|
79
|
+
|
|
80
|
+
Vantage は「設定より規約」を徹底しています。次のファイルはプロジェクトに置くと **ハードエラー**
|
|
81
|
+
(`vantage check` が失敗)になります。
|
|
82
|
+
|
|
83
|
+
- `vite.config.*`
|
|
84
|
+
- `tailwind.config.*`
|
|
85
|
+
- `postcss.config.*`
|
|
86
|
+
- `components.json`
|
|
87
|
+
- `vantage.config.*`
|
|
88
|
+
|
|
89
|
+
これらが担っていた役割は、すべて Vantage 側が持っています。カスタマイズが必要なときは、
|
|
90
|
+
各ガイドで説明する「明示的なエスケープハッチ」を使います。
|
|
91
|
+
|
|
92
|
+
## 次に読む
|
|
93
|
+
|
|
94
|
+
- [ファイルベースルーティング](routing) — ページを増やす
|
|
95
|
+
- [ページと definePage](pages-and-metadata) — ページの契約とメタデータ
|
package/docs/ja/index.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Vantage とは
|
|
2
|
+
|
|
3
|
+
> 設定ファイル不要(config-free)な React ダッシュボードフレームワーク。書くのは index.tsx だけ。
|
|
4
|
+
|
|
5
|
+
**Vantage**(ヴァンテージ)は「見晴らしのいい地点」を意味する言葉です。データ全体を一望できる
|
|
6
|
+
ダッシュボードを、最小の手間で用意する ― その姿勢を名前に込めています。
|
|
7
|
+
|
|
8
|
+
**Vantage** は [Squadbase Editor](https://squadbase.dev) 向けの、設定ファイル不要(config-free)な
|
|
9
|
+
React ダッシュボードフレームワークです。Vite 8 の上に構築されており、アプリ作者が書くのは
|
|
10
|
+
`index.tsx` **1 ファイルだけ**。ルーティング・React のセットアップ・TanStack Query・Tailwind CSS・
|
|
11
|
+
UI キット・開発サーバー・オプションの API サーバー・ビルドは、すべて **Vantage が所有**します。
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
// index.tsx → ルート "/"
|
|
15
|
+
export default function Dashboard() {
|
|
16
|
+
return (
|
|
17
|
+
<main className="p-6">
|
|
18
|
+
<h1 className="text-2xl font-semibold">Dashboard</h1>
|
|
19
|
+
</main>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
この 7 行が、そのまま動くダッシュボードアプリになります。`vite.config`・`tailwind.config`・
|
|
25
|
+
`postcss.config`・`components.json`・`vantage.config` は **一切書きません**。
|
|
26
|
+
|
|
27
|
+
> [!NOTE]
|
|
28
|
+
> このサイトは **アプリ作者**(Vantage を使ってダッシュボードを作る人)向けのガイドです。
|
|
29
|
+
> フレームワーク自体の内部実装については、リポジトリの `README.md` と設計ドキュメントを参照してください。
|
|
30
|
+
|
|
31
|
+
## 特徴
|
|
32
|
+
|
|
33
|
+
### まず 1 ファイル
|
|
34
|
+
|
|
35
|
+
単一の `index.tsx` が完結したアプリになる。ページを増やしたくなったら `.tsx` を足すだけ。
|
|
36
|
+
|
|
37
|
+
### 設定より規約
|
|
38
|
+
|
|
39
|
+
設定ファイルは不要どころか禁止。ファイル名とディレクトリの規約がすべてを駆動する。
|
|
40
|
+
|
|
41
|
+
### 管理されたスタック
|
|
42
|
+
|
|
43
|
+
React・Vite・TanStack Router/Query・Tailwind・UI キットのバージョンは Vantage が固定する。
|
|
44
|
+
|
|
45
|
+
### サーバーはオプション
|
|
46
|
+
|
|
47
|
+
`server/` を足すと API が有効になる。なければクライアントのみの SPA。
|
|
48
|
+
|
|
49
|
+
## 次のステップ
|
|
50
|
+
|
|
51
|
+
### はじめに
|
|
52
|
+
|
|
53
|
+
インストールから最初のアプリの起動まで。
|
|
54
|
+
|
|
55
|
+
### ファイルベースルーティング
|
|
56
|
+
|
|
57
|
+
ファイルを置くだけでルートが生まれる仕組み。
|
|
58
|
+
|
|
59
|
+
### データ取得
|
|
60
|
+
|
|
61
|
+
管理された TanStack Query でサーバー状態を扱う。
|
|
62
|
+
|
|
63
|
+
### API とサーバー
|
|
64
|
+
|
|
65
|
+
`server/api` でバックエンドを書く。
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# MarkdownRenderer
|
|
2
|
+
|
|
3
|
+
> Markdown を描画する。シンタックスハイライト込み。
|
|
4
|
+
|
|
5
|
+
Markdown 文字列を描画します。表・コードブロック(シンタックスハイライト付き)・数式まで扱える
|
|
6
|
+
ので、LLM の出力や、データベースに入っている説明文をそのまま出すのに使えます。
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { MarkdownRenderer } from "@squadbase/vantage/markdown";
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
| Prop | Type | 説明 |
|
|
13
|
+
| --- | --- | --- |
|
|
14
|
+
| `content` | `string` | 描画する Markdown。 |
|
|
15
|
+
| `className` | `string` | 足すクラス。 |
|
|
16
|
+
|
|
17
|
+
## なぜ別のサブパスなのか
|
|
18
|
+
|
|
19
|
+
`@squadbase/vantage/components` からは**意図的に再エクスポートしていません**。Markdown の描画は
|
|
20
|
+
Shiki の全言語文法を抱えており、import の辺があるだけでバンドラは落とせません。共有のバレルに
|
|
21
|
+
置くと、Markdown を使わないアプリのビルド出力まで約 11 MB / 300 ファイル増えます。
|
|
22
|
+
|
|
23
|
+
別サブパスにしてあるので、**このコンポーネントを import したアプリだけ**がその重さを負担します。
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// これは重い(そして、それでよい)
|
|
27
|
+
import { MarkdownRenderer } from "@squadbase/vantage/markdown";
|
|
28
|
+
|
|
29
|
+
// これは軽いまま
|
|
30
|
+
import { DashboardCardPreset } from "@squadbase/vantage/components";
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## LLM の出力を流す
|
|
34
|
+
|
|
35
|
+
`content` を差し替えるだけなので、ストリーミングされてくる途中の文字列をそのまま渡せます。
|
|
36
|
+
未完成の Markdown(閉じていないコードブロックなど)も壊れずに描画されます。
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
const [text, setText] = useState("");
|
|
40
|
+
// …チャンクが来るたびに setText((prev) => prev + chunk)
|
|
41
|
+
|
|
42
|
+
<MarkdownRenderer content={text} />;
|
|
43
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# ページと definePage
|
|
2
|
+
|
|
3
|
+
> ページの唯一の要件は default export。definePage でタイトルと説明を静的に付与する。
|
|
4
|
+
|
|
5
|
+
## 唯一の要件は default export
|
|
6
|
+
|
|
7
|
+
Vantage のページに必要なのは、**React コンポーネントの default export だけ**です。
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
export default function MonthlyAnalysis() {
|
|
11
|
+
return <h1>月次分析</h1>;
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
default export が無いページは `vantage check` が `MISSING_DEFAULT_EXPORT` エラーで指摘します。
|
|
16
|
+
|
|
17
|
+
## definePage でメタデータを付ける
|
|
18
|
+
|
|
19
|
+
タイトルや説明を付けたいときは `definePage` を使います。任意です。
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { definePage } from "@squadbase/vantage";
|
|
23
|
+
|
|
24
|
+
export const page = definePage({
|
|
25
|
+
title: "月次分析 · Acme Analytics",
|
|
26
|
+
navLabel: "月次分析",
|
|
27
|
+
description: "売上と主要指標の月次サマリー",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export default function MonthlyAnalysis() {
|
|
31
|
+
return <h1>月次分析</h1>;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- `title` は `document.title` を駆動します(末端のルートマッチのタイトルが使われ、無ければ
|
|
36
|
+
ドキュメント初期の `<title>` にフォールバック)。
|
|
37
|
+
- `navLabel` は [`useRoutes()`](routing#ルート一覧からナビを作る) で組むナビの表示名です。
|
|
38
|
+
省略すると `title` が使われます。`title` にサイト名を含めるときに分けます。
|
|
39
|
+
- `title`/`description`/`navLabel` は **生成時に静的に読まれます**。Vantage はページを実行して
|
|
40
|
+
読むのではなく、ソースを静的に解析します。したがって値は**リテラル**にしてください。
|
|
41
|
+
|
|
42
|
+
> [!WARNING]
|
|
43
|
+
> `export const page = definePage({...})` の**エクスポート名は `page` 固定**です。別名にすると
|
|
44
|
+
> メタデータが読まれません。
|
|
45
|
+
|
|
46
|
+
## Fast Refresh との関係
|
|
47
|
+
|
|
48
|
+
`page` のような非コンポーネントのエクスポートがあっても、Vantage はそれを内部で扱うため
|
|
49
|
+
React Fast Refresh は生き残ります。ページ本体を編集しても、state を保ったまま更新されます。
|
|
50
|
+
|
|
51
|
+
## プロトタイプの制約
|
|
52
|
+
|
|
53
|
+
`definePage` は `pendingComponent` / `errorComponent` / `validateSearch` も型として受け付けますが、
|
|
54
|
+
現行プロトタイプでは **lazy ルートにまだ結線されていません**。ページごとの pending/error UI の
|
|
55
|
+
上書きは未実装で、フレームワーク共通のデフォルトが描画されます。
|
|
56
|
+
|
|
57
|
+
## 次に読む
|
|
58
|
+
|
|
59
|
+
- [データ取得](data-fetching) — サーバー状態を扱う
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# AppShell
|
|
2
|
+
|
|
3
|
+
> ナビゲーション定義を渡すだけのアプリ枠。
|
|
4
|
+
|
|
5
|
+
アプリ全体の外枠です。`groups` にナビゲーションを配列で渡すだけで、折りたためるサイドバー
|
|
6
|
+
(または狭い画面向けのヘッダー)が組み上がります。[`Sidebar`](ui/sidebar) を自分で
|
|
7
|
+
組む代わりに使ってください。
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { AppShell } from "@squadbase/vantage/components";
|
|
11
|
+
import type { NavGroup, NavItem } from "@squadbase/vantage/components";
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Default | 説明 |
|
|
15
|
+
| --- | --- | --- | --- |
|
|
16
|
+
| `groups` | `NavGroup[]` | | ナビゲーション。`{ label?, items: NavItem[] }` の配列。 |
|
|
17
|
+
| `variant` | `"sidebar" \| "header"` | `"sidebar"` | サイドバー枠か、セレクト式のヘッダー枠か。 |
|
|
18
|
+
| `actions` | `ReactNode` | | 上部右端に置く要素。 |
|
|
19
|
+
| `header` | `ReactNode` | | 既定のヘッダーを丸ごと差し替える。 |
|
|
20
|
+
| `defaultOpen` | `boolean` | `true` | `variant="sidebar"` のとき、初期状態で開いているか。 |
|
|
21
|
+
| `linkComponent` | `ElementType` | | 項目を描くリンクコンポーネント。 |
|
|
22
|
+
| `onNavigate` | `(href: string) => void` | | 項目が選ばれたとき。既定では `location.assign`。 |
|
|
23
|
+
|
|
24
|
+
## NavItem
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
interface NavItem {
|
|
28
|
+
label: string;
|
|
29
|
+
href: string;
|
|
30
|
+
icon?: ComponentType<{ className?: string }>;
|
|
31
|
+
isActive?: boolean;
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
badge?: string;
|
|
34
|
+
children?: NavItem[]; // 折りたたむサブ項目
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`children` を持つ項目は、開閉するサブメニューになります。
|
|
39
|
+
|
|
40
|
+
## ルーターと繋ぐ
|
|
41
|
+
|
|
42
|
+
クライアントサイド遷移にしたいときは `onNavigate` を渡します。
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { useNavigate } from "@squadbase/vantage/router";
|
|
46
|
+
|
|
47
|
+
const navigate = useNavigate();
|
|
48
|
+
|
|
49
|
+
<AppShell groups={groups} onNavigate={(href) => navigate({ to: href })}>
|
|
50
|
+
{children}
|
|
51
|
+
</AppShell>;
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
現在地の強調は `isActive` で指定します — ルートのパスと `href` を突き合わせて立ててください。
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# DashboardCard
|
|
2
|
+
|
|
3
|
+
> ダッシュボードのタイル。プリセットとスケルトン付き。
|
|
4
|
+
|
|
5
|
+
ダッシュボードに並べるタイルです。素の [`Card`](ui/card) より余白が詰まっており、
|
|
6
|
+
読み込み中用のスケルトンが同じ形で用意されています。よくある組み方は
|
|
7
|
+
`DashboardCardPreset` 一つで済みます。
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import {
|
|
11
|
+
DashboardCard,
|
|
12
|
+
DashboardCardHeader,
|
|
13
|
+
DashboardCardTitle,
|
|
14
|
+
DashboardCardDescription,
|
|
15
|
+
DashboardCardAction,
|
|
16
|
+
DashboardCardContent,
|
|
17
|
+
DashboardCardFooter,
|
|
18
|
+
DashboardCardSkeleton,
|
|
19
|
+
DashboardCardPreset,
|
|
20
|
+
} from "@squadbase/vantage/components";
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## DashboardCardPreset
|
|
24
|
+
|
|
25
|
+
| Prop | Type | 説明 |
|
|
26
|
+
| --- | --- | --- |
|
|
27
|
+
| `title` | `ReactNode` | 見出し。 |
|
|
28
|
+
| `description` | `ReactNode` | 見出しの下の補足。 |
|
|
29
|
+
| `actions` | `ReactNode` | 見出し行の右端。 |
|
|
30
|
+
| `footer` | `ReactNode` | 下端の行。 |
|
|
31
|
+
| `children` | `ReactNode` | 本文。 |
|
|
32
|
+
| `headerClassName` | `string` | |
|
|
33
|
+
| `contentClassName` | `string` | |
|
|
34
|
+
| `footerClassName` | `string` | |
|
|
35
|
+
|
|
36
|
+
`title` / `description` / `actions` がすべて未指定ならヘッダーごと省かれます。`footer` も同様です。
|
|
37
|
+
|
|
38
|
+
## 自分で組む
|
|
39
|
+
|
|
40
|
+
配置を変えたいときは、パーツを直接使います。
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<DashboardCard>
|
|
44
|
+
<DashboardCardHeader>
|
|
45
|
+
<div>
|
|
46
|
+
<DashboardCardTitle>売上</DashboardCardTitle>
|
|
47
|
+
<DashboardCardDescription>今月</DashboardCardDescription>
|
|
48
|
+
</div>
|
|
49
|
+
<DashboardCardAction>
|
|
50
|
+
<Button variant="ghost" size="xs">詳細</Button>
|
|
51
|
+
</DashboardCardAction>
|
|
52
|
+
</DashboardCardHeader>
|
|
53
|
+
<DashboardCardContent>…</DashboardCardContent>
|
|
54
|
+
<DashboardCardFooter>前月比 +12.4%</DashboardCardFooter>
|
|
55
|
+
</DashboardCard>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 読み込み中
|
|
59
|
+
|
|
60
|
+
`DashboardCardSkeleton` は同じ寸法の箱を描くので、データが届いても画面が跳ねません。
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
{isLoading ? <DashboardCardSkeleton /> : <DashboardCardPreset title="売上">…</DashboardCardPreset>}
|
|
64
|
+
```
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# DataTable
|
|
2
|
+
|
|
3
|
+
> TanStack Table ベースの表。並べ替え・検索・ページング・選択。
|
|
4
|
+
|
|
5
|
+
並べ替え・検索・ページング・行選択・列の表示切り替えを備えた表です。中身は TanStack Table で、
|
|
6
|
+
列定義は TanStack の `ColumnDef` そのものです。ひととおり揃った形が欲しいだけなら
|
|
7
|
+
`DataTablePreset` の 1 コンポーネントで済みます。
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import {
|
|
11
|
+
DataTable,
|
|
12
|
+
DataTableToolbar,
|
|
13
|
+
DataTableContent,
|
|
14
|
+
DataTablePagination,
|
|
15
|
+
DataTableColumnVisibility,
|
|
16
|
+
DataTablePreset,
|
|
17
|
+
useDataTable,
|
|
18
|
+
} from "@squadbase/vantage/components";
|
|
19
|
+
import type { ColumnDef, SortingState, PaginationState } from "@squadbase/vantage/components";
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## DataTablePreset
|
|
23
|
+
|
|
24
|
+
まずこれを試してください。ツールバー・本体・ページャを既定の並びで組み上げます。
|
|
25
|
+
|
|
26
|
+
| Prop | Type | 説明 |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| `columns` | `ColumnDef<TData>[]` | TanStack Table の列定義。 |
|
|
29
|
+
| `data` | `TData[]` | 行データ。 |
|
|
30
|
+
| `enableSorting` | `boolean` | ヘッダークリックで並べ替える。 |
|
|
31
|
+
| `enableFiltering` | `boolean` | ツールバーに検索欄を出す。 |
|
|
32
|
+
| `enablePagination` | `boolean` | ページャを出す。 |
|
|
33
|
+
| `enableRowSelection` | `boolean` | 先頭にチェックボックス列を足す。 |
|
|
34
|
+
| `enableColumnVisibility` | `boolean` | 表示する列を選ぶメニューを出す。 |
|
|
35
|
+
| `columnLabels` | `Record<string, string>` | 列メニューに出す表示名。 |
|
|
36
|
+
| `toolbar` | `ReactNode` | ツールバーに差し込む要素。 |
|
|
37
|
+
| `bulkActions` | `(selectedRows: TData[]) => ReactNode` | 行を選択しているときに出す操作。 |
|
|
38
|
+
| `pageCount` | `number` | サーバー側ページングのときの総ページ数。 |
|
|
39
|
+
|
|
40
|
+
`sorting` / `columnFilters` / `globalFilter` / `pagination` / `rowSelection` /
|
|
41
|
+
`columnVisibility` は、対応する `on…Change` と一緒に渡せば制御コンポーネントになります。渡さな
|
|
42
|
+
ければ内部で状態を持ちます。
|
|
43
|
+
|
|
44
|
+
## 自分で組む
|
|
45
|
+
|
|
46
|
+
配置を変えたいときはパーツを直接使います。状態は `DataTable` が持ち、子のパーツが読みます。
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<DataTable columns={columns} data={data} enableSorting enableFiltering>
|
|
50
|
+
<DataTableToolbar showSearch toolbar={<FilterBarPreset … />} />
|
|
51
|
+
<DataTableContent />
|
|
52
|
+
<DataTablePagination pageSizeOptions={[10, 25, 50]} />
|
|
53
|
+
</DataTable>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`useDataTable()` を使うと、子コンポーネントから TanStack の `table` インスタンスを直接触れます。
|
|
57
|
+
|
|
58
|
+
## サーバー側でページングする
|
|
59
|
+
|
|
60
|
+
`pagination` と `onPaginationChange` を自分で持ち、`pageCount` に総ページ数を渡します。
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 25 });
|
|
64
|
+
|
|
65
|
+
const { data } = useQuery({
|
|
66
|
+
queryKey: ["sales", pagination],
|
|
67
|
+
queryFn: () => apiFetch(`/api/sales?page=${pagination.pageIndex}`).then((r) => r.json()),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
<DataTablePreset
|
|
71
|
+
columns={columns}
|
|
72
|
+
data={data.rows}
|
|
73
|
+
pagination={pagination}
|
|
74
|
+
onPaginationChange={setPagination}
|
|
75
|
+
pageCount={data.pageCount}
|
|
76
|
+
/>;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## ソースを編集したいとき
|
|
80
|
+
|
|
81
|
+
`DataTable` だけは編集可能なソースをコピーできます。
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
vantage add ui data-table
|
|
85
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# DateRangePicker
|
|
2
|
+
|
|
3
|
+
> プリセット付きの期間選択。
|
|
4
|
+
|
|
5
|
+
「今日」「直近 7 日」といったプリセットと、2 か月分のカレンダーを組み合わせた期間選択です。
|
|
6
|
+
ダッシュボードの期間指定はこれで足ります。
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { DateRangePicker, defaultPresets } from "@squadbase/vantage/components";
|
|
10
|
+
import type { DateRange, PresetItem } from "@squadbase/vantage/components";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | 説明 |
|
|
14
|
+
| --- | --- | --- | --- |
|
|
15
|
+
| `value` | `DateRange` | | `{ from, to }`。どちらも `Date \| undefined`。 |
|
|
16
|
+
| `onChange` | `(range: DateRange) => void` | | 確定時。 |
|
|
17
|
+
| `presets` | `PresetItem[]` | `defaultPresets` | 左側に並べるプリセット。 |
|
|
18
|
+
| `showPresets` | `boolean` | `true` | プリセット列を出すか。 |
|
|
19
|
+
| `minDate` | `Date` | | 選べる下限。 |
|
|
20
|
+
| `maxDate` | `Date` | | 選べる上限。 |
|
|
21
|
+
| `placeholder` | `string` | | 未選択時のトリガー表示。 |
|
|
22
|
+
| `align` | `"start" \| "center" \| "end"` | | ポップオーバーの寄せ方。 |
|
|
23
|
+
| `disabled` | `boolean` | | 操作を無効にする。 |
|
|
24
|
+
|
|
25
|
+
## プリセットを差し替える
|
|
26
|
+
|
|
27
|
+
`defaultPresets` は「今日 / 昨日 / 直近 7 日 / 直近 14 日 / …」です。自分で定義するときは
|
|
28
|
+
`getValue` が `DateRange` を返すようにします。
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
const presets: PresetItem[] = [
|
|
32
|
+
{ label: "今四半期", getValue: () => ({ from: quarterStart, to: today }) },
|
|
33
|
+
...defaultPresets,
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
<DateRangePicker presets={presets} value={range} onChange={setRange} />;
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> [!NOTE]
|
|
40
|
+
> `onChange` は `from` だけが決まった途中の状態でも呼ばれます。`to` が `undefined` のあいだは
|
|
41
|
+
> 再取得しない、という分岐を入れてください。
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# EChart
|
|
2
|
+
|
|
3
|
+
> Apache ECharts の薄いラッパー。配色は option で指定する。
|
|
4
|
+
|
|
5
|
+
Apache ECharts をそのまま使えるようにした薄いラッパーです。キャンバスの初期化・リサイズ・破棄と、
|
|
6
|
+
ローディング表示・イベント購読・PNG 保存だけを面倒みます。**配色や軸の見た目はテーマに自動追従
|
|
7
|
+
しません** — `option` の中で色を決めるか、`theme` に ECharts のテーマを渡してください。
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { EChart } from "@squadbase/vantage/components";
|
|
11
|
+
import type { EChartsOption } from "@squadbase/vantage/components";
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
| Prop | Type | 説明 |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| `option` | `EChartsOption` | ECharts の option。そのまま渡す。 |
|
|
17
|
+
| `height` | `string \| number` | 高さ。数値は px。`className` で決めても良い。 |
|
|
18
|
+
| `loading` | `boolean` | ECharts のローディング表示を出す。 |
|
|
19
|
+
| `theme` | `string \| object` | `echarts.init` に渡すテーマ(名前または登録済みテーマ)。 |
|
|
20
|
+
| `onEvents` | `Record<string, (params: unknown) => void>` | ECharts のイベント購読(`click` など)。 |
|
|
21
|
+
| `ariaLabel` | `string` | チャートの説明。 |
|
|
22
|
+
| `actions` | `boolean` | 画像保存などの操作を出す。 |
|
|
23
|
+
| `fileName` | `string` | 保存時のファイル名。 |
|
|
24
|
+
|
|
25
|
+
## 配色を決める
|
|
26
|
+
|
|
27
|
+
系列の色は `option.color` で指定します。テーマの `--chart-1` 〜 `--chart-5` に揃えたいときは、
|
|
28
|
+
ECharts はキャンバス描画で CSS 変数を読めないため、色の実値を渡してください。
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const option: EChartsOption = {
|
|
32
|
+
color: ["#3b82f6", "#f59e0b", "#10b981"],
|
|
33
|
+
series: [{ type: "bar", data: [1, 2, 3] }],
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
複数チャートで配色を使い回すなら、[`echarts.registerTheme`](https://echarts.apache.org/en/api.html#echarts.registerTheme)
|
|
38
|
+
でテーマを登録し、その名前を `theme` プロップに渡すのが簡潔です。
|
|
39
|
+
|
|
40
|
+
## 凡例と重ならないようにする
|
|
41
|
+
|
|
42
|
+
`legend` を出すときは `top: 0` を付け、`grid.top` でプロット領域を下げてください。省くと凡例が
|
|
43
|
+
プロットに重なります。
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
legend: { top: 0 },
|
|
47
|
+
grid: { top: 32, containLabel: true },
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> [!NOTE]
|
|
51
|
+
> `echarts` を直接 import しないでください。管理されたスタックを差し替えられるようにするため、
|
|
52
|
+
> 入り口は `EChart` と `EChartsOption` 型に絞ってあります。
|