@squadbase/vantage-template 0.1.1-dev1.da9fa09 → 0.1.1-dev1.e37e90d
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 +11 -1
- package/base-template/.squadbase/skills/vantage-design/SKILL.md +34 -24
- package/base-template/.squadbase/skills/vantage-design/references/extract.md +16 -14
- package/base-template/.squadbase/skills/vantage-design/references/format.md +6 -5
- package/base-template/.squadbase/skills/vantage-design/references/presets.md +60 -110
- package/base-template/.squadbase/skills/vantage-pitfalls/SKILL.md +5 -0
- package/base-template/.squadbase/skills/vantage-slide/SKILL.md +54 -36
- package/base-template/AGENTS.md +72 -4
- package/base-template/DESIGN.md +7 -6
- package/base-template/agents/doc.md +48 -0
- package/base-template/agents/page.md +32 -1
- package/base-template/agents/slide.md +70 -2
- package/base-template/bun.lock +24 -24
- package/base-template/bunfig.toml +5 -0
- package/base-template/package.json +2 -2
- package/base-template/src/_layout.tsx +13 -6
- package/base-template/src/components/build-recovery.tsx +37 -1
- package/base-template/src/components/user-card.tsx +10 -10
- package/base-template/src/styles.css +105 -18
- package/dist/index.js +956 -0
- package/package.json +20 -17
- package/ui-templates/kpi-chart-simple/pages/index.tsx +47 -47
- package/ui-templates/kpi-chart-simple-ja/pages/index.tsx +47 -47
package/base-template/AGENTS.md
CHANGED
|
@@ -47,6 +47,8 @@ UI キット・開発サーバー・API サーバー・ビルドはすべて Van
|
|
|
47
47
|
- **`definePage` の値はリテラルで書く。** title/description/navLabel はビルド時に静的抽出される
|
|
48
48
|
ため、変数・関数呼び出し・テンプレート補間は使わない。`page` エクスポートはランタイムでは
|
|
49
49
|
読まれない。
|
|
50
|
+
- **アプリの表示言語は、ルート `_layout.tsx` の `export const lang = "ja"`(リテラル)で指定する。**
|
|
51
|
+
`<html lang>` になり、日本語の文節改行とスライドの文言切り替えに効く。未指定は `"en"`。
|
|
50
52
|
|
|
51
53
|
## ディレクトリ構造(ページをどこに置くか)
|
|
52
54
|
|
|
@@ -93,13 +95,25 @@ root/
|
|
|
93
95
|
| `@squadbase/vantage/router` | `Link`・`Outlet`・`useParams`・`useSearch`・`useNavigate`・`redirect`・`notFound`・`useRoutes`・`useCurrentRoute`・`useSearchParam`・`useSearchState` |
|
|
94
96
|
| `@squadbase/vantage/query` | `useApiQuery`・`useApiMutation`・`apiJson`・`apiFetch`・`apiUrl`・`ApiError`、ほか `useQuery`/`useMutation` など TanStack Query の再エクスポート |
|
|
95
97
|
| `@squadbase/vantage/ui` | shadcn/ui(Base UI バリアント)プリミティブ(`Button`・`Loading`・`ErrorState`・`Empty` ほか) |
|
|
96
|
-
| `@squadbase/vantage/components` | 複合パーツ(`PageShell`・`DashboardCardPreset`・`DataTablePreset`、型付きチャート `LineChart`・`BarChart`・`AreaChart`・`DonutChart`・`BarList` ほか、`EChart`) |
|
|
98
|
+
| `@squadbase/vantage/components` | 複合パーツ(`PageShell`・`DashboardCardPreset`・`DataTablePreset`、KPI の `KpiCard`・`Delta`、型付きチャート `LineChart`・`BarChart`・`AreaChart`・`DonutChart`・`BarList` ほか、`EChart`、書式の `formatValue`) |
|
|
97
99
|
| `@squadbase/vantage/table` | `FilePageView`・`TableViewer`(データファイルページの表ビューア) |
|
|
98
|
-
| `@squadbase/vantage/slide` | `SlideDeck`・`Slide`・`Steps`・`Step`・`MorphElement`・`useSlideNumber`・`useIsActiveSlide`(スライド専用。1920×1080 の固定キャンバス) |
|
|
99
|
-
| `@squadbase/vantage/doc` | `Document`(ドキュメント専用。中の素の HTML 要素に見出し・表などのスタイルが当たる) |
|
|
100
|
+
| `@squadbase/vantage/slide` | `SlideDeck`・`Slide`・`Steps`・`Step`・`MorphElement`・`useSlideNumber`・`useIsActiveSlide`、1 枚分の block `SlideCover`・`SlideExecSummary`・`SlideKpiHero`・`SlideKpiGrid`・`SlideChartInsight`・`SlideScorecardTable`・`SlideNextActions`・`SlideSection`・`SlideComparison`・`SlideChartFull`、手書きの 1 枚に使う部品 `SlideHeading`・`SlideSourceLine`・`SlideColumns`・`SlideColumn`・`DeltaText`(スライド専用。1920×1080 の固定キャンバス) |
|
|
101
|
+
| `@squadbase/vantage/doc` | `Document`、ドキュメント用の block `DocReportHeader`・`DocExecutiveSummary`・`DocKpiScorecard`・`DocFigure`・`DocDataTable`・`DocCallout`・`DocKeyFindings`・`DocActionItems`・`DocNotesAndSources`、部品 `DeltaText`(ドキュメント専用。中の素の HTML 要素に見出し・表などのスタイルが当たる) |
|
|
100
102
|
| `@squadbase/vantage/markdown` | `MarkdownRenderer`(Shiki を隔離するための専用サブパス) |
|
|
101
103
|
| `@squadbase/vantage/server` | `ApiContext`・`ApiHandler`・`HttpError`・`isHttpError`・`json`(server/ 側でのみ使う) |
|
|
102
104
|
|
|
105
|
+
**KPI は `KpiCard`、増減は `Delta`(`comparison` と `polarity` を渡す)。** 向き・率・色は値から計算
|
|
106
|
+
されるので手で渡さない。`TrendIndicator` は非推奨(`direction` を手で渡すので値と食い違いうる)。props は
|
|
107
|
+
`vantage docs kpi-card` / `vantage docs delta` を引く。
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import { KpiCard, Delta } from "@squadbase/vantage/components";
|
|
111
|
+
|
|
112
|
+
<KpiCard label="売上" value={48_200_000} format="currency"
|
|
113
|
+
comparison={{ previous: 42_900_000, vs: "prior-period" }} />
|
|
114
|
+
<Delta value={0.021} comparison={{ previous: 0.026, vs: "prior-period" }} polarity="lower-is-better" />
|
|
115
|
+
```
|
|
116
|
+
|
|
103
117
|
## モードは 2 つ、切り替えるのは `server/` の有無だけ
|
|
104
118
|
|
|
105
119
|
`server/` ディレクトリがあれば **fullstack**、無ければ **SPA**。`vantage-manifest.json` の
|
|
@@ -233,7 +247,7 @@ vantage add skill --all --dir .claude/skills # 置き場所を指定(既定は
|
|
|
233
247
|
> `vantage upgrade` はこのファイルをフレームワーク同梱の正本で丸ごと上書きするため、
|
|
234
248
|
> このセクションは消えます。消えたら squadbase-monorepo の
|
|
235
249
|
> `packages/vantage-template/agents/vantage/` から貼り直してください
|
|
236
|
-
> (リポジトリ側では `
|
|
250
|
+
> (リポジトリ側では `pnpm run agents` が正本と結合して再生成します)。
|
|
237
251
|
|
|
238
252
|
## Squadbase の Connection / Query からデータを読む
|
|
239
253
|
|
|
@@ -351,6 +365,10 @@ return Response.json((report.rows ?? []).map(toSessionsDaily))
|
|
|
351
365
|
`components/build-recovery.tsx` の `BuildRecovery` が、その画面を DOM から検知して
|
|
352
366
|
`Working on it…` 表示を被せ、dev では 1.2 秒待ってから自動でリロードして復帰させる
|
|
353
367
|
(上限 3 回。使い切ったら「再読み込み」の案内に降格し、無事に描けたら残数が戻る)。
|
|
368
|
+
**ただし `window.__VANTAGE_DRAFT__?.active` が `true` の間(AI の書きかけのファイルを下書きとして
|
|
369
|
+
プレビューに出している間)は、覆わず・リロードもしない。** 下書き中の描画エラーはフレームワークが
|
|
370
|
+
直前に通った版へ戻すので、ここで覆うとその版の表示まで隠れ、リロードすると下書きの表示ごと消える。
|
|
371
|
+
下書きが終わった時点でエラー画面が残っていれば、通常どおり覆う。
|
|
354
372
|
降格した画面にはエラー本文をそのまま出し、`Copy log` でコピーできるようにしてある —
|
|
355
373
|
自力で直らないときに本文をそのまま貼り戻してもらうため。
|
|
356
374
|
`_error.tsx` も同じ `RecoveringState` を描くので、ルートレイアウトが throw したときの
|
|
@@ -386,6 +404,9 @@ lockfile は `bun.lock`)。Squadbase のサンドボックスは bun と依存
|
|
|
386
404
|
`bun install` を一度走らせて `bun.lock` を追従させ、両方を同じコミットに入れる。
|
|
387
405
|
- スクリプトは `bun run <script>`(`bun run dev` / `bun run build` / `bun run check` /
|
|
388
406
|
`bun run routes`)。`npm run <script>` でも動くが、install に npm を使わないこと。
|
|
407
|
+
- **公開から 48 時間未満の版は入らない。** `bunfig.toml` の `minimumReleaseAge`(サプライチェーン対策)で
|
|
408
|
+
弾かれる。`bun add` / `bun install` が「バージョンが見つからない」で落ちたら、直近の版を避けて
|
|
409
|
+
少し前の版を指定する。`bunfig.toml` の設定を緩めたり `@squadbase/*` 以外の除外を足したりしない。
|
|
389
410
|
|
|
390
411
|
## このアプリで作れるもの
|
|
391
412
|
|
|
@@ -454,3 +475,50 @@ Squadbase のチャットは、回答の根拠になったグラフ・表・KPI
|
|
|
454
475
|
- **ページ内で一意にする。**
|
|
455
476
|
- **新しく作った・直した画面では付ける。更新では既存の値を変えない** — 領域の意味が変わったときだけ変える
|
|
456
477
|
(値を変えると、それを指していた過去のリンクが開けなくなる)。触っていない画面へ遡って付けることはしない。
|
|
478
|
+
|
|
479
|
+
## ファイル内の書く順序(値 → 画面本体 → 子の部品)
|
|
480
|
+
|
|
481
|
+
ページ・部品のファイルは、上から次の順に書く。
|
|
482
|
+
|
|
483
|
+
1. `import`(と `definePage(...)`)
|
|
484
|
+
2. **値** — データ・定数・列定義・小さな関数。短く
|
|
485
|
+
3. **画面本体** — `export default` のコンポーネント
|
|
486
|
+
4. **子の部品** — 大文字始まりの部品。`function` 宣言で書く
|
|
487
|
+
|
|
488
|
+
理由: ファイルは上から順に書かれ、書きかけでもプレビューに反映される。**本体が書かれた時点で画面が出る。**
|
|
489
|
+
値を本体より後ろに書くと、本体はまだ無い値を読むので、その値が書かれるまで画面が出ない。
|
|
490
|
+
子の部品は後ろでよい — 未定義の部品はプレビューが仮の枠で埋める。
|
|
491
|
+
|
|
492
|
+
```tsx
|
|
493
|
+
import { definePage } from "@squadbase/vantage"
|
|
494
|
+
|
|
495
|
+
export const page = definePage({ title: "売上" })
|
|
496
|
+
|
|
497
|
+
const KPI_ITEMS: Kpi[] = [/* … */] // 値は本体より上
|
|
498
|
+
type Kpi = { label: string; value: number }
|
|
499
|
+
|
|
500
|
+
export default function SalesPage() { // 本体
|
|
501
|
+
return <KpiRow items={KPI_ITEMS} />
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function KpiRow({ items }: { items: Kpi[] }) { /* … */ } // 子の部品は下
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### 追加の不変条件
|
|
508
|
+
|
|
509
|
+
- **子の部品は `function` 宣言で書く。** 宣言は巻き上げられるので、本体より後ろでも安全。
|
|
510
|
+
`const Foo = () => …` のアロー関数は後ろに置くと、モジュール評価時に参照された瞬間に TDZ(初期化前参照)で落ちる。
|
|
511
|
+
- **値(定数・データ・列定義・小さな関数)は本体より上。** 小文字の関数・hook も値として上に置く。
|
|
512
|
+
- 型は消えるのでどこでもよい。値のそばに置く。
|
|
513
|
+
- 順序だけのために、既に並んでいるファイルを書き換えない。
|
|
514
|
+
|
|
515
|
+
## アプリの表示言語(`lang`)
|
|
516
|
+
|
|
517
|
+
ルートの `src/_layout.tsx` の `export const lang = "en"` が `<html lang>` になる。**アプリの内容の言語に合わせて書き換える**
|
|
518
|
+
(ユーザーが日本語で依頼している・画面の文言が日本語なら `"ja"`)。
|
|
519
|
+
|
|
520
|
+
- `lang` は**リテラル文字列**(BCP 47。`"ja"` / `"en"` / `"ja-JP"`)。変数・テンプレート補間は読まれない。
|
|
521
|
+
- 読まれるのは**ルートの `src/_layout.tsx` だけ**。入れ子の `_layout.tsx` やページには書かない。
|
|
522
|
+
- 日本語アプリで `"en"` のままだと、スライドの文節改行(`word-break: auto-phrase`)が効かず、見出しが単語の途中で折れる。
|
|
523
|
+
スライドのツールバー文言も `lang` で切り替わる(`"ja"` なら日本語、`en*` なら英語)。
|
|
524
|
+
- 値は消さない。指定が無いと `"en"` 扱いになる。
|
package/base-template/DESIGN.md
CHANGED
|
@@ -26,7 +26,7 @@ DESIGN.md — このアプリの「見た目の意図」を書くファイルで
|
|
|
26
26
|
|
|
27
27
|
| 役割 | トークン | 使う場所 |
|
|
28
28
|
| --- | --- | --- |
|
|
29
|
-
| 主色 (Primary) | `--primary` / `--primary-foreground` |
|
|
29
|
+
| 主色 (Primary) | `--primary` / `--primary-foreground` | 主要ボタン、選択中の状態。既定(テーマ `neutral`)は青 |
|
|
30
30
|
| 強調 (Accent) | `--chart-1` | 1 つだけ目立たせたい数値・系列・リンク的な強調 |
|
|
31
31
|
| 良い (Positive) | `--chart-2` | 前期比のプラスなど、良い変化の小さな印 |
|
|
32
32
|
| 悪い (Negative) | `--destructive` | 前期比のマイナス、エラー、削除操作 |
|
|
@@ -43,20 +43,21 @@ DESIGN.md — このアプリの「見た目の意図」を書くファイルで
|
|
|
43
43
|
## チャート (Charts)
|
|
44
44
|
|
|
45
45
|
- 系列の順番は `--chart-1` → `--chart-2` → `--chart-3` → `--chart-4` → `--chart-5`
|
|
46
|
-
(
|
|
47
|
-
- 1 系列だけを目立たせるときは、その系列を `--chart-1`、残りをすべて `--chart-5`
|
|
46
|
+
(現在はテーマ `neutral`: 青 → 黄緑 → 赤紫 → ティール → 紫)。
|
|
47
|
+
- 1 系列だけを目立たせるときは、その系列を `--chart-1`、残りをすべて `--chart-5` にする。
|
|
48
48
|
- 良い / 悪いを色で塗り分けるときは `--chart-2` / `--destructive`。色だけに頼らず ▲▼ や符号も添える。
|
|
49
49
|
- 系列は 5 つまで。それ以上はグループ化するか「その他」にまとめる。
|
|
50
50
|
- 禁止: 同じチャートで `--destructive` を普通の系列色として使う(悪い値に見える)。
|
|
51
51
|
- 禁止: 隣り合う系列に `--chart-3` と `--chart-4` を並べて細い線で描く(見分けにくい)。
|
|
52
|
-
- 配色を丸ごと変えるときは `npx @squadbase/vantage-template
|
|
53
|
-
(`
|
|
52
|
+
- 配色を丸ごと変えるときは `npx @squadbase/vantage-template theme <id>` を使う
|
|
53
|
+
(`neutral` / `ocean` / `forest` / `sunset` / `violet` / `rose` / `mono`)。チャートだけ別の配色にするときは
|
|
54
|
+
`chart <preset>`(`blue` / `ocean` / `sunset` / `forest` / `berry` / `mono`)。
|
|
54
55
|
|
|
55
56
|
## 書体 (Typography)
|
|
56
57
|
|
|
57
58
|
| 用途 | 指定 | 備考 |
|
|
58
59
|
| --- | --- | --- |
|
|
59
|
-
| 見出し・本文 | 日本語を含むシステムフォント(
|
|
60
|
+
| 見出し・本文 | 日本語を含むシステムフォント(`--font-sans`) | Web フォントは使わない |
|
|
60
61
|
| 数字 | 同上 + `tabular-nums` | 桁がそろうように必ず付ける |
|
|
61
62
|
| スライドの見出し | `--slide-font-display` | 既定は日本語を含むシステムフォント |
|
|
62
63
|
| スライドの本文 | `--slide-font-body` | 既定は見出しと同じ |
|
|
@@ -15,6 +15,13 @@ import { definePage } from "@squadbase/vantage"
|
|
|
15
15
|
import { BarChart } from "@squadbase/vantage/components"
|
|
16
16
|
import { Document } from "@squadbase/vantage/doc"
|
|
17
17
|
|
|
18
|
+
const weekly = [
|
|
19
|
+
{ week: "第1週", 売上: 1180 },
|
|
20
|
+
{ week: "第2週", 売上: 1240 },
|
|
21
|
+
{ week: "第3週", 売上: 1210 },
|
|
22
|
+
{ week: "第4週", 売上: 1620 },
|
|
23
|
+
]
|
|
24
|
+
|
|
18
25
|
export const page = definePage({ title: "6月度サマリー", navLabel: "6月度サマリー" })
|
|
19
26
|
export default function JuneSummary() {
|
|
20
27
|
return (
|
|
@@ -50,6 +57,30 @@ export default function JuneSummary() {
|
|
|
50
57
|
- **ページ全体を包むのは `<Document>` だけ。** `PageShell` などのダッシュボード用の枠で包まない
|
|
51
58
|
(本文の幅と余白は `<Document>` が決めます)。
|
|
52
59
|
|
|
60
|
+
## まず block を探す
|
|
61
|
+
|
|
62
|
+
1 節分の中身は、手で組む前に `@squadbase/vantage/doc` の block から探します(`<Document>` の直下に
|
|
63
|
+
並べる。多くは 1 block = 1 節。`DocCallout`・`DocFigure`・`DocDataTable` は節ではなく、節の中(本文の間)に置く部品)。props は `vantage docs <name>`(例: `vantage docs doc-kpi-scorecard`)で引く。
|
|
64
|
+
|
|
65
|
+
| block | 用途 |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| `DocReportHeader` | レポートの冒頭(タイトル・サブタイトル・対象期間・データ時点・作成者・出典) |
|
|
68
|
+
| `DocExecutiveSummary` | 結論を先に述べる要約の節 |
|
|
69
|
+
| `DocKpiScorecard` | 主要指標をまとめたスコアカード |
|
|
70
|
+
| `DocFigure` | 図表 1 つとキャプション(チャートは children で渡す) |
|
|
71
|
+
| `DocDataTable` | 素の `table` による表 |
|
|
72
|
+
| `DocCallout` | 補足・示唆・注意・決定の囲み(`kind`: `note` / `insight` / `warning` / `decision`) |
|
|
73
|
+
| `DocKeyFindings` | 主要な発見の箇条 |
|
|
74
|
+
| `DocActionItems` | 次のアクション(担当・期限つき) |
|
|
75
|
+
| `DocNotesAndSources` | 末尾の注記・用語の定義・データソースをまとめた節 |
|
|
76
|
+
|
|
77
|
+
**props の渡し方は block 間で共通。** 数値は `value: number | null` と `format`(整形は block がする。表示を上書きするときだけ `display`。`null` は「—」)。前期比などは `delta: { value, format? }` と `comparisonLabel`(例 `"前年同期比"`)、良し悪しは指標ごとの `betterWhen`(`"up"` が既定、コストなど下がるほど良いものは `"down"`。向きは block が符号から出す)。目標は `target: number`。出典は `source`、時点は `asOf` に**日付だけ**(例 `"2026-09-30"`。「データ時点」は block が付けるので「時点」を書かない)。時系列は、単一系列なら `{ x, y }[]`(`trend`)。
|
|
78
|
+
|
|
79
|
+
本文の中で増減を書くときは `DeltaText`(部品。「▲ +3.2%」の形で、文字サイズは持たず置かれた行に従う。`value` `format` `betterWhen` `comparisonLabel`)を使う。節ではなく文の中に置く。
|
|
80
|
+
|
|
81
|
+
block が合わない**1 節だけ**を素の HTML 要素で手で書く。import 元は `@squadbase/vantage/doc` のままで、
|
|
82
|
+
block のための新しい import 元はありません。本文は文字列か ReactNode で渡し、Markdown 文字列は渡さない。
|
|
83
|
+
|
|
53
84
|
## 見た目を変える
|
|
54
85
|
|
|
55
86
|
配色・書体・本文の幅は `--doc-*` の CSS 変数です。既定値はアプリのトークンへの別名なので、
|
|
@@ -74,3 +105,20 @@ export default function JuneSummary() {
|
|
|
74
105
|
`.doc` を付けられるのはルートになるページモジュールだけで、`_layout.doc.tsx` などは
|
|
75
106
|
`INVALID_PAGE_VARIANT` エラーになります。`june.doc.tsx` と `june.tsx` は同じ URL に解決するので
|
|
76
107
|
`ROUTE_CONFLICT` です。
|
|
108
|
+
|
|
109
|
+
## ファイル形式の規約
|
|
110
|
+
|
|
111
|
+
置き場所・URL・default export・`definePage` の書き方は全ページ共通(`agents/page.md` の
|
|
112
|
+
「ページファイルの規約」)。ここではドキュメント固有のものだけを挙げます。
|
|
113
|
+
|
|
114
|
+
**MUST**
|
|
115
|
+
|
|
116
|
+
- ファイル名は `<name>.doc.tsx`(`.jsx` も可)。サフィックスは小文字で 1 つだけ。`.doc.mdx` は
|
|
117
|
+
`INVALID_PAGE_VARIANT`、`.DOC.tsx`・二重サフィックスは黙って通常ページになる
|
|
118
|
+
- default export は `<Document>` をルートに返す。フレームワークは包まない
|
|
119
|
+
- ドキュメントの部品は `@squadbase/vantage/doc` から import する
|
|
120
|
+
|
|
121
|
+
**SHOULD**
|
|
122
|
+
|
|
123
|
+
- `PageShell` で包まない・PDF の保存ボタンを自作しない(上の「書き方」)
|
|
124
|
+
- 数値はコードに直接書き、いつ時点の値かを本文に書く
|
|
@@ -71,6 +71,7 @@ URL になる。各ページは**デフォルトエクスポートの React コ
|
|
|
71
71
|
| `_404.tsx` | Not Found ページ |
|
|
72
72
|
| `_error.tsx` | ルートが throw したときのエラーページ |
|
|
73
73
|
| `monthly-report.slide.tsx` | `/monthly-report`(スライドデッキ。詳しくは `agents/slide.md`) |
|
|
74
|
+
| `june-summary.doc.tsx` | `/june-summary`(ドキュメント。詳しくは `agents/doc.md`) |
|
|
74
75
|
| `sales-export.csv` | `/sales-export`(詳しくは `agents/csv.md`) |
|
|
75
76
|
| `data/june.xlsx` | `/data/june`(詳しくは `agents/xlsx.md`) |
|
|
76
77
|
|
|
@@ -89,6 +90,26 @@ export default function MonthlyAnalysis() {
|
|
|
89
90
|
}
|
|
90
91
|
```
|
|
91
92
|
|
|
93
|
+
### ページファイルの規約(`.tsx` / `.slide.tsx` / `.doc.tsx` 共通)
|
|
94
|
+
|
|
95
|
+
**MUST**
|
|
96
|
+
|
|
97
|
+
- ページルートの配下に置く。`components/` などの走査対象外のディレクトリに置いたファイルはページに
|
|
98
|
+
ならず、エラーも出ない。`_` 始まりの名前は予約名(`_layout` / `_404` / `_error`)にだけ使う
|
|
99
|
+
(それ以外の `_` 始まりはページにならない。予約名にサフィックスを付けると `INVALID_PAGE_VARIANT`)
|
|
100
|
+
- URL はサフィックスと拡張子を除いたパスで決まる。同じ URL になる別ファイル(`june.tsx` /
|
|
101
|
+
`june.slide.tsx` / `june.doc.tsx` / `june.csv`)を並べない(`ROUTE_CONFLICT`)。テンプレートの
|
|
102
|
+
未編集の `index.tsx` だけは例外で、`index.slide.tsx` / `index.doc.tsx` が `/` を取れる
|
|
103
|
+
- default export は React の関数コンポーネント(無いと `MISSING_DEFAULT_EXPORT`。関数かどうかは
|
|
104
|
+
検査されない)
|
|
105
|
+
- `definePage({ ... })` にはオブジェクトリテラルを直接渡し、`title` / `description` / `navLabel` は
|
|
106
|
+
文字列リテラルで書く。ビルド時に静的抽出されるので、変数・関数呼び出し・spread・shorthand・
|
|
107
|
+
`${}` を含むテンプレート文字列は**エラーにならず黙ってメタなし**になる
|
|
108
|
+
|
|
109
|
+
**SHOULD**
|
|
110
|
+
|
|
111
|
+
- `definePage` に `title` と `navLabel` を書く(ナビの表示名とブラウザのタブ名になる)
|
|
112
|
+
|
|
92
113
|
### ナビはルート一覧から組む
|
|
93
114
|
|
|
94
115
|
`useRoutes()` がページルート一覧(スキャン順)を返すので、リンク配列を手で持たない。
|
|
@@ -109,7 +130,7 @@ routes.map((r) => (
|
|
|
109
130
|
```
|
|
110
131
|
|
|
111
132
|
`RouteInfo`: `path`(`/sales/:id`)・`to`(`/sales/$id`)・`params`・`dynamic`・`index`・`label`・
|
|
112
|
-
`title`・`description`・`navLabel`・`kind`(`"module"` | `"file"`)・`variant`(`"slide"`)。
|
|
133
|
+
`title`・`description`・`navLabel`・`kind`(`"module"` | `"file"`)・`variant`(`"slide"` | `"doc"`)。
|
|
113
134
|
後ろの 2 つで、ナビをダッシュボード / スライド / データに分けたりアイコンを変えたりできます。
|
|
114
135
|
|
|
115
136
|
### フィルタ状態は URL に置く
|
|
@@ -177,6 +198,16 @@ refetchOnWindowFocus false・networkMode "always")。挙動を変えたいとき
|
|
|
177
198
|
`/components` の複合パーツも全部取り出せる(名前は kebab-case: `add ui bar-chart`。
|
|
178
199
|
ブロックは `add block sales-overview`。未知名で実行すると候補が一覧表示される)。
|
|
179
200
|
|
|
201
|
+
### 長い表はページングする(縦スクロール箱を作らない)
|
|
202
|
+
|
|
203
|
+
- 行が多い表は `DataTablePreset`(または `DataTable`)に `enablePagination` を付けて**ページング**する
|
|
204
|
+
(既定は 10 行 / ページ。ページングは既定で無効なので、付け忘れると全行が並ぶ)。素の `<table>` を
|
|
205
|
+
手書きして全行を流し込まない。
|
|
206
|
+
- カードの中に `max-h-*` + `overflow-y-auto` の**縦スクロール領域を作らない**。ホイールやキー
|
|
207
|
+
(End / Space)がその箱に吸われ、ページ全体がスクロールしなくなる。高さは内容に任せる。
|
|
208
|
+
- 横に広い表の `overflow-x-auto` は構わない。`SheetGrid`(`.csv` / `.xlsx` のビューア)は
|
|
209
|
+
グリッドとして意図した入れ子スクロールなので対象外。
|
|
210
|
+
|
|
180
211
|
### グラフはまず型付きチャートで描く
|
|
181
212
|
|
|
182
213
|
- 推移は `LineChart` / `AreaChart`、比較は `BarChart`、構成比は `DonutChart`。`data`(行の配列)・
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
- 新規プロジェクトでまだ `/` が空いている場合のみ、`index.slide.tsx` を使ってよい。
|
|
20
20
|
|
|
21
21
|
```tsx
|
|
22
|
+
import { definePage } from "@squadbase/vantage"
|
|
22
23
|
import { Slide, SlideDeck } from "@squadbase/vantage/slide"
|
|
23
24
|
|
|
24
25
|
export const page = definePage({ title: "6月度レビュー", navLabel: "6月度" })
|
|
@@ -34,8 +35,10 @@ export default function Deck() {
|
|
|
34
35
|
|
|
35
36
|
**`<Slide>` は `<SlideDeck>` の直接の子に書く。** `SlideDeck` は直下の `<Slide>` 要素だけを数えるので、
|
|
36
37
|
`<Slide>` を自作コンポーネント(`<Slide1 />` など)や Fragment で包むと 1 枚も数えられず「1 / 0」に
|
|
37
|
-
なります(`{items.map((x) => <Slide key={x.id}>…</Slide>)}`
|
|
38
|
-
|
|
38
|
+
なります(`{items.map((x) => <Slide key={x.id}>…</Slide>)}` のような配列はファイル形式としては可。
|
|
39
|
+
1 枚の中で視覚要素を `map` で量産しない方針は `vantage-slide` skill の「繰り返す要素は `map` ではなく
|
|
40
|
+
コンポーネント」)。共通の部品は `<Slide>` の**中**に置くコンポーネントとして切り出します
|
|
41
|
+
(`<Slide><CoverPage /></Slide>`)。
|
|
39
42
|
|
|
40
43
|
1920×1080 の固定キャンバスに絶対 px で書き、画面サイズに合わせて縮小されます。キー / クリックで
|
|
41
44
|
送れ、左のスライド一覧(サムネイル列)は `L` で開閉、`F` で全画面、ツールバーから pptx を
|
|
@@ -51,3 +54,68 @@ pptx が壊れる条件、説明と図表のデータ時点の揃え方)。
|
|
|
51
54
|
`.slide` を付けられるのはルートになるページモジュールだけで、`_layout.slide.tsx` などは
|
|
52
55
|
`INVALID_PAGE_VARIANT` エラーになります。`june.slide.tsx` と `june.tsx` は同じ URL に解決するので
|
|
53
56
|
`ROUTE_CONFLICT` です。
|
|
57
|
+
|
|
58
|
+
## まず block を探す
|
|
59
|
+
|
|
60
|
+
1 枚分の中身は、手で組む前に `@squadbase/vantage/slide` の block から探します(`<Slide>` の**中**に
|
|
61
|
+
置く。ルートは 100% で、`<Slide>` 自体は持たない)。props は `vantage docs <name>`(例:
|
|
62
|
+
`vantage docs slide-kpi-hero`)で引く。
|
|
63
|
+
|
|
64
|
+
| block | 用途 |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `SlideCover` | 表紙(タイトル・サブタイトル・期間) |
|
|
67
|
+
| `SlideExecSummary` | 結論を先に述べるエグゼクティブサマリー |
|
|
68
|
+
| `SlideKpiHero` | 主要な KPI 1 つを大きく見せる |
|
|
69
|
+
| `SlideKpiGrid` | 複数の KPI を並べる |
|
|
70
|
+
| `SlideChartInsight` | チャート 1 つと、そこから読み取れること |
|
|
71
|
+
| `SlideScorecardTable` | 指標と目標・達成度を表にしたスコアカード |
|
|
72
|
+
| `SlideNextActions` | 次のアクション(担当・期限つき) |
|
|
73
|
+
| `SlideSection` | 章の扉(`items` を渡すと番号付きのアジェンダ。`current` の章を強調) |
|
|
74
|
+
| `SlideComparison` | A vs B・前後の 2〜3 列比較(各列に見出し・主要数値・箇条) |
|
|
75
|
+
| `SlideChartFull` | チャートを全幅に置き、注記を 1 行添える |
|
|
76
|
+
|
|
77
|
+
**手書きの 1 枚には部品を使う。** block が合わない 1 枚でも、見出し・出典行・列割りは自前で組まず、
|
|
78
|
+
次の部品を使う(どれも `@squadbase/vantage/slide`。1 枚にはならないので `<Slide>` の中に並べる)。
|
|
79
|
+
|
|
80
|
+
| 部品 | 用途 |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `SlideHeading` | 見出し(`title`、任意で `eyebrow`)。1 枚の先頭に置く |
|
|
83
|
+
| `SlideSourceLine` | 足元の出典・時点(`source` `asOf`)。`page={{ current, total }}` を渡すとページ番号も出す |
|
|
84
|
+
| `SlideColumns` / `SlideColumn` | 12 列の割り付け(`<SlideColumn span={8}>` と `span={4}` など)。`align` は `start` / `center` / `stretch` |
|
|
85
|
+
| `DeltaText` | 増減の文字(「▲ +3.2%」)。`value` `format` `betterWhen` `comparisonLabel` |
|
|
86
|
+
|
|
87
|
+
`SlideSection` は `Steps` を持たない。順に見せたいときは呼び出し側で `<Steps>` で包む。
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { Slide, SlideDeck, SlideCover, SlideExecSummary } from "@squadbase/vantage/slide"
|
|
91
|
+
// <SlideDeck><Slide><SlideCover … /></Slide><Slide><SlideExecSummary … /></Slide></SlideDeck>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**props の渡し方は block 間で共通。** 数値は `value: number | null` と `format`(整形は block がする。表示を上書きするときだけ `display`。`null` は「—」)。前期比などは `delta: { value, format? }` と `comparisonLabel`(例 `"前年同期比"`)、良し悪しは指標ごとの `betterWhen`(`"up"` が既定、コストなど下がるほど良いものは `"down"`。向きは block が符号から出す)。目標は `target: number`。出典は `source`(文字列)、時点は `asOf` に**日付だけ**(例 `"2026-09-30"`。「時点」は block が付けるので書かない)。時系列は、単一系列なら `{ x, y }[]`(kpi-hero の `trend`。scorecard に `trend` は無い)、複数系列なら `{ categories, series }`(chart-insight の `chart`)。
|
|
95
|
+
|
|
96
|
+
block が合わない**1 枚だけ**を手で書く(デッキ全体を手書きに切り替えない)。import 元は
|
|
97
|
+
`@squadbase/vantage/slide` のままで、block のための新しい import 元はありません。
|
|
98
|
+
|
|
99
|
+
## ファイル形式の規約
|
|
100
|
+
|
|
101
|
+
置き場所・URL・default export・`definePage` の書き方は全ページ共通(`agents/page.md` の
|
|
102
|
+
「ページファイルの規約」)。ここではスライド固有のものだけを挙げます。**中身の値(キャンバス・
|
|
103
|
+
セーフエリア・グリッド・文字サイズ・余白)は `vantage-slide` skill を参照。**
|
|
104
|
+
|
|
105
|
+
**MUST**(破ると黙って壊れるものが多い。`vantage check` が拾うのは名前の誤りだけ)
|
|
106
|
+
|
|
107
|
+
- ファイル名は `<name>.slide.tsx`(`.jsx` も可)。サフィックスは小文字で 1 つだけ。`.slide.ts` は
|
|
108
|
+
`INVALID_PAGE_VARIANT`、`.SLIDE.tsx`・二重サフィックス・`.slide.test.tsx` は黙って通常ページになる
|
|
109
|
+
- default export は `<SlideDeck>` をルートに返す。フレームワークは包まない
|
|
110
|
+
- `<Slide>` は `<SlideDeck>` の直接の子(配列は可。Fragment・自作コンポーネントで包まない)
|
|
111
|
+
- `<Step>` は `<Steps>` の直接の子(包むと常に表示される)
|
|
112
|
+
- スライドの部品は `@squadbase/vantage/slide` から import する
|
|
113
|
+
|
|
114
|
+
**SHOULD**
|
|
115
|
+
|
|
116
|
+
- 1 ファイル = 1 デッキ。ヘルパーコンポーネント・定数も同じ `.slide.tsx` に書く
|
|
117
|
+
- 各 `<Slide>` のルート要素は `width: "100%"; height: "100%"` でキャンバスを埋める
|
|
118
|
+
- canvas に描くチャート(`EChart`)は `data-waitfor="canvas"` で包む(無いと pptx でそのスライドが白紙になりうる)
|
|
119
|
+
- pptx に出る中身をアプリの Context(router / query / テーマ)に依存させない
|
|
120
|
+
- `MorphElement` の `id` はページ内で一意にし、入れ子にしない。遷移先の `<Slide>` で `transition.morph` を有効にする
|
|
121
|
+
- pptx 用などの依存を追加しない(html-to-image / fflate は自動で入る)
|
package/base-template/bun.lock
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
"name": "vibe-app",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@squadbase/react": "^0.1.0",
|
|
9
|
-
"@squadbase/vantage": "0.6.2-dev1.
|
|
10
|
-
"@squadbase/vantage-sdk": "0.1.1-dev1.
|
|
9
|
+
"@squadbase/vantage": "0.6.2-dev1.20b05d1",
|
|
10
|
+
"@squadbase/vantage-sdk": "0.1.1-dev1.95274ee",
|
|
11
11
|
"date-fns": "^4.1.0",
|
|
12
12
|
"lucide-react": "^0.468.0",
|
|
13
13
|
"react": "^19.3.1",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
|
|
115
115
|
"@mermaid-js/parser": ["@mermaid-js/parser@1.2.1", "", { "dependencies": { "@chevrotain/types": "~11.1.2" } }, "sha512-n12NohV3mrUyUL2o93IgG/ifeW9FTyeJn3zDxkhwa8MJ9Fxg3HQMlA3RiGmD/3UnJvheztkjjQAjA2T4LmUcpw=="],
|
|
116
116
|
|
|
117
|
-
"@oxc-project/types": ["@oxc-project/types@0.
|
|
117
|
+
"@oxc-project/types": ["@oxc-project/types@0.155.0", "", {}, "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q=="],
|
|
118
118
|
|
|
119
119
|
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.7", "", {}, "sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q=="],
|
|
120
120
|
|
|
@@ -148,35 +148,35 @@
|
|
|
148
148
|
|
|
149
149
|
"@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rDiah9wvtqihWtWz02XreeRKIxt2EJF8y5D9rtY9l5A2zxePAtcPiOMpDugNRw5bFHz+1/8viVoc7ZVKiJknCw=="],
|
|
150
150
|
|
|
151
|
-
"@rolldown/binding-android-arm-eabi": ["@rolldown/binding-android-arm-eabi@1.2.
|
|
151
|
+
"@rolldown/binding-android-arm-eabi": ["@rolldown/binding-android-arm-eabi@1.2.15", "", { "os": "android", "cpu": "arm" }, "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw=="],
|
|
152
152
|
|
|
153
|
-
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.2.
|
|
153
|
+
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.2.15", "", { "os": "android", "cpu": "arm64" }, "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg=="],
|
|
154
154
|
|
|
155
|
-
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.2.
|
|
155
|
+
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.2.15", "", { "os": "darwin", "cpu": "arm64" }, "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA=="],
|
|
156
156
|
|
|
157
|
-
"@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.2.
|
|
157
|
+
"@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.2.15", "", { "os": "darwin", "cpu": "x64" }, "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A=="],
|
|
158
158
|
|
|
159
|
-
"@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.2.
|
|
159
|
+
"@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.2.15", "", { "os": "freebsd", "cpu": "x64" }, "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ=="],
|
|
160
160
|
|
|
161
|
-
"@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.2.
|
|
161
|
+
"@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.2.15", "", { "os": "linux", "cpu": "arm" }, "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ=="],
|
|
162
162
|
|
|
163
|
-
"@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.2.
|
|
163
|
+
"@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.2.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw=="],
|
|
164
164
|
|
|
165
|
-
"@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.2.
|
|
165
|
+
"@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.2.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ=="],
|
|
166
166
|
|
|
167
|
-
"@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.2.
|
|
167
|
+
"@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.2.15", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw=="],
|
|
168
168
|
|
|
169
|
-
"@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.2.
|
|
169
|
+
"@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.2.15", "", { "os": "linux", "cpu": "s390x" }, "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA=="],
|
|
170
170
|
|
|
171
|
-
"@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.2.
|
|
171
|
+
"@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.2.15", "", { "os": "linux", "cpu": "x64" }, "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw=="],
|
|
172
172
|
|
|
173
|
-
"@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.2.
|
|
173
|
+
"@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.2.15", "", { "os": "linux", "cpu": "x64" }, "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ=="],
|
|
174
174
|
|
|
175
|
-
"@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.2.
|
|
175
|
+
"@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.2.15", "", { "os": "none", "cpu": "arm64" }, "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w=="],
|
|
176
176
|
|
|
177
|
-
"@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.2.
|
|
177
|
+
"@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.2.15", "", { "os": "win32", "cpu": "arm64" }, "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg=="],
|
|
178
178
|
|
|
179
|
-
"@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.2.
|
|
179
|
+
"@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.2.15", "", { "os": "win32", "cpu": "x64" }, "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ=="],
|
|
180
180
|
|
|
181
181
|
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="],
|
|
182
182
|
|
|
@@ -196,9 +196,9 @@
|
|
|
196
196
|
|
|
197
197
|
"@squadbase/react": ["@squadbase/react@0.1.0", "", { "dependencies": { "zod": "^4.3.6" }, "peerDependencies": { "@types/react": "17.x || 18.x || 19.x", "react": "17.x || 18.x || 19.x" }, "optionalPeers": ["@types/react"] }, "sha512-k+Dpyj7eH+Yjydw54iEluCjYDae086d12hWgBjNMpw4wLbQGz3CrJ6Yipodg8n1cKUt7zvwddlcTHd79bgKsXg=="],
|
|
198
198
|
|
|
199
|
-
"@squadbase/vantage": ["@squadbase/vantage@0.6.2-dev1.
|
|
199
|
+
"@squadbase/vantage": ["@squadbase/vantage@0.6.2-dev1.20b05d1", "", { "dependencies": { "@base-ui/react": "^1.6.0", "@hono/node-server": "^2.1.5", "@streamdown/code": "^1.1.1", "@tailwindcss/vite": "^4.3.3", "@tanstack/react-query": "^5.101.2", "@tanstack/react-router": "^1.170.17", "@tanstack/react-table": "^8.21.3", "@vitejs/plugin-react": "^6.1.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", "date-fns": "^4.1.0", "echarts": "^6.0.0", "esbuild": "0.28.1", "fflate": "^0.8.3", "hono": "^4.13.13", "html-to-image": "^1.11.13", "lucide-react": "^0.468.0", "papaparse": "^5.7.0", "picocolors": "^1.1.1", "react-day-picker": "^10.0.1", "read-excel-file": "^9.3.10", "shiki": "3.23.0", "streamdown": "^2.5.0", "tailwind-merge": "3.6.0", "tailwindcss": "^4.3.3", "tw-animate-css": "^1.0.0", "vite": "^8.3.4" }, "peerDependencies": { "react": ">=18.2.0", "react-dom": ">=18.2.0", "typescript": ">=5.0.0" }, "optionalPeers": ["typescript"], "bin": { "vantage": "dist/cli.js" } }, "sha512-SqwvsAm14PuZROG53qB5jdefdFKUJ6OhrzB1t/9YIIKqfOM+XwcWz5K0/qMJA76bsC8lGZSMB5GgFR58GR/xyQ=="],
|
|
200
200
|
|
|
201
|
-
"@squadbase/vantage-sdk": ["@squadbase/vantage-sdk@0.1.1-dev1.
|
|
201
|
+
"@squadbase/vantage-sdk": ["@squadbase/vantage-sdk@0.1.1-dev1.95274ee", "", {}, "sha512-YPT6tq3KN1rTRiVsNhDr/5MxfZryzUa8HyitUPZNdZJyQVxXqaztDjpCbl/DVyUeFpovc9SJbUxD+/afEPFOsA=="],
|
|
202
202
|
|
|
203
203
|
"@streamdown/code": ["@streamdown/code@1.1.1", "", { "dependencies": { "shiki": "^3.19.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-i7HTNuDgZWb+VdrNVOam9gQhIc5MSSDXKWXgbUrn/4vSRaSMM+Rtl10MQj4wLWPNpF7p80waJsAqFP8HZfb0Jg=="],
|
|
204
204
|
|
|
@@ -716,7 +716,7 @@
|
|
|
716
716
|
|
|
717
717
|
"react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="],
|
|
718
718
|
|
|
719
|
-
"read-excel-file": ["read-excel-file@9.3.
|
|
719
|
+
"read-excel-file": ["read-excel-file@9.3.12", "", { "dependencies": { "fflate": "^0.8.3", "saxen": "^11.1.0", "unzipper-esm": "^0.13.3", "worker-f": "^0.1.12" } }, "sha512-benNAoQbe5HqoTi3qrQkR8wMeHq0gVWLt2Br73hVvmBPGdzMf9OLGsps/812AfZ+bvzVYsUyhF77Y3o4B51yCA=="],
|
|
720
720
|
|
|
721
721
|
"regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="],
|
|
722
722
|
|
|
@@ -744,7 +744,7 @@
|
|
|
744
744
|
|
|
745
745
|
"robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="],
|
|
746
746
|
|
|
747
|
-
"rolldown": ["rolldown@1.2.
|
|
747
|
+
"rolldown": ["rolldown@1.2.15", "", { "dependencies": { "@oxc-project/types": "=0.155.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm-eabi": "1.2.15", "@rolldown/binding-android-arm64": "1.2.15", "@rolldown/binding-darwin-arm64": "1.2.15", "@rolldown/binding-darwin-x64": "1.2.15", "@rolldown/binding-freebsd-x64": "1.2.15", "@rolldown/binding-linux-arm-gnueabihf": "1.2.15", "@rolldown/binding-linux-arm64-gnu": "1.2.15", "@rolldown/binding-linux-arm64-musl": "1.2.15", "@rolldown/binding-linux-ppc64-gnu": "1.2.15", "@rolldown/binding-linux-s390x-gnu": "1.2.15", "@rolldown/binding-linux-x64-gnu": "1.2.15", "@rolldown/binding-linux-x64-musl": "1.2.15", "@rolldown/binding-openharmony-arm64": "1.2.15", "@rolldown/binding-win32-arm64-msvc": "1.2.15", "@rolldown/binding-win32-x64-msvc": "1.2.15" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g=="],
|
|
748
748
|
|
|
749
749
|
"roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="],
|
|
750
750
|
|
|
@@ -752,7 +752,7 @@
|
|
|
752
752
|
|
|
753
753
|
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
|
754
754
|
|
|
755
|
-
"saxen": ["saxen@11.
|
|
755
|
+
"saxen": ["saxen@11.2.0", "", {}, "sha512-2bG564AAJcm/3vyZC0Uhs/mACrH+4AHMaKHKAB2M5xMqomUZa27FQ7MYaQGFKVcJk/MVzSEQ34A8QZWW+eiWEw=="],
|
|
756
756
|
|
|
757
757
|
"scheduler": ["scheduler@0.28.0", "", {}, "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw=="],
|
|
758
758
|
|
|
@@ -830,7 +830,7 @@
|
|
|
830
830
|
|
|
831
831
|
"vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="],
|
|
832
832
|
|
|
833
|
-
"vite": ["vite@8.3.
|
|
833
|
+
"vite": ["vite@8.3.5", "", { "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.7", "postcss": "^8.5.30", "rolldown": "~1.2.14", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.7.1 || ^0.8.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ=="],
|
|
834
834
|
|
|
835
835
|
"web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
|
|
836
836
|
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@squadbase/react": "^0.1.0",
|
|
15
|
-
"@squadbase/vantage": "0.6.2-dev1.
|
|
16
|
-
"@squadbase/vantage-sdk": "0.1.1-dev1.
|
|
15
|
+
"@squadbase/vantage": "0.6.2-dev1.20b05d1",
|
|
16
|
+
"@squadbase/vantage-sdk": "0.1.1-dev1.95274ee",
|
|
17
17
|
"date-fns": "^4.1.0",
|
|
18
18
|
"lucide-react": "^0.468.0",
|
|
19
19
|
"react": "^19.3.1",
|
|
@@ -8,13 +8,11 @@ import { BuildRecovery } from "./components/build-recovery"
|
|
|
8
8
|
import { UserCard } from "./components/user-card"
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* The app's display language, written to `<html lang>` (a BCP 47 literal, e.g.
|
|
12
|
+
* "ja"). Set it to the language of the app's content: it also switches the slide
|
|
13
|
+
* toolbar messages and enables Japanese phrase-aware line breaking in slides.
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
|
-
return <Link to={href} {...props} />
|
|
17
|
-
}
|
|
15
|
+
export const lang = "en"
|
|
18
16
|
|
|
19
17
|
/**
|
|
20
18
|
* The nav *is* the route list — adding a page file puts it in the nav, with no
|
|
@@ -67,3 +65,12 @@ export default function RootLayout() {
|
|
|
67
65
|
</SquadbaseProvider>
|
|
68
66
|
)
|
|
69
67
|
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* `AppShell` is router-agnostic and renders nav entries through whatever
|
|
71
|
+
* component it is handed, using an `href` prop. Adapt it to the Vantage router
|
|
72
|
+
* so navigation stays client-side.
|
|
73
|
+
*/
|
|
74
|
+
function RouterLink({ href, ...props }: { href: string } & ComponentProps<"a">) {
|
|
75
|
+
return <Link to={href} {...props} />
|
|
76
|
+
}
|