@squadbase/vantage-template 0.1.1-dev1.470473f → 0.1.1-dev1.7a4f5d9
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/base-template/.squadbase/skills/vantage-add-feature/SKILL.md +9 -7
- package/base-template/.squadbase/skills/vantage-app/SKILL.md +10 -6
- package/base-template/.squadbase/skills/vantage-design/SKILL.md +12 -2
- package/base-template/.squadbase/skills/vantage-design/references/format.md +1 -1
- package/base-template/.squadbase/skills/vantage-pitfalls/SKILL.md +45 -1
- package/base-template/.squadbase/skills/vantage-slide/SKILL.md +281 -0
- package/base-template/.squadbase/skills/vantage-slide/references/morph.md +102 -0
- package/base-template/.squadbase/skills/vantage-slide/references/steps.md +57 -0
- package/base-template/.squadbase/skills/vantage-slide/references/tokens.md +87 -0
- package/base-template/.squadbase/skills/vantage-slide/references/transitions.md +196 -0
- package/base-template/AGENTS.md +162 -2
- package/base-template/DESIGN.md +1 -1
- package/base-template/agents/api.md +29 -0
- package/base-template/agents/csv.md +2 -1
- package/base-template/agents/doc.md +4 -3
- package/base-template/agents/page.md +32 -8
- package/base-template/agents/slide.md +6 -1
- package/base-template/agents/xlsx.md +2 -1
- package/base-template/bun.lock +78 -68
- package/base-template/bunfig.toml +5 -0
- package/base-template/package.json +6 -6
- package/base-template/src/_layout.tsx +9 -9
- package/base-template/src/components/build-recovery.tsx +37 -1
- package/base-template/src/components/user-card.tsx +10 -10
- package/base-template/src/index.tsx +7 -3
- package/base-template/src/styles.css +11 -0
- package/package.json +16 -16
- package/ui-templates/CLAUDE.md +2 -0
- package/ui-templates/kpi-chart-simple/pages/index.tsx +48 -48
- package/ui-templates/kpi-chart-simple-ja/pages/index.tsx +48 -48
|
@@ -66,14 +66,18 @@ const CHARTS = [
|
|
|
66
66
|
]
|
|
67
67
|
|
|
68
68
|
export default function HomePage() {
|
|
69
|
+
// `data-vantage-sample` marks this page as the untouched template sample (the coding
|
|
70
|
+
// agent looks for it). Remove it together with the sample content.
|
|
71
|
+
const sampleNote = navigator.language.startsWith("ja")
|
|
72
|
+
? "サンプルデータです。お手元のデータに置き換えて始めましょう。"
|
|
73
|
+
: "Sample data — replace with your own to get started."
|
|
74
|
+
|
|
69
75
|
return (
|
|
70
76
|
<PageShell>
|
|
71
77
|
<PageShellHeader>
|
|
72
78
|
<PageShellHeading>
|
|
73
79
|
<PageShellTitle>Dashboard</PageShellTitle>
|
|
74
|
-
<PageShellDescription>
|
|
75
|
-
Sample data — replace with your own to get started.
|
|
76
|
-
</PageShellDescription>
|
|
80
|
+
<PageShellDescription data-vantage-sample="home">{sampleNote}</PageShellDescription>
|
|
77
81
|
</PageShellHeading>
|
|
78
82
|
</PageShellHeader>
|
|
79
83
|
|
|
@@ -17,6 +17,17 @@
|
|
|
17
17
|
/* --radius: 0.625rem; */
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/* Page typeface. Latin system faces first, then Japanese system faces so kana and
|
|
21
|
+
kanji do not fall back to a thin locale default. `ui-sans-serif` / `system-ui`
|
|
22
|
+
come after the Japanese families on purpose: on Japanese Windows they resolve to
|
|
23
|
+
the condensed Yu Gothic UI, which would otherwise take the kana. Put a Latin
|
|
24
|
+
webfont in front if you add one, but keep the Japanese families. */
|
|
25
|
+
body {
|
|
26
|
+
font-family:
|
|
27
|
+
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Hiragino Sans",
|
|
28
|
+
"Hiragino Kaku Gothic ProN", "Noto Sans JP", Meiryo, ui-sans-serif, system-ui, sans-serif;
|
|
29
|
+
}
|
|
30
|
+
|
|
20
31
|
/* vantage-template:chart-preset — regenerated by `chart`; edits here are lost */
|
|
21
32
|
:root {
|
|
22
33
|
--chart-1: var(--color-blue-600);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squadbase/vantage-template",
|
|
3
|
-
"version": "0.1.1-dev1.
|
|
3
|
+
"version": "0.1.1-dev1.7a4f5d9",
|
|
4
4
|
"description": "CLI tool for initializing and customizing Squadbase Vantage projects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"squadbase",
|
|
@@ -36,19 +36,6 @@
|
|
|
36
36
|
"access": "public",
|
|
37
37
|
"registry": "https://registry.npmjs.org"
|
|
38
38
|
},
|
|
39
|
-
"scripts": {
|
|
40
|
-
"sync-base": "rsync -a --delete --exclude='node_modules' --exclude='dist' --exclude='.vantage' --exclude='*.tsbuildinfo' --exclude='*.log' template/ base-template/ && mv base-template/.gitignore base-template/_gitignore",
|
|
41
|
-
"build": "npm run sync-base && tsup",
|
|
42
|
-
"type-check": "tsc",
|
|
43
|
-
"agents": "node scripts/build-agents.cjs",
|
|
44
|
-
"agents:check": "node scripts/build-agents.cjs --check",
|
|
45
|
-
"template:install": "bun install --cwd template --frozen-lockfile",
|
|
46
|
-
"template:build": "npm --prefix template run build",
|
|
47
|
-
"prepublishOnly": "npm run agents:check && npm run build",
|
|
48
|
-
"release": "npm publish --@squadbase:registry=https://registry.npmjs.org",
|
|
49
|
-
"dev": "node scripts/dev.mjs",
|
|
50
|
-
"screenshot": "node scripts/screenshot.mjs"
|
|
51
|
-
},
|
|
52
39
|
"devDependencies": {
|
|
53
40
|
"@types/node": "^22.15.0",
|
|
54
41
|
"playwright": "^1.49.0",
|
|
@@ -58,7 +45,20 @@
|
|
|
58
45
|
"optionalDependencies": {
|
|
59
46
|
"@ai-sdk/anthropic": "^2.0.0",
|
|
60
47
|
"@ai-sdk/google": "^2.0.0",
|
|
61
|
-
"@ai-sdk/openai": "
|
|
48
|
+
"@ai-sdk/openai": "2.0.122",
|
|
62
49
|
"ai": "^5.0.52"
|
|
50
|
+
},
|
|
51
|
+
"gitHead": "7a4f5d9abf8a188105421f02222a69ad9173cffb",
|
|
52
|
+
"scripts": {
|
|
53
|
+
"sync-base": "rsync -a --delete --exclude='node_modules' --exclude='dist' --exclude='.vantage' --exclude='*.tsbuildinfo' --exclude='*.log' template/ base-template/ && mv base-template/.gitignore base-template/_gitignore",
|
|
54
|
+
"build": "pnpm run sync-base && tsup",
|
|
55
|
+
"type-check": "tsc",
|
|
56
|
+
"agents": "node scripts/build-agents.cjs",
|
|
57
|
+
"agents:check": "node scripts/build-agents.cjs --check",
|
|
58
|
+
"template:install": "bun install --cwd template --frozen-lockfile",
|
|
59
|
+
"template:build": "bun run --cwd template build",
|
|
60
|
+
"release": "pnpm publish --@squadbase:registry=https://registry.npmjs.org",
|
|
61
|
+
"dev": "node scripts/dev.mjs",
|
|
62
|
+
"screenshot": "node scripts/screenshot.mjs"
|
|
63
63
|
}
|
|
64
|
-
}
|
|
64
|
+
}
|
package/ui-templates/CLAUDE.md
CHANGED
|
@@ -96,6 +96,8 @@ server/api/<endpoint>.ts # ★ サンプルデータ + GET ハ
|
|
|
96
96
|
| --- | --- |
|
|
97
97
|
| `PageShell*` / `DashboardCard*` / `EChart` / `EChartsOption` / `DataTable*` / `ColumnDef` / `DateRangePicker` / `FilterBar*` / `FunnelSteps` / `MetricValue` / `TrendIndicator` / `StatusBadge` / `SegmentedControl` / `MultiSelect` / `SearchableSelect` / `SectionHeader` / `AppShell` / `Placeholder` / `Sparkline` | `@squadbase/vantage/components` |
|
|
98
98
|
| `Button` / `Input` / `Badge` / `Tabs*` / `ToggleGroup*` / `Table*` / `Select*` / `Dialog*` / `cn` ほか shadcn プリミティブ | `@squadbase/vantage/ui` |
|
|
99
|
+
|
|
100
|
+
型付きチャート(`LineChart` / `AreaChart` / `BarChart` / `DonutChart` / `BarList` / `CategoryBar` / `ProgressCircle` / `Tracker`、`@squadbase/vantage/components`)と `Avatar` / `Pagination` / `RadioGroup` / `AlertDialog` / `Drawer` / `Toaster` / `Field` / `Combobox` / `HoverCard` / `Kbd`(`@squadbase/vantage/ui`)は 0.6.3 で入った。雛形の依存が `^0.5.3` の間は使わない(上の EChart の書き方のまま)。
|
|
99
101
|
| `definePage` | `@squadbase/vantage` |
|
|
100
102
|
| `Link` / `Outlet` / `useParams` / `useSearch` / `useNavigate` / `useRoutes` / `useCurrentRoute` / `useSearchParam` / `useSearchState` | `@squadbase/vantage/router` |
|
|
101
103
|
| `useApiQuery` / `useApiMutation` / `useQuery` / `useMutation` / `apiFetch` | `@squadbase/vantage/query` |
|
|
@@ -104,54 +104,6 @@ const RANGE_OPTIONS: SegmentOption[] = [
|
|
|
104
104
|
{ label: "90 days", value: "90d" },
|
|
105
105
|
]
|
|
106
106
|
|
|
107
|
-
function DashboardBody({ data }: { data: KpiSummary }) {
|
|
108
|
-
return (
|
|
109
|
-
<>
|
|
110
|
-
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
111
|
-
{data.kpis.map((kpi) => {
|
|
112
|
-
const { label, icon: Icon, format } = KPI_META[kpi.id]
|
|
113
|
-
return (
|
|
114
|
-
<DashboardCard key={kpi.id}>
|
|
115
|
-
<DashboardCardHeader>
|
|
116
|
-
<DashboardCardTitle className="text-muted-foreground">
|
|
117
|
-
{label}
|
|
118
|
-
</DashboardCardTitle>
|
|
119
|
-
<DashboardCardAction>
|
|
120
|
-
<Icon className="size-4 text-muted-foreground" />
|
|
121
|
-
</DashboardCardAction>
|
|
122
|
-
</DashboardCardHeader>
|
|
123
|
-
<DashboardCardContent>
|
|
124
|
-
<Placeholder className="text-2xl font-bold">
|
|
125
|
-
{format(kpi.value)}
|
|
126
|
-
</Placeholder>
|
|
127
|
-
<div className="mt-2">
|
|
128
|
-
<Placeholder className="text-sm font-medium">
|
|
129
|
-
{kpi.change >= 0 ? `+${kpi.change}%` : `${kpi.change}%`}
|
|
130
|
-
</Placeholder>
|
|
131
|
-
</div>
|
|
132
|
-
<Sparkline
|
|
133
|
-
data={kpi.sparklineData.map((v) => ({ value: v }))}
|
|
134
|
-
height={32}
|
|
135
|
-
area
|
|
136
|
-
className="mt-3"
|
|
137
|
-
/>
|
|
138
|
-
</DashboardCardContent>
|
|
139
|
-
</DashboardCard>
|
|
140
|
-
)
|
|
141
|
-
})}
|
|
142
|
-
</div>
|
|
143
|
-
|
|
144
|
-
<DashboardCardPreset title="Trend" description="Values over the selected period">
|
|
145
|
-
<EChart option={trendOption(data.trend)} height="320px" />
|
|
146
|
-
</DashboardCardPreset>
|
|
147
|
-
|
|
148
|
-
<DashboardCardPreset title="Top items" description="Ranked by value">
|
|
149
|
-
<TopItemsTable data={data.topItems} />
|
|
150
|
-
</DashboardCardPreset>
|
|
151
|
-
</>
|
|
152
|
-
)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
107
|
export default function HomePage() {
|
|
156
108
|
// Filter state belongs in the URL rather than `useState`: it survives a
|
|
157
109
|
// reload, and a pasted link reproduces exactly what you were looking at.
|
|
@@ -198,3 +150,51 @@ export default function HomePage() {
|
|
|
198
150
|
</PageShell>
|
|
199
151
|
)
|
|
200
152
|
}
|
|
153
|
+
|
|
154
|
+
function DashboardBody({ data }: { data: KpiSummary }) {
|
|
155
|
+
return (
|
|
156
|
+
<>
|
|
157
|
+
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
158
|
+
{data.kpis.map((kpi) => {
|
|
159
|
+
const { label, icon: Icon, format } = KPI_META[kpi.id]
|
|
160
|
+
return (
|
|
161
|
+
<DashboardCard key={kpi.id} data-sq-ref={kpi.id}>
|
|
162
|
+
<DashboardCardHeader>
|
|
163
|
+
<DashboardCardTitle className="text-muted-foreground">
|
|
164
|
+
{label}
|
|
165
|
+
</DashboardCardTitle>
|
|
166
|
+
<DashboardCardAction>
|
|
167
|
+
<Icon className="size-4 text-muted-foreground" />
|
|
168
|
+
</DashboardCardAction>
|
|
169
|
+
</DashboardCardHeader>
|
|
170
|
+
<DashboardCardContent>
|
|
171
|
+
<Placeholder className="text-2xl font-bold">
|
|
172
|
+
{format(kpi.value)}
|
|
173
|
+
</Placeholder>
|
|
174
|
+
<div className="mt-2">
|
|
175
|
+
<Placeholder className="text-sm font-medium">
|
|
176
|
+
{kpi.change >= 0 ? `+${kpi.change}%` : `${kpi.change}%`}
|
|
177
|
+
</Placeholder>
|
|
178
|
+
</div>
|
|
179
|
+
<Sparkline
|
|
180
|
+
data={kpi.sparklineData.map((v) => ({ value: v }))}
|
|
181
|
+
height={32}
|
|
182
|
+
area
|
|
183
|
+
className="mt-3"
|
|
184
|
+
/>
|
|
185
|
+
</DashboardCardContent>
|
|
186
|
+
</DashboardCard>
|
|
187
|
+
)
|
|
188
|
+
})}
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
<DashboardCardPreset data-sq-ref="trend" title="Trend" description="Values over the selected period">
|
|
192
|
+
<EChart option={trendOption(data.trend)} height="320px" />
|
|
193
|
+
</DashboardCardPreset>
|
|
194
|
+
|
|
195
|
+
<DashboardCardPreset data-sq-ref="top-items" title="Top items" description="Ranked by value">
|
|
196
|
+
<TopItemsTable data={data.topItems} />
|
|
197
|
+
</DashboardCardPreset>
|
|
198
|
+
</>
|
|
199
|
+
)
|
|
200
|
+
}
|
|
@@ -104,54 +104,6 @@ const RANGE_OPTIONS: SegmentOption[] = [
|
|
|
104
104
|
{ label: "90日", value: "90d" },
|
|
105
105
|
]
|
|
106
106
|
|
|
107
|
-
function DashboardBody({ data }: { data: KpiSummary }) {
|
|
108
|
-
return (
|
|
109
|
-
<>
|
|
110
|
-
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
111
|
-
{data.kpis.map((kpi) => {
|
|
112
|
-
const { label, icon: Icon, format } = KPI_META[kpi.id]
|
|
113
|
-
return (
|
|
114
|
-
<DashboardCard key={kpi.id}>
|
|
115
|
-
<DashboardCardHeader>
|
|
116
|
-
<DashboardCardTitle className="text-muted-foreground">
|
|
117
|
-
{label}
|
|
118
|
-
</DashboardCardTitle>
|
|
119
|
-
<DashboardCardAction>
|
|
120
|
-
<Icon className="size-4 text-muted-foreground" />
|
|
121
|
-
</DashboardCardAction>
|
|
122
|
-
</DashboardCardHeader>
|
|
123
|
-
<DashboardCardContent>
|
|
124
|
-
<Placeholder className="text-2xl font-bold">
|
|
125
|
-
{format(kpi.value)}
|
|
126
|
-
</Placeholder>
|
|
127
|
-
<div className="mt-2">
|
|
128
|
-
<Placeholder className="text-sm font-medium">
|
|
129
|
-
{kpi.change >= 0 ? `+${kpi.change}%` : `${kpi.change}%`}
|
|
130
|
-
</Placeholder>
|
|
131
|
-
</div>
|
|
132
|
-
<Sparkline
|
|
133
|
-
data={kpi.sparklineData.map((v) => ({ value: v }))}
|
|
134
|
-
height={32}
|
|
135
|
-
area
|
|
136
|
-
className="mt-3"
|
|
137
|
-
/>
|
|
138
|
-
</DashboardCardContent>
|
|
139
|
-
</DashboardCard>
|
|
140
|
-
)
|
|
141
|
-
})}
|
|
142
|
-
</div>
|
|
143
|
-
|
|
144
|
-
<DashboardCardPreset title="トレンド" description="選択期間の値">
|
|
145
|
-
<EChart option={trendOption(data.trend)} height="320px" />
|
|
146
|
-
</DashboardCardPreset>
|
|
147
|
-
|
|
148
|
-
<DashboardCardPreset title="上位項目" description="値で並べ替え">
|
|
149
|
-
<TopItemsTable data={data.topItems} />
|
|
150
|
-
</DashboardCardPreset>
|
|
151
|
-
</>
|
|
152
|
-
)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
107
|
export default function HomePage() {
|
|
156
108
|
// 絞り込み状態は useState ではなく URL に置く。リロードで消えず、URL を
|
|
157
109
|
// そのまま共有すれば相手も同じ画面を見られる。
|
|
@@ -198,3 +150,51 @@ export default function HomePage() {
|
|
|
198
150
|
</PageShell>
|
|
199
151
|
)
|
|
200
152
|
}
|
|
153
|
+
|
|
154
|
+
function DashboardBody({ data }: { data: KpiSummary }) {
|
|
155
|
+
return (
|
|
156
|
+
<>
|
|
157
|
+
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
158
|
+
{data.kpis.map((kpi) => {
|
|
159
|
+
const { label, icon: Icon, format } = KPI_META[kpi.id]
|
|
160
|
+
return (
|
|
161
|
+
<DashboardCard key={kpi.id} data-sq-ref={kpi.id}>
|
|
162
|
+
<DashboardCardHeader>
|
|
163
|
+
<DashboardCardTitle className="text-muted-foreground">
|
|
164
|
+
{label}
|
|
165
|
+
</DashboardCardTitle>
|
|
166
|
+
<DashboardCardAction>
|
|
167
|
+
<Icon className="size-4 text-muted-foreground" />
|
|
168
|
+
</DashboardCardAction>
|
|
169
|
+
</DashboardCardHeader>
|
|
170
|
+
<DashboardCardContent>
|
|
171
|
+
<Placeholder className="text-2xl font-bold">
|
|
172
|
+
{format(kpi.value)}
|
|
173
|
+
</Placeholder>
|
|
174
|
+
<div className="mt-2">
|
|
175
|
+
<Placeholder className="text-sm font-medium">
|
|
176
|
+
{kpi.change >= 0 ? `+${kpi.change}%` : `${kpi.change}%`}
|
|
177
|
+
</Placeholder>
|
|
178
|
+
</div>
|
|
179
|
+
<Sparkline
|
|
180
|
+
data={kpi.sparklineData.map((v) => ({ value: v }))}
|
|
181
|
+
height={32}
|
|
182
|
+
area
|
|
183
|
+
className="mt-3"
|
|
184
|
+
/>
|
|
185
|
+
</DashboardCardContent>
|
|
186
|
+
</DashboardCard>
|
|
187
|
+
)
|
|
188
|
+
})}
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
<DashboardCardPreset data-sq-ref="trend" title="トレンド" description="選択期間の値">
|
|
192
|
+
<EChart option={trendOption(data.trend)} height="320px" />
|
|
193
|
+
</DashboardCardPreset>
|
|
194
|
+
|
|
195
|
+
<DashboardCardPreset data-sq-ref="top-items" title="上位項目" description="値で並べ替え">
|
|
196
|
+
<TopItemsTable data={data.topItems} />
|
|
197
|
+
</DashboardCardPreset>
|
|
198
|
+
</>
|
|
199
|
+
)
|
|
200
|
+
}
|