@squadbase/vantage 0.6.2-dev1.9d91dda → 0.6.2-dev1.abc3f77
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/dist/add-4GHF2TX2.js +6 -0
- package/dist/add-4GHF2TX2.js.map +1 -0
- package/dist/{build-TVKFIVFQ.js → build-A23M4GCH.js} +9 -9
- package/dist/{build-TVKFIVFQ.js.map → build-A23M4GCH.js.map} +1 -1
- package/dist/{check-3KHZXZMQ.js → check-FBHT6W6J.js} +7 -7
- package/dist/{check-3KHZXZMQ.js.map → check-FBHT6W6J.js.map} +1 -1
- package/dist/chunk-2IAPIOPS.js +152 -0
- package/dist/chunk-2IAPIOPS.js.map +1 -0
- package/dist/{chunk-5ZOP4SQR.js → chunk-2N72FKLB.js} +12 -7
- package/dist/chunk-2N72FKLB.js.map +1 -0
- package/dist/chunk-57GHR5LN.js +163 -0
- package/dist/chunk-57GHR5LN.js.map +1 -0
- package/dist/{chunk-P7W4LR3Z.js → chunk-5C2SEDPH.js} +22 -5
- package/dist/chunk-5C2SEDPH.js.map +1 -0
- package/dist/chunk-6OTTGAPO.js +44 -0
- package/dist/chunk-6OTTGAPO.js.map +1 -0
- package/dist/{chunk-RPZAALCX.js → chunk-7S52M2SL.js} +256 -165
- package/dist/chunk-7S52M2SL.js.map +1 -0
- package/dist/{chunk-U2M6HGKQ.js → chunk-AABMKHEU.js} +4 -4
- package/dist/{chunk-U2M6HGKQ.js.map → chunk-AABMKHEU.js.map} +1 -1
- package/dist/{chunk-PVTHHV7X.js → chunk-ANZLVSEP.js} +28 -7
- package/dist/chunk-ANZLVSEP.js.map +1 -0
- package/dist/chunk-CKWPK4RO.js +50 -0
- package/dist/chunk-CKWPK4RO.js.map +1 -0
- package/dist/{chunk-QI3XQKHS.js → chunk-GNXCX4WE.js} +10 -3
- package/dist/chunk-GNXCX4WE.js.map +1 -0
- package/dist/chunk-JXFCSF3K.js +673 -0
- package/dist/chunk-JXFCSF3K.js.map +1 -0
- package/dist/{chunk-PXRX5PEC.js → chunk-PDOBHMUQ.js} +3 -3
- package/dist/chunk-PDOBHMUQ.js.map +1 -0
- package/dist/chunk-QOXXOFGL.js +7051 -0
- package/dist/chunk-QOXXOFGL.js.map +1 -0
- package/dist/{chunk-ZVANIULZ.js → chunk-RNTDBX6S.js} +4 -4
- package/dist/{chunk-ZVANIULZ.js.map → chunk-RNTDBX6S.js.map} +1 -1
- package/dist/{chunk-CEXAQQ5W.js → chunk-S5MDTHH7.js} +180 -18
- package/dist/chunk-S5MDTHH7.js.map +1 -0
- package/dist/chunk-SDJTTMLK.js +1877 -0
- package/dist/chunk-SDJTTMLK.js.map +1 -0
- package/dist/{chunk-LMUACBMA.js → chunk-SHZM3EXB.js} +68 -12
- package/dist/chunk-SHZM3EXB.js.map +1 -0
- package/dist/{chunk-A2UUGASH.js → chunk-U736PVHY.js} +2 -2
- package/dist/chunk-U736PVHY.js.map +1 -0
- package/dist/{chunk-JKLLFVEU.js → chunk-UWSQUHX6.js} +4 -99
- package/dist/chunk-UWSQUHX6.js.map +1 -0
- package/dist/cli.js +12 -11
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts +34 -3
- package/dist/client/index.js +211 -12
- package/dist/client/index.js.map +1 -1
- package/dist/components/index.d.ts +1740 -29
- package/dist/components/index.js +7 -4
- package/dist/delta-text-CvwBGJ95.d.ts +15 -0
- package/dist/{dev-GDKATCC7.js → dev-H4I2JL63.js} +10 -10
- package/dist/dev-H4I2JL63.js.map +1 -0
- package/dist/doc/index.d.ts +215 -2
- package/dist/doc/index.js +309 -5
- package/dist/doc/index.js.map +1 -1
- package/dist/{docs-EJJ3BECT.js → docs-JVP4RPKT.js} +3 -3
- package/dist/{docs-EJJ3BECT.js.map → docs-JVP4RPKT.js.map} +1 -1
- package/dist/{doctor-WQXPXP6K.js → doctor-B2O3GJDU.js} +7 -7
- package/dist/{doctor-WQXPXP6K.js.map → doctor-B2O3GJDU.js.map} +1 -1
- package/dist/format-U0cQl069.d.ts +243 -0
- package/dist/markdown/index.js +1 -1
- package/dist/markdown/index.js.map +1 -1
- package/dist/{preview-OGMCNQUO.js → preview-T6CLSQVX.js} +3 -3
- package/dist/{preview-OGMCNQUO.js.map → preview-T6CLSQVX.js.map} +1 -1
- package/dist/query/index.d.ts +0 -11
- package/dist/query/index.js +2 -2
- package/dist/{routes-MWBWWOJ2.js → routes-PVKNT777.js} +6 -6
- package/dist/{routes-MWBWWOJ2.js.map → routes-PVKNT777.js.map} +1 -1
- package/dist/{search-6Y422SV6.js → search-5LC4XPB5.js} +3 -3
- package/dist/{search-6Y422SV6.js.map → search-5LC4XPB5.js.map} +1 -1
- package/dist/slide/index.d.ts +272 -1
- package/dist/slide/index.js +974 -4
- package/dist/slide/index.js.map +1 -1
- package/dist/table/index.js +14 -10
- package/dist/table/index.js.map +1 -1
- package/dist/ui/index.d.ts +148 -12
- package/dist/ui/index.js +1340 -88
- package/dist/ui/index.js.map +1 -1
- package/dist/{upgrade-HCANX4GQ.js → upgrade-6DT7ADRP.js} +7 -7
- package/dist/{upgrade-HCANX4GQ.js.map → upgrade-6DT7ADRP.js.map} +1 -1
- package/dist/vite/index.d.ts +10 -0
- package/dist/vite/index.js +4 -4
- package/docs/en/changelog.md +2 -0
- package/docs/en/components.md +42 -17
- package/docs/en/doc/delta-text.md +40 -0
- package/docs/en/doc/doc-action-items.md +49 -0
- package/docs/en/doc/doc-callout.md +38 -0
- package/docs/en/doc/doc-data-table.md +60 -0
- package/docs/en/doc/doc-executive-summary.md +64 -0
- package/docs/en/doc/doc-figure.md +56 -0
- package/docs/en/doc/doc-key-findings.md +61 -0
- package/docs/en/doc/doc-kpi-scorecard.md +80 -0
- package/docs/en/doc/doc-notes-and-sources.md +43 -0
- package/docs/en/doc/doc-report-header.md +46 -0
- package/docs/en/pages-and-metadata.md +15 -0
- package/docs/en/parts/area-chart.md +99 -0
- package/docs/en/parts/bar-chart.md +91 -0
- package/docs/en/parts/bar-list.md +50 -0
- package/docs/en/parts/category-bar.md +37 -0
- package/docs/en/parts/chart-frame.md +39 -0
- package/docs/en/parts/data-table.md +22 -0
- package/docs/en/parts/delta.md +51 -0
- package/docs/en/parts/donut-chart.md +72 -0
- package/docs/en/parts/format.md +43 -0
- package/docs/en/parts/funnel-steps.md +2 -1
- package/docs/en/parts/heatmap.md +53 -0
- package/docs/en/parts/kpi-card.md +58 -0
- package/docs/en/parts/legend.md +35 -0
- package/docs/en/parts/line-chart.md +94 -0
- package/docs/en/parts/metric-value.md +3 -2
- package/docs/en/parts/progress-circle.md +33 -0
- package/docs/en/parts/sample-data.md +39 -0
- package/docs/en/parts/scatter-chart.md +56 -0
- package/docs/en/parts/sparkline.md +1 -1
- package/docs/en/parts/tracker.md +36 -0
- package/docs/en/parts/trend-indicator.md +17 -1
- package/docs/en/parts/updated-at.md +30 -0
- package/docs/en/parts/waterfall-chart.md +56 -0
- package/docs/en/slide/slide-chart-full.md +48 -0
- package/docs/en/slide/slide-chart-insight.md +52 -0
- package/docs/en/slide/slide-columns.md +46 -0
- package/docs/en/slide/slide-comparison.md +68 -0
- package/docs/en/slide/slide-cover.md +39 -0
- package/docs/en/slide/slide-exec-summary.md +47 -0
- package/docs/en/slide/slide-heading.md +38 -0
- package/docs/en/slide/slide-kpi-grid.md +55 -0
- package/docs/en/slide/slide-kpi-hero.md +58 -0
- package/docs/en/slide/slide-next-actions.md +49 -0
- package/docs/en/slide/slide-scorecard-table.md +54 -0
- package/docs/en/slide/slide-section.md +44 -0
- package/docs/en/slide/slide-source-line.md +34 -0
- package/docs/en/ui/alert-dialog.md +42 -0
- package/docs/en/ui/avatar.md +31 -0
- package/docs/en/ui/combobox.md +74 -0
- package/docs/en/ui/drawer.md +41 -0
- package/docs/en/ui/empty.md +1 -1
- package/docs/en/ui/error-state.md +4 -3
- package/docs/en/ui/field.md +42 -0
- package/docs/en/ui/hover-card.md +21 -0
- package/docs/en/ui/kbd.md +17 -0
- package/docs/en/ui/loading.md +1 -1
- package/docs/en/ui/pagination.md +36 -0
- package/docs/en/ui/radio-group.md +21 -0
- package/docs/en/ui/toast.md +44 -0
- package/docs/en/ui/toggle-group.md +4 -3
- package/docs/en/ui-and-theming.md +1 -1
- package/docs/index.json +1184 -114
- package/docs/ja/changelog.md +33 -0
- package/docs/ja/components.md +68 -101
- package/docs/ja/doc/delta-text.md +40 -0
- package/docs/ja/doc/doc-action-items.md +49 -0
- package/docs/ja/doc/doc-callout.md +38 -0
- package/docs/ja/doc/doc-data-table.md +60 -0
- package/docs/ja/doc/doc-executive-summary.md +64 -0
- package/docs/ja/doc/doc-figure.md +56 -0
- package/docs/ja/doc/doc-key-findings.md +61 -0
- package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
- package/docs/ja/doc/doc-notes-and-sources.md +43 -0
- package/docs/ja/doc/doc-report-header.md +46 -0
- package/docs/ja/page-types/csv.md +83 -0
- package/docs/ja/page-types/doc.md +83 -0
- package/docs/ja/page-types/excel.md +82 -0
- package/docs/ja/page-types/slide.md +133 -0
- package/docs/ja/page-types.md +47 -0
- package/docs/ja/pages-and-metadata.md +15 -0
- package/docs/ja/parts/area-chart.md +85 -0
- package/docs/ja/parts/bar-chart.md +95 -0
- package/docs/ja/parts/bar-list.md +58 -0
- package/docs/ja/parts/category-bar.md +36 -0
- package/docs/ja/parts/chart-frame.md +36 -0
- package/docs/ja/parts/data-table.md +22 -0
- package/docs/ja/parts/delta.md +51 -0
- package/docs/ja/parts/donut-chart.md +66 -0
- package/docs/ja/parts/echart.md +3 -0
- package/docs/ja/parts/format.md +44 -0
- package/docs/ja/parts/funnel-steps.md +27 -8
- package/docs/ja/parts/heatmap.md +45 -0
- package/docs/ja/parts/kpi-card.md +56 -0
- package/docs/ja/parts/legend.md +36 -0
- package/docs/ja/parts/line-chart.md +84 -0
- package/docs/ja/parts/metric-value.md +3 -2
- package/docs/ja/parts/progress-circle.md +34 -0
- package/docs/ja/parts/sample-data.md +61 -0
- package/docs/ja/parts/scatter-chart.md +69 -0
- package/docs/ja/parts/sparkline.md +2 -2
- package/docs/ja/parts/tracker.md +32 -0
- package/docs/ja/parts/trend-indicator.md +17 -1
- package/docs/ja/parts/updated-at.md +27 -0
- package/docs/ja/parts/waterfall-chart.md +61 -0
- package/docs/ja/routing.md +8 -86
- package/docs/ja/slide/slide-chart-full.md +48 -0
- package/docs/ja/slide/slide-chart-insight.md +52 -0
- package/docs/ja/slide/slide-columns.md +46 -0
- package/docs/ja/slide/slide-comparison.md +68 -0
- package/docs/ja/slide/slide-cover.md +39 -0
- package/docs/ja/slide/slide-exec-summary.md +47 -0
- package/docs/ja/slide/slide-heading.md +38 -0
- package/docs/ja/slide/slide-kpi-grid.md +55 -0
- package/docs/ja/slide/slide-kpi-hero.md +58 -0
- package/docs/ja/slide/slide-next-actions.md +49 -0
- package/docs/ja/slide/slide-scorecard-table.md +54 -0
- package/docs/ja/slide/slide-section.md +44 -0
- package/docs/ja/slide/slide-source-line.md +34 -0
- package/docs/ja/ui/alert-dialog.md +41 -0
- package/docs/ja/ui/avatar.md +31 -0
- package/docs/ja/ui/combobox.md +74 -0
- package/docs/ja/ui/drawer.md +41 -0
- package/docs/ja/ui/empty.md +1 -1
- package/docs/ja/ui/error-state.md +4 -3
- package/docs/ja/ui/field.md +42 -0
- package/docs/ja/ui/hover-card.md +21 -0
- package/docs/ja/ui/kbd.md +16 -0
- package/docs/ja/ui/loading.md +1 -1
- package/docs/ja/ui/pagination.md +36 -0
- package/docs/ja/ui/radio-group.md +21 -0
- package/docs/ja/ui/toast.md +46 -0
- package/docs/ja/ui/toggle-group.md +4 -3
- package/docs/ja/ui-and-theming.md +14 -7
- package/package.json +41 -31
- package/registry/ui/accordion.tsx +76 -0
- package/registry/ui/alert-dialog.tsx +189 -0
- package/registry/ui/alert.tsx +80 -0
- package/registry/ui/app-shell.tsx +287 -0
- package/registry/ui/area-chart.tsx +3701 -0
- package/registry/ui/attention-list.tsx +303 -0
- package/registry/ui/avatar.tsx +110 -0
- package/registry/ui/badge.tsx +56 -0
- package/registry/ui/bar-chart.tsx +3698 -0
- package/registry/ui/bar-list.tsx +3743 -0
- package/registry/ui/box-plot-chart.tsx +3906 -0
- package/registry/ui/breadcrumb.tsx +128 -0
- package/registry/ui/button.tsx +62 -0
- package/registry/ui/calendar.tsx +223 -0
- package/registry/ui/card.tsx +107 -0
- package/registry/ui/category-bar.tsx +1290 -0
- package/registry/ui/chart-frame.tsx +1393 -0
- package/registry/ui/checkbox.tsx +30 -0
- package/registry/ui/collapsible.tsx +23 -0
- package/registry/ui/combobox.tsx +310 -0
- package/registry/ui/command.tsx +198 -0
- package/registry/ui/dashboard-card.tsx +217 -0
- package/registry/ui/data-table.tsx +693 -146
- package/registry/ui/date-range-picker.tsx +390 -0
- package/registry/ui/delta.tsx +191 -0
- package/registry/ui/dialog.tsx +161 -0
- package/registry/ui/donut-chart.tsx +3751 -0
- package/registry/ui/drawer.tsx +229 -0
- package/registry/ui/dropdown-menu.tsx +274 -0
- package/registry/ui/echart.tsx +1040 -0
- package/registry/ui/field.tsx +240 -0
- package/registry/ui/filter-bar.tsx +392 -0
- package/registry/ui/funnel-steps.tsx +3569 -0
- package/registry/ui/heatmap.tsx +1786 -0
- package/registry/ui/histogram-chart.tsx +3986 -0
- package/registry/ui/hover-card.tsx +52 -0
- package/registry/ui/input-group.tsx +160 -0
- package/registry/ui/input.tsx +24 -0
- package/registry/ui/kbd.tsx +30 -0
- package/registry/ui/kpi-card.tsx +704 -0
- package/registry/ui/label.tsx +22 -0
- package/registry/ui/legend.tsx +3563 -0
- package/registry/ui/line-chart.tsx +3699 -0
- package/registry/ui/metric-value.tsx +62 -0
- package/registry/ui/multi-select.tsx +232 -0
- package/registry/ui/page-shell.tsx +282 -0
- package/registry/ui/pagination.tsx +140 -0
- package/registry/ui/paired-chart.tsx +3827 -0
- package/registry/ui/placeholder.tsx +36 -0
- package/registry/ui/popover.tsx +92 -0
- package/registry/ui/progress-circle.tsx +867 -0
- package/registry/ui/progress.tsx +85 -0
- package/registry/ui/radio-group.tsx +39 -0
- package/registry/ui/sample-data.tsx +86 -0
- package/registry/ui/scatter-chart.tsx +4212 -0
- package/registry/ui/scroll-area.tsx +56 -0
- package/registry/ui/searchable-select.tsx +214 -0
- package/registry/ui/section-header.tsx +43 -0
- package/registry/ui/segmented-control.tsx +76 -0
- package/registry/ui/select.tsx +255 -0
- package/registry/ui/separator.tsx +27 -0
- package/registry/ui/sheet.tsx +139 -0
- package/registry/ui/sidebar.tsx +725 -0
- package/registry/ui/skeleton.tsx +17 -0
- package/registry/ui/slider.tsx +56 -0
- package/registry/ui/sparkline.tsx +230 -0
- package/registry/ui/spinner.tsx +14 -0
- package/registry/ui/states.tsx +90 -0
- package/registry/ui/status-badge.tsx +121 -0
- package/registry/ui/switch.tsx +34 -0
- package/registry/ui/table.tsx +118 -0
- package/registry/ui/tabs.tsx +84 -0
- package/registry/ui/textarea.tsx +22 -0
- package/registry/ui/toast.tsx +250 -0
- package/registry/ui/toggle-group.tsx +91 -0
- package/registry/ui/toggle.tsx +47 -0
- package/registry/ui/tooltip.tsx +72 -0
- package/registry/ui/tracker.tsx +849 -0
- package/registry/ui/trend-indicator.tsx +74 -0
- package/registry/ui/updated-at.tsx +122 -0
- package/registry/ui/waterfall-chart.tsx +4248 -0
- package/skills/vantage-add-feature/SKILL.md +9 -7
- package/skills/vantage-design/SKILL.md +34 -24
- package/skills/vantage-design/references/extract.md +16 -14
- package/skills/vantage-design/references/format.md +6 -5
- package/skills/vantage-design/references/presets.md +60 -110
- package/skills/vantage-pitfalls/SKILL.md +10 -1
- package/skills/vantage-slide/SKILL.md +54 -36
- package/templates/AGENTS.md +26 -3
- package/templates/agents/csv.md +2 -1
- package/templates/agents/doc.md +52 -3
- package/templates/agents/page.md +54 -9
- package/templates/agents/slide.md +70 -2
- package/templates/agents/xlsx.md +2 -1
- package/theme.css +247 -138
- package/dist/add-DY4AXANK.js +0 -6
- package/dist/add-DY4AXANK.js.map +0 -1
- package/dist/chunk-5ZOP4SQR.js.map +0 -1
- package/dist/chunk-A2UUGASH.js.map +0 -1
- package/dist/chunk-CEXAQQ5W.js.map +0 -1
- package/dist/chunk-DTDVSFRY.js +0 -29
- package/dist/chunk-DTDVSFRY.js.map +0 -1
- package/dist/chunk-JKLLFVEU.js.map +0 -1
- package/dist/chunk-LMUACBMA.js.map +0 -1
- package/dist/chunk-NKFBFDRZ.js +0 -2241
- package/dist/chunk-NKFBFDRZ.js.map +0 -1
- package/dist/chunk-P7W4LR3Z.js.map +0 -1
- package/dist/chunk-PVTHHV7X.js.map +0 -1
- package/dist/chunk-PXRX5PEC.js.map +0 -1
- package/dist/chunk-QI3XQKHS.js.map +0 -1
- package/dist/chunk-RPZAALCX.js.map +0 -1
- package/dist/chunk-VA776YE5.js +0 -316
- package/dist/chunk-VA776YE5.js.map +0 -1
- package/dist/dev-GDKATCC7.js.map +0 -1
package/theme.css
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/* GENERATED by scripts/gen-theme.mjs — do not edit. Sources:
|
|
2
|
+
* packages/squadkit/registry/theme/theme.css (UI part tokens)
|
|
3
|
+
* packages/squadkit/theme/slide-doc.css (slide / document styles) */
|
|
4
|
+
|
|
1
5
|
/**
|
|
2
6
|
* Vantage design tokens. Imported after `@import "tailwindcss"` by the
|
|
3
7
|
* generated runtime.css. Defines CSS variables (light + dark), maps them to
|
|
@@ -18,123 +22,154 @@
|
|
|
18
22
|
`<select>` popup. */
|
|
19
23
|
color-scheme: light;
|
|
20
24
|
|
|
21
|
-
--background: oklch(
|
|
22
|
-
--foreground: oklch(0.
|
|
25
|
+
--background: oklch(0.975 0.004 255);
|
|
26
|
+
--foreground: oklch(0.21 0.02 260);
|
|
23
27
|
--card: oklch(1 0 0);
|
|
24
|
-
--card-foreground: oklch(0.
|
|
28
|
+
--card-foreground: oklch(0.21 0.02 260);
|
|
25
29
|
--popover: oklch(1 0 0);
|
|
26
|
-
--popover-foreground: oklch(0.
|
|
27
|
-
--primary: oklch(0.
|
|
30
|
+
--popover-foreground: oklch(0.21 0.02 260);
|
|
31
|
+
--primary: oklch(0.55 0.2 262);
|
|
28
32
|
--primary-foreground: oklch(0.985 0 0);
|
|
29
|
-
--secondary: oklch(0.
|
|
30
|
-
--secondary-foreground: oklch(0.
|
|
31
|
-
--muted: oklch(0.
|
|
32
|
-
--muted-foreground: oklch(0.
|
|
33
|
-
--accent: oklch(0.
|
|
34
|
-
--accent-foreground: oklch(0.
|
|
35
|
-
--destructive: oklch(0.
|
|
33
|
+
--secondary: oklch(0.965 0.005 255);
|
|
34
|
+
--secondary-foreground: oklch(0.25 0.02 260);
|
|
35
|
+
--muted: oklch(0.965 0.005 255);
|
|
36
|
+
--muted-foreground: oklch(0.5 0.02 258);
|
|
37
|
+
--accent: oklch(0.955 0.01 255);
|
|
38
|
+
--accent-foreground: oklch(0.25 0.02 260);
|
|
39
|
+
--destructive: oklch(0.53 0.21 27.325);
|
|
36
40
|
--destructive-foreground: oklch(0.985 0 0);
|
|
37
|
-
--border: oklch(0.
|
|
38
|
-
--input: oklch(0.
|
|
39
|
-
--ring: oklch(0.
|
|
40
|
-
--radius: 0.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
--
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
These are aliases, not values. Custom properties resolve lazily, so
|
|
59
|
-
pointing them at the tokens above is enough for a deck to follow `.dark`
|
|
60
|
-
and `[data-theme="dark"]` on its own — restating them in the dark block
|
|
61
|
-
below would create two places to keep in step for no gain. A deck
|
|
62
|
-
overrides any of them inline through `<SlideDeck theme>`. */
|
|
63
|
-
--slide-bg: var(--background);
|
|
64
|
-
--slide-fg: var(--foreground);
|
|
65
|
-
--slide-accent: var(--primary);
|
|
66
|
-
--slide-muted: var(--muted-foreground);
|
|
67
|
-
--slide-radius: var(--radius);
|
|
68
|
-
/* A system stack that includes Japanese. The pptx export rasterises through
|
|
69
|
-
an SVG `foreignObject`, where locally installed families resolve by name
|
|
70
|
-
but webfonts must be inlined — so a system default is what makes the
|
|
71
|
-
common path export correctly with nothing embedded. */
|
|
72
|
-
--slide-font-display:
|
|
73
|
-
system-ui, -apple-system, "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo,
|
|
41
|
+
--border: oklch(0.93 0.006 255);
|
|
42
|
+
--input: oklch(0.9 0.01 255);
|
|
43
|
+
--ring: oklch(0.7 0.12 262);
|
|
44
|
+
--radius: 0.5rem;
|
|
45
|
+
|
|
46
|
+
/* Card elevation: a hairline-soft shadow in light, none in dark (the border does the work there). */
|
|
47
|
+
--shadow-card: 0 1px 2px 0 oklch(0.2 0.02 260 / 0.06);
|
|
48
|
+
|
|
49
|
+
/* Body typeface: a system stack only (no web font is shipped). Presets may swap
|
|
50
|
+
it; `@theme inline` below points `font-sans` at this variable, so overriding
|
|
51
|
+
the variable also moves the utility (and the `html` rule in `@layer base`).
|
|
52
|
+
Latin system faces carry no kana/kanji, so without Japanese families here the
|
|
53
|
+
browser picks a per-locale fallback (lang="en" -> e.g. thin "Yu Gothic" Regular
|
|
54
|
+
on Windows, or a face without a 500 weight on macOS) and kana render thin.
|
|
55
|
+
List the Japanese system faces explicitly, after the Latin ones, and keep
|
|
56
|
+
`ui-sans-serif` / `system-ui` behind them: on Japanese Windows both resolve to
|
|
57
|
+
the menu font, Yu Gothic UI, which is condensed (made to avoid UI resizing)
|
|
58
|
+
and has kana, so it would take the kana before Meiryo is ever reached.
|
|
59
|
+
`-apple-system` is Safari/Firefox; Chrome on macOS needs `BlinkMacSystemFont`. */
|
|
60
|
+
--font-sans:
|
|
61
|
+
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Noto Sans JP", Meiryo, ui-sans-serif, system-ui,
|
|
74
62
|
sans-serif;
|
|
75
|
-
--slide-font-body: var(--slide-font-display);
|
|
76
|
-
/* Canvas pixels, on the 1920x1080 canvas — not rem: a slide is scaled as a
|
|
77
|
-
whole, so its type must not also follow the browser's root font size. */
|
|
78
|
-
--slide-size-hero: 168px;
|
|
79
|
-
--slide-size-body: 36px;
|
|
80
63
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
--
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
--
|
|
89
|
-
--
|
|
90
|
-
--
|
|
91
|
-
--
|
|
92
|
-
--
|
|
93
|
-
--
|
|
94
|
-
--
|
|
95
|
-
--
|
|
64
|
+
--chart-1: oklch(0.55 0.2 262);
|
|
65
|
+
--chart-2: oklch(0.62 0.17 118);
|
|
66
|
+
--chart-3: oklch(0.5 0.19 352);
|
|
67
|
+
--chart-4: oklch(0.62 0.1 195);
|
|
68
|
+
--chart-5: oklch(0.44 0.18 300);
|
|
69
|
+
|
|
70
|
+
/* Semantic status tokens — see the contract above the `@theme inline` block. */
|
|
71
|
+
--positive: oklch(0.52 0.14 150);
|
|
72
|
+
--positive-subtle: oklch(0.96 0.04 150);
|
|
73
|
+
--negative: oklch(0.53 0.19 25);
|
|
74
|
+
--negative-subtle: oklch(0.96 0.03 25);
|
|
75
|
+
--warning: oklch(0.53 0.12 70);
|
|
76
|
+
--warning-subtle: oklch(0.96 0.05 85);
|
|
77
|
+
--info: oklch(0.52 0.16 255);
|
|
78
|
+
--info-subtle: oklch(0.96 0.03 250);
|
|
79
|
+
--positive-fill: oklch(0.62 0.15 150);
|
|
80
|
+
--negative-fill: oklch(0.62 0.17 25);
|
|
81
|
+
--warning-fill: oklch(0.79 0.16 82);
|
|
82
|
+
--info-fill: oklch(0.62 0.15 250);
|
|
83
|
+
--neutral-fill: oklch(0.62 0 0);
|
|
84
|
+
--neutral: oklch(0.52 0 0);
|
|
85
|
+
--neutral-subtle: oklch(0.96 0 0);
|
|
86
|
+
|
|
87
|
+
--sidebar: oklch(0.985 0.003 255);
|
|
88
|
+
--sidebar-foreground: oklch(0.21 0.02 260);
|
|
89
|
+
--sidebar-primary: oklch(0.55 0.2 262);
|
|
90
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
91
|
+
--sidebar-accent: oklch(0.955 0.01 255);
|
|
92
|
+
--sidebar-accent-foreground: oklch(0.25 0.02 260);
|
|
93
|
+
--sidebar-border: oklch(0.915 0.008 255);
|
|
94
|
+
--sidebar-ring: oklch(0.7 0.12 262);
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
.dark,
|
|
99
98
|
[data-theme="dark"] {
|
|
100
99
|
color-scheme: dark;
|
|
101
100
|
|
|
102
|
-
--
|
|
103
|
-
|
|
104
|
-
--
|
|
105
|
-
--
|
|
106
|
-
--
|
|
107
|
-
--
|
|
108
|
-
--
|
|
109
|
-
--
|
|
110
|
-
--
|
|
111
|
-
--
|
|
112
|
-
--
|
|
113
|
-
--
|
|
114
|
-
--
|
|
115
|
-
--
|
|
101
|
+
--shadow-card: none;
|
|
102
|
+
|
|
103
|
+
--background: oklch(0.16 0.012 262);
|
|
104
|
+
--foreground: oklch(0.96 0.005 255);
|
|
105
|
+
--card: oklch(0.215 0.015 262);
|
|
106
|
+
--card-foreground: oklch(0.96 0.005 255);
|
|
107
|
+
--popover: oklch(0.235 0.016 262);
|
|
108
|
+
--popover-foreground: oklch(0.96 0.005 255);
|
|
109
|
+
--primary: oklch(0.68 0.19 262);
|
|
110
|
+
--primary-foreground: oklch(0.145 0.02 262);
|
|
111
|
+
--secondary: oklch(0.27 0.016 262);
|
|
112
|
+
--secondary-foreground: oklch(0.96 0.005 255);
|
|
113
|
+
--muted: oklch(0.27 0.016 262);
|
|
114
|
+
--muted-foreground: oklch(0.72 0.02 258);
|
|
115
|
+
--accent: oklch(0.3 0.02 262);
|
|
116
|
+
--accent-foreground: oklch(0.96 0.005 255);
|
|
116
117
|
--destructive: oklch(0.704 0.191 22.216);
|
|
117
|
-
--destructive-foreground: oklch(0.
|
|
118
|
+
--destructive-foreground: oklch(0.145 0.02 262);
|
|
118
119
|
--border: oklch(1 0 0 / 10%);
|
|
119
120
|
--input: oklch(1 0 0 / 15%);
|
|
120
|
-
--ring: oklch(0.
|
|
121
|
-
|
|
122
|
-
--chart-1:
|
|
123
|
-
--chart-2:
|
|
124
|
-
--chart-3:
|
|
125
|
-
--chart-4:
|
|
126
|
-
--chart-5:
|
|
127
|
-
|
|
128
|
-
--
|
|
129
|
-
--
|
|
130
|
-
--
|
|
131
|
-
--
|
|
132
|
-
--
|
|
133
|
-
--
|
|
121
|
+
--ring: oklch(0.6 0.15 262);
|
|
122
|
+
|
|
123
|
+
--chart-1: oklch(0.56 0.19 262);
|
|
124
|
+
--chart-2: oklch(0.75 0.17 118);
|
|
125
|
+
--chart-3: oklch(0.64 0.19 352);
|
|
126
|
+
--chart-4: oklch(0.78 0.105 195);
|
|
127
|
+
--chart-5: oklch(0.71 0.17 300);
|
|
128
|
+
|
|
129
|
+
--positive: oklch(0.76 0.15 150);
|
|
130
|
+
--positive-subtle: oklch(0.27 0.05 150);
|
|
131
|
+
--negative: oklch(0.74 0.15 22);
|
|
132
|
+
--negative-subtle: oklch(0.27 0.06 25);
|
|
133
|
+
--warning: oklch(0.8 0.14 80);
|
|
134
|
+
--warning-subtle: oklch(0.27 0.05 75);
|
|
135
|
+
--info: oklch(0.75 0.12 250);
|
|
136
|
+
--info-subtle: oklch(0.27 0.06 255);
|
|
137
|
+
--positive-fill: oklch(0.56 0.13 150);
|
|
138
|
+
--negative-fill: oklch(0.56 0.15 22);
|
|
139
|
+
--warning-fill: oklch(0.73 0.145 78);
|
|
140
|
+
--info-fill: oklch(0.56 0.13 250);
|
|
141
|
+
--neutral-fill: oklch(0.56 0 0);
|
|
142
|
+
--neutral: oklch(0.85 0 0);
|
|
143
|
+
--neutral-subtle: oklch(0.27 0 0);
|
|
144
|
+
|
|
145
|
+
--sidebar: oklch(0.2 0.014 262);
|
|
146
|
+
--sidebar-foreground: oklch(0.96 0.005 255);
|
|
147
|
+
--sidebar-primary: oklch(0.68 0.19 262);
|
|
148
|
+
--sidebar-primary-foreground: oklch(0.145 0.02 262);
|
|
149
|
+
--sidebar-accent: oklch(0.3 0.02 262);
|
|
150
|
+
--sidebar-accent-foreground: oklch(0.96 0.005 255);
|
|
134
151
|
--sidebar-border: oklch(1 0 0 / 10%);
|
|
135
|
-
--sidebar-ring: oklch(0.
|
|
152
|
+
--sidebar-ring: oklch(0.6 0.15 262);
|
|
136
153
|
}
|
|
137
154
|
|
|
155
|
+
/* Semantic status tokens (increase/decrease/status). Every increase, decrease
|
|
156
|
+
and status colour in registry/ comes from these — never a Tailwind palette
|
|
157
|
+
colour like `green-500` (tests/raw-colors.test.ts enforces it).
|
|
158
|
+
--<tone> text colour on --background, --card and --<tone>-subtle
|
|
159
|
+
(>= 4.5:1), and dot / line / icon colour (>= 3:1).
|
|
160
|
+
--<tone>-subtle tinted background behind --<tone> text (badges, callouts).
|
|
161
|
+
--<tone>-fill (incl. --neutral-fill, the grey area) FILL colour for areas (bars, heatmap cells, tracker blocks). Not for
|
|
162
|
+
text or icons — use --<tone>. Same lightness step from the page in both
|
|
163
|
+
modes (light 0.62 / dark 0.56: ~0.36-0.40 OKLCH L away from --background,
|
|
164
|
+
>= 3:1 against --background and --card), so a fill is never strong in one
|
|
165
|
+
mode and faint in the other. Presets may tune hue and chroma within the
|
|
166
|
+
status bands while preserving contrast and fill strength (tests/theme-presets.test.ts).
|
|
167
|
+
--warning-fill is the exception: amber (light 0.79 / dark 0.73, ~#f5b324 / ~#d99a1e) is
|
|
168
|
+
a light colour by nature, so it is ~2:1 on the light page (still >= 0.18 L away)
|
|
169
|
+
and ~7-8:1 on the dark one; dark text (--foreground in light, --background in dark) sits on it at >= 4.5:1.
|
|
170
|
+
Tones: positive (green), negative (red), warning (amber), info (blue),
|
|
171
|
+
neutral (grey). Colour never carries the meaning alone — pair it with an
|
|
172
|
+
arrow or sign. `npm run contrast` prints the measured ratios. */
|
|
138
173
|
@theme inline {
|
|
139
174
|
--color-background: var(--background);
|
|
140
175
|
--color-foreground: var(--foreground);
|
|
@@ -155,6 +190,21 @@
|
|
|
155
190
|
--color-border: var(--border);
|
|
156
191
|
--color-input: var(--input);
|
|
157
192
|
--color-ring: var(--ring);
|
|
193
|
+
--color-positive: var(--positive);
|
|
194
|
+
--color-positive-subtle: var(--positive-subtle);
|
|
195
|
+
--color-negative: var(--negative);
|
|
196
|
+
--color-negative-subtle: var(--negative-subtle);
|
|
197
|
+
--color-warning: var(--warning);
|
|
198
|
+
--color-warning-subtle: var(--warning-subtle);
|
|
199
|
+
--color-info: var(--info);
|
|
200
|
+
--color-info-subtle: var(--info-subtle);
|
|
201
|
+
--color-positive-fill: var(--positive-fill);
|
|
202
|
+
--color-negative-fill: var(--negative-fill);
|
|
203
|
+
--color-warning-fill: var(--warning-fill);
|
|
204
|
+
--color-info-fill: var(--info-fill);
|
|
205
|
+
--color-neutral-fill: var(--neutral-fill);
|
|
206
|
+
--color-neutral: var(--neutral);
|
|
207
|
+
--color-neutral-subtle: var(--neutral-subtle);
|
|
158
208
|
--color-chart-1: var(--chart-1);
|
|
159
209
|
--color-chart-2: var(--chart-2);
|
|
160
210
|
--color-chart-3: var(--chart-3);
|
|
@@ -168,10 +218,7 @@
|
|
|
168
218
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
169
219
|
--color-sidebar-border: var(--sidebar-border);
|
|
170
220
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
171
|
-
--
|
|
172
|
-
--color-slide-fg: var(--slide-fg);
|
|
173
|
-
--color-slide-accent: var(--slide-accent);
|
|
174
|
-
--color-slide-muted: var(--slide-muted);
|
|
221
|
+
--font-sans: var(--font-sans);
|
|
175
222
|
--radius-sm: calc(var(--radius) - 4px);
|
|
176
223
|
--radius-md: calc(var(--radius) - 2px);
|
|
177
224
|
--radius-lg: var(--radius);
|
|
@@ -272,6 +319,103 @@
|
|
|
272
319
|
}
|
|
273
320
|
}
|
|
274
321
|
|
|
322
|
+
/* ------------------------------------------------------------ utilities */
|
|
323
|
+
|
|
324
|
+
@utility no-scrollbar {
|
|
325
|
+
-ms-overflow-style: none;
|
|
326
|
+
scrollbar-width: none;
|
|
327
|
+
|
|
328
|
+
&::-webkit-scrollbar {
|
|
329
|
+
display: none;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* Icons that must point the other way when the document is right-to-left. */
|
|
334
|
+
.cn-rtl-flip {
|
|
335
|
+
&:where([dir="rtl"], [dir="rtl"] *) {
|
|
336
|
+
transform: scaleX(-1);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/* Page defaults live in `@layer base`, like shadcn's own init, so a project's
|
|
341
|
+
`html { @apply font-sans }`, its `next/font` setup and its own border rules
|
|
342
|
+
(all unlayered or later in the layer) win over them instead of losing to an
|
|
343
|
+
unlayered rule here. */
|
|
344
|
+
@layer base {
|
|
345
|
+
html {
|
|
346
|
+
font-family: var(--font-sans);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
body {
|
|
350
|
+
background-color: var(--background);
|
|
351
|
+
color: var(--foreground);
|
|
352
|
+
-webkit-font-smoothing: antialiased;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
* {
|
|
356
|
+
border-color: var(--border);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Vantage framework styles: the slide / document tokens and the document
|
|
362
|
+
* typesetting. The UI parts' tokens live in SquadKit
|
|
363
|
+
* (packages/squadkit/registry/theme/theme.css); packages/vantage/scripts/gen-theme.mjs
|
|
364
|
+
* appends this file to them to produce packages/vantage/theme.css.
|
|
365
|
+
*/
|
|
366
|
+
|
|
367
|
+
:root {
|
|
368
|
+
/* Slides (@squadbase/vantage/slide).
|
|
369
|
+
These are aliases, not values. A var() in a custom property is resolved
|
|
370
|
+
on the element that declares it and inherited as that result, so
|
|
371
|
+
pointing them at the tokens above is enough for a deck to follow `.dark`
|
|
372
|
+
and `[data-theme="dark"]` set on :root — restating them in the dark block
|
|
373
|
+
below would create two places to keep in step for no gain. Tokens
|
|
374
|
+
overridden on a descendant (a scoped theme) do not reach them: re-declare
|
|
375
|
+
the aliases there. A deck overrides any of them inline through
|
|
376
|
+
`<SlideDeck theme>`. */
|
|
377
|
+
--slide-bg: var(--background);
|
|
378
|
+
--slide-fg: var(--foreground);
|
|
379
|
+
--slide-accent: var(--primary);
|
|
380
|
+
--slide-muted: var(--muted-foreground);
|
|
381
|
+
--slide-radius: var(--radius);
|
|
382
|
+
/* A system stack that includes Japanese. The pptx export rasterises through
|
|
383
|
+
an SVG `foreignObject`, where locally installed families resolve by name
|
|
384
|
+
but webfonts must be inlined — so a system default is what makes the
|
|
385
|
+
common path export correctly with nothing embedded. */
|
|
386
|
+
--slide-font-display:
|
|
387
|
+
-apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo,
|
|
388
|
+
system-ui, sans-serif;
|
|
389
|
+
--slide-font-body: var(--slide-font-display);
|
|
390
|
+
/* Canvas pixels, on the 1920x1080 canvas — not rem: a slide is scaled as a
|
|
391
|
+
whole, so its type must not also follow the browser's root font size. */
|
|
392
|
+
--slide-size-hero: 168px;
|
|
393
|
+
--slide-size-body: 36px;
|
|
394
|
+
|
|
395
|
+
/* Documents (@squadbase/vantage/doc). Aliases, like --slide-*: they follow
|
|
396
|
+
`.dark` through the tokens they point at, so they are not restated in the
|
|
397
|
+
dark block. A document overrides any of them inline through
|
|
398
|
+
`<Document theme>`, an app through its styles.css. */
|
|
399
|
+
--doc-fg: var(--foreground);
|
|
400
|
+
--doc-muted: var(--muted-foreground);
|
|
401
|
+
--doc-accent: var(--primary);
|
|
402
|
+
--doc-border: var(--border);
|
|
403
|
+
--doc-subtle: var(--muted);
|
|
404
|
+
--doc-font-body: inherit;
|
|
405
|
+
--doc-font-heading: var(--doc-font-body);
|
|
406
|
+
--doc-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
407
|
+
--doc-size-body: 1rem;
|
|
408
|
+
--doc-line-height: 1.8;
|
|
409
|
+
--doc-max-width: 48rem;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
@theme inline {
|
|
413
|
+
--color-slide-bg: var(--slide-bg);
|
|
414
|
+
--color-slide-fg: var(--slide-fg);
|
|
415
|
+
--color-slide-accent: var(--slide-accent);
|
|
416
|
+
--color-slide-muted: var(--slide-muted);
|
|
417
|
+
}
|
|
418
|
+
|
|
275
419
|
/* ------------------------------------------------------------ documents */
|
|
276
420
|
|
|
277
421
|
/* Typesetting for `<Document>`. Plain elements inside it need no classes.
|
|
@@ -440,38 +584,3 @@
|
|
|
440
584
|
overflow: visible;
|
|
441
585
|
}
|
|
442
586
|
}
|
|
443
|
-
|
|
444
|
-
/* ------------------------------------------------------------ utilities */
|
|
445
|
-
|
|
446
|
-
@utility no-scrollbar {
|
|
447
|
-
-ms-overflow-style: none;
|
|
448
|
-
scrollbar-width: none;
|
|
449
|
-
|
|
450
|
-
&::-webkit-scrollbar {
|
|
451
|
-
display: none;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
/* Icons that must point the other way when the document is right-to-left. */
|
|
456
|
-
.cn-rtl-flip {
|
|
457
|
-
&:where([dir="rtl"], [dir="rtl"] *) {
|
|
458
|
-
transform: scaleX(-1);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
body {
|
|
463
|
-
background-color: var(--background);
|
|
464
|
-
color: var(--foreground);
|
|
465
|
-
/* Latin system faces carry no kana/kanji, so without Japanese families here the
|
|
466
|
-
browser picks a per-locale fallback (lang="en" → e.g. thin "Yu Gothic" Regular
|
|
467
|
-
on Windows, or a face without a 500 weight on macOS) and kana render thin.
|
|
468
|
-
List the Japanese system faces explicitly, after the Latin ones. */
|
|
469
|
-
font-family:
|
|
470
|
-
ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Noto Sans JP", "Yu Gothic UI", Meiryo,
|
|
471
|
-
sans-serif;
|
|
472
|
-
-webkit-font-smoothing: antialiased;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
* {
|
|
476
|
-
border-color: var(--border);
|
|
477
|
-
}
|
package/dist/add-DY4AXANK.js
DELETED
package/dist/add-DY4AXANK.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"add-DY4AXANK.js"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/states.tsx"],"names":[],"mappings":";;;;AAGO,SAAS,OAAA,CAAQ,EAAE,KAAA,GAAQ,eAAA,EAAY,WAAU,EAA2C;AACjG,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,iDAAiD,SAAS,CAAA,EAAG,IAAA,EAAK,QAAA,EAAS,WAAA,EAAU,QAAA,EACtG,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,uDAAA,EACb,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,gFAAA,EAAiF,CAAA;AAAA,IAChG;AAAA,GAAA,EACH,CAAA,EACF,CAAA;AAEJ;AAEO,SAAS,KAAA,CAAM;AAAA,EACpB,KAAA,GAAQ,kBAAA;AAAA,EACR,WAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAMG;AACD,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,kEAAA,EAAoE,SAAS,CAAA,EAC7F,QAAA,EAAA;AAAA,IAAA,IAAA,mBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EAAkC,gBAAK,CAAA,GAAS,IAAA;AAAA,oBACvE,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,aAAA,EAAe,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,IACjC,8BAAc,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wCAAA,EAA0C,uBAAY,CAAA,GAAO,IAAA;AAAA,IACxF,yBAAS,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,MAAA,EAAQ,kBAAO,CAAA,GAAS;AAAA,GAAA,EACnD,CAAA;AAEJ;AAEO,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA,GAAQ,sBAAA;AAAA,EACR,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,8DAAA,EAAgE,SAAS,CAAA;AAAA,MACvF,IAAA,EAAK,OAAA;AAAA,MAEL,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,gCAAA,EAAkC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QACpD,0BAAU,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oCAAA,EAAsC,mBAAQ,CAAA,GAAO,IAAA;AAAA,QAC5E,yBAAS,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,MAAA,EAAQ,kBAAO,CAAA,GAAS;AAAA;AAAA;AAAA,GACnD;AAEJ","file":"chunk-5ZOP4SQR.js","sourcesContent":["import type { ReactNode } from \"react\"\nimport { cn } from \"./cn\"\n\nexport function Loading({ label = \"Loading…\", className }: { label?: string; className?: string }) {\n return (\n <div className={cn(\"flex min-h-[30vh] items-center justify-center\", className)} role=\"status\" aria-live=\"polite\">\n <div className=\"flex items-center gap-3 text-sm text-muted-foreground\">\n <span className=\"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n {label}\n </div>\n </div>\n )\n}\n\nexport function Empty({\n title = \"Nothing here yet\",\n description,\n icon,\n action,\n className,\n}: {\n title?: string\n description?: string\n icon?: ReactNode\n action?: ReactNode\n className?: string\n}) {\n return (\n <div className={cn(\"flex flex-col items-center justify-center gap-2 p-10 text-center\", className)}>\n {icon ? <div className=\"text-3xl text-muted-foreground\">{icon}</div> : null}\n <p className=\"font-medium\">{title}</p>\n {description ? <p className=\"max-w-sm text-sm text-muted-foreground\">{description}</p> : null}\n {action ? <div className=\"mt-2\">{action}</div> : null}\n </div>\n )\n}\n\nexport function ErrorState({\n title = \"Something went wrong\",\n message,\n action,\n className,\n}: {\n title?: string\n message?: ReactNode\n action?: ReactNode\n className?: string\n}) {\n return (\n <div\n className={cn(\"rounded-xl border border-destructive/30 bg-destructive/5 p-6\", className)}\n role=\"alert\"\n >\n <p className=\"font-semibold text-destructive\">{title}</p>\n {message ? <p className=\"mt-1 text-sm text-muted-foreground\">{message}</p> : null}\n {action ? <div className=\"mt-3\">{action}</div> : null}\n </div>\n )\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/cn.ts"],"names":[],"mappings":";;;;;AAUO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"chunk-A2UUGASH.js","sourcesContent":["/**\n * Class merger used by every component in the kit. `clsx` resolves conditional\n * class values, `tailwind-merge` drops the earlier of two conflicting Tailwind\n * utilities so a caller's `className` always wins over a component default.\n */\nimport { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport type { ClassValue }\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs))\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/placeholder.ts","../src/core/file-page.ts","../src/core/route-tree.ts"],"names":["depth","path"],"mappings":"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","file":"chunk-CEXAQQ5W.js","sourcesContent":["/**\n * Detect whether a file is an untouched template placeholder.\n *\n * When a Vantage project is initialized from the template, it includes\n * a placeholder home page at `src/index.tsx` (or `index.tsx` at the root).\n * If that file remains completely untouched and a new artifact (e.g. a slide)\n * wants to claim route `/`, we allow it by treating the placeholder as yieldable\n * instead of reporting ROUTE_CONFLICT.\n */\n\n/**\n * Expected content of the template placeholder `src/index.tsx`.\n * This is the exact content from @squadbase/vantage-template 0.1.1.\n * When the template is updated, this constant must be updated as well.\n */\nconst PLACEHOLDER_HOME_PAGE = `import { definePage } from \"@squadbase/vantage\"\nimport {\n DashboardCardPreset,\n EChart,\n PageShell,\n PageShellContent,\n PageShellDescription,\n PageShellHeader,\n PageShellHeading,\n PageShellTitle,\n Placeholder,\n Sparkline,\n type EChartsOption,\n} from \"@squadbase/vantage/components\"\n\nexport const page = definePage({\n title: \"Dashboard\",\n description: \"Sample data — replace with your own to get started.\",\n navLabel: \"Home\",\n})\n\nconst METRICS = [\n { label: \"Metric 1\", value: \"1,234\", trend: [3, 4, 3, 5, 6, 5, 7] },\n { label: \"Metric 2\", value: \"5,678\", trend: [6, 5, 6, 4, 5, 6, 6] },\n { label: \"Metric 3\", value: \"90.1%\", trend: [2, 3, 5, 4, 6, 7, 8] },\n { label: \"Metric 4\", value: \"$12.3k\", trend: [5, 6, 4, 6, 5, 7, 6] },\n]\n\n// Sample charts. \\`EChart\\` paints series with \\`--chart-1..5\\` and the sparklines\n// use \\`--primary\\` (both from \\`styles.css\\`), so a theme change shows up here.\nconst BAR_OPTION: EChartsOption = {\n legend: { top: 0 },\n grid: { top: 36, right: 8, bottom: 24, left: 36 },\n xAxis: { type: \"category\", data: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\"] },\n yAxis: { type: \"value\" },\n series: [\n { name: \"Series A\", type: \"bar\", data: [12, 18, 15, 22, 26, 24] },\n { name: \"Series B\", type: \"bar\", data: [8, 11, 13, 12, 16, 19] },\n { name: \"Series C\", type: \"bar\", data: [5, 7, 6, 9, 8, 11] },\n ],\n}\n\nconst PIE_OPTION: EChartsOption = {\n legend: { bottom: 0 },\n series: [\n {\n type: \"pie\",\n radius: [\"45%\", \"70%\"],\n center: [\"50%\", \"45%\"],\n label: { show: false },\n data: [\n { name: \"Category A\", value: 35 },\n { name: \"Category B\", value: 25 },\n { name: \"Category C\", value: 18 },\n { name: \"Category D\", value: 12 },\n { name: \"Category E\", value: 10 },\n ],\n },\n ],\n}\n\nconst CHARTS = [\n { title: \"Chart 1\", option: BAR_OPTION },\n { title: \"Chart 2\", option: PIE_OPTION },\n]\n\nexport default function HomePage() {\n return (\n <PageShell>\n <PageShellHeader>\n <PageShellHeading>\n <PageShellTitle>Dashboard</PageShellTitle>\n <PageShellDescription>\n Sample data — replace with your own to get started.\n </PageShellDescription>\n </PageShellHeading>\n </PageShellHeader>\n\n <PageShellContent>\n <section className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4\">\n {METRICS.map((metric) => (\n <DashboardCardPreset key={metric.label} title={metric.label}>\n <Placeholder className=\"text-2xl font-bold\">{metric.value}</Placeholder>\n <Sparkline\n className=\"mt-2\"\n data={metric.trend.map((value) => ({ value }))}\n color=\"text-primary\"\n area\n />\n </DashboardCardPreset>\n ))}\n </section>\n\n <section className=\"grid grid-cols-1 gap-4 lg:grid-cols-2\">\n {CHARTS.map((chart) => (\n <DashboardCardPreset key={chart.title} title={chart.title}>\n <EChart option={chart.option} height={256} ariaLabel={chart.title} />\n </DashboardCardPreset>\n ))}\n </section>\n </PageShellContent>\n </PageShell>\n )\n}\n`\n\n/**\n * Check if a file content matches the template placeholder home page.\n * Returns true if the file is the exact untouched placeholder.\n * \n * This is a fallback for projects created from the older template (0.1.1-dev1.2be5c44)\n * before the explicit `placeholder: true` marker was added.\n */\nexport function isPlaceholderHomePage(content: string): boolean {\n // First check for explicit placeholder marker\n if (/\\bplaceholder\\s*:\\s*true\\b/.test(content)) return true\n \n // Fallback: exact content match for older templates\n return content.trim() === PLACEHOLDER_HOME_PAGE.trim()\n}\n\n/**\n * Check if a file path is the home page (index.tsx at root or in src/).\n */\nexport function isHomePagePath(file: string): boolean {\n return file === \"index.tsx\" || file === \"src/index.tsx\"\n}\n","/**\n * Everything the rest of the framework needs to know about a data-file page:\n * its title, the token the viewer switches on, and the name of the wrapper\n * module generated for it. One source of truth, the same way\n * `route-spec.ts`'s `detectApiMethods` is the one source for API methods —\n * `route-tree.ts` (metadata) and `generate.ts` (codegen) both read from here.\n */\nimport path from \"node:path\"\nimport { createHash } from \"node:crypto\"\n\n/** The parts of a file page each helper below needs. */\ninterface FileNamed {\n /** Project-relative POSIX path. */\n file: string\n}\ninterface FileTyped {\n /** The data-file extension, e.g. `\".csv\"`. */\n fileExt?: string\n}\n/** Metadata also needs the page-root-relative directory, which the URL uses. */\ntype FileMetaInput = FileNamed & FileTyped & { dir: string }\n\n/** The same shape `definePage` metadata takes, so callers can spread either. */\ninterface PageMeta {\n title?: string\n description?: string\n navLabel?: string\n placeholder?: boolean\n}\n\n/**\n * Turn a file stem into a title: `monthly_report-2024` -> \"Monthly Report\n * 2024\", `salesByRegion` -> \"Sales By Region\". All-caps tokens are left alone\n * (`KPI` stays `KPI`) because they are almost always acronyms.\n */\nexport function humanize(stem: string): string {\n return stem\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((word) => (word === word.toUpperCase() ? word : word[0]!.toUpperCase() + word.slice(1)))\n .join(\" \")\n}\n\n/**\n * Title for a data-file page, derived from its name — a spreadsheet cannot\n * carry a `definePage`. `index.csv` borrows its directory's name (its own name\n * is not in the URL either); a root-level `index.csv` gets no title at all,\n * exactly like a root `index.tsx` without `definePage`.\n */\nexport function filePageMeta(page: FileMetaInput): PageMeta {\n const base = path.posix.basename(page.file)\n let stem = page.fileExt ? base.slice(0, -page.fileExt.length) : base\n if (stem.toLowerCase() === \"index\") stem = page.dir.split(\"/\").filter(Boolean).pop() ?? \"\"\n if (stem === \"\") return {}\n return { title: humanize(stem) }\n}\n\n/** The token handed to the client viewer: `\".xlsx\"` -> `\"xlsx\"`. */\nexport function filePageKind(page: FileTyped): string {\n return (page.fileExt ?? \"\").slice(1)\n}\n\n/**\n * Name of the wrapper module generated for a data-file page. Derived from the\n * source path so it is stable across runs (`writeIfChanged` stays a no-op) and\n * readable in a stack trace; the hash suffix keeps `a/b.csv` and `a-b.csv` from\n * colliding once slugified.\n */\nexport function filePageModuleName(page: FileNamed): string {\n const slug = page.file\n .replace(/[^A-Za-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .toLowerCase()\n const hash = createHash(\"sha256\").update(page.file).digest(\"hex\").slice(0, 8)\n return `${slug}-${hash}.tsx`\n}\n","import fs from \"node:fs\"\nimport type { FilePageExt, PageVariant } from \"./constants\"\nimport { filePageMeta } from \"./file-page\"\nimport { isHomePagePath, isPlaceholderHomePage } from \"./placeholder\"\nimport type { PageKind, RouteModel, Segment } from \"./types\"\n\n/** A layout route (path-bearing) in the built tree. */\nexport interface BuiltLayout {\n id: string\n dir: string\n parentId: string | null\n /** Router path relative to its parent (TanStack `$param` form). */\n path: string\n file: string\n}\n\n/** A page route in the built tree. */\nexport interface BuiltPage {\n file: string\n routePath: string\n parentLayoutId: string | null\n /** Router path relative to parent, or \"/\" for an index route. */\n path: string\n index: boolean\n title?: string\n description?: string\n navLabel?: string\n kind: PageKind\n fileExt?: FilePageExt\n variant?: PageVariant\n placeholder?: boolean\n}\n\n/** The structured route tree emitted for the client runtime. */\nexport interface BuiltTree {\n rootLayout: string | null\n notFound: string | null\n error: string | null\n layouts: BuiltLayout[]\n pages: BuiltPage[]\n}\n\nfunction segToRouter(s: Segment): string {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `$${s.name}`\n return \"$\"\n}\n\n/** Convert a relative directory string (may contain `[param]`) to a router path. */\nfunction dirToRouterPath(relDir: string): string {\n return relDir\n .split(\"/\")\n .filter(Boolean)\n .map((token) => {\n const catchall = token.match(/^\\[\\.\\.\\.(.+)\\]$/)\n if (catchall) return \"$\"\n const param = token.match(/^\\[(.+)\\]$/)\n if (param) return `$${param[1]}`\n return token\n })\n .join(\"/\")\n}\n\nfunction isAncestorDir(ancestor: string, dir: string): boolean {\n if (ancestor === \"\") return true\n return dir === ancestor || dir.startsWith(ancestor + \"/\")\n}\n\nfunction isStrictAncestorDir(ancestor: string, dir: string): boolean {\n return dir.startsWith(ancestor + \"/\")\n}\n\nfunction depth(dir: string): number {\n return dir === \"\" ? 0 : dir.split(\"/\").length\n}\n\n/**\n * Extract the argument object body of the first `definePage({ ... })` call\n * using balanced-brace scanning, so nested objects/functions (e.g.\n * `validateSearch: (s) => ({ ... })`) don't truncate the match. Returns null\n * when there is no definePage call — the caller then emits no metadata rather\n * than falling back to the whole file (which would match unrelated `title:`\n * keys in chart/option configs).\n */\nfunction extractDefinePageArgs(src: string): string | null {\n const call = src.match(/\\bdefinePage\\s*\\(/)\n if (!call) return null\n let i = (call.index ?? 0) + call[0].length\n while (i < src.length && /\\s/.test(src[i]!)) i++\n if (src[i] !== \"{\") return null\n const start = i\n let depth = 0\n for (; i < src.length; i++) {\n const c = src[i]\n if (c === \"{\") depth++\n else if (c === \"}\" && --depth === 0) return src.slice(start + 1, i)\n }\n return null\n}\n\n/**\n * Match `key: \"...\"` allowing the value's own quote character to differ and\n * handling escapes, so values containing an apostrophe/quote are not truncated.\n */\nfunction matchStringField(scope: string, key: string): string | undefined {\n const re = new RegExp(\n `\\\\b${key}\\\\s*:\\\\s*(?:\"((?:\\\\\\\\.|[^\"\\\\\\\\])*)\"|'((?:\\\\\\\\.|[^'\\\\\\\\])*)'|\\`((?:\\\\\\\\.|[^\\`\\\\\\\\])*)\\`)`,\n )\n const m = scope.match(re)\n if (!m) return undefined\n return (m[1] ?? m[2] ?? m[3] ?? \"\").replace(/\\\\(.)/g, \"$1\")\n}\n\ninterface PageMeta {\n title?: string\n description?: string\n navLabel?: string\n placeholder?: boolean\n}\n\n/**\n * Cache keyed on mtime+size. A long-lived dev server regenerates the route tree\n * on every structural change, and re-reading + re-parsing every page module for\n * metadata that almost never changes is pure waste. `statSync` is an order of\n * magnitude cheaper than the read plus the brace scan it feeds.\n */\nconst metaCache = new Map<string, { mtimeMs: number; size: number; meta: PageMeta }>()\n\nfunction parsePageMeta(src: string): PageMeta {\n const args = extractDefinePageArgs(src)\n if (args == null) return {}\n const meta: PageMeta = {}\n const title = matchStringField(args, \"title\")\n const description = matchStringField(args, \"description\")\n const navLabel = matchStringField(args, \"navLabel\")\n if (title) meta.title = title\n if (description) meta.description = description\n if (navLabel) meta.navLabel = navLabel\n // Check for placeholder: true (boolean literal)\n if (/\\bplaceholder\\s*:\\s*true\\b/.test(args)) meta.placeholder = true\n return meta\n}\n\n/** Best-effort static extraction of definePage title/description/navLabel. */\nexport function extractPageMeta(absFile: string): PageMeta {\n let stat: fs.Stats\n try {\n stat = fs.statSync(absFile)\n } catch {\n return {}\n }\n const hit = metaCache.get(absFile)\n if (hit && hit.mtimeMs === stat.mtimeMs && hit.size === stat.size) return hit.meta\n\n let src: string\n try {\n src = fs.readFileSync(absFile, \"utf8\")\n } catch {\n return {}\n }\n const meta = parsePageMeta(src)\n \n // Check for placeholder using the robust detection from placeholder.ts\n // This includes both explicit marker and fallback exact match\n const fileName = absFile.split(/[/\\\\]/).pop() ?? \"\"\n const relPath = absFile.includes(\"/src/\") ? `src/${fileName}` : fileName\n if (isHomePagePath(relPath) && isPlaceholderHomePage(src)) {\n meta.placeholder = true\n }\n \n metaCache.set(absFile, { mtimeMs: stat.mtimeMs, size: stat.size, meta })\n return meta\n}\n\n/**\n * Build the structured route tree from a scan. Layouts become path-bearing\n * routes; pages attach to the deepest layout that owns their directory.\n */\nexport function buildRouteTree(model: RouteModel): BuiltTree {\n const rootLayoutRoute = model.layouts.find((l) => l.dir === \"\") ?? null\n const nestedLayouts = model.layouts\n .filter((l) => l.dir !== \"\")\n .sort((a, b) => depth(a.dir) - depth(b.dir))\n\n const built: BuiltLayout[] = []\n const dirToId = new Map<string, string>()\n\n nestedLayouts.forEach((layout, i) => {\n const id = `L${i}`\n // Parent = deepest other layout that is a strict ancestor of this dir.\n let parent: { id: string; dir: string } | null = null\n for (const cand of built) {\n if (isStrictAncestorDir(cand.dir, layout.dir)) {\n if (!parent || depth(cand.dir) > depth(parent.dir)) parent = { id: cand.id, dir: cand.dir }\n }\n }\n const parentDir = parent ? parent.dir : \"\"\n const relDir = parentDir === \"\" ? layout.dir : layout.dir.slice(parentDir.length + 1)\n built.push({\n id,\n dir: layout.dir,\n parentId: parent ? parent.id : null,\n path: dirToRouterPath(relDir),\n file: layout.file,\n })\n dirToId.set(layout.dir, id)\n })\n\n const pages: BuiltPage[] = model.pages.map((page) => {\n // Owner = deepest layout whose dir is an ancestor-or-equal of the page dir.\n let owner: BuiltLayout | null = null\n for (const l of built) {\n if (isAncestorDir(l.dir, page.dir)) {\n if (!owner || depth(l.dir) > depth(owner.dir)) owner = l\n }\n }\n const ownerSegCount = owner ? depth(owner.dir) : 0\n const remaining = page.segments.slice(ownerSegCount)\n const index = remaining.length === 0\n const path = index ? \"/\" : remaining.map(segToRouter).join(\"/\")\n // `extractPageMeta` reads the file as UTF-8 and runs regexes over it, so a\n // data file must never reach it — a few MB of spreadsheet binary would be\n // decoded and scanned for a `definePage` that cannot exist there.\n const meta = page.kind === \"file\" ? filePageMeta(page) : extractPageMeta(page.absFile)\n const builtPage: BuiltPage = {\n file: page.file,\n routePath: page.routePath,\n parentLayoutId: owner ? owner.id : null,\n path,\n index,\n kind: page.kind,\n }\n if (meta.title) builtPage.title = meta.title\n if (meta.description) builtPage.description = meta.description\n if (meta.navLabel) builtPage.navLabel = meta.navLabel\n if (page.fileExt) builtPage.fileExt = page.fileExt\n if (page.variant) builtPage.variant = page.variant\n if (meta.placeholder) builtPage.placeholder = meta.placeholder\n return builtPage\n })\n\n // Filter out placeholder pages when there's another page at the same route.\n // This allows new artifacts (e.g. index.slide.tsx) to claim \"/\" when the\n // template's placeholder home page is untouched.\n const byRoutePath = new Map<string, { placeholder: BuiltPage[]; nonPlaceholder: BuiltPage[] }>()\n for (const page of pages) {\n const group = byRoutePath.get(page.routePath) ?? { placeholder: [], nonPlaceholder: [] }\n if (page.placeholder) {\n group.placeholder.push(page)\n } else {\n group.nonPlaceholder.push(page)\n }\n byRoutePath.set(page.routePath, group)\n }\n\n const filteredPages: BuiltPage[] = []\n for (const group of byRoutePath.values()) {\n // If there are non-placeholder pages, use only those\n if (group.nonPlaceholder.length > 0) {\n filteredPages.push(...group.nonPlaceholder)\n } else {\n // Otherwise, use the placeholder(s)\n filteredPages.push(...group.placeholder)\n }\n }\n\n return {\n rootLayout: rootLayoutRoute ? rootLayoutRoute.file : null,\n notFound: model.notFound,\n error: model.error,\n layouts: built,\n pages: filteredPages,\n }\n}\n"]}
|
package/dist/chunk-DTDVSFRY.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { QueryClient } from '@tanstack/react-query';
|
|
2
|
-
|
|
3
|
-
// @squadbase/vantage — generated build. Do not edit.
|
|
4
|
-
|
|
5
|
-
function createQueryClient() {
|
|
6
|
-
return new QueryClient({
|
|
7
|
-
defaultOptions: {
|
|
8
|
-
queries: {
|
|
9
|
-
staleTime: 3e4,
|
|
10
|
-
retry: 1,
|
|
11
|
-
refetchOnWindowFocus: false,
|
|
12
|
-
// A dashboard talks to its own origin (or the configured API base), so
|
|
13
|
-
// the browser's offline heuristic says nothing useful about whether a
|
|
14
|
-
// request can succeed. Under the default "online" mode a failed request
|
|
15
|
-
// is *paused* rather than retried whenever that heuristic reads
|
|
16
|
-
// offline, and the page sits on its loading state forever instead of
|
|
17
|
-
// showing the error.
|
|
18
|
-
networkMode: "always"
|
|
19
|
-
},
|
|
20
|
-
mutations: {
|
|
21
|
-
networkMode: "always"
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export { createQueryClient };
|
|
28
|
-
//# sourceMappingURL=chunk-DTDVSFRY.js.map
|
|
29
|
-
//# sourceMappingURL=chunk-DTDVSFRY.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/query/client.ts"],"names":[],"mappings":";;;;AAOO,SAAS,iBAAA,GAAiC;AAC/C,EAAA,OAAO,IAAI,WAAA,CAAY;AAAA,IACrB,cAAA,EAAgB;AAAA,MACd,OAAA,EAAS;AAAA,QACP,SAAA,EAAW,GAAA;AAAA,QACX,KAAA,EAAO,CAAA;AAAA,QACP,oBAAA,EAAsB,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOtB,WAAA,EAAa;AAAA,OACf;AAAA,MACA,SAAA,EAAW;AAAA,QACT,WAAA,EAAa;AAAA;AACf;AACF,GACD,CAAA;AACH","file":"chunk-DTDVSFRY.js","sourcesContent":["import { QueryClient } from \"@tanstack/react-query\"\n\n/**\n * Create the QueryClient with Vantage defaults. Individual queries may override\n * these, but replacing the QueryClient wholesale is intentionally not exposed —\n * Squadbase relies on a single managed client for auth, logging and telemetry.\n */\nexport function createQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 30_000,\n retry: 1,\n refetchOnWindowFocus: false,\n // A dashboard talks to its own origin (or the configured API base), so\n // the browser's offline heuristic says nothing useful about whether a\n // request can succeed. Under the default \"online\" mode a failed request\n // is *paused* rather than retried whenever that heuristic reads\n // offline, and the page sits on its loading state forever instead of\n // showing the error.\n networkMode: \"always\",\n },\n mutations: {\n networkMode: \"always\",\n },\n },\n })\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/source.ts","../src/core/route-spec.ts"],"names":[],"mappings":"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","file":"chunk-JKLLFVEU.js","sourcesContent":["/**\n * Low-level source scanning helpers shared by the static analyzers\n * (`diagnostics.ts`, `route-spec.ts`). Everything here is text-only — user code\n * is never imported or executed.\n */\n\n/**\n * Strip block and line comments so commented-out code doesn't produce false\n * positives (or hide real issues). Naive but adequate for presence checks:\n * URLs (`http://`) are preserved via the `[^:]` guard before `//`.\n */\nexport function stripComments(src: string): string {\n return src.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\").replace(/(^|[^:\"'`\\\\])\\/\\/[^\\n]*/g, \"$1\")\n}\n\nconst OPENERS: Record<string, string> = { \"(\": \")\", \"[\": \"]\", \"{\": \"}\" }\n\n/**\n * Read a balanced bracketed region starting at `openIndex` (which must hold\n * `(`, `[` or `{`), returning the raw text *between* the brackets. Quote- and\n * nesting-aware so brackets inside string literals don't unbalance the scan.\n * Returns null when the region is never closed.\n */\nexport function readBracketBody(src: string, openIndex: number): string | null {\n const open = src[openIndex]\n if (!open || !OPENERS[open]) return null\n let depth = 0\n let quote: string | null = null\n for (let i = openIndex; i < src.length; i++) {\n const c = src[i]!\n if (quote) {\n if (c === \"\\\\\") i++\n else if (c === quote) quote = null\n continue\n }\n if (c === '\"' || c === \"'\" || c === \"`\") {\n quote = c\n continue\n }\n if (OPENERS[c]) depth++\n else if (c === \")\" || c === \"]\" || c === \"}\") {\n if (--depth === 0) return src.slice(openIndex + 1, i)\n }\n }\n return null\n}\n\n/**\n * Split an argument list or object body on top-level commas, ignoring commas\n * nested inside brackets or string literals. Empty parts are dropped.\n */\nexport function splitTopLevel(body: string): string[] {\n const parts: string[] = []\n let depth = 0\n let quote: string | null = null\n let start = 0\n for (let i = 0; i < body.length; i++) {\n const c = body[i]!\n if (quote) {\n if (c === \"\\\\\") i++\n else if (c === quote) quote = null\n continue\n }\n if (c === '\"' || c === \"'\" || c === \"`\") {\n quote = c\n continue\n }\n if (OPENERS[c]) depth++\n else if (c === \")\" || c === \"]\" || c === \"}\") depth--\n else if (c === \",\" && depth === 0) {\n parts.push(body.slice(start, i))\n start = i + 1\n }\n }\n parts.push(body.slice(start))\n return parts.map((p) => p.trim()).filter(Boolean)\n}\n\n/**\n * Lex a module just far enough to tell code, comments and string literals\n * apart, *without* moving anything: comments come back blanked to spaces\n * (newlines kept) so offsets and line numbers still match the raw file, and\n * `inString[i]` is 1 where offset `i` sits inside a `'…'`, `\"…\"` or `` `…` ``\n * literal (template `${…}` bodies count as string — close enough for literal\n * scans). `'`/`\"` literals end at a newline, so an apostrophe in JSX text\n * cannot swallow more than the rest of its own line.\n */\nexport function maskSource(src: string): { code: string; inString: Uint8Array } {\n const out = src.split(\"\")\n const inString = new Uint8Array(src.length)\n let i = 0\n while (i < src.length) {\n const c = src[i]!\n const next = src[i + 1]\n if (c === \"/\" && next === \"/\" && src[i - 1] !== \":\") {\n while (i < src.length && src[i] !== \"\\n\") out[i++] = \" \"\n continue\n }\n if (c === \"/\" && next === \"*\") {\n const end = src.indexOf(\"*/\", i + 2)\n const stop = end === -1 ? src.length : end + 2\n for (; i < stop; i++) if (src[i] !== \"\\n\") out[i] = \" \"\n continue\n }\n if (c === '\"' || c === \"'\" || c === \"`\") {\n i++\n while (i < src.length) {\n const d = src[i]!\n if (d === \"\\\\\") {\n inString[i] = 1\n inString[i + 1] = 1\n i += 2\n continue\n }\n if (d === c) break\n if (d === \"\\n\" && c !== \"`\") break\n inString[i++] = 1\n }\n i++\n continue\n }\n i++\n }\n return { code: out.join(\"\"), inString }\n}\n","import fs from \"node:fs\"\nimport { API_METHODS, type ApiMethod } from \"./constants\"\nimport { filePageMeta } from \"./file-page\"\nimport { extractPageMeta } from \"./route-tree\"\nimport { readBracketBody, splitTopLevel, stripComments } from \"./source\"\nimport type { ApiRoute, PageRoute, Segment } from \"./types\"\n\n/**\n * Best-effort *static* specs for the routes `vantage routes --detail` prints:\n * what a page takes in its path, and what an API route accepts and answers\n * with. Like `diagnostics.ts` this only reads text — user modules are never\n * imported or executed — so every field is a hint derived from the source, not\n * a guarantee. Callers pass sources through {@link stripComments} first.\n */\n\n/** A dynamic segment of a route path. */\nexport interface RouteParam {\n name: string\n kind: \"param\" | \"catchall\"\n}\n\n/** Static spec of a page route. */\nexport interface PageSpec {\n params: RouteParam[]\n title?: string\n description?: string\n navLabel?: string\n}\n\n/** The request body an API handler reads, when detectable. */\nexport interface ApiBodySpec {\n format: \"json\" | \"formData\" | \"text\" | \"binary\"\n /** Top-level keys, when the handler destructures them. */\n keys?: string[]\n}\n\n/** A response an API handler returns. */\nexport interface ApiResponseSpec {\n status: number\n /** Response content type, omitted when it can't be derived. */\n contentType?: string\n /** Top-level keys, when the payload is an object literal. */\n keys?: string[]\n}\n\n/** An `HttpError` an API handler throws. */\nexport interface ApiErrorSpec {\n status: number\n message?: string\n}\n\n/** Static spec of one HTTP method handler. */\nexport interface ApiMethodSpec {\n method: ApiMethod\n /** Query string keys read via `searchParams`. */\n query: string[]\n body?: ApiBodySpec\n responses: ApiResponseSpec[]\n errors: ApiErrorSpec[]\n}\n\n/** Static spec of an API route module. */\nexport interface ApiSpec {\n params: RouteParam[]\n methods: ApiMethodSpec[]\n}\n\n/**\n * HTTP method handlers a module exports (direct declaration or export list).\n * `src` must be comment-stripped. Shared with the `INVALID_API_EXPORT`\n * diagnostic so both agree on what counts as a handler.\n */\nexport function detectApiMethods(src: string): ApiMethod[] {\n return API_METHODS.filter(\n (m) =>\n new RegExp(`export\\\\s+(async\\\\s+)?(function|const|let|var)\\\\s+${m}\\\\b`).test(src) ||\n new RegExp(`export\\\\s*\\\\{[^}]*\\\\b${m}\\\\b[^}]*\\\\}`).test(src),\n )\n}\n\n/**\n * Slice the module into one source region per handler: from a handler's export\n * declaration to the next one (or EOF). Coarse on purpose — matching a function\n * body would have to cope with arrow bodies, overloads and trailing helpers —\n * and good enough because handlers are written one after another. A method\n * exported only through an export list gets the whole module as its region.\n */\nfunction methodRegions(src: string): Map<ApiMethod, string> {\n const re = new RegExp(\n `export\\\\s+(?:async\\\\s+)?(?:function|const|let|var)\\\\s+(${API_METHODS.join(\"|\")})\\\\b`,\n \"g\",\n )\n const decls: { method: ApiMethod; index: number }[] = []\n let m: RegExpExecArray | null\n while ((m = re.exec(src))) decls.push({ method: m[1] as ApiMethod, index: m.index })\n\n const regions = new Map<ApiMethod, string>()\n decls.forEach((d, i) => {\n regions.set(d.method, src.slice(d.index, decls[i + 1]?.index ?? src.length))\n })\n for (const method of detectApiMethods(src)) {\n if (!regions.has(method)) regions.set(method, src)\n }\n return regions\n}\n\n/** Top-level keys of an object literal expression, `…` standing in for spreads. */\nfunction objectKeys(expr: string): string[] | undefined {\n const trimmed = expr.trim()\n if (!trimmed.startsWith(\"{\")) return undefined\n const body = readBracketBody(trimmed, 0)\n if (body == null) return undefined\n const keys: string[] = []\n for (const part of splitTopLevel(body)) {\n if (part.startsWith(\"...\")) {\n keys.push(\"…\")\n continue\n }\n const name = part.match(/^[\"'`]?([A-Za-z0-9_$]+)/)\n if (name) keys.push(name[1]!)\n }\n return keys.length ? keys : undefined\n}\n\n/** Read `status: 201` out of a `ResponseInit` literal. */\nfunction initStatus(init: string | undefined): number | undefined {\n const m = init?.match(/\\bstatus\\s*:\\s*(\\d{3})\\b/)\n return m ? Number(m[1]) : undefined\n}\n\n/** Read a content-type header out of a `ResponseInit` literal. */\nfunction initContentType(init: string | undefined): string | undefined {\n const m = init?.match(/[\"']?content-type[\"']?\\s*:\\s*[\"']([^\"';]+)/i)\n return m ? m[1]!.trim() : undefined\n}\n\n/** Every `Response.json(…)` / `json(…)` / `new Response(…)` in a handler region. */\nfunction extractResponses(region: string): ApiResponseSpec[] {\n const re = /\\bnew\\s+Response\\s*\\(|\\bResponse\\s*\\.\\s*json\\s*\\(|(?<![.\\w$])json\\s*\\(/g\n const out: ApiResponseSpec[] = []\n const seen = new Set<string>()\n let m: RegExpExecArray | null\n while ((m = re.exec(region))) {\n const isJson = !m[0].startsWith(\"new\")\n const args = readBracketBody(region, m.index + m[0].length - 1)\n if (args == null) continue\n const [payload, init] = splitTopLevel(args)\n const contentType = isJson\n ? \"application/json\"\n : (initContentType(init) ??\n (payload?.startsWith(\"JSON.stringify\") ? \"application/json\" : undefined))\n const keys = isJson && payload ? objectKeys(payload) : undefined\n const spec: ApiResponseSpec = {\n status: initStatus(init) ?? 200,\n ...(contentType ? { contentType } : {}),\n ...(keys ? { keys } : {}),\n }\n const key = JSON.stringify(spec)\n if (seen.has(key)) continue\n seen.add(key)\n out.push(spec)\n }\n return out\n}\n\n/** Every `new HttpError(status, \"message\")` in a handler region. */\nfunction extractErrors(region: string): ApiErrorSpec[] {\n const re = /\\bHttpError\\s*\\(\\s*(\\d{3})\\s*(?:,\\s*(?:([\"'`])((?:\\\\.|(?!\\2)[\\s\\S])*)\\2))?/g\n const out: ApiErrorSpec[] = []\n const seen = new Set<string>()\n let m: RegExpExecArray | null\n while ((m = re.exec(region))) {\n const message = m[3]?.replace(/\\\\(.)/g, \"$1\")\n const spec: ApiErrorSpec = { status: Number(m[1]), ...(message ? { message } : {}) }\n const key = JSON.stringify(spec)\n if (seen.has(key)) continue\n seen.add(key)\n out.push(spec)\n }\n return out\n}\n\n/** Query keys read through `searchParams.get/getAll/has(\"x\")`. */\nfunction extractQuery(region: string): string[] {\n const re = /searchParams\\s*\\.\\s*(?:get|getAll|has)\\s*\\(\\s*[\"'`]([^\"'`]+)[\"'`]/g\n const out = new Set<string>()\n let m: RegExpExecArray | null\n while ((m = re.exec(region))) out.add(m[1]!)\n return [...out]\n}\n\n/** The request body a handler reads, plus destructured keys when present. */\nfunction extractBody(region: string): ApiBodySpec | undefined {\n const read = region.match(/\\b(?:request|req)\\s*\\.\\s*(json|formData|text|arrayBuffer|blob)\\s*\\(/)\n if (!read) return undefined\n const method = read[1]!\n const format: ApiBodySpec[\"format\"] =\n method === \"json\" || method === \"formData\" || method === \"text\" ? method : \"binary\"\n\n const destructured = region.match(\n /(?:const|let|var)\\s*(\\{[\\s\\S]*?\\})\\s*=\\s*(?:await\\s+)?[\\w.]*\\.json\\s*\\(/,\n )\n const keys = format === \"json\" && destructured ? objectKeys(destructured[1]!) : undefined\n return { format, ...(keys ? { keys } : {}) }\n}\n\nfunction toParams(segments: Segment[]): RouteParam[] {\n const out: RouteParam[] = []\n for (const s of segments) {\n if (s.kind === \"static\") continue\n out.push({ name: s.name, kind: s.kind })\n }\n return out\n}\n\n/** Static spec of a page: its path params and its `definePage` metadata. */\nexport function extractPageSpec(page: PageRoute): PageSpec {\n // A data file has no `definePage` to read, and reading it as UTF-8 would\n // decode megabytes of spreadsheet binary; its title is derived from the name.\n const meta = page.kind === \"file\" ? filePageMeta(page) : extractPageMeta(page.absFile)\n return { params: toParams(page.segments), ...meta }\n}\n\n/** Static spec of an API route: path params and a per-method request/response sketch. */\nexport function extractApiSpec(api: ApiRoute): ApiSpec {\n const params = toParams(api.segments)\n let src: string\n try {\n src = stripComments(fs.readFileSync(api.absFile, \"utf8\"))\n } catch {\n return { params, methods: [] }\n }\n const regions = methodRegions(src)\n const methods = API_METHODS.filter((m) => regions.has(m)).map((method) => {\n const region = regions.get(method)!\n const body = extractBody(region)\n return {\n method,\n query: extractQuery(region),\n ...(body ? { body } : {}),\n responses: extractResponses(region),\n errors: extractErrors(region),\n }\n })\n return { params, methods }\n}\n"]}
|