@nocoo/basalt 2.1.8 → 2.2.0
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/ai/INTEGRATION.md +64 -28
- package/ai/RECIPES.md +46 -1
- package/ai/USAGE.md +2 -2
- package/ai/registry.json +56 -14
- package/dist/assets/brand-mark.js.map +1 -1
- package/dist/charts/area.js.map +1 -1
- package/dist/charts/bar.js.map +1 -1
- package/dist/charts/bullet.js.map +1 -1
- package/dist/charts/charts.js.map +1 -1
- package/dist/charts/config.js.map +1 -1
- package/dist/charts/custom-chart.js.map +1 -1
- package/dist/charts/date-navigation.js.map +1 -1
- package/dist/charts/donut.js.map +1 -1
- package/dist/charts/frame.js.map +1 -1
- package/dist/charts/funnel.js.map +1 -1
- package/dist/charts/gauge.js.map +1 -1
- package/dist/charts/grouped-bar.js.map +1 -1
- package/dist/charts/heatmap-calendar.js.map +1 -1
- package/dist/charts/heatmap-matrix.js.map +1 -1
- package/dist/charts/item-list.js.map +1 -1
- package/dist/charts/legend.js.map +1 -1
- package/dist/charts/line.js.map +1 -1
- package/dist/charts/palette.js.map +1 -1
- package/dist/charts/radar.js.map +1 -1
- package/dist/charts/sample.js.map +1 -1
- package/dist/charts/sankey.js.map +1 -1
- package/dist/charts/series.js.map +1 -1
- package/dist/charts/slot-bar.js.map +1 -1
- package/dist/charts/sparkline.js.map +1 -1
- package/dist/charts/stacked-bar.js.map +1 -1
- package/dist/charts/stat-card.js.map +1 -1
- package/dist/charts/timeline.js.map +1 -1
- package/dist/charts/timeseries.js.map +1 -1
- package/dist/charts/tooltip.js.map +1 -1
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/app-header.d.ts +5 -1
- package/dist/components/app-header.js +12 -4
- package/dist/components/app-header.js.map +1 -1
- package/dist/components/app-shell.d.ts +4 -1
- package/dist/components/app-shell.js +7 -4
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/badge.js.map +1 -1
- package/dist/components/banner.js.map +1 -1
- package/dist/components/basalt-mark.js.map +1 -1
- package/dist/components/battery-meter.js.map +1 -1
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/button.js.map +1 -1
- package/dist/components/chat-bubble.js.map +1 -1
- package/dist/components/chat-composer.js.map +1 -1
- package/dist/components/chat-header.js.map +1 -1
- package/dist/components/chat-inbox.js.map +1 -1
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/clipboard-text.js.map +1 -1
- package/dist/components/code.js.map +1 -1
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/command-palette.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +4 -1
- package/dist/components/confirm-dialog.js +20 -18
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/delete-resource.js.map +1 -1
- package/dist/components/description-list.js.map +1 -1
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/dock.js.map +1 -1
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/editable-nav-item.js.map +1 -1
- package/dist/components/empty.js.map +1 -1
- package/dist/components/fab.js.map +1 -1
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-dropzone.js.map +1 -1
- package/dist/components/filter-bar.js.map +1 -1
- package/dist/components/flow.js.map +1 -1
- package/dist/components/grid.js.map +1 -1
- package/dist/components/hover-card.js.map +1 -1
- package/dist/components/icon-picker.js.map +1 -1
- package/dist/components/inline-editable.js.map +1 -1
- package/dist/components/input-area.js.map +1 -1
- package/dist/components/input-group.js.map +1 -1
- package/dist/components/input.js.map +1 -1
- package/dist/components/label.js.map +1 -1
- package/dist/components/layer-card.js.map +1 -1
- package/dist/components/link.js.map +1 -1
- package/dist/components/loader.js.map +1 -1
- package/dist/components/loading-screen.js.map +1 -1
- package/dist/components/menu-bar.js.map +1 -1
- package/dist/components/meter.js.map +1 -1
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/overlay.js.map +1 -1
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/pagination.js.map +1 -1
- package/dist/components/popover.js.map +1 -1
- package/dist/components/radio.js.map +1 -1
- package/dist/components/resource-list.js.map +1 -1
- package/dist/components/responsive-master-detail.js +5 -5
- package/dist/components/responsive-master-detail.js.map +1 -1
- package/dist/components/scroll-area.js.map +1 -1
- package/dist/components/section-rule.js.map +1 -1
- package/dist/components/segment-control.js.map +1 -1
- package/dist/components/select.js.map +1 -1
- package/dist/components/sensitive-input.js.map +1 -1
- package/dist/components/separator.js.map +1 -1
- package/dist/components/sheet.js +1 -0
- package/dist/components/sheet.js.map +1 -1
- package/dist/components/sidebar.d.ts +3 -1
- package/dist/components/sidebar.js +8 -5
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/skeleton-line.js.map +1 -1
- package/dist/components/slider.js.map +1 -1
- package/dist/components/stat-strip.js.map +1 -1
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table-of-contents.js.map +1 -1
- package/dist/components/table-pager.js.map +1 -1
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag-badge.js.map +1 -1
- package/dist/components/tag-color-picker.js.map +1 -1
- package/dist/components/text.js.map +1 -1
- package/dist/components/theme-toggle.js.map +1 -1
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/toolbar.js.map +1 -1
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/typeahead-field.js.map +1 -1
- package/dist/components/upload-queue.js.map +1 -1
- package/dist/providers/accent.js +1 -1
- package/dist/providers/accent.js.map +1 -1
- package/dist/providers/link.js.map +1 -1
- package/dist/providers/theme.js +1 -1
- package/dist/providers/theme.js.map +1 -1
- package/dist/styles/base.css +116 -0
- package/dist/styles/standalone.css +124 -3
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/control-surface.js.map +1 -1
- package/dist/utils/preference-store.js +1 -1
- package/dist/utils/preference-store.js.map +1 -1
- package/dist/utils/selection-indicator.js.map +1 -1
- package/dist/utils/use-checkable-group.js.map +1 -1
- package/package.json +1 -1
package/dist/charts/bar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bar.js","names":[],"sources":["../../src/charts/bar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Bar, CartesianGrid, BarChart as RechartsBar, Tooltip, XAxis, YAxis } from \"recharts\";\nimport {\n\tANIMATION_PROPS,\n\tBAR_RADIUS,\n\tCHART_PLOT_MARGIN,\n\tCHART_PLOT_MARGIN_BARE,\n\tcartesianAxisProps,\n\tchartTooltipProps,\n\tGRID_PROPS,\n\tseriesColor,\n} from \"./config\";\nimport { ChartShell } from \"./frame\";\nimport { ChartLegend } from \"./legend\";\nimport type {\n\tLineChartAxisDomain,\n\tLineChartLegendRenderer,\n\tLineChartNumericKeys,\n\tLineChartTooltipRenderer,\n} from \"./line\";\nimport {\n\tapplyLeadColor,\n\ttype ChartSeriesDescriptor,\n\tresolveChartSeries,\n\ttype XYPoint,\n} from \"./series\";\n\nexport type BarChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function BarChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({\n\tdata,\n\tseries,\n\tariaLabel = \"Bar chart\",\n\tclassName,\n\tshowAxes = false,\n\tshowLegend = false,\n\tcolor,\n\tvalueFormatter,\n\txValueFormatter,\n\tyDomain,\n\tlegend,\n\tcustomTooltip,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: BarChartProps<TData, K>) {\n\tconst bars = applyLeadColor(resolveChartSeries(series, [\"y\" as K]), color);\n\tconst resolvedLegend =\n\t\tlegend !== undefined ? (\n\t\t\ttypeof legend === \"function\" ? (\n\t\t\t\tlegend({ items: bars })\n\t\t\t) : (\n\t\t\t\tlegend\n\t\t\t)\n\t\t) : showLegend ? (\n\t\t\t<ChartLegend items={bars} shape=\"bar\" />\n\t\t) : undefined;\n\n\treturn (\n\t\t<ChartShell\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tlegend={resolvedLegend}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsBar data={data} margin={showAxes ? CHART_PLOT_MARGIN : CHART_PLOT_MARGIN_BARE}>\n\t\t\t\t{showAxes ? <CartesianGrid {...GRID_PROPS} /> : null}\n\t\t\t\t<XAxis dataKey=\"x\" {...cartesianAxisProps(!showAxes)} tickFormatter={xValueFormatter} />\n\t\t\t\t<YAxis\n\t\t\t\t\t{...cartesianAxisProps(!showAxes)}\n\t\t\t\t\ttickFormatter={valueFormatter}\n\t\t\t\t\t{...(yDomain ? { domain: yDomain as [number, number] } : {})}\n\t\t\t\t/>\n\t\t\t\t<Tooltip\n\t\t\t\t\t{...chartTooltipProps({\n\t\t\t\t\t\tformatter: valueFormatter,\n\t\t\t\t\t\tcursor: \"bar\",\n\t\t\t\t\t\tcustomTooltip,\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t\t{bars.map((item, index) => (\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tfill={seriesColor(item, index)}\n\t\t\t\t\t\tradius={BAR_RADIUS.vertical}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</RechartsBar>\n\t\t</ChartShell>\n\t);\n}\n"],"mappings":";;;;;;;;AAoFA,
|
|
1
|
+
{"version":3,"file":"bar.js","names":["RechartsBar","BarChart$1","BarChart","bars","applyLeadColor","resolveChartSeries","series","color","resolvedLegend","legend","showLegend","ChartLegend","ChartShell","showAxes","CHART_PLOT_MARGIN","CHART_PLOT_MARGIN_BARE","CartesianGrid","GRID_PROPS","XAxis","cartesianAxisProps","xValueFormatter","YAxis","valueFormatter","yDomain","Tooltip","chartTooltipProps","Bar","item","seriesColor","index","BAR_RADIUS","ANIMATION_PROPS"],"sources":["../../src/charts/bar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Bar, CartesianGrid, BarChart as RechartsBar, Tooltip, XAxis, YAxis } from \"recharts\";\nimport {\n\tANIMATION_PROPS,\n\tBAR_RADIUS,\n\tCHART_PLOT_MARGIN,\n\tCHART_PLOT_MARGIN_BARE,\n\tcartesianAxisProps,\n\tchartTooltipProps,\n\tGRID_PROPS,\n\tseriesColor,\n} from \"./config\";\nimport { ChartShell } from \"./frame\";\nimport { ChartLegend } from \"./legend\";\nimport type {\n\tLineChartAxisDomain,\n\tLineChartLegendRenderer,\n\tLineChartNumericKeys,\n\tLineChartTooltipRenderer,\n} from \"./line\";\nimport {\n\tapplyLeadColor,\n\ttype ChartSeriesDescriptor,\n\tresolveChartSeries,\n\ttype XYPoint,\n} from \"./series\";\n\nexport type BarChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function BarChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({\n\tdata,\n\tseries,\n\tariaLabel = \"Bar chart\",\n\tclassName,\n\tshowAxes = false,\n\tshowLegend = false,\n\tcolor,\n\tvalueFormatter,\n\txValueFormatter,\n\tyDomain,\n\tlegend,\n\tcustomTooltip,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: BarChartProps<TData, K>) {\n\tconst bars = applyLeadColor(resolveChartSeries(series, [\"y\" as K]), color);\n\tconst resolvedLegend =\n\t\tlegend !== undefined ? (\n\t\t\ttypeof legend === \"function\" ? (\n\t\t\t\tlegend({ items: bars })\n\t\t\t) : (\n\t\t\t\tlegend\n\t\t\t)\n\t\t) : showLegend ? (\n\t\t\t<ChartLegend items={bars} shape=\"bar\" />\n\t\t) : undefined;\n\n\treturn (\n\t\t<ChartShell\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tlegend={resolvedLegend}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsBar data={data} margin={showAxes ? CHART_PLOT_MARGIN : CHART_PLOT_MARGIN_BARE}>\n\t\t\t\t{showAxes ? <CartesianGrid {...GRID_PROPS} /> : null}\n\t\t\t\t<XAxis dataKey=\"x\" {...cartesianAxisProps(!showAxes)} tickFormatter={xValueFormatter} />\n\t\t\t\t<YAxis\n\t\t\t\t\t{...cartesianAxisProps(!showAxes)}\n\t\t\t\t\ttickFormatter={valueFormatter}\n\t\t\t\t\t{...(yDomain ? { domain: yDomain as [number, number] } : {})}\n\t\t\t\t/>\n\t\t\t\t<Tooltip\n\t\t\t\t\t{...chartTooltipProps({\n\t\t\t\t\t\tformatter: valueFormatter,\n\t\t\t\t\t\tcursor: \"bar\",\n\t\t\t\t\t\tcustomTooltip,\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t\t{bars.map((item, index) => (\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tfill={seriesColor(item, index)}\n\t\t\t\t\t\tradius={BAR_RADIUS.vertical}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</RechartsBar>\n\t\t</ChartShell>\n\t);\n}\n"],"mappings":";;;;;;;;AAoFA,SAAgBE,EAGd,EACD,SACA,WACA,eAAY,aACZ,cACA,cAAW,IACX,gBAAa,IACb,UACA,mBACA,oBACA,YACA,WACA,kBACA,YACA,oBACA,yBAC2B;CAC3B,IAAMC,IAAOC,EAAeC,EAAmBC,GAAQ,CAAC,GAAQ,CAAC,GAAGC,CAAK,GACnEC,IACLC,MAAW,KAAA,IAMPC,IACH,kBAACC,GAAD;EAAa,OAAOR;EAAM,OAAM;CAAO,CAAA,IACpC,KAAA,IAPH,OAAOM,KAAW,aACjBA,EAAO,EAAE,OAAON,EAAK,CAAC,IAEtBM;CAMH,OACC,kBAACG,GAAD;EACY;EACA;EACX,QAAQJ;EACC;EACQ;EACG;EAEpB,UAAA,kBAACR,GAAD;GAAmB;GAAM,QAAQa,IAAWC,IAAoBC;GAAhE,UAAA;IACEF,IAAW,kBAACG,GAAD,EAAe,GAAIC,EAAa,CAAA,IAAI;IAChD,kBAACC,GAAD;KAAO,SAAQ;KAAI,GAAIC,EAAmB,CAACN,CAAQ;KAAG,eAAeO;IAAkB,CAAA;IACvF,kBAACC,GAAD;KACC,GAAIF,EAAmB,CAACN,CAAQ;KAChC,eAAeS;KACf,GAAKC,IAAU,EAAE,QAAQA,EAA4B,IAAI,CAAC;IAC1D,CAAA;IACD,kBAACC,GAAD,EACC,GAAIC,EAAkB;KACrB,WAAWH;KACX,QAAQ;KACR;IACD,CAAC,EACD,CAAA;IACAnB,EAAK,KAAK,GAAM,MAChB,kBAACuB,GAAD;KAEC,SAASC,EAAK;KACd,MAAMA,EAAK,SAASA,EAAK;KACzB,MAAMC,EAAYD,GAAME,CAAK;KAC7B,QAAQC,EAAW;KACnB,GAAIC;IACJ,GANKJ,EAAK,GAMV,CACD;GACW;;CACF,CAAA;AAEd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bullet.js","names":[],"sources":["../../src/charts/bullet.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Bar, BarChart as RechartsBar, Tooltip, XAxis, YAxis } from \"recharts\";\nimport { ANIMATION_PROPS, cartesianAxisProps, chartTooltipProps, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport { type BulletPoint, type BulletSeriesDescriptor, resolveChartSeries } from \"./series\";\n\nexport type BulletChartProps = {\n\tdata: BulletPoint[];\n\tseries?: BulletSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function BulletChart({\n\tdata,\n\tseries,\n\tariaLabel = \"Bullet chart\",\n\tclassName,\n\tshowAxes = true,\n\tvalueFormatter,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: BulletChartProps) {\n\tconst bars = resolveChartSeries(series, [\"target\", \"value\"]);\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsBar data={data} layout=\"vertical\">\n\t\t\t\t<XAxis type=\"number\" {...cartesianAxisProps(!showAxes)} tickFormatter={valueFormatter} />\n\t\t\t\t<YAxis type=\"category\" dataKey=\"name\" {...cartesianAxisProps(!showAxes)} />\n\t\t\t\t<Tooltip {...chartTooltipProps({ formatter: valueFormatter, cursor: \"bar\" })} />\n\t\t\t\t{bars.map((item) => (\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tfill={seriesColor(item, item.key === \"target\" ? 6 : 1)}\n\t\t\t\t\t\tbarSize={item.key === \"target\" ? 10 : 6}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</RechartsBar>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;;AA+BA,
|
|
1
|
+
{"version":3,"file":"bullet.js","names":["RechartsBar","BulletChart","bars","resolveChartSeries","series","ChartFrame","BarChart","XAxis","cartesianAxisProps","showAxes","valueFormatter","YAxis","Tooltip","chartTooltipProps","Bar","item","seriesColor","ANIMATION_PROPS"],"sources":["../../src/charts/bullet.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Bar, BarChart as RechartsBar, Tooltip, XAxis, YAxis } from \"recharts\";\nimport { ANIMATION_PROPS, cartesianAxisProps, chartTooltipProps, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport { type BulletPoint, type BulletSeriesDescriptor, resolveChartSeries } from \"./series\";\n\nexport type BulletChartProps = {\n\tdata: BulletPoint[];\n\tseries?: BulletSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function BulletChart({\n\tdata,\n\tseries,\n\tariaLabel = \"Bullet chart\",\n\tclassName,\n\tshowAxes = true,\n\tvalueFormatter,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: BulletChartProps) {\n\tconst bars = resolveChartSeries(series, [\"target\", \"value\"]);\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsBar data={data} layout=\"vertical\">\n\t\t\t\t<XAxis type=\"number\" {...cartesianAxisProps(!showAxes)} tickFormatter={valueFormatter} />\n\t\t\t\t<YAxis type=\"category\" dataKey=\"name\" {...cartesianAxisProps(!showAxes)} />\n\t\t\t\t<Tooltip {...chartTooltipProps({ formatter: valueFormatter, cursor: \"bar\" })} />\n\t\t\t\t{bars.map((item) => (\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tfill={seriesColor(item, item.key === \"target\" ? 6 : 1)}\n\t\t\t\t\t\tbarSize={item.key === \"target\" ? 10 : 6}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</RechartsBar>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;;AA+BA,SAAgBC,EAAY,EAC3B,SACA,WACA,eAAY,gBACZ,cACA,cAAW,IACX,mBACA,YACA,oBACA,yBACoB;CACpB,IAAMC,IAAOC,EAAmBC,GAAQ,CAAC,UAAU,OAAO,CAAC;CAC3D,OACC,kBAACC,GAAD;EACY;EACA;EACF;EACQ;EACG;EAEpB,UAAA,kBAACL,GAAD;GAAmB;GAAM,QAAO;GAAhC,UAAA;IACC,kBAACO,GAAD;KAAO,MAAK;KAAS,GAAIC,EAAmB,CAACC,CAAQ;KAAG,eAAeC;IAAiB,CAAA;IACxF,kBAACC,GAAD;KAAO,MAAK;KAAW,SAAQ;KAAO,GAAIH,EAAmB,CAACC,CAAQ;IAAI,CAAA;IAC1E,kBAACG,GAAD,EAAS,GAAIC,EAAkB;KAAE,WAAWH;KAAgB,QAAQ;IAAM,CAAC,EAAI,CAAA;IAC9ER,EAAK,KAAK,MACV,kBAACY,GAAD;KAEC,SAASC,EAAK;KACd,MAAMA,EAAK,SAASA,EAAK;KACzB,MAAMC,EAAYD,GAAMA,EAAK,QAAQ,WAAW,IAAI,CAAC;KACrD,SAASA,EAAK,QAAQ,WAAW,KAAK;KACtC,GAAIE;IACJ,GANKF,EAAK,GAMV,CACD;GACW;;CACF,CAAA;AAEd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"charts.js","names":[],"sources":["../../src/charts/charts.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport {\n\tLineChart,\n\ttype LineChartAxisDomain,\n\ttype LineChartLegendRenderer,\n\ttype LineChartNumericKeys,\n\ttype LineChartTooltipRenderer,\n} from \"./line\";\nimport type { ChartSeriesDescriptor, XYPoint } from \"./series\";\n\nexport type ChartsProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function Charts<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({ ariaLabel = \"Charts\", ...props }: ChartsProps<TData, K>) {\n\treturn <LineChart<TData, K> ariaLabel={ariaLabel} {...props} />;\n}\n"],"mappings":";;;;AAmEA,
|
|
1
|
+
{"version":3,"file":"charts.js","names":["Charts","props","LineChart"],"sources":["../../src/charts/charts.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport {\n\tLineChart,\n\ttype LineChartAxisDomain,\n\ttype LineChartLegendRenderer,\n\ttype LineChartNumericKeys,\n\ttype LineChartTooltipRenderer,\n} from \"./line\";\nimport type { ChartSeriesDescriptor, XYPoint } from \"./series\";\n\nexport type ChartsProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function Charts<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({ ariaLabel = \"Charts\", ...props }: ChartsProps<TData, K>) {\n\treturn <LineChart<TData, K> ariaLabel={ariaLabel} {...props} />;\n}\n"],"mappings":";;;;AAmEA,SAAgBA,EAGd,EAAE,eAAY,UAAU,GAAGC,KAAgC;CAC5D,OAAO,kBAACC,GAAD;EAAgC;EAAW,GAAID;CAAQ,CAAA;AAC/D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":[],"sources":["../../src/charts/config.ts"],"sourcesContent":["import { createElement, type ReactNode } from \"react\";\nimport { CHART_COLORS, chartAxis, withAlpha } from \"./palette\";\nimport type { ChartSeriesDescriptor } from \"./series\";\nimport { ChartTooltipContent, type ChartTooltipItem } from \"./tooltip\";\n\nexport type { ChartSeriesDescriptor } from \"./series\";\n\nexport type ChartTypeFace = \"axis\" | \"legend\" | \"tooltipTitle\" | \"tooltipBody\";\n\nexport const CHART_TYPE = {\n\taxisFontSize: 11,\n\tlegendFontSize: 12,\n\ttooltipTitleSize: 12,\n\ttooltipBodySize: 12,\n\ttooltipDot: 8,\n\tstrokeWidth: 2,\n\tgridDash: \"3 3\",\n\tgridOpacity: 0.15,\n\tareaFillAlpha: 0.2,\n} as const;\n\nexport function chartFontSize(face: ChartTypeFace): number {\n\tif (face === \"legend\") {\n\t\treturn CHART_TYPE.legendFontSize;\n\t}\n\tif (face === \"tooltipTitle\") {\n\t\treturn CHART_TYPE.tooltipTitleSize;\n\t}\n\tif (face === \"tooltipBody\") {\n\t\treturn CHART_TYPE.tooltipBodySize;\n\t}\n\treturn CHART_TYPE.axisFontSize;\n}\n\nexport function chartTextStyle(face: ChartTypeFace): { fontSize: number } {\n\treturn { fontSize: chartFontSize(face) };\n}\n\nexport function chartTickStyle(face: ChartTypeFace = \"axis\"): {\n\tfontSize: number;\n\tfill: string;\n} {\n\treturn { fontSize: chartFontSize(face), fill: chartAxis };\n}\n\nexport function getChartColor(index: number): string {\n\treturn CHART_COLORS[index % CHART_COLORS.length] ?? CHART_COLORS[0];\n}\n\nexport const AXIS_CONFIG = {\n\tget tick() {\n\t\treturn chartTickStyle(\"axis\");\n\t},\n\taxisLine: false as const,\n\ttickLine: false as const,\n};\n\nexport function cartesianAxisProps(hidden = false) {\n\treturn { hide: hidden, ...AXIS_CONFIG };\n}\n\nexport const GRID_PROPS = {\n\tvertical: false as const,\n\tstroke: chartAxis,\n\tstrokeOpacity: CHART_TYPE.gridOpacity,\n\tstrokeDasharray: CHART_TYPE.gridDash,\n};\n\nexport const BAR_RADIUS = {\n\thorizontal: [0, 4, 4, 0] as [number, number, number, number],\n\tvertical: [4, 4, 0, 0] as [number, number, number, number],\n};\n\nexport const ANIMATION_PROPS = {\n\tisAnimationActive: false,\n};\n\nexport const CHART_TOOLTIP_CURSOR_LINE = {\n\tstroke: chartAxis,\n\tstrokeOpacity: 0.35,\n\tstrokeWidth: 1,\n} as const;\n\nexport const CHART_TOOLTIP_CURSOR_BAR = {\n\tfill: withAlpha(\"foreground\", 0.06),\n\tstroke: \"none\",\n} as const;\n\nexport function chartTooltipContentStyle(): {\n\tbackground: string;\n\tborder: string;\n\tborderRadius: string;\n\tboxShadow: string;\n\tfontSize: number;\n\tcolor: string;\n\tpadding: string;\n} {\n\treturn {\n\t\tbackground: \"transparent\",\n\t\tborder: \"none\",\n\t\tborderRadius: \"0\",\n\t\tboxShadow: \"none\",\n\t\tfontSize: chartFontSize(\"tooltipBody\"),\n\t\tcolor: \"hsl(var(--basalt-foreground))\",\n\t\tpadding: \"0\",\n\t};\n}\n\nexport function chartTooltipProps(options?: {\n\tformatter?: (value: number) => string;\n\tcursor?: \"bar\" | \"line\" | false;\n\tcustomTooltip?: (props: {\n\t\tactive?: boolean;\n\t\tpayload?: readonly ChartTooltipItem[];\n\t\tlabel?: string | number;\n\t}) => ReactNode;\n}) {\n\tconst cursor =\n\t\toptions?.cursor === false\n\t\t\t? false\n\t\t\t: options?.cursor === \"line\"\n\t\t\t\t? CHART_TOOLTIP_CURSOR_LINE\n\t\t\t\t: CHART_TOOLTIP_CURSOR_BAR;\n\treturn {\n\t\tisAnimationActive: false,\n\t\tanimationDuration: 0,\n\t\toffset: 12,\n\t\tallowEscapeViewBox: { x: false, y: false },\n\t\tcursor,\n\t\twrapperStyle: {\n\t\t\toutline: \"none\",\n\t\t\tzIndex: 40,\n\t\t\tpointerEvents: \"none\" as const,\n\t\t\ttransition: \"none\",\n\t\t\tanimation: \"none\",\n\t\t},\n\t\tcontentStyle: chartTooltipContentStyle(),\n\t\tcontent: ((props: {\n\t\t\tactive?: boolean;\n\t\t\tpayload?: readonly ChartTooltipItem[];\n\t\t\tlabel?: unknown;\n\t\t}) => {\n\t\t\tif (options?.customTooltip) {\n\t\t\t\treturn options.customTooltip({\n\t\t\t\t\tactive: props.active,\n\t\t\t\t\tpayload: props.payload,\n\t\t\t\t\tlabel: props.label as string | number | undefined,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn createElement(ChartTooltipContent, {\n\t\t\t\tactive: props.active,\n\t\t\t\tpayload: props.payload,\n\t\t\t\tlabel: props.label as string | number | undefined,\n\t\t\t\tformatter: options?.formatter,\n\t\t\t});\n\t\t}) as never,\n\t};\n}\n\nexport function seriesColor(\n\tseries: ChartSeriesDescriptor | undefined,\n\tindex: number,\n): string | undefined {\n\treturn series?.color ?? CHART_COLORS[index % CHART_COLORS.length];\n}\n\nexport const RESPONSIVE_CONTAINER_PROPS = {\n\twidth: \"100%\" as const,\n\theight: \"100%\" as const,\n\tminWidth: 0,\n\tminHeight: 0,\n\tdebounce: 150,\n};\n\nexport const CHART_PLOT_MARGIN = {\n\ttop: 4,\n\tright: 4,\n\tbottom: 0,\n\tleft: 0,\n} as const;\n\nexport const CHART_PLOT_MARGIN_BARE = {\n\ttop: 2,\n\tright: 2,\n\tbottom: 2,\n\tleft: 2,\n} as const;\n"],"mappings":";;;;;AASA,
|
|
1
|
+
{"version":3,"file":"config.js","names":["CHART_TYPE","chartFontSize","face","chartTextStyle","chartTickStyle","chartAxis","getChartColor","CHART_COLORS","index","AXIS_CONFIG","cartesianAxisProps","hidden","GRID_PROPS","BAR_RADIUS","ANIMATION_PROPS","CHART_TOOLTIP_CURSOR_LINE","CHART_TOOLTIP_CURSOR_BAR","withAlpha","chartTooltipContentStyle","chartTooltipProps","options","props","createElement","ChartTooltipContent","seriesColor","series","RESPONSIVE_CONTAINER_PROPS","CHART_PLOT_MARGIN","CHART_PLOT_MARGIN_BARE"],"sources":["../../src/charts/config.ts"],"sourcesContent":["import { createElement, type ReactNode } from \"react\";\nimport { CHART_COLORS, chartAxis, withAlpha } from \"./palette\";\nimport type { ChartSeriesDescriptor } from \"./series\";\nimport { ChartTooltipContent, type ChartTooltipItem } from \"./tooltip\";\n\nexport type { ChartSeriesDescriptor } from \"./series\";\n\nexport type ChartTypeFace = \"axis\" | \"legend\" | \"tooltipTitle\" | \"tooltipBody\";\n\nexport const CHART_TYPE = {\n\taxisFontSize: 11,\n\tlegendFontSize: 12,\n\ttooltipTitleSize: 12,\n\ttooltipBodySize: 12,\n\ttooltipDot: 8,\n\tstrokeWidth: 2,\n\tgridDash: \"3 3\",\n\tgridOpacity: 0.15,\n\tareaFillAlpha: 0.2,\n} as const;\n\nexport function chartFontSize(face: ChartTypeFace): number {\n\tif (face === \"legend\") {\n\t\treturn CHART_TYPE.legendFontSize;\n\t}\n\tif (face === \"tooltipTitle\") {\n\t\treturn CHART_TYPE.tooltipTitleSize;\n\t}\n\tif (face === \"tooltipBody\") {\n\t\treturn CHART_TYPE.tooltipBodySize;\n\t}\n\treturn CHART_TYPE.axisFontSize;\n}\n\nexport function chartTextStyle(face: ChartTypeFace): { fontSize: number } {\n\treturn { fontSize: chartFontSize(face) };\n}\n\nexport function chartTickStyle(face: ChartTypeFace = \"axis\"): {\n\tfontSize: number;\n\tfill: string;\n} {\n\treturn { fontSize: chartFontSize(face), fill: chartAxis };\n}\n\nexport function getChartColor(index: number): string {\n\treturn CHART_COLORS[index % CHART_COLORS.length] ?? CHART_COLORS[0];\n}\n\nexport const AXIS_CONFIG = {\n\tget tick() {\n\t\treturn chartTickStyle(\"axis\");\n\t},\n\taxisLine: false as const,\n\ttickLine: false as const,\n};\n\nexport function cartesianAxisProps(hidden = false) {\n\treturn { hide: hidden, ...AXIS_CONFIG };\n}\n\nexport const GRID_PROPS = {\n\tvertical: false as const,\n\tstroke: chartAxis,\n\tstrokeOpacity: CHART_TYPE.gridOpacity,\n\tstrokeDasharray: CHART_TYPE.gridDash,\n};\n\nexport const BAR_RADIUS = {\n\thorizontal: [0, 4, 4, 0] as [number, number, number, number],\n\tvertical: [4, 4, 0, 0] as [number, number, number, number],\n};\n\nexport const ANIMATION_PROPS = {\n\tisAnimationActive: false,\n};\n\nexport const CHART_TOOLTIP_CURSOR_LINE = {\n\tstroke: chartAxis,\n\tstrokeOpacity: 0.35,\n\tstrokeWidth: 1,\n} as const;\n\nexport const CHART_TOOLTIP_CURSOR_BAR = {\n\tfill: withAlpha(\"foreground\", 0.06),\n\tstroke: \"none\",\n} as const;\n\nexport function chartTooltipContentStyle(): {\n\tbackground: string;\n\tborder: string;\n\tborderRadius: string;\n\tboxShadow: string;\n\tfontSize: number;\n\tcolor: string;\n\tpadding: string;\n} {\n\treturn {\n\t\tbackground: \"transparent\",\n\t\tborder: \"none\",\n\t\tborderRadius: \"0\",\n\t\tboxShadow: \"none\",\n\t\tfontSize: chartFontSize(\"tooltipBody\"),\n\t\tcolor: \"hsl(var(--basalt-foreground))\",\n\t\tpadding: \"0\",\n\t};\n}\n\nexport function chartTooltipProps(options?: {\n\tformatter?: (value: number) => string;\n\tcursor?: \"bar\" | \"line\" | false;\n\tcustomTooltip?: (props: {\n\t\tactive?: boolean;\n\t\tpayload?: readonly ChartTooltipItem[];\n\t\tlabel?: string | number;\n\t}) => ReactNode;\n}) {\n\tconst cursor =\n\t\toptions?.cursor === false\n\t\t\t? false\n\t\t\t: options?.cursor === \"line\"\n\t\t\t\t? CHART_TOOLTIP_CURSOR_LINE\n\t\t\t\t: CHART_TOOLTIP_CURSOR_BAR;\n\treturn {\n\t\tisAnimationActive: false,\n\t\tanimationDuration: 0,\n\t\toffset: 12,\n\t\tallowEscapeViewBox: { x: false, y: false },\n\t\tcursor,\n\t\twrapperStyle: {\n\t\t\toutline: \"none\",\n\t\t\tzIndex: 40,\n\t\t\tpointerEvents: \"none\" as const,\n\t\t\ttransition: \"none\",\n\t\t\tanimation: \"none\",\n\t\t},\n\t\tcontentStyle: chartTooltipContentStyle(),\n\t\tcontent: ((props: {\n\t\t\tactive?: boolean;\n\t\t\tpayload?: readonly ChartTooltipItem[];\n\t\t\tlabel?: unknown;\n\t\t}) => {\n\t\t\tif (options?.customTooltip) {\n\t\t\t\treturn options.customTooltip({\n\t\t\t\t\tactive: props.active,\n\t\t\t\t\tpayload: props.payload,\n\t\t\t\t\tlabel: props.label as string | number | undefined,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn createElement(ChartTooltipContent, {\n\t\t\t\tactive: props.active,\n\t\t\t\tpayload: props.payload,\n\t\t\t\tlabel: props.label as string | number | undefined,\n\t\t\t\tformatter: options?.formatter,\n\t\t\t});\n\t\t}) as never,\n\t};\n}\n\nexport function seriesColor(\n\tseries: ChartSeriesDescriptor | undefined,\n\tindex: number,\n): string | undefined {\n\treturn series?.color ?? CHART_COLORS[index % CHART_COLORS.length];\n}\n\nexport const RESPONSIVE_CONTAINER_PROPS = {\n\twidth: \"100%\" as const,\n\theight: \"100%\" as const,\n\tminWidth: 0,\n\tminHeight: 0,\n\tdebounce: 150,\n};\n\nexport const CHART_PLOT_MARGIN = {\n\ttop: 4,\n\tright: 4,\n\tbottom: 0,\n\tleft: 0,\n} as const;\n\nexport const CHART_PLOT_MARGIN_BARE = {\n\ttop: 2,\n\tright: 2,\n\tbottom: 2,\n\tleft: 2,\n} as const;\n"],"mappings":";;;;;AASA,IAAaA,IAAa;CACzB,cAAc;CACd,gBAAgB;CAChB,kBAAkB;CAClB,iBAAiB;CACjB,YAAY;CACZ,aAAa;CACb,UAAU;CACV,aAAa;CACb,eAAe;AAChB;AAEA,SAAgBC,EAAc,GAA6B;CAU1D,OATIC,MAAS,WACLF,EAAW,iBAEfE,MAAS,iBACLF,EAAW,mBAEfE,MAAS,gBACLF,EAAW,kBAEZA,EAAW;AACnB;AAEA,SAAgBG,EAAe,GAA2C;CACzE,OAAO,EAAE,UAAUF,EAAcC,CAAI,EAAE;AACxC;AAEA,SAAgBE,EAAe,IAAsB,QAGnD;CACD,OAAO;EAAE,UAAUH,EAAcC,CAAI;EAAG,MAAMG;CAAU;AACzD;AAEA,SAAgBC,EAAc,GAAuB;CACpD,OAAOC,EAAaC,IAAQD,EAAa,WAAWA,EAAa;AAClE;AAEA,IAAaE,IAAc;CAC1B,IAAI,OAAO;EACV,OAAOL,EAAe,MAAM;CAC7B;CACA,UAAU;CACV,UAAU;AACX;AAEA,SAAgBM,EAAmB,IAAS,IAAO;CAClD,OAAO;EAAE,MAAMC;EAAQ,GAAGF;CAAY;AACvC;AAEA,IAAaG,IAAa;CACzB,UAAU;CACV,QAAQP;CACR,eAAeL,EAAW;CAC1B,iBAAiBA,EAAW;AAC7B,GAEaa,IAAa;CACzB,YAAY;EAAC;EAAG;EAAG;EAAG;CAAC;CACvB,UAAU;EAAC;EAAG;EAAG;EAAG;CAAC;AACtB,GAEaC,IAAkB,EAC9B,mBAAmB,GACpB,GAEaC,IAA4B;CACxC,QAAQV;CACR,eAAe;CACf,aAAa;AACd,GAEaW,IAA2B;CACvC,MAAMC,EAAU,cAAc,GAAI;CAClC,QAAQ;AACT;AAEA,SAAgBC,IAQd;CACD,OAAO;EACN,YAAY;EACZ,QAAQ;EACR,cAAc;EACd,WAAW;EACX,UAAUjB,EAAc,aAAa;EACrC,OAAO;EACP,SAAS;CACV;AACD;AAEA,SAAgBkB,EAAkB,GAQ/B;CAOF,OAAO;EACN,mBAAmB;EACnB,mBAAmB;EACnB,QAAQ;EACR,oBAAoB;GAAE,GAAG;GAAO,GAAG;EAAM;EACzC,QAVAC,GAAS,WAAW,KACjB,KACAA,GAAS,WAAW,SACnBL,IACAC;EAOJ,cAAc;GACb,SAAS;GACT,QAAQ;GACR,eAAe;GACf,YAAY;GACZ,WAAW;EACZ;EACA,cAAcE,EAAyB;EACvC,WAAW,MAKNE,GAAS,gBACLA,EAAQ,cAAc;GAC5B,QAAQC,EAAM;GACd,SAASA,EAAM;GACf,OAAOA,EAAM;EACd,CAAC,IAEKC,EAAcC,GAAqB;GACzC,QAAQF,EAAM;GACd,SAASA,EAAM;GACf,OAAOA,EAAM;GACb,WAAWD,GAAS;EACrB,CAAC;CAEH;AACD;AAEA,SAAgBI,EACf,GACA,GACqB;CACrB,OAAOC,GAAQ,SAASlB,EAAaC,IAAQD,EAAa;AAC3D;AAEA,IAAamB,IAA6B;CACzC,OAAO;CACP,QAAQ;CACR,UAAU;CACV,WAAW;CACX,UAAU;AACX,GAEaC,IAAoB;CAChC,KAAK;CACL,OAAO;CACP,QAAQ;CACR,MAAM;AACP,GAEaC,IAAyB;CACrC,KAAK;CACL,OAAO;CACP,QAAQ;CACR,MAAM;AACP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-chart.js","names":[],"sources":["../../src/charts/custom-chart.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport {\n\tLineChart,\n\ttype LineChartAxisDomain,\n\ttype LineChartLegendRenderer,\n\ttype LineChartNumericKeys,\n\ttype LineChartTooltipRenderer,\n} from \"./line\";\nimport type { ChartSeriesDescriptor, XYPoint } from \"./series\";\n\nexport type CustomChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function CustomChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({ ariaLabel = \"Custom chart\", ...props }: CustomChartProps<TData, K>) {\n\treturn <LineChart<TData, K> ariaLabel={ariaLabel} {...props} />;\n}\n"],"mappings":";;;;AAmEA,
|
|
1
|
+
{"version":3,"file":"custom-chart.js","names":["CustomChart","props","LineChart"],"sources":["../../src/charts/custom-chart.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport {\n\tLineChart,\n\ttype LineChartAxisDomain,\n\ttype LineChartLegendRenderer,\n\ttype LineChartNumericKeys,\n\ttype LineChartTooltipRenderer,\n} from \"./line\";\nimport type { ChartSeriesDescriptor, XYPoint } from \"./series\";\n\nexport type CustomChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function CustomChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({ ariaLabel = \"Custom chart\", ...props }: CustomChartProps<TData, K>) {\n\treturn <LineChart<TData, K> ariaLabel={ariaLabel} {...props} />;\n}\n"],"mappings":";;;;AAmEA,SAAgBA,EAGd,EAAE,eAAY,gBAAgB,GAAGC,KAAqC;CACvE,OAAO,kBAACC,GAAD;EAAgC;EAAW,GAAID;CAAQ,CAAA;AAC/D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-navigation.js","names":[],"sources":["../../src/charts/date-navigation.tsx"],"sourcesContent":["import { Calendar as CalendarIcon, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { type ComponentProps, useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { DatePicker } from \"../components/date-picker\";\nimport { cn } from \"../utils/cn\";\n\nfunction shiftIso(value: string, delta: number) {\n\tconst match = /^(\\d{4,})-(\\d{2})-(\\d{2})$/.exec(value);\n\tconst date = match\n\t\t? new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]))\n\t\t: new Date();\n\tdate.setDate(date.getDate() + delta);\n\tconst year = date.getFullYear();\n\tconst month = String(date.getMonth() + 1).padStart(2, \"0\");\n\tconst day = String(date.getDate()).padStart(2, \"0\");\n\treturn `${year}-${month}-${day}`;\n}\n\nfunction civilInZone(date: Date, timeZone?: string) {\n\tconst parts = new Intl.DateTimeFormat(\"en-CA\", {\n\t\ttimeZone,\n\t\tyear: \"numeric\",\n\t\tmonth: \"2-digit\",\n\t\tday: \"2-digit\",\n\t}).formatToParts(date);\n\tconst read = (type: Intl.DateTimeFormatPartTypes) =>\n\t\tNumber(parts.find((part) => part.type === type)?.value);\n\treturn { y: read(\"year\"), m: read(\"month\"), d: read(\"day\") };\n}\n\nfunction isSameCivil(\n\tleft: { y: number; m: number; d: number },\n\tright: { y: number; m: number; d: number },\n) {\n\treturn left.y === right.y && left.m === right.m && left.d === right.d;\n}\n\ntype PickerProps = ComponentProps<typeof DatePicker> & {\n\tariaLabel?: string;\n\tselectedDate?: undefined;\n};\n\ntype DisplayProps = {\n\tselectedDate: Date;\n\tonPrevDay: () => void;\n\tonNextDay: () => void;\n\tonToday: () => void;\n\tonToggleCalendar?: () => void;\n\ttodayLabel?: string;\n\tpreviousDayLabel?: string;\n\tnextDayLabel?: string;\n\tformatDate?: (date: Date) => string;\n\tlocale?: string;\n\ttimeZone?: string;\n\tclassName?: string;\n};\n\nexport type DateNavigationPickerProps = {\n\tariaLabel?: string;\n\tclassName?: string;\n};\n\nexport type DateNavigationDisplayProps = DisplayProps;\n\nexport function DateNavigation(props: PickerProps | DisplayProps) {\n\tif (\"onPrevDay\" in props) {\n\t\treturn <DateNavigationDisplay {...props} />;\n\t}\n\treturn <DateNavigationPicker {...props} />;\n}\n\nfunction DateNavigationPicker({\n\tvalue,\n\tdefaultValue = \"\",\n\tonChange,\n\tdisabled,\n\tariaLabel,\n\t\"aria-label\": ariaLabelAttr,\n\t...props\n}: PickerProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(value ?? defaultValue);\n\tconst selected = value ?? uncontrolled;\n\tfunction commit(next: string) {\n\t\tif (value === undefined) {\n\t\t\tsetUncontrolled(next);\n\t\t}\n\t\tonChange?.(next);\n\t}\n\treturn (\n\t\t<div className=\"inline-flex items-center gap-1\">\n\t\t\t<Button\n\t\t\t\tvariant=\"outline\"\n\t\t\t\tsize=\"icon\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label=\"Previous day\"\n\t\t\t\tonClick={() => commit(shiftIso(selected, -1))}\n\t\t\t>\n\t\t\t\t<ChevronLeft />\n\t\t\t</Button>\n\t\t\t<DatePicker\n\t\t\t\t{...props}\n\t\t\t\tvalue={selected}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonChange={commit}\n\t\t\t\taria-label={ariaLabel ?? ariaLabelAttr ?? \"Date navigation\"}\n\t\t\t/>\n\t\t\t<Button\n\t\t\t\tvariant=\"outline\"\n\t\t\t\tsize=\"icon\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label=\"Next day\"\n\t\t\t\tonClick={() => commit(shiftIso(selected, 1))}\n\t\t\t>\n\t\t\t\t<ChevronRight />\n\t\t\t</Button>\n\t\t</div>\n\t);\n}\n\nfunction DateNavigationDisplay({\n\tselectedDate,\n\tonPrevDay,\n\tonNextDay,\n\tonToday,\n\tonToggleCalendar,\n\ttodayLabel = \"Today\",\n\tpreviousDayLabel = \"Previous day\",\n\tnextDayLabel = \"Next day\",\n\tformatDate,\n\tlocale = \"en-US\",\n\ttimeZone,\n\tclassName,\n}: DisplayProps) {\n\tconst resolvedFormatDate =\n\t\tformatDate ??\n\t\t((date: Date) =>\n\t\t\tdate.toLocaleDateString(locale, {\n\t\t\t\tweekday: \"short\",\n\t\t\t\tyear: \"numeric\",\n\t\t\t\tmonth: \"short\",\n\t\t\t\tday: \"numeric\",\n\t\t\t\ttimeZone,\n\t\t\t}));\n\tconst isToday = isSameCivil(\n\t\tcivilInZone(selectedDate, timeZone),\n\t\tcivilInZone(new Date(), timeZone),\n\t);\n\tconst formatted = resolvedFormatDate(selectedDate);\n\treturn (\n\t\t<div className={cn(\"flex items-center justify-center gap-2\", className)}>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onToday}\n\t\t\t\tdisabled={isToday}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"mr-2 rounded-lg px-3 py-1.5 text-sm font-medium transition-colors\",\n\t\t\t\t\tisToday\n\t\t\t\t\t\t? \"cursor-not-allowed text-basalt-muted-foreground opacity-50\"\n\t\t\t\t\t\t: \"bg-basalt-secondary text-basalt-foreground hover:bg-basalt-accent\",\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{todayLabel}\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onPrevDay}\n\t\t\t\taria-label={previousDayLabel}\n\t\t\t\tclassName=\"flex h-8 w-8 items-center justify-center rounded-lg text-basalt-muted-foreground transition-colors hover:bg-basalt-accent hover:text-basalt-foreground\"\n\t\t\t>\n\t\t\t\t<ChevronLeft className=\"h-4 w-4\" strokeWidth={1.5} />\n\t\t\t</button>\n\t\t\t{onToggleCalendar ? (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={onToggleCalendar}\n\t\t\t\t\tclassName=\"flex cursor-pointer items-center gap-2 rounded-lg px-3 py-1.5 text-lg font-medium transition-colors hover:bg-basalt-accent\"\n\t\t\t\t>\n\t\t\t\t\t<span>{formatted}</span>\n\t\t\t\t\t<CalendarIcon className=\"h-4 w-4 text-basalt-muted-foreground\" strokeWidth={1.5} />\n\t\t\t\t</button>\n\t\t\t) : (\n\t\t\t\t<span className=\"flex items-center gap-2 rounded-lg px-3 py-1.5 text-lg font-medium\">\n\t\t\t\t\t{formatted}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onNextDay}\n\t\t\t\taria-label={nextDayLabel}\n\t\t\t\tclassName=\"flex h-8 w-8 items-center justify-center rounded-lg text-basalt-muted-foreground transition-colors hover:bg-basalt-accent hover:text-basalt-foreground\"\n\t\t\t>\n\t\t\t\t<ChevronRight className=\"h-4 w-4\" strokeWidth={1.5} />\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;;AAMA,
|
|
1
|
+
{"version":3,"file":"date-navigation.js","names":["CalendarIcon","shiftIso","match","value","date","delta","civilInZone","parts","read","part","type","isSameCivil","left","right","DateNavigation","props","DateNavigationDisplay","DateNavigationPicker","ariaLabelAttr","uncontrolled","setUncontrolled","useState","defaultValue","selected","commit","next","onChange","Button","ChevronLeft","DatePicker","ariaLabel","ChevronRight","resolvedFormatDate","formatDate","locale","isToday","selectedDate","timeZone","formatted","cn","className","onToday","todayLabel","onPrevDay","previousDayLabel","onToggleCalendar","Calendar","onNextDay","nextDayLabel"],"sources":["../../src/charts/date-navigation.tsx"],"sourcesContent":["import { Calendar as CalendarIcon, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { type ComponentProps, useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { DatePicker } from \"../components/date-picker\";\nimport { cn } from \"../utils/cn\";\n\nfunction shiftIso(value: string, delta: number) {\n\tconst match = /^(\\d{4,})-(\\d{2})-(\\d{2})$/.exec(value);\n\tconst date = match\n\t\t? new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]))\n\t\t: new Date();\n\tdate.setDate(date.getDate() + delta);\n\tconst year = date.getFullYear();\n\tconst month = String(date.getMonth() + 1).padStart(2, \"0\");\n\tconst day = String(date.getDate()).padStart(2, \"0\");\n\treturn `${year}-${month}-${day}`;\n}\n\nfunction civilInZone(date: Date, timeZone?: string) {\n\tconst parts = new Intl.DateTimeFormat(\"en-CA\", {\n\t\ttimeZone,\n\t\tyear: \"numeric\",\n\t\tmonth: \"2-digit\",\n\t\tday: \"2-digit\",\n\t}).formatToParts(date);\n\tconst read = (type: Intl.DateTimeFormatPartTypes) =>\n\t\tNumber(parts.find((part) => part.type === type)?.value);\n\treturn { y: read(\"year\"), m: read(\"month\"), d: read(\"day\") };\n}\n\nfunction isSameCivil(\n\tleft: { y: number; m: number; d: number },\n\tright: { y: number; m: number; d: number },\n) {\n\treturn left.y === right.y && left.m === right.m && left.d === right.d;\n}\n\ntype PickerProps = ComponentProps<typeof DatePicker> & {\n\tariaLabel?: string;\n\tselectedDate?: undefined;\n};\n\ntype DisplayProps = {\n\tselectedDate: Date;\n\tonPrevDay: () => void;\n\tonNextDay: () => void;\n\tonToday: () => void;\n\tonToggleCalendar?: () => void;\n\ttodayLabel?: string;\n\tpreviousDayLabel?: string;\n\tnextDayLabel?: string;\n\tformatDate?: (date: Date) => string;\n\tlocale?: string;\n\ttimeZone?: string;\n\tclassName?: string;\n};\n\nexport type DateNavigationPickerProps = {\n\tariaLabel?: string;\n\tclassName?: string;\n};\n\nexport type DateNavigationDisplayProps = DisplayProps;\n\nexport function DateNavigation(props: PickerProps | DisplayProps) {\n\tif (\"onPrevDay\" in props) {\n\t\treturn <DateNavigationDisplay {...props} />;\n\t}\n\treturn <DateNavigationPicker {...props} />;\n}\n\nfunction DateNavigationPicker({\n\tvalue,\n\tdefaultValue = \"\",\n\tonChange,\n\tdisabled,\n\tariaLabel,\n\t\"aria-label\": ariaLabelAttr,\n\t...props\n}: PickerProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(value ?? defaultValue);\n\tconst selected = value ?? uncontrolled;\n\tfunction commit(next: string) {\n\t\tif (value === undefined) {\n\t\t\tsetUncontrolled(next);\n\t\t}\n\t\tonChange?.(next);\n\t}\n\treturn (\n\t\t<div className=\"inline-flex items-center gap-1\">\n\t\t\t<Button\n\t\t\t\tvariant=\"outline\"\n\t\t\t\tsize=\"icon\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label=\"Previous day\"\n\t\t\t\tonClick={() => commit(shiftIso(selected, -1))}\n\t\t\t>\n\t\t\t\t<ChevronLeft />\n\t\t\t</Button>\n\t\t\t<DatePicker\n\t\t\t\t{...props}\n\t\t\t\tvalue={selected}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonChange={commit}\n\t\t\t\taria-label={ariaLabel ?? ariaLabelAttr ?? \"Date navigation\"}\n\t\t\t/>\n\t\t\t<Button\n\t\t\t\tvariant=\"outline\"\n\t\t\t\tsize=\"icon\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label=\"Next day\"\n\t\t\t\tonClick={() => commit(shiftIso(selected, 1))}\n\t\t\t>\n\t\t\t\t<ChevronRight />\n\t\t\t</Button>\n\t\t</div>\n\t);\n}\n\nfunction DateNavigationDisplay({\n\tselectedDate,\n\tonPrevDay,\n\tonNextDay,\n\tonToday,\n\tonToggleCalendar,\n\ttodayLabel = \"Today\",\n\tpreviousDayLabel = \"Previous day\",\n\tnextDayLabel = \"Next day\",\n\tformatDate,\n\tlocale = \"en-US\",\n\ttimeZone,\n\tclassName,\n}: DisplayProps) {\n\tconst resolvedFormatDate =\n\t\tformatDate ??\n\t\t((date: Date) =>\n\t\t\tdate.toLocaleDateString(locale, {\n\t\t\t\tweekday: \"short\",\n\t\t\t\tyear: \"numeric\",\n\t\t\t\tmonth: \"short\",\n\t\t\t\tday: \"numeric\",\n\t\t\t\ttimeZone,\n\t\t\t}));\n\tconst isToday = isSameCivil(\n\t\tcivilInZone(selectedDate, timeZone),\n\t\tcivilInZone(new Date(), timeZone),\n\t);\n\tconst formatted = resolvedFormatDate(selectedDate);\n\treturn (\n\t\t<div className={cn(\"flex items-center justify-center gap-2\", className)}>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onToday}\n\t\t\t\tdisabled={isToday}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"mr-2 rounded-lg px-3 py-1.5 text-sm font-medium transition-colors\",\n\t\t\t\t\tisToday\n\t\t\t\t\t\t? \"cursor-not-allowed text-basalt-muted-foreground opacity-50\"\n\t\t\t\t\t\t: \"bg-basalt-secondary text-basalt-foreground hover:bg-basalt-accent\",\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{todayLabel}\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onPrevDay}\n\t\t\t\taria-label={previousDayLabel}\n\t\t\t\tclassName=\"flex h-8 w-8 items-center justify-center rounded-lg text-basalt-muted-foreground transition-colors hover:bg-basalt-accent hover:text-basalt-foreground\"\n\t\t\t>\n\t\t\t\t<ChevronLeft className=\"h-4 w-4\" strokeWidth={1.5} />\n\t\t\t</button>\n\t\t\t{onToggleCalendar ? (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={onToggleCalendar}\n\t\t\t\t\tclassName=\"flex cursor-pointer items-center gap-2 rounded-lg px-3 py-1.5 text-lg font-medium transition-colors hover:bg-basalt-accent\"\n\t\t\t\t>\n\t\t\t\t\t<span>{formatted}</span>\n\t\t\t\t\t<CalendarIcon className=\"h-4 w-4 text-basalt-muted-foreground\" strokeWidth={1.5} />\n\t\t\t\t</button>\n\t\t\t) : (\n\t\t\t\t<span className=\"flex items-center gap-2 rounded-lg px-3 py-1.5 text-lg font-medium\">\n\t\t\t\t\t{formatted}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onNextDay}\n\t\t\t\taria-label={nextDayLabel}\n\t\t\t\tclassName=\"flex h-8 w-8 items-center justify-center rounded-lg text-basalt-muted-foreground transition-colors hover:bg-basalt-accent hover:text-basalt-foreground\"\n\t\t\t>\n\t\t\t\t<ChevronRight className=\"h-4 w-4\" strokeWidth={1.5} />\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
package/dist/charts/donut.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"donut.js","names":[],"sources":["../../src/charts/donut.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Cell, Pie, PieChart, Tooltip } from \"recharts\";\nimport { ANIMATION_PROPS, chartTooltipProps, seriesColor } from \"./config\";\nimport { ChartShell } from \"./frame\";\nimport { ChartLegend } from \"./legend\";\nimport type { ChartSeriesDescriptor, NamedValue } from \"./series\";\n\nexport type DonutChartProps = {\n\tdata: NamedValue[];\n\tseries?: ChartSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowLegend?: boolean;\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function DonutChart({\n\tdata,\n\tseries,\n\tariaLabel = \"Donut chart\",\n\tclassName,\n\tshowLegend = false,\n\tvalueFormatter,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: DonutChartProps) {\n\tconst legendItems = data.map((entry, index) => {\n\t\tconst item = series?.find((candidate) => candidate.key === entry.name);\n\t\treturn {\n\t\t\tkey: `${entry.name}-${index}`,\n\t\t\tlabel: item?.label ?? entry.name,\n\t\t\tcolor: seriesColor(item, index),\n\t\t};\n\t});\n\treturn (\n\t\t<ChartShell\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsize=\"h-36 w-36\"\n\t\t\tlegend={showLegend ? <ChartLegend items={legendItems} shape=\"bar\" /> : undefined}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<PieChart>\n\t\t\t\t<Pie\n\t\t\t\t\tdata={data}\n\t\t\t\t\tdataKey=\"value\"\n\t\t\t\t\tnameKey=\"name\"\n\t\t\t\t\tinnerRadius={24}\n\t\t\t\t\touterRadius={48}\n\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t>\n\t\t\t\t\t{data.map((entry, index) => {\n\t\t\t\t\t\tconst item = series?.find((candidate) => candidate.key === entry.name);\n\t\t\t\t\t\treturn <Cell key={`${entry.name}-${index}`} fill={seriesColor(item, index)} />;\n\t\t\t\t\t})}\n\t\t\t\t</Pie>\n\t\t\t\t<Tooltip {...chartTooltipProps({ formatter: valueFormatter, cursor: false })} />\n\t\t\t</PieChart>\n\t\t</ChartShell>\n\t);\n}\n"],"mappings":";;;;;;;AAgCA,
|
|
1
|
+
{"version":3,"file":"donut.js","names":["DonutChart","legendItems","data","item","series","candidate","entry","index","seriesColor","ChartShell","showLegend","ChartLegend","PieChart","Pie","ANIMATION_PROPS","Cell","Tooltip","chartTooltipProps","valueFormatter"],"sources":["../../src/charts/donut.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Cell, Pie, PieChart, Tooltip } from \"recharts\";\nimport { ANIMATION_PROPS, chartTooltipProps, seriesColor } from \"./config\";\nimport { ChartShell } from \"./frame\";\nimport { ChartLegend } from \"./legend\";\nimport type { ChartSeriesDescriptor, NamedValue } from \"./series\";\n\nexport type DonutChartProps = {\n\tdata: NamedValue[];\n\tseries?: ChartSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowLegend?: boolean;\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function DonutChart({\n\tdata,\n\tseries,\n\tariaLabel = \"Donut chart\",\n\tclassName,\n\tshowLegend = false,\n\tvalueFormatter,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: DonutChartProps) {\n\tconst legendItems = data.map((entry, index) => {\n\t\tconst item = series?.find((candidate) => candidate.key === entry.name);\n\t\treturn {\n\t\t\tkey: `${entry.name}-${index}`,\n\t\t\tlabel: item?.label ?? entry.name,\n\t\t\tcolor: seriesColor(item, index),\n\t\t};\n\t});\n\treturn (\n\t\t<ChartShell\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsize=\"h-36 w-36\"\n\t\t\tlegend={showLegend ? <ChartLegend items={legendItems} shape=\"bar\" /> : undefined}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<PieChart>\n\t\t\t\t<Pie\n\t\t\t\t\tdata={data}\n\t\t\t\t\tdataKey=\"value\"\n\t\t\t\t\tnameKey=\"name\"\n\t\t\t\t\tinnerRadius={24}\n\t\t\t\t\touterRadius={48}\n\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t>\n\t\t\t\t\t{data.map((entry, index) => {\n\t\t\t\t\t\tconst item = series?.find((candidate) => candidate.key === entry.name);\n\t\t\t\t\t\treturn <Cell key={`${entry.name}-${index}`} fill={seriesColor(item, index)} />;\n\t\t\t\t\t})}\n\t\t\t\t</Pie>\n\t\t\t\t<Tooltip {...chartTooltipProps({ formatter: valueFormatter, cursor: false })} />\n\t\t\t</PieChart>\n\t\t</ChartShell>\n\t);\n}\n"],"mappings":";;;;;;;AAgCA,SAAgBA,EAAW,EAC1B,SACA,WACA,eAAY,eACZ,cACA,gBAAa,IACb,mBACA,YACA,oBACA,yBACmB;CACnB,IAAMC,IAAcC,EAAK,KAAK,GAAO,MAAU;EAC9C,IAAMC,IAAOC,GAAQ,MAAM,MAAcC,EAAU,QAAQC,EAAM,IAAI;EACrE,OAAO;GACN,KAAK,GAAGA,EAAM,KAAK,GAAGC;GACtB,OAAOJ,GAAM,SAASG,EAAM;GAC5B,OAAOE,EAAYL,GAAMI,CAAK;EAC/B;CACD,CAAC;CACD,OACC,kBAACE,GAAD;EACY;EACA;EACX,MAAK;EACL,QAAQC,IAAa,kBAACC,GAAD;GAAa,OAAOV;GAAa,OAAM;EAAO,CAAA,IAAI,KAAA;EAC9D;EACQ;EACG;EAEpB,UAAA,kBAACW,GAAD,EAAA,UAAA,CACC,kBAACC,GAAD;GACO;GACN,SAAQ;GACR,SAAQ;GACR,aAAa;GACb,aAAa;GACb,QAAO;GACP,GAAIC;GAEH,UAAAZ,EAAK,KAAK,GAAO,MAAU;IAC3B,IAAMC,IAAOC,GAAQ,MAAM,MAAcC,EAAU,QAAQC,EAAM,IAAI;IACrE,OAAO,kBAACS,GAAD,EAAqC,MAAMP,EAAYL,GAAMI,CAAK,EAAI,GAA3D,GAAGD,EAAM,KAAK,GAAGC,GAA0C;GAC9E,CAAC;EACG,CAAA,GACL,kBAACS,GAAD,EAAS,GAAIC,EAAkB;GAAE,WAAWC;GAAgB,QAAQ;EAAM,CAAC,EAAI,CAAA,CACtE,EAAA,CAAA;CACC,CAAA;AAEd"}
|
package/dist/charts/frame.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame.js","names":[],"sources":["../../src/charts/frame.tsx"],"sourcesContent":["import { cloneElement, type ReactElement, type ReactNode, useId } from \"react\";\nimport { ResponsiveContainer } from \"recharts\";\nimport { cn } from \"../utils/cn\";\nimport { RESPONSIVE_CONTAINER_PROPS } from \"./config\";\n\nexport type ChartFrameProps = {\n\t/**\n\t * Accessible label describing the purpose or dataset of the chart.\n\t */\n\tariaLabel: string;\n\t/**\n\t * Additional CSS class names for styling the chart container.\n\t */\n\tclassName?: string;\n\t/**\n\t * Single child Recharts element to render inside the responsive container.\n\t * Explicit child accessibilityLayer prop takes precedence over wrapper prop, which defaults to true.\n\t */\n\tchildren: ReactElement<{\n\t\taccessibilityLayer?: boolean;\n\t\t\"aria-label\"?: string;\n\t\t\"aria-describedby\"?: string;\n\t}>;\n\t/**\n\t * Tailwind size classes for the chart container.\n\t * @default \"h-36 w-56\"\n\t */\n\tsize?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport type ChartShellProps = ChartFrameProps & {\n\t/**\n\t * Optional legend node rendered alongside the chart plot.\n\t */\n\tlegend?: ReactNode;\n};\n\nexport type ChartAccessibilityProps = Pick<\n\tChartFrameProps,\n\t\"summary\" | \"dataAlternative\" | \"accessibilityLayer\"\n>;\n\nfunction hasSlotContent(slot: ReactNode | undefined): boolean {\n\treturn slot !== undefined && slot !== null && slot !== false;\n}\n\nfunction ChartContainer({\n\tariaLabel,\n\tclassName,\n\tchildren,\n\tsize = \"h-36 w-56\",\n\tlegend,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer = true,\n}: ChartShellProps) {\n\tconst summaryId = useId();\n\tconst hasSummary = hasSlotContent(summary);\n\tconst hasAlternative = hasSlotContent(dataAlternative);\n\n\tconst childProps = (children?.props ?? {}) as {\n\t\taccessibilityLayer?: boolean;\n\t\t\"aria-label\"?: string;\n\t\t\"aria-describedby\"?: string;\n\t};\n\tconst childLayer = childProps.accessibilityLayer;\n\tconst resolvedLayer = childLayer !== undefined ? childLayer : accessibilityLayer;\n\n\tconst clonedChild = cloneElement(children, {\n\t\taccessibilityLayer: resolvedLayer,\n\t\t\"aria-label\": childProps[\"aria-label\"] ?? ariaLabel,\n\t\t\"aria-describedby\": childProps[\"aria-describedby\"] ?? (hasSummary ? summaryId : undefined),\n\t});\n\n\tlet plotContainer: ReactNode;\n\tif (hasSlotContent(legend)) {\n\t\tplotContainer = (\n\t\t\t<div\n\t\t\t\tdata-testid=\"chart-shell\"\n\t\t\t\tclassName={cn(size, className)}\n\t\t\t\tstyle={{ display: \"flex\", flexDirection: \"column\", minHeight: 0, minWidth: 0 }}\n\t\t\t>\n\t\t\t\t<div className=\"min-h-0 w-full flex-1 basalt-chart [&_.recharts-surface:focus-visible]:outline-2 [&_.recharts-surface:focus-visible]:outline-offset-2 [&_.recharts-surface:focus-visible]:outline-basalt-ring\">\n\t\t\t\t\t<ResponsiveContainer {...RESPONSIVE_CONTAINER_PROPS}>{clonedChild}</ResponsiveContainer>\n\t\t\t\t</div>\n\t\t\t\t{legend}\n\t\t\t</div>\n\t\t);\n\t} else {\n\t\tplotContainer = (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\tsize,\n\t\t\t\t\t\"min-h-0 min-w-0 basalt-chart [&_.recharts-surface:focus-visible]:outline-2 [&_.recharts-surface:focus-visible]:outline-offset-2 [&_.recharts-surface:focus-visible]:outline-basalt-ring\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<ResponsiveContainer {...RESPONSIVE_CONTAINER_PROPS}>{clonedChild}</ResponsiveContainer>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!hasSummary && !hasAlternative) {\n\t\treturn (\n\t\t\t<figure role=\"group\" aria-label={ariaLabel} className=\"contents m-0 p-0\">\n\t\t\t\t{plotContainer}\n\t\t\t</figure>\n\t\t);\n\t}\n\n\treturn (\n\t\t<figure\n\t\t\trole=\"group\"\n\t\t\taria-label={ariaLabel}\n\t\t\taria-describedby={hasSummary ? summaryId : undefined}\n\t\t\tclassName=\"m-0 flex flex-col gap-2 p-0 min-h-0 min-w-0\"\n\t\t>\n\t\t\t{hasSummary ? (\n\t\t\t\t<div id={summaryId} className=\"text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t{summary}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{plotContainer}\n\t\t\t{hasAlternative ? (\n\t\t\t\t<div className=\"text-xs text-basalt-muted-foreground\">{dataAlternative}</div>\n\t\t\t) : null}\n\t\t</figure>\n\t);\n}\n\nexport function ChartFrame(props: ChartFrameProps) {\n\treturn <ChartContainer {...props} />;\n}\n\nexport function ChartShell(props: ChartShellProps) {\n\treturn <ChartContainer {...props} />;\n}\n"],"mappings":";;;;;;;AA0DA,
|
|
1
|
+
{"version":3,"file":"frame.js","names":["hasSlotContent","slot","ChartContainer","summaryId","useId","hasSummary","summary","hasAlternative","dataAlternative","childProps","children","childLayer","clonedChild","cloneElement","accessibilityLayer","ariaLabel","plotContainer","legend","cn","size","className","ResponsiveContainer","RESPONSIVE_CONTAINER_PROPS","ChartFrame","props","ChartShell"],"sources":["../../src/charts/frame.tsx"],"sourcesContent":["import { cloneElement, type ReactElement, type ReactNode, useId } from \"react\";\nimport { ResponsiveContainer } from \"recharts\";\nimport { cn } from \"../utils/cn\";\nimport { RESPONSIVE_CONTAINER_PROPS } from \"./config\";\n\nexport type ChartFrameProps = {\n\t/**\n\t * Accessible label describing the purpose or dataset of the chart.\n\t */\n\tariaLabel: string;\n\t/**\n\t * Additional CSS class names for styling the chart container.\n\t */\n\tclassName?: string;\n\t/**\n\t * Single child Recharts element to render inside the responsive container.\n\t * Explicit child accessibilityLayer prop takes precedence over wrapper prop, which defaults to true.\n\t */\n\tchildren: ReactElement<{\n\t\taccessibilityLayer?: boolean;\n\t\t\"aria-label\"?: string;\n\t\t\"aria-describedby\"?: string;\n\t}>;\n\t/**\n\t * Tailwind size classes for the chart container.\n\t * @default \"h-36 w-56\"\n\t */\n\tsize?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport type ChartShellProps = ChartFrameProps & {\n\t/**\n\t * Optional legend node rendered alongside the chart plot.\n\t */\n\tlegend?: ReactNode;\n};\n\nexport type ChartAccessibilityProps = Pick<\n\tChartFrameProps,\n\t\"summary\" | \"dataAlternative\" | \"accessibilityLayer\"\n>;\n\nfunction hasSlotContent(slot: ReactNode | undefined): boolean {\n\treturn slot !== undefined && slot !== null && slot !== false;\n}\n\nfunction ChartContainer({\n\tariaLabel,\n\tclassName,\n\tchildren,\n\tsize = \"h-36 w-56\",\n\tlegend,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer = true,\n}: ChartShellProps) {\n\tconst summaryId = useId();\n\tconst hasSummary = hasSlotContent(summary);\n\tconst hasAlternative = hasSlotContent(dataAlternative);\n\n\tconst childProps = (children?.props ?? {}) as {\n\t\taccessibilityLayer?: boolean;\n\t\t\"aria-label\"?: string;\n\t\t\"aria-describedby\"?: string;\n\t};\n\tconst childLayer = childProps.accessibilityLayer;\n\tconst resolvedLayer = childLayer !== undefined ? childLayer : accessibilityLayer;\n\n\tconst clonedChild = cloneElement(children, {\n\t\taccessibilityLayer: resolvedLayer,\n\t\t\"aria-label\": childProps[\"aria-label\"] ?? ariaLabel,\n\t\t\"aria-describedby\": childProps[\"aria-describedby\"] ?? (hasSummary ? summaryId : undefined),\n\t});\n\n\tlet plotContainer: ReactNode;\n\tif (hasSlotContent(legend)) {\n\t\tplotContainer = (\n\t\t\t<div\n\t\t\t\tdata-testid=\"chart-shell\"\n\t\t\t\tclassName={cn(size, className)}\n\t\t\t\tstyle={{ display: \"flex\", flexDirection: \"column\", minHeight: 0, minWidth: 0 }}\n\t\t\t>\n\t\t\t\t<div className=\"min-h-0 w-full flex-1 basalt-chart [&_.recharts-surface:focus-visible]:outline-2 [&_.recharts-surface:focus-visible]:outline-offset-2 [&_.recharts-surface:focus-visible]:outline-basalt-ring\">\n\t\t\t\t\t<ResponsiveContainer {...RESPONSIVE_CONTAINER_PROPS}>{clonedChild}</ResponsiveContainer>\n\t\t\t\t</div>\n\t\t\t\t{legend}\n\t\t\t</div>\n\t\t);\n\t} else {\n\t\tplotContainer = (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\tsize,\n\t\t\t\t\t\"min-h-0 min-w-0 basalt-chart [&_.recharts-surface:focus-visible]:outline-2 [&_.recharts-surface:focus-visible]:outline-offset-2 [&_.recharts-surface:focus-visible]:outline-basalt-ring\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<ResponsiveContainer {...RESPONSIVE_CONTAINER_PROPS}>{clonedChild}</ResponsiveContainer>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!hasSummary && !hasAlternative) {\n\t\treturn (\n\t\t\t<figure role=\"group\" aria-label={ariaLabel} className=\"contents m-0 p-0\">\n\t\t\t\t{plotContainer}\n\t\t\t</figure>\n\t\t);\n\t}\n\n\treturn (\n\t\t<figure\n\t\t\trole=\"group\"\n\t\t\taria-label={ariaLabel}\n\t\t\taria-describedby={hasSummary ? summaryId : undefined}\n\t\t\tclassName=\"m-0 flex flex-col gap-2 p-0 min-h-0 min-w-0\"\n\t\t>\n\t\t\t{hasSummary ? (\n\t\t\t\t<div id={summaryId} className=\"text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t{summary}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{plotContainer}\n\t\t\t{hasAlternative ? (\n\t\t\t\t<div className=\"text-xs text-basalt-muted-foreground\">{dataAlternative}</div>\n\t\t\t) : null}\n\t\t</figure>\n\t);\n}\n\nexport function ChartFrame(props: ChartFrameProps) {\n\treturn <ChartContainer {...props} />;\n}\n\nexport function ChartShell(props: ChartShellProps) {\n\treturn <ChartContainer {...props} />;\n}\n"],"mappings":";;;;;;;AA0DA,SAASA,EAAe,GAAsC;CAC7D,OAAOC,KAA+B,QAAQA,MAAS;AACxD;AAEA,SAASC,EAAe,EACvB,cACA,cACA,aACA,UAAO,aACP,WACA,YACA,oBACA,wBAAqB,MACF;CACnB,IAAMC,IAAYC,EAAM,GAClBC,IAAaL,EAAeM,CAAO,GACnCC,IAAiBP,EAAeQ,CAAe,GAE/CC,IAAcC,GAAU,SAAS,CAAC,GAKlCC,IAAaF,EAAW,oBAGxBG,IAAcC,EAAaH,GAAU;EAC1C,oBAHqBC,MAAe,KAAA,IAAyBG,IAAbH;EAIhD,cAAcF,EAAW,iBAAiBM;EAC1C,oBAAoBN,EAAW,wBAAwBJ,IAAaF,IAAY,KAAA;CACjF,CAAC,GAEGa;CAoCJ,OAnCA,AAcCA,IAdGhB,EAAeiB,CAAM,IAEvB,kBAAC,OAAD;EACC,eAAY;EACZ,WAAWC,EAAGC,GAAMC,CAAS;EAC7B,OAAO;GAAE,SAAS;GAAQ,eAAe;GAAU,WAAW;GAAG,UAAU;EAAE;EAH9E,UAAA,CAKC,kBAAC,OAAD;GAAK,WAAU;GACd,UAAA,kBAACC,GAAD;IAAqB,GAAIC;IAA6B,UAAAV;GAAiC,CAAA;EACnF,CAAA,GACJK,CACG;MAIL,kBAAC,OAAD;EACC,WAAWC,EACVC,GACA,2LACAC,CACD;EAEA,UAAA,kBAACC,GAAD;GAAqB,GAAIC;GAA6B,UAAAV;EAAiC,CAAA;CACnF,CAAA,GAIH,CAACP,KAAc,CAACE,IAElB,kBAAC,UAAD;EAAQ,MAAK;EAAQ,cAAYQ;EAAW,WAAU;EACpD,UAAAC;CACM,CAAA,IAKT,kBAAC,UAAD;EACC,MAAK;EACL,cAAYD;EACZ,oBAAkBV,IAAaF,IAAY,KAAA;EAC3C,WAAU;EAJX,UAAA;GAMEE,IACA,kBAAC,OAAD;IAAK,IAAIF;IAAW,WAAU;IAC5B,UAAAG;GACG,CAAA,IACF;GACHU;GACAT,IACA,kBAAC,OAAD;IAAK,WAAU;IAAwC,UAAAC;GAAqB,CAAA,IACzE;EACG;;AAEV;AAEA,SAAgBe,EAAW,GAAwB;CAClD,OAAO,kBAACrB,GAAD,EAAgB,GAAIsB,EAAQ,CAAA;AACpC;AAEA,SAAgBC,EAAW,GAAwB;CAClD,OAAO,kBAACvB,GAAD,EAAgB,GAAIsB,EAAQ,CAAA;AACpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"funnel.js","names":[],"sources":["../../src/charts/funnel.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Funnel, LabelList, FunnelChart as RechartsFunnel, Tooltip } from \"recharts\";\nimport { ANIMATION_PROPS, chartFontSize, chartTooltipProps, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport { chartAxis } from \"./palette\";\nimport type { ChartSeriesDescriptor, NamedValue } from \"./series\";\n\nexport type FunnelChartProps = {\n\tdata: NamedValue[];\n\tseries?: ChartSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function FunnelChart({\n\tdata,\n\tseries,\n\tariaLabel = \"Funnel chart\",\n\tclassName,\n\tvalueFormatter,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: FunnelChartProps) {\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsFunnel>\n\t\t\t\t<Tooltip {...chartTooltipProps({ formatter: valueFormatter, cursor: false })} />\n\t\t\t\t<Funnel\n\t\t\t\t\tdata={data}\n\t\t\t\t\tdataKey=\"value\"\n\t\t\t\t\tnameKey=\"name\"\n\t\t\t\t\tfill={seriesColor(series?.[0], 1)}\n\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t>\n\t\t\t\t\t<LabelList\n\t\t\t\t\t\tdataKey=\"name\"\n\t\t\t\t\t\tposition=\"right\"\n\t\t\t\t\t\tfill={chartAxis}\n\t\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t\tfontSize={chartFontSize(\"axis\")}\n\t\t\t\t\t/>\n\t\t\t\t</Funnel>\n\t\t\t</RechartsFunnel>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;;AA+BA,
|
|
1
|
+
{"version":3,"file":"funnel.js","names":["RechartsFunnel","FunnelChart$1","FunnelChart","ChartFrame","Tooltip","chartTooltipProps","valueFormatter","Funnel","seriesColor","series","ANIMATION_PROPS","LabelList","chartAxis","chartFontSize"],"sources":["../../src/charts/funnel.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Funnel, LabelList, FunnelChart as RechartsFunnel, Tooltip } from \"recharts\";\nimport { ANIMATION_PROPS, chartFontSize, chartTooltipProps, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport { chartAxis } from \"./palette\";\nimport type { ChartSeriesDescriptor, NamedValue } from \"./series\";\n\nexport type FunnelChartProps = {\n\tdata: NamedValue[];\n\tseries?: ChartSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function FunnelChart({\n\tdata,\n\tseries,\n\tariaLabel = \"Funnel chart\",\n\tclassName,\n\tvalueFormatter,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: FunnelChartProps) {\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsFunnel>\n\t\t\t\t<Tooltip {...chartTooltipProps({ formatter: valueFormatter, cursor: false })} />\n\t\t\t\t<Funnel\n\t\t\t\t\tdata={data}\n\t\t\t\t\tdataKey=\"value\"\n\t\t\t\t\tnameKey=\"name\"\n\t\t\t\t\tfill={seriesColor(series?.[0], 1)}\n\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t>\n\t\t\t\t\t<LabelList\n\t\t\t\t\t\tdataKey=\"name\"\n\t\t\t\t\t\tposition=\"right\"\n\t\t\t\t\t\tfill={chartAxis}\n\t\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t\tfontSize={chartFontSize(\"axis\")}\n\t\t\t\t\t/>\n\t\t\t\t</Funnel>\n\t\t\t</RechartsFunnel>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;;AA+BA,SAAgBE,EAAY,EAC3B,SACA,WACA,eAAY,gBACZ,cACA,mBACA,YACA,oBACA,yBACoB;CACpB,OACC,kBAACC,GAAD;EACY;EACA;EACF;EACQ;EACG;EAEpB,UAAA,kBAACH,GAAD,EAAA,UAAA,CACC,kBAACI,GAAD,EAAS,GAAIC,EAAkB;GAAE,WAAWC;GAAgB,QAAQ;EAAM,CAAC,EAAI,CAAA,GAC/E,kBAACC,GAAD;GACO;GACN,SAAQ;GACR,SAAQ;GACR,MAAMC,EAAYC,IAAS,IAAI,CAAC;GAChC,QAAO;GACP,GAAIC;GAEJ,UAAA,kBAACC,GAAD;IACC,SAAQ;IACR,UAAS;IACT,MAAMC;IACN,QAAO;IACP,UAAUC,EAAc,MAAM;GAC9B,CAAA;EACM,CAAA,CACO,EAAA,CAAA;CACL,CAAA;AAEd"}
|
package/dist/charts/gauge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gauge.js","names":[],"sources":["../../src/charts/gauge.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useId } from \"react\";\nimport { PolarAngleAxis, RadialBar, RadialBarChart } from \"recharts\";\nimport { cn } from \"../utils/cn\";\nimport { ANIMATION_PROPS, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport { chartMuted } from \"./palette\";\nimport type { ChartSeriesDescriptor } from \"./series\";\n\nexport type GaugeProps = {\n\tvalue: number;\n\tmax?: number;\n\tseries?: ChartSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\thideValue?: boolean;\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function Gauge({\n\tvalue,\n\tmax = 100,\n\tseries,\n\tariaLabel = \"Gauge\",\n\tclassName,\n\thideValue = false,\n\tvalueFormatter,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: GaugeProps) {\n\tconst summaryId = useId();\n\tconst percent = max === 0 ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n\tconst display = valueFormatter ? valueFormatter(value) : String(value);\n\tconst hasSummary = summary !== undefined && summary !== null && summary !== false;\n\tconst hasAlternative =\n\t\tdataAlternative !== undefined && dataAlternative !== null && dataAlternative !== false;\n\n\tconst plot = (\n\t\t<div className={cn(\"relative h-36 w-36\", className)}>\n\t\t\t<ChartFrame\n\t\t\t\tariaLabel={ariaLabel}\n\t\t\t\tclassName=\"h-full w-full\"\n\t\t\t\tsize=\"h-full w-full\"\n\t\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t\t>\n\t\t\t\t<RadialBarChart\n\t\t\t\t\tcx=\"50%\"\n\t\t\t\t\tcy=\"50%\"\n\t\t\t\t\tinnerRadius=\"75%\"\n\t\t\t\t\touterRadius=\"95%\"\n\t\t\t\t\tstartAngle={90}\n\t\t\t\t\tendAngle={-270}\n\t\t\t\t\tdata={[{ value: percent }]}\n\t\t\t\t\tbarSize={12}\n\t\t\t\t\t{...(hasSummary ? { \"aria-describedby\": summaryId } : {})}\n\t\t\t\t>\n\t\t\t\t\t<PolarAngleAxis type=\"number\" domain={[0, 100]} angleAxisId={0} tick={false} />\n\t\t\t\t\t<RadialBar\n\t\t\t\t\t\tdataKey=\"value\"\n\t\t\t\t\t\tcornerRadius={6}\n\t\t\t\t\t\tfill={seriesColor(series?.[0], 2)}\n\t\t\t\t\t\tbackground={{ fill: chartMuted }}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t</RadialBarChart>\n\t\t\t</ChartFrame>\n\t\t\t{hideValue ? null : (\n\t\t\t\t<span className=\"pointer-events-none absolute inset-0 flex items-center justify-center text-sm font-semibold text-basalt-foreground\">\n\t\t\t\t\t{display}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t</div>\n\t);\n\n\tif (!hasSummary && !hasAlternative) {\n\t\treturn plot;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-2 min-h-0 min-w-0\">\n\t\t\t{hasSummary ? (\n\t\t\t\t<div id={summaryId} className=\"text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t{summary}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{plot}\n\t\t\t{hasAlternative ? (\n\t\t\t\t<div className=\"text-xs text-basalt-muted-foreground\">{dataAlternative}</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;;;AAmCA,
|
|
1
|
+
{"version":3,"file":"gauge.js","names":["Gauge","summaryId","useId","percent","max","value","display","valueFormatter","hasSummary","summary","hasAlternative","dataAlternative","plot","cn","className","ChartFrame","RadialBarChart","PolarAngleAxis","RadialBar","seriesColor","series","chartMuted","ANIMATION_PROPS","hideValue"],"sources":["../../src/charts/gauge.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useId } from \"react\";\nimport { PolarAngleAxis, RadialBar, RadialBarChart } from \"recharts\";\nimport { cn } from \"../utils/cn\";\nimport { ANIMATION_PROPS, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport { chartMuted } from \"./palette\";\nimport type { ChartSeriesDescriptor } from \"./series\";\n\nexport type GaugeProps = {\n\tvalue: number;\n\tmax?: number;\n\tseries?: ChartSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\thideValue?: boolean;\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function Gauge({\n\tvalue,\n\tmax = 100,\n\tseries,\n\tariaLabel = \"Gauge\",\n\tclassName,\n\thideValue = false,\n\tvalueFormatter,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: GaugeProps) {\n\tconst summaryId = useId();\n\tconst percent = max === 0 ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n\tconst display = valueFormatter ? valueFormatter(value) : String(value);\n\tconst hasSummary = summary !== undefined && summary !== null && summary !== false;\n\tconst hasAlternative =\n\t\tdataAlternative !== undefined && dataAlternative !== null && dataAlternative !== false;\n\n\tconst plot = (\n\t\t<div className={cn(\"relative h-36 w-36\", className)}>\n\t\t\t<ChartFrame\n\t\t\t\tariaLabel={ariaLabel}\n\t\t\t\tclassName=\"h-full w-full\"\n\t\t\t\tsize=\"h-full w-full\"\n\t\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t\t>\n\t\t\t\t<RadialBarChart\n\t\t\t\t\tcx=\"50%\"\n\t\t\t\t\tcy=\"50%\"\n\t\t\t\t\tinnerRadius=\"75%\"\n\t\t\t\t\touterRadius=\"95%\"\n\t\t\t\t\tstartAngle={90}\n\t\t\t\t\tendAngle={-270}\n\t\t\t\t\tdata={[{ value: percent }]}\n\t\t\t\t\tbarSize={12}\n\t\t\t\t\t{...(hasSummary ? { \"aria-describedby\": summaryId } : {})}\n\t\t\t\t>\n\t\t\t\t\t<PolarAngleAxis type=\"number\" domain={[0, 100]} angleAxisId={0} tick={false} />\n\t\t\t\t\t<RadialBar\n\t\t\t\t\t\tdataKey=\"value\"\n\t\t\t\t\t\tcornerRadius={6}\n\t\t\t\t\t\tfill={seriesColor(series?.[0], 2)}\n\t\t\t\t\t\tbackground={{ fill: chartMuted }}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t</RadialBarChart>\n\t\t\t</ChartFrame>\n\t\t\t{hideValue ? null : (\n\t\t\t\t<span className=\"pointer-events-none absolute inset-0 flex items-center justify-center text-sm font-semibold text-basalt-foreground\">\n\t\t\t\t\t{display}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t</div>\n\t);\n\n\tif (!hasSummary && !hasAlternative) {\n\t\treturn plot;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-2 min-h-0 min-w-0\">\n\t\t\t{hasSummary ? (\n\t\t\t\t<div id={summaryId} className=\"text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t{summary}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{plot}\n\t\t\t{hasAlternative ? (\n\t\t\t\t<div className=\"text-xs text-basalt-muted-foreground\">{dataAlternative}</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;;;AAmCA,SAAgBA,EAAM,EACrB,UACA,SAAM,KACN,WACA,eAAY,SACZ,cACA,eAAY,IACZ,mBACA,YACA,oBACA,yBACc;CACd,IAAMC,IAAYC,EAAM,GAClBC,IAAUC,MAAQ,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,GAAIC,IAAQD,IAAO,GAAG,CAAC,GACxEE,IAAUC,IAAiBA,EAAeF,CAAK,IAAI,OAAOA,CAAK,GAC/DG,IAAaC,KAAqC,QAAQA,MAAY,IACtEC,IACLC,KAAqD,QAAQA,MAAoB,IAE5EC,IACL,kBAAC,OAAD;EAAK,WAAWC,EAAG,sBAAsBC,CAAS;EAAlD,UAAA,CACC,kBAACC,GAAD;GACY;GACX,WAAU;GACV,MAAK;GACe;GAEpB,UAAA,kBAACC,GAAD;IACC,IAAG;IACH,IAAG;IACH,aAAY;IACZ,aAAY;IACZ,YAAY;IACZ,UAAU;IACV,MAAM,CAAC,EAAE,OAAOb,EAAQ,CAAC;IACzB,SAAS;IACT,GAAKK,IAAa,EAAE,oBAAoBP,EAAU,IAAI,CAAC;IATxD,UAAA,CAWC,kBAACgB,GAAD;KAAgB,MAAK;KAAS,QAAQ,CAAC,GAAG,GAAG;KAAG,aAAa;KAAG,MAAM;IAAQ,CAAA,GAC9E,kBAACC,GAAD;KACC,SAAQ;KACR,cAAc;KACd,MAAMC,EAAYC,IAAS,IAAI,CAAC;KAChC,YAAY,EAAE,MAAMC,EAAW;KAC/B,GAAIC;IACJ,CAAA,CACc;;EACL,CAAA,GACXC,IAAY,OACZ,kBAAC,QAAD;GAAM,WAAU;GACd,UAAAjB;EACI,CAAA,CAEH;;CAON,OAJI,CAACE,KAAc,CAACE,IACZE,IAIP,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACEJ,IACA,kBAAC,OAAD;IAAK,IAAIP;IAAW,WAAU;IAC5B,UAAAQ;GACG,CAAA,IACF;GACHG;GACAF,IACA,kBAAC,OAAD;IAAK,WAAU;IAAwC,UAAAC;GAAqB,CAAA,IACzE;EACA;;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grouped-bar.js","names":[],"sources":["../../src/charts/grouped-bar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { BarChart } from \"./bar\";\nimport type {\n\tLineChartAxisDomain,\n\tLineChartLegendRenderer,\n\tLineChartNumericKeys,\n\tLineChartTooltipRenderer,\n} from \"./line\";\nimport { type ChartSeriesDescriptor, resolveChartSeries, type XYPoint } from \"./series\";\n\nexport type GroupedBarChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function GroupedBarChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({ series, ariaLabel = \"Grouped bar chart\", ...props }: GroupedBarChartProps<TData, K>) {\n\tconst resolvedSeries = resolveChartSeries(series, [\"y\", \"y2\"] as K[]);\n\treturn (\n\t\t<BarChart<TData, K>\n\t\t\tseries={resolvedSeries}\n\t\t\tariaLabel={ariaLabel}\n\t\t\t{...props}\n\t\t\tcolor={undefined}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;AAkEA,
|
|
1
|
+
{"version":3,"file":"grouped-bar.js","names":["GroupedBarChart","props","resolvedSeries","resolveChartSeries","series","BarChart"],"sources":["../../src/charts/grouped-bar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { BarChart } from \"./bar\";\nimport type {\n\tLineChartAxisDomain,\n\tLineChartLegendRenderer,\n\tLineChartNumericKeys,\n\tLineChartTooltipRenderer,\n} from \"./line\";\nimport { type ChartSeriesDescriptor, resolveChartSeries, type XYPoint } from \"./series\";\n\nexport type GroupedBarChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function GroupedBarChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({ series, ariaLabel = \"Grouped bar chart\", ...props }: GroupedBarChartProps<TData, K>) {\n\tconst resolvedSeries = resolveChartSeries(series, [\"y\", \"y2\"] as K[]);\n\treturn (\n\t\t<BarChart<TData, K>\n\t\t\tseries={resolvedSeries}\n\t\t\tariaLabel={ariaLabel}\n\t\t\t{...props}\n\t\t\tcolor={undefined}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;AAkEA,SAAgBA,EAGd,EAAE,WAAQ,eAAY,qBAAqB,GAAGC,KAAyC;CACxF,IAAMC,IAAiBC,EAAmBC,GAAQ,CAAC,KAAK,IAAI,CAAQ;CACpE,OACC,kBAACC,GAAD;EACC,QAAQH;EACG;EACX,GAAID;EACJ,OAAO,KAAA;CACP,CAAA;AAEH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heatmap-calendar.js","names":[],"sources":["../../src/charts/heatmap-calendar.tsx"],"sourcesContent":["import { type KeyboardEvent, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../components/tooltip\";\nimport { cn } from \"../utils/cn\";\n\nexport type HeatmapDataPoint = { date: string; value: number };\n\nexport const heatmapColorScales = {\n\tgreen: [\n\t\t\"hsl(var(--basalt-muted))\",\n\t\t\"hsl(var(--basalt-heatmap-green-1))\",\n\t\t\"hsl(var(--basalt-heatmap-green-2))\",\n\t\t\"hsl(var(--basalt-heatmap-green-3))\",\n\t\t\"hsl(var(--basalt-heatmap-green-4))\",\n\t],\n\tred: [\n\t\t\"hsl(var(--basalt-muted))\",\n\t\t\"hsl(var(--basalt-heatmap-red-1))\",\n\t\t\"hsl(var(--basalt-heatmap-red-2))\",\n\t\t\"hsl(var(--basalt-heatmap-red-3))\",\n\t\t\"hsl(var(--basalt-heatmap-red-4))\",\n\t],\n\tblue: [\n\t\t\"hsl(var(--basalt-muted))\",\n\t\t\"hsl(var(--basalt-heatmap-blue-1))\",\n\t\t\"hsl(var(--basalt-heatmap-blue-2))\",\n\t\t\"hsl(var(--basalt-heatmap-blue-3))\",\n\t\t\"hsl(var(--basalt-heatmap-blue-4))\",\n\t],\n\torange: [\n\t\t\"hsl(var(--basalt-muted))\",\n\t\t\"hsl(var(--basalt-heatmap-orange-1))\",\n\t\t\"hsl(var(--basalt-heatmap-orange-2))\",\n\t\t\"hsl(var(--basalt-heatmap-orange-3))\",\n\t\t\"hsl(var(--basalt-heatmap-orange-4))\",\n\t],\n} as const;\n\nfunction weekdayNames(locale: string) {\n\treturn Array.from({ length: 7 }, (_, index) =>\n\t\tnew Intl.DateTimeFormat(locale, { weekday: \"short\" }).format(new Date(2023, 0, 1 + index)),\n\t);\n}\n\nfunction monthNames(locale: string) {\n\treturn Array.from({ length: 12 }, (_, index) =>\n\t\tnew Intl.DateTimeFormat(locale, { month: \"short\" }).format(new Date(2023, index, 1)),\n\t);\n}\n\nfunction getYearWeeks(year: number): Date[][] {\n\tconst weeks: Date[][] = [];\n\tconst startDate = new Date(year, 0, 1);\n\tconst endDate = new Date(year, 11, 31);\n\tconst firstDay = new Date(startDate);\n\tfirstDay.setDate(firstDay.getDate() - firstDay.getDay());\n\tlet currentDate = new Date(firstDay);\n\tlet currentWeek: Date[] = [];\n\twhile (currentDate <= endDate || currentWeek.length > 0) {\n\t\tif (currentWeek.length === 7) {\n\t\t\tweeks.push(currentWeek);\n\t\t\tcurrentWeek = [];\n\t\t}\n\t\tif (currentDate > endDate) {\n\t\t\tbreak;\n\t\t}\n\t\tcurrentWeek.push(new Date(currentDate));\n\t\tcurrentDate = new Date(currentDate);\n\t\tcurrentDate.setDate(currentDate.getDate() + 1);\n\t}\n\tif (currentWeek.length > 0) {\n\t\tweeks.push(currentWeek);\n\t}\n\treturn weeks;\n}\n\nfunction formatDate(date: Date): string {\n\tconst year = date.getFullYear();\n\tconst month = String(date.getMonth() + 1).padStart(2, \"0\");\n\tconst day = String(date.getDate()).padStart(2, \"0\");\n\treturn `${year}-${month}-${day}`;\n}\n\nfunction getColorIndex(value: number, maxValue: number, colorScale: readonly string[]): number {\n\tif (value === 0) {\n\t\treturn 0;\n\t}\n\tconst levels = colorScale.length - 1;\n\tconst normalized = Math.min(value / maxValue, 1);\n\treturn Math.ceil(normalized * levels);\n}\n\nexport type HeatmapCalendarValuesProps = {\n\t/**\n\t * Numeric values sequence to display in a compact 7-column grid.\n\t */\n\tvalues: number[];\n\t/**\n\t * Accessible name describing the heatmap purpose or data.\n\t * @default \"Heatmap calendar\"\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Additional CSS class names for the outer container.\n\t */\n\tclassName?: string;\n};\n\nexport type HeatmapCalendarYearProps = {\n\t/**\n\t * Dataset of daily metrics with ISO date strings (\"YYYY-MM-DD\") and numeric values.\n\t */\n\tdata: HeatmapDataPoint[];\n\t/**\n\t * Calendar year to render.\n\t */\n\tyear: number;\n\t/**\n\t * Array of color values forming the intensity gradient from lowest to highest.\n\t * @default heatmapColorScales.green\n\t */\n\tcolorScale?: readonly string[];\n\t/**\n\t * Formatter for tooltip value display and accessible label.\n\t * @default (value) => value.toLocaleString()\n\t */\n\tvalueFormatter?: (value: number, date: string) => string;\n\t/**\n\t * Name of the metric for accessible labeling and tooltips.\n\t * @default \"Value\"\n\t */\n\tmetricLabel?: string;\n\t/**\n\t * Pixel width and height of each day cell.\n\t * @default 12\n\t */\n\tcellSize?: number;\n\t/**\n\t * Pixel gap between adjacent cells.\n\t * @default 2\n\t */\n\tcellGap?: number;\n\t/**\n\t * BCP 47 locale tag used for weekday and month label formatting.\n\t * @default \"en-US\"\n\t */\n\tlocale?: string;\n\t/**\n\t * Explicit custom weekday labels override.\n\t */\n\tweekdayLabels?: string[];\n\t/**\n\t * Explicit custom month labels override.\n\t */\n\tmonthLabels?: string[];\n\t/**\n\t * Label text for the lower end of the color scale legend.\n\t * @default \"Less\"\n\t */\n\tlessLabel?: string;\n\t/**\n\t * Label text for the upper end of the color scale legend.\n\t * @default \"More\"\n\t */\n\tmoreLabel?: string;\n\t/**\n\t * Accessible name describing the yearly heatmap dataset.\n\t * @default \"Heatmap calendar\"\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Additional CSS class names for the outer scrollable container.\n\t */\n\tclassName?: string;\n};\n\nexport type HeatmapCalendarProps = HeatmapCalendarValuesProps | HeatmapCalendarYearProps;\n\nexport function HeatmapCalendar(props: HeatmapCalendarProps) {\n\tif (\"data\" in props) {\n\t\treturn <YearHeatmap {...props} />;\n\t}\n\treturn <ValuesHeatmap {...props} />;\n}\n\nfunction ValuesHeatmap({\n\tvalues,\n\tariaLabel = \"Heatmap calendar\",\n\tclassName,\n}: HeatmapCalendarValuesProps) {\n\tconst [activeIdx, setActiveIdx] = useState(0);\n\tconst [openTooltipIdx, setOpenTooltipIdx] = useState<number | null>(null);\n\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\tconst cellRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\tconst isFocusedInsideRef = useRef(false);\n\n\t// When values array shrinks, empties, or restores: if an item or container currently held focus,\n\t// restore focus to the new valid index or empty container without stealing focus from outside.\n\tuseEffect(() => {\n\t\tconst hadFocus = isFocusedInsideRef.current;\n\t\tif (values.length === 0) {\n\t\t\tsetActiveIdx(0);\n\t\t\tsetOpenTooltipIdx(null);\n\t\t\tif (hadFocus) {\n\t\t\t\tcontainerRef.current?.focus();\n\t\t\t}\n\t\t} else if (activeIdx >= values.length) {\n\t\t\tconst next = values.length - 1;\n\t\t\tsetActiveIdx(next);\n\t\t\tif (hadFocus) {\n\t\t\t\tcellRefs.current[next]?.focus();\n\t\t\t}\n\t\t} else if (hadFocus) {\n\t\t\tcellRefs.current[activeIdx]?.focus();\n\t\t}\n\t}, [values.length, activeIdx]);\n\n\tconst handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>, currentIndex: number) => {\n\t\tif (values.length === 0) return;\n\n\t\tif (e.key === \"Escape\") {\n\t\t\tsetOpenTooltipIdx(null);\n\t\t\treturn;\n\t\t}\n\n\t\tlet nextIdx = currentIndex;\n\t\tif (e.key === \"ArrowRight\") {\n\t\t\tnextIdx = Math.min(values.length - 1, currentIndex + 1);\n\t\t} else if (e.key === \"ArrowLeft\") {\n\t\t\tnextIdx = Math.max(0, currentIndex - 1);\n\t\t} else if (e.key === \"ArrowDown\") {\n\t\t\tnextIdx = Math.min(values.length - 1, currentIndex + 7);\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\tnextIdx = Math.max(0, currentIndex - 7);\n\t\t} else if (e.key === \"Home\") {\n\t\t\tnextIdx = 0;\n\t\t} else if (e.key === \"End\") {\n\t\t\tnextIdx = values.length - 1;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\te.preventDefault();\n\t\tsetActiveIdx(nextIdx);\n\t\tsetOpenTooltipIdx(nextIdx);\n\t\tcellRefs.current[nextIdx]?.focus();\n\t};\n\n\tconst container = (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\ttabIndex={-1}\n\t\t\trole=\"region\"\n\t\t\taria-label={ariaLabel}\n\t\t\tonFocus={() => {\n\t\t\t\tisFocusedInsideRef.current = true;\n\t\t\t}}\n\t\t\tonBlur={(e) => {\n\t\t\t\tif (!e.currentTarget.contains(e.relatedTarget)) {\n\t\t\t\t\tisFocusedInsideRef.current = false;\n\t\t\t\t}\n\t\t\t}}\n\t\t\tclassName={cn(\"grid grid-cols-7 gap-1 p-0.5 outline-none\", className)}\n\t\t>\n\t\t\t{values.map((value, index) => {\n\t\t\t\tconst isCurrent = index === activeIdx;\n\t\t\t\tconst isOpen = openTooltipIdx === index;\n\t\t\t\treturn (\n\t\t\t\t\t<Tooltip\n\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\topen={isOpen}\n\t\t\t\t\t\tonOpenChange={(next) => {\n\t\t\t\t\t\t\tif (next) {\n\t\t\t\t\t\t\t\tsetOpenTooltipIdx(index);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsetOpenTooltipIdx((curr) => {\n\t\t\t\t\t\t\t\t\tif (curr !== index) return curr;\n\t\t\t\t\t\t\t\t\t// If this cell currently holds document focus, ignore scroll dismiss\n\t\t\t\t\t\t\t\t\tconst isCellFocused =\n\t\t\t\t\t\t\t\t\t\tcellRefs.current[index] !== null &&\n\t\t\t\t\t\t\t\t\t\tdocument.activeElement === cellRefs.current[index];\n\t\t\t\t\t\t\t\t\treturn isCellFocused ? curr : null;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tref={(el) => {\n\t\t\t\t\t\t\t\t\tcellRefs.current[index] = el;\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\ttabIndex={isCurrent ? 0 : -1}\n\t\t\t\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\t\t\t\tsetActiveIdx(index);\n\t\t\t\t\t\t\t\t\tsetOpenTooltipIdx(index);\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tonBlur={() => {\n\t\t\t\t\t\t\t\t\tsetOpenTooltipIdx((curr) => (curr === index ? null : curr));\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tonKeyDown={(e) => handleKeyDown(e, index)}\n\t\t\t\t\t\t\t\taria-label={`Position ${index + 1}: ${value}`}\n\t\t\t\t\t\t\t\tclassName=\"box-border m-0 h-3 w-3 cursor-pointer rounded-sm border-0 p-0 transition-colors focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-basalt-ring\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackgroundColor: `hsl(var(--basalt-chart-5) / ${0.2 + Math.min(4, Math.max(0, value)) * 0.15})`,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t<TooltipContent>\n\t\t\t\t\t\t\t<div className=\"text-xs\">\n\t\t\t\t\t\t\t\tPosition {index + 1}: {value}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t</Tooltip>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n\n\tif (values.length === 0) {\n\t\treturn container;\n\t}\n\n\treturn <TooltipProvider>{container}</TooltipProvider>;\n}\n\nfunction YearHeatmap({\n\tdata,\n\tyear,\n\tcolorScale = heatmapColorScales.green,\n\tvalueFormatter = (value) => value.toLocaleString(),\n\tmetricLabel = \"Value\",\n\tcellSize = 12,\n\tcellGap = 2,\n\tlocale = \"en-US\",\n\tweekdayLabels,\n\tmonthLabels,\n\tlessLabel = \"Less\",\n\tmoreLabel = \"More\",\n\tariaLabel = \"Heatmap calendar\",\n\tclassName,\n}: HeatmapCalendarYearProps) {\n\tconst weekdays = weekdayLabels ?? weekdayNames(locale);\n\tconst months = monthLabels ?? monthNames(locale);\n\tconst calendarId = useId();\n\tconst scrollRegionRef = useRef<HTMLDivElement | null>(null);\n\n\tconst { weeks, dataMap, maxValue, labels, validDays, dateToValidIndex } = useMemo(() => {\n\t\tconst weeks = getYearWeeks(year);\n\t\tconst dataMap = new Map<string, number>();\n\t\tlet maxValue = 0;\n\t\tfor (const point of data) {\n\t\t\tdataMap.set(point.date, point.value);\n\t\t\tif (point.value > maxValue) {\n\t\t\t\tmaxValue = point.value;\n\t\t\t}\n\t\t}\n\n\t\tconst labels: { month: string; weekIndex: number }[] = [];\n\t\tlet lastMonth = -1;\n\t\tweeks.forEach((week, weekIndex) => {\n\t\t\tconst firstDayOfWeek = week.find((date) => date.getFullYear() === year);\n\t\t\tif (firstDayOfWeek) {\n\t\t\t\tconst month = firstDayOfWeek.getMonth();\n\t\t\t\tif (month !== lastMonth) {\n\t\t\t\t\tlabels.push({ month: months[month], weekIndex });\n\t\t\t\t\tlastMonth = month;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst validDays: string[] = [];\n\t\tconst dateToValidIndex = new Map<string, number>();\n\n\t\tweeks.forEach((week) => {\n\t\t\tweek.forEach((date) => {\n\t\t\t\tif (date.getFullYear() === year) {\n\t\t\t\t\tconst dateStr = formatDate(date);\n\t\t\t\t\tdateToValidIndex.set(dateStr, validDays.length);\n\t\t\t\t\tvalidDays.push(dateStr);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\treturn { weeks, dataMap, maxValue, labels, validDays, dateToValidIndex };\n\t}, [data, months, year]);\n\n\tconst [activeDate, setActiveDate] = useState<string>(() => {\n\t\treturn validDays[0] ?? `${year}-01-01`;\n\t});\n\tconst [openTooltipDate, setOpenTooltipDate] = useState<string | null>(null);\n\n\tconst cellRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\n\tconst isYearFocusedInsideRef = useRef(false);\n\n\t// If year or validDays change: if a cell held focus, restore focus to the clamped\n\t// active date or scroll container; if focus was outside, do NOT steal focus.\n\tuseEffect(() => {\n\t\tconst hadFocus = isYearFocusedInsideRef.current;\n\t\tif (validDays.length === 0) {\n\t\t\tsetActiveDate(\"\");\n\t\t\tsetOpenTooltipDate(null);\n\t\t\tif (hadFocus) {\n\t\t\t\tscrollRegionRef.current?.focus();\n\t\t\t}\n\t\t} else if (!dateToValidIndex.has(activeDate)) {\n\t\t\tconst nextDate = validDays[0] ?? \"\";\n\t\t\tsetActiveDate(nextDate);\n\t\t\tif (hadFocus) {\n\t\t\t\tcellRefs.current.get(nextDate)?.focus();\n\t\t\t}\n\t\t}\n\t}, [validDays, dateToValidIndex, activeDate]);\n\n\tconst selectedDate = dateToValidIndex.has(activeDate) ? activeDate : validDays[0];\n\n\tconst navigateToDay = (targetDate: string | undefined) => {\n\t\tif (!targetDate) return;\n\t\tsetActiveDate(targetDate);\n\t\tsetOpenTooltipDate(targetDate);\n\t\tconst btn = cellRefs.current.get(targetDate);\n\t\tbtn?.focus();\n\t};\n\n\tconst handleCellKeyDown = (e: KeyboardEvent<HTMLButtonElement>, dateStr: string) => {\n\t\tif (validDays.length === 0) return;\n\n\t\tconst currentIdx = dateToValidIndex.get(dateStr) ?? 0;\n\n\t\tif (e.key === \"Escape\") {\n\t\t\tsetOpenTooltipDate(null);\n\t\t\treturn;\n\t\t}\n\n\t\tif (e.key === \"ArrowDown\") {\n\t\t\te.preventDefault();\n\t\t\t// Visually next day (down in the column)\n\t\t\tconst nextDay = validDays[currentIdx + 1];\n\t\t\tif (nextDay) {\n\t\t\t\tnavigateToDay(nextDay);\n\t\t\t}\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\te.preventDefault();\n\t\t\t// Visually previous day (up in the column)\n\t\t\tconst prevDay = validDays[currentIdx - 1];\n\t\t\tif (prevDay) {\n\t\t\t\tnavigateToDay(prevDay);\n\t\t\t}\n\t\t} else if (e.key === \"ArrowRight\") {\n\t\t\te.preventDefault();\n\t\t\t// Visually next week (right in the row: +7 days by index)\n\t\t\tconst targetIdx = currentIdx + 7;\n\t\t\tif (targetIdx < validDays.length) {\n\t\t\t\tnavigateToDay(validDays[targetIdx]);\n\t\t\t} else {\n\t\t\t\tnavigateToDay(validDays[validDays.length - 1]);\n\t\t\t}\n\t\t} else if (e.key === \"ArrowLeft\") {\n\t\t\te.preventDefault();\n\t\t\t// Visually previous week (left in the row: -7 days by index)\n\t\t\tconst targetIdx = currentIdx - 7;\n\t\t\tif (targetIdx >= 0) {\n\t\t\t\tnavigateToDay(validDays[targetIdx]);\n\t\t\t} else {\n\t\t\t\tnavigateToDay(validDays[0]);\n\t\t\t}\n\t\t} else if (e.key === \"Home\") {\n\t\t\te.preventDefault();\n\t\t\tnavigateToDay(validDays[0]);\n\t\t} else if (e.key === \"End\") {\n\t\t\te.preventDefault();\n\t\t\tnavigateToDay(validDays[validDays.length - 1]);\n\t\t}\n\t};\n\n\tconst labelWidth = 30;\n\n\treturn (\n\t\t<div\n\t\t\tref={scrollRegionRef}\n\t\t\ttabIndex={-1}\n\t\t\trole=\"region\"\n\t\t\taria-label={`${ariaLabel} scrollable view`}\n\t\t\tonFocus={() => {\n\t\t\t\tisYearFocusedInsideRef.current = true;\n\t\t\t}}\n\t\t\tonBlur={(e) => {\n\t\t\t\tif (!e.currentTarget.contains(e.relatedTarget)) {\n\t\t\t\t\tisYearFocusedInsideRef.current = false;\n\t\t\t\t}\n\t\t\t}}\n\t\t\tclassName={cn(\n\t\t\t\t\"overflow-x-auto rounded-md outline-none focus-visible:ring-1 focus-visible:ring-basalt-ring\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<TooltipProvider>\n\t\t\t\t<div className=\"inline-block p-1\" role=\"group\" aria-label={ariaLabel}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"relative mb-1 h-4 text-xs text-basalt-muted-foreground\"\n\t\t\t\t\t\tstyle={{ marginLeft: labelWidth }}\n\t\t\t\t\t>\n\t\t\t\t\t\t{labels.map((label) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={`${label.month}-${label.weekIndex}`}\n\t\t\t\t\t\t\t\tclassName=\"absolute\"\n\t\t\t\t\t\t\t\tstyle={{ left: label.weekIndex * (cellSize + cellGap) }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{label.month}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex\">\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"mr-1 flex flex-col text-xs text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\tstyle={{ width: labelWidth }}\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{weekdays.map((day, index) => (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={`${day}-${index}`}\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\theight: cellSize + cellGap,\n\t\t\t\t\t\t\t\t\t\tlineHeight: `${cellSize + cellGap}px`,\n\t\t\t\t\t\t\t\t\t\tvisibility: index % 2 === 1 ? \"visible\" : \"hidden\",\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\t{day}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"flex\" style={{ gap: cellGap }}>\n\t\t\t\t\t\t\t{weeks.map((week, weekIndex) => (\n\t\t\t\t\t\t\t\t<div key={weekIndex} className=\"flex flex-col\" style={{ gap: cellGap }}>\n\t\t\t\t\t\t\t\t\t{week.map((date, dayIndex) => {\n\t\t\t\t\t\t\t\t\t\tconst dateStr = formatDate(date);\n\t\t\t\t\t\t\t\t\t\tconst isCurrentYear = date.getFullYear() === year;\n\t\t\t\t\t\t\t\t\t\tif (!isCurrentYear) {\n\t\t\t\t\t\t\t\t\t\t\treturn (\n\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\tkey={dayIndex}\n\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\twidth: cellSize,\n\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\tvisibility: \"hidden\",\n\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\taria-hidden=\"true\"\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}\n\n\t\t\t\t\t\t\t\t\t\tconst value = dataMap.get(dateStr) ?? 0;\n\t\t\t\t\t\t\t\t\t\tconst colorIndex = getColorIndex(value, maxValue, colorScale);\n\t\t\t\t\t\t\t\t\t\tconst isSelected = selectedDate === dateStr;\n\t\t\t\t\t\t\t\t\t\tconst formattedValue = valueFormatter(value, dateStr);\n\t\t\t\t\t\t\t\t\t\tconst labelText = `${dateStr}, ${metricLabel}: ${formattedValue}`;\n\t\t\t\t\t\t\t\t\t\tconst isOpen = openTooltipDate === dateStr;\n\n\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\t\t\t\t\tkey={dayIndex}\n\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\tonOpenChange={(next) => {\n\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\tsetOpenTooltipDate(dateStr);\n\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\tsetOpenTooltipDate((curr) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (curr !== dateStr) return curr;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// If this cell currently holds document focus, ignore scroll dismiss\n\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\tdocument.activeElement === cellRefs.current.get(dateStr);\n\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});\n\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}}\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<TooltipTrigger asChild>\n\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\tref={(el) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (el) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcellRefs.current.set(dateStr, el);\n\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\tcellRefs.current.delete(dateStr);\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\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-label={labelText}\n\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\tonFocus={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetActiveDate(dateStr);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipDate(dateStr);\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\tonBlur={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipDate((curr) => (curr === dateStr ? null : curr));\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\tonKeyDown={(e) => handleCellKeyDown(e, dateStr)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"box-border m-0 cursor-pointer rounded-sm border-0 p-0 transition-colors 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\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\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\tbackgroundColor: colorScale[colorIndex],\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/>\n\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<TooltipContent id={`${calendarId}-${dateStr}`}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"font-medium\">{dateStr}</div>\n\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{metricLabel}: {formattedValue}\n\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</div>\n\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</Tooltip>\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</div>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"mt-2 flex items-center justify-end gap-1 text-xs text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<span>{lessLabel}</span>\n\t\t\t\t\t\t{colorScale.map((color) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={color}\n\t\t\t\t\t\t\t\tclassName=\"rounded-sm\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t<span>{moreLabel}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</TooltipProvider>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"heatmap-calendar.js","names":["heatmapColorScales","weekdayNames","locale","index","monthNames","getYearWeeks","weeks","startDate","year","endDate","firstDay","currentDate","currentWeek","formatDate","date","getColorIndex","value","levels","colorScale","normalized","maxValue","HeatmapCalendar","props","YearHeatmap","ValuesHeatmap","activeIdx","setActiveIdx","useState","openTooltipIdx","setOpenTooltipIdx","containerRef","useRef","cellRefs","isFocusedInsideRef","hadFocus","values","next","handleKeyDown","nextIdx","currentIndex","container","ariaLabel","cn","className","Tooltip","curr","TooltipTrigger","el","TooltipContent","TooltipProvider","weekdays","weekdayLabels","months","monthLabels","calendarId","useId","scrollRegionRef","useMemo","dataMap","point","data","labels","lastMonth","firstDayOfWeek","week","month","validDays","dateToValidIndex","dateStr","activeDate","setActiveDate","openTooltipDate","setOpenTooltipDate","isYearFocusedInsideRef","nextDate","selectedDate","navigateToDay","targetDate","handleCellKeyDown","currentIdx","nextDay","prevDay","targetIdx","label","cellSize","cellGap","day","dayIndex","colorIndex","isSelected","formattedValue","valueFormatter","labelText","metricLabel","weekIndex","lessLabel","color","moreLabel"],"sources":["../../src/charts/heatmap-calendar.tsx"],"sourcesContent":["import { type KeyboardEvent, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../components/tooltip\";\nimport { cn } from \"../utils/cn\";\n\nexport type HeatmapDataPoint = { date: string; value: number };\n\nexport const heatmapColorScales = {\n\tgreen: [\n\t\t\"hsl(var(--basalt-muted))\",\n\t\t\"hsl(var(--basalt-heatmap-green-1))\",\n\t\t\"hsl(var(--basalt-heatmap-green-2))\",\n\t\t\"hsl(var(--basalt-heatmap-green-3))\",\n\t\t\"hsl(var(--basalt-heatmap-green-4))\",\n\t],\n\tred: [\n\t\t\"hsl(var(--basalt-muted))\",\n\t\t\"hsl(var(--basalt-heatmap-red-1))\",\n\t\t\"hsl(var(--basalt-heatmap-red-2))\",\n\t\t\"hsl(var(--basalt-heatmap-red-3))\",\n\t\t\"hsl(var(--basalt-heatmap-red-4))\",\n\t],\n\tblue: [\n\t\t\"hsl(var(--basalt-muted))\",\n\t\t\"hsl(var(--basalt-heatmap-blue-1))\",\n\t\t\"hsl(var(--basalt-heatmap-blue-2))\",\n\t\t\"hsl(var(--basalt-heatmap-blue-3))\",\n\t\t\"hsl(var(--basalt-heatmap-blue-4))\",\n\t],\n\torange: [\n\t\t\"hsl(var(--basalt-muted))\",\n\t\t\"hsl(var(--basalt-heatmap-orange-1))\",\n\t\t\"hsl(var(--basalt-heatmap-orange-2))\",\n\t\t\"hsl(var(--basalt-heatmap-orange-3))\",\n\t\t\"hsl(var(--basalt-heatmap-orange-4))\",\n\t],\n} as const;\n\nfunction weekdayNames(locale: string) {\n\treturn Array.from({ length: 7 }, (_, index) =>\n\t\tnew Intl.DateTimeFormat(locale, { weekday: \"short\" }).format(new Date(2023, 0, 1 + index)),\n\t);\n}\n\nfunction monthNames(locale: string) {\n\treturn Array.from({ length: 12 }, (_, index) =>\n\t\tnew Intl.DateTimeFormat(locale, { month: \"short\" }).format(new Date(2023, index, 1)),\n\t);\n}\n\nfunction getYearWeeks(year: number): Date[][] {\n\tconst weeks: Date[][] = [];\n\tconst startDate = new Date(year, 0, 1);\n\tconst endDate = new Date(year, 11, 31);\n\tconst firstDay = new Date(startDate);\n\tfirstDay.setDate(firstDay.getDate() - firstDay.getDay());\n\tlet currentDate = new Date(firstDay);\n\tlet currentWeek: Date[] = [];\n\twhile (currentDate <= endDate || currentWeek.length > 0) {\n\t\tif (currentWeek.length === 7) {\n\t\t\tweeks.push(currentWeek);\n\t\t\tcurrentWeek = [];\n\t\t}\n\t\tif (currentDate > endDate) {\n\t\t\tbreak;\n\t\t}\n\t\tcurrentWeek.push(new Date(currentDate));\n\t\tcurrentDate = new Date(currentDate);\n\t\tcurrentDate.setDate(currentDate.getDate() + 1);\n\t}\n\tif (currentWeek.length > 0) {\n\t\tweeks.push(currentWeek);\n\t}\n\treturn weeks;\n}\n\nfunction formatDate(date: Date): string {\n\tconst year = date.getFullYear();\n\tconst month = String(date.getMonth() + 1).padStart(2, \"0\");\n\tconst day = String(date.getDate()).padStart(2, \"0\");\n\treturn `${year}-${month}-${day}`;\n}\n\nfunction getColorIndex(value: number, maxValue: number, colorScale: readonly string[]): number {\n\tif (value === 0) {\n\t\treturn 0;\n\t}\n\tconst levels = colorScale.length - 1;\n\tconst normalized = Math.min(value / maxValue, 1);\n\treturn Math.ceil(normalized * levels);\n}\n\nexport type HeatmapCalendarValuesProps = {\n\t/**\n\t * Numeric values sequence to display in a compact 7-column grid.\n\t */\n\tvalues: number[];\n\t/**\n\t * Accessible name describing the heatmap purpose or data.\n\t * @default \"Heatmap calendar\"\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Additional CSS class names for the outer container.\n\t */\n\tclassName?: string;\n};\n\nexport type HeatmapCalendarYearProps = {\n\t/**\n\t * Dataset of daily metrics with ISO date strings (\"YYYY-MM-DD\") and numeric values.\n\t */\n\tdata: HeatmapDataPoint[];\n\t/**\n\t * Calendar year to render.\n\t */\n\tyear: number;\n\t/**\n\t * Array of color values forming the intensity gradient from lowest to highest.\n\t * @default heatmapColorScales.green\n\t */\n\tcolorScale?: readonly string[];\n\t/**\n\t * Formatter for tooltip value display and accessible label.\n\t * @default (value) => value.toLocaleString()\n\t */\n\tvalueFormatter?: (value: number, date: string) => string;\n\t/**\n\t * Name of the metric for accessible labeling and tooltips.\n\t * @default \"Value\"\n\t */\n\tmetricLabel?: string;\n\t/**\n\t * Pixel width and height of each day cell.\n\t * @default 12\n\t */\n\tcellSize?: number;\n\t/**\n\t * Pixel gap between adjacent cells.\n\t * @default 2\n\t */\n\tcellGap?: number;\n\t/**\n\t * BCP 47 locale tag used for weekday and month label formatting.\n\t * @default \"en-US\"\n\t */\n\tlocale?: string;\n\t/**\n\t * Explicit custom weekday labels override.\n\t */\n\tweekdayLabels?: string[];\n\t/**\n\t * Explicit custom month labels override.\n\t */\n\tmonthLabels?: string[];\n\t/**\n\t * Label text for the lower end of the color scale legend.\n\t * @default \"Less\"\n\t */\n\tlessLabel?: string;\n\t/**\n\t * Label text for the upper end of the color scale legend.\n\t * @default \"More\"\n\t */\n\tmoreLabel?: string;\n\t/**\n\t * Accessible name describing the yearly heatmap dataset.\n\t * @default \"Heatmap calendar\"\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Additional CSS class names for the outer scrollable container.\n\t */\n\tclassName?: string;\n};\n\nexport type HeatmapCalendarProps = HeatmapCalendarValuesProps | HeatmapCalendarYearProps;\n\nexport function HeatmapCalendar(props: HeatmapCalendarProps) {\n\tif (\"data\" in props) {\n\t\treturn <YearHeatmap {...props} />;\n\t}\n\treturn <ValuesHeatmap {...props} />;\n}\n\nfunction ValuesHeatmap({\n\tvalues,\n\tariaLabel = \"Heatmap calendar\",\n\tclassName,\n}: HeatmapCalendarValuesProps) {\n\tconst [activeIdx, setActiveIdx] = useState(0);\n\tconst [openTooltipIdx, setOpenTooltipIdx] = useState<number | null>(null);\n\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\tconst cellRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\tconst isFocusedInsideRef = useRef(false);\n\n\t// When values array shrinks, empties, or restores: if an item or container currently held focus,\n\t// restore focus to the new valid index or empty container without stealing focus from outside.\n\tuseEffect(() => {\n\t\tconst hadFocus = isFocusedInsideRef.current;\n\t\tif (values.length === 0) {\n\t\t\tsetActiveIdx(0);\n\t\t\tsetOpenTooltipIdx(null);\n\t\t\tif (hadFocus) {\n\t\t\t\tcontainerRef.current?.focus();\n\t\t\t}\n\t\t} else if (activeIdx >= values.length) {\n\t\t\tconst next = values.length - 1;\n\t\t\tsetActiveIdx(next);\n\t\t\tif (hadFocus) {\n\t\t\t\tcellRefs.current[next]?.focus();\n\t\t\t}\n\t\t} else if (hadFocus) {\n\t\t\tcellRefs.current[activeIdx]?.focus();\n\t\t}\n\t}, [values.length, activeIdx]);\n\n\tconst handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>, currentIndex: number) => {\n\t\tif (values.length === 0) return;\n\n\t\tif (e.key === \"Escape\") {\n\t\t\tsetOpenTooltipIdx(null);\n\t\t\treturn;\n\t\t}\n\n\t\tlet nextIdx = currentIndex;\n\t\tif (e.key === \"ArrowRight\") {\n\t\t\tnextIdx = Math.min(values.length - 1, currentIndex + 1);\n\t\t} else if (e.key === \"ArrowLeft\") {\n\t\t\tnextIdx = Math.max(0, currentIndex - 1);\n\t\t} else if (e.key === \"ArrowDown\") {\n\t\t\tnextIdx = Math.min(values.length - 1, currentIndex + 7);\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\tnextIdx = Math.max(0, currentIndex - 7);\n\t\t} else if (e.key === \"Home\") {\n\t\t\tnextIdx = 0;\n\t\t} else if (e.key === \"End\") {\n\t\t\tnextIdx = values.length - 1;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\te.preventDefault();\n\t\tsetActiveIdx(nextIdx);\n\t\tsetOpenTooltipIdx(nextIdx);\n\t\tcellRefs.current[nextIdx]?.focus();\n\t};\n\n\tconst container = (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\ttabIndex={-1}\n\t\t\trole=\"region\"\n\t\t\taria-label={ariaLabel}\n\t\t\tonFocus={() => {\n\t\t\t\tisFocusedInsideRef.current = true;\n\t\t\t}}\n\t\t\tonBlur={(e) => {\n\t\t\t\tif (!e.currentTarget.contains(e.relatedTarget)) {\n\t\t\t\t\tisFocusedInsideRef.current = false;\n\t\t\t\t}\n\t\t\t}}\n\t\t\tclassName={cn(\"grid grid-cols-7 gap-1 p-0.5 outline-none\", className)}\n\t\t>\n\t\t\t{values.map((value, index) => {\n\t\t\t\tconst isCurrent = index === activeIdx;\n\t\t\t\tconst isOpen = openTooltipIdx === index;\n\t\t\t\treturn (\n\t\t\t\t\t<Tooltip\n\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\topen={isOpen}\n\t\t\t\t\t\tonOpenChange={(next) => {\n\t\t\t\t\t\t\tif (next) {\n\t\t\t\t\t\t\t\tsetOpenTooltipIdx(index);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsetOpenTooltipIdx((curr) => {\n\t\t\t\t\t\t\t\t\tif (curr !== index) return curr;\n\t\t\t\t\t\t\t\t\t// If this cell currently holds document focus, ignore scroll dismiss\n\t\t\t\t\t\t\t\t\tconst isCellFocused =\n\t\t\t\t\t\t\t\t\t\tcellRefs.current[index] !== null &&\n\t\t\t\t\t\t\t\t\t\tdocument.activeElement === cellRefs.current[index];\n\t\t\t\t\t\t\t\t\treturn isCellFocused ? curr : null;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tref={(el) => {\n\t\t\t\t\t\t\t\t\tcellRefs.current[index] = el;\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\ttabIndex={isCurrent ? 0 : -1}\n\t\t\t\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\t\t\t\tsetActiveIdx(index);\n\t\t\t\t\t\t\t\t\tsetOpenTooltipIdx(index);\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tonBlur={() => {\n\t\t\t\t\t\t\t\t\tsetOpenTooltipIdx((curr) => (curr === index ? null : curr));\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tonKeyDown={(e) => handleKeyDown(e, index)}\n\t\t\t\t\t\t\t\taria-label={`Position ${index + 1}: ${value}`}\n\t\t\t\t\t\t\t\tclassName=\"box-border m-0 h-3 w-3 cursor-pointer rounded-sm border-0 p-0 transition-colors focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-basalt-ring\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackgroundColor: `hsl(var(--basalt-chart-5) / ${0.2 + Math.min(4, Math.max(0, value)) * 0.15})`,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t<TooltipContent>\n\t\t\t\t\t\t\t<div className=\"text-xs\">\n\t\t\t\t\t\t\t\tPosition {index + 1}: {value}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t</Tooltip>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n\n\tif (values.length === 0) {\n\t\treturn container;\n\t}\n\n\treturn <TooltipProvider>{container}</TooltipProvider>;\n}\n\nfunction YearHeatmap({\n\tdata,\n\tyear,\n\tcolorScale = heatmapColorScales.green,\n\tvalueFormatter = (value) => value.toLocaleString(),\n\tmetricLabel = \"Value\",\n\tcellSize = 12,\n\tcellGap = 2,\n\tlocale = \"en-US\",\n\tweekdayLabels,\n\tmonthLabels,\n\tlessLabel = \"Less\",\n\tmoreLabel = \"More\",\n\tariaLabel = \"Heatmap calendar\",\n\tclassName,\n}: HeatmapCalendarYearProps) {\n\tconst weekdays = weekdayLabels ?? weekdayNames(locale);\n\tconst months = monthLabels ?? monthNames(locale);\n\tconst calendarId = useId();\n\tconst scrollRegionRef = useRef<HTMLDivElement | null>(null);\n\n\tconst { weeks, dataMap, maxValue, labels, validDays, dateToValidIndex } = useMemo(() => {\n\t\tconst weeks = getYearWeeks(year);\n\t\tconst dataMap = new Map<string, number>();\n\t\tlet maxValue = 0;\n\t\tfor (const point of data) {\n\t\t\tdataMap.set(point.date, point.value);\n\t\t\tif (point.value > maxValue) {\n\t\t\t\tmaxValue = point.value;\n\t\t\t}\n\t\t}\n\n\t\tconst labels: { month: string; weekIndex: number }[] = [];\n\t\tlet lastMonth = -1;\n\t\tweeks.forEach((week, weekIndex) => {\n\t\t\tconst firstDayOfWeek = week.find((date) => date.getFullYear() === year);\n\t\t\tif (firstDayOfWeek) {\n\t\t\t\tconst month = firstDayOfWeek.getMonth();\n\t\t\t\tif (month !== lastMonth) {\n\t\t\t\t\tlabels.push({ month: months[month], weekIndex });\n\t\t\t\t\tlastMonth = month;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst validDays: string[] = [];\n\t\tconst dateToValidIndex = new Map<string, number>();\n\n\t\tweeks.forEach((week) => {\n\t\t\tweek.forEach((date) => {\n\t\t\t\tif (date.getFullYear() === year) {\n\t\t\t\t\tconst dateStr = formatDate(date);\n\t\t\t\t\tdateToValidIndex.set(dateStr, validDays.length);\n\t\t\t\t\tvalidDays.push(dateStr);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\treturn { weeks, dataMap, maxValue, labels, validDays, dateToValidIndex };\n\t}, [data, months, year]);\n\n\tconst [activeDate, setActiveDate] = useState<string>(() => {\n\t\treturn validDays[0] ?? `${year}-01-01`;\n\t});\n\tconst [openTooltipDate, setOpenTooltipDate] = useState<string | null>(null);\n\n\tconst cellRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\n\tconst isYearFocusedInsideRef = useRef(false);\n\n\t// If year or validDays change: if a cell held focus, restore focus to the clamped\n\t// active date or scroll container; if focus was outside, do NOT steal focus.\n\tuseEffect(() => {\n\t\tconst hadFocus = isYearFocusedInsideRef.current;\n\t\tif (validDays.length === 0) {\n\t\t\tsetActiveDate(\"\");\n\t\t\tsetOpenTooltipDate(null);\n\t\t\tif (hadFocus) {\n\t\t\t\tscrollRegionRef.current?.focus();\n\t\t\t}\n\t\t} else if (!dateToValidIndex.has(activeDate)) {\n\t\t\tconst nextDate = validDays[0] ?? \"\";\n\t\t\tsetActiveDate(nextDate);\n\t\t\tif (hadFocus) {\n\t\t\t\tcellRefs.current.get(nextDate)?.focus();\n\t\t\t}\n\t\t}\n\t}, [validDays, dateToValidIndex, activeDate]);\n\n\tconst selectedDate = dateToValidIndex.has(activeDate) ? activeDate : validDays[0];\n\n\tconst navigateToDay = (targetDate: string | undefined) => {\n\t\tif (!targetDate) return;\n\t\tsetActiveDate(targetDate);\n\t\tsetOpenTooltipDate(targetDate);\n\t\tconst btn = cellRefs.current.get(targetDate);\n\t\tbtn?.focus();\n\t};\n\n\tconst handleCellKeyDown = (e: KeyboardEvent<HTMLButtonElement>, dateStr: string) => {\n\t\tif (validDays.length === 0) return;\n\n\t\tconst currentIdx = dateToValidIndex.get(dateStr) ?? 0;\n\n\t\tif (e.key === \"Escape\") {\n\t\t\tsetOpenTooltipDate(null);\n\t\t\treturn;\n\t\t}\n\n\t\tif (e.key === \"ArrowDown\") {\n\t\t\te.preventDefault();\n\t\t\t// Visually next day (down in the column)\n\t\t\tconst nextDay = validDays[currentIdx + 1];\n\t\t\tif (nextDay) {\n\t\t\t\tnavigateToDay(nextDay);\n\t\t\t}\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\te.preventDefault();\n\t\t\t// Visually previous day (up in the column)\n\t\t\tconst prevDay = validDays[currentIdx - 1];\n\t\t\tif (prevDay) {\n\t\t\t\tnavigateToDay(prevDay);\n\t\t\t}\n\t\t} else if (e.key === \"ArrowRight\") {\n\t\t\te.preventDefault();\n\t\t\t// Visually next week (right in the row: +7 days by index)\n\t\t\tconst targetIdx = currentIdx + 7;\n\t\t\tif (targetIdx < validDays.length) {\n\t\t\t\tnavigateToDay(validDays[targetIdx]);\n\t\t\t} else {\n\t\t\t\tnavigateToDay(validDays[validDays.length - 1]);\n\t\t\t}\n\t\t} else if (e.key === \"ArrowLeft\") {\n\t\t\te.preventDefault();\n\t\t\t// Visually previous week (left in the row: -7 days by index)\n\t\t\tconst targetIdx = currentIdx - 7;\n\t\t\tif (targetIdx >= 0) {\n\t\t\t\tnavigateToDay(validDays[targetIdx]);\n\t\t\t} else {\n\t\t\t\tnavigateToDay(validDays[0]);\n\t\t\t}\n\t\t} else if (e.key === \"Home\") {\n\t\t\te.preventDefault();\n\t\t\tnavigateToDay(validDays[0]);\n\t\t} else if (e.key === \"End\") {\n\t\t\te.preventDefault();\n\t\t\tnavigateToDay(validDays[validDays.length - 1]);\n\t\t}\n\t};\n\n\tconst labelWidth = 30;\n\n\treturn (\n\t\t<div\n\t\t\tref={scrollRegionRef}\n\t\t\ttabIndex={-1}\n\t\t\trole=\"region\"\n\t\t\taria-label={`${ariaLabel} scrollable view`}\n\t\t\tonFocus={() => {\n\t\t\t\tisYearFocusedInsideRef.current = true;\n\t\t\t}}\n\t\t\tonBlur={(e) => {\n\t\t\t\tif (!e.currentTarget.contains(e.relatedTarget)) {\n\t\t\t\t\tisYearFocusedInsideRef.current = false;\n\t\t\t\t}\n\t\t\t}}\n\t\t\tclassName={cn(\n\t\t\t\t\"overflow-x-auto rounded-md outline-none focus-visible:ring-1 focus-visible:ring-basalt-ring\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<TooltipProvider>\n\t\t\t\t<div className=\"inline-block p-1\" role=\"group\" aria-label={ariaLabel}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"relative mb-1 h-4 text-xs text-basalt-muted-foreground\"\n\t\t\t\t\t\tstyle={{ marginLeft: labelWidth }}\n\t\t\t\t\t>\n\t\t\t\t\t\t{labels.map((label) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={`${label.month}-${label.weekIndex}`}\n\t\t\t\t\t\t\t\tclassName=\"absolute\"\n\t\t\t\t\t\t\t\tstyle={{ left: label.weekIndex * (cellSize + cellGap) }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{label.month}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex\">\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"mr-1 flex flex-col text-xs text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\tstyle={{ width: labelWidth }}\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{weekdays.map((day, index) => (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={`${day}-${index}`}\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\theight: cellSize + cellGap,\n\t\t\t\t\t\t\t\t\t\tlineHeight: `${cellSize + cellGap}px`,\n\t\t\t\t\t\t\t\t\t\tvisibility: index % 2 === 1 ? \"visible\" : \"hidden\",\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\t{day}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"flex\" style={{ gap: cellGap }}>\n\t\t\t\t\t\t\t{weeks.map((week, weekIndex) => (\n\t\t\t\t\t\t\t\t<div key={weekIndex} className=\"flex flex-col\" style={{ gap: cellGap }}>\n\t\t\t\t\t\t\t\t\t{week.map((date, dayIndex) => {\n\t\t\t\t\t\t\t\t\t\tconst dateStr = formatDate(date);\n\t\t\t\t\t\t\t\t\t\tconst isCurrentYear = date.getFullYear() === year;\n\t\t\t\t\t\t\t\t\t\tif (!isCurrentYear) {\n\t\t\t\t\t\t\t\t\t\t\treturn (\n\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\tkey={dayIndex}\n\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\twidth: cellSize,\n\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\tvisibility: \"hidden\",\n\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\taria-hidden=\"true\"\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}\n\n\t\t\t\t\t\t\t\t\t\tconst value = dataMap.get(dateStr) ?? 0;\n\t\t\t\t\t\t\t\t\t\tconst colorIndex = getColorIndex(value, maxValue, colorScale);\n\t\t\t\t\t\t\t\t\t\tconst isSelected = selectedDate === dateStr;\n\t\t\t\t\t\t\t\t\t\tconst formattedValue = valueFormatter(value, dateStr);\n\t\t\t\t\t\t\t\t\t\tconst labelText = `${dateStr}, ${metricLabel}: ${formattedValue}`;\n\t\t\t\t\t\t\t\t\t\tconst isOpen = openTooltipDate === dateStr;\n\n\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\t\t\t\t\tkey={dayIndex}\n\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\tonOpenChange={(next) => {\n\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\tsetOpenTooltipDate(dateStr);\n\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\tsetOpenTooltipDate((curr) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (curr !== dateStr) return curr;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// If this cell currently holds document focus, ignore scroll dismiss\n\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\tdocument.activeElement === cellRefs.current.get(dateStr);\n\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});\n\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}}\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<TooltipTrigger asChild>\n\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\tref={(el) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (el) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcellRefs.current.set(dateStr, el);\n\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\tcellRefs.current.delete(dateStr);\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\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-label={labelText}\n\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\tonFocus={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetActiveDate(dateStr);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipDate(dateStr);\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\tonBlur={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipDate((curr) => (curr === dateStr ? null : curr));\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\tonKeyDown={(e) => handleCellKeyDown(e, dateStr)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"box-border m-0 cursor-pointer rounded-sm border-0 p-0 transition-colors 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\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\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\tbackgroundColor: colorScale[colorIndex],\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/>\n\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<TooltipContent id={`${calendarId}-${dateStr}`}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"font-medium\">{dateStr}</div>\n\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{metricLabel}: {formattedValue}\n\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</div>\n\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</Tooltip>\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</div>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"mt-2 flex items-center justify-end gap-1 text-xs text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<span>{lessLabel}</span>\n\t\t\t\t\t\t{colorScale.map((color) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={color}\n\t\t\t\t\t\t\t\tclassName=\"rounded-sm\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t<span>{moreLabel}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</TooltipProvider>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|