@nocoo/basalt 3.2.0 → 3.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -19
- package/ai/COMPATIBILITY.md +41 -36
- package/ai/DESIGN.md +73 -56
- package/ai/INTEGRATION.md +819 -825
- package/ai/RECIPES.md +334 -135
- package/ai/USAGE.md +2 -2
- package/ai/registry.json +454 -97
- package/ai/sources.json +2 -2
- package/dist/assets/brand-mark.js +1 -2
- package/dist/charts/area.js +1 -2
- package/dist/charts/bar.js +1 -2
- package/dist/charts/bullet.js +1 -2
- package/dist/charts/chart-colors.js +1 -2
- package/dist/charts/charts.js +1 -2
- package/dist/charts/config.js +1 -2
- package/dist/charts/custom-chart.js +1 -2
- package/dist/charts/date-navigation.js +1 -2
- package/dist/charts/donut.js +1 -2
- package/dist/charts/frame.js +3 -4
- package/dist/charts/frame.js.map +1 -1
- package/dist/charts/funnel.js +1 -2
- package/dist/charts/gauge.js +1 -2
- package/dist/charts/grouped-bar.js +1 -2
- package/dist/charts/heatmap-calendar.js +7 -11
- package/dist/charts/heatmap-calendar.js.map +1 -1
- package/dist/charts/heatmap-matrix.js +4 -5
- package/dist/charts/heatmap-matrix.js.map +1 -1
- package/dist/charts/item-list.js +1 -2
- package/dist/charts/legend.js +1 -2
- package/dist/charts/line.js +1 -2
- package/dist/charts/palette.js +1 -2
- package/dist/charts/radar.js +1 -2
- package/dist/charts/sample.js +1 -2
- package/dist/charts/sankey.js +1 -2
- package/dist/charts/series.js +1 -2
- package/dist/charts/slot-bar.js +1 -2
- package/dist/charts/sparkline.js +1 -2
- package/dist/charts/stacked-bar.js +1 -2
- package/dist/charts/stat-card.js +1 -2
- package/dist/charts/timeline.js +1 -2
- package/dist/charts/timeseries.js +1 -2
- package/dist/charts/tooltip.js +31 -27
- package/dist/charts/tooltip.js.map +1 -1
- package/dist/components/accordion.js +1 -2
- package/dist/components/alert-dialog.js +1 -2
- package/dist/components/app-header.js +2 -3
- package/dist/components/app-header.js.map +1 -1
- package/dist/components/app-shell.js +2 -3
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/approval-card.js +1 -2
- package/dist/components/autocomplete.js +1 -2
- package/dist/components/avatar.js +1 -2
- package/dist/components/badge.js +1 -2
- package/dist/components/banner.js +1 -2
- package/dist/components/basalt-mark.js +1 -2
- package/dist/components/battery-meter.js +1 -2
- package/dist/components/breadcrumbs.js +1 -2
- package/dist/components/button.d.ts +1 -1
- package/dist/components/button.js +3 -3
- package/dist/components/button.js.map +1 -1
- package/dist/components/chat-bubble.js +1 -2
- package/dist/components/chat-composer.js +2 -3
- package/dist/components/chat-composer.js.map +1 -1
- package/dist/components/chat-header.js +1 -2
- package/dist/components/chat-inbox.js +1 -2
- package/dist/components/chat-markdown.js +1 -2
- package/dist/components/chat-message.js +2 -3
- package/dist/components/chat-message.js.map +1 -1
- package/dist/components/checkbox.js +1 -2
- package/dist/components/clipboard-text.js +1 -2
- package/dist/components/code.js +2 -3
- package/dist/components/code.js.map +1 -1
- package/dist/components/collapsible.js +1 -2
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/combobox.js +1 -2
- package/dist/components/command-palette.js +3 -4
- package/dist/components/command-palette.js.map +1 -1
- package/dist/components/confirm-dialog.js +3 -12
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/context-cards.js +2 -3
- package/dist/components/context-cards.js.map +1 -1
- package/dist/components/context-menu.js +2 -3
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/data-table.js +129 -131
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.js +7 -18
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/delete-resource.js +1 -2
- package/dist/components/description-list.js +1 -2
- package/dist/components/dialog.js +1 -2
- package/dist/components/diff-table.js +2 -3
- package/dist/components/diff-table.js.map +1 -1
- package/dist/components/dock.js +1 -2
- package/dist/components/dock.js.map +1 -1
- package/dist/components/dropdown-menu.js +2 -3
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/editable-nav-item.js +3 -4
- package/dist/components/editable-nav-item.js.map +1 -1
- package/dist/components/empty.js +1 -2
- package/dist/components/fab.js +1 -2
- package/dist/components/field.js +1 -2
- package/dist/components/file-dropzone.js +2 -3
- package/dist/components/file-dropzone.js.map +1 -1
- package/dist/components/filter-bar.js +2 -3
- package/dist/components/filter-bar.js.map +1 -1
- package/dist/components/flow.js +1 -2
- package/dist/components/grid.js +1 -2
- package/dist/components/hover-card.js +1 -2
- package/dist/components/icon-picker.js +4 -5
- package/dist/components/icon-picker.js.map +1 -1
- package/dist/components/inline-editable.js +2 -3
- package/dist/components/inline-editable.js.map +1 -1
- package/dist/components/input-area.js +1 -2
- package/dist/components/input-group.js +4 -5
- package/dist/components/input-group.js.map +1 -1
- package/dist/components/input.js +1 -2
- package/dist/components/label.js +1 -2
- package/dist/components/layer-card.js +3 -3
- package/dist/components/layer-card.js.map +1 -1
- package/dist/components/link.js +2 -3
- package/dist/components/link.js.map +1 -1
- package/dist/components/loader.js +1 -2
- package/dist/components/loading-screen.js +1 -2
- package/dist/components/menu-bar.js +3 -4
- package/dist/components/menu-bar.js.map +1 -1
- package/dist/components/meter.js +1 -2
- package/dist/components/multi-select.js +2 -3
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/navigation-menu.js +1 -2
- package/dist/components/overlay.d.ts +3 -6
- package/dist/components/overlay.js +4 -5
- package/dist/components/overlay.js.map +1 -1
- package/dist/components/page-header.js +1 -2
- package/dist/components/pagination.js +1 -2
- package/dist/components/popover.js +1 -2
- package/dist/components/prompt-bar.js +1 -2
- package/dist/components/radio.js +2 -7
- package/dist/components/radio.js.map +1 -1
- package/dist/components/recommendation-card.js +1 -2
- package/dist/components/resource-list.js +1 -2
- package/dist/components/responsive-master-detail.js +3 -4
- package/dist/components/responsive-master-detail.js.map +1 -1
- package/dist/components/scroll-area.js +2 -3
- package/dist/components/scroll-area.js.map +1 -1
- package/dist/components/section-rule.js +1 -2
- package/dist/components/segment-control.js +2 -3
- package/dist/components/segment-control.js.map +1 -1
- package/dist/components/select.js +2 -3
- package/dist/components/select.js.map +1 -1
- package/dist/components/sensitive-input.js +2 -3
- package/dist/components/sensitive-input.js.map +1 -1
- package/dist/components/separator.js +1 -2
- package/dist/components/sheet.js +1 -2
- package/dist/components/sidebar.d.ts +53 -19
- package/dist/components/sidebar.js +201 -100
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/skeleton-line.js +1 -2
- package/dist/components/slider.js +1 -2
- package/dist/components/stat-strip.js +1 -2
- package/dist/components/switch.js +1 -2
- package/dist/components/table-of-contents.js +1 -2
- package/dist/components/table-pager.js +1 -2
- package/dist/components/table.js +2 -3
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.js +2 -3
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag-badge.js +1 -2
- package/dist/components/tag-color-picker.js +3 -4
- package/dist/components/tag-color-picker.js.map +1 -1
- package/dist/components/text.js +1 -2
- package/dist/components/theme-toggle.js +1 -2
- package/dist/components/thinking.js +1 -2
- package/dist/components/toast.js +2 -3
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.js +1 -2
- package/dist/components/toggle.js +1 -2
- package/dist/components/tool-chips.js +1 -2
- package/dist/components/toolbar.js +9 -10
- package/dist/components/toolbar.js.map +1 -1
- package/dist/components/tooltip.js +1 -2
- package/dist/components/typeahead-field.js +6 -21
- package/dist/components/typeahead-field.js.map +1 -1
- package/dist/components/upload-queue.js +1 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -11
- package/dist/models/agent-feedback.js +1 -2
- package/dist/models/avatar.js +1 -2
- package/dist/models/code.js +1 -2
- package/dist/models/context-cards.js +1 -2
- package/dist/models/diff-table.js +1 -2
- package/dist/models/recommendation.js +1 -2
- package/dist/providers/accent.js +2 -7
- package/dist/providers/accent.js.map +1 -1
- package/dist/providers/link.js +1 -2
- package/dist/providers/theme.js +2 -7
- package/dist/providers/theme.js.map +1 -1
- package/dist/styles/base.css +71 -0
- package/dist/styles/standalone.css +127 -98
- package/dist/styles/tailwind.css +10 -2
- package/dist/styles/tokens.css +55 -7
- package/dist/utils/cn.js +1 -2
- package/dist/utils/control-surface.js +1 -2
- package/dist/utils/navigation.d.ts +2 -2
- package/dist/utils/navigation.js +2 -3
- package/dist/utils/navigation.js.map +1 -1
- package/dist/utils/preference-store.js +1 -2
- package/dist/utils/selection-indicator.js +1 -2
- package/dist/utils/use-checkable-group.js +1 -2
- package/dist/utils/use-hover-highlight.js +2 -3
- package/dist/utils/use-hover-highlight.js.map +1 -1
- package/dist/viewmodels/use-approval-card.js +11 -13
- package/dist/viewmodels/use-approval-card.js.map +1 -1
- package/dist/viewmodels/use-chat-composer.js +1 -2
- package/dist/viewmodels/use-chat-message.js +1 -2
- package/dist/viewmodels/use-code-block.js +1 -2
- package/dist/viewmodels/use-code-block.js.map +1 -1
- package/dist/viewmodels/use-context-cards.js +1 -2
- package/dist/viewmodels/use-diff-table.js +1 -2
- package/dist/viewmodels/use-diff-table.js.map +1 -1
- package/dist/viewmodels/use-loader.js +1 -2
- package/dist/viewmodels/use-recommendation-card.js +1 -2
- package/dist/viewmodels/use-recommendation-card.js.map +1 -1
- package/dist/viewmodels/use-thinking.js +1 -2
- package/dist/viewmodels/use-tool-chips.js +1 -2
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import { Tooltip as t, TooltipContent as n, TooltipProvider as r, TooltipTrigger
|
|
|
4
4
|
import { heatmapColorScales as a } from "./heatmap-calendar.js";
|
|
5
5
|
import { forwardRef as o, useCallback as s, useEffect as c, useId as l, useMemo as u, useRef as d, useState as f } from "react";
|
|
6
6
|
import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/charts/heatmap-matrix.tsx
|
|
8
8
|
function g(e, t, n, r) {
|
|
9
9
|
if (e == null || typeof e != "number" || !Number.isFinite(e)) return -1;
|
|
10
10
|
if (r <= 1) return 0;
|
|
@@ -94,7 +94,7 @@ var _ = o(function({ rowLabels: o, columnLabels: _, values: v, domain: y, colorS
|
|
|
94
94
|
role: "region",
|
|
95
95
|
"aria-label": w,
|
|
96
96
|
"data-testid": "heatmap-matrix",
|
|
97
|
-
className: e("flex flex-col gap-basalt-space-lg rounded-basalt-md border border-basalt-border/60 bg-basalt-card p-basalt-space-lg text-basalt-sm
|
|
97
|
+
className: e("basalt-focus basalt-focus-inset flex flex-col gap-basalt-space-lg rounded-basalt-md border border-basalt-border/60 bg-basalt-card p-basalt-space-lg text-basalt-sm", $ ? "text-basalt-muted-foreground" : "text-basalt-foreground", A),
|
|
98
98
|
style: j,
|
|
99
99
|
onFocus: re,
|
|
100
100
|
onBlur: ie,
|
|
@@ -107,7 +107,7 @@ var _ = o(function({ rowLabels: o, columnLabels: _, values: v, domain: y, colorS
|
|
|
107
107
|
tabIndex: -1,
|
|
108
108
|
role: "region",
|
|
109
109
|
"aria-label": `${w} scrollable table`,
|
|
110
|
-
className: "w-full overflow-x-auto
|
|
110
|
+
className: "basalt-focus basalt-focus-inset w-full overflow-x-auto",
|
|
111
111
|
children: /* @__PURE__ */ h("table", {
|
|
112
112
|
role: "grid",
|
|
113
113
|
"aria-label": w,
|
|
@@ -176,7 +176,7 @@ var _ = o(function({ rowLabels: o, columnLabels: _, values: v, domain: y, colorS
|
|
|
176
176
|
onBlur: () => {
|
|
177
177
|
K((e) => e === s ? null : e);
|
|
178
178
|
},
|
|
179
|
-
className: "box-border block cursor-pointer rounded-basalt-sm border-0 p-0 transition-colors basalt-motion hover:ring-1 hover:ring-basalt-foreground
|
|
179
|
+
className: "basalt-focus basalt-focus-inset basalt-focus-swatch box-border block cursor-pointer rounded-basalt-sm border-0 p-0 transition-colors basalt-motion hover:ring-1 hover:ring-basalt-foreground",
|
|
180
180
|
style: {
|
|
181
181
|
width: B,
|
|
182
182
|
height: T,
|
|
@@ -243,7 +243,6 @@ var _ = o(function({ rowLabels: o, columnLabels: _, values: v, domain: y, colorS
|
|
|
243
243
|
}) });
|
|
244
244
|
});
|
|
245
245
|
_.displayName = "HeatmapMatrix";
|
|
246
|
-
//#endregion
|
|
247
246
|
export { _ as HeatmapMatrix };
|
|
248
247
|
|
|
249
248
|
//# sourceMappingURL=heatmap-matrix.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heatmap-matrix.js","names":["_Fragment","Fragment$1","resolveColorIndex","value","colorScaleLength","levels","max","min","normalized","HeatmapMatrix","forwardRef","heatmapColorScales","val","rest","matrixId","useId","numRows","rowLabels","numCols","columnLabels","effectiveColWidth","columnWidth","cellSize","minVal","maxVal","useMemo","domain","d0","d1","lowest","highest","r","row","values","c","v","activePos","setActivePos","useState","openTooltipPos","setOpenTooltipPos","dismissedByEscapeRef","useRef","activePosRef","containerRef","cellRefs","isFocusedInsideRef","hadFocus","curR","curC","nextR","nextC","prev","key","target","handleContainerKeyDown","onKeyDown","currentRow","currentCol","nextKey","targetButton","scrollContainer","rowHeader","containerRect","btnRect","stickyWidth","visibleLeft","visibleRight","cellGap","handleContainerFocus","onFocus","handleContainerBlur","onBlur","callerCleanupRef","setRootRef","useCallback","node","ref","cleanup","isEmpty","TooltipProvider","ariaLabel","cn","className","missingLabel","col","colIdx","rowName","cellKey","rowIdx","rawVal","isMissing","colorIdx","colorScale","formattedVal","valueFormatter","cellBg","accessibleCellLabel","colName","metricLabel","isSelected","isOpen","cellContext","Tooltip","next","curr","TooltipTrigger","el","TooltipContent","renderTooltip","showLegend","lessLabel","color","idx","moreLabel"],"sources":["../../src/charts/heatmap-matrix.tsx"],"sourcesContent":["import {\n\ttype ComponentProps,\n\ttype FocusEvent,\n\tforwardRef,\n\ttype KeyboardEvent,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseId,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../components/tooltip\";\nimport { cn } from \"../utils/cn\";\nimport { heatmapColorScales } from \"./heatmap-calendar\";\n\nexport type HeatmapMatrixValue = number | null | undefined;\n\nexport interface HeatmapMatrixCellContext {\n\trowIndex: number;\n\tcolIndex: number;\n\trowLabel: string;\n\tcolumnLabel: string;\n\tvalue: HeatmapMatrixValue;\n\tformattedValue: string;\n\tisMissing: boolean;\n\tcolorIndex: number;\n}\n\nexport interface HeatmapMatrixProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Ordered row labels (e.g. weekdays [\"Mon\", \"Tue\", ...], service tiers, or regions).\n\t */\n\trowLabels: readonly string[];\n\t/**\n\t * Ordered column labels (e.g. 24 hours [\"00:00\", ...], days, or status buckets).\n\t */\n\tcolumnLabels: readonly string[];\n\t/**\n\t * 2D matrix of values indexed by [rowIndex][colIndex].\n\t * Supports ragged rows, null, undefined, and non-finite values (treated as missing).\n\t * Numeric `0` is a valid reading and distinct from missing data.\n\t */\n\tvalues: readonly (readonly HeatmapMatrixValue[])[];\n\t/**\n\t * Explicit [min, max] domain for color intensity scaling.\n\t * If reversed [max, min], bounds are automatically normalized to [min, max].\n\t * If equal [v, v], values <= v receive level 0 while values > v clamp to the highest level.\n\t * If non-finite or omitted, dynamically derived solely from visible finite numeric cells in the dataset (or [0, 0] if no finite values exist).\n\t * Values at or below min receive level 0; values >= max clamp to the highest level.\n\t */\n\tdomain?: readonly [min: number, max: number];\n\t/**\n\t * Sequential color palette array from lowest to highest intensity.\n\t * If empty or single-color, gracefully resolves to base level.\n\t * @default heatmapColorScales.green\n\t */\n\tcolorScale?: readonly string[];\n\t/**\n\t * Formatter for numeric values displayed in tooltips and accessible labels.\n\t * Defaults to `value.toLocaleString()`.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Placeholder string used for missing/null/undefined readings.\n\t * @default \"—\"\n\t */\n\tmissingLabel?: string;\n\t/**\n\t * Accessible label describing the matrix purpose or metric name.\n\t * @default \"Heatmap matrix\"\n\t */\n\tmetricLabel?: string;\n\t/**\n\t * Accessible name for the entire grid region.\n\t * @default \"Heatmap matrix\"\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Pixel height (and default width) of each matrix data cell.\n\t * @default 16\n\t */\n\tcellSize?: number;\n\t/**\n\t * Pixel width of each matrix column / data cell.\n\t * When omitted, falls back to `cellSize` for square cells.\n\t * Allows wider rectangular cells to fit readable column headers (e.g. timestamps or service names).\n\t */\n\tcolumnWidth?: number;\n\t/**\n\t * Pixel gap between adjacent cells.\n\t * @default 2\n\t */\n\tcellGap?: number;\n\t/**\n\t * Text for lowest bound legend.\n\t * @default \"Less\"\n\t */\n\tlessLabel?: string;\n\t/**\n\t * Text for highest bound legend.\n\t * @default \"More\"\n\t */\n\tmoreLabel?: string;\n\t/**\n\t * Whether to show the bottom intensity scale legend.\n\t * @default true\n\t */\n\tshowLegend?: boolean;\n\t/**\n\t * Custom cell tooltip content renderer.\n\t * If provided, replaces the default tooltip contents.\n\t */\n\trenderTooltip?: (cell: HeatmapMatrixCellContext) => ReactNode;\n}\n\nfunction resolveColorIndex(\n\tvalue: HeatmapMatrixValue,\n\tmin: number,\n\tmax: number,\n\tcolorScaleLength: number,\n): number {\n\tif (value == null || typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\treturn -1; // missing indicator\n\t}\n\tif (colorScaleLength <= 1) {\n\t\treturn 0;\n\t}\n\tconst levels = colorScaleLength - 1;\n\tif (max <= min) {\n\t\treturn value > min ? levels : 0;\n\t}\n\tconst clamped = Math.max(min, Math.min(max, value));\n\tconst normalized = (clamped - min) / (max - min);\n\tif (normalized <= 0) {\n\t\treturn 0;\n\t}\n\treturn Math.min(levels, Math.ceil(normalized * levels));\n}\n\nexport const HeatmapMatrix = forwardRef<HTMLDivElement, HeatmapMatrixProps>(function HeatmapMatrix(\n\t{\n\t\trowLabels,\n\t\tcolumnLabels,\n\t\tvalues,\n\t\tdomain,\n\t\tcolorScale = heatmapColorScales.green,\n\t\tvalueFormatter = (val) => val.toLocaleString(),\n\t\tmissingLabel = \"—\",\n\t\tmetricLabel = \"Heatmap matrix\",\n\t\tariaLabel = \"Heatmap matrix\",\n\t\tcellSize = 16,\n\t\tcolumnWidth,\n\t\tcellGap = 2,\n\t\tlessLabel = \"Less\",\n\t\tmoreLabel = \"More\",\n\t\tshowLegend = true,\n\t\trenderTooltip,\n\t\tclassName,\n\t\tstyle,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonKeyDown,\n\t\t...rest\n\t},\n\tref,\n) {\n\tconst matrixId = useId();\n\tconst numRows = rowLabels.length;\n\tconst numCols = columnLabels.length;\n\tconst effectiveColWidth = columnWidth ?? cellSize;\n\n\t// Derive domain restricted to visible row/col matrix bounds\n\tconst [minVal, maxVal] = useMemo(() => {\n\t\tif (domain) {\n\t\t\tconst [d0, d1] = domain;\n\t\t\tif (Number.isFinite(d0) && Number.isFinite(d1)) {\n\t\t\t\treturn [Math.min(d0, d1), Math.max(d0, d1)];\n\t\t\t}\n\t\t}\n\t\tlet lowest = Number.POSITIVE_INFINITY;\n\t\tlet highest = Number.NEGATIVE_INFINITY;\n\t\tfor (let r = 0; r < numRows; r++) {\n\t\t\tconst row = values[r];\n\t\t\tif (!row) continue;\n\t\t\tfor (let c = 0; c < numCols; c++) {\n\t\t\t\tconst v = row[c];\n\t\t\t\tif (typeof v === \"number\" && Number.isFinite(v)) {\n\t\t\t\t\tif (v < lowest) lowest = v;\n\t\t\t\t\tif (v > highest) highest = v;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!Number.isFinite(lowest) || !Number.isFinite(highest)) {\n\t\t\treturn [0, 0];\n\t\t}\n\t\treturn [lowest, highest];\n\t}, [domain, values, numRows, numCols]);\n\n\t// Focus state: active cell position [rowIndex, colIndex]\n\tconst [activePos, setActivePos] = useState<[number, number]>([0, 0]);\n\tconst [openTooltipPos, setOpenTooltipPos] = useState<string | null>(null);\n\tconst dismissedByEscapeRef = useRef(false);\n\n\tconst activePosRef = useRef<[number, number]>([0, 0]);\n\tactivePosRef.current = activePos;\n\n\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\tconst cellRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\n\tconst isFocusedInsideRef = useRef(false);\n\n\t// Clamp active position when dimensions change\n\tuseEffect(() => {\n\t\tconst hadFocus = isFocusedInsideRef.current;\n\t\tif (numRows === 0 || numCols === 0) {\n\t\t\tsetActivePos(([curR, curC]) => {\n\t\t\t\tif (curR === 0 && curC === 0) return [curR, curC];\n\t\t\t\treturn [0, 0];\n\t\t\t});\n\t\t\tsetOpenTooltipPos(null);\n\t\t\tif (hadFocus) {\n\t\t\t\tcontainerRef.current?.focus();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst [curR, curC] = activePosRef.current;\n\t\tconst nextR = Math.min(numRows - 1, Math.max(0, curR));\n\t\tconst nextC = Math.min(numCols - 1, Math.max(0, curC));\n\n\t\tsetActivePos((prev) => {\n\t\t\tif (prev[0] === nextR && prev[1] === nextC) {\n\t\t\t\treturn prev;\n\t\t\t}\n\t\t\treturn [nextR, nextC];\n\t\t});\n\n\t\tif (hadFocus) {\n\t\t\tconst key = `${nextR}-${nextC}`;\n\t\t\tconst target = cellRefs.current.get(key);\n\t\t\tif (target && document.activeElement !== target) {\n\t\t\t\ttarget.focus();\n\t\t\t}\n\t\t}\n\t}, [numRows, numCols]);\n\n\tconst handleContainerKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n\t\tif (e.key === \"Escape\") {\n\t\t\tdismissedByEscapeRef.current = true;\n\t\t\tsetOpenTooltipPos(null);\n\t\t}\n\n\t\t// Call caller onKeyDown first so caller can inspect or preventDefault\n\t\tonKeyDown?.(e);\n\t\tif (e.defaultPrevented) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (numRows === 0 || numCols === 0) return;\n\t\tif (e.key === \"Escape\") return;\n\n\t\tconst [currentRow, currentCol] = activePosRef.current;\n\t\tlet nextR = currentRow;\n\t\tlet nextC = currentCol;\n\n\t\tif (e.key === \"ArrowRight\") {\n\t\t\tnextC = Math.min(numCols - 1, currentCol + 1);\n\t\t} else if (e.key === \"ArrowLeft\") {\n\t\t\tnextC = Math.max(0, currentCol - 1);\n\t\t} else if (e.key === \"ArrowDown\") {\n\t\t\tnextR = Math.min(numRows - 1, currentRow + 1);\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\tnextR = Math.max(0, currentRow - 1);\n\t\t} else if (e.key === \"Home\") {\n\t\t\tnextC = 0;\n\t\t} else if (e.key === \"End\") {\n\t\t\tnextC = numCols - 1;\n\t\t} else if (e.key === \"PageUp\") {\n\t\t\tnextR = 0;\n\t\t} else if (e.key === \"PageDown\") {\n\t\t\tnextR = numRows - 1;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\te.preventDefault();\n\t\tdismissedByEscapeRef.current = false;\n\t\tsetActivePos([nextR, nextC]);\n\t\tconst nextKey = `${nextR}-${nextC}`;\n\t\tsetOpenTooltipPos(nextKey);\n\t\tconst targetButton = cellRefs.current.get(nextKey);\n\t\tif (targetButton) {\n\t\t\ttargetButton.focus();\n\t\t\tconst scrollContainer = targetButton.closest<HTMLElement>(\n\t\t\t\t'[role=\"region\"][aria-label$=\"scrollable table\"]',\n\t\t\t);\n\t\t\tconst rowHeader = targetButton.closest(\"tr\")?.querySelector<HTMLElement>('th[scope=\"row\"]');\n\n\t\t\tif (scrollContainer) {\n\t\t\t\tconst containerRect = scrollContainer.getBoundingClientRect();\n\t\t\t\tconst btnRect = targetButton.getBoundingClientRect();\n\t\t\t\tconst stickyWidth = rowHeader ? rowHeader.getBoundingClientRect().width : 0;\n\n\t\t\t\tconst visibleLeft = containerRect.left + stickyWidth;\n\t\t\t\tconst visibleRight = containerRect.right;\n\n\t\t\t\tif (btnRect.left < visibleLeft) {\n\t\t\t\t\tscrollContainer.scrollLeft -= visibleLeft - btnRect.left + cellGap;\n\t\t\t\t} else if (btnRect.right > visibleRight) {\n\t\t\t\t\tscrollContainer.scrollLeft += btnRect.right - visibleRight + cellGap;\n\t\t\t\t}\n\t\t\t} else if (typeof targetButton.scrollIntoView === \"function\") {\n\t\t\t\ttargetButton.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleContainerFocus = (e: FocusEvent<HTMLDivElement>) => {\n\t\tisFocusedInsideRef.current = true;\n\t\tonFocus?.(e);\n\t};\n\n\tconst handleContainerBlur = (e: FocusEvent<HTMLDivElement>) => {\n\t\tif (!e.currentTarget.contains(e.relatedTarget)) {\n\t\t\tisFocusedInsideRef.current = false;\n\t\t\tdismissedByEscapeRef.current = false;\n\t\t}\n\t\tonBlur?.(e);\n\t};\n\n\tconst callerCleanupRef = useRef<(() => void) | undefined>(undefined);\n\n\tconst setRootRef = useCallback(\n\t\t(node: HTMLDivElement | null) => {\n\t\t\tcontainerRef.current = node;\n\n\t\t\tif (callerCleanupRef.current) {\n\t\t\t\tcallerCleanupRef.current();\n\t\t\t\tcallerCleanupRef.current = undefined;\n\t\t\t}\n\n\t\t\tif (typeof ref === \"function\") {\n\t\t\t\tconst cleanup = ref(node);\n\t\t\t\tif (typeof cleanup === \"function\") {\n\t\t\t\t\tcallerCleanupRef.current = cleanup;\n\t\t\t\t}\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = node;\n\t\t\t}\n\n\t\t\treturn () => {\n\t\t\t\tcontainerRef.current = null;\n\t\t\t\tif (callerCleanupRef.current) {\n\t\t\t\t\tcallerCleanupRef.current();\n\t\t\t\t\tcallerCleanupRef.current = undefined;\n\t\t\t\t} else if (typeof ref === \"function\") {\n\t\t\t\t\tref(null);\n\t\t\t\t} else if (ref) {\n\t\t\t\t\tref.current = null;\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\t[ref],\n\t);\n\n\tconst isEmpty = numRows === 0 || numCols === 0;\n\n\treturn (\n\t\t<TooltipProvider>\n\t\t\t<div\n\t\t\t\tref={setRootRef}\n\t\t\t\ttabIndex={isEmpty ? -1 : undefined}\n\t\t\t\trole=\"region\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tdata-testid=\"heatmap-matrix\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex flex-col gap-basalt-space-lg rounded-basalt-md border border-basalt-border/60 bg-basalt-card p-basalt-space-lg text-basalt-sm outline-none\",\n\t\t\t\t\tisEmpty ? \"text-basalt-muted-foreground\" : \"text-basalt-foreground\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tstyle={style}\n\t\t\t\tonFocus={handleContainerFocus}\n\t\t\t\tonBlur={handleContainerBlur}\n\t\t\t\tonKeyDown={handleContainerKeyDown}\n\t\t\t\t{...rest}\n\t\t\t>\n\t\t\t\t{isEmpty ? (\n\t\t\t\t\t<span className=\"italic\">{missingLabel}</span>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{/* Scrollable table container */}\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\trole=\"region\"\n\t\t\t\t\t\t\taria-label={`${ariaLabel} scrollable table`}\n\t\t\t\t\t\t\tclassName=\"w-full overflow-x-auto outline-none\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<table\n\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: W3C ARIA interactive 2D grid table with descendant roving tab buttons\n\t\t\t\t\t\t\t\trole=\"grid\"\n\t\t\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t\t\t\tclassName=\"border-separate\"\n\t\t\t\t\t\t\t\tstyle={{ borderSpacing: cellGap }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t{/* Top-left empty header */}\n\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"sticky left-0 z-10 bg-basalt-card p-0 text-left font-normal\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ minWidth: 64 }}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Row \\ Column</span>\n\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t{columnLabels.map((col, colIdx) => (\n\t\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\t\tkey={`${matrixId}-col-${colIdx}`}\n\t\t\t\t\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"p-0 text-center font-mono text-basalt-sm text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\twidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxWidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={col}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{col}\n\t\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t\t{rowLabels.map((rowName, rowIdx) => (\n\t\t\t\t\t\t\t\t\t\t<tr key={`${matrixId}-row-${rowIdx}`}>\n\t\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\t\tscope=\"row\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"sticky left-0 z-10 bg-basalt-card pr-basalt-space-lg text-left font-medium text-basalt-foreground select-none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\tlineHeight: `${cellSize}px`,\n\t\t\t\t\t\t\t\t\t\t\t\t\tminWidth: 64,\n\t\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{rowName}\n\t\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t\t{columnLabels.map((colName, colIdx) => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellKey = `${rowIdx}-${colIdx}`;\n\t\t\t\t\t\t\t\t\t\t\t\tconst rawVal = values[rowIdx]?.[colIdx];\n\t\t\t\t\t\t\t\t\t\t\t\tconst isMissing =\n\t\t\t\t\t\t\t\t\t\t\t\t\trawVal == null || typeof rawVal !== \"number\" || !Number.isFinite(rawVal);\n\t\t\t\t\t\t\t\t\t\t\t\tconst colorIdx = resolveColorIndex(\n\t\t\t\t\t\t\t\t\t\t\t\t\trawVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tminVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorScale.length,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst formattedVal = isMissing\n\t\t\t\t\t\t\t\t\t\t\t\t\t? missingLabel\n\t\t\t\t\t\t\t\t\t\t\t\t\t: valueFormatter(rawVal as number);\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellBg =\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorIdx < 0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? \"hsl(var(--basalt-muted) / 0.4)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: (colorScale[colorIdx] ?? \"hsl(var(--basalt-muted))\");\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst accessibleCellLabel = `${rowName}, ${colName}: ${formattedVal} (${metricLabel})`;\n\t\t\t\t\t\t\t\t\t\t\t\tconst isSelected = activePos[0] === rowIdx && activePos[1] === colIdx;\n\t\t\t\t\t\t\t\t\t\t\t\tconst isOpen = openTooltipPos === cellKey;\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellContext: HeatmapMatrixCellContext = {\n\t\t\t\t\t\t\t\t\t\t\t\t\trowIndex: rowIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolIndex: colIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t\trowLabel: rowName,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolumnLabel: colName,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: rawVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tformattedValue: formattedVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tisMissing,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorIndex: colorIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: ARIA gridcell container wrapping roving interactive button\n\t\t\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/useFocusableInteractive: Focus is managed on child button via roving tabindex\n\t\t\t\t\t\t\t\t\t\t\t\t\t<td key={cellKey} role=\"gridcell\" className=\"p-0 text-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\topen={isOpen}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonOpenChange={(next) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (next) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (!dismissedByEscapeRef.current) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos((curr) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (curr !== cellKey) return curr;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (dismissedByEscapeRef.current) return null;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isCellFocused =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdocument.activeElement === cellRefs.current.get(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn isCellFocused ? curr : null;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tref={(el) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (el) cellRefs.current.set(cellKey, el);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\telse cellRefs.current.delete(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-label={accessibleCellLabel}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttabIndex={isSelected ? 0 : -1}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetActivePos([rowIdx, colIdx]);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdismissedByEscapeRef.current = false;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonBlur={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos((curr) => (curr === cellKey ? null : curr));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"box-border block cursor-pointer rounded-basalt-sm border-0 p-0 transition-colors basalt-motion hover:ring-1 hover:ring-basalt-foreground focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-basalt-ring\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbackgroundColor: cellBg,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipContent\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tid={`${matrixId}-${cellKey}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonEscapeKeyDown={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdismissedByEscapeRef.current = true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(null);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{renderTooltip ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trenderTooltip(cellContext)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-basalt-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"font-semibold text-basalt-popover-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{rowName} · {colName}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{metricLabel}:{\" \"}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-medium text-basalt-popover-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{formattedVal}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* Legend footer */}\n\t\t\t\t\t\t{showLegend ? (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"mt-basalt-space-sm flex items-center justify-end gap-basalt-space-sm text-basalt-sm text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{lessLabel}</span>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-basalt-sm\"\n\t\t\t\t\t\t\t\t\ttitle=\"Missing data\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: \"hsl(var(--basalt-muted) / 0.4)\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{colorScale.map((color, idx) => (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tkey={`${color}-${idx}`}\n\t\t\t\t\t\t\t\t\t\tclassName=\"rounded-basalt-sm\"\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t<span>{moreLabel}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</TooltipProvider>\n\t);\n});\n\nHeatmapMatrix.displayName = \"HeatmapMatrix\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"heatmap-matrix.js","names":["_Fragment","Fragment$1","resolveColorIndex","value","colorScaleLength","levels","max","min","normalized","HeatmapMatrix","forwardRef","heatmapColorScales","val","rest","matrixId","useId","numRows","rowLabels","numCols","columnLabels","effectiveColWidth","columnWidth","cellSize","minVal","maxVal","useMemo","domain","d0","d1","lowest","highest","r","row","values","c","v","activePos","setActivePos","useState","openTooltipPos","setOpenTooltipPos","dismissedByEscapeRef","useRef","activePosRef","containerRef","cellRefs","isFocusedInsideRef","hadFocus","curR","curC","nextR","nextC","prev","key","target","handleContainerKeyDown","onKeyDown","currentRow","currentCol","nextKey","targetButton","scrollContainer","rowHeader","containerRect","btnRect","stickyWidth","visibleLeft","visibleRight","cellGap","handleContainerFocus","onFocus","handleContainerBlur","onBlur","callerCleanupRef","setRootRef","useCallback","node","ref","cleanup","isEmpty","TooltipProvider","ariaLabel","cn","className","missingLabel","col","colIdx","rowName","cellKey","rowIdx","rawVal","isMissing","colorIdx","colorScale","formattedVal","valueFormatter","cellBg","accessibleCellLabel","colName","metricLabel","isSelected","isOpen","cellContext","Tooltip","next","curr","TooltipTrigger","el","TooltipContent","renderTooltip","showLegend","lessLabel","color","idx","moreLabel"],"sources":["../../src/charts/heatmap-matrix.tsx"],"sourcesContent":["import {\n\ttype ComponentProps,\n\ttype FocusEvent,\n\tforwardRef,\n\ttype KeyboardEvent,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseId,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../components/tooltip\";\nimport { cn } from \"../utils/cn\";\nimport { heatmapColorScales } from \"./heatmap-calendar\";\n\nexport type HeatmapMatrixValue = number | null | undefined;\n\nexport interface HeatmapMatrixCellContext {\n\trowIndex: number;\n\tcolIndex: number;\n\trowLabel: string;\n\tcolumnLabel: string;\n\tvalue: HeatmapMatrixValue;\n\tformattedValue: string;\n\tisMissing: boolean;\n\tcolorIndex: number;\n}\n\nexport interface HeatmapMatrixProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Ordered row labels (e.g. weekdays [\"Mon\", \"Tue\", ...], service tiers, or regions).\n\t */\n\trowLabels: readonly string[];\n\t/**\n\t * Ordered column labels (e.g. 24 hours [\"00:00\", ...], days, or status buckets).\n\t */\n\tcolumnLabels: readonly string[];\n\t/**\n\t * 2D matrix of values indexed by [rowIndex][colIndex].\n\t * Supports ragged rows, null, undefined, and non-finite values (treated as missing).\n\t * Numeric `0` is a valid reading and distinct from missing data.\n\t */\n\tvalues: readonly (readonly HeatmapMatrixValue[])[];\n\t/**\n\t * Explicit [min, max] domain for color intensity scaling.\n\t * If reversed [max, min], bounds are automatically normalized to [min, max].\n\t * If equal [v, v], values <= v receive level 0 while values > v clamp to the highest level.\n\t * If non-finite or omitted, dynamically derived solely from visible finite numeric cells in the dataset (or [0, 0] if no finite values exist).\n\t * Values at or below min receive level 0; values >= max clamp to the highest level.\n\t */\n\tdomain?: readonly [min: number, max: number];\n\t/**\n\t * Sequential color palette array from lowest to highest intensity.\n\t * If empty or single-color, gracefully resolves to base level.\n\t * @default heatmapColorScales.green\n\t */\n\tcolorScale?: readonly string[];\n\t/**\n\t * Formatter for numeric values displayed in tooltips and accessible labels.\n\t * Defaults to `value.toLocaleString()`.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Placeholder string used for missing/null/undefined readings.\n\t * @default \"—\"\n\t */\n\tmissingLabel?: string;\n\t/**\n\t * Accessible label describing the matrix purpose or metric name.\n\t * @default \"Heatmap matrix\"\n\t */\n\tmetricLabel?: string;\n\t/**\n\t * Accessible name for the entire grid region.\n\t * @default \"Heatmap matrix\"\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Pixel height (and default width) of each matrix data cell.\n\t * @default 16\n\t */\n\tcellSize?: number;\n\t/**\n\t * Pixel width of each matrix column / data cell.\n\t * When omitted, falls back to `cellSize` for square cells.\n\t * Allows wider rectangular cells to fit readable column headers (e.g. timestamps or service names).\n\t */\n\tcolumnWidth?: number;\n\t/**\n\t * Pixel gap between adjacent cells.\n\t * @default 2\n\t */\n\tcellGap?: number;\n\t/**\n\t * Text for lowest bound legend.\n\t * @default \"Less\"\n\t */\n\tlessLabel?: string;\n\t/**\n\t * Text for highest bound legend.\n\t * @default \"More\"\n\t */\n\tmoreLabel?: string;\n\t/**\n\t * Whether to show the bottom intensity scale legend.\n\t * @default true\n\t */\n\tshowLegend?: boolean;\n\t/**\n\t * Custom cell tooltip content renderer.\n\t * If provided, replaces the default tooltip contents.\n\t */\n\trenderTooltip?: (cell: HeatmapMatrixCellContext) => ReactNode;\n}\n\nfunction resolveColorIndex(\n\tvalue: HeatmapMatrixValue,\n\tmin: number,\n\tmax: number,\n\tcolorScaleLength: number,\n): number {\n\tif (value == null || typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\treturn -1; // missing indicator\n\t}\n\tif (colorScaleLength <= 1) {\n\t\treturn 0;\n\t}\n\tconst levels = colorScaleLength - 1;\n\tif (max <= min) {\n\t\treturn value > min ? levels : 0;\n\t}\n\tconst clamped = Math.max(min, Math.min(max, value));\n\tconst normalized = (clamped - min) / (max - min);\n\tif (normalized <= 0) {\n\t\treturn 0;\n\t}\n\treturn Math.min(levels, Math.ceil(normalized * levels));\n}\n\nexport const HeatmapMatrix = forwardRef<HTMLDivElement, HeatmapMatrixProps>(function HeatmapMatrix(\n\t{\n\t\trowLabels,\n\t\tcolumnLabels,\n\t\tvalues,\n\t\tdomain,\n\t\tcolorScale = heatmapColorScales.green,\n\t\tvalueFormatter = (val) => val.toLocaleString(),\n\t\tmissingLabel = \"—\",\n\t\tmetricLabel = \"Heatmap matrix\",\n\t\tariaLabel = \"Heatmap matrix\",\n\t\tcellSize = 16,\n\t\tcolumnWidth,\n\t\tcellGap = 2,\n\t\tlessLabel = \"Less\",\n\t\tmoreLabel = \"More\",\n\t\tshowLegend = true,\n\t\trenderTooltip,\n\t\tclassName,\n\t\tstyle,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonKeyDown,\n\t\t...rest\n\t},\n\tref,\n) {\n\tconst matrixId = useId();\n\tconst numRows = rowLabels.length;\n\tconst numCols = columnLabels.length;\n\tconst effectiveColWidth = columnWidth ?? cellSize;\n\n\t// Derive domain restricted to visible row/col matrix bounds\n\tconst [minVal, maxVal] = useMemo(() => {\n\t\tif (domain) {\n\t\t\tconst [d0, d1] = domain;\n\t\t\tif (Number.isFinite(d0) && Number.isFinite(d1)) {\n\t\t\t\treturn [Math.min(d0, d1), Math.max(d0, d1)];\n\t\t\t}\n\t\t}\n\t\tlet lowest = Number.POSITIVE_INFINITY;\n\t\tlet highest = Number.NEGATIVE_INFINITY;\n\t\tfor (let r = 0; r < numRows; r++) {\n\t\t\tconst row = values[r];\n\t\t\tif (!row) continue;\n\t\t\tfor (let c = 0; c < numCols; c++) {\n\t\t\t\tconst v = row[c];\n\t\t\t\tif (typeof v === \"number\" && Number.isFinite(v)) {\n\t\t\t\t\tif (v < lowest) lowest = v;\n\t\t\t\t\tif (v > highest) highest = v;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!Number.isFinite(lowest) || !Number.isFinite(highest)) {\n\t\t\treturn [0, 0];\n\t\t}\n\t\treturn [lowest, highest];\n\t}, [domain, values, numRows, numCols]);\n\n\t// Focus state: active cell position [rowIndex, colIndex]\n\tconst [activePos, setActivePos] = useState<[number, number]>([0, 0]);\n\tconst [openTooltipPos, setOpenTooltipPos] = useState<string | null>(null);\n\tconst dismissedByEscapeRef = useRef(false);\n\n\tconst activePosRef = useRef<[number, number]>([0, 0]);\n\tactivePosRef.current = activePos;\n\n\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\tconst cellRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\n\tconst isFocusedInsideRef = useRef(false);\n\n\t// Clamp active position when dimensions change\n\tuseEffect(() => {\n\t\tconst hadFocus = isFocusedInsideRef.current;\n\t\tif (numRows === 0 || numCols === 0) {\n\t\t\tsetActivePos(([curR, curC]) => {\n\t\t\t\tif (curR === 0 && curC === 0) return [curR, curC];\n\t\t\t\treturn [0, 0];\n\t\t\t});\n\t\t\tsetOpenTooltipPos(null);\n\t\t\tif (hadFocus) {\n\t\t\t\tcontainerRef.current?.focus();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst [curR, curC] = activePosRef.current;\n\t\tconst nextR = Math.min(numRows - 1, Math.max(0, curR));\n\t\tconst nextC = Math.min(numCols - 1, Math.max(0, curC));\n\n\t\tsetActivePos((prev) => {\n\t\t\tif (prev[0] === nextR && prev[1] === nextC) {\n\t\t\t\treturn prev;\n\t\t\t}\n\t\t\treturn [nextR, nextC];\n\t\t});\n\n\t\tif (hadFocus) {\n\t\t\tconst key = `${nextR}-${nextC}`;\n\t\t\tconst target = cellRefs.current.get(key);\n\t\t\tif (target && document.activeElement !== target) {\n\t\t\t\ttarget.focus();\n\t\t\t}\n\t\t}\n\t}, [numRows, numCols]);\n\n\tconst handleContainerKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n\t\tif (e.key === \"Escape\") {\n\t\t\tdismissedByEscapeRef.current = true;\n\t\t\tsetOpenTooltipPos(null);\n\t\t}\n\n\t\t// Call caller onKeyDown first so caller can inspect or preventDefault\n\t\tonKeyDown?.(e);\n\t\tif (e.defaultPrevented) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (numRows === 0 || numCols === 0) return;\n\t\tif (e.key === \"Escape\") return;\n\n\t\tconst [currentRow, currentCol] = activePosRef.current;\n\t\tlet nextR = currentRow;\n\t\tlet nextC = currentCol;\n\n\t\tif (e.key === \"ArrowRight\") {\n\t\t\tnextC = Math.min(numCols - 1, currentCol + 1);\n\t\t} else if (e.key === \"ArrowLeft\") {\n\t\t\tnextC = Math.max(0, currentCol - 1);\n\t\t} else if (e.key === \"ArrowDown\") {\n\t\t\tnextR = Math.min(numRows - 1, currentRow + 1);\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\tnextR = Math.max(0, currentRow - 1);\n\t\t} else if (e.key === \"Home\") {\n\t\t\tnextC = 0;\n\t\t} else if (e.key === \"End\") {\n\t\t\tnextC = numCols - 1;\n\t\t} else if (e.key === \"PageUp\") {\n\t\t\tnextR = 0;\n\t\t} else if (e.key === \"PageDown\") {\n\t\t\tnextR = numRows - 1;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\te.preventDefault();\n\t\tdismissedByEscapeRef.current = false;\n\t\tsetActivePos([nextR, nextC]);\n\t\tconst nextKey = `${nextR}-${nextC}`;\n\t\tsetOpenTooltipPos(nextKey);\n\t\tconst targetButton = cellRefs.current.get(nextKey);\n\t\tif (targetButton) {\n\t\t\ttargetButton.focus();\n\t\t\tconst scrollContainer = targetButton.closest<HTMLElement>(\n\t\t\t\t'[role=\"region\"][aria-label$=\"scrollable table\"]',\n\t\t\t);\n\t\t\tconst rowHeader = targetButton.closest(\"tr\")?.querySelector<HTMLElement>('th[scope=\"row\"]');\n\n\t\t\tif (scrollContainer) {\n\t\t\t\tconst containerRect = scrollContainer.getBoundingClientRect();\n\t\t\t\tconst btnRect = targetButton.getBoundingClientRect();\n\t\t\t\tconst stickyWidth = rowHeader ? rowHeader.getBoundingClientRect().width : 0;\n\n\t\t\t\tconst visibleLeft = containerRect.left + stickyWidth;\n\t\t\t\tconst visibleRight = containerRect.right;\n\n\t\t\t\tif (btnRect.left < visibleLeft) {\n\t\t\t\t\tscrollContainer.scrollLeft -= visibleLeft - btnRect.left + cellGap;\n\t\t\t\t} else if (btnRect.right > visibleRight) {\n\t\t\t\t\tscrollContainer.scrollLeft += btnRect.right - visibleRight + cellGap;\n\t\t\t\t}\n\t\t\t} else if (typeof targetButton.scrollIntoView === \"function\") {\n\t\t\t\ttargetButton.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleContainerFocus = (e: FocusEvent<HTMLDivElement>) => {\n\t\tisFocusedInsideRef.current = true;\n\t\tonFocus?.(e);\n\t};\n\n\tconst handleContainerBlur = (e: FocusEvent<HTMLDivElement>) => {\n\t\tif (!e.currentTarget.contains(e.relatedTarget)) {\n\t\t\tisFocusedInsideRef.current = false;\n\t\t\tdismissedByEscapeRef.current = false;\n\t\t}\n\t\tonBlur?.(e);\n\t};\n\n\tconst callerCleanupRef = useRef<(() => void) | undefined>(undefined);\n\n\tconst setRootRef = useCallback(\n\t\t(node: HTMLDivElement | null) => {\n\t\t\tcontainerRef.current = node;\n\n\t\t\tif (callerCleanupRef.current) {\n\t\t\t\tcallerCleanupRef.current();\n\t\t\t\tcallerCleanupRef.current = undefined;\n\t\t\t}\n\n\t\t\tif (typeof ref === \"function\") {\n\t\t\t\tconst cleanup = ref(node);\n\t\t\t\tif (typeof cleanup === \"function\") {\n\t\t\t\t\tcallerCleanupRef.current = cleanup;\n\t\t\t\t}\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = node;\n\t\t\t}\n\n\t\t\treturn () => {\n\t\t\t\tcontainerRef.current = null;\n\t\t\t\tif (callerCleanupRef.current) {\n\t\t\t\t\tcallerCleanupRef.current();\n\t\t\t\t\tcallerCleanupRef.current = undefined;\n\t\t\t\t} else if (typeof ref === \"function\") {\n\t\t\t\t\tref(null);\n\t\t\t\t} else if (ref) {\n\t\t\t\t\tref.current = null;\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\t[ref],\n\t);\n\n\tconst isEmpty = numRows === 0 || numCols === 0;\n\n\treturn (\n\t\t<TooltipProvider>\n\t\t\t<div\n\t\t\t\tref={setRootRef}\n\t\t\t\ttabIndex={isEmpty ? -1 : undefined}\n\t\t\t\trole=\"region\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tdata-testid=\"heatmap-matrix\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"basalt-focus basalt-focus-inset flex flex-col gap-basalt-space-lg rounded-basalt-md border border-basalt-border/60 bg-basalt-card p-basalt-space-lg text-basalt-sm\",\n\t\t\t\t\tisEmpty ? \"text-basalt-muted-foreground\" : \"text-basalt-foreground\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tstyle={style}\n\t\t\t\tonFocus={handleContainerFocus}\n\t\t\t\tonBlur={handleContainerBlur}\n\t\t\t\tonKeyDown={handleContainerKeyDown}\n\t\t\t\t{...rest}\n\t\t\t>\n\t\t\t\t{isEmpty ? (\n\t\t\t\t\t<span className=\"italic\">{missingLabel}</span>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{/* Scrollable table container */}\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\trole=\"region\"\n\t\t\t\t\t\t\taria-label={`${ariaLabel} scrollable table`}\n\t\t\t\t\t\t\tclassName=\"basalt-focus basalt-focus-inset w-full overflow-x-auto\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<table\n\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: W3C ARIA interactive 2D grid table with descendant roving tab buttons\n\t\t\t\t\t\t\t\trole=\"grid\"\n\t\t\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t\t\t\tclassName=\"border-separate\"\n\t\t\t\t\t\t\t\tstyle={{ borderSpacing: cellGap }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t{/* Top-left empty header */}\n\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"sticky left-0 z-10 bg-basalt-card p-0 text-left font-normal\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ minWidth: 64 }}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Row \\ Column</span>\n\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t{columnLabels.map((col, colIdx) => (\n\t\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\t\tkey={`${matrixId}-col-${colIdx}`}\n\t\t\t\t\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"p-0 text-center font-mono text-basalt-sm text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\twidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxWidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={col}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{col}\n\t\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t\t{rowLabels.map((rowName, rowIdx) => (\n\t\t\t\t\t\t\t\t\t\t<tr key={`${matrixId}-row-${rowIdx}`}>\n\t\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\t\tscope=\"row\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"sticky left-0 z-10 bg-basalt-card pr-basalt-space-lg text-left font-medium text-basalt-foreground select-none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\tlineHeight: `${cellSize}px`,\n\t\t\t\t\t\t\t\t\t\t\t\t\tminWidth: 64,\n\t\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{rowName}\n\t\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t\t{columnLabels.map((colName, colIdx) => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellKey = `${rowIdx}-${colIdx}`;\n\t\t\t\t\t\t\t\t\t\t\t\tconst rawVal = values[rowIdx]?.[colIdx];\n\t\t\t\t\t\t\t\t\t\t\t\tconst isMissing =\n\t\t\t\t\t\t\t\t\t\t\t\t\trawVal == null || typeof rawVal !== \"number\" || !Number.isFinite(rawVal);\n\t\t\t\t\t\t\t\t\t\t\t\tconst colorIdx = resolveColorIndex(\n\t\t\t\t\t\t\t\t\t\t\t\t\trawVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tminVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorScale.length,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst formattedVal = isMissing\n\t\t\t\t\t\t\t\t\t\t\t\t\t? missingLabel\n\t\t\t\t\t\t\t\t\t\t\t\t\t: valueFormatter(rawVal as number);\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellBg =\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorIdx < 0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? \"hsl(var(--basalt-muted) / 0.4)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: (colorScale[colorIdx] ?? \"hsl(var(--basalt-muted))\");\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst accessibleCellLabel = `${rowName}, ${colName}: ${formattedVal} (${metricLabel})`;\n\t\t\t\t\t\t\t\t\t\t\t\tconst isSelected = activePos[0] === rowIdx && activePos[1] === colIdx;\n\t\t\t\t\t\t\t\t\t\t\t\tconst isOpen = openTooltipPos === cellKey;\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellContext: HeatmapMatrixCellContext = {\n\t\t\t\t\t\t\t\t\t\t\t\t\trowIndex: rowIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolIndex: colIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t\trowLabel: rowName,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolumnLabel: colName,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: rawVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tformattedValue: formattedVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tisMissing,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorIndex: colorIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: ARIA gridcell container wrapping roving interactive button\n\t\t\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/useFocusableInteractive: Focus is managed on child button via roving tabindex\n\t\t\t\t\t\t\t\t\t\t\t\t\t<td key={cellKey} role=\"gridcell\" className=\"p-0 text-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\topen={isOpen}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonOpenChange={(next) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (next) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (!dismissedByEscapeRef.current) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos((curr) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (curr !== cellKey) return curr;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (dismissedByEscapeRef.current) return null;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isCellFocused =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdocument.activeElement === cellRefs.current.get(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn isCellFocused ? curr : null;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tref={(el) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (el) cellRefs.current.set(cellKey, el);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\telse cellRefs.current.delete(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-label={accessibleCellLabel}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttabIndex={isSelected ? 0 : -1}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetActivePos([rowIdx, colIdx]);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdismissedByEscapeRef.current = false;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonBlur={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos((curr) => (curr === cellKey ? null : curr));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"basalt-focus basalt-focus-inset basalt-focus-swatch box-border block cursor-pointer rounded-basalt-sm border-0 p-0 transition-colors basalt-motion hover:ring-1 hover:ring-basalt-foreground\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbackgroundColor: cellBg,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipContent\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tid={`${matrixId}-${cellKey}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonEscapeKeyDown={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdismissedByEscapeRef.current = true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(null);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{renderTooltip ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trenderTooltip(cellContext)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-basalt-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"font-semibold text-basalt-popover-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{rowName} · {colName}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{metricLabel}:{\" \"}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-medium text-basalt-popover-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{formattedVal}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* Legend footer */}\n\t\t\t\t\t\t{showLegend ? (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"mt-basalt-space-sm flex items-center justify-end gap-basalt-space-sm text-basalt-sm text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{lessLabel}</span>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-basalt-sm\"\n\t\t\t\t\t\t\t\t\ttitle=\"Missing data\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: \"hsl(var(--basalt-muted) / 0.4)\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{colorScale.map((color, idx) => (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tkey={`${color}-${idx}`}\n\t\t\t\t\t\t\t\t\t\tclassName=\"rounded-basalt-sm\"\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t<span>{moreLabel}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</TooltipProvider>\n\t);\n});\n\nHeatmapMatrix.displayName = \"HeatmapMatrix\";\n"],"mappings":"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"}
|
package/dist/charts/item-list.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
3
|
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
4
|
-
|
|
4
|
+
// src/charts/item-list.tsx
|
|
5
5
|
function r({ items: r, ariaLabel: i = "Item list", className: a }) {
|
|
6
6
|
return /* @__PURE__ */ t("ul", {
|
|
7
7
|
className: e("space-y-basalt-space-sm text-basalt-base", a),
|
|
@@ -12,7 +12,6 @@ function r({ items: r, ariaLabel: i = "Item list", className: a }) {
|
|
|
12
12
|
}) : null] }, e.id ?? `${e.label}-${e.value ?? ""}-${t}`))
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
|
-
//#endregion
|
|
16
15
|
export { r as ItemList };
|
|
17
16
|
|
|
18
17
|
//# sourceMappingURL=item-list.js.map
|
package/dist/charts/legend.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { seriesColor as e } from "./config.js";
|
|
3
3
|
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
4
|
-
|
|
4
|
+
// src/charts/legend.tsx
|
|
5
5
|
function r({ items: r, shape: i = "line" }) {
|
|
6
6
|
return r.length === 0 ? null : /* @__PURE__ */ t("div", {
|
|
7
7
|
"data-testid": "chart-legend",
|
|
@@ -50,7 +50,6 @@ function r({ items: r, shape: i = "line" }) {
|
|
|
50
50
|
})
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
|
-
//#endregion
|
|
54
53
|
export { r as ChartLegend };
|
|
55
54
|
|
|
56
55
|
//# sourceMappingURL=legend.js.map
|
package/dist/charts/line.js
CHANGED
|
@@ -5,7 +5,7 @@ import { ChartShell as d } from "./frame.js";
|
|
|
5
5
|
import { ChartLegend as f } from "./legend.js";
|
|
6
6
|
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
7
7
|
import { CartesianGrid as h, Line as g, LineChart as _, Tooltip as v, XAxis as y, YAxis as b } from "recharts";
|
|
8
|
-
|
|
8
|
+
// src/charts/line.tsx
|
|
9
9
|
function x({ data: x, series: S, ariaLabel: C = "Line chart", className: w, showAxes: T = !1, showLegend: E = !1, color: D, valueFormatter: O, xValueFormatter: k, yDomain: A, legend: j, customTooltip: M, summary: N, dataAlternative: P, accessibilityLayer: F }) {
|
|
10
10
|
let I = c(l(S, u(x)), D), L = j === void 0 ? E ? /* @__PURE__ */ p(f, {
|
|
11
11
|
items: I,
|
|
@@ -51,7 +51,6 @@ function x({ data: x, series: S, ariaLabel: C = "Line chart", className: w, show
|
|
|
51
51
|
})
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
|
-
//#endregion
|
|
55
54
|
export { x as LineChart };
|
|
56
55
|
|
|
57
56
|
//# sourceMappingURL=line.js.map
|
package/dist/charts/palette.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as e } from "react/jsx-runtime";
|
|
3
|
-
|
|
3
|
+
// src/charts/palette.tsx
|
|
4
4
|
var t = (e) => `hsl(var(--basalt-${e}))`, n = (e, t) => `hsl(var(--basalt-${e}) / ${t})`, r = t("chart-axis"), i = t("chart-muted"), a = {
|
|
5
5
|
primary: t("chart-1"),
|
|
6
6
|
sky: t("chart-2"),
|
|
@@ -44,7 +44,6 @@ function s({ ariaLabel: t = "Chart colors" }) {
|
|
|
44
44
|
}, t))
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
-
//#endregion
|
|
48
47
|
export { o as CHART_COLORS, s as ChartPalette, a as chart, r as chartAxis, i as chartMuted, n as withAlpha };
|
|
49
48
|
|
|
50
49
|
//# sourceMappingURL=palette.js.map
|
package/dist/charts/radar.js
CHANGED
|
@@ -3,7 +3,7 @@ import { ANIMATION_PROPS as e, CHART_TYPE as t, GRID_PROPS as n, chartTickStyle
|
|
|
3
3
|
import { ChartFrame as a } from "./frame.js";
|
|
4
4
|
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
5
5
|
import { PolarAngleAxis as c, PolarGrid as l, Radar as u, RadarChart as d } from "recharts";
|
|
6
|
-
|
|
6
|
+
// src/charts/radar.tsx
|
|
7
7
|
function f({ data: f, series: p, ariaLabel: m = "Radar chart", className: h, summary: g, dataAlternative: _, accessibilityLayer: v }) {
|
|
8
8
|
let y = i(p?.[0], 3);
|
|
9
9
|
return /* @__PURE__ */ o(a, {
|
|
@@ -38,7 +38,6 @@ function f({ data: f, series: p, ariaLabel: m = "Radar chart", className: h, sum
|
|
|
38
38
|
})
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
//#endregion
|
|
42
41
|
export { f as RadarChart };
|
|
43
42
|
|
|
44
43
|
//# sourceMappingURL=radar.js.map
|
package/dist/charts/sample.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
2
|
+
// src/charts/sample.ts
|
|
3
3
|
var e = [
|
|
4
4
|
{
|
|
5
5
|
x: "Mon",
|
|
@@ -118,7 +118,6 @@ var e = [
|
|
|
118
118
|
}
|
|
119
119
|
]
|
|
120
120
|
};
|
|
121
|
-
//#endregion
|
|
122
121
|
export { i as BULLET_SAMPLE, t as DONUT_SAMPLE, r as FUNNEL_SAMPLE, n as RADAR_SAMPLE, e as SAMPLE, a as SANKEY_SAMPLE };
|
|
123
122
|
|
|
124
123
|
//# sourceMappingURL=sample.js.map
|
package/dist/charts/sankey.js
CHANGED
|
@@ -4,7 +4,7 @@ import { chartFontSize as n, chartTooltipProps as r } from "./config.js";
|
|
|
4
4
|
import { ChartFrame as i } from "./frame.js";
|
|
5
5
|
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
6
6
|
import { Sankey as s, Tooltip as c } from "recharts";
|
|
7
|
-
|
|
7
|
+
// src/charts/sankey.tsx
|
|
8
8
|
function l({ x: r, y: i, width: s, height: c, payload: l }) {
|
|
9
9
|
return /* @__PURE__ */ o("g", { children: [/* @__PURE__ */ a("rect", {
|
|
10
10
|
x: r,
|
|
@@ -47,7 +47,6 @@ function u({ data: t, ariaLabel: n = "Sankey chart", className: o, summary: u, d
|
|
|
47
47
|
})
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
-
//#endregion
|
|
51
50
|
export { u as SankeyChart };
|
|
52
51
|
|
|
53
52
|
//# sourceMappingURL=sankey.js.map
|
package/dist/charts/series.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
2
|
+
// src/charts/series.ts
|
|
3
3
|
function e(e, t) {
|
|
4
4
|
return e && e.length > 0 ? e : t.map((e) => ({ key: e }));
|
|
5
5
|
}
|
|
@@ -13,7 +13,6 @@ function n(e) {
|
|
|
13
13
|
let t = ["y"];
|
|
14
14
|
return e.some((e) => e.y2 != null) && t.push("y2"), e.some((e) => e.y3 != null) && t.push("y3"), t;
|
|
15
15
|
}
|
|
16
|
-
//#endregion
|
|
17
16
|
export { t as applyLeadColor, e as resolveChartSeries, n as xyFallbackKeys };
|
|
18
17
|
|
|
19
18
|
//# sourceMappingURL=series.js.map
|
package/dist/charts/slot-bar.js
CHANGED
|
@@ -6,7 +6,7 @@ import { resolveChartSeries as l } from "./series.js";
|
|
|
6
6
|
import { ChartFrame as u } from "./frame.js";
|
|
7
7
|
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
8
8
|
import { Bar as p, BarChart as m, XAxis as h, YAxis as g } from "recharts";
|
|
9
|
-
|
|
9
|
+
// src/charts/slot-bar.tsx
|
|
10
10
|
function _(e) {
|
|
11
11
|
if ("items" in e) return /* @__PURE__ */ d(v, { ...e });
|
|
12
12
|
let { series: t, ariaLabel: n = "Slot bar chart", className: r, summary: i, dataAlternative: _, accessibilityLayer: y } = e, b = l(t, ["y"]);
|
|
@@ -72,7 +72,6 @@ function v({ items: a, ariaLabel: o = "Slot bar chart", heightClass: s = "h-basa
|
|
|
72
72
|
children: g
|
|
73
73
|
}) : g;
|
|
74
74
|
}
|
|
75
|
-
//#endregion
|
|
76
75
|
export { _ as SlotBarChart };
|
|
77
76
|
|
|
78
77
|
//# sourceMappingURL=slot-bar.js.map
|
package/dist/charts/sparkline.js
CHANGED
|
@@ -5,7 +5,7 @@ import { resolveChartSeries as r } from "./series.js";
|
|
|
5
5
|
import { ChartFrame as i } from "./frame.js";
|
|
6
6
|
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
7
7
|
import { Bar as s, BarChart as c, Cell as l, XAxis as u, YAxis as d } from "recharts";
|
|
8
|
-
|
|
8
|
+
// src/charts/sparkline.tsx
|
|
9
9
|
function f({ data: f, series: p, ariaLabel: m = "Sparkline", className: h, summary: g, dataAlternative: _, accessibilityLayer: v }) {
|
|
10
10
|
let y = r(p, ["y"]);
|
|
11
11
|
return /* @__PURE__ */ a(i, {
|
|
@@ -43,7 +43,6 @@ function f({ data: f, series: p, ariaLabel: m = "Sparkline", className: h, summa
|
|
|
43
43
|
})
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
-
//#endregion
|
|
47
46
|
export { f as Sparkline };
|
|
48
47
|
|
|
49
48
|
//# sourceMappingURL=sparkline.js.map
|
|
@@ -5,7 +5,7 @@ import { ChartShell as l } from "./frame.js";
|
|
|
5
5
|
import { ChartLegend as u } from "./legend.js";
|
|
6
6
|
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
7
7
|
import { Bar as p, BarChart as m, CartesianGrid as h, Tooltip as g, XAxis as _, YAxis as v } from "recharts";
|
|
8
|
-
|
|
8
|
+
// src/charts/stacked-bar.tsx
|
|
9
9
|
function y({ data: y, series: b, ariaLabel: x = "Stacked bar chart", className: S, showAxes: C = !1, showLegend: w = !1, stackOffset: T, valueFormatter: E, xValueFormatter: D, yDomain: O, legend: k, customTooltip: A, summary: j, dataAlternative: M, accessibilityLayer: N }) {
|
|
10
10
|
let P = c(b, [
|
|
11
11
|
"y",
|
|
@@ -55,7 +55,6 @@ function y({ data: y, series: b, ariaLabel: x = "Stacked bar chart", className:
|
|
|
55
55
|
})
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
|
-
//#endregion
|
|
59
58
|
export { y as StackedBarChart };
|
|
60
59
|
|
|
61
60
|
//# sourceMappingURL=stacked-bar.js.map
|
package/dist/charts/stat-card.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
3
|
import { LayerCard as t } from "../components/layer-card.js";
|
|
4
4
|
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
5
|
-
|
|
5
|
+
// src/charts/stat-card.tsx
|
|
6
6
|
function i(e) {
|
|
7
7
|
return e != null && e !== !1;
|
|
8
8
|
}
|
|
@@ -85,7 +85,6 @@ function o({ children: t, columns: r = 4, className: i }) {
|
|
|
85
85
|
children: t
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
|
-
//#endregion
|
|
89
88
|
export { a as StatCard, o as StatGrid };
|
|
90
89
|
|
|
91
90
|
//# sourceMappingURL=stat-card.js.map
|
package/dist/charts/timeline.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
3
|
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
4
|
-
|
|
4
|
+
// src/charts/timeline.tsx
|
|
5
5
|
var r = Array.from({ length: 24 }, (e, t) => t);
|
|
6
6
|
function i(e) {
|
|
7
7
|
return Number.parseInt(e.split(":")[0] ?? "0", 10);
|
|
@@ -78,7 +78,6 @@ function o({ events: a, ariaLabel: o, className: s }) {
|
|
|
78
78
|
})
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
|
-
//#endregion
|
|
82
81
|
export { a as Timeline };
|
|
83
82
|
|
|
84
83
|
//# sourceMappingURL=timeline.js.map
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { LineChart as e } from "./line.js";
|
|
3
3
|
import { jsx as t } from "react/jsx-runtime";
|
|
4
|
-
|
|
4
|
+
// src/charts/timeseries.tsx
|
|
5
5
|
function n({ ariaLabel: n = "Timeseries", ...r }) {
|
|
6
6
|
return /* @__PURE__ */ t(e, {
|
|
7
7
|
ariaLabel: n,
|
|
8
8
|
...r
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
|
-
//#endregion
|
|
12
11
|
export { n as Timeseries };
|
|
13
12
|
|
|
14
13
|
//# sourceMappingURL=timeseries.js.map
|
package/dist/charts/tooltip.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
3
|
-
|
|
3
|
+
// src/charts/tooltip.tsx
|
|
4
4
|
var n = /* @__PURE__ */ new Set([
|
|
5
5
|
"y",
|
|
6
6
|
"y2",
|
|
@@ -58,6 +58,7 @@ function u({ label: n, value: r, color: o, unit: s, formatter: c, hideIndicator:
|
|
|
58
58
|
},
|
|
59
59
|
children: n
|
|
60
60
|
}) : null,
|
|
61
|
+
m ? " " : null,
|
|
61
62
|
/* @__PURE__ */ t("span", {
|
|
62
63
|
style: {
|
|
63
64
|
color: "hsl(var(--basalt-popover-foreground))",
|
|
@@ -106,33 +107,37 @@ function f({ label: n = "Total", value: r, unit: a, formatter: o, style: s, ...c
|
|
|
106
107
|
...s
|
|
107
108
|
},
|
|
108
109
|
...c,
|
|
109
|
-
children: [
|
|
110
|
-
|
|
111
|
-
color: "hsl(var(--basalt-muted-foreground))",
|
|
112
|
-
flex: 1,
|
|
113
|
-
fontWeight: 600,
|
|
114
|
-
minWidth: 0,
|
|
115
|
-
overflow: "hidden",
|
|
116
|
-
textOverflow: "ellipsis",
|
|
117
|
-
whiteSpace: "nowrap"
|
|
118
|
-
},
|
|
119
|
-
children: n
|
|
120
|
-
}) : null, /* @__PURE__ */ t("span", {
|
|
121
|
-
style: {
|
|
122
|
-
color: "hsl(var(--basalt-popover-foreground))",
|
|
123
|
-
flexShrink: 0,
|
|
124
|
-
fontVariantNumeric: "tabular-nums",
|
|
125
|
-
fontWeight: 700,
|
|
126
|
-
marginLeft: d ? 0 : "auto"
|
|
127
|
-
},
|
|
128
|
-
children: [u, a != null && u !== "—" ? /* @__PURE__ */ e("span", {
|
|
110
|
+
children: [
|
|
111
|
+
d ? /* @__PURE__ */ e("span", {
|
|
129
112
|
style: {
|
|
130
|
-
|
|
131
|
-
|
|
113
|
+
color: "hsl(var(--basalt-muted-foreground))",
|
|
114
|
+
flex: 1,
|
|
115
|
+
fontWeight: 600,
|
|
116
|
+
minWidth: 0,
|
|
117
|
+
overflow: "hidden",
|
|
118
|
+
textOverflow: "ellipsis",
|
|
119
|
+
whiteSpace: "nowrap"
|
|
132
120
|
},
|
|
133
|
-
children:
|
|
134
|
-
}) : null
|
|
135
|
-
|
|
121
|
+
children: n
|
|
122
|
+
}) : null,
|
|
123
|
+
d ? " " : null,
|
|
124
|
+
/* @__PURE__ */ t("span", {
|
|
125
|
+
style: {
|
|
126
|
+
color: "hsl(var(--basalt-popover-foreground))",
|
|
127
|
+
flexShrink: 0,
|
|
128
|
+
fontVariantNumeric: "tabular-nums",
|
|
129
|
+
fontWeight: 700,
|
|
130
|
+
marginLeft: d ? 0 : "auto"
|
|
131
|
+
},
|
|
132
|
+
children: [u, a != null && u !== "—" ? /* @__PURE__ */ e("span", {
|
|
133
|
+
style: {
|
|
134
|
+
fontWeight: 500,
|
|
135
|
+
marginLeft: "var(--basalt-space-xs)"
|
|
136
|
+
},
|
|
137
|
+
children: a
|
|
138
|
+
}) : null]
|
|
139
|
+
})
|
|
140
|
+
]
|
|
136
141
|
});
|
|
137
142
|
}
|
|
138
143
|
function p({ active: n, payload: i, label: a, formatter: l }) {
|
|
@@ -178,7 +183,6 @@ function p({ active: n, payload: i, label: a, formatter: l }) {
|
|
|
178
183
|
})]
|
|
179
184
|
});
|
|
180
185
|
}
|
|
181
|
-
//#endregion
|
|
182
186
|
export { p as ChartTooltipContent, d as ChartTooltipDivider, u as ChartTooltipRow, f as ChartTooltipSummary, o as formatChartNumber };
|
|
183
187
|
|
|
184
188
|
//# sourceMappingURL=tooltip.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip.js","names":["HIDDEN_SERIES_KEYS","TITLE_SIZE","BODY_SIZE","DOT_SIZE","formatChartNumber","value","seriesLabel","name","item","key","seriesSwatch","formatTooltipValue","val","formatter","ChartTooltipRow","rest","formattedValue","hasLabel","label","swatchColor","color","style","hideIndicator","unit","ChartTooltipDivider","ChartTooltipSummary","ChartTooltipContent","active","payload","format","title","raw","numeric","labelText","index"],"sources":["../../src/charts/tooltip.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from \"react\";\n\nconst HIDDEN_SERIES_KEYS = new Set([\"y\", \"y2\", \"y3\", \"value\", \"target\"]);\nconst TITLE_SIZE = \"var(--basalt-text-sm)\";\nconst BODY_SIZE = \"var(--basalt-text-sm)\";\nconst DOT_SIZE = \"var(--basalt-space-lg)\";\n\nexport type ChartTooltipItem = {\n\tname?: string;\n\tvalue?: number | string;\n\tcolor?: string;\n\tfill?: string;\n\tstroke?: string;\n\tdataKey?: string | number;\n};\n\nexport type ChartTooltipContentProps = {\n\tactive?: boolean;\n\tpayload?: readonly ChartTooltipItem[];\n\tlabel?: string | number;\n\tformatter?: (value: number) => string;\n};\n\nexport interface ChartTooltipRowProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Series or metric name displayed beside the color dot.\n\t * Preserves numeric `0` and React nodes; nullish values omit the label element.\n\t */\n\tlabel?: ReactNode;\n\t/**\n\t * Display value of the point or metric.\n\t * Finite numbers are automatically formatted via `formatter` or `formatChartNumber`.\n\t * `null` or `undefined` renders placeholder \"—\". ReactNode values are passed through.\n\t */\n\tvalue?: ReactNode;\n\t/**\n\t * Dot swatch indicator color. Defaults to `--basalt-chart-1`.\n\t */\n\tcolor?: string;\n\t/**\n\t * Optional unit suffix (e.g., \"ms\", \"req/s\", \"%\") rendered adjacent to valid values.\n\t * Omitted when `value` evaluates to placeholder \"—\".\n\t */\n\tunit?: ReactNode;\n\t/**\n\t * Custom numeric value formatter overriding `formatChartNumber`.\n\t */\n\tformatter?: (value: number) => string;\n\t/**\n\t * When true, suppresses rendering of the decorative color dot.\n\t * @default false\n\t */\n\thideIndicator?: boolean;\n}\n\nexport interface ChartTooltipSummaryProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Summary row heading label.\n\t * Preserves numeric `0` and custom nodes.\n\t * @default \"Total\"\n\t */\n\tlabel?: ReactNode;\n\t/**\n\t * Aggregated metric value. Finite numbers are formatted; nullish renders \"—\".\n\t */\n\tvalue?: ReactNode;\n\t/**\n\t * Optional unit suffix appended to the summary value.\n\t */\n\tunit?: ReactNode;\n\t/**\n\t * Custom numeric formatter for the summary value.\n\t */\n\tformatter?: (value: number) => string;\n}\n\nexport interface ChartTooltipDividerProps extends Omit<ComponentProps<\"hr\">, \"children\"> {}\n\nexport function formatChartNumber(value: number): string {\n\tif (!Number.isFinite(value)) {\n\t\treturn \"—\";\n\t}\n\treturn new Intl.NumberFormat(undefined, {\n\t\tmaximumFractionDigits: Number.isInteger(value) ? 0 : 1,\n\t}).format(value);\n}\n\nfunction seriesLabel(item: ChartTooltipItem): string | undefined {\n\tconst name = item.name == null ? \"\" : String(item.name);\n\tconst key = item.dataKey == null ? \"\" : String(item.dataKey);\n\tif (HIDDEN_SERIES_KEYS.has(name) || HIDDEN_SERIES_KEYS.has(key)) {\n\t\treturn undefined;\n\t}\n\treturn name || undefined;\n}\n\nfunction seriesSwatch(item: ChartTooltipItem): string {\n\treturn item.color ?? item.fill ?? item.stroke ?? \"hsl(var(--basalt-chart-1))\";\n}\n\nfunction formatTooltipValue(val: ReactNode, formatter?: (value: number) => string): ReactNode {\n\tif (val == null) {\n\t\treturn \"—\";\n\t}\n\tif (typeof val === \"number\") {\n\t\treturn formatter ? formatter(val) : formatChartNumber(val);\n\t}\n\treturn val;\n}\n\nexport function ChartTooltipRow({\n\tlabel,\n\tvalue,\n\tcolor,\n\tunit,\n\tformatter,\n\thideIndicator = false,\n\tstyle,\n\t...rest\n}: ChartTooltipRowProps) {\n\tconst formattedValue = formatTooltipValue(value, formatter);\n\tconst hasLabel = label != null;\n\tconst swatchColor = color ?? \"hsl(var(--basalt-chart-1))\";\n\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip-row\"\n\t\t\tstyle={{\n\t\t\t\talignItems: \"center\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\tgap: \"var(--basalt-space-lg)\",\n\t\t\t\tlineHeight: \"var(--basalt-leading-relaxed)\",\n\t\t\t\tminWidth: 0,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{!hideIndicator ? (\n\t\t\t\t<span\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: swatchColor,\n\t\t\t\t\t\tborderRadius: \"var(--basalt-radius-full)\",\n\t\t\t\t\t\tboxShadow: \"0 0 0 1px hsl(var(--basalt-popover-foreground) / 0.12)\",\n\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\theight: DOT_SIZE,\n\t\t\t\t\t\twidth: DOT_SIZE,\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{hasLabel ? (\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{label}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\tmarginLeft: hasLabel ? 0 : \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{formattedValue}\n\t\t\t\t{unit != null && formattedValue !== \"—\" ? (\n\t\t\t\t\t<span style={{ fontWeight: 400, marginLeft: \"var(--basalt-space-xs)\" }}>{unit}</span>\n\t\t\t\t) : null}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n\nexport function ChartTooltipDivider({ style, ...rest }: ChartTooltipDividerProps) {\n\treturn (\n\t\t<hr\n\t\t\taria-orientation=\"horizontal\"\n\t\t\tdata-testid=\"chart-tooltip-divider\"\n\t\t\tstyle={{\n\t\t\t\tbackgroundColor: \"hsl(var(--basalt-border) / 0.55)\",\n\t\t\t\tborder: 0,\n\t\t\t\theight: 1,\n\t\t\t\tmargin: \"var(--basalt-space-sm) 0\",\n\t\t\t\twidth: \"100%\",\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t/>\n\t);\n}\n\nexport function ChartTooltipSummary({\n\tlabel = \"Total\",\n\tvalue,\n\tunit,\n\tformatter,\n\tstyle,\n\t...rest\n}: ChartTooltipSummaryProps) {\n\tconst formattedValue = formatTooltipValue(value, formatter);\n\tconst hasLabel = label != null;\n\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip-summary\"\n\t\t\tstyle={{\n\t\t\t\talignItems: \"center\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\tgap: \"var(--basalt-space-lg)\",\n\t\t\t\tlineHeight: \"var(--basalt-leading-relaxed)\",\n\t\t\t\tminWidth: 0,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{hasLabel ? (\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{label}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\tfontWeight: 700,\n\t\t\t\t\tmarginLeft: hasLabel ? 0 : \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{formattedValue}\n\t\t\t\t{unit != null && formattedValue !== \"—\" ? (\n\t\t\t\t\t<span style={{ fontWeight: 500, marginLeft: \"var(--basalt-space-xs)\" }}>{unit}</span>\n\t\t\t\t) : null}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n\nexport function ChartTooltipContent({\n\tactive,\n\tpayload,\n\tlabel,\n\tformatter,\n}: ChartTooltipContentProps) {\n\tif (!active || !payload?.length) {\n\t\treturn null;\n\t}\n\tconst format = formatter ?? formatChartNumber;\n\tconst title = label == null || label === \"\" ? undefined : String(label);\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip\"\n\t\t\tstyle={{\n\t\t\t\tbackground: \"hsl(var(--basalt-popover))\",\n\t\t\t\tborder: \"1px solid hsl(var(--basalt-border) / 0.55)\",\n\t\t\t\tborderRadius: \"var(--basalt-radius-md)\",\n\t\t\t\tboxShadow: \"0 12px 28px -8px rgb(0 0 0 / 0.28), 0 4px 10px -4px rgb(0 0 0 / 0.16)\",\n\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\tmaxWidth: \"13.75rem\",\n\t\t\t\tminWidth: \"8rem\",\n\t\t\t\tpadding: \"var(--basalt-space-default)\",\n\t\t\t}}\n\t\t>\n\t\t\t{title ? (\n\t\t\t\t<p\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\t\tfontSize: TITLE_SIZE,\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\tletterSpacing: \"-0.01em\",\n\t\t\t\t\t\tlineHeight: \"var(--basalt-leading-tight)\",\n\t\t\t\t\t\tmargin: \"0 0 var(--basalt-space-lg)\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{title}\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t<div style={{ display: \"flex\", flexDirection: \"column\", gap: \"var(--basalt-space-sm)\" }}>\n\t\t\t\t{payload.map((item, index) => {\n\t\t\t\t\tconst raw = item.value;\n\t\t\t\t\tconst numeric =\n\t\t\t\t\t\ttypeof raw === \"number\" ? raw : typeof raw === \"string\" ? Number(raw) : Number.NaN;\n\t\t\t\t\tconst labelText = seriesLabel(item);\n\t\t\t\t\tconst key = `${String(item.dataKey ?? item.name ?? index)}-${String(index)}`;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<ChartTooltipRow\n\t\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\t\tlabel={labelText}\n\t\t\t\t\t\t\tcolor={seriesSwatch(item)}\n\t\t\t\t\t\t\tvalue={Number.isFinite(numeric) ? format(numeric) : String(raw ?? \"—\")}\n\t\t\t\t\t\t\tdata-testid={undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tooltip.js","names":["HIDDEN_SERIES_KEYS","TITLE_SIZE","BODY_SIZE","DOT_SIZE","formatChartNumber","value","seriesLabel","name","item","key","seriesSwatch","formatTooltipValue","val","formatter","ChartTooltipRow","rest","formattedValue","hasLabel","label","swatchColor","color","style","hideIndicator","unit","ChartTooltipDivider","ChartTooltipSummary","ChartTooltipContent","active","payload","format","title","raw","numeric","labelText","index"],"sources":["../../src/charts/tooltip.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from \"react\";\n\nconst HIDDEN_SERIES_KEYS = new Set([\"y\", \"y2\", \"y3\", \"value\", \"target\"]);\nconst TITLE_SIZE = \"var(--basalt-text-sm)\";\nconst BODY_SIZE = \"var(--basalt-text-sm)\";\nconst DOT_SIZE = \"var(--basalt-space-lg)\";\n\nexport type ChartTooltipItem = {\n\tname?: string;\n\tvalue?: number | string;\n\tcolor?: string;\n\tfill?: string;\n\tstroke?: string;\n\tdataKey?: string | number;\n};\n\nexport type ChartTooltipContentProps = {\n\tactive?: boolean;\n\tpayload?: readonly ChartTooltipItem[];\n\tlabel?: string | number;\n\tformatter?: (value: number) => string;\n};\n\nexport interface ChartTooltipRowProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Series or metric name displayed beside the color dot.\n\t * Preserves numeric `0` and React nodes; nullish values omit the label element.\n\t */\n\tlabel?: ReactNode;\n\t/**\n\t * Display value of the point or metric.\n\t * Finite numbers are automatically formatted via `formatter` or `formatChartNumber`.\n\t * `null` or `undefined` renders placeholder \"—\". ReactNode values are passed through.\n\t */\n\tvalue?: ReactNode;\n\t/**\n\t * Dot swatch indicator color. Defaults to `--basalt-chart-1`.\n\t */\n\tcolor?: string;\n\t/**\n\t * Optional unit suffix (e.g., \"ms\", \"req/s\", \"%\") rendered adjacent to valid values.\n\t * Omitted when `value` evaluates to placeholder \"—\".\n\t */\n\tunit?: ReactNode;\n\t/**\n\t * Custom numeric value formatter overriding `formatChartNumber`.\n\t */\n\tformatter?: (value: number) => string;\n\t/**\n\t * When true, suppresses rendering of the decorative color dot.\n\t * @default false\n\t */\n\thideIndicator?: boolean;\n}\n\nexport interface ChartTooltipSummaryProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Summary row heading label.\n\t * Preserves numeric `0` and custom nodes.\n\t * @default \"Total\"\n\t */\n\tlabel?: ReactNode;\n\t/**\n\t * Aggregated metric value. Finite numbers are formatted; nullish renders \"—\".\n\t */\n\tvalue?: ReactNode;\n\t/**\n\t * Optional unit suffix appended to the summary value.\n\t */\n\tunit?: ReactNode;\n\t/**\n\t * Custom numeric formatter for the summary value.\n\t */\n\tformatter?: (value: number) => string;\n}\n\nexport interface ChartTooltipDividerProps extends Omit<ComponentProps<\"hr\">, \"children\"> {}\n\nexport function formatChartNumber(value: number): string {\n\tif (!Number.isFinite(value)) {\n\t\treturn \"—\";\n\t}\n\treturn new Intl.NumberFormat(undefined, {\n\t\tmaximumFractionDigits: Number.isInteger(value) ? 0 : 1,\n\t}).format(value);\n}\n\nfunction seriesLabel(item: ChartTooltipItem): string | undefined {\n\tconst name = item.name == null ? \"\" : String(item.name);\n\tconst key = item.dataKey == null ? \"\" : String(item.dataKey);\n\tif (HIDDEN_SERIES_KEYS.has(name) || HIDDEN_SERIES_KEYS.has(key)) {\n\t\treturn undefined;\n\t}\n\treturn name || undefined;\n}\n\nfunction seriesSwatch(item: ChartTooltipItem): string {\n\treturn item.color ?? item.fill ?? item.stroke ?? \"hsl(var(--basalt-chart-1))\";\n}\n\nfunction formatTooltipValue(val: ReactNode, formatter?: (value: number) => string): ReactNode {\n\tif (val == null) {\n\t\treturn \"—\";\n\t}\n\tif (typeof val === \"number\") {\n\t\treturn formatter ? formatter(val) : formatChartNumber(val);\n\t}\n\treturn val;\n}\n\nexport function ChartTooltipRow({\n\tlabel,\n\tvalue,\n\tcolor,\n\tunit,\n\tformatter,\n\thideIndicator = false,\n\tstyle,\n\t...rest\n}: ChartTooltipRowProps) {\n\tconst formattedValue = formatTooltipValue(value, formatter);\n\tconst hasLabel = label != null;\n\tconst swatchColor = color ?? \"hsl(var(--basalt-chart-1))\";\n\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip-row\"\n\t\t\tstyle={{\n\t\t\t\talignItems: \"center\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\tgap: \"var(--basalt-space-lg)\",\n\t\t\t\tlineHeight: \"var(--basalt-leading-relaxed)\",\n\t\t\t\tminWidth: 0,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{!hideIndicator ? (\n\t\t\t\t<span\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: swatchColor,\n\t\t\t\t\t\tborderRadius: \"var(--basalt-radius-full)\",\n\t\t\t\t\t\tboxShadow: \"0 0 0 1px hsl(var(--basalt-popover-foreground) / 0.12)\",\n\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\theight: DOT_SIZE,\n\t\t\t\t\t\twidth: DOT_SIZE,\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{hasLabel ? (\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{label}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t{hasLabel ? \" \" : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\tmarginLeft: hasLabel ? 0 : \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{formattedValue}\n\t\t\t\t{unit != null && formattedValue !== \"—\" ? (\n\t\t\t\t\t<span style={{ fontWeight: 400, marginLeft: \"var(--basalt-space-xs)\" }}>{unit}</span>\n\t\t\t\t) : null}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n\nexport function ChartTooltipDivider({ style, ...rest }: ChartTooltipDividerProps) {\n\treturn (\n\t\t<hr\n\t\t\taria-orientation=\"horizontal\"\n\t\t\tdata-testid=\"chart-tooltip-divider\"\n\t\t\tstyle={{\n\t\t\t\tbackgroundColor: \"hsl(var(--basalt-border) / 0.55)\",\n\t\t\t\tborder: 0,\n\t\t\t\theight: 1,\n\t\t\t\tmargin: \"var(--basalt-space-sm) 0\",\n\t\t\t\twidth: \"100%\",\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t/>\n\t);\n}\n\nexport function ChartTooltipSummary({\n\tlabel = \"Total\",\n\tvalue,\n\tunit,\n\tformatter,\n\tstyle,\n\t...rest\n}: ChartTooltipSummaryProps) {\n\tconst formattedValue = formatTooltipValue(value, formatter);\n\tconst hasLabel = label != null;\n\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip-summary\"\n\t\t\tstyle={{\n\t\t\t\talignItems: \"center\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\tgap: \"var(--basalt-space-lg)\",\n\t\t\t\tlineHeight: \"var(--basalt-leading-relaxed)\",\n\t\t\t\tminWidth: 0,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{hasLabel ? (\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{label}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t{hasLabel ? \" \" : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\tfontWeight: 700,\n\t\t\t\t\tmarginLeft: hasLabel ? 0 : \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{formattedValue}\n\t\t\t\t{unit != null && formattedValue !== \"—\" ? (\n\t\t\t\t\t<span style={{ fontWeight: 500, marginLeft: \"var(--basalt-space-xs)\" }}>{unit}</span>\n\t\t\t\t) : null}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n\nexport function ChartTooltipContent({\n\tactive,\n\tpayload,\n\tlabel,\n\tformatter,\n}: ChartTooltipContentProps) {\n\tif (!active || !payload?.length) {\n\t\treturn null;\n\t}\n\tconst format = formatter ?? formatChartNumber;\n\tconst title = label == null || label === \"\" ? undefined : String(label);\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip\"\n\t\t\tstyle={{\n\t\t\t\tbackground: \"hsl(var(--basalt-popover))\",\n\t\t\t\tborder: \"1px solid hsl(var(--basalt-border) / 0.55)\",\n\t\t\t\tborderRadius: \"var(--basalt-radius-md)\",\n\t\t\t\tboxShadow: \"0 12px 28px -8px rgb(0 0 0 / 0.28), 0 4px 10px -4px rgb(0 0 0 / 0.16)\",\n\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\tmaxWidth: \"13.75rem\",\n\t\t\t\tminWidth: \"8rem\",\n\t\t\t\tpadding: \"var(--basalt-space-default)\",\n\t\t\t}}\n\t\t>\n\t\t\t{title ? (\n\t\t\t\t<p\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\t\tfontSize: TITLE_SIZE,\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\tletterSpacing: \"-0.01em\",\n\t\t\t\t\t\tlineHeight: \"var(--basalt-leading-tight)\",\n\t\t\t\t\t\tmargin: \"0 0 var(--basalt-space-lg)\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{title}\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t<div style={{ display: \"flex\", flexDirection: \"column\", gap: \"var(--basalt-space-sm)\" }}>\n\t\t\t\t{payload.map((item, index) => {\n\t\t\t\t\tconst raw = item.value;\n\t\t\t\t\tconst numeric =\n\t\t\t\t\t\ttypeof raw === \"number\" ? raw : typeof raw === \"string\" ? Number(raw) : Number.NaN;\n\t\t\t\t\tconst labelText = seriesLabel(item);\n\t\t\t\t\tconst key = `${String(item.dataKey ?? item.name ?? index)}-${String(index)}`;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<ChartTooltipRow\n\t\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\t\tlabel={labelText}\n\t\t\t\t\t\t\tcolor={seriesSwatch(item)}\n\t\t\t\t\t\t\tvalue={Number.isFinite(numeric) ? format(numeric) : String(raw ?? \"—\")}\n\t\t\t\t\t\t\tdata-testid={undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
|
|
|
4
4
|
import * as n from "react";
|
|
5
5
|
import { jsx as r } from "react/jsx-runtime";
|
|
6
6
|
import * as i from "@radix-ui/react-accordion";
|
|
7
|
-
|
|
7
|
+
// src/components/accordion.tsx
|
|
8
8
|
var a = n.forwardRef(({ className: n, ...a }, o) => /* @__PURE__ */ r(i.Root, {
|
|
9
9
|
ref: o,
|
|
10
10
|
className: e(t, n),
|
|
@@ -22,7 +22,6 @@ var o = i.Item, s = n.forwardRef(({ className: n, children: a, ...o }, s) => /*
|
|
|
22
22
|
}));
|
|
23
23
|
s.displayName = i.Trigger.displayName;
|
|
24
24
|
var c = i.Content;
|
|
25
|
-
//#endregion
|
|
26
25
|
export { a as Accordion, c as AccordionContent, o as AccordionItem, s as AccordionTrigger };
|
|
27
26
|
|
|
28
27
|
//# sourceMappingURL=accordion.js.map
|