@columenlabs/lumen-ui 0.0.0-stage → 0.2.1

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 (301) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +12 -0
  3. package/README.md +4 -2
  4. package/dist/add-column.d.ts +23 -0
  5. package/dist/add-column.js +62 -0
  6. package/dist/api-fetch.d.ts +9 -0
  7. package/dist/api-fetch.js +60 -0
  8. package/dist/app-switcher.d.ts +21 -0
  9. package/dist/app-switcher.js +12 -0
  10. package/dist/app-views.d.ts +18 -0
  11. package/dist/app-views.js +41 -0
  12. package/dist/assistant-context.d.ts +72 -0
  13. package/dist/assistant-context.js +30 -0
  14. package/dist/assistant-panel.d.ts +58 -0
  15. package/dist/assistant-panel.js +244 -0
  16. package/dist/assistant-screen.d.ts +124 -0
  17. package/dist/assistant-screen.js +252 -0
  18. package/dist/card-switch.d.ts +16 -0
  19. package/dist/card-switch.js +16 -0
  20. package/dist/color-dot.d.ts +14 -0
  21. package/dist/color-dot.js +19 -0
  22. package/dist/confirm.d.ts +18 -0
  23. package/dist/confirm.js +5 -0
  24. package/dist/connections.d.ts +45 -0
  25. package/dist/connections.js +275 -0
  26. package/dist/coverage-calendar-map.d.ts +27 -0
  27. package/dist/coverage-calendar-map.js +84 -0
  28. package/dist/coverage-cells.d.ts +55 -0
  29. package/dist/coverage-cells.js +85 -0
  30. package/dist/coverage-map.d.ts +112 -0
  31. package/dist/coverage-map.js +428 -0
  32. package/dist/details-table.d.ts +20 -0
  33. package/dist/details-table.js +13 -0
  34. package/dist/drawer-section.d.ts +27 -0
  35. package/dist/drawer-section.js +23 -0
  36. package/dist/floating-head.d.ts +2 -0
  37. package/dist/floating-head.js +57 -0
  38. package/dist/fold.d.ts +16 -0
  39. package/dist/fold.js +70 -0
  40. package/dist/form-issues.d.ts +32 -0
  41. package/dist/form-issues.js +60 -0
  42. package/dist/formula-input.d.ts +17 -0
  43. package/dist/formula-input.js +104 -0
  44. package/dist/frame-script.d.ts +7 -0
  45. package/dist/frame-script.js +103 -0
  46. package/dist/freshness.d.ts +24 -0
  47. package/dist/freshness.js +99 -0
  48. package/dist/group-button.d.ts +33 -0
  49. package/dist/group-button.js +67 -0
  50. package/dist/growth-chart.d.ts +77 -0
  51. package/dist/growth-chart.js +195 -0
  52. package/dist/hooks/use-keyboard-fit.d.ts +15 -0
  53. package/dist/hooks/use-keyboard-fit.js +29 -0
  54. package/dist/hooks/use-mobile.d.ts +1 -0
  55. package/dist/hooks/use-mobile.js +15 -0
  56. package/dist/icon-button.d.ts +21 -0
  57. package/dist/icon-button.js +22 -0
  58. package/dist/icon-picker.d.ts +14 -0
  59. package/dist/icon-picker.js +36 -0
  60. package/dist/index.d.ts +83 -0
  61. package/dist/index.js +90 -0
  62. package/dist/integrations.d.ts +57 -0
  63. package/dist/integrations.js +73 -0
  64. package/dist/joins.d.ts +128 -0
  65. package/dist/joins.js +767 -0
  66. package/dist/kit-config.d.ts +13 -0
  67. package/dist/kit-config.js +15 -0
  68. package/dist/lib/utils.d.ts +2 -0
  69. package/dist/lib/utils.js +5 -0
  70. package/dist/lumen-boundary.d.ts +7 -0
  71. package/dist/lumen-boundary.js +10 -0
  72. package/dist/lumen-code-editor-impl.d.ts +2 -0
  73. package/dist/lumen-code-editor-impl.js +16 -0
  74. package/dist/lumen-code-editor.d.ts +11 -0
  75. package/dist/lumen-code-editor.js +11 -0
  76. package/dist/lumen-code.d.ts +22 -0
  77. package/dist/lumen-code.js +75 -0
  78. package/dist/lumen-drawer.d.ts +30 -0
  79. package/dist/lumen-drawer.js +27 -0
  80. package/dist/lumen-echart.d.ts +58 -0
  81. package/dist/lumen-echart.js +129 -0
  82. package/dist/lumen-filter.d.ts +75 -0
  83. package/dist/lumen-filter.js +546 -0
  84. package/dist/lumen-finder.d.ts +62 -0
  85. package/dist/lumen-finder.js +275 -0
  86. package/dist/lumen-form.d.ts +34 -0
  87. package/dist/lumen-form.js +81 -0
  88. package/dist/lumen-geo-map.d.ts +9 -0
  89. package/dist/lumen-geo-map.js +135 -0
  90. package/dist/lumen-grid.d.ts +49 -0
  91. package/dist/lumen-grid.js +203 -0
  92. package/dist/lumen-layout.d.ts +150 -0
  93. package/dist/lumen-layout.js +661 -0
  94. package/dist/lumen-links.d.ts +96 -0
  95. package/dist/lumen-links.js +213 -0
  96. package/dist/lumen-page-state.d.ts +20 -0
  97. package/dist/lumen-page-state.js +15 -0
  98. package/dist/lumen-selector.d.ts +139 -0
  99. package/dist/lumen-selector.js +308 -0
  100. package/dist/lumen-source.d.ts +137 -0
  101. package/dist/lumen-source.js +327 -0
  102. package/dist/lumen-tab-drawer.d.ts +27 -0
  103. package/dist/lumen-tab-drawer.js +26 -0
  104. package/dist/lumen-tabs.d.ts +21 -0
  105. package/dist/lumen-tabs.js +6 -0
  106. package/dist/lumen-toast.d.ts +11 -0
  107. package/dist/lumen-toast.js +16 -0
  108. package/dist/lumen-trend.d.ts +18 -0
  109. package/dist/lumen-trend.js +157 -0
  110. package/dist/lumen-view-card.d.ts +35 -0
  111. package/dist/lumen-view-card.js +50 -0
  112. package/dist/lumen-view.d.ts +172 -0
  113. package/dist/lumen-view.js +645 -0
  114. package/dist/lumen-widget-charts.d.ts +57 -0
  115. package/dist/lumen-widget-charts.js +69 -0
  116. package/dist/lumen-widget.d.ts +720 -0
  117. package/dist/lumen-widget.js +609 -0
  118. package/dist/market/compare-chart.d.ts +34 -0
  119. package/dist/market/compare-chart.js +292 -0
  120. package/dist/market/indicator-picker.d.ts +29 -0
  121. package/dist/market/indicator-picker.js +125 -0
  122. package/dist/market/indicators.d.ts +63 -0
  123. package/dist/market/indicators.js +314 -0
  124. package/dist/market/live.d.ts +120 -0
  125. package/dist/market/live.js +444 -0
  126. package/dist/market/lumen-chart.d.ts +88 -0
  127. package/dist/market/lumen-chart.js +645 -0
  128. package/dist/market/market-widget.d.ts +45 -0
  129. package/dist/market/market-widget.js +346 -0
  130. package/dist/market/option-chain.d.ts +19 -0
  131. package/dist/market/option-chain.js +53 -0
  132. package/dist/market/price-chart.d.ts +128 -0
  133. package/dist/market/price-chart.js +619 -0
  134. package/dist/mcp-settings.d.ts +20 -0
  135. package/dist/mcp-settings.js +65 -0
  136. package/dist/nav.d.ts +77 -0
  137. package/dist/nav.js +73 -0
  138. package/dist/note-line.d.ts +13 -0
  139. package/dist/note-line.js +5 -0
  140. package/dist/notifications.d.ts +9 -0
  141. package/dist/notifications.js +166 -0
  142. package/dist/origin-legend.d.ts +14 -0
  143. package/dist/origin-legend.js +38 -0
  144. package/dist/overview.d.ts +84 -0
  145. package/dist/overview.js +105 -0
  146. package/dist/page-inputs.d.ts +14 -0
  147. package/dist/page-inputs.js +16 -0
  148. package/dist/page.d.ts +32 -0
  149. package/dist/page.js +45 -0
  150. package/dist/pager.d.ts +10 -0
  151. package/dist/pager.js +14 -0
  152. package/dist/prefs.d.ts +71 -0
  153. package/dist/prefs.js +126 -0
  154. package/dist/query-client.d.ts +7 -0
  155. package/dist/query-client.js +19 -0
  156. package/dist/refresh.d.ts +4 -0
  157. package/dist/refresh.js +19 -0
  158. package/dist/rename-field.d.ts +11 -0
  159. package/dist/rename-field.js +26 -0
  160. package/dist/reset-button.d.ts +9 -0
  161. package/dist/reset-button.js +10 -0
  162. package/dist/route-error.d.ts +42 -0
  163. package/dist/route-error.js +229 -0
  164. package/dist/schedules.d.ts +88 -0
  165. package/dist/schedules.js +221 -0
  166. package/dist/settings.d.ts +51 -0
  167. package/dist/settings.js +181 -0
  168. package/dist/shell.d.ts +99 -0
  169. package/dist/shell.js +137 -0
  170. package/dist/source-health.d.ts +12 -0
  171. package/dist/source-health.js +58 -0
  172. package/dist/sourced-card.d.ts +10 -0
  173. package/dist/sourced-card.js +69 -0
  174. package/dist/spotlight.d.ts +23 -0
  175. package/dist/spotlight.js +138 -0
  176. package/dist/status-health.d.ts +16 -0
  177. package/dist/status-health.js +41 -0
  178. package/dist/status.d.ts +9 -0
  179. package/dist/status.js +12 -0
  180. package/dist/summary-cards.d.ts +56 -0
  181. package/dist/summary-cards.js +270 -0
  182. package/dist/symbol-sheet-context.d.ts +4 -0
  183. package/dist/symbol-sheet-context.js +5 -0
  184. package/dist/symbol-sheet.d.ts +9 -0
  185. package/dist/symbol-sheet.js +24 -0
  186. package/dist/tasks.d.ts +29 -0
  187. package/dist/tasks.js +278 -0
  188. package/dist/theme.css +606 -0
  189. package/dist/tile.d.ts +37 -0
  190. package/dist/tile.js +23 -0
  191. package/dist/ui/alert-dialog.d.ts +18 -0
  192. package/dist/ui/alert-dialog.js +41 -0
  193. package/dist/ui/alert.d.ts +10 -0
  194. package/dist/ui/alert.js +27 -0
  195. package/dist/ui/avatar.d.ts +11 -0
  196. package/dist/ui/avatar.js +22 -0
  197. package/dist/ui/badge.d.ts +9 -0
  198. package/dist/ui/badge.js +27 -0
  199. package/dist/ui/breadcrumb.d.ts +11 -0
  200. package/dist/ui/breadcrumb.js +27 -0
  201. package/dist/ui/button-group.d.ts +11 -0
  202. package/dist/ui/button-group.js +27 -0
  203. package/dist/ui/button.d.ts +10 -0
  204. package/dist/ui/button.js +38 -0
  205. package/dist/ui/card.d.ts +11 -0
  206. package/dist/ui/card.js +24 -0
  207. package/dist/ui/chart.d.ts +44 -0
  208. package/dist/ui/chart.js +117 -0
  209. package/dist/ui/checkbox.d.ts +4 -0
  210. package/dist/ui/checkbox.js +8 -0
  211. package/dist/ui/collapsible.d.ts +5 -0
  212. package/dist/ui/collapsible.js +12 -0
  213. package/dist/ui/combobox.d.ts +24 -0
  214. package/dist/ui/combobox.js +60 -0
  215. package/dist/ui/command.d.ts +18 -0
  216. package/dist/ui/command.js +34 -0
  217. package/dist/ui/dialog.d.ts +23 -0
  218. package/dist/ui/dialog.js +50 -0
  219. package/dist/ui/dropdown-menu.d.ts +29 -0
  220. package/dist/ui/dropdown-menu.js +50 -0
  221. package/dist/ui/emoji-picker.d.ts +6 -0
  222. package/dist/ui/emoji-picker.js +28 -0
  223. package/dist/ui/empty.d.ts +11 -0
  224. package/dist/ui/empty.js +33 -0
  225. package/dist/ui/field.d.ts +24 -0
  226. package/dist/ui/field.js +65 -0
  227. package/dist/ui/hover-card.d.ts +6 -0
  228. package/dist/ui/hover-card.js +13 -0
  229. package/dist/ui/input-group.d.ts +16 -0
  230. package/dist/ui/input-group.js +56 -0
  231. package/dist/ui/input.d.ts +3 -0
  232. package/dist/ui/input.js +6 -0
  233. package/dist/ui/item.d.ts +23 -0
  234. package/dist/ui/item.js +67 -0
  235. package/dist/ui/kbd.d.ts +3 -0
  236. package/dist/ui/kbd.js +9 -0
  237. package/dist/ui/label.d.ts +4 -0
  238. package/dist/ui/label.js +7 -0
  239. package/dist/ui/popover.d.ts +10 -0
  240. package/dist/ui/popover.js +25 -0
  241. package/dist/ui/progress.d.ts +4 -0
  242. package/dist/ui/progress.js +9 -0
  243. package/dist/ui/resizable.d.ts +7 -0
  244. package/dist/ui/resizable.js +13 -0
  245. package/dist/ui/scroll-area.d.ts +5 -0
  246. package/dist/ui/scroll-area.js +10 -0
  247. package/dist/ui/select.d.ts +15 -0
  248. package/dist/ui/select.js +36 -0
  249. package/dist/ui/separator.d.ts +4 -0
  250. package/dist/ui/separator.js +7 -0
  251. package/dist/ui/sheet.d.ts +14 -0
  252. package/dist/ui/sheet.js +54 -0
  253. package/dist/ui/sidebar.d.ts +69 -0
  254. package/dist/ui/sidebar.js +206 -0
  255. package/dist/ui/skeleton.d.ts +2 -0
  256. package/dist/ui/skeleton.js +6 -0
  257. package/dist/ui/slider.d.ts +4 -0
  258. package/dist/ui/slider.js +9 -0
  259. package/dist/ui/sonner.d.ts +3 -0
  260. package/dist/ui/sonner.js +24 -0
  261. package/dist/ui/spinner.d.ts +2 -0
  262. package/dist/ui/spinner.js +7 -0
  263. package/dist/ui/switch.d.ts +6 -0
  264. package/dist/ui/switch.js +7 -0
  265. package/dist/ui/table.d.ts +10 -0
  266. package/dist/ui/table.js +31 -0
  267. package/dist/ui/tabs.d.ts +7 -0
  268. package/dist/ui/tabs.js +22 -0
  269. package/dist/ui/textarea.d.ts +3 -0
  270. package/dist/ui/textarea.js +6 -0
  271. package/dist/ui/toggle-group.d.ts +10 -0
  272. package/dist/ui/toggle-group.js +22 -0
  273. package/dist/ui/toggle.d.ts +9 -0
  274. package/dist/ui/toggle.js +25 -0
  275. package/dist/ui/tooltip.d.ts +7 -0
  276. package/dist/ui/tooltip.js +16 -0
  277. package/dist/view-edit-cell.d.ts +49 -0
  278. package/dist/view-edit-cell.js +198 -0
  279. package/dist/view-editor.d.ts +52 -0
  280. package/dist/view-editor.js +1081 -0
  281. package/dist/view-formulas.d.ts +61 -0
  282. package/dist/view-formulas.js +247 -0
  283. package/dist/view-icons.d.ts +20 -0
  284. package/dist/view-icons.js +70 -0
  285. package/dist/view-model.d.ts +390 -0
  286. package/dist/view-model.js +316 -0
  287. package/dist/whats-new.d.ts +3 -0
  288. package/dist/whats-new.js +53 -0
  289. package/dist/widget-controls.d.ts +9 -0
  290. package/dist/widget-controls.js +26 -0
  291. package/dist/widget-data.d.ts +4 -0
  292. package/dist/widget-data.js +32 -0
  293. package/dist/widget-settings.d.ts +516 -0
  294. package/dist/widget-settings.js +290 -0
  295. package/dist/widget-thumbs.d.ts +3 -0
  296. package/dist/widget-thumbs.js +29 -0
  297. package/dist/workspace-keys.d.ts +12 -0
  298. package/dist/workspace-keys.js +13 -0
  299. package/dist/workspaces.d.ts +57 -0
  300. package/dist/workspaces.js +473 -0
  301. package/package.json +82 -4
@@ -0,0 +1,57 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type ChartConfig } from './ui/chart.js';
3
+ /** Parts a split bar shows on their own; the rest fold into Other. */
4
+ export declare const STACK_MAX = 5;
5
+ type Item = {
6
+ name: string;
7
+ v: number;
8
+ fill: string;
9
+ };
10
+ type Fmt = (v: number) => string;
11
+ /** The widget's lead number over its chart: total and a short caption. */
12
+ export declare function Headline({ value, caption, tone, }: {
13
+ value: string;
14
+ caption: ReactNode;
15
+ tone?: 'gain' | 'loss';
16
+ }): import("react").JSX.Element;
17
+ /** Each bar split into parts (an account's sectors) on a full track; name and total over it. */
18
+ export declare function StackedBars({ rows, parts, fmt, exact, share, }: {
19
+ rows: Record<string, number | string>[];
20
+ parts: {
21
+ name: string;
22
+ key: string;
23
+ fill: string;
24
+ }[];
25
+ fmt: Fmt;
26
+ exact: Fmt;
27
+ share: (v: number) => string;
28
+ }): import("react").JSX.Element;
29
+ /** Horizontal bars as a ranked list: a full track per row, each bar its own colour. */
30
+ export declare function RankedBars({ id, items, signed, fmt, share, }: {
31
+ id: string;
32
+ items: Item[];
33
+ signed: boolean;
34
+ fmt: Fmt;
35
+ share: (v: number) => string;
36
+ }): import("react").JSX.Element;
37
+ /** A donut with its total in the middle; hovering a slice or its legend line shows its share. */
38
+ export declare function Donut({ items, total, fmt, share, caption, legend, }: {
39
+ items: Item[];
40
+ total: number;
41
+ fmt: Fmt;
42
+ share: (v: number) => string;
43
+ caption: string;
44
+ /** Its lines under the ring (Edit widget ▸ Controls ▸ Legend). */
45
+ legend?: boolean;
46
+ }): import("react").JSX.Element;
47
+ /** One stacked bar with gaps, the name and share inside each slice wide enough for them. */
48
+ export declare function AllocationBar({ items, total, config, tooltip, share, }: {
49
+ items: (Item & {
50
+ key: string;
51
+ })[];
52
+ total: number;
53
+ config: ChartConfig;
54
+ tooltip: ReactNode;
55
+ share: (v: number) => string;
56
+ }): import("react").JSX.Element;
57
+ export {};
@@ -0,0 +1,69 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Chart widgets: each leads with a headline number; bars are a ranked
3
+ // list on full tracks (or split into parts by a text field), the donut carries its total in the
4
+ // middle, allocation names its wide slices. Flat marks, no glow. Recharts only.
5
+ import { useState } from 'react';
6
+ import { Bar, BarChart, Cell, Label, LabelList, Pie, PieChart, XAxis, YAxis, usePlotArea, } from 'recharts';
7
+ import { cn } from './lib/utils.js';
8
+ import { ChartContainer, ChartTooltip, ChartTooltipContent } from './ui/chart.js';
9
+ /** Parts a split bar shows on their own; the rest fold into Other. */
10
+ export const STACK_MAX = 5;
11
+ /** The widget's lead number over its chart: total and a short caption. */
12
+ export function Headline({ value, caption, tone, }) {
13
+ return (_jsxs("div", { className: "mb-3 flex items-baseline gap-2", children: [_jsx("span", { className: cn('num font-semibold tracking-tight', 'text-2xl', tone === 'gain' && 'text-gain', tone === 'loss' && 'text-loss'), children: value }), _jsx("span", { className: "truncate text-xs text-muted-foreground", children: caption })] }));
14
+ }
15
+ /** Name and share over each bar, value at the track's right end. */
16
+ function RankLabel(p) {
17
+ const area = usePlotArea();
18
+ const it = p.items[p.index ?? 0];
19
+ if (!it || !area)
20
+ return null;
21
+ const y = Number(p.y) - 6;
22
+ return (_jsxs("g", { children: [_jsx("text", { x: area.x, y: y, className: "fill-foreground", fontSize: 12, fontWeight: 500, children: it.name.length > 26 ? `${it.name.slice(0, 25)}…` : it.name }), _jsxs("text", { x: area.x + area.width, y: y, textAnchor: "end", fontSize: 12, className: "num fill-foreground", children: [_jsxs("tspan", { className: "fill-muted-foreground", fontSize: 11, children: [p.share(it.v), ' '] }), p.fmt(it.v)] })] }));
23
+ }
24
+ /** Each bar split into parts (an account's sectors) on a full track; name and total over it. */
25
+ export function StackedBars({ rows, parts, fmt, exact, share, }) {
26
+ const hi = Math.max(0, ...rows.map((r) => Number(r.total)));
27
+ const config = Object.fromEntries(parts.map((p) => [p.key, { label: p.name, color: p.fill }]));
28
+ return (_jsxs("div", { className: "flex flex-col gap-3", children: [rows.map((r) => {
29
+ const total = Number(r.total);
30
+ return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "flex items-baseline gap-2 text-xs", children: [_jsx("span", { className: "truncate font-medium", children: String(r.name) }), _jsx("span", { className: "num ml-auto text-[11px] text-muted-foreground", children: share(total) }), _jsx("span", { className: "num", children: fmt(total) })] }), _jsx("div", { className: "h-2.5 overflow-hidden rounded-full bg-muted", children: _jsx(ChartContainer, { config: config, className: "aspect-auto h-full w-full", children: _jsxs(BarChart, { data: [r], layout: "vertical", margin: { left: 0, right: 0, top: 0, bottom: 0 }, barCategoryGap: 0, children: [_jsx(XAxis, { type: "number", hide: true, domain: [0, hi] }), _jsx(YAxis, { type: "category", hide: true }), _jsx(ChartTooltip, { cursor: false, shared: false, allowEscapeViewBox: { x: false, y: true }, wrapperStyle: { zIndex: 50 }, content: _jsx(ChartTooltipContent, { hideLabel: true, formatter: (v, name) => (_jsxs("span", { className: "flex w-full items-center gap-2", children: [_jsx("span", { className: "size-2 shrink-0 rounded-full", style: { background: config[String(name)]?.color } }), _jsx("span", { children: config[String(name)]?.label }), _jsxs("span", { className: "num ml-auto pl-3 whitespace-nowrap", children: [exact(Number(v)), " \u00B7", ' ', total ? ((Number(v) / total) * 100).toFixed(1) : 0, "%"] })] })) }) }), parts.map((p) => (_jsx(Bar, { dataKey: p.key, stackId: "a", fill: p.fill, stroke: "var(--card)", strokeWidth: 1, isAnimationActive: false }, p.key)))] }) }) })] }, String(r.name)));
31
+ }), _jsx("ul", { className: "flex flex-wrap gap-x-3 gap-y-1 pt-1 text-xs text-muted-foreground", children: parts.map((p) => (_jsxs("li", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "size-2 rounded-sm", style: { background: p.fill } }), p.name] }, p.key))) })] }));
32
+ }
33
+ /** Horizontal bars as a ranked list: a full track per row, each bar its own colour. */
34
+ export function RankedBars({ id, items, signed, fmt, share, }) {
35
+ const ROW = 34;
36
+ const lo = Math.min(0, ...items.map((i) => i.v));
37
+ const hi = Math.max(0, ...items.map((i) => i.v));
38
+ const config = { v: { label: 'Value', color: 'var(--chart-1)' } };
39
+ return (_jsx(ChartContainer, { config: config, className: "aspect-auto w-full", style: { height: items.length * ROW + 14 }, children: _jsxs(BarChart, { data: items, layout: "vertical", margin: { left: 0, right: 0, top: 14, bottom: 0 }, barCategoryGap: 0, children: [_jsx("defs", { children: items.map((it, i) => (_jsxs("linearGradient", { id: `rb-${id}-${i}`, x1: "0", x2: "1", y1: "0", y2: "0", children: [_jsx("stop", { offset: "0%", stopColor: it.fill, stopOpacity: it.v < 0 ? 1 : 0.35 }), _jsx("stop", { offset: "100%", stopColor: it.fill, stopOpacity: it.v < 0 ? 0.35 : 1 })] }, it.name))) }), _jsx(XAxis, { type: "number", hide: true, domain: signed ? [lo, hi] : [0, hi] }), _jsx(YAxis, { type: "category", dataKey: "name", hide: true }), _jsxs(Bar, { dataKey: "v", barSize: 10, radius: 5, background: { fill: 'var(--muted)', radius: 5 }, isAnimationActive: false, children: [items.map((it, i) => (_jsx(Cell, { fill: `url(#rb-${id}-${i})`, style: { color: it.fill } }, it.name))), _jsx(LabelList, { dataKey: "v", content: _jsx(RankLabel, { items: items, fmt: fmt, share: share }) })] })] }) }));
40
+ }
41
+ /** A donut with its total in the middle; hovering a slice or its legend line shows its share. */
42
+ export function Donut({ items, total, fmt, share, caption, legend = true, }) {
43
+ const [active, setActive] = useState(null);
44
+ const config = Object.fromEntries(items.map((s) => [s.name, { label: s.name, color: s.fill }]));
45
+ const hot = active === null ? null : items[active];
46
+ return (_jsxs("div", { className: "flex flex-col items-center gap-4", children: [_jsx(ChartContainer, { config: config, className: cn('aspect-square shrink-0 [&_.recharts-surface]:overflow-visible', 'size-44'), children: _jsx(PieChart, { children: _jsxs(Pie, { data: items, dataKey: "v", nameKey: "name", innerRadius: 54, outerRadius: 78, paddingAngle: 2, cornerRadius: 4, stroke: "none", isAnimationActive: false, onMouseEnter: (_, i) => setActive(i), onMouseLeave: () => setActive(null), children: [items.map((s) => (_jsx(Cell, { fill: s.fill, fillOpacity: active === null || items[active] === s ? 1 : 0.3, style: { color: s.fill } }, s.name))), _jsx(Label, { position: "center", content: () => {
47
+ const cx = '50%';
48
+ const cy = '50%';
49
+ return (_jsxs("text", { x: cx, y: cy, textAnchor: "middle", dominantBaseline: "middle", children: [_jsx("tspan", { x: cx, dy: "-0.4em", className: "num fill-foreground", fontSize: 16, fontWeight: 600, children: hot ? share(hot.v) : fmt(total) }), _jsx("tspan", { x: cx, dy: "1.5em", className: "fill-muted-foreground", fontSize: 11, children: hot
50
+ ? hot.name.length > 14
51
+ ? `${hot.name.slice(0, 13)}…`
52
+ : hot.name
53
+ : caption })] }));
54
+ } })] }) }) }), legend && (_jsx("ul", { className: "grid w-full min-w-0 grid-cols-2 gap-x-5 gap-y-1.5 text-xs", children: items.map((s, i) => (_jsxs("li", { className: cn('flex min-w-0 items-center gap-2 rounded px-1 transition-opacity', active !== null && active !== i && 'opacity-40'), onMouseEnter: () => setActive(i), onMouseLeave: () => setActive(null), children: [_jsx("span", { className: "size-2.5 shrink-0 rounded-sm", style: { background: s.fill } }), _jsx("span", { className: "truncate font-medium", children: s.name }), _jsx("span", { className: "num ml-auto pl-2 text-muted-foreground", children: share(s.v) })] }, s.name))) }))] }));
55
+ }
56
+ /** One stacked bar with gaps, the name and share inside each slice wide enough for them. */
57
+ export function AllocationBar({ items, total, config, tooltip, share, }) {
58
+ const row = Object.fromEntries(items.map((s) => [s.key, s.v]));
59
+ return (_jsx(ChartContainer, { config: config, className: cn('aspect-auto h-9 w-full [&_.recharts-surface]:[clip-path:inset(0_round_8px)]'), children: _jsxs(BarChart, { data: [row], layout: "vertical", margin: { left: 0, right: 0, top: 0, bottom: 0 }, children: [_jsx("defs", { children: items.map((s) => (_jsxs("linearGradient", { id: `al-${s.key}`, x1: "0", x2: "0", y1: "0", y2: "1", children: [_jsx("stop", { offset: "0%", stopColor: s.fill, stopOpacity: 1 }), _jsx("stop", { offset: "100%", stopColor: s.fill, stopOpacity: 0.6 })] }, s.key))) }), _jsx(XAxis, { type: "number", hide: true, domain: [0, total] }), _jsx(YAxis, { type: "category", hide: true }), tooltip, items.map((s) => (_jsx(Bar, { dataKey: s.key, stackId: "a", fill: `url(#al-${s.key})`, stroke: "var(--card)", strokeWidth: 3, isAnimationActive: false, children: _jsx(LabelList, { dataKey: s.key, content: (p) => {
60
+ const w = Number(p.width);
61
+ const text = `${s.name} ${share(s.v)}`;
62
+ if (w < text.length * 7 + 16)
63
+ return null;
64
+ const name = s.name.length > Math.floor(w / 8)
65
+ ? `${s.name.slice(0, Math.floor(w / 8) - 1)}…`
66
+ : s.name;
67
+ return (_jsxs("text", { x: Number(p.x) + 8, y: Number(p.y) + Number(p.height) / 2, dy: "0.35em", fontSize: 11, fontWeight: 600, style: { fill: 'var(--background)' }, children: [name, _jsx("tspan", { fontWeight: 400, dx: 6, className: "num", children: share(s.v) })] }));
68
+ } }) }, s.key)))] }) }));
69
+ }