@squadbase/vantage 0.6.2-stg.3a2ba98 → 0.7.0-dev1.1197de7
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-O5TVNH4E.js → build-U7GO26HR.js} +9 -9
- package/dist/{build-O5TVNH4E.js.map → build-U7GO26HR.js.map} +1 -1
- package/dist/{check-WFBEDHDR.js → check-MRVAIHG5.js} +7 -7
- package/dist/{check-WFBEDHDR.js.map → check-MRVAIHG5.js.map} +1 -1
- package/dist/{chunk-QDZA5JSL.js → chunk-AABMKHEU.js} +4 -4
- package/dist/{chunk-QDZA5JSL.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-EG4PX726.js +678 -0
- package/dist/chunk-EG4PX726.js.map +1 -0
- package/dist/{chunk-3G43C6OL.js → chunk-GNXCX4WE.js} +46 -3
- package/dist/chunk-GNXCX4WE.js.map +1 -0
- package/dist/chunk-LYUGDHSF.js +61 -0
- package/dist/chunk-LYUGDHSF.js.map +1 -0
- package/dist/{chunk-RPZAALCX.js → chunk-MQUIAP66.js} +321 -165
- package/dist/chunk-MQUIAP66.js.map +1 -0
- package/dist/chunk-P2KIHF65.js +152 -0
- package/dist/chunk-P2KIHF65.js.map +1 -0
- package/dist/{chunk-BCE22JSM.js → chunk-PJ4SPXHS.js} +52 -16
- package/dist/chunk-PJ4SPXHS.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-PXRX5PEC.js → chunk-ROHNXP7J.js} +73 -4
- package/dist/chunk-ROHNXP7J.js.map +1 -0
- package/dist/chunk-S5MDTHH7.js +466 -0
- 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-EP6JHXSR.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-JGRMRXXZ.js → chunk-UWSQUHX6.js} +4 -99
- package/dist/chunk-UWSQUHX6.js.map +1 -0
- package/dist/chunk-XRKSIC5Z.js +176 -0
- package/dist/chunk-XRKSIC5Z.js.map +1 -0
- package/dist/chunk-YJQCB3UP.js +10764 -0
- package/dist/chunk-YJQCB3UP.js.map +1 -0
- package/dist/cli.js +15 -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 +2389 -31
- package/dist/components/index.js +7 -4
- package/dist/delta-text-tav2Lh5d.d.ts +17 -0
- package/dist/{dev-NZRLOQCL.js → dev-O42JFQ64.js} +24 -13
- package/dist/dev-O42JFQ64.js.map +1 -0
- package/dist/doc/index.d.ts +215 -2
- package/dist/doc/index.js +423 -5
- package/dist/doc/index.js.map +1 -1
- package/dist/{docs-ZGDJUHJI.js → docs-JVP4RPKT.js} +3 -3
- package/dist/{docs-ZGDJUHJI.js.map → docs-JVP4RPKT.js.map} +1 -1
- package/dist/{doctor-VFKEMR54.js → doctor-YD3XAAOT.js} +8 -8
- package/dist/doctor-YD3XAAOT.js.map +1 -0
- package/dist/format-D34piCei.d.ts +250 -0
- package/dist/geo-japan-7BMSOJRX.js +8 -0
- package/dist/geo-japan-7BMSOJRX.js.map +1 -0
- package/dist/geo-us-GVOG7VXH.js +8 -0
- package/dist/geo-us-GVOG7VXH.js.map +1 -0
- package/dist/geo-world-35HL56UU.js +8 -0
- package/dist/geo-world-35HL56UU.js.map +1 -0
- package/dist/markdown/index.js +1 -1
- package/dist/markdown/index.js.map +1 -1
- package/dist/{preview-QDCIVVSR.js → preview-T6CLSQVX.js} +12 -4
- package/dist/preview-T6CLSQVX.js.map +1 -0
- package/dist/query/index.d.ts +0 -11
- package/dist/query/index.js +2 -2
- package/dist/{routes-RHP5FVGD.js → routes-PVKNT777.js} +6 -6
- package/dist/{routes-RHP5FVGD.js.map → routes-PVKNT777.js.map} +1 -1
- package/dist/{search-RFBELGY7.js → search-5LC4XPB5.js} +3 -3
- package/dist/{search-RFBELGY7.js.map → search-5LC4XPB5.js.map} +1 -1
- package/dist/slide/index.d.ts +272 -1
- package/dist/slide/index.js +1086 -19
- package/dist/slide/index.js.map +1 -1
- package/dist/table/index.js +13 -10
- package/dist/table/index.js.map +1 -1
- package/dist/ui/index.d.ts +148 -12
- package/dist/ui/index.js +1339 -88
- package/dist/ui/index.js.map +1 -1
- package/dist/{upgrade-GF2P67M6.js → upgrade-6DT7ADRP.js} +7 -7
- package/dist/{upgrade-GF2P67M6.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/agent-skills.md +1 -1
- package/docs/en/changelog.md +82 -0
- package/docs/en/cli-reference.md +30 -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/draft-chart.md +42 -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/page-shell.md +2 -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 +1222 -132
- package/docs/ja/agent-skills.md +1 -1
- package/docs/ja/changelog.md +84 -0
- package/docs/ja/cli-reference.md +29 -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/draft-chart.md +40 -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/page-shell.md +2 -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 +43 -29
- package/registry/parts.json +5221 -0
- 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 +424 -0
- package/registry/ui/area-chart.tsx +3960 -0
- package/registry/ui/attention-list.tsx +465 -0
- package/registry/ui/avatar.tsx +110 -0
- package/registry/ui/badge.tsx +56 -0
- package/registry/ui/bar-chart.tsx +3954 -0
- package/registry/ui/bar-list.tsx +3998 -0
- package/registry/ui/box-plot-chart.tsx +4214 -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 +1498 -0
- package/registry/ui/chart-frame.tsx +1612 -0
- package/registry/ui/checkbox.tsx +30 -0
- package/registry/ui/collapsible.tsx +23 -0
- package/registry/ui/combo-chart.tsx +1852 -0
- package/registry/ui/combobox.tsx +310 -0
- package/registry/ui/command.tsx +198 -0
- package/registry/ui/dashboard-card.tsx +219 -0
- package/registry/ui/data-table.tsx +899 -158
- package/registry/ui/date-range-picker.tsx +544 -0
- package/registry/ui/delta.tsx +352 -0
- package/registry/ui/dialog.tsx +161 -0
- package/registry/ui/donut-chart.tsx +4006 -0
- package/registry/ui/drawer.tsx +229 -0
- package/registry/ui/dropdown-menu.tsx +274 -0
- package/registry/ui/echart.tsx +1178 -0
- package/registry/ui/field.tsx +240 -0
- package/registry/ui/filter-bar.tsx +553 -0
- package/registry/ui/forecast-chart.tsx +4734 -0
- package/registry/ui/funnel-steps.tsx +3843 -0
- package/registry/ui/heatmap.tsx +2027 -0
- package/registry/ui/histogram-chart.tsx +4284 -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 +907 -0
- package/registry/ui/label.tsx +22 -0
- package/registry/ui/legend.tsx +3817 -0
- package/registry/ui/line-chart.tsx +3958 -0
- package/registry/ui/metric-value.tsx +62 -0
- package/registry/ui/multi-select.tsx +382 -0
- package/registry/ui/page-shell.tsx +441 -0
- package/registry/ui/pagination.tsx +140 -0
- package/registry/ui/paired-chart.tsx +4086 -0
- package/registry/ui/pivot-table.tsx +1260 -0
- package/registry/ui/placeholder.tsx +36 -0
- package/registry/ui/popover.tsx +92 -0
- package/registry/ui/progress-circle.tsx +1033 -0
- package/registry/ui/progress.tsx +85 -0
- package/registry/ui/radio-group.tsx +39 -0
- package/registry/ui/sample-data.tsx +230 -0
- package/registry/ui/scatter-chart.tsx +4503 -0
- package/registry/ui/scroll-area.tsx +56 -0
- package/registry/ui/searchable-select.tsx +352 -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 +247 -0
- package/registry/ui/status-badge.tsx +286 -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 +1015 -0
- package/registry/ui/treemap.tsx +1917 -0
- package/registry/ui/trend-indicator.tsx +217 -0
- package/registry/ui/updated-at.tsx +276 -0
- package/registry/ui/waterfall-chart.tsx +4561 -0
- package/skills/vantage-add-feature/SKILL.md +14 -7
- package/skills/vantage-design/SKILL.md +62 -52
- package/skills/vantage-design/references/extract.md +26 -27
- package/skills/vantage-design/references/format.md +12 -172
- package/skills/vantage-design/references/presets.md +50 -110
- package/skills/vantage-pitfalls/SKILL.md +10 -1
- package/skills/vantage-slide/SKILL.md +71 -36
- package/templates/AGENTS.md +54 -16
- package/templates/agents/api.md +36 -0
- package/templates/agents/csv.md +2 -1
- package/templates/agents/doc.md +52 -3
- package/templates/agents/page.md +91 -10
- package/templates/agents/slide.md +90 -4
- package/templates/agents/xlsx.md +2 -1
- package/theme.css +247 -132
- package/dist/add-EISGSZAH.js +0 -6
- package/dist/add-EISGSZAH.js.map +0 -1
- package/dist/chunk-3G43C6OL.js.map +0 -1
- package/dist/chunk-5ZOP4SQR.js +0 -47
- package/dist/chunk-5ZOP4SQR.js.map +0 -1
- package/dist/chunk-A2UUGASH.js.map +0 -1
- package/dist/chunk-BCE22JSM.js.map +0 -1
- package/dist/chunk-DTDVSFRY.js +0 -29
- package/dist/chunk-DTDVSFRY.js.map +0 -1
- package/dist/chunk-EP6JHXSR.js.map +0 -1
- package/dist/chunk-JGRMRXXZ.js.map +0 -1
- package/dist/chunk-KLEIVDUV.js +0 -165
- package/dist/chunk-KLEIVDUV.js.map +0 -1
- package/dist/chunk-LSRMRIXA.js +0 -2227
- package/dist/chunk-LSRMRIXA.js.map +0 -1
- package/dist/chunk-PVTHHV7X.js.map +0 -1
- package/dist/chunk-PXRX5PEC.js.map +0 -1
- package/dist/chunk-RPZAALCX.js.map +0 -1
- package/dist/chunk-T3FLAGI6.js +0 -316
- package/dist/chunk-T3FLAGI6.js.map +0 -1
- package/dist/dev-NZRLOQCL.js.map +0 -1
- package/dist/doctor-VFKEMR54.js.map +0 -1
- package/dist/preview-QDCIVVSR.js.map +0 -1
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
// Copied by `vantage add ui delta`. This file is yours to edit.
|
|
2
|
+
// Generated from @squadbase/squadkit registry/components/delta.tsx by `pnpm run registry` (in Vantage, edit packages/squadkit, not registry/).
|
|
3
|
+
"use client"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Delta — the change of a value against a comparison, as arrow + signed change + comparison label on one line; it is not a card, so place it beside a value.
|
|
7
|
+
*
|
|
8
|
+
* It renders as arrow + signed
|
|
9
|
+
* change + comparison label ("↑ +12.4% vs. prior month"; ja: "↑ +12.4% 前月比") on one line, in the page's
|
|
10
|
+
* language (`<html lang>`) unless `locale` is given.
|
|
11
|
+
*
|
|
12
|
+
* Direction, rate, colour and wording are all derived here from `value` and
|
|
13
|
+
* `comparison` (via `computeComparison`); none of them can be passed in, so they
|
|
14
|
+
* cannot contradict each other. Colour is never the only signal: the arrow and
|
|
15
|
+
* the sign always accompany it. Set `betterWhen="down"` for metrics
|
|
16
|
+
* where a rise is bad (churn, error rate).
|
|
17
|
+
*
|
|
18
|
+
* - A flat change (inside `neutralBand`) uses a right arrow (→), never a minus-like dash, so it cannot
|
|
19
|
+
* read as "− +0.19pt".
|
|
20
|
+
* - The label comes from `comparison.vs` and `comparison.grain`: a monthly
|
|
21
|
+
* `prior-period` reads "前月比", `prior-year` "前年同月比".
|
|
22
|
+
* - Pass the metric's `format`: a `percent` metric (a rate) shows the difference
|
|
23
|
+
* in percentage points ("−0.5pt") instead of a relative change ("−19.2%"). A minus is
|
|
24
|
+
* always U+2212, and the digits of a relative change / points are fixed (default 1:
|
|
25
|
+
* "+14.0%" beside "+11.9%"); `digits` sets the same count for every card in a group.
|
|
26
|
+
* - A running total (YTD / MTD) sets `comparison.toDate`: `prior-year` then reads
|
|
27
|
+
* "前年同期比" instead of "前年比" whatever the grain.
|
|
28
|
+
* - When the values cannot be compared (a null value, no previous one), it shows a single muted
|
|
29
|
+
* "—" with no arrow (and the label, so "— 前年同月比" says which comparison is missing). The
|
|
30
|
+
* screen-reader text says "比較できません".
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* import { Delta } from "@/components/delta"
|
|
34
|
+
* // Vantage: import { Delta } from "@squadbase/vantage/components"
|
|
35
|
+
*
|
|
36
|
+
* <Delta value={48_200_000} comparison={{ previous: 42_900_000, vs: "prior-period", grain: "month" }} />
|
|
37
|
+
* <Delta value={0.021} format="percent" betterWhen="down"
|
|
38
|
+
* comparison={{ previous: 0.026, vs: "prior-year", grain: "month" }} />
|
|
39
|
+
*/
|
|
40
|
+
import { forwardRef, type HTMLAttributes } from "react"
|
|
41
|
+
import { ArrowDown, ArrowRight, ArrowUp } from "lucide-react"
|
|
42
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
43
|
+
|
|
44
|
+
import { cn } from "@squadbase/vantage/ui"
|
|
45
|
+
import {
|
|
46
|
+
computeComparison,
|
|
47
|
+
defaultChangeDisplay,
|
|
48
|
+
formatChange,
|
|
49
|
+
formatChangeAmount,
|
|
50
|
+
type ChangeDisplay,
|
|
51
|
+
type Comparison,
|
|
52
|
+
type ComparisonResult,
|
|
53
|
+
type Polarity,
|
|
54
|
+
} from "@squadbase/vantage/components"
|
|
55
|
+
import { EMPTY_VALUE, type ValueFormat } from "@squadbase/vantage/components"
|
|
56
|
+
import { useSyncExternalStore } from "react"
|
|
57
|
+
|
|
58
|
+
/* ---------- inlined from @squadbase/squadkit registry/lib/locale.ts (internal to @squadbase/vantage) ---------- */
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The display language of the parts and the defaults that follow it.
|
|
62
|
+
*
|
|
63
|
+
* The language comes from `<html lang>`: a tag starting with `ja` reads Japanese, anything else English.
|
|
64
|
+
* Without a usable `lang` (missing, invalid, or no `document` — SSR, Node) the locale is `FALLBACK_LOCALE`
|
|
65
|
+
* (`en-US`). A `locale` passed explicitly (a prop, an argument) always wins.
|
|
66
|
+
*
|
|
67
|
+
* Parts read the locale through `useLocale` (`hooks/use-locale`) and pass it down; the pure helpers here
|
|
68
|
+
* and in `format` / `comparison` / `chart-*` take it as an argument and fall back to `documentLocale()`.
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
/** The language of the built-in wording: Japanese or English. */
|
|
72
|
+
type UiLanguage = "ja" | "en"
|
|
73
|
+
|
|
74
|
+
/** The locale used when `<html lang>` gives none (and on the server). */
|
|
75
|
+
const FALLBACK_LOCALE = "en-US"
|
|
76
|
+
|
|
77
|
+
/** `"ja"` when `locale` starts with `ja` (`ja`, `ja-JP`), else `"en"`. A missing locale is `"en"`. */
|
|
78
|
+
function uiLanguage(locale: string | null | undefined): UiLanguage {
|
|
79
|
+
return typeof locale === "string" && locale.trim().toLowerCase().startsWith("ja") ? "ja" : "en"
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** A BCP 47 tag in its canonical form (`en-gb` → `en-GB`), or `FALLBACK_LOCALE` when it is empty or invalid. */
|
|
83
|
+
function normalizeLocale(tag: string | null | undefined): string {
|
|
84
|
+
const value = tag?.trim()
|
|
85
|
+
if (!value) return FALLBACK_LOCALE
|
|
86
|
+
try {
|
|
87
|
+
return Intl.getCanonicalLocales(value)[0] ?? FALLBACK_LOCALE
|
|
88
|
+
} catch {
|
|
89
|
+
return FALLBACK_LOCALE
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The locale of the page: `document.documentElement.lang`, canonicalized. `FALLBACK_LOCALE` when it is empty or
|
|
95
|
+
* invalid, or there is no `document`. Parts read it through `useLocale`, never while rendering.
|
|
96
|
+
*/
|
|
97
|
+
function documentLocale(): string {
|
|
98
|
+
if (typeof document === "undefined") return FALLBACK_LOCALE
|
|
99
|
+
return normalizeLocale(document.documentElement?.getAttribute("lang"))
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** `locale` when given, else the page's locale (`documentLocale()`). */
|
|
103
|
+
function resolveLocale(locale?: string | null): string {
|
|
104
|
+
return locale || documentLocale()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Picks the wording table of the locale's language. */
|
|
108
|
+
function pickLocale<T>(table: { ja: T; en: T }, locale?: string | null): T {
|
|
109
|
+
return table[uiLanguage(resolveLocale(locale))]
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** The currency `format="currency"` uses without a `currency`: JPY for Japanese, USD otherwise. */
|
|
113
|
+
function defaultCurrency(locale?: string | null): string {
|
|
114
|
+
return uiLanguage(resolveLocale(locale)) === "ja" ? "JPY" : "USD"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** The month a fiscal year starts in (1–12) when none is given: April for Japanese, January otherwise. */
|
|
118
|
+
function defaultFiscalYearStartMonth(locale?: string | null): number {
|
|
119
|
+
return uiLanguage(resolveLocale(locale)) === "ja" ? 4 : 1
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** A day of the week, 0 = Sunday … 6 = Saturday (the `Date#getDay` / date-fns numbering). */
|
|
123
|
+
type WeekDay = 0 | 1 | 2 | 3 | 4 | 5 | 6
|
|
124
|
+
|
|
125
|
+
/** Locales whose week starts on Sunday when the runtime has no week data. */
|
|
126
|
+
const SUNDAY_FIRST = new Set(["en", "en-US", "en-CA"])
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The first day of the week: Monday for Japanese; otherwise the locale's convention from `Intl.Locale`
|
|
130
|
+
* (`en-US` Sunday, `en-GB` Monday). Without week data in the runtime: Sunday for `en` / `en-US` / `en-CA`,
|
|
131
|
+
* Monday for the rest.
|
|
132
|
+
*/
|
|
133
|
+
function weekStartsOn(locale?: string | null): WeekDay {
|
|
134
|
+
const tag = normalizeLocale(resolveLocale(locale))
|
|
135
|
+
if (uiLanguage(tag) === "ja") return 1
|
|
136
|
+
try {
|
|
137
|
+
const info = new Intl.Locale(tag) as Intl.Locale & {
|
|
138
|
+
getWeekInfo?: () => { firstDay: number }
|
|
139
|
+
weekInfo?: { firstDay: number }
|
|
140
|
+
}
|
|
141
|
+
const firstDay = info.getWeekInfo?.().firstDay ?? info.weekInfo?.firstDay
|
|
142
|
+
if (typeof firstDay === "number" && firstDay >= 1 && firstDay <= 7) return (firstDay % 7) as WeekDay
|
|
143
|
+
} catch {
|
|
144
|
+
// Fall through to the table below.
|
|
145
|
+
}
|
|
146
|
+
return SUNDAY_FIRST.has(tag) ? 0 : 1
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* ---------- inlined from @squadbase/squadkit registry/hooks/use-locale.ts (internal to @squadbase/vantage) ---------- */
|
|
150
|
+
|
|
151
|
+
const listeners = new Set<() => void>()
|
|
152
|
+
let observer: MutationObserver | null = null
|
|
153
|
+
|
|
154
|
+
/** One observer on `<html lang>` for every subscribed part. */
|
|
155
|
+
function subscribe(onChange: () => void): () => void {
|
|
156
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined") return () => {}
|
|
157
|
+
listeners.add(onChange)
|
|
158
|
+
if (!observer) {
|
|
159
|
+
observer = new MutationObserver(() => {
|
|
160
|
+
for (const listener of [...listeners]) listener()
|
|
161
|
+
})
|
|
162
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["lang"] })
|
|
163
|
+
}
|
|
164
|
+
return () => {
|
|
165
|
+
listeners.delete(onChange)
|
|
166
|
+
if (listeners.size === 0 && observer) {
|
|
167
|
+
observer.disconnect()
|
|
168
|
+
observer = null
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const serverLocale = () => FALLBACK_LOCALE
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* The page's locale (`<html lang>`), following changes made while the page runs. On the server and during
|
|
177
|
+
* hydration it is `FALLBACK_LOCALE` (`en-US`), so the markup matches; it switches right after.
|
|
178
|
+
*/
|
|
179
|
+
function useDocumentLocale(): string {
|
|
180
|
+
return useSyncExternalStore(subscribe, documentLocale, serverLocale)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** The locale a part renders in: its `locale` prop when given, else the page's (`useDocumentLocale`). */
|
|
184
|
+
function useLocale(locale?: string | null): string {
|
|
185
|
+
const page = useDocumentLocale()
|
|
186
|
+
return locale || page
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* ---------- end of inlined code ---------- */
|
|
190
|
+
|
|
191
|
+
const deltaVariants = cva(
|
|
192
|
+
"inline-flex w-fit shrink-0 items-center gap-1 font-medium whitespace-nowrap tabular-nums",
|
|
193
|
+
{
|
|
194
|
+
variants: {
|
|
195
|
+
variant: {
|
|
196
|
+
badge: "h-5 rounded-md border px-2 py-0.5 text-xs font-medium [&>svg]:size-3",
|
|
197
|
+
inline: "text-sm [&>svg]:size-3.5",
|
|
198
|
+
},
|
|
199
|
+
sentiment: {
|
|
200
|
+
positive: "text-positive",
|
|
201
|
+
negative: "text-negative",
|
|
202
|
+
neutral: "text-neutral",
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
compoundVariants: [
|
|
206
|
+
{ variant: "badge", sentiment: "positive", className: "border-positive/20 bg-positive-subtle dark:border-positive/25" },
|
|
207
|
+
{ variant: "badge", sentiment: "negative", className: "border-negative/20 bg-negative-subtle dark:border-negative/25" },
|
|
208
|
+
{ variant: "badge", sentiment: "neutral", className: "border-neutral/20 bg-neutral-subtle dark:border-neutral/25" },
|
|
209
|
+
],
|
|
210
|
+
defaultVariants: {
|
|
211
|
+
variant: "badge",
|
|
212
|
+
sentiment: "neutral",
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
export interface DeltaProps
|
|
218
|
+
extends
|
|
219
|
+
Omit<HTMLAttributes<HTMLSpanElement>, "children">,
|
|
220
|
+
Pick<VariantProps<typeof deltaVariants>, "variant"> {
|
|
221
|
+
/** The current value. The previous one comes from `comparison`. */
|
|
222
|
+
value: number | null | undefined
|
|
223
|
+
/** What the value is compared against. Required so the delta always carries its label. */
|
|
224
|
+
comparison: Comparison
|
|
225
|
+
/** Which direction is good: `"up"` (default) or `"down"` (churn, error rate). Wins over `polarity`. */
|
|
226
|
+
betterWhen?: "up" | "down"
|
|
227
|
+
/** @deprecated Older name of `betterWhen` (`"higher-is-better"` / `"lower-is-better"`); `"neutral"` is only reachable here. `betterWhen` wins if both are given. */
|
|
228
|
+
polarity?: Polarity
|
|
229
|
+
/** Absolute ratio below which the change reads as flat (0.01 = 1%). Default 0.01. */
|
|
230
|
+
neutralBand?: number
|
|
231
|
+
/** Format of the metric itself; a `percent` metric shows its change in points. */
|
|
232
|
+
format?: ValueFormat
|
|
233
|
+
/**
|
|
234
|
+
* `"relative"` ("+12.4%"), `"points"` ("-0.5pt") or `"difference"` (the absolute difference in the
|
|
235
|
+
* metric's own `format`, "+¥530万"). Default: points for a `percent` format, else relative.
|
|
236
|
+
*/
|
|
237
|
+
change?: ChangeDisplay
|
|
238
|
+
/**
|
|
239
|
+
* 変化(`"relative"` の率・`"points"` の pt)の小数桁数。固定で、末尾の 0 も出す。例: `digits={2}` → "+0.14pt"。
|
|
240
|
+
* 同じカード群で桁がばらつかないよう、全部に同じ値を渡す。未指定は 1 桁("+14.0%")。`"points"` は未指定のとき `format.digits` に従う。
|
|
241
|
+
*/
|
|
242
|
+
digits?: number
|
|
243
|
+
/** Locale for the change and its label. Default: the page's (`<html lang>`, else `"en-US"`). */
|
|
244
|
+
locale?: string
|
|
245
|
+
/** Show the comparison label ("前月比") after the change. Default true. */
|
|
246
|
+
showLabel?: boolean
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** Text shown when the values cannot be compared (no previous value, or a zero baseline): the same "—" as every missing value. */
|
|
250
|
+
export const DELTA_NOT_COMPARABLE = EMPTY_VALUE
|
|
251
|
+
|
|
252
|
+
const ARIA_TEXT = {
|
|
253
|
+
ja: {
|
|
254
|
+
none: (label: string) => `${label} 比較できません`,
|
|
255
|
+
flat: (label: string) => `${label} 横ばい`,
|
|
256
|
+
points: " ポイント",
|
|
257
|
+
change: (label: string, amount: string, up: boolean) => `${label} ${amount} ${up ? "増加" : "減少"}`,
|
|
258
|
+
},
|
|
259
|
+
en: {
|
|
260
|
+
none: (label: string) => `${label}: not comparable`,
|
|
261
|
+
flat: (label: string) => `Flat ${label}`,
|
|
262
|
+
points: " points",
|
|
263
|
+
change: (label: string, amount: string, up: boolean) => `${up ? "Up" : "Down"} ${amount} ${label}`,
|
|
264
|
+
},
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Screen-reader text, e.g. "Up 12.4% vs. prior month" / "Down 0.5 points vs. prior month" / "Flat vs. prior month" /
|
|
269
|
+
* "vs. prior month: not comparable" (ja: "前月比 12.4% 増加" / "前月比 0.5 ポイント 減少" / "前月比 横ばい" / "前月比 比較できません").
|
|
270
|
+
* The amount carries no sign, since the verb already says the direction ("−0.5 ポイント 減少" would negate twice).
|
|
271
|
+
* `locale` defaults to the page's (`<html lang>`).
|
|
272
|
+
*/
|
|
273
|
+
export function deltaAriaLabel(
|
|
274
|
+
result: ComparisonResult,
|
|
275
|
+
locale?: string,
|
|
276
|
+
change: ChangeDisplay = "relative",
|
|
277
|
+
format?: ValueFormat,
|
|
278
|
+
digits?: number,
|
|
279
|
+
): string {
|
|
280
|
+
const resolved = resolveLocale(locale)
|
|
281
|
+
const t = ARIA_TEXT[uiLanguage(resolved)]
|
|
282
|
+
const { label, direction, ratio } = result
|
|
283
|
+
if (direction === "none" || ratio === null) return t.none(label)
|
|
284
|
+
if (direction === "flat") return t.flat(label)
|
|
285
|
+
const amount = formatChangeAmount(result, change, resolved, format, digits)
|
|
286
|
+
if (amount === null) return t.none(label)
|
|
287
|
+
return t.change(label, change === "points" ? amount.replace(/pt$/, t.points) : amount, direction === "up")
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export const Delta = forwardRef<HTMLSpanElement, DeltaProps>(
|
|
291
|
+
(
|
|
292
|
+
{
|
|
293
|
+
value,
|
|
294
|
+
comparison,
|
|
295
|
+
betterWhen,
|
|
296
|
+
polarity,
|
|
297
|
+
neutralBand,
|
|
298
|
+
format,
|
|
299
|
+
change,
|
|
300
|
+
digits,
|
|
301
|
+
locale: localeProp,
|
|
302
|
+
showLabel = true,
|
|
303
|
+
variant = "badge",
|
|
304
|
+
className,
|
|
305
|
+
...props
|
|
306
|
+
},
|
|
307
|
+
ref,
|
|
308
|
+
) => {
|
|
309
|
+
const locale = useLocale(localeProp)
|
|
310
|
+
// Nothing to compare against yet (a draft fills props in steps).
|
|
311
|
+
if (!comparison) return null
|
|
312
|
+
const result = computeComparison(value, comparison, {
|
|
313
|
+
polarity: betterWhen ? (betterWhen === "down" ? "lower-is-better" : "higher-is-better") : polarity,
|
|
314
|
+
neutralBand,
|
|
315
|
+
locale,
|
|
316
|
+
})
|
|
317
|
+
const display = change ?? defaultChangeDisplay(format)
|
|
318
|
+
const formatDigits = typeof format === "object" && format !== null && "digits" in format ? format.digits : undefined
|
|
319
|
+
const changeDigits = display === "points" ? (digits ?? formatDigits) : digits
|
|
320
|
+
const comparable = result.direction !== "none"
|
|
321
|
+
const Icon = result.direction === "up" ? ArrowUp : result.direction === "down" ? ArrowDown : ArrowRight
|
|
322
|
+
const text = formatChange(result, display, locale, format, changeDigits)
|
|
323
|
+
|
|
324
|
+
return (
|
|
325
|
+
<span
|
|
326
|
+
ref={ref}
|
|
327
|
+
role="img"
|
|
328
|
+
data-slot="delta"
|
|
329
|
+
data-direction={result.direction}
|
|
330
|
+
data-sentiment={result.sentiment}
|
|
331
|
+
aria-label={deltaAriaLabel(result, locale, display, format, changeDigits)}
|
|
332
|
+
className={cn(
|
|
333
|
+
deltaVariants({ variant, sentiment: result.sentiment }),
|
|
334
|
+
!comparable && "text-muted-foreground",
|
|
335
|
+
className,
|
|
336
|
+
)}
|
|
337
|
+
{...props}
|
|
338
|
+
>
|
|
339
|
+
{comparable && <Icon aria-hidden="true" />}
|
|
340
|
+
<span aria-hidden="true">{text ?? DELTA_NOT_COMPARABLE}</span>
|
|
341
|
+
{showLabel && (
|
|
342
|
+
<span aria-hidden="true" className="font-normal text-muted-foreground">
|
|
343
|
+
{result.label}
|
|
344
|
+
</span>
|
|
345
|
+
)}
|
|
346
|
+
</span>
|
|
347
|
+
)
|
|
348
|
+
},
|
|
349
|
+
)
|
|
350
|
+
Delta.displayName = "Delta"
|
|
351
|
+
|
|
352
|
+
export { deltaVariants }
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// Copied by `vantage add ui dialog`. This file is yours to edit.
|
|
2
|
+
// Generated from @squadbase/squadkit registry/ui/dialog.tsx by `pnpm run registry` (in Vantage, edit packages/squadkit, not registry/).
|
|
3
|
+
"use client"
|
|
4
|
+
|
|
5
|
+
import * as React from "react"
|
|
6
|
+
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog"
|
|
7
|
+
|
|
8
|
+
import { cn } from "@squadbase/vantage/ui"
|
|
9
|
+
import { Button } from "@squadbase/vantage/ui"
|
|
10
|
+
import { XIcon } from "lucide-react"
|
|
11
|
+
|
|
12
|
+
function Dialog({ ...props }: DialogPrimitive.Root.Props) {
|
|
13
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
|
|
17
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {
|
|
21
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function DialogClose({ ...props }: DialogPrimitive.Close.Props) {
|
|
25
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function DialogOverlay({
|
|
29
|
+
className,
|
|
30
|
+
...props
|
|
31
|
+
}: DialogPrimitive.Backdrop.Props) {
|
|
32
|
+
return (
|
|
33
|
+
<DialogPrimitive.Backdrop
|
|
34
|
+
data-slot="dialog-overlay"
|
|
35
|
+
className={cn(
|
|
36
|
+
"fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in motion-reduce:animate-none! data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
|
|
37
|
+
className
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function DialogContent({
|
|
45
|
+
className,
|
|
46
|
+
children,
|
|
47
|
+
showCloseButton = true,
|
|
48
|
+
...props
|
|
49
|
+
}: DialogPrimitive.Popup.Props & {
|
|
50
|
+
showCloseButton?: boolean
|
|
51
|
+
}) {
|
|
52
|
+
return (
|
|
53
|
+
<DialogPortal>
|
|
54
|
+
<DialogOverlay />
|
|
55
|
+
<DialogPrimitive.Popup
|
|
56
|
+
data-slot="dialog-content"
|
|
57
|
+
className={cn(
|
|
58
|
+
"fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in motion-reduce:animate-none! data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
59
|
+
className
|
|
60
|
+
)}
|
|
61
|
+
{...props}
|
|
62
|
+
>
|
|
63
|
+
{children}
|
|
64
|
+
{showCloseButton && (
|
|
65
|
+
<DialogPrimitive.Close
|
|
66
|
+
data-slot="dialog-close"
|
|
67
|
+
render={
|
|
68
|
+
<Button
|
|
69
|
+
variant="ghost"
|
|
70
|
+
className="absolute top-2 right-2"
|
|
71
|
+
size="icon-sm"
|
|
72
|
+
/>
|
|
73
|
+
}
|
|
74
|
+
>
|
|
75
|
+
<XIcon />
|
|
76
|
+
<span className="sr-only">Close</span>
|
|
77
|
+
</DialogPrimitive.Close>
|
|
78
|
+
)}
|
|
79
|
+
</DialogPrimitive.Popup>
|
|
80
|
+
</DialogPortal>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
85
|
+
return (
|
|
86
|
+
<div
|
|
87
|
+
data-slot="dialog-header"
|
|
88
|
+
className={cn("flex flex-col gap-2", className)}
|
|
89
|
+
{...props}
|
|
90
|
+
/>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function DialogFooter({
|
|
95
|
+
className,
|
|
96
|
+
showCloseButton = false,
|
|
97
|
+
children,
|
|
98
|
+
...props
|
|
99
|
+
}: React.ComponentProps<"div"> & {
|
|
100
|
+
showCloseButton?: boolean
|
|
101
|
+
}) {
|
|
102
|
+
return (
|
|
103
|
+
<div
|
|
104
|
+
data-slot="dialog-footer"
|
|
105
|
+
className={cn(
|
|
106
|
+
"-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",
|
|
107
|
+
className
|
|
108
|
+
)}
|
|
109
|
+
{...props}
|
|
110
|
+
>
|
|
111
|
+
{children}
|
|
112
|
+
{showCloseButton && (
|
|
113
|
+
<DialogPrimitive.Close render={<Button variant="outline" />}>
|
|
114
|
+
Close
|
|
115
|
+
</DialogPrimitive.Close>
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
|
|
122
|
+
return (
|
|
123
|
+
<DialogPrimitive.Title
|
|
124
|
+
data-slot="dialog-title"
|
|
125
|
+
className={cn(
|
|
126
|
+
"cn-font-heading text-base leading-none font-medium",
|
|
127
|
+
className
|
|
128
|
+
)}
|
|
129
|
+
{...props}
|
|
130
|
+
/>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function DialogDescription({
|
|
135
|
+
className,
|
|
136
|
+
...props
|
|
137
|
+
}: DialogPrimitive.Description.Props) {
|
|
138
|
+
return (
|
|
139
|
+
<DialogPrimitive.Description
|
|
140
|
+
data-slot="dialog-description"
|
|
141
|
+
className={cn(
|
|
142
|
+
"text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
|
|
143
|
+
className
|
|
144
|
+
)}
|
|
145
|
+
{...props}
|
|
146
|
+
/>
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export {
|
|
151
|
+
Dialog,
|
|
152
|
+
DialogClose,
|
|
153
|
+
DialogContent,
|
|
154
|
+
DialogDescription,
|
|
155
|
+
DialogFooter,
|
|
156
|
+
DialogHeader,
|
|
157
|
+
DialogOverlay,
|
|
158
|
+
DialogPortal,
|
|
159
|
+
DialogTitle,
|
|
160
|
+
DialogTrigger,
|
|
161
|
+
}
|