@squadbase/vantage 0.6.2-dev1.d7c0911 → 0.6.2-dev1.e85faec

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.
Files changed (221) hide show
  1. package/dist/chunk-2IAPIOPS.js +152 -0
  2. package/dist/chunk-2IAPIOPS.js.map +1 -0
  3. package/dist/chunk-57GHR5LN.js +163 -0
  4. package/dist/chunk-57GHR5LN.js.map +1 -0
  5. package/dist/chunk-6OTTGAPO.js +44 -0
  6. package/dist/chunk-6OTTGAPO.js.map +1 -0
  7. package/dist/{chunk-XPQSTZUU.js → chunk-7S52M2SL.js} +4 -3
  8. package/dist/chunk-7S52M2SL.js.map +1 -0
  9. package/dist/chunk-JXFCSF3K.js +673 -0
  10. package/dist/chunk-JXFCSF3K.js.map +1 -0
  11. package/dist/{chunk-WRSX2MDK.js → chunk-QOXXOFGL.js} +115 -930
  12. package/dist/chunk-QOXXOFGL.js.map +1 -0
  13. package/dist/components/index.d.ts +13 -249
  14. package/dist/components/index.js +5 -2
  15. package/dist/delta-text-CvwBGJ95.d.ts +15 -0
  16. package/dist/doc/index.d.ts +215 -2
  17. package/dist/doc/index.js +300 -3
  18. package/dist/doc/index.js.map +1 -1
  19. package/dist/format-U0cQl069.d.ts +243 -0
  20. package/dist/slide/index.d.ts +272 -1
  21. package/dist/slide/index.js +968 -3
  22. package/dist/slide/index.js.map +1 -1
  23. package/dist/table/index.js +6 -3
  24. package/dist/table/index.js.map +1 -1
  25. package/dist/ui/index.d.ts +4 -1
  26. package/dist/ui/index.js +3 -3
  27. package/dist/ui/index.js.map +1 -1
  28. package/docs/en/components.md +13 -2
  29. package/docs/en/doc/delta-text.md +40 -0
  30. package/docs/en/doc/doc-action-items.md +49 -0
  31. package/docs/en/doc/doc-callout.md +38 -0
  32. package/docs/en/doc/doc-data-table.md +60 -0
  33. package/docs/en/doc/doc-executive-summary.md +64 -0
  34. package/docs/en/doc/doc-figure.md +56 -0
  35. package/docs/en/doc/doc-key-findings.md +61 -0
  36. package/docs/en/doc/doc-kpi-scorecard.md +80 -0
  37. package/docs/en/doc/doc-notes-and-sources.md +43 -0
  38. package/docs/en/doc/doc-report-header.md +46 -0
  39. package/docs/en/parts/area-chart.md +99 -0
  40. package/docs/en/parts/bar-chart.md +91 -0
  41. package/docs/en/parts/bar-list.md +50 -0
  42. package/docs/en/parts/category-bar.md +37 -0
  43. package/docs/en/parts/chart-frame.md +39 -0
  44. package/docs/en/parts/delta.md +4 -3
  45. package/docs/en/parts/donut-chart.md +72 -0
  46. package/docs/en/parts/funnel-steps.md +2 -1
  47. package/docs/en/parts/heatmap.md +53 -0
  48. package/docs/en/parts/kpi-card.md +2 -1
  49. package/docs/en/parts/legend.md +35 -0
  50. package/docs/en/parts/line-chart.md +94 -0
  51. package/docs/en/parts/progress-circle.md +33 -0
  52. package/docs/en/parts/sample-data.md +39 -0
  53. package/docs/en/parts/scatter-chart.md +56 -0
  54. package/docs/en/parts/tracker.md +36 -0
  55. package/docs/en/parts/updated-at.md +30 -0
  56. package/docs/en/parts/waterfall-chart.md +56 -0
  57. package/docs/en/slide/slide-chart-full.md +48 -0
  58. package/docs/en/slide/slide-chart-insight.md +52 -0
  59. package/docs/en/slide/slide-columns.md +46 -0
  60. package/docs/en/slide/slide-comparison.md +68 -0
  61. package/docs/en/slide/slide-cover.md +39 -0
  62. package/docs/en/slide/slide-exec-summary.md +47 -0
  63. package/docs/en/slide/slide-heading.md +38 -0
  64. package/docs/en/slide/slide-kpi-grid.md +55 -0
  65. package/docs/en/slide/slide-kpi-hero.md +58 -0
  66. package/docs/en/slide/slide-next-actions.md +49 -0
  67. package/docs/en/slide/slide-scorecard-table.md +54 -0
  68. package/docs/en/slide/slide-section.md +44 -0
  69. package/docs/en/slide/slide-source-line.md +34 -0
  70. package/docs/en/ui/alert-dialog.md +42 -0
  71. package/docs/en/ui/avatar.md +31 -0
  72. package/docs/en/ui/combobox.md +74 -0
  73. package/docs/en/ui/drawer.md +41 -0
  74. package/docs/en/ui/empty.md +1 -1
  75. package/docs/en/ui/error-state.md +4 -3
  76. package/docs/en/ui/field.md +42 -0
  77. package/docs/en/ui/hover-card.md +21 -0
  78. package/docs/en/ui/kbd.md +17 -0
  79. package/docs/en/ui/loading.md +1 -1
  80. package/docs/en/ui/pagination.md +36 -0
  81. package/docs/en/ui/radio-group.md +21 -0
  82. package/docs/en/ui/toast.md +44 -0
  83. package/docs/en/ui/toggle-group.md +4 -3
  84. package/docs/index.json +857 -77
  85. package/docs/ja/components.md +12 -1
  86. package/docs/ja/doc/delta-text.md +40 -0
  87. package/docs/ja/doc/doc-action-items.md +49 -0
  88. package/docs/ja/doc/doc-callout.md +38 -0
  89. package/docs/ja/doc/doc-data-table.md +60 -0
  90. package/docs/ja/doc/doc-executive-summary.md +64 -0
  91. package/docs/ja/doc/doc-figure.md +56 -0
  92. package/docs/ja/doc/doc-key-findings.md +61 -0
  93. package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
  94. package/docs/ja/doc/doc-notes-and-sources.md +43 -0
  95. package/docs/ja/doc/doc-report-header.md +46 -0
  96. package/docs/ja/parts/area-chart.md +49 -25
  97. package/docs/ja/parts/bar-chart.md +50 -24
  98. package/docs/ja/parts/bar-list.md +31 -8
  99. package/docs/ja/parts/chart-frame.md +36 -0
  100. package/docs/ja/parts/delta.md +5 -4
  101. package/docs/ja/parts/donut-chart.md +45 -26
  102. package/docs/ja/parts/funnel-steps.md +27 -8
  103. package/docs/ja/parts/heatmap.md +45 -0
  104. package/docs/ja/parts/kpi-card.md +2 -1
  105. package/docs/ja/parts/legend.md +36 -0
  106. package/docs/ja/parts/line-chart.md +48 -22
  107. package/docs/ja/parts/sample-data.md +61 -0
  108. package/docs/ja/parts/scatter-chart.md +69 -0
  109. package/docs/ja/parts/updated-at.md +27 -0
  110. package/docs/ja/parts/waterfall-chart.md +61 -0
  111. package/docs/ja/slide/slide-chart-full.md +48 -0
  112. package/docs/ja/slide/slide-chart-insight.md +52 -0
  113. package/docs/ja/slide/slide-columns.md +46 -0
  114. package/docs/ja/slide/slide-comparison.md +68 -0
  115. package/docs/ja/slide/slide-cover.md +39 -0
  116. package/docs/ja/slide/slide-exec-summary.md +47 -0
  117. package/docs/ja/slide/slide-heading.md +38 -0
  118. package/docs/ja/slide/slide-kpi-grid.md +55 -0
  119. package/docs/ja/slide/slide-kpi-hero.md +58 -0
  120. package/docs/ja/slide/slide-next-actions.md +49 -0
  121. package/docs/ja/slide/slide-scorecard-table.md +54 -0
  122. package/docs/ja/slide/slide-section.md +44 -0
  123. package/docs/ja/slide/slide-source-line.md +34 -0
  124. package/docs/ja/ui/empty.md +1 -1
  125. package/docs/ja/ui/error-state.md +4 -3
  126. package/docs/ja/ui/loading.md +1 -1
  127. package/docs/ja/ui/toggle-group.md +4 -3
  128. package/package.json +26 -25
  129. package/registry/ui/accordion.tsx +1 -1
  130. package/registry/ui/alert-dialog.tsx +1 -1
  131. package/registry/ui/alert.tsx +1 -1
  132. package/registry/ui/app-shell.tsx +1 -1
  133. package/registry/ui/area-chart.tsx +89 -27
  134. package/registry/ui/attention-list.tsx +303 -0
  135. package/registry/ui/avatar.tsx +1 -1
  136. package/registry/ui/badge.tsx +1 -1
  137. package/registry/ui/bar-chart.tsx +89 -27
  138. package/registry/ui/bar-list.tsx +88 -25
  139. package/registry/ui/box-plot-chart.tsx +3906 -0
  140. package/registry/ui/breadcrumb.tsx +1 -1
  141. package/registry/ui/button.tsx +1 -1
  142. package/registry/ui/calendar.tsx +1 -1
  143. package/registry/ui/card.tsx +1 -1
  144. package/registry/ui/category-bar.tsx +55 -20
  145. package/registry/ui/chart-frame.tsx +57 -22
  146. package/registry/ui/checkbox.tsx +1 -1
  147. package/registry/ui/collapsible.tsx +1 -1
  148. package/registry/ui/combobox.tsx +1 -1
  149. package/registry/ui/command.tsx +1 -1
  150. package/registry/ui/dashboard-card.tsx +5 -5
  151. package/registry/ui/data-table.tsx +1 -1
  152. package/registry/ui/date-range-picker.tsx +1 -1
  153. package/registry/ui/delta.tsx +12 -9
  154. package/registry/ui/dialog.tsx +1 -1
  155. package/registry/ui/donut-chart.tsx +90 -27
  156. package/registry/ui/drawer.tsx +1 -1
  157. package/registry/ui/dropdown-menu.tsx +1 -1
  158. package/registry/ui/echart.tsx +195 -45
  159. package/registry/ui/field.tsx +1 -1
  160. package/registry/ui/filter-bar.tsx +1 -1
  161. package/registry/ui/funnel-steps.tsx +34 -6
  162. package/registry/ui/heatmap.tsx +56 -22
  163. package/registry/ui/histogram-chart.tsx +3986 -0
  164. package/registry/ui/hover-card.tsx +1 -1
  165. package/registry/ui/input-group.tsx +1 -1
  166. package/registry/ui/input.tsx +1 -1
  167. package/registry/ui/kbd.tsx +1 -1
  168. package/registry/ui/kpi-card.tsx +42 -15
  169. package/registry/ui/label.tsx +1 -1
  170. package/registry/ui/legend.tsx +88 -25
  171. package/registry/ui/line-chart.tsx +89 -27
  172. package/registry/ui/metric-value.tsx +1 -1
  173. package/registry/ui/multi-select.tsx +1 -1
  174. package/registry/ui/page-shell.tsx +11 -11
  175. package/registry/ui/pagination.tsx +1 -1
  176. package/registry/ui/paired-chart.tsx +3827 -0
  177. package/registry/ui/placeholder.tsx +1 -1
  178. package/registry/ui/popover.tsx +1 -1
  179. package/registry/ui/progress-circle.tsx +1 -1
  180. package/registry/ui/progress.tsx +1 -1
  181. package/registry/ui/radio-group.tsx +1 -1
  182. package/registry/ui/sample-data.tsx +2 -2
  183. package/registry/ui/scatter-chart.tsx +89 -27
  184. package/registry/ui/scroll-area.tsx +1 -1
  185. package/registry/ui/searchable-select.tsx +1 -1
  186. package/registry/ui/section-header.tsx +3 -3
  187. package/registry/ui/segmented-control.tsx +1 -1
  188. package/registry/ui/select.tsx +1 -1
  189. package/registry/ui/separator.tsx +1 -1
  190. package/registry/ui/sheet.tsx +1 -1
  191. package/registry/ui/sidebar.tsx +1 -1
  192. package/registry/ui/skeleton.tsx +1 -1
  193. package/registry/ui/slider.tsx +2 -2
  194. package/registry/ui/sparkline.tsx +1 -1
  195. package/registry/ui/spinner.tsx +1 -1
  196. package/registry/ui/states.tsx +1 -1
  197. package/registry/ui/status-badge.tsx +9 -9
  198. package/registry/ui/switch.tsx +1 -1
  199. package/registry/ui/table.tsx +1 -1
  200. package/registry/ui/tabs.tsx +1 -1
  201. package/registry/ui/textarea.tsx +1 -1
  202. package/registry/ui/toast.tsx +1 -1
  203. package/registry/ui/toggle-group.tsx +1 -1
  204. package/registry/ui/toggle.tsx +1 -1
  205. package/registry/ui/tooltip.tsx +7 -3
  206. package/registry/ui/tracker.tsx +10 -4
  207. package/registry/ui/trend-indicator.tsx +3 -3
  208. package/registry/ui/updated-at.tsx +1 -1
  209. package/registry/ui/waterfall-chart.tsx +89 -27
  210. package/skills/vantage-design/SKILL.md +34 -24
  211. package/skills/vantage-design/references/extract.md +16 -14
  212. package/skills/vantage-design/references/format.md +6 -5
  213. package/skills/vantage-design/references/presets.md +60 -110
  214. package/skills/vantage-slide/SKILL.md +54 -36
  215. package/templates/AGENTS.md +2 -2
  216. package/templates/agents/doc.md +48 -0
  217. package/templates/agents/page.md +32 -1
  218. package/templates/agents/slide.md +70 -2
  219. package/theme.css +25 -20
  220. package/dist/chunk-WRSX2MDK.js.map +0 -1
  221. package/dist/chunk-XPQSTZUU.js.map +0 -1
@@ -1,14 +1,16 @@
1
- import { Tooltip, TooltipTrigger, TooltipContent, Badge, SidebarProvider, Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarFooter, SidebarRail, SidebarInset, SidebarTrigger, Separator, Input, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Skeleton, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, useIsMobile, Popover, PopoverTrigger, PopoverContent, Calendar, ToggleGroup, ToggleGroupItem, SelectGroup, SelectLabel, Collapsible, CollapsibleTrigger, SidebarMenuButton, SidebarMenuBadge, CollapsibleContent, SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton, SidebarMenuItem, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, Checkbox, Card, CardHeader, CardDescription, CardTitle, CardAction, CardFooter } from './chunk-XPQSTZUU.js';
1
+ import { ChartFrameContext, useChartSurface, resolveChartColors, CHART_OTHER_COLOR, EChart, resolveFillColors } from './chunk-JXFCSF3K.js';
2
+ import { Sparkline } from './chunk-2IAPIOPS.js';
3
+ import { formatDateRange, EMPTY_VALUE, DEFAULT_LOCALE, formatDate, toValueFormatter, formatValue, formatPoints, formatKind, formatDelta, MINUS_SIGN, formatDatesInText } from './chunk-57GHR5LN.js';
4
+ import { Tooltip, TooltipTrigger, TooltipContent, Badge, SidebarProvider, Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarFooter, SidebarRail, SidebarInset, SidebarTrigger, Separator, Input, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Skeleton, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, useIsMobile, Popover, PopoverTrigger, PopoverContent, Calendar, ToggleGroup, ToggleGroupItem, SelectGroup, SelectLabel, Collapsible, CollapsibleTrigger, SidebarMenuButton, SidebarMenuBadge, CollapsibleContent, SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton, SidebarMenuItem, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, Checkbox, Card, CardHeader, CardDescription, CardTitle, CardAction, CardFooter } from './chunk-7S52M2SL.js';
2
5
  import { Button } from './chunk-PDOBHMUQ.js';
3
6
  import { cn } from './chunk-U736PVHY.js';
4
- import { forwardRef, useState, useEffect, createContext, useId, useRef, useMemo, useCallback, useContext, Fragment as Fragment$1 } from 'react';
7
+ import { forwardRef, useState, useEffect, createContext, useId, useMemo, useRef, useCallback, Fragment as Fragment$1, useContext } from 'react';
5
8
  import { cva } from 'class-variance-authority';
6
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { Check, Copy, Download, Search, Columns3, CalendarIcon, ChevronDownIcon, ArrowUp, ArrowDown, ArrowRight, Minus, ChevronRight, ArrowUpDown, XIcon, LoaderIcon, CheckIcon, ChevronDown, X, CircleX, TriangleAlert, CircleCheck } from 'lucide-react';
8
- import { use, init } from 'echarts/core';
9
- import { BarChart, CustomChart, LineChart, PieChart, ScatterChart as ScatterChart$1, HeatmapChart } from 'echarts/charts';
10
- import { GridComponent, LegendComponent, MarkAreaComponent, MarkLineComponent, MarkPointComponent, TooltipComponent, GraphicComponent, VisualMapComponent } from 'echarts/components';
11
- import { CanvasRenderer } from 'echarts/renderers';
10
+ import { Search, Columns3, CalendarIcon, ChevronDownIcon, ArrowUp, ArrowDown, ArrowRight, Minus, ChevronRight, ArrowUpDown, XIcon, LoaderIcon, CheckIcon, Download, ChevronDown, X, CircleX, TriangleAlert, CircleCheck } from 'lucide-react';
11
+ import { use } from 'echarts/core';
12
+ import { GraphicComponent, VisualMapComponent } from 'echarts/components';
13
+ import { ScatterChart as ScatterChart$1, HeatmapChart } from 'echarts/charts';
12
14
  import 'echarts';
13
15
  import { flexRender, useReactTable, getPaginationRowModel, getFilteredRowModel, getSortedRowModel, getCoreRowModel } from '@tanstack/react-table';
14
16
  import { subMonths, subDays, endOfDay, startOfDay, startOfWeek, subWeeks, endOfWeek, startOfMonth, endOfMonth, isSameDay, format, addMonths } from 'date-fns';
@@ -16,164 +18,6 @@ import { ja } from 'date-fns/locale';
16
18
 
17
19
  // @squadbase/vantage — generated build. Do not edit.
18
20
 
19
- // ../squadkit/registry/lib/format.ts
20
- var DEFAULT_LOCALE = "ja-JP";
21
- var EMPTY_VALUE = "\u2014";
22
- var MINUS_SIGN = "\u2212";
23
- var PERCENT_DIGITS = 1;
24
- var DEFAULT_CURRENCY = "JPY";
25
- var MULTIPLE_SUFFIX = "\xD7";
26
- var POINTS_SUFFIX = "pt";
27
- function normalize(format2) {
28
- if (format2 === void 0) return { type: "compact" };
29
- return typeof format2 === "string" ? { type: format2 } : format2;
30
- }
31
- function formatKind(format2) {
32
- return normalize(format2).type;
33
- }
34
- function digitOptions(digits, defaultMax, significantDigits) {
35
- if (significantDigits !== void 0) return { maximumSignificantDigits: significantDigits };
36
- if (digits !== void 0) return { minimumFractionDigits: digits, maximumFractionDigits: digits };
37
- return defaultMax === void 0 ? {} : { maximumFractionDigits: defaultMax };
38
- }
39
- function formatParts(locale, options, value) {
40
- if (options.notation === "compact") {
41
- const compact = new Intl.NumberFormat(locale, {
42
- ...options,
43
- useGrouping: "always"
44
- }).formatToParts(value);
45
- if (!compact.some((p) => p.type === "compact")) return formatParts(locale, { ...options, notation: "standard" }, value);
46
- return joinParts(compact);
47
- }
48
- return joinParts(new Intl.NumberFormat(locale, options).formatToParts(value));
49
- }
50
- var joinParts = (parts) => parts.map((p) => p.type === "currency" ? p.value.normalize("NFKC") : p.type === "minusSign" ? MINUS_SIGN : p.value).join("");
51
- function formatValue(value, format2, locale = DEFAULT_LOCALE, options) {
52
- if (value === null || value === void 0 || Number.isNaN(value)) return EMPTY_VALUE;
53
- const { type, digits, currency, notation, unit, divisor, durationUnit } = normalize(format2);
54
- if (divisor !== void 0 && Number.isFinite(divisor) && divisor !== 0) value = value / divisor;
55
- const signDisplay = options?.signDisplay ?? "auto";
56
- const sig = options?.significantDigits;
57
- const withUnit = (s) => unit ? `${s}${unit}` : s;
58
- switch (type) {
59
- case "number":
60
- return withUnit(formatParts(locale, { ...digitOptions(digits, 2, sig), signDisplay }, value));
61
- case "percent":
62
- return formatParts(locale, { style: "percent", ...digitOptions(digits ?? PERCENT_DIGITS, void 0, sig), signDisplay }, value);
63
- case "currency":
64
- return withUnit(
65
- formatParts(
66
- locale,
67
- {
68
- style: "currency",
69
- currency: currency ?? DEFAULT_CURRENCY,
70
- notation: notation ?? "compact",
71
- ...digitOptions(digits, notation === "standard" ? void 0 : 1, sig),
72
- signDisplay
73
- },
74
- value
75
- )
76
- );
77
- case "multiple":
78
- return `${formatParts(locale, { ...digitOptions(digits, 2, sig), signDisplay }, value)}${unit || MULTIPLE_SUFFIX}`;
79
- case "compact":
80
- return withUnit(formatParts(locale, { ...digitOptions(digits, 1, sig), signDisplay, notation: "compact" }, value));
81
- case "duration":
82
- return formatDuration(value, durationUnit ?? "second", locale, digits, signDisplay);
83
- }
84
- }
85
- var SECONDS_PER = { second: 1, minute: 60, hour: 3600, day: 86400 };
86
- function durationWords(locale) {
87
- return locale.toLowerCase().startsWith("ja") ? { day: "\u65E5", hour: "\u6642\u9593", minute: "\u5206", second: "\u79D2", sep: "" } : { day: "d", hour: "h", minute: "min", second: "s", sep: " " };
88
- }
89
- function formatDuration(value, unit, locale, digits, signDisplay) {
90
- const w = durationWords(locale);
91
- const abs = Math.round(Math.abs(value) * SECONDS_PER[unit]);
92
- const join = (...parts) => parts.filter(([n]) => n !== 0).map(([n, u]) => `${n}${w.sep}${u}`).join(w.sep) || `0${w.sep}${parts.at(-1)?.[1] ?? w.second}`;
93
- let body;
94
- let zero = false;
95
- if (abs >= 86400) {
96
- const days = new Intl.NumberFormat(locale, { maximumFractionDigits: digits ?? 1, minimumFractionDigits: digits ?? 0 });
97
- body = `${days.format(abs / 86400)}${w.sep}${w.day}`;
98
- } else if (abs >= 3600) {
99
- const minutes = Math.round(abs / 60);
100
- body = join([Math.floor(minutes / 60), w.hour], [minutes % 60, w.minute]);
101
- } else if (abs >= 60) {
102
- body = join([Math.floor(abs / 60), w.minute], [abs % 60, w.second]);
103
- } else {
104
- zero = abs === 0;
105
- body = `${abs}${w.sep}${w.second}`;
106
- }
107
- const sign = zero ? "" : value < 0 ? MINUS_SIGN : signDisplay === "exceptZero" ? "+" : "";
108
- return `${sign}${body}`;
109
- }
110
- function formatDelta(value, format2, locale = DEFAULT_LOCALE) {
111
- return formatValue(value, format2, locale, { signDisplay: "exceptZero" });
112
- }
113
- function formatPoints(difference, locale = DEFAULT_LOCALE, options) {
114
- if (difference === null || difference === void 0 || Number.isNaN(difference)) return EMPTY_VALUE;
115
- const digits = options?.digits ?? PERCENT_DIGITS;
116
- const number = formatParts(
117
- locale,
118
- { minimumFractionDigits: digits, maximumFractionDigits: digits, signDisplay: options?.signDisplay ?? "exceptZero" },
119
- difference * 100
120
- );
121
- return `${number}${POINTS_SUFFIX}`;
122
- }
123
- function toValueFormatter(format2, locale = DEFAULT_LOCALE) {
124
- return (value) => formatValue(value, format2, locale);
125
- }
126
- var DATE_STYLE_OPTIONS = {
127
- date: { year: "numeric", month: "2-digit", day: "2-digit" },
128
- datetime: { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", hourCycle: "h23" },
129
- month: { month: "short" },
130
- "year-month": { year: "numeric", month: "long" },
131
- year: { year: "numeric" }
132
- };
133
- var CALENDAR_DATE = /^\d{4}-\d{2}(-\d{2})?$/;
134
- function formatDate(value, style = "date", locale = DEFAULT_LOCALE, options) {
135
- if (value === null || value === void 0 || value === "") return EMPTY_VALUE;
136
- const calendar = typeof value === "string" && CALENDAR_DATE.test(value);
137
- const date = value instanceof Date ? value : new Date(value);
138
- if (!Number.isFinite(date.getTime())) return EMPTY_VALUE;
139
- return new Intl.DateTimeFormat(locale, {
140
- ...DATE_STYLE_OPTIONS[style],
141
- timeZone: calendar ? "UTC" : options?.timeZone
142
- }).format(date);
143
- }
144
- function formatDateRange(start, end, options) {
145
- const locale = options?.locale ?? DEFAULT_LOCALE;
146
- const parse = (value) => {
147
- if (value === null || value === void 0 || value === "") return null;
148
- const calendar = typeof value === "string" && CALENDAR_DATE.test(value);
149
- const date = value instanceof Date ? value : new Date(value);
150
- if (!Number.isFinite(date.getTime())) return null;
151
- return { date, timeZone: calendar ? "UTC" : options?.timeZone };
152
- };
153
- const a = parse(start);
154
- const b = parse(end);
155
- if (!a || !b) return EMPTY_VALUE;
156
- const full = (x, withYear) => new Intl.DateTimeFormat(locale, {
157
- ...withYear ? { year: "numeric" } : {},
158
- month: "numeric",
159
- day: "numeric",
160
- timeZone: x.timeZone
161
- }).format(x.date);
162
- const year = (x) => new Intl.DateTimeFormat("en-US", { year: "numeric", timeZone: x.timeZone }).format(x.date);
163
- const startText = full(a, true);
164
- const sameYear = year(a) === year(b);
165
- const endFull = full(b, true);
166
- if (startText === endFull) return startText;
167
- const separator = locale.toLowerCase().startsWith("ja") ? "\u301C" : " \u2013 ";
168
- return `${startText}${separator}${sameYear ? full(b, false) : endFull}`;
169
- }
170
- function formatDatesInText(text, locale = DEFAULT_LOCALE) {
171
- return text.replace(
172
- /(?<![\d-])(\d{4})-(0[1-9]|1[0-2])(-(0[1-9]|[12]\d|3[01]))?(?![\d-])/g,
173
- (match, _y, _m, day) => formatDate(match, day ? "date" : "year-month", locale)
174
- );
175
- }
176
-
177
21
  // ../squadkit/registry/lib/relative-time.ts
178
22
  var SECOND = 1e3;
179
23
  var MINUTE = 60 * SECOND;
@@ -282,17 +126,17 @@ var PageShellHeader = forwardRef(
282
126
  {
283
127
  ref,
284
128
  "data-slot": "page-shell-header",
285
- className: cn("flex flex-wrap items-start gap-x-4 gap-y-6 px-6 py-12", className),
129
+ className: cn("flex flex-wrap items-start gap-x-4 gap-y-4 px-6 pt-8", className),
286
130
  ...props,
287
131
  children: [
288
132
  children,
289
133
  updatedAt !== void 0 && updatedAt !== null ? /* @__PURE__ */ jsx("div", { "data-slot": "page-shell-updated-at", className: "ml-auto max-w-full shrink-0 text-right", children: /* @__PURE__ */ jsx(UpdatedAt, { at: updatedAt, variant: updatedAtVariant, timeZone }) }) : null,
290
134
  hasChips ? /* @__PURE__ */ jsxs("div", { "data-slot": "page-shell-chips", className: "order-1 flex basis-full flex-wrap gap-1.5", children: [
291
- source ? /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "h-auto max-w-full whitespace-normal", children: [
135
+ source ? /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "h-auto max-w-full whitespace-normal text-muted-foreground", children: [
292
136
  "\u51FA\u5178\uFF1A",
293
137
  source
294
138
  ] }) : null,
295
- periodText && periodText !== EMPTY_VALUE ? /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "tabular-nums", children: periodText }) : null
139
+ periodText && periodText !== EMPTY_VALUE ? /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "tabular-nums text-muted-foreground", children: periodText }) : null
296
140
  ] }) : null,
297
141
  hasStatus ? /* @__PURE__ */ jsx("div", { "data-slot": "page-shell-status", className: "order-2 min-w-0 basis-full", children: status }) : null
298
142
  ]
@@ -319,7 +163,7 @@ var PageShellTitle = forwardRef(
319
163
  {
320
164
  ref,
321
165
  "data-slot": "page-shell-title",
322
- className: cn("text-2xl font-bold tracking-tight text-foreground", className),
166
+ className: cn("text-2xl font-semibold tracking-tight text-foreground", className),
323
167
  ...props
324
168
  }
325
169
  )
@@ -389,11 +233,11 @@ var PageShellSummary = forwardRef(
389
233
  );
390
234
  PageShellSummary.displayName = "PageShellSummary";
391
235
  var summaryCardTones = {
392
- positive: "border-positive/30 bg-positive-subtle [&>svg]:text-positive",
393
- negative: "border-negative/30 bg-negative-subtle [&>svg]:text-negative",
394
- warning: "border-warning/30 bg-warning-subtle [&>svg]:text-warning",
395
- info: "border-info/30 bg-info-subtle [&>svg]:text-info",
396
- neutral: "border-neutral/30 bg-neutral-subtle [&>svg]:text-neutral",
236
+ positive: "border-positive/20 dark:border-positive/25 bg-positive-subtle [&>svg]:text-positive",
237
+ negative: "border-negative/20 dark:border-negative/25 bg-negative-subtle [&>svg]:text-negative",
238
+ warning: "border-warning/20 dark:border-warning/25 bg-warning-subtle [&>svg]:text-warning",
239
+ info: "border-info/20 dark:border-info/25 bg-info-subtle [&>svg]:text-info",
240
+ neutral: "border-neutral/20 dark:border-neutral/25 bg-neutral-subtle [&>svg]:text-neutral",
397
241
  violet: "border-chart-4/30 bg-chart-4/5 [&>svg]:text-chart-4",
398
242
  pink: "border-chart-5/30 bg-chart-5/5 [&>svg]:text-chart-5"
399
243
  };
@@ -451,7 +295,7 @@ var PageShellContent = forwardRef(
451
295
  {
452
296
  ref,
453
297
  "data-slot": "page-shell-content",
454
- className: cn("flex-1 p-6", className),
298
+ className: cn("flex min-w-0 flex-1 flex-col gap-6 p-6", className),
455
299
  ...props
456
300
  }
457
301
  )
@@ -630,8 +474,8 @@ var AppShell = forwardRef((props, ref) => {
630
474
  AppShell.displayName = "AppShell";
631
475
  var headingStyles = {
632
476
  h1: "text-3xl font-bold tracking-tight",
633
- h2: "text-xl font-semibold tracking-tight",
634
- h3: "text-xl font-semibold",
477
+ h2: "text-base font-semibold tracking-tight",
478
+ h3: "text-base font-semibold",
635
479
  h4: "text-lg font-semibold"
636
480
  };
637
481
  var SectionHeader = forwardRef(
@@ -667,7 +511,7 @@ function SampleBadge({ label: label2 = DEFAULT_SAMPLE_LABEL, className, ...props
667
511
  {
668
512
  "data-slot": "sample-badge",
669
513
  title: SAMPLE_TITLE,
670
- className: cn("border-warning/30 bg-warning-subtle text-warning align-middle", className),
514
+ className: cn("border-warning/20 dark:border-warning/25 bg-warning-subtle text-warning align-middle", className),
671
515
  ...props,
672
516
  children: label2
673
517
  }
@@ -678,8 +522,8 @@ function SampleData({ label: label2 = DEFAULT_SAMPLE_LABEL, children }) {
678
522
  return /* @__PURE__ */ jsx("div", { "data-slot": "sample-data", style: { display: "contents" }, children: /* @__PURE__ */ jsx(SampleContext.Provider, { value: state, children }) });
679
523
  }
680
524
  var SUBGRID_CLASS = {
681
- 2: "row-span-2 grid content-start grid-rows-subgrid",
682
- 3: "row-span-3 grid content-start grid-rows-subgrid"
525
+ 2: "row-span-2 grid min-w-0 grid-cols-1 content-start grid-rows-subgrid",
526
+ 3: "row-span-3 grid min-w-0 grid-cols-1 content-start grid-rows-subgrid"
683
527
  };
684
528
  var DashboardCard = forwardRef(
685
529
  ({ className, subgrid, size = "default", ...props }, ref) => /* @__PURE__ */ jsx(
@@ -716,7 +560,7 @@ var DashboardCardTitle = forwardRef(
716
560
  {
717
561
  ref,
718
562
  "data-slot": "dashboard-card-title",
719
- className: cn("text-sm leading-none font-semibold tracking-tight", className),
563
+ className: cn("text-sm leading-snug font-semibold tracking-tight", className),
720
564
  ...props
721
565
  }
722
566
  )
@@ -727,7 +571,7 @@ var DashboardCardDescription = forwardRef(({ className, ...props }, ref) => /* @
727
571
  {
728
572
  ref,
729
573
  "data-slot": "dashboard-card-description",
730
- className: cn("text-xs text-muted-foreground", className),
574
+ className: cn("text-xs leading-normal text-muted-foreground", className),
731
575
  ...props
732
576
  }
733
577
  ));
@@ -807,223 +651,6 @@ function DashboardCardPreset({
807
651
  footer && /* @__PURE__ */ jsx(DashboardCardFooter, { className: cn(subgrid === 3 && "row-start-3", footerClassName), children: footer })
808
652
  ] }) });
809
653
  }
810
- var CHART_OTHER_COLOR = "color-mix(in oklab, var(--neutral) 50%, var(--background))";
811
- var ChartFrameContext = createContext(false);
812
- var SERIES_TOKENS = ["--chart-1", "--chart-2", "--chart-3", "--chart-4", "--chart-5"];
813
- var normalizeContext;
814
- var ZRENDER_COLOR_RE = /^(?:#[0-9a-f]{6}|rgba?\()/i;
815
- function toCanvasColor(value) {
816
- const raw = value.trim();
817
- if (!raw) return null;
818
- if (normalizeContext === void 0) {
819
- const canvas = document.createElement("canvas");
820
- canvas.width = 1;
821
- canvas.height = 1;
822
- normalizeContext = canvas.getContext("2d", { willReadFrequently: true });
823
- }
824
- const ctx = normalizeContext;
825
- if (!ctx) return raw;
826
- ctx.fillStyle = "#000000";
827
- ctx.fillStyle = raw;
828
- const onBlack = ctx.fillStyle;
829
- ctx.fillStyle = "#ffffff";
830
- ctx.fillStyle = raw;
831
- if (onBlack !== ctx.fillStyle || typeof onBlack !== "string") return null;
832
- if (ZRENDER_COLOR_RE.test(onBlack)) return onBlack;
833
- ctx.clearRect(0, 0, 1, 1);
834
- ctx.fillRect(0, 0, 1, 1);
835
- const [r = 0, g = 0, b = 0, a = 0] = ctx.getImageData(0, 0, 1, 1).data;
836
- return a === 255 ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${Math.round(a / 255 * 1e3) / 1e3})`;
837
- }
838
- function readChartTokens(el) {
839
- if (typeof document === "undefined") return null;
840
- const target = document.documentElement;
841
- if (!target) return null;
842
- const styles = getComputedStyle(target);
843
- const read = (name) => toCanvasColor(styles.getPropertyValue(name));
844
- const series = [];
845
- for (const token of SERIES_TOKENS) {
846
- const color = read(token);
847
- if (color) series.push(color);
848
- }
849
- return {
850
- series,
851
- foreground: read("--foreground"),
852
- mutedForeground: read("--muted-foreground"),
853
- border: read("--border"),
854
- popover: read("--popover"),
855
- popoverForeground: read("--popover-foreground")
856
- };
857
- }
858
- function sameChartTokens(a, b) {
859
- if (a === b) return true;
860
- if (!a || !b) return false;
861
- return a.series.length === b.series.length && a.series.every((color, i) => color === b.series[i]) && a.foreground === b.foreground && a.mutedForeground === b.mutedForeground && a.border === b.border && a.popover === b.popover && a.popoverForeground === b.popoverForeground;
862
- }
863
- function watchChartTokens(onChange) {
864
- if (typeof document === "undefined") return () => {
865
- };
866
- let frame = 0;
867
- const schedule = () => {
868
- if (frame) return;
869
- frame = requestAnimationFrame(() => {
870
- frame = 0;
871
- onChange();
872
- });
873
- };
874
- const themeObserver = new MutationObserver(schedule);
875
- const attributeFilter = ["class", "style", "data-theme"];
876
- themeObserver.observe(document.documentElement, { attributes: true, attributeFilter });
877
- if (document.body) themeObserver.observe(document.body, { attributes: true, attributeFilter });
878
- const styleObserver = new MutationObserver(schedule);
879
- if (document.head) {
880
- styleObserver.observe(document.head, {
881
- childList: true,
882
- subtree: true,
883
- characterData: true,
884
- attributes: true,
885
- attributeFilter: ["href", "media", "disabled"]
886
- });
887
- }
888
- const onLoad = (event) => {
889
- if (event.target instanceof HTMLLinkElement) schedule();
890
- };
891
- document.addEventListener("load", onLoad, true);
892
- const media = window.matchMedia("(prefers-color-scheme: dark)");
893
- media.addEventListener("change", schedule);
894
- return () => {
895
- if (frame) cancelAnimationFrame(frame);
896
- themeObserver.disconnect();
897
- styleObserver.disconnect();
898
- document.removeEventListener("load", onLoad, true);
899
- media.removeEventListener("change", schedule);
900
- };
901
- }
902
- function axisTheme(tokens, splitLine) {
903
- const line = tokens.border ?? void 0;
904
- return {
905
- axisLine: { show: false },
906
- axisTick: { show: false },
907
- axisLabel: { show: true, color: tokens.mutedForeground ?? void 0, fontSize: 12 },
908
- // Faint horizontal rules only: the border colour at low opacity.
909
- splitLine: { show: splitLine, lineStyle: { color: line ? [line] : void 0, opacity: 0.5, width: 1 } },
910
- splitArea: { show: false }
911
- };
912
- }
913
- function buildChartTheme(tokens) {
914
- const text = tokens.foreground ?? void 0;
915
- const muted = tokens.mutedForeground ?? void 0;
916
- const line = tokens.border ?? void 0;
917
- return {
918
- // Let the page background show through: charts sit on cards, not on a canvas.
919
- backgroundColor: "transparent",
920
- ...tokens.series.length > 0 ? { color: tokens.series } : {},
921
- textStyle: { color: text },
922
- title: { textStyle: { color: text }, subtextStyle: { color: muted } },
923
- legend: { textStyle: { color: muted } },
924
- categoryAxis: axisTheme(tokens, false),
925
- valueAxis: axisTheme(tokens, true),
926
- logAxis: axisTheme(tokens, true),
927
- timeAxis: axisTheme(tokens, true),
928
- tooltip: {
929
- // ECharts' default 0.4s transform lags the tooltip ~300ms behind the cursor.
930
- transitionDuration: 0,
931
- backgroundColor: tokens.popover ?? void 0,
932
- borderColor: line,
933
- borderWidth: 1,
934
- padding: [8, 12],
935
- // Rounded card with a soft shadow; in dark mode the shadow barely shows, so the border carries the edge.
936
- extraCssText: "border-radius:8px;box-shadow:var(--shadow-card, 0 4px 12px rgb(0 0 0 / 0.08));",
937
- textStyle: { color: tokens.popoverForeground ?? void 0, fontSize: 12 },
938
- axisPointer: { lineStyle: { color: line }, crossStyle: { color: line } }
939
- }
940
- };
941
- }
942
- function useChartTokens() {
943
- const [tokens, setTokens] = useState(() => readChartTokens());
944
- const tokensRef = useRef(tokens);
945
- useEffect(() => {
946
- const sync = () => {
947
- const next = readChartTokens();
948
- if (sameChartTokens(tokensRef.current, next)) return;
949
- tokensRef.current = next;
950
- setTokens(next);
951
- };
952
- sync();
953
- return watchChartTokens(sync);
954
- }, []);
955
- return tokens;
956
- }
957
- var SERIES_TOKEN_NAME_RE = /^chart-([1-5])$/;
958
- var TONE_NAME_RE = /^(?:positive|warning|negative|neutral|info)(?:-fill)?$/;
959
- var CSS_VAR_RE = /^var\(\s*(--[\w-]+)\s*(?:,\s*(.+))?\)$/;
960
- var EMBEDDED_VAR_RE = /var\(\s*(--[\w-]+)\s*\)/g;
961
- function resolveChartColors(colors, tokens) {
962
- return colors.map((color) => {
963
- const token = SERIES_TOKEN_NAME_RE.exec(color.trim());
964
- if (token) return tokens?.series[Number(token[1]) - 1] ?? "";
965
- if (TONE_NAME_RE.test(color.trim())) {
966
- if (typeof document === "undefined") return "";
967
- return toCanvasColor(getComputedStyle(document.documentElement).getPropertyValue(`--${color.trim()}`)) ?? "";
968
- }
969
- if (typeof document === "undefined") return color;
970
- let value = color.trim();
971
- const cssVar = CSS_VAR_RE.exec(value);
972
- const styles = getComputedStyle(document.documentElement);
973
- if (cssVar) {
974
- value = styles.getPropertyValue(cssVar[1]).trim() || (cssVar[2] ?? "").trim();
975
- } else if (value.includes("var(")) {
976
- value = value.replace(EMBEDDED_VAR_RE, (_, name) => styles.getPropertyValue(name).trim());
977
- }
978
- return toCanvasColor(value) ?? "";
979
- });
980
- }
981
- function resolveFillColors(tokens) {
982
- const [positive = "", warning = "", negative = "", neutral = ""] = resolveChartColors(
983
- ["positive-fill", "warning-fill", "negative-fill", "neutral-fill"],
984
- tokens
985
- );
986
- return { positive, warning, negative, neutral };
987
- }
988
- var TRANSPARENT_RE = /^(?:transparent|rgba\([^)]*,\s*0(?:\.0+)?\))$/i;
989
- function readChartSurface(el) {
990
- if (typeof document === "undefined") return null;
991
- for (let node = el; node; node = node.parentElement) {
992
- const bg = getComputedStyle(node).backgroundColor.trim();
993
- if (bg && !TRANSPARENT_RE.test(bg)) {
994
- const color = toCanvasColor(bg);
995
- if (color) return color;
996
- }
997
- }
998
- return toCanvasColor(getComputedStyle(document.documentElement).getPropertyValue("--background"));
999
- }
1000
- var WIDTH_BUCKET = 40;
1001
- function useChartSurface(forwarded, tokens) {
1002
- const [node, setNode] = useState(null);
1003
- const [surface, setSurface] = useState(void 0);
1004
- const [width, setWidth] = useState(void 0);
1005
- const ref = useCallback(
1006
- (el) => {
1007
- setNode(el);
1008
- if (typeof forwarded === "function") forwarded(el);
1009
- else if (forwarded) forwarded.current = el;
1010
- },
1011
- [forwarded]
1012
- );
1013
- useEffect(() => {
1014
- if (!node) return;
1015
- setSurface(readChartSurface(node) ?? void 0);
1016
- }, [node, tokens]);
1017
- useEffect(() => {
1018
- if (!node || typeof ResizeObserver === "undefined") return;
1019
- const update = (w) => setWidth(Math.floor(w / WIDTH_BUCKET) * WIDTH_BUCKET);
1020
- update(node.getBoundingClientRect().width);
1021
- const observer = new ResizeObserver((entries) => update(entries[0]?.contentRect.width ?? 0));
1022
- observer.observe(node);
1023
- return () => observer.disconnect();
1024
- }, [node]);
1025
- return { ref, surface, width };
1026
- }
1027
654
  var DEFAULT_CHART_HEIGHT = 288;
1028
655
  var DEFAULT_EMPTY_TITLE = "\u8868\u793A\u3067\u304D\u308B\u30C7\u30FC\u30BF\u304C\u3042\u308A\u307E\u305B\u3093";
1029
656
  var ChartFrame = forwardRef(function ChartFrame2({
@@ -1047,8 +674,8 @@ var ChartFrame = forwardRef(function ChartFrame2({
1047
674
  const state = isLoading ? "loading" : isEmpty ? "empty" : "ready";
1048
675
  return /* @__PURE__ */ jsxs("figure", { "data-slot": "chart-frame", className: cn("m-0 flex w-full min-w-0 flex-col gap-3", className), ...props, children: [
1049
676
  (title || summary) && /* @__PURE__ */ jsxs("figcaption", { "data-slot": "chart-frame-header", className: "flex flex-col gap-1", children: [
1050
- title && /* @__PURE__ */ jsx("h3", { id: titleId, "data-slot": "chart-frame-title", className: "text-sm leading-none font-medium", children: title }),
1051
- summary && /* @__PURE__ */ jsx("p", { id: summaryId, "data-slot": "chart-frame-summary", className: "text-sm text-muted-foreground", children: summary })
677
+ title && /* @__PURE__ */ jsx("h3", { id: titleId, "data-slot": "chart-frame-title", className: "text-sm leading-snug font-semibold", children: title }),
678
+ summary && /* @__PURE__ */ jsx("p", { id: summaryId, "data-slot": "chart-frame-summary", className: "text-sm leading-relaxed text-muted-foreground", children: summary })
1052
679
  ] }),
1053
680
  /* @__PURE__ */ jsx(
1054
681
  "div",
@@ -1107,336 +734,6 @@ function ChartEmpty({ title, description, action }) {
1107
734
  }
1108
735
  );
1109
736
  }
1110
- use([
1111
- BarChart,
1112
- CustomChart,
1113
- LineChart,
1114
- PieChart,
1115
- GridComponent,
1116
- LegendComponent,
1117
- MarkAreaComponent,
1118
- MarkLineComponent,
1119
- MarkPointComponent,
1120
- TooltipComponent,
1121
- CanvasRenderer
1122
- ]);
1123
- var HEADER_PAD_X = 16;
1124
- var HEADER_PAD_TOP = 16;
1125
- var HEADER_PAD_BOTTOM = 12;
1126
- var HEADER_LINE_HEIGHT = 20;
1127
- var HEADER_GAP = 4;
1128
- var HEADER_FONT_SIZE = 14;
1129
- function wrapChartText(text, maxWidth, measure) {
1130
- const lines = [];
1131
- let line = "";
1132
- for (const ch of text) {
1133
- if (ch === "\n") {
1134
- lines.push(line);
1135
- line = "";
1136
- continue;
1137
- }
1138
- if (line !== "" && measure(line + ch) > maxWidth) {
1139
- lines.push(line);
1140
- line = ch.trim() === "" ? "" : ch;
1141
- } else {
1142
- line += ch;
1143
- }
1144
- }
1145
- if (line !== "" || lines.length === 0) lines.push(line);
1146
- return lines.filter((l, i) => l !== "" || i < lines.length - 1);
1147
- }
1148
- function chartExportHeaderLayout(header, width, measure) {
1149
- const title = header?.title?.trim();
1150
- const summary = header?.summary?.trim();
1151
- if (!title && !summary) return { lines: [], height: 0 };
1152
- const room = Math.max(40, width - HEADER_PAD_X * 2);
1153
- const lines = [
1154
- ...title ? wrapChartText(title, room, (t) => measure(t, "title")).map((text) => ({ text, kind: "title" })) : [],
1155
- ...summary ? wrapChartText(summary, room, (t) => measure(t, "summary")).map((text) => ({ text, kind: "summary" })) : []
1156
- ];
1157
- const gap = title && summary ? HEADER_GAP : 0;
1158
- return { lines, height: HEADER_PAD_TOP + lines.length * HEADER_LINE_HEIGHT + gap + HEADER_PAD_BOTTOM };
1159
- }
1160
- function loadImage(src) {
1161
- return new Promise((resolve, reject) => {
1162
- const image = new Image();
1163
- image.onload = () => resolve(image);
1164
- image.onerror = () => reject(new Error("PNG \u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F"));
1165
- image.src = src;
1166
- });
1167
- }
1168
- async function pngWithHeader(dataUrl, header, look, pixelRatio) {
1169
- const image = await loadImage(dataUrl);
1170
- const width = image.width / pixelRatio;
1171
- const plotHeight = image.height / pixelRatio;
1172
- const canvas = document.createElement("canvas");
1173
- const ctx = canvas.getContext("2d");
1174
- if (!ctx) return dataUrl;
1175
- const font = (kind) => `${kind === "title" ? 500 : 400} ${HEADER_FONT_SIZE}px ${look.fontFamily}`;
1176
- ctx.font = font("title");
1177
- const layout = chartExportHeaderLayout(header, width, (text, kind) => {
1178
- ctx.font = font(kind);
1179
- return ctx.measureText(text).width;
1180
- });
1181
- if (layout.height === 0) return dataUrl;
1182
- canvas.width = Math.round(image.width);
1183
- canvas.height = Math.round((layout.height + plotHeight) * pixelRatio);
1184
- ctx.scale(pixelRatio, pixelRatio);
1185
- ctx.fillStyle = look.background;
1186
- ctx.fillRect(0, 0, width, layout.height + plotHeight);
1187
- ctx.textBaseline = "middle";
1188
- let y = HEADER_PAD_TOP;
1189
- let previous = null;
1190
- for (const line of layout.lines) {
1191
- if (previous === "title" && line.kind === "summary") y += HEADER_GAP;
1192
- ctx.font = font(line.kind);
1193
- ctx.fillStyle = line.kind === "title" ? look.color : look.mutedColor;
1194
- ctx.fillText(line.text, HEADER_PAD_X, y + HEADER_LINE_HEIGHT / 2);
1195
- y += HEADER_LINE_HEIGHT;
1196
- previous = line.kind;
1197
- }
1198
- ctx.drawImage(image, 0, layout.height, width, plotHeight);
1199
- return canvas.toDataURL("image/png");
1200
- }
1201
- function useResolvedChartColors(colors) {
1202
- const tokens = useChartTokens();
1203
- const key = colors.join("\0");
1204
- return useMemo(() => resolveChartColors(colors, tokens), [key, tokens]);
1205
- }
1206
- var COMPONENT_MAIN_TYPES = /* @__PURE__ */ new Set([
1207
- "title",
1208
- "legend",
1209
- "grid",
1210
- "xAxis",
1211
- "yAxis",
1212
- "polar",
1213
- "radiusAxis",
1214
- "angleAxis",
1215
- "radar",
1216
- "dataZoom",
1217
- "visualMap",
1218
- "tooltip",
1219
- "axisPointer",
1220
- "toolbox",
1221
- "brush",
1222
- "geo",
1223
- "parallel",
1224
- "parallelAxis",
1225
- "singleAxis",
1226
- "graphic",
1227
- "calendar",
1228
- "dataset",
1229
- "series",
1230
- "matrix",
1231
- "thumbnail"
1232
- ]);
1233
- function echartSetOptionOpts(prev, next) {
1234
- const special = (o) => "timeline" in o || "baseOption" in o || "options" in o || "media" in o;
1235
- if (!prev || special(prev) || special(next)) return { notMerge: true, lazyUpdate: true };
1236
- const types = /* @__PURE__ */ new Set();
1237
- for (const key of [...Object.keys(prev), ...Object.keys(next)]) if (COMPONENT_MAIN_TYPES.has(key)) types.add(key);
1238
- return { notMerge: false, replaceMerge: [...types], lazyUpdate: true };
1239
- }
1240
- function withMotionPreference(option, reducedMotion) {
1241
- return { ...option, animation: reducedMotion ? false : option.animation ?? true };
1242
- }
1243
- var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
1244
- function usePrefersReducedMotion() {
1245
- const [reduced, setReduced] = useState(
1246
- () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(REDUCED_MOTION_QUERY).matches
1247
- );
1248
- useEffect(() => {
1249
- if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1250
- const media = window.matchMedia(REDUCED_MOTION_QUERY);
1251
- const sync = () => setReduced(media.matches);
1252
- sync();
1253
- media.addEventListener("change", sync);
1254
- return () => media.removeEventListener("change", sync);
1255
- }, []);
1256
- return reduced;
1257
- }
1258
- var EChart = forwardRef(function EChart2({
1259
- option,
1260
- height,
1261
- loading = false,
1262
- theme,
1263
- onEvents,
1264
- ariaLabel,
1265
- className,
1266
- actions = false,
1267
- fileName = "chart.png",
1268
- exportHeader
1269
- }, ref) {
1270
- const containerRef = useRef(null);
1271
- const [instance, setInstance] = useState(null);
1272
- const [copied, setCopied] = useState(false);
1273
- const [tokens, setTokens] = useState(() => readChartTokens());
1274
- const reducedMotion = usePrefersReducedMotion();
1275
- const appliedRef = useRef(null);
1276
- const tokensRef = useRef(tokens);
1277
- useEffect(() => {
1278
- if (theme !== void 0) return;
1279
- const sync = () => {
1280
- const next = readChartTokens();
1281
- if (sameChartTokens(tokensRef.current, next)) return;
1282
- tokensRef.current = next;
1283
- setTokens(next);
1284
- };
1285
- sync();
1286
- return watchChartTokens(sync);
1287
- }, [theme]);
1288
- const autoTheme = useMemo(() => tokens ? buildChartTheme(tokens) : void 0, [tokens]);
1289
- const resolvedTheme = theme ?? autoTheme;
1290
- useEffect(() => {
1291
- const container = containerRef.current;
1292
- if (!container) return;
1293
- const inst = init(container, resolvedTheme, { renderer: "canvas" });
1294
- appliedRef.current = null;
1295
- container.dataset.rendering = "";
1296
- inst.on("finished", () => {
1297
- delete container.dataset.rendering;
1298
- });
1299
- setInstance(inst);
1300
- let frame = 0;
1301
- const observer = new ResizeObserver(() => {
1302
- cancelAnimationFrame(frame);
1303
- frame = requestAnimationFrame(() => {
1304
- if (!inst.isDisposed()) inst.resize();
1305
- });
1306
- });
1307
- observer.observe(container);
1308
- return () => {
1309
- observer.disconnect();
1310
- cancelAnimationFrame(frame);
1311
- inst.dispose();
1312
- };
1313
- }, [resolvedTheme]);
1314
- useEffect(() => {
1315
- if (!instance) return;
1316
- if (containerRef.current) containerRef.current.dataset.rendering = "";
1317
- const next = withMotionPreference(option, reducedMotion);
1318
- instance.setOption(next, echartSetOptionOpts(appliedRef.current, next));
1319
- appliedRef.current = next;
1320
- }, [instance, option, reducedMotion]);
1321
- useEffect(() => {
1322
- if (!instance) return;
1323
- if (loading) instance.showLoading();
1324
- else instance.hideLoading();
1325
- }, [instance, loading]);
1326
- useEffect(() => {
1327
- if (!instance || !onEvents) return;
1328
- const entries = Object.entries(onEvents);
1329
- for (const [event, handler] of entries) {
1330
- instance.on(event, handler);
1331
- }
1332
- return () => {
1333
- if (instance.isDisposed()) return;
1334
- for (const [event, handler] of entries) {
1335
- instance.off(event, handler);
1336
- }
1337
- };
1338
- }, [instance, onEvents]);
1339
- const includeTitle = typeof actions === "object" ? actions.includeTitle ?? true : true;
1340
- const getPngDataUrl = useCallback(async () => {
1341
- if (!instance) return null;
1342
- let backgroundColor = "#ffffff";
1343
- for (let el = containerRef.current; el; el = el.parentElement) {
1344
- const bg = getComputedStyle(el).backgroundColor;
1345
- if (bg && bg !== "rgba(0, 0, 0, 0)" && bg !== "transparent") {
1346
- backgroundColor = bg;
1347
- break;
1348
- }
1349
- }
1350
- const pixelRatio = 2;
1351
- const dataUrl = instance.getDataURL({ type: "png", pixelRatio, backgroundColor });
1352
- if (!includeTitle || !exportHeader || !(exportHeader.title || exportHeader.summary) || !containerRef.current) return dataUrl;
1353
- try {
1354
- const style = getComputedStyle(containerRef.current);
1355
- return await pngWithHeader(
1356
- dataUrl,
1357
- exportHeader,
1358
- { background: backgroundColor, color: style.color, mutedColor: tokens?.mutedForeground ?? style.color, fontFamily: style.fontFamily },
1359
- pixelRatio
1360
- );
1361
- } catch {
1362
- return dataUrl;
1363
- }
1364
- }, [instance, includeTitle, exportHeader, tokens]);
1365
- const handleCopy = useCallback(async () => {
1366
- const dataUrl = await getPngDataUrl();
1367
- if (!dataUrl) return;
1368
- try {
1369
- const blob = await (await fetch(dataUrl)).blob();
1370
- await navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]);
1371
- setCopied(true);
1372
- setTimeout(() => setCopied(false), 2e3);
1373
- } catch {
1374
- }
1375
- }, [getPngDataUrl]);
1376
- const handleDownload = useCallback(async () => {
1377
- const dataUrl = await getPngDataUrl();
1378
- if (!dataUrl) return;
1379
- const link = document.createElement("a");
1380
- link.href = dataUrl;
1381
- link.download = fileName;
1382
- link.click();
1383
- }, [getPngDataUrl, fileName]);
1384
- const inFrame = useContext(ChartFrameContext);
1385
- const styleHeight = height == null ? void 0 : typeof height === "number" ? `${height}px` : height;
1386
- return /* @__PURE__ */ jsxs(
1387
- "div",
1388
- {
1389
- ref,
1390
- "data-slot": "echart",
1391
- className: cn("group relative w-full", height == null && "h-[400px]", className),
1392
- style: styleHeight != null ? { height: styleHeight } : void 0,
1393
- children: [
1394
- /* @__PURE__ */ jsx(
1395
- "div",
1396
- {
1397
- ref: containerRef,
1398
- "data-slot": "echart-canvas",
1399
- className: "h-full w-full",
1400
- role: inFrame ? void 0 : "img",
1401
- "aria-label": inFrame ? void 0 : ariaLabel ?? "\u30C1\u30E3\u30FC\u30C8"
1402
- }
1403
- ),
1404
- actions && /* @__PURE__ */ jsxs(
1405
- "div",
1406
- {
1407
- "data-slot": "echart-actions",
1408
- className: "absolute top-2 right-2 z-10 flex gap-1 pointer-events-none opacity-0 transition-opacity group-hover:pointer-events-auto group-hover:opacity-100 focus-within:pointer-events-auto focus-within:opacity-100 [@media(hover:none)]:pointer-events-auto [@media(hover:none)]:opacity-100",
1409
- children: [
1410
- /* @__PURE__ */ jsx(
1411
- Button,
1412
- {
1413
- type: "button",
1414
- variant: "ghost",
1415
- size: "icon-sm",
1416
- onClick: handleCopy,
1417
- "aria-label": copied ? "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F" : "PNG \u3092\u30AF\u30EA\u30C3\u30D7\u30DC\u30FC\u30C9\u306B\u30B3\u30D4\u30FC",
1418
- children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" })
1419
- }
1420
- ),
1421
- /* @__PURE__ */ jsx(
1422
- Button,
1423
- {
1424
- type: "button",
1425
- variant: "ghost",
1426
- size: "icon-sm",
1427
- onClick: handleDownload,
1428
- "aria-label": "PNG \u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9",
1429
- children: /* @__PURE__ */ jsx(Download, { className: "size-4" })
1430
- }
1431
- )
1432
- ]
1433
- }
1434
- )
1435
- ]
1436
- }
1437
- );
1438
- });
1439
- EChart.displayName = "EChart";
1440
737
 
1441
738
  // ../squadkit/registry/lib/chart-utils.ts
1442
739
  var ROOT_PROP_KEYS = /* @__PURE__ */ new Set(["id", "style", "role", "tabIndex", "lang", "hidden"]);
@@ -1939,6 +1236,8 @@ function timeFormat(locale, options) {
1939
1236
  }
1940
1237
  var toDate = (t) => new Date(t.year, t.month - 1, t.day);
1941
1238
  var TIME_AXIS_MAX_LABELS = 6;
1239
+ var NARROW_PLOT_WIDTH = 400;
1240
+ var NARROW_TIME_AXIS_MAX_LABELS = 4;
1942
1241
  var TIME_AXIS_STEPS = {
1943
1242
  year: [1, 2, 5, 10, 20, 50, 100],
1944
1243
  month: [1, 2, 3, 4, 6, 12, 24, 36, 60, 120],
@@ -2175,7 +1474,8 @@ var LEGEND_LINE_HEIGHT = 24;
2175
1474
  var LEGEND_LINE_BUDGET = 320;
2176
1475
  function legendLines(items, plotWidth, reserve = 0) {
2177
1476
  const width = items.reduce((sum, name) => sum + [...name].length * 12 + 8 + 5 + 16, 0);
2178
- const budget = Math.max(80, (plotWidth ? Math.min(LEGEND_LINE_BUDGET, plotWidth) : LEGEND_LINE_BUDGET) - reserve);
1477
+ const narrow = plotWidth !== void 0 && plotWidth < NARROW_PLOT_WIDTH;
1478
+ const budget = Math.max(80, (plotWidth ? narrow ? plotWidth : Math.min(LEGEND_LINE_BUDGET, plotWidth) : LEGEND_LINE_BUDGET) - (narrow ? 0 : reserve));
2179
1479
  return Math.min(3, Math.max(1, Math.ceil(width / budget)));
2180
1480
  }
2181
1481
  var ACTIONS_RESERVE = 80;
@@ -2331,7 +1631,13 @@ function buildCartesianOption(cfg) {
2331
1631
  const last = labels.length - 1;
2332
1632
  const timeStep = startEndOnly ? null : timeAxisLabelStep(
2333
1633
  rawIndex,
2334
- plotWidth ? Math.max(2, Math.min(TIME_AXIS_MAX_LABELS, Math.floor(plotWidth / TIME_LABEL_WIDTH))) : void 0
1634
+ plotWidth ? Math.max(
1635
+ 2,
1636
+ Math.min(
1637
+ plotWidth < NARROW_PLOT_WIDTH ? NARROW_TIME_AXIS_MAX_LABELS : TIME_AXIS_MAX_LABELS,
1638
+ Math.floor(plotWidth / TIME_LABEL_WIDTH)
1639
+ )
1640
+ ) : void 0
2335
1641
  );
2336
1642
  const plainStep = (() => {
2337
1643
  if (kind !== "line" || startEndOnly || timeStep !== null || !plotWidth || labels.length < 3) return 1;
@@ -2351,7 +1657,8 @@ function buildCartesianOption(cfg) {
2351
1657
  const shareHighlight = percent && kind === "area";
2352
1658
  const picked = highlight !== "auto" || mainIdx.length === 0 || percent && !shareHighlight ? [] : shareHighlight ? categories.length <= 2 ? pickShareHighlightPoints(values[0] ?? []) : [] : stackTotals ? pickHighlightPoints(stackTotals) : mainIdx.length <= 2 ? pickHighlightPoints(values[highlightSeries] ?? []) : [];
2353
1659
  const pointGap = plotWidth && labels.length > 1 ? plotWidth / (kind === "bar" ? labels.length : labels.length - 1) : null;
2354
- const highlightPoints = picked.length === 2 && pointGap !== null && Math.abs(picked[1].index - picked[0].index) * pointGap < HIGHLIGHT_LABEL_WIDTH ? [picked[1]] : picked;
1660
+ const latestOnly = cfg.highlight === void 0 && !shareHighlight && picked.length === 2;
1661
+ const highlightPoints = latestOnly ? [picked[1]] : picked.length === 2 && pointGap !== null && Math.abs(picked[1].index - picked[0].index) * pointGap < HIGHLIGHT_LABEL_WIDTH ? [picked[1]] : picked;
2355
1662
  const boundaryIndex = kind !== "bar" && !percent && cfg.forecast && cfg.forecast.data.length > 0 ? lastActual : -1;
2356
1663
  const edgeAlign = (i) => horizontalBars || labels.length < 2 ? void 0 : i === boundaryIndex && i !== last ? { align: "right", offset: [-6, 0] } : i === last ? { align: "right", ...kind === "bar" ? { offset: [8, 0] } : {} } : i === 0 ? { align: "left", ...kind === "bar" ? { offset: [-8, 0] } : {} } : void 0;
2357
1664
  const perBarTarget = kind === "bar" && Boolean(targetKey);
@@ -2500,6 +1807,8 @@ function buildCartesianOption(cfg) {
2500
1807
  // 100% stacked: the top band's upper edge is the 100% line, not a value — drawn, it reads as「this band = 100%」.
2501
1808
  lineStyle: percent && c === categories.length - 1 ? { width: 0, color, opacity: 0 } : { width: 2, color, opacity: dimSeries ? DIMMED : 1 },
2502
1809
  itemStyle: { color, opacity: dimSeries ? DIMMED : 1 },
1810
+ // Hovering a series fades the others (not for a stack, where the bands read together).
1811
+ emphasis: stacked ? void 0 : { focus: "series" },
2503
1812
  areaStyle: areaStyle && dimSeries ? { ...areaStyle, opacity: DIMMED * 0.3 } : areaStyle,
2504
1813
  markPoint: markPointFor(c, color),
2505
1814
  markLine: void 0,
@@ -2892,7 +2201,8 @@ function buildCartesianOption(cfg) {
2892
2201
  legend: {
2893
2202
  show: showLegend,
2894
2203
  top: 0,
2895
- right: reserveActions ? ACTIONS_RESERVE : 0,
2204
+ // Narrow: left-aligned and wrapping above the plot, so nothing is cut off at the right edge.
2205
+ ...plotWidth !== void 0 && plotWidth < NARROW_PLOT_WIDTH ? { left: 0, right: 0 } : { right: reserveActions ? ACTIONS_RESERVE : 0 },
2896
2206
  // Plain wraps onto a second line at narrow widths instead of hiding items behind arrows.
2897
2207
  type: "plain",
2898
2208
  icon: "circle",
@@ -2942,7 +2252,11 @@ function buildCartesianOption(cfg) {
2942
2252
  };
2943
2253
  };
2944
2254
  const shares = percent ? cartesianSeriesValues(i <= lastActual ? [row] : [], categories, "percent") : null;
2945
- for (const p of list) {
2255
+ const legendRank = (p) => {
2256
+ const at = categories.indexOf(p.seriesName ?? "");
2257
+ return at === -1 ? categories.length : at;
2258
+ };
2259
+ for (const p of [...list].sort((a, b) => legendRank(a) - legendRank(b))) {
2946
2260
  const color = typeof p.color === "string" ? p.color : "currentColor";
2947
2261
  if (p.seriesId === FORECAST_SERIES_ID) {
2948
2262
  if (i > lastActual) rows.push({ name: p.seriesName ?? forecastLabel, color, value: forecastValues[i] ?? null });
@@ -3210,8 +2524,7 @@ function AreaChartImpl({
3210
2524
  className,
3211
2525
  ...rest
3212
2526
  }, ref) {
3213
- const tokens = useChartTokens();
3214
- const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
2527
+ const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
3215
2528
  const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format2), [valueFormatter, format2]);
3216
2529
  const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format2), [valueFormatter, format2]);
3217
2530
  const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format2), [valueFormatter, format2]);
@@ -3393,8 +2706,7 @@ function BarChartImpl({
3393
2706
  className,
3394
2707
  ...rest
3395
2708
  }, ref) {
3396
- const tokens = useChartTokens();
3397
- const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
2709
+ const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
3398
2710
  const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format2), [valueFormatter, format2]);
3399
2711
  const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format2), [valueFormatter, format2]);
3400
2712
  const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format2), [valueFormatter, format2]);
@@ -3529,8 +2841,8 @@ function BarChartImpl({
3529
2841
  }
3530
2842
  );
3531
2843
  }
3532
- var BarChart2 = forwardRef(BarChartImpl);
3533
- BarChart2.displayName = "BarChart";
2844
+ var BarChart = forwardRef(BarChartImpl);
2845
+ BarChart.displayName = "BarChart";
3534
2846
  var NO_ROWS3 = [];
3535
2847
  function LineChartImpl({
3536
2848
  data = NO_ROWS3,
@@ -3578,8 +2890,7 @@ function LineChartImpl({
3578
2890
  className,
3579
2891
  ...rest
3580
2892
  }, ref) {
3581
- const tokens = useChartTokens();
3582
- const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
2893
+ const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
3583
2894
  const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format2), [valueFormatter, format2]);
3584
2895
  const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format2), [valueFormatter, format2]);
3585
2896
  const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format2), [valueFormatter, format2]);
@@ -3716,8 +3027,8 @@ function LineChartImpl({
3716
3027
  }
3717
3028
  );
3718
3029
  }
3719
- var LineChart2 = forwardRef(LineChartImpl);
3720
- LineChart2.displayName = "LineChart";
3030
+ var LineChart = forwardRef(LineChartImpl);
3031
+ LineChart.displayName = "LineChart";
3721
3032
  function useElementWidth() {
3722
3033
  const [node, setNode] = useState(null);
3723
3034
  const [width, setWidth] = useState(null);
@@ -3767,7 +3078,7 @@ function DonutChartImpl({
3767
3078
  const maxSlices = donutOptions?.maxSlices;
3768
3079
  const showLegend = donutOptions?.showLegend ?? true;
3769
3080
  const valueFormatter = useMemo(() => resolveValueFormatter(valueFormatterProp, format2), [valueFormatterProp, format2]);
3770
- const tokens = useChartTokens();
3081
+ const { ref: frameRef, tokens } = useChartSurface(ref);
3771
3082
  const slices = useMemo(
3772
3083
  () => donutSlices(data, { index: labelKey, value: valueKey, colors, maxSlices, otherColor: CHART_OTHER_COLOR }),
3773
3084
  [data, labelKey, valueKey, colors, maxSlices]
@@ -3833,7 +3144,7 @@ function DonutChartImpl({
3833
3144
  ChartFrame,
3834
3145
  {
3835
3146
  ...chartRootProps(rest),
3836
- ref,
3147
+ ref: frameRef,
3837
3148
  title,
3838
3149
  summary: resolvedSummary,
3839
3150
  isLoading: isLoading ?? loading ?? false,
@@ -4149,8 +3460,14 @@ function blockColorToCss(color) {
4149
3460
  }
4150
3461
  var NO_ROWS7 = [];
4151
3462
  var Tracker = forwardRef(function Tracker2({ data = NO_ROWS7, defaultColor, hoverEffect = true, className, ...props }, ref) {
3463
+ const containerRef = useRef(null);
3464
+ const setRef = useCallback((node) => {
3465
+ containerRef.current = node;
3466
+ if (typeof ref === "function") return ref(node);
3467
+ if (ref) ref.current = node;
3468
+ }, [ref]);
4152
3469
  const fallback = defaultColor ? blockColorToCss(defaultColor) : DEFAULT_BLOCK_COLOR;
4153
- return /* @__PURE__ */ jsx("div", { ref, "data-slot": "tracker", className: cn("flex h-6 w-full gap-0.5", className), ...props, children: data.map((block, i) => {
3470
+ return /* @__PURE__ */ jsx("div", { ref: setRef, "data-slot": "tracker", className: cn("flex h-6 w-full gap-0.5", className), ...props, children: data.map((block, i) => {
4154
3471
  const blockClass = cn(
4155
3472
  "h-full min-w-0 flex-1 rounded-[2px]",
4156
3473
  hoverEffect && "transition-opacity hover:opacity-60 motion-reduce:transition-none"
@@ -4164,7 +3481,7 @@ var Tracker = forwardRef(function Tracker2({ data = NO_ROWS7, defaultColor, hove
4164
3481
  render: /* @__PURE__ */ jsx("div", { "data-slot": "tracker-block", role: "img", tabIndex: 0, "aria-label": block.tooltip, className: blockClass, style })
4165
3482
  }
4166
3483
  ),
4167
- /* @__PURE__ */ jsx(TooltipContent, { children: block.tooltip })
3484
+ /* @__PURE__ */ jsx(TooltipContent, { container: containerRef, children: block.tooltip })
4168
3485
  ] }, block.key ?? i) : /* @__PURE__ */ jsx("div", { "data-slot": "tracker-block", className: blockClass, style }, block.key ?? i);
4169
3486
  }) });
4170
3487
  });
@@ -4541,8 +3858,7 @@ function WaterfallChartImpl({
4541
3858
  ...rest
4542
3859
  }, ref) {
4543
3860
  const valueKey = categories[0] ?? "";
4544
- const tokens = useChartTokens();
4545
- const { ref: frameRef, width: plotWidth } = useChartSurface(ref, tokens);
3861
+ const { ref: frameRef, width: plotWidth, tokens } = useChartSurface(ref);
4546
3862
  const valueFormatter = useMemo(() => resolveValueFormatter(valueFormatterProp, format2), [valueFormatterProp, format2]);
4547
3863
  const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatterProp, format2), [valueFormatterProp, format2]);
4548
3864
  const steps = useMemo(() => waterfallSteps(data, { index, value: valueKey, totals, mode }), [data, index, valueKey, totals, mode]);
@@ -4941,8 +4257,7 @@ function ScatterChartImpl({
4941
4257
  className,
4942
4258
  ...rest
4943
4259
  }, ref) {
4944
- const tokens = useChartTokens();
4945
- const { ref: frameRef, width: plotWidth } = useChartSurface(ref, tokens);
4260
+ const { ref: frameRef, width: plotWidth, tokens } = useChartSurface(ref);
4946
4261
  const formatters = useMemo(
4947
4262
  () => ({
4948
4263
  x: resolveValueFormatter(valueFormatter, xFormat ?? format2),
@@ -5646,8 +4961,7 @@ function HeatmapImpl({
5646
4961
  ariaLabel,
5647
4962
  ...rest
5648
4963
  }, ref) {
5649
- const tokens = useChartTokens();
5650
- const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
4964
+ const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
5651
4965
  const formatter = useMemo(() => resolveValueFormatter(valueFormatter, format2 ?? "number"), [valueFormatter, format2]);
5652
4966
  const model = useMemo(
5653
4967
  () => buildHeatmapModel({ data, x, y, value, xLabels, yLabels, flag, scale, minValue, maxValue }),
@@ -5716,149 +5030,6 @@ function HeatmapLegend({
5716
5030
  }
5717
5031
  var Heatmap = forwardRef(HeatmapImpl);
5718
5032
  Heatmap.displayName = "Heatmap";
5719
- var VB_WIDTH = 100;
5720
- function normalizeData(values, height, vPad = 2) {
5721
- const min = Math.min(...values);
5722
- const max = Math.max(...values);
5723
- const range = max - min;
5724
- const drawHeight = height - vPad * 2;
5725
- if (range === 0) return values.map(() => vPad + drawHeight / 2);
5726
- return values.map((v) => height - vPad - (v - min) / range * drawHeight);
5727
- }
5728
- function buildLinePath(ys) {
5729
- if (ys.length === 0) return "";
5730
- const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
5731
- return ys.map((y, i) => `${i === 0 ? "M" : "L"}${(i * step).toFixed(2)},${y.toFixed(2)}`).join(" ");
5732
- }
5733
- function buildAreaPath(ys, height) {
5734
- if (ys.length === 0) return "";
5735
- const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
5736
- const lastX = ((ys.length - 1) * step).toFixed(2);
5737
- return `${buildLinePath(ys)} L${lastX},${height} L0,${height} Z`;
5738
- }
5739
- function sparklineHighlightPoints(values) {
5740
- if (values.length === 0) return [];
5741
- const last = values.length - 1;
5742
- const points = [{ kind: "latest", index: last }];
5743
- let maxI = 0;
5744
- let minI = 0;
5745
- let max = values[0];
5746
- let min = max;
5747
- values.forEach((v, i) => {
5748
- if (v >= max) [max, maxI] = [v, i];
5749
- if (v <= min) [min, minI] = [v, i];
5750
- });
5751
- const latest = values[last];
5752
- if (max === min) return points;
5753
- if (max !== latest) points.push({ kind: "max", index: maxI });
5754
- if (min !== latest) points.push({ kind: "min", index: minI });
5755
- return points;
5756
- }
5757
- function buildBarRects(ys, height, gap = 1) {
5758
- const barW = Math.max(1, VB_WIDTH / ys.length - gap);
5759
- return ys.map((y, i) => ({ x: i * (barW + gap), y, w: barW, h: height - y }));
5760
- }
5761
- var NO_ROWS12 = [];
5762
- var Sparkline = forwardRef(function Sparkline2({
5763
- data = NO_ROWS12,
5764
- variant = "line",
5765
- height = 40,
5766
- color = "text-chart-1",
5767
- area = false,
5768
- animate = false,
5769
- highlight = "auto",
5770
- "aria-label": ariaLabel,
5771
- className,
5772
- ...props
5773
- }, ref) {
5774
- const [mounted, setMounted] = useState(false);
5775
- useEffect(() => {
5776
- if (animate) setMounted(true);
5777
- }, [animate]);
5778
- if (data.length === 0) return null;
5779
- const values = data.map((d) => d.value);
5780
- const ys = normalizeData(values, height);
5781
- const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
5782
- const points = variant !== "line" ? [] : highlight === "auto" ? sparklineHighlightPoints(values) : highlight === "latest" ? [{ kind: "latest", index: values.length - 1 }] : [];
5783
- return /* @__PURE__ */ jsxs(
5784
- "svg",
5785
- {
5786
- ref,
5787
- "data-slot": "sparkline",
5788
- viewBox: `0 0 ${VB_WIDTH} ${height}`,
5789
- preserveAspectRatio: "none",
5790
- width: "100%",
5791
- height,
5792
- role: ariaLabel ? "img" : void 0,
5793
- "aria-label": ariaLabel,
5794
- "aria-hidden": ariaLabel ? void 0 : true,
5795
- className: cn("overflow-visible", className),
5796
- ...props,
5797
- children: [
5798
- variant === "line" && /* @__PURE__ */ jsxs(Fragment, { children: [
5799
- area && /* @__PURE__ */ jsx(
5800
- "path",
5801
- {
5802
- d: buildAreaPath(ys, height),
5803
- strokeWidth: 0,
5804
- className: cn("fill-current opacity-15", color)
5805
- }
5806
- ),
5807
- /* @__PURE__ */ jsx(
5808
- "path",
5809
- {
5810
- d: buildLinePath(ys),
5811
- fill: "none",
5812
- strokeWidth: 1.5,
5813
- strokeLinecap: "round",
5814
- strokeLinejoin: "round",
5815
- vectorEffect: "non-scaling-stroke",
5816
- pathLength: animate ? 1 : void 0,
5817
- strokeDasharray: animate ? 1 : void 0,
5818
- strokeDashoffset: animate ? mounted ? 0 : 1 : void 0,
5819
- className: cn("stroke-current", animate && "motion-reduce:transition-none!", color),
5820
- style: animate ? { transition: "stroke-dashoffset 0.6s ease-in-out" } : void 0
5821
- }
5822
- ),
5823
- points.map((p) => {
5824
- const x = (p.index * step).toFixed(2);
5825
- const y = (ys[p.index] ?? 0).toFixed(2);
5826
- return /* @__PURE__ */ jsx(
5827
- "path",
5828
- {
5829
- "data-slot": "sparkline-point",
5830
- "data-point": p.kind,
5831
- d: `M${x},${y} L${x},${y}`,
5832
- fill: "none",
5833
- strokeWidth: p.kind === "latest" ? 5 : 4,
5834
- strokeLinecap: "round",
5835
- vectorEffect: "non-scaling-stroke",
5836
- className: cn("stroke-current", p.kind === "latest" ? color : "text-muted-foreground")
5837
- },
5838
- p.kind
5839
- );
5840
- })
5841
- ] }),
5842
- variant === "bar" && buildBarRects(ys, height).map((rect, i) => /* @__PURE__ */ jsx(
5843
- "rect",
5844
- {
5845
- x: rect.x,
5846
- y: animate ? mounted ? rect.y : height : rect.y,
5847
- width: rect.w,
5848
- height: animate ? mounted ? rect.h : 0 : rect.h,
5849
- rx: 0.5,
5850
- className: cn("fill-current", animate && "motion-reduce:transition-none!", color),
5851
- style: animate ? {
5852
- transition: `height 0.4s ease-out ${i * 0.02}s, y 0.4s ease-out ${i * 0.02}s`
5853
- } : void 0
5854
- },
5855
- i
5856
- ))
5857
- ]
5858
- }
5859
- );
5860
- });
5861
- Sparkline.displayName = "Sparkline";
5862
5033
  function resolveFormat(format2, row) {
5863
5034
  return typeof format2 === "function" ? format2(row) : format2;
5864
5035
  }
@@ -5923,10 +5094,10 @@ function useDataTable() {
5923
5094
  if (!ctx) throw new Error("useDataTable must be used inside <DataTable>");
5924
5095
  return ctx;
5925
5096
  }
5926
- var NO_ROWS13 = [];
5097
+ var NO_ROWS12 = [];
5927
5098
  function DataTable({
5928
- columns = NO_ROWS13,
5929
- data = NO_ROWS13,
5099
+ columns = NO_ROWS12,
5100
+ data = NO_ROWS12,
5930
5101
  enableSorting = true,
5931
5102
  sorting: sortingProp,
5932
5103
  onSortingChange,
@@ -7362,7 +6533,7 @@ var deltaVariants = cva(
7362
6533
  {
7363
6534
  variants: {
7364
6535
  variant: {
7365
- badge: "h-5 rounded-4xl px-2 py-0.5 text-xs font-semibold [&>svg]:size-3",
6536
+ badge: "h-5 rounded-md border px-2 py-0.5 text-xs font-medium [&>svg]:size-3",
7366
6537
  inline: "text-sm [&>svg]:size-3.5"
7367
6538
  },
7368
6539
  sentiment: {
@@ -7372,9 +6543,9 @@ var deltaVariants = cva(
7372
6543
  }
7373
6544
  },
7374
6545
  compoundVariants: [
7375
- { variant: "badge", sentiment: "positive", className: "bg-positive-subtle" },
7376
- { variant: "badge", sentiment: "negative", className: "bg-negative-subtle" },
7377
- { variant: "badge", sentiment: "neutral", className: "bg-neutral-subtle" }
6546
+ { variant: "badge", sentiment: "positive", className: "border-positive/20 bg-positive-subtle dark:border-positive/25" },
6547
+ { variant: "badge", sentiment: "negative", className: "border-negative/20 bg-negative-subtle dark:border-negative/25" },
6548
+ { variant: "badge", sentiment: "neutral", className: "border-neutral/20 bg-neutral-subtle dark:border-neutral/25" }
7378
6549
  ],
7379
6550
  defaultVariants: {
7380
6551
  variant: "badge",
@@ -7395,6 +6566,7 @@ var Delta = forwardRef(
7395
6566
  ({
7396
6567
  value,
7397
6568
  comparison,
6569
+ betterWhen,
7398
6570
  polarity,
7399
6571
  neutralBand,
7400
6572
  format: format2,
@@ -7407,7 +6579,7 @@ var Delta = forwardRef(
7407
6579
  ...props
7408
6580
  }, ref) => {
7409
6581
  if (!comparison) return null;
7410
- const result = computeComparison(value, comparison, { polarity, neutralBand });
6582
+ const result = computeComparison(value, comparison, { polarity: betterWhen ? betterWhen === "down" ? "lower-is-better" : "higher-is-better" : polarity, neutralBand });
7411
6583
  const display = change ?? defaultChangeDisplay(format2);
7412
6584
  const formatDigits = typeof format2 === "object" && format2 !== null && "digits" in format2 ? format2.digits : void 0;
7413
6585
  const changeDigits = display === "points" ? digits ?? formatDigits : digits;
@@ -7443,6 +6615,9 @@ var SPARKLINE_MIN_POINTS = 6;
7443
6615
  var SPARKLINE_HEIGHT = 32;
7444
6616
  var DELTA_PLACEMENT = "col-start-1 row-span-1 row-start-3 justify-self-start @[288px]/card:col-start-2 @[288px]/card:row-span-2 @[288px]/card:row-start-1 @[288px]/card:justify-self-end";
7445
6617
  var HEADER_CLASS = "@container/card pb-(--card-spacing)";
6618
+ var LONG_VALUE_CHARS = 10;
6619
+ var DELTA_UNDER_PLACEMENT = "col-start-1 row-span-1 row-start-3 justify-self-start";
6620
+ var KPI_FOOTER_CLASS = "flex-col items-start gap-2 rounded-none border-t-0 bg-transparent pt-0 text-sm";
7446
6621
  var PLACEHOLDER = /\{(\w+)\}/g;
7447
6622
  var isJapanese2 = (locale) => locale.toLowerCase().startsWith("ja");
7448
6623
  var isMissing = (v) => v === null || v === void 0 || v === "";
@@ -7479,6 +6654,9 @@ function warnShallowSummary(template) {
7479
6654
  `[KpiCard] summary="${template}" only repeats the delta badge and the previous actual. Say one fact beyond the comparison \u2014 composition, target, record or rate (e.g. "{label}\u306F\u76EE\u6A19\u306E {achievement} \u307E\u3067\u6765\u3066\u3044\u307E\u3059\u3002").`
7480
6655
  );
7481
6656
  }
6657
+ function digitGroups(text) {
6658
+ return text.match(/[^,,]*[,,]|[^,,]+$/g) ?? [text];
6659
+ }
7482
6660
  function KpiCard({
7483
6661
  label: label2,
7484
6662
  value,
@@ -7487,7 +6665,8 @@ function KpiCard({
7487
6665
  comparison: comparisonProp,
7488
6666
  comparisons,
7489
6667
  provisional,
7490
- polarity,
6668
+ betterWhen,
6669
+ polarity: polarityProp,
7491
6670
  change,
7492
6671
  neutralBand,
7493
6672
  showPrevious = true,
@@ -7514,6 +6693,7 @@ function KpiCard({
7514
6693
  const isProvisional = provisional !== void 0 && provisional !== false;
7515
6694
  const provisionalLabel = typeof provisional === "object" && provisional.label ? provisional.label : "\u901F\u5831";
7516
6695
  const sample = useSampleMark();
6696
+ const polarity = betterWhen ? betterWhen === "down" ? "lower-is-better" : "higher-is-better" : polarityProp;
7517
6697
  const neutral = polarity === "neutral";
7518
6698
  const hasPrevious = comparison !== void 0 && showPrevious;
7519
6699
  const stacked = allComparisons.length > 1;
@@ -7565,7 +6745,7 @@ function KpiCard({
7565
6745
  /* @__PURE__ */ jsx(Skeleton, { "aria-hidden": "true", className: "h-5 w-3/5" })
7566
6746
  ] }) : null
7567
6747
  ] }),
7568
- (summary || record || hasTarget && !targetBar || sourceParts.length > 0 || hasUpdated || showSparkline) && /* @__PURE__ */ jsxs(CardFooter, { className: "flex-col items-start gap-1.5 text-sm", children: [
6748
+ (summary || record || hasTarget && !targetBar || sourceParts.length > 0 || hasUpdated || showSparkline) && /* @__PURE__ */ jsxs(CardFooter, { className: KPI_FOOTER_CLASS, children: [
7569
6749
  summary && /* @__PURE__ */ jsx(Skeleton, { "aria-hidden": "true", className: "h-5 w-4/5" }),
7570
6750
  record && /* @__PURE__ */ jsx(Skeleton, { "aria-hidden": "true", className: "h-5 w-28 rounded-4xl" }),
7571
6751
  hasTarget && !targetBar && /* @__PURE__ */ jsx(Skeleton, { "aria-hidden": "true", className: "h-5 w-3/5" }),
@@ -7646,27 +6826,32 @@ function KpiCard({
7646
6826
  },
7647
6827
  i
7648
6828
  ));
6829
+ const valueText = fmt(value);
6830
+ const longValue = valueText.length > LONG_VALUE_CHARS;
7649
6831
  return /* @__PURE__ */ jsxs(Card, { "data-slot": "kpi-card", size, className: cardClass, ...props, children: [
7650
6832
  /* @__PURE__ */ jsxs(CardHeader, { className: HEADER_CLASS, children: [
7651
- /* @__PURE__ */ jsx(CardDescription, { "data-slot": "kpi-card-label", title: label2, className: "col-start-1 min-w-0 truncate text-[13px] font-medium text-muted-foreground", children: label2 }),
6833
+ /* @__PURE__ */ jsx(CardDescription, { "data-slot": "kpi-card-label", title: label2, className: "col-start-1 min-w-0 truncate text-[13px] leading-snug font-medium text-muted-foreground", children: label2 }),
7652
6834
  /* @__PURE__ */ jsxs(
7653
6835
  CardTitle,
7654
6836
  {
7655
6837
  "data-slot": "kpi-card-value",
7656
- title: fmt(value),
6838
+ title: valueText,
7657
6839
  className: cn(
7658
- "col-start-1 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 font-semibold tracking-tight tabular-nums",
6840
+ "col-start-1 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 leading-none font-semibold tracking-tight tabular-nums",
7659
6841
  // Fixed size: the step follows the card width only, never the length of the value.
7660
6842
  valueSize
7661
6843
  ),
7662
6844
  children: [
7663
- /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: fmt(value) }),
6845
+ /* @__PURE__ */ jsx("span", { "data-slot": "kpi-card-value-text", className: longValue ? "min-w-0 break-words" : "whitespace-nowrap", children: longValue ? digitGroups(valueText).map((group, i) => /* @__PURE__ */ jsxs("span", { className: "whitespace-nowrap", children: [
6846
+ group,
6847
+ /* @__PURE__ */ jsx("wbr", {})
6848
+ ] }, i)) : valueText }),
7664
6849
  isProvisional && /* @__PURE__ */ jsx(Badge, { "data-slot": "kpi-card-provisional", variant: "outline", className: "align-middle", children: provisionalLabel }),
7665
6850
  sample && /* @__PURE__ */ jsx(SampleBadge, { label: sample.label })
7666
6851
  ]
7667
6852
  }
7668
6853
  ),
7669
- comparison && (stacked ? /* @__PURE__ */ jsx("div", { "data-slot": "kpi-card-comparisons", className: "flex flex-wrap items-center gap-1", children: deltas }) : /* @__PURE__ */ jsx(CardAction, { className: DELTA_PLACEMENT, children: deltas })),
6854
+ comparison && (stacked ? /* @__PURE__ */ jsx("div", { "data-slot": "kpi-card-comparisons", className: "flex flex-wrap items-center gap-1", children: deltas }) : /* @__PURE__ */ jsx(CardAction, { className: longValue ? DELTA_UNDER_PLACEMENT : DELTA_PLACEMENT, children: deltas })),
7670
6855
  hasPrevious && comparison && /* @__PURE__ */ jsx("div", { "data-slot": "kpi-card-previous", className: "col-span-full text-sm text-muted-foreground tabular-nums", children: result?.previous != null ? `${baseline} ${fmt(result.previous)}` : `${baseline}\u306E\u5B9F\u7E3E\u306A\u3057` }),
7671
6856
  bar && progress && /* @__PURE__ */ jsxs("div", { "data-slot": "kpi-card-target-progress", className: "col-span-full mt-1 flex min-w-0 flex-col gap-1.5", children: [
7672
6857
  /* @__PURE__ */ jsxs(
@@ -7719,8 +6904,8 @@ function KpiCard({
7719
6904
  )
7720
6905
  ] })
7721
6906
  ] }),
7722
- hasFooter && /* @__PURE__ */ jsxs(CardFooter, { className: "flex-col items-start gap-1.5 text-sm", children: [
7723
- summaryText && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-summary", title: summaryText, className: "line-clamp-2 font-medium tabular-nums", children: summaryText }),
6907
+ hasFooter && /* @__PURE__ */ jsxs(CardFooter, { className: KPI_FOOTER_CLASS, children: [
6908
+ summaryText && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-summary", title: summaryText, className: "line-clamp-2 text-sm leading-relaxed text-muted-foreground tabular-nums", children: summaryText }),
7724
6909
  record && /* @__PURE__ */ jsx(Badge, { "data-slot": "kpi-card-record", variant: "outline", children: record.label }),
7725
6910
  targetText && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-target", className: "text-muted-foreground tabular-nums", children: targetText }),
7726
6911
  sourceParts.length > 0 && /* @__PURE__ */ jsx(
@@ -7728,11 +6913,11 @@ function KpiCard({
7728
6913
  {
7729
6914
  "data-slot": "kpi-card-source",
7730
6915
  title: sourceParts.join("\u30FB"),
7731
- className: "line-clamp-2 w-full text-xs text-muted-foreground tabular-nums",
6916
+ className: "line-clamp-2 w-full text-xs leading-normal text-muted-foreground tabular-nums",
7732
6917
  children: sourceParts.join("\u30FB")
7733
6918
  }
7734
6919
  ),
7735
- hasUpdated && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-updated", className: "text-xs text-muted-foreground", children: updatedAtText(updatedAt, updatedAtDisplay, locale, now, timeZone) }),
6920
+ hasUpdated && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-updated", className: "text-xs leading-normal text-muted-foreground", children: updatedAtText(updatedAt, updatedAtDisplay, locale, now, timeZone) }),
7736
6921
  showSparkline && // mt-auto: the footers of a row are as tall as the tallest, so the sparklines share one bottom edge.
7737
6922
  /* @__PURE__ */ jsx("div", { "data-slot": "kpi-card-history", className: "mt-auto w-full pt-2 text-chart-1", children: /* @__PURE__ */ jsx(
7738
6923
  Sparkline,
@@ -7756,8 +6941,8 @@ function updatedAtText(updatedAt, display, locale, now, timeZone) {
7756
6941
  var trendIndicatorVariants = cva("inline-flex items-center gap-0.5 text-sm font-medium", {
7757
6942
  variants: {
7758
6943
  sentiment: {
7759
- positive: "text-chart-1",
7760
- negative: "text-primary",
6944
+ positive: "text-positive",
6945
+ negative: "text-negative",
7761
6946
  neutral: "text-muted-foreground"
7762
6947
  }
7763
6948
  },
@@ -7817,11 +7002,11 @@ var legacyColorTones = {
7817
7002
  blue: "info"
7818
7003
  };
7819
7004
  var toneStyles = {
7820
- positive: { dot: "bg-positive", bg: "bg-positive-subtle", text: "text-positive" },
7821
- negative: { dot: "bg-negative", bg: "bg-negative-subtle", text: "text-negative" },
7822
- warning: { dot: "bg-warning", bg: "bg-warning-subtle", text: "text-warning" },
7823
- info: { dot: "bg-info", bg: "bg-info-subtle", text: "text-info" },
7824
- neutral: { dot: "bg-neutral", bg: "bg-neutral-subtle", text: "text-neutral" }
7005
+ positive: { dot: "bg-positive", bg: "bg-positive-subtle", text: "text-positive", border: "border-positive/20 dark:border-positive/25" },
7006
+ negative: { dot: "bg-negative", bg: "bg-negative-subtle", text: "text-negative", border: "border-negative/20 dark:border-negative/25" },
7007
+ warning: { dot: "bg-warning", bg: "bg-warning-subtle", text: "text-warning", border: "border-warning/20 dark:border-warning/25" },
7008
+ info: { dot: "bg-info", bg: "bg-info-subtle", text: "text-info", border: "border-info/20 dark:border-info/25" },
7009
+ neutral: { dot: "bg-neutral", bg: "bg-neutral-subtle", text: "text-neutral", border: "border-neutral/20 dark:border-neutral/25" }
7825
7010
  };
7826
7011
  var resolveTone = (color) => {
7827
7012
  if (color === void 0) return "neutral";
@@ -7838,10 +7023,10 @@ var StatusBadge = forwardRef(function StatusBadge2({ status, label: label2, colo
7838
7023
  ref,
7839
7024
  "data-slot": "status-badge",
7840
7025
  variant: "outline",
7841
- className: cn("gap-1.5 border-transparent", style.bg, style.text, className),
7026
+ className: cn("gap-1.5 rounded-md", style.border, style.bg, style.text, className),
7842
7027
  "aria-label": displayLabel,
7843
7028
  children: [
7844
- /* @__PURE__ */ jsx("span", { className: cn("inline-block size-2 rounded-full", style.dot), "aria-hidden": "true" }),
7029
+ /* @__PURE__ */ jsx("span", { className: cn("inline-block size-1.5 rounded-full", style.dot), "aria-hidden": "true" }),
7845
7030
  displayLabel
7846
7031
  ]
7847
7032
  }
@@ -7861,6 +7046,6 @@ var Placeholder = forwardRef(function Placeholder2({ className, ...props }, ref)
7861
7046
  });
7862
7047
  Placeholder.displayName = "Placeholder";
7863
7048
 
7864
- export { AppShell, AreaChart, BarChart2 as BarChart, BarList, COMPARISON_LABELS, CategoryBar, ChartFrame, DEFAULT_LOCALE, DEFAULT_SAMPLE_LABEL, DELTA_NOT_COMPARABLE, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTableExport, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, Delta, DonutChart, EChart, EMPTY_VALUE, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, Heatmap, KpiCard, Legend, LineChart2 as LineChart, MINUS_SIGN, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, ProgressCircle, RECORD_MIN_POINTS, SampleBadge, SampleClaim, SampleData, ScatterChart, SearchableSelect, SectionHeader, SegmentedControl, Sparkline, StatusBadge, Tracker, TrendIndicator, UpdatedAt, WaterfallChart, comparisonBaseline, comparisonLabel, computeComparison, computeTargetProgress, defaultChangeDisplay, defaultPresets, deltaVariants, detectRecord, fillKpiTemplate, flattenOptions, formatChange, formatChangeAmount, formatDate, formatDateRange, formatDatesInText, formatDelta, formatKind, formatPoints, formatRelativeTime, formatValue, funnelStepsVariants, inferPeriodGrain, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, tableToCsv, toCsv, toValueFormatter, toneForValue, useDataTable, useResolvedChartColors, useSampleMark };
7865
- //# sourceMappingURL=chunk-WRSX2MDK.js.map
7866
- //# sourceMappingURL=chunk-WRSX2MDK.js.map
7049
+ export { AppShell, AreaChart, BarChart, BarList, COMPARISON_LABELS, CategoryBar, ChartFrame, DEFAULT_SAMPLE_LABEL, DELTA_NOT_COMPARABLE, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTableExport, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, Delta, DonutChart, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, Heatmap, KpiCard, Legend, LineChart, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, ProgressCircle, RECORD_MIN_POINTS, SampleBadge, SampleClaim, SampleData, ScatterChart, SearchableSelect, SectionHeader, SegmentedControl, StatusBadge, Tracker, TrendIndicator, UpdatedAt, WaterfallChart, comparisonBaseline, comparisonLabel, computeComparison, computeTargetProgress, defaultChangeDisplay, defaultPresets, deltaVariants, detectRecord, fillKpiTemplate, flattenOptions, formatChange, formatChangeAmount, formatRelativeTime, funnelStepsVariants, inferPeriodGrain, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, tableToCsv, toCsv, toneForValue, useDataTable, useSampleMark };
7050
+ //# sourceMappingURL=chunk-QOXXOFGL.js.map
7051
+ //# sourceMappingURL=chunk-QOXXOFGL.js.map