@acronis-platform/ui-react 2.0.0 → 4.0.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.
Files changed (243) hide show
  1. package/dist/components/ui/accordion-container/accordion-container.js +144 -0
  2. package/dist/components/ui/accordion-container/accordion-container.js.map +1 -0
  3. package/dist/components/ui/app-shell-chat/app-shell-chat.js.map +1 -1
  4. package/dist/components/ui/area-chart/area-chart.js +141 -139
  5. package/dist/components/ui/area-chart/area-chart.js.map +1 -1
  6. package/dist/components/ui/avatar/avatar.js +33 -22
  7. package/dist/components/ui/avatar/avatar.js.map +1 -1
  8. package/dist/components/ui/bar-chart/bar-chart.js +295 -293
  9. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  10. package/dist/components/ui/card/card.js +150 -74
  11. package/dist/components/ui/card/card.js.map +1 -1
  12. package/dist/components/ui/card-section/card-section.js +111 -0
  13. package/dist/components/ui/card-section/card-section.js.map +1 -0
  14. package/dist/components/ui/category-bar/category-bar.js +109 -93
  15. package/dist/components/ui/category-bar/category-bar.js.map +1 -1
  16. package/dist/components/ui/chart/chart-palette.js +113 -0
  17. package/dist/components/ui/chart/chart-palette.js.map +1 -0
  18. package/dist/components/ui/chart/chart.js +176 -129
  19. package/dist/components/ui/chart/chart.js.map +1 -1
  20. package/dist/components/ui/chart-state/chart-state-illustrations.js +310 -0
  21. package/dist/components/ui/chart-state/chart-state-illustrations.js.map +1 -0
  22. package/dist/components/ui/chart-state/chart-state.js +48 -34
  23. package/dist/components/ui/chart-state/chart-state.js.map +1 -1
  24. package/dist/components/ui/chart-widget/chart-widget.js +87 -0
  25. package/dist/components/ui/chart-widget/chart-widget.js.map +1 -0
  26. package/dist/components/ui/composed-chart/composed-chart.js +117 -115
  27. package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
  28. package/dist/components/ui/confidence-cone/confidence-cone.js +166 -158
  29. package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
  30. package/dist/components/ui/data-table/data-table.js +4 -2
  31. package/dist/components/ui/data-table/data-table.js.map +1 -1
  32. package/dist/components/ui/empty-overlay/empty-overlay.js +49 -0
  33. package/dist/components/ui/empty-overlay/empty-overlay.js.map +1 -0
  34. package/dist/components/ui/funnel-chart/funnel-chart.js +162 -161
  35. package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
  36. package/dist/components/ui/histogram/histogram.js +94 -92
  37. package/dist/components/ui/histogram/histogram.js.map +1 -1
  38. package/dist/components/ui/input/input.js.map +1 -1
  39. package/dist/components/ui/label/label.js +2 -9
  40. package/dist/components/ui/label/label.js.map +1 -1
  41. package/dist/components/ui/line-chart/line-chart.js +143 -141
  42. package/dist/components/ui/line-chart/line-chart.js.map +1 -1
  43. package/dist/components/ui/metric/metric.js +74 -185
  44. package/dist/components/ui/metric/metric.js.map +1 -1
  45. package/dist/components/ui/page-content/page-content.js.map +1 -1
  46. package/dist/components/ui/pie-chart/pie-chart.js +201 -195
  47. package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
  48. package/dist/components/ui/radar-chart/radar-chart.js +133 -131
  49. package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
  50. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +297 -265
  51. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
  52. package/dist/components/ui/sankey-chart/sankey-chart.js +123 -101
  53. package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -1
  54. package/dist/components/ui/scatter-chart/scatter-chart.js +76 -74
  55. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
  56. package/dist/components/ui/section/section.js +157 -31
  57. package/dist/components/ui/section/section.js.map +1 -1
  58. package/dist/components/ui/stepper/stepper.js +24 -24
  59. package/dist/components/ui/stepper/stepper.js.map +1 -1
  60. package/dist/components/ui/stepper-item/stepper-item.js +43 -24
  61. package/dist/components/ui/stepper-item/stepper-item.js.map +1 -1
  62. package/dist/components/ui/table/table.js +27 -27
  63. package/dist/components/ui/table/table.js.map +1 -1
  64. package/dist/components/ui/treemap/treemap.js +133 -124
  65. package/dist/components/ui/treemap/treemap.js.map +1 -1
  66. package/dist/components/ui/trend-indicator/trend-indicator.js +34 -69
  67. package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -1
  68. package/dist/components/ui/wizard/wizard.js +59 -0
  69. package/dist/components/ui/wizard/wizard.js.map +1 -0
  70. package/dist/hooks/use-wizard.js +75 -0
  71. package/dist/hooks/use-wizard.js.map +1 -0
  72. package/dist/index.js +540 -525
  73. package/dist/index.js.map +1 -1
  74. package/dist/llms/accordion-container.md +181 -0
  75. package/dist/llms/accordion.md +124 -0
  76. package/dist/llms/alert.md +225 -0
  77. package/dist/llms/app-shell-chat.md +415 -0
  78. package/dist/llms/area-chart.md +355 -0
  79. package/dist/llms/avatar.md +208 -0
  80. package/dist/llms/bar-chart.md +406 -0
  81. package/dist/llms/breadcrumb.md +326 -0
  82. package/dist/llms/button-group.md +298 -0
  83. package/dist/llms/button-icon-input.md +142 -0
  84. package/dist/llms/button-icon-menu.md +209 -0
  85. package/dist/llms/button-icon.md +128 -0
  86. package/dist/llms/button-menu.md +172 -0
  87. package/dist/llms/button.md +185 -0
  88. package/dist/llms/calendar-panel.md +733 -0
  89. package/dist/llms/calendar.md +188 -0
  90. package/dist/llms/card-filter.md +214 -0
  91. package/dist/llms/card-section.md +293 -0
  92. package/dist/llms/card.md +447 -0
  93. package/dist/llms/carousel-dialog.md +156 -0
  94. package/dist/llms/category-bar.md +193 -0
  95. package/dist/llms/chart-state.md +190 -0
  96. package/dist/llms/chart-widget.md +209 -0
  97. package/dist/llms/chart.md +182 -0
  98. package/dist/llms/checkbox.md +257 -0
  99. package/dist/llms/chip.md +195 -0
  100. package/dist/llms/combobox.md +164 -0
  101. package/dist/llms/composed-chart.md +508 -0
  102. package/dist/llms/confidence-cone.md +277 -0
  103. package/dist/llms/data-table.md +474 -0
  104. package/dist/llms/date-range-picker.md +272 -0
  105. package/dist/llms/description-list.md +131 -0
  106. package/dist/llms/dialog-footer-carousel.md +147 -0
  107. package/dist/llms/dialog-footer-default.md +142 -0
  108. package/dist/llms/dialog-root.md +246 -0
  109. package/dist/llms/dialog-welcome.md +223 -0
  110. package/dist/llms/dialog.md +403 -0
  111. package/dist/llms/dropdown-menu.md +193 -0
  112. package/dist/llms/empty-overlay.md +146 -0
  113. package/dist/llms/empty.md +156 -0
  114. package/dist/llms/field.md +185 -0
  115. package/dist/llms/filter-cards.md +157 -0
  116. package/dist/llms/filter-chips.md +323 -0
  117. package/dist/llms/filter-search.md +512 -0
  118. package/dist/llms/form.md +154 -0
  119. package/dist/llms/funnel-chart.md +333 -0
  120. package/dist/llms/grid.md +80 -0
  121. package/dist/llms/histogram.md +190 -0
  122. package/dist/llms/input-date-picker.md +203 -0
  123. package/dist/llms/input-otp.md +173 -0
  124. package/dist/llms/input-password.md +197 -0
  125. package/dist/llms/input-search.md +170 -0
  126. package/dist/llms/input-select.md +278 -0
  127. package/dist/llms/input-text-area.md +271 -0
  128. package/dist/llms/input-text.md +192 -0
  129. package/dist/llms/line-chart.md +369 -0
  130. package/dist/llms/link.md +209 -0
  131. package/dist/llms/loading.md +130 -0
  132. package/dist/llms/meter.md +177 -0
  133. package/dist/llms/metric.md +204 -0
  134. package/dist/llms/number-field.md +122 -0
  135. package/dist/llms/page-content.md +69 -0
  136. package/dist/llms/page-header.md +182 -0
  137. package/dist/llms/pagination.md +133 -0
  138. package/dist/llms/pie-chart.md +307 -0
  139. package/dist/llms/popover.md +252 -0
  140. package/dist/llms/progress-circle.md +126 -0
  141. package/dist/llms/progress.md +111 -0
  142. package/dist/llms/radar-chart.md +316 -0
  143. package/dist/llms/radial-bar-chart.md +319 -0
  144. package/dist/llms/radio.md +255 -0
  145. package/dist/llms/resizable.md +195 -0
  146. package/dist/llms/sankey-chart.md +208 -0
  147. package/dist/llms/scatter-chart.md +239 -0
  148. package/dist/llms/scroll-area.md +183 -0
  149. package/dist/llms/section.md +401 -0
  150. package/dist/llms/select.md +210 -0
  151. package/dist/llms/separator.md +87 -0
  152. package/dist/llms/sheet.md +202 -0
  153. package/dist/llms/sidebar-primary.md +360 -0
  154. package/dist/llms/sidebar-secondary.md +417 -0
  155. package/dist/llms/skeleton.md +81 -0
  156. package/dist/llms/slider.md +97 -0
  157. package/dist/llms/spinner.md +100 -0
  158. package/dist/llms/stack.md +80 -0
  159. package/dist/llms/stepper-item.md +309 -0
  160. package/dist/llms/stepper.md +251 -0
  161. package/dist/llms/switch.md +140 -0
  162. package/dist/llms/table.md +436 -0
  163. package/dist/llms/tabs.md +197 -0
  164. package/dist/llms/tag.md +139 -0
  165. package/dist/llms/timeline.md +361 -0
  166. package/dist/llms/timer.md +259 -0
  167. package/dist/llms/toast.md +241 -0
  168. package/dist/llms/toggle-group.md +121 -0
  169. package/dist/llms/toolbar.md +453 -0
  170. package/dist/llms/tooltip.md +164 -0
  171. package/dist/llms/treemap.md +254 -0
  172. package/dist/llms/trend-indicator.md +132 -0
  173. package/dist/llms/widget-placeholder.md +169 -0
  174. package/dist/llms/wizard.md +412 -0
  175. package/dist/llms.txt +142 -0
  176. package/dist/react.js +540 -525
  177. package/dist/react.js.map +1 -1
  178. package/dist/src/components/ui/accordion-container/accordion-container.d.ts +44 -0
  179. package/dist/src/components/ui/accordion-container/index.d.ts +1 -0
  180. package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
  181. package/dist/src/components/ui/avatar/avatar.d.ts +27 -8
  182. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
  183. package/dist/src/components/ui/button/button.d.ts +1 -1
  184. package/dist/src/components/ui/card/card.d.ts +69 -8
  185. package/dist/src/components/ui/card/index.d.ts +1 -1
  186. package/dist/src/components/ui/card-section/card-section.d.ts +50 -0
  187. package/dist/src/components/ui/card-section/index.d.ts +1 -0
  188. package/dist/src/components/ui/category-bar/category-bar.d.ts +10 -4
  189. package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +48 -0
  190. package/dist/src/components/ui/chart/__tests__/chart-palette.test.d.ts +1 -0
  191. package/dist/src/components/ui/chart/chart-palette.d.ts +128 -0
  192. package/dist/src/components/ui/chart/chart.d.ts +66 -15
  193. package/dist/src/components/ui/chart/index.d.ts +4 -2
  194. package/dist/src/components/ui/chart-state/chart-state-illustrations.d.ts +6 -0
  195. package/dist/src/components/ui/chart-state/chart-state.d.ts +13 -2
  196. package/dist/src/components/ui/chart-state/index.d.ts +1 -0
  197. package/dist/src/components/ui/chart-widget/chart-widget.d.ts +64 -0
  198. package/dist/src/components/ui/chart-widget/index.d.ts +1 -0
  199. package/dist/src/components/ui/composed-chart/composed-chart.d.ts +12 -7
  200. package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +10 -5
  201. package/dist/src/components/ui/dialog/dialog.d.ts +1 -1
  202. package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +20 -0
  203. package/dist/src/components/ui/empty-overlay/index.d.ts +2 -0
  204. package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
  205. package/dist/src/components/ui/grid/grid.d.ts +1 -1
  206. package/dist/src/components/ui/histogram/histogram.d.ts +10 -4
  207. package/dist/src/components/ui/label/index.d.ts +1 -1
  208. package/dist/src/components/ui/label/label.d.ts +1 -5
  209. package/dist/src/components/ui/line-chart/line-chart.d.ts +9 -4
  210. package/dist/src/components/ui/metric/metric.d.ts +13 -14
  211. package/dist/src/components/ui/pie-chart/pie-chart.d.ts +17 -8
  212. package/dist/src/components/ui/radar-chart/radar-chart.d.ts +10 -5
  213. package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +17 -6
  214. package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +10 -5
  215. package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +10 -5
  216. package/dist/src/components/ui/section/index.d.ts +1 -1
  217. package/dist/src/components/ui/section/section.d.ts +75 -6
  218. package/dist/src/components/ui/sheet/sheet.d.ts +1 -1
  219. package/dist/src/components/ui/stack/stack.d.ts +1 -1
  220. package/dist/src/components/ui/stepper-item/stepper-item.d.ts +6 -5
  221. package/dist/src/components/ui/tag/tag.d.ts +1 -1
  222. package/dist/src/components/ui/treemap/treemap.d.ts +11 -5
  223. package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +3 -7
  224. package/dist/src/components/ui/wizard/index.d.ts +1 -0
  225. package/dist/src/components/ui/wizard/wizard.d.ts +6 -0
  226. package/dist/src/hooks/index.d.ts +1 -0
  227. package/dist/src/hooks/use-wizard.d.ts +80 -0
  228. package/dist/src/index.d.ts +5 -3
  229. package/dist/ui-react.css +1 -1
  230. package/package.json +12 -6
  231. package/dist/components/ui/app-shell/app-shell.js +0 -75
  232. package/dist/components/ui/app-shell/app-shell.js.map +0 -1
  233. package/dist/components/ui/auth-layout/auth-layout.js +0 -56
  234. package/dist/components/ui/auth-layout/auth-layout.js.map +0 -1
  235. package/dist/components/ui/collapsible/collapsible.js +0 -22
  236. package/dist/components/ui/collapsible/collapsible.js.map +0 -1
  237. package/dist/src/components/ui/app-shell/app-shell.d.ts +0 -8
  238. package/dist/src/components/ui/app-shell/index.d.ts +0 -1
  239. package/dist/src/components/ui/auth-layout/auth-layout.d.ts +0 -6
  240. package/dist/src/components/ui/auth-layout/index.d.ts +0 -1
  241. package/dist/src/components/ui/collapsible/collapsible.d.ts +0 -5
  242. package/dist/src/components/ui/collapsible/index.d.ts +0 -1
  243. package/dist/src/components/ui/label/label.docs.d.ts +0 -10
@@ -1 +1 @@
1
- {"version":3,"file":"confidence-cone.js","sources":["../../../../src/components/ui/confidence-cone/confidence-cone.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n Area,\n CartesianGrid,\n ComposedChart,\n Line,\n ReferenceArea,\n ReferenceLine,\n Text,\n XAxis,\n YAxis,\n} from 'recharts';\n\nimport { cn } from '@/lib/utils';\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n resolveAxisDomain,\n resolveAnimation,\n resolveRotatedTickAnchor,\n resolveXAxisHeight,\n resolveXAxisTitle,\n resolveYAxisTitle,\n CHART_LABEL_FONT_SIZE,\n type ChartConfig,\n type ChartLegendContentProps,\n type ChartTooltipContentProps,\n type CartesianChartProps,\n type ChartAnimationProps,\n} from '../chart';\n\n// A forecast confidence-cone: a solid line over the known/actual period, a\n// dashed line over the forecast period, and a shaded band (the \"cone\") between\n// a lower and upper bound that typically widens with the horizon — visualizing\n// growing uncertainty. Built on the shared Chart primitives; no new tokens\n// (series colors are caller-supplied via `config`). The whole metric renders in\n// one hue — actual and forecast differ by line style, not color — so the cone\n// band and the forecast line both reuse the actual series' color.\n\n// Each series' band is a synthetic `[lower, upper]` range field per row that a\n// recharts <Area> shades; kept out of the tooltip/legend (see the filters\n// below). One band per series, so the key carries the series' actual key — the\n// whole `__cone` prefix is reserved.\nconst BAND_PREFIX = '__cone';\nconst bandKeyFor = (actualKey: string) => `${BAND_PREFIX}:${actualKey}`;\n\n/**\n * Drop every synthetic cone-band range series from a recharts tooltip/legend\n * payload, keeping the real actual/forecast series (and their order). Applied to\n * both the default tooltip and any caller-supplied `tooltipContent`, so no band\n * surfaces regardless of which path renders or how many series are plotted.\n */\nexport function dropConeBand<T extends { dataKey?: unknown }>(\n payload: readonly T[] | undefined\n): T[] | undefined {\n return payload?.filter(\n (item) =>\n !(typeof item.dataKey === 'string' && item.dataKey.startsWith(BAND_PREFIX))\n );\n}\n\n/**\n * Reduce a legend payload to the metrics the chart plots — one entry per series.\n * A series' actual, forecast and cone are three recharts series painting a\n * single metric in a single hue, so the legend names each metric once, with its\n * actual series' swatch, instead of listing line styles as separate series.\n */\nexport function keepMetricSeries<T extends { dataKey?: unknown }>(\n payload: readonly T[] | undefined,\n actualKeys: readonly string[]\n): T[] | undefined {\n return payload?.filter(\n (item) => typeof item.dataKey === 'string' && actualKeys.includes(item.dataKey)\n );\n}\n\n/**\n * Wrap a caller-supplied `tooltipContent` so the synthetic cone band is stripped\n * from the payload before it renders, while preserving recharts' own mount\n * semantics — a function is mounted via `createElement` (its own component\n * identity + hook state), an element via `cloneElement`. This mirrors what the\n * pass-through charts get by handing `content` straight to recharts, so a\n * function-form tooltip keeps its state across re-renders here too. The returned\n * component is a stable content type (memoize it on `tooltipContent`).\n */\ntype TooltipContentType = NonNullable<\n React.ComponentProps<typeof ChartTooltip>['content']\n>;\ntype TooltipContentFn = Extract<TooltipContentType, (...args: never[]) => unknown>;\ntype TooltipRenderProps = Parameters<TooltipContentFn>[0];\n\nexport function createConeTooltip(tooltipContent: TooltipContentType) {\n return function ConeTooltip(props: TooltipRenderProps) {\n const merged = {\n ...props,\n payload: dropConeBand(props.payload),\n } as TooltipRenderProps;\n return typeof tooltipContent === 'function'\n ? React.createElement(\n tooltipContent as React.FunctionComponent<TooltipRenderProps>,\n merged\n )\n : React.cloneElement(tooltipContent, merged);\n };\n}\n\n/**\n * One plotted metric: its actual / forecast columns and, optionally, the two\n * bound columns that shade its cone. Omit `lowerKey`/`upperKey` for a band-less\n * metric — a solid line handing off to a bare dashed projection.\n */\nexport interface ConfidenceConeSeries {\n /** Field for the known/actual values — drawn as a solid line with a filled area. */\n actualKey: string;\n /** Field for the projected values — drawn as a dashed line. */\n forecastKey: string;\n /** Field for the cone's lower bound. Omit (with `upperKey`) for no cone. */\n lowerKey?: string;\n /** Field for the cone's upper bound. Omit (with `lowerKey`) for no cone. */\n upperKey?: string;\n}\n\n/**\n * The x values of the projected period — every row carrying a forecast value for\n * at least one series, in data order. The first is the hand-off point (where the\n * shaded region and divider start); the whole set drives the forecast tick\n * styling, matched by value so tick `interval` can't skew it the way a tick\n * index would. Exported for unit tests; not part of the package's public API.\n */\nexport function forecastPeriodX(\n data: ReadonlyArray<Record<string, string | number | null | undefined>>,\n series: readonly ConfidenceConeSeries[],\n xKey: string\n): Array<string | number | null | undefined> {\n return data\n .filter((row) => series.some(({ forecastKey }) => typeof row[forecastKey] === 'number'))\n .map((row) => row[xKey]);\n}\n\n/**\n * Build the X-axis tick renderer that sets the projected columns apart: italic,\n * in the metric's hue. Styled inline rather than through the `fill` attribute\n * recharts hands every tick, so the accent survives the class-based tick color\n * a chart theme may apply. A custom tick owns its own text, so the caller's\n * `xTickFormatter` is applied here — recharts only applies it to default ticks.\n * Exported for unit tests; not part of the package's public API.\n */\nexport function createForecastTick(\n forecastX: ReadonlySet<string | number | null | undefined>,\n color: string,\n tickFormatter?: CartesianChartProps['xTickFormatter']\n) {\n return function ForecastTick({\n payload,\n index,\n ...tickProps\n }: {\n payload?: { value?: string | number };\n index?: number;\n }) {\n const value = payload?.value;\n return (\n <Text\n {...tickProps}\n style={\n value != null && forecastX.has(value)\n ? { fontStyle: 'italic', fill: color }\n : undefined\n }\n >\n {tickFormatter && value != null ? tickFormatter(value, index) : value}\n </Text>\n );\n };\n}\n\n/** A dashed horizontal threshold on the value axis. */\nexport interface ConfidenceConeReferenceLine {\n /** Position on the value (Y) axis. */\n value: number;\n /** Optional caption rendered at the line's right end. */\n label?: string;\n}\n\n/**\n * Every prop except the one-form-or-the-other requirement `ConfidenceConeProps`\n * layers on below. Exported so the stories can type their `Meta` on a single\n * object shape — Storybook can't split a union's required args between `meta.args`\n * and a story's. Not re-exported from `index.ts`; not part of the public API.\n */\nexport interface ConfidenceConeBaseProps\n extends Omit<React.ComponentProps<'div'>, 'children'>,\n CartesianChartProps,\n ChartAnimationProps {\n /**\n * Row-per-point data — the shared x dimension plus each series' actual /\n * forecast / bound fields. Rows are naturally sparse (a point has either an\n * actual or a forecast + bounds), so missing fields are allowed. Avoid fields\n * starting with `__cone` — that prefix is reserved for the internal\n * prediction-band series.\n */\n data: ReadonlyArray<Record<string, string | number | null | undefined>>;\n /**\n * Per-series map of `label` / `color` for the actual + forecast lines\n * (imported from the shared `Chart` primitives). Colors are caller-supplied —\n * reference an existing semantic `--ui-*` token; there is no chart palette tier\n * yet. Each metric renders in one hue: its cone band and forecast line both\n * reuse its actual series' color — actual and forecast differ by line style,\n * not hue.\n */\n config: ChartConfig;\n /** Category / time axis key (the shared dimension across rows). */\n xKey: string;\n /**\n * Plot several metrics against one shared axis — each with its own actual /\n * forecast / bound fields and its own hue (from `config[actualKey]`). Takes\n * precedence over the single-series `actualKey`/`forecastKey`/`lowerKey`/\n * `upperKey` shorthand below; pass one form or the other, not both. One of the\n * two forms is required.\n */\n series?: readonly ConfidenceConeSeries[];\n /**\n * Single-series shorthand — field for the known/actual values, drawn as a\n * solid line with a filled area. Required (with `forecastKey`) unless `series`\n * is set, which supersedes it.\n */\n actualKey?: string;\n /**\n * Single-series shorthand — field for the projected values, drawn as a dashed\n * line. Required (with `actualKey`) unless `series` is set, which supersedes\n * it.\n */\n forecastKey?: string;\n /** Field for the cone's lower bound. Omit (with `upperKey`) for no cone. */\n lowerKey?: string;\n /** Field for the cone's upper bound. Omit (with `lowerKey`) for no cone. */\n upperKey?: string;\n /**\n * How the known/actual period is drawn: a filled `area` under the line (the\n * default), or a bare `line` — for a chart where the cone is the only shaded\n * region, or where several metrics' fills would muddy each other.\n */\n actualType?: 'area' | 'line';\n /** Stroke width of the actual + forecast lines. */\n strokeWidth?: number;\n /**\n * Mark each data point: a filled dot on the observed values, a hollow one on\n * the projection — so a point reads as measured or predicted at a glance.\n */\n showDots?: boolean;\n /**\n * Italicize the X-axis ticks over the forecast period and paint them in the\n * first series' hue, so the projected columns read as projected even when the\n * shaded region is off.\n */\n styleForecastTicks?: boolean;\n /**\n * One or more dashed horizontal thresholds on the value axis — e.g. a target\n * or a capacity limit. Pass a single object or an array to draw several.\n */\n referenceLine?: ConfidenceConeReferenceLine | ConfidenceConeReferenceLine[];\n /**\n * Set off the forecast period from the actuals with a dashed divider at the\n * hand-off point (the first row with a forecast value) and a subtle shaded\n * band over the forecast region.\n */\n showForecastRegion?: boolean;\n showLegend?: boolean;\n}\n\n/**\n * Which columns to plot has to be spelled out one way or the other: the `series`\n * array, or the flat `actualKey` + `forecastKey` shorthand. Expressed as a union\n * so a chart with neither is a compile error rather than a silent plot of axes\n * and nothing else. Both forms together stay legal — `series` wins (see\n * `plotted`), which is what the multi-series stories rely on to clear the args\n * table.\n */\nexport type ConfidenceConeProps = ConfidenceConeBaseProps &\n (\n | { series: readonly ConfidenceConeSeries[] }\n | { actualKey: string; forecastKey: string }\n );\n\nconst ConfidenceCone = React.forwardRef<HTMLDivElement, ConfidenceConeProps>(\n (\n {\n className,\n config,\n data,\n xKey,\n series,\n actualKey,\n forecastKey,\n lowerKey,\n upperKey,\n xAxisLabel,\n yAxisLabel,\n yUnit,\n actualType = 'area',\n strokeWidth = 2,\n showDots = false,\n styleForecastTicks = false,\n referenceLine,\n showForecastRegion = true,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n showXAxis = true,\n showYAxis = true,\n xTickFormatter,\n yTickFormatter,\n xAxisAngle,\n xAxisInterval,\n yAxisTickCount,\n yAxisDomain,\n gridDashed,\n gridHorizontal,\n gridVertical,\n tooltipContent,\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n ...props\n },\n ref\n ) => {\n // The flat *Key props are the single-series shorthand for `series`.\n const plotted = React.useMemo<readonly ConfidenceConeSeries[]>(() => {\n if (series?.length) return series;\n if (!actualKey || !forecastKey) return [];\n return [{ actualKey, forecastKey, lowerKey, upperKey }];\n }, [series, actualKey, forecastKey, lowerKey, upperKey]);\n\n const animation = resolveAnimation({\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n });\n // Memoized so recharts sees a stable content type across renders — a fresh\n // wrapper each render would remount the caller's tooltip and reset its state.\n const customTooltip = React.useMemo(\n () => (tooltipContent ? createConeTooltip(tooltipContent) : undefined),\n [tooltipContent]\n );\n\n const xAxisTitle = resolveXAxisTitle(xAxisLabel);\n const yAxisTitle = resolveYAxisTitle(yAxisLabel);\n\n const yDomain = resolveAxisDomain(yAxisDomain);\n\n // One hue per metric. Each cone and forecast line already paints with its own\n // series' actual color; re-pointing that series' forecast key's `--color-*`\n // at it too means nothing downstream — a custom tooltip, a caller's\n // `var(--color-<forecastKey>)` — can reintroduce a second color.\n const seriesConfig = React.useMemo(() => {\n let next: ChartConfig | undefined;\n for (const { actualKey: aKey, forecastKey: fKey } of plotted) {\n const actual = config[aKey];\n const forecast = config[fKey];\n if (!actual || !forecast) continue;\n next ??= { ...config };\n next[fKey] = {\n label: forecast.label,\n icon: forecast.icon,\n ...(actual.theme ? { theme: actual.theme } : { color: actual.color }),\n };\n }\n return next ?? config;\n }, [config, plotted]);\n\n const xAxisHeight = resolveXAxisHeight(xAxisLabel, xAxisAngle);\n\n // Augment each row with one `[lower, upper]` band tuple per coned series for\n // its Area to shade. Rows missing a numeric bound are left un-coned (the\n // band breaks there); a series without bounds gets no band at all.\n const chartData = data.map((row) => {\n const next: Record<string, unknown> = { ...row };\n for (const { actualKey: aKey, lowerKey: lKey, upperKey: uKey } of plotted) {\n if (!lKey || !uKey) continue;\n const lower = row[lKey];\n const upper = row[uKey];\n next[bandKeyFor(aKey)] =\n typeof lower === 'number' && typeof upper === 'number'\n ? [lower, upper]\n : undefined;\n }\n return next;\n });\n\n const forecastX = forecastPeriodX(data, plotted, xKey);\n // Set the projected period off from the actuals with a shaded band + a\n // divider at the hand-off.\n const forecastStart = showForecastRegion ? forecastX[0] : undefined;\n const lastX = data[data.length - 1]?.[xKey];\n\n const renderForecastTick = createForecastTick(\n new Set(forecastX),\n `var(--color-${plotted[0]?.actualKey})`,\n xTickFormatter\n );\n\n const referenceLines = referenceLine\n ? Array.isArray(referenceLine)\n ? referenceLine\n : [referenceLine]\n : [];\n\n // Everything from here to the `return` is lifted out of the returned tree\n // only to keep it readable as a flat list of chart children. Nothing in\n // recharts forces the `render*` helpers to be plain functions: axes and\n // series register themselves with the chart's store, and `<Cell>` is the\n // only child still looked up by element type — a component wrapper renders\n // fine (see AreaChart's `AreaFillGradients`). They stay functions because\n // they are declared inside the render body, where a component would get a\n // fresh element type on every render and remount its subtree.\n\n const renderAxes = () => (\n <>\n <XAxis\n dataKey={xKey}\n type=\"category\"\n hide={!showXAxis}\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n tickFormatter={xTickFormatter}\n tick={styleForecastTicks ? renderForecastTick : undefined}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={resolveRotatedTickAnchor(xAxisAngle)}\n height={xAxisHeight}\n label={xAxisTitle}\n />\n <YAxis\n type=\"number\"\n hide={!showYAxis}\n tickLine={false}\n axisLine={false}\n unit={yUnit}\n tickFormatter={yTickFormatter}\n tickCount={yAxisTickCount}\n domain={yDomain}\n width={yAxisLabel ? 72 : undefined}\n label={yAxisTitle}\n />\n </>\n );\n\n // Set the forecast region off from the actuals (behind everything).\n const renderForecastRegion = () => (\n <>\n {forecastStart != null && lastX != null && (\n <ReferenceArea\n x1={forecastStart}\n x2={lastX}\n fill=\"var(--ui-background-surface-secondary)\"\n fillOpacity={0.5}\n ifOverflow=\"extendDomain\"\n />\n )}\n {forecastStart != null && (\n <ReferenceLine\n x={forecastStart}\n stroke=\"var(--ui-border-on-surface-border)\"\n strokeDasharray=\"4 4\"\n />\n )}\n </>\n );\n\n const renderThreshold = (\n threshold: ConfidenceConeReferenceLine,\n index: number\n ) => (\n <ReferenceLine\n key={`${threshold.label ?? 'threshold'}-${index}`}\n y={threshold.value}\n stroke=\"var(--ui-text-on-surface-secondary)\"\n strokeDasharray=\"4 4\"\n // extendDomain so a threshold beyond the data max stays visible.\n ifOverflow=\"extendDomain\"\n label={\n threshold.label\n ? {\n value: threshold.label,\n position: 'insideTopRight',\n fill: 'var(--ui-text-on-surface-secondary)',\n fontSize: CHART_LABEL_FONT_SIZE,\n }\n : undefined\n }\n />\n );\n\n const renderTooltip = () =>\n customTooltip ? (\n // Strips the synthetic band before the caller's tooltip sees it — the\n // `__cone` series feeds the Area, not the tooltip.\n <ChartTooltip content={customTooltip} />\n ) : (\n <ChartTooltip\n content={(tp) => (\n <ChartTooltipContent\n active={tp.active}\n label={tp.label}\n // The synthetic band feeds the Area, not the tooltip.\n payload={\n dropConeBand(tp.payload) as ChartTooltipContentProps['payload']\n }\n />\n )}\n />\n );\n\n const renderLegend = () => (\n <ChartLegend\n content={(lp) => (\n <ChartLegendContent\n verticalAlign={lp.verticalAlign}\n payload={\n keepMetricSeries(\n lp.payload,\n plotted.map((s) => s.actualKey)\n ) as ChartLegendContentProps['payload']\n }\n />\n )}\n />\n );\n\n // One color per metric — actual and forecast differ by line style, not hue\n // — so a cone reuses its series' actual color.\n const renderConeBand = ({\n actualKey: aKey,\n lowerKey: lKey,\n upperKey: uKey,\n }: ConfidenceConeSeries) =>\n lKey && uKey ? (\n <Area\n key={bandKeyFor(aKey)}\n // The band paints in the same hue, at the same opacity, as the\n // actual series' own area, so nothing on the rendered path tells\n // the two apart. recharts forwards `data-*` onto the path it\n // draws; the tests select the band through this.\n data-slot=\"confidence-cone-band\"\n dataKey={bandKeyFor(aKey)}\n type=\"monotone\"\n stroke=\"none\"\n fill={`var(--color-${aKey})`}\n fillOpacity={0.15}\n connectNulls={false}\n dot={false}\n activeDot={false}\n {...animation}\n legendType=\"none\"\n tooltipType=\"none\"\n />\n ) : null;\n\n const renderActualMark = ({ actualKey: aKey }: ConfidenceConeSeries) => {\n // An area and a line take the same props here; only the region under the\n // curve (and the mark recharts draws) differ. A `Line` gets no fill at\n // all — `fillOpacity: 0` would also erase its dots.\n const ActualMark = actualType === 'line' ? Line : Area;\n const areaFill =\n actualType === 'line'\n ? undefined\n : { fill: `var(--color-${aKey})`, fillOpacity: 0.15 };\n // Observed points read as measured: LineChart's dot geometry (r 3, 2px\n // ring) filled with the metric hue. The ring is that same hue, so the\n // mark is solid — and wide enough against the 2px line not to read as a\n // mere thickening of it. `fillOpacity: 1` is load-bearing: recharts\n // merges the parent mark's own presentation props into every dot it\n // draws, so an `<Area>`'s 0.15 would otherwise wash the dot out to a halo.\n const dot = showDots\n ? {\n r: 3,\n fill: `var(--color-${aKey})`,\n fillOpacity: 1,\n stroke: `var(--color-${aKey})`,\n strokeWidth: 2,\n }\n : false;\n return (\n <ActualMark\n key={aKey}\n dataKey={aKey}\n type=\"monotone\"\n stroke={`var(--color-${aKey})`}\n strokeWidth={strokeWidth}\n {...areaFill}\n dot={dot}\n activeDot={showDots ? { r: 5 } : false}\n connectNulls\n {...animation}\n // The legend names the metric once, so it carries the swatch that\n // stands for the whole series rather than the actual line's style.\n legendType=\"rect\"\n />\n );\n };\n\n const renderForecastLine = ({\n actualKey: aKey,\n forecastKey: fKey,\n }: ConfidenceConeSeries) => {\n // Projected points read as predicted: the same LineChart dot, inverted —\n // the metric's hue as the ring, the surface color as the fill, so the\n // dashed line doesn't show through the middle. (LineChart leaves the fill\n // to recharts, whose `Line` defaults it to `#fff`; the token is that same\n // white in the light theme and also holds up in the dark one.)\n // `strokeDasharray: 'none'` is load-bearing: recharts merges the parent\n // mark's presentation props into every dot, so this line's `5 5` would\n // otherwise break each dot's ring into two arcs.\n const dot = showDots\n ? {\n r: 3,\n fill: 'var(--ui-background-surface-primary)',\n stroke: `var(--color-${aKey})`,\n strokeWidth: 2,\n strokeDasharray: 'none',\n }\n : false;\n return (\n <Line\n key={fKey}\n dataKey={fKey}\n type=\"monotone\"\n stroke={`var(--color-${aKey})`}\n strokeWidth={strokeWidth}\n strokeDasharray=\"5 5\"\n dot={dot}\n // Paired with `dot` the way every other chart does it — left unset,\n // the projection would keep recharts' default active dot while the\n // actuals had none (and a different radius when on).\n activeDot={showDots ? { r: 5 } : false}\n connectNulls\n {...animation}\n />\n );\n };\n\n return (\n <div ref={ref} className={cn(className)} {...props}>\n <ChartContainer\n config={seriesConfig}\n className=\"size-full [&_.recharts-label]:fill-foreground\"\n >\n <ComposedChart data={chartData as readonly unknown[]}>\n {showGrid && (\n <CartesianGrid\n horizontal={gridHorizontal ?? true}\n vertical={gridVertical ?? false}\n strokeDasharray={gridDashed ? '3 3' : undefined}\n />\n )}\n {renderAxes()}\n {renderForecastRegion()}\n {referenceLines.map(renderThreshold)}\n {showTooltip && renderTooltip()}\n {showLegend && renderLegend()}\n {/* Every cone renders before any line, so the lines draw on top of\n all of them. */}\n {plotted.map(renderConeBand)}\n {plotted.map(renderActualMark)}\n {plotted.map(renderForecastLine)}\n </ComposedChart>\n </ChartContainer>\n </div>\n );\n }\n);\nConfidenceCone.displayName = 'ConfidenceCone';\n\nexport { ConfidenceCone };\n"],"names":["BAND_PREFIX","bandKeyFor","actualKey","dropConeBand","payload","item","keepMetricSeries","actualKeys","createConeTooltip","tooltipContent","props","merged","React","forecastPeriodX","data","series","xKey","row","forecastKey","createForecastTick","forecastX","color","tickFormatter","index","tickProps","value","jsx","Text","ConfidenceCone","className","config","lowerKey","upperKey","xAxisLabel","yAxisLabel","yUnit","actualType","strokeWidth","showDots","styleForecastTicks","referenceLine","showForecastRegion","showGrid","showTooltip","showLegend","showXAxis","showYAxis","xTickFormatter","yTickFormatter","xAxisAngle","xAxisInterval","yAxisTickCount","yAxisDomain","gridDashed","gridHorizontal","gridVertical","animate","animationDuration","animationBegin","animationEasing","ref","plotted","animation","resolveAnimation","customTooltip","xAxisTitle","resolveXAxisTitle","yAxisTitle","resolveYAxisTitle","yDomain","resolveAxisDomain","seriesConfig","next","aKey","fKey","actual","forecast","xAxisHeight","resolveXAxisHeight","chartData","lKey","uKey","lower","upper","forecastStart","lastX","_a","renderForecastTick","_b","referenceLines","renderAxes","jsxs","Fragment","XAxis","resolveRotatedTickAnchor","YAxis","renderForecastRegion","ReferenceArea","ReferenceLine","renderThreshold","threshold","CHART_LABEL_FONT_SIZE","renderTooltip","ChartTooltip","tp","ChartTooltipContent","renderLegend","ChartLegend","lp","ChartLegendContent","s","renderConeBand","Area","renderActualMark","ActualMark","Line","areaFill","dot","renderForecastLine","cn","ChartContainer","ComposedChart","CartesianGrid"],"mappings":"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"}
1
+ {"version":3,"file":"confidence-cone.js","sources":["../../../../src/components/ui/confidence-cone/confidence-cone.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n Area,\n CartesianGrid,\n ComposedChart,\n Line,\n ReferenceArea,\n ReferenceLine,\n Text,\n XAxis,\n YAxis,\n} from 'recharts';\n\nimport { cn } from '@/lib/utils';\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n resolveAxisDomain,\n resolveAnimation,\n resolveRotatedTickAnchor,\n resolveXAxisHeight,\n resolveXAxisTitle,\n resolveYAxisTitle,\n CHART_LABEL_FONT_SIZE,\n type ChartConfig,\n type ChartPalette,\n type ChartLegendContentProps,\n type ChartTooltipContentProps,\n type CartesianChartProps,\n type ChartAnimationProps,\n} from '../chart';\n\n// A forecast confidence-cone: a solid line over the known/actual period, a\n// dashed line over the forecast period, and a shaded band (the \"cone\") between\n// a lower and upper bound that typically widens with the horizon — visualizing\n// growing uncertainty. Built on the shared Chart primitives; no new tokens\n// (series colors are caller-supplied via `config`). The whole metric renders in\n// one hue — actual and forecast differ by line style, not color — so the cone\n// band and the forecast line both reuse the actual series' color.\n\n// Each series' band is a synthetic `[lower, upper]` range field per row that a\n// recharts <Area> shades; kept out of the tooltip/legend (see the filters\n// below). One band per series, so the key carries the series' actual key — the\n// whole `__cone` prefix is reserved.\nconst BAND_PREFIX = '__cone';\nconst bandKeyFor = (actualKey: string) => `${BAND_PREFIX}:${actualKey}`;\n\n/**\n * Drop every synthetic cone-band range series from a recharts tooltip/legend\n * payload, keeping the real actual/forecast series (and their order). Applied to\n * both the default tooltip and any caller-supplied `tooltipContent`, so no band\n * surfaces regardless of which path renders or how many series are plotted.\n */\nexport function dropConeBand<T extends { dataKey?: unknown }>(\n payload: readonly T[] | undefined\n): T[] | undefined {\n return payload?.filter(\n (item) =>\n !(\n typeof item.dataKey === 'string' && item.dataKey.startsWith(BAND_PREFIX)\n )\n );\n}\n\n/**\n * Reduce a legend payload to the metrics the chart plots — one entry per series.\n * A series' actual, forecast and cone are three recharts series painting a\n * single metric in a single hue, so the legend names each metric once, with its\n * actual series' swatch, instead of listing line styles as separate series.\n */\nexport function keepMetricSeries<T extends { dataKey?: unknown }>(\n payload: readonly T[] | undefined,\n actualKeys: readonly string[]\n): T[] | undefined {\n return payload?.filter(\n (item) =>\n typeof item.dataKey === 'string' && actualKeys.includes(item.dataKey)\n );\n}\n\n/**\n * Wrap a caller-supplied `tooltipContent` so the synthetic cone band is stripped\n * from the payload before it renders, while preserving recharts' own mount\n * semantics — a function is mounted via `createElement` (its own component\n * identity + hook state), an element via `cloneElement`. This mirrors what the\n * pass-through charts get by handing `content` straight to recharts, so a\n * function-form tooltip keeps its state across re-renders here too. The returned\n * component is a stable content type (memoize it on `tooltipContent`).\n */\ntype TooltipContentType = NonNullable<\n React.ComponentProps<typeof ChartTooltip>['content']\n>;\ntype TooltipContentFn = Extract<\n TooltipContentType,\n (...args: never[]) => unknown\n>;\ntype TooltipRenderProps = Parameters<TooltipContentFn>[0];\n\nexport function createConeTooltip(tooltipContent: TooltipContentType) {\n return function ConeTooltip(props: TooltipRenderProps) {\n const merged = {\n ...props,\n payload: dropConeBand(props.payload),\n } as TooltipRenderProps;\n return typeof tooltipContent === 'function'\n ? React.createElement(\n tooltipContent as React.FunctionComponent<TooltipRenderProps>,\n merged\n )\n : React.cloneElement(tooltipContent, merged);\n };\n}\n\n/**\n * One plotted metric: its actual / forecast columns and, optionally, the two\n * bound columns that shade its cone. Omit `lowerKey`/`upperKey` for a band-less\n * metric — a solid line handing off to a bare dashed projection.\n */\nexport interface ConfidenceConeSeries {\n /** Field for the known/actual values — drawn as a solid line with a filled area. */\n actualKey: string;\n /** Field for the projected values — drawn as a dashed line. */\n forecastKey: string;\n /** Field for the cone's lower bound. Omit (with `upperKey`) for no cone. */\n lowerKey?: string;\n /** Field for the cone's upper bound. Omit (with `lowerKey`) for no cone. */\n upperKey?: string;\n}\n\n/**\n * The x values of the projected period — every row carrying a forecast value for\n * at least one series, in data order. The first is the hand-off point (where the\n * shaded region and divider start); the whole set drives the forecast tick\n * styling, matched by value so tick `interval` can't skew it the way a tick\n * index would. Exported for unit tests; not part of the package's public API.\n */\nexport function forecastPeriodX(\n data: ReadonlyArray<Record<string, string | number | null | undefined>>,\n series: readonly ConfidenceConeSeries[],\n xKey: string\n): Array<string | number | null | undefined> {\n return data\n .filter((row) =>\n series.some(({ forecastKey }) => typeof row[forecastKey] === 'number')\n )\n .map((row) => row[xKey]);\n}\n\n/**\n * Build the X-axis tick renderer that sets the projected columns apart: italic,\n * in the metric's hue. Styled inline rather than through the `fill` attribute\n * recharts hands every tick, so the accent survives the class-based tick color\n * a chart theme may apply. A custom tick owns its own text, so the caller's\n * `xTickFormatter` is applied here — recharts only applies it to default ticks.\n * Exported for unit tests; not part of the package's public API.\n */\nexport function createForecastTick(\n forecastX: ReadonlySet<string | number | null | undefined>,\n color: string,\n tickFormatter?: CartesianChartProps['xTickFormatter']\n) {\n return function ForecastTick({\n payload,\n index,\n ...tickProps\n }: {\n payload?: { value?: string | number };\n index?: number;\n }) {\n const value = payload?.value;\n return (\n <Text\n {...tickProps}\n style={\n value != null && forecastX.has(value)\n ? { fontStyle: 'italic', fill: color }\n : undefined\n }\n >\n {tickFormatter && value != null ? tickFormatter(value, index) : value}\n </Text>\n );\n };\n}\n\n/** A dashed horizontal threshold on the value axis. */\nexport interface ConfidenceConeReferenceLine {\n /** Position on the value (Y) axis. */\n value: number;\n /** Optional caption rendered at the line's right end. */\n label?: string;\n}\n\n/**\n * Every prop except the one-form-or-the-other requirement `ConfidenceConeProps`\n * layers on below. Exported so the stories can type their `Meta` on a single\n * object shape — Storybook can't split a union's required args between `meta.args`\n * and a story's. Not re-exported from `index.ts`; not part of the public API.\n */\nexport interface ConfidenceConeBaseProps\n extends\n Omit<React.ComponentProps<'div'>, 'children'>,\n CartesianChartProps,\n ChartAnimationProps {\n /**\n * The dataviz palette this chart's series are painted from. Series that\n * state no `color` of their own take a stop of it. See `ChartPalette`.\n */\n palette?: ChartPalette;\n /**\n * Row-per-point data — the shared x dimension plus each series' actual /\n * forecast / bound fields. Rows are naturally sparse (a point has either an\n * actual or a forecast + bounds), so missing fields are allowed. Avoid fields\n * starting with `__cone` — that prefix is reserved for the internal\n * prediction-band series.\n */\n data: ReadonlyArray<Record<string, string | number | null | undefined>>;\n /**\n * Per-series map of `label` / `icon` / `tone` for the actual + forecast lines\n * (imported from the shared `Chart` primitives). Series take their colour from\n * the container's `palette`; each entry maps a key to a `label` and an optional\n * `tone`. Each metric renders in one hue: its cone band and forecast line both\n * reuse its actual series' color — actual and forecast differ by line style,\n * not hue.\n */\n config: ChartConfig;\n /** Category / time axis key (the shared dimension across rows). */\n xKey: string;\n /**\n * Plot several metrics against one shared axis — each with its own actual /\n * forecast / bound fields and its own hue (from `config[actualKey]`). Takes\n * precedence over the single-series `actualKey`/`forecastKey`/`lowerKey`/\n * `upperKey` shorthand below; pass one form or the other, not both. One of the\n * two forms is required.\n */\n series?: readonly ConfidenceConeSeries[];\n /**\n * Single-series shorthand — field for the known/actual values, drawn as a\n * solid line with a filled area. Required (with `forecastKey`) unless `series`\n * is set, which supersedes it.\n */\n actualKey?: string;\n /**\n * Single-series shorthand — field for the projected values, drawn as a dashed\n * line. Required (with `actualKey`) unless `series` is set, which supersedes\n * it.\n */\n forecastKey?: string;\n /** Field for the cone's lower bound. Omit (with `upperKey`) for no cone. */\n lowerKey?: string;\n /** Field for the cone's upper bound. Omit (with `lowerKey`) for no cone. */\n upperKey?: string;\n /**\n * How the known/actual period is drawn: a filled `area` under the line (the\n * default), or a bare `line` — for a chart where the cone is the only shaded\n * region, or where several metrics' fills would muddy each other.\n */\n actualType?: 'area' | 'line';\n /** Stroke width of the actual + forecast lines. */\n strokeWidth?: number;\n /**\n * Mark each data point: a filled dot on the observed values, a hollow one on\n * the projection — so a point reads as measured or predicted at a glance.\n */\n showDots?: boolean;\n /**\n * Italicize the X-axis ticks over the forecast period and paint them in the\n * first series' hue, so the projected columns read as projected even when the\n * shaded region is off.\n */\n styleForecastTicks?: boolean;\n /**\n * One or more dashed horizontal thresholds on the value axis — e.g. a target\n * or a capacity limit. Pass a single object or an array to draw several.\n */\n referenceLine?: ConfidenceConeReferenceLine | ConfidenceConeReferenceLine[];\n /**\n * Set off the forecast period from the actuals with a dashed divider at the\n * hand-off point (the first row with a forecast value) and a subtle shaded\n * band over the forecast region.\n */\n showForecastRegion?: boolean;\n showLegend?: boolean;\n}\n\n/**\n * Which columns to plot has to be spelled out one way or the other: the `series`\n * array, or the flat `actualKey` + `forecastKey` shorthand. Expressed as a union\n * so a chart with neither is a compile error rather than a silent plot of axes\n * and nothing else. Both forms together stay legal — `series` wins (see\n * `plotted`), which is what the multi-series stories rely on to clear the args\n * table.\n */\nexport type ConfidenceConeProps = ConfidenceConeBaseProps &\n (\n | { series: readonly ConfidenceConeSeries[] }\n | { actualKey: string; forecastKey: string }\n );\n\nconst ConfidenceCone = React.forwardRef<HTMLDivElement, ConfidenceConeProps>(\n (\n {\n className,\n config,\n palette,\n data,\n xKey,\n series,\n actualKey,\n forecastKey,\n lowerKey,\n upperKey,\n xAxisLabel,\n yAxisLabel,\n yUnit,\n actualType = 'area',\n strokeWidth = 2,\n showDots = false,\n styleForecastTicks = false,\n referenceLine,\n showForecastRegion = true,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n showXAxis = true,\n showYAxis = true,\n xTickFormatter,\n yTickFormatter,\n xAxisAngle,\n xAxisInterval,\n yAxisTickCount,\n yAxisDomain,\n gridDashed,\n gridHorizontal,\n gridVertical,\n tooltipContent,\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n ...props\n },\n ref\n ) => {\n // The flat *Key props are the single-series shorthand for `series`.\n const plotted = React.useMemo<readonly ConfidenceConeSeries[]>(() => {\n if (series?.length) return series;\n if (!actualKey || !forecastKey) return [];\n return [{ actualKey, forecastKey, lowerKey, upperKey }];\n }, [series, actualKey, forecastKey, lowerKey, upperKey]);\n\n const animation = resolveAnimation({\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n });\n // Memoized so recharts sees a stable content type across renders — a fresh\n // wrapper each render would remount the caller's tooltip and reset its state.\n const customTooltip = React.useMemo(\n () => (tooltipContent ? createConeTooltip(tooltipContent) : undefined),\n [tooltipContent]\n );\n\n const xAxisTitle = resolveXAxisTitle(xAxisLabel);\n const yAxisTitle = resolveYAxisTitle(yAxisLabel);\n\n const yDomain = resolveAxisDomain(yAxisDomain);\n\n // One hue per metric. Each cone and forecast line already paints with its own\n // series' actual color; re-pointing that series' forecast key's `--color-*`\n // at it too means nothing downstream — a custom tooltip, a caller's\n // `var(--color-<forecastKey>)` — can reintroduce a second color.\n const seriesConfig = React.useMemo(() => {\n let next: ChartConfig | undefined;\n for (const { actualKey: aKey, forecastKey: fKey } of plotted) {\n const actual = config[aKey];\n const forecast = config[fKey];\n if (!actual || !forecast) continue;\n next ??= { ...config };\n next[fKey] = {\n label: forecast.label,\n icon: forecast.icon,\n tone: { sameAs: aKey },\n };\n }\n return next ?? config;\n }, [config, plotted]);\n\n const xAxisHeight = resolveXAxisHeight(xAxisLabel, xAxisAngle);\n\n // Augment each row with one `[lower, upper]` band tuple per coned series for\n // its Area to shade. Rows missing a numeric bound are left un-coned (the\n // band breaks there); a series without bounds gets no band at all.\n const chartData = data.map((row) => {\n const next: Record<string, unknown> = { ...row };\n for (const {\n actualKey: aKey,\n lowerKey: lKey,\n upperKey: uKey,\n } of plotted) {\n if (!lKey || !uKey) continue;\n const lower = row[lKey];\n const upper = row[uKey];\n next[bandKeyFor(aKey)] =\n typeof lower === 'number' && typeof upper === 'number'\n ? [lower, upper]\n : undefined;\n }\n return next;\n });\n\n const forecastX = forecastPeriodX(data, plotted, xKey);\n // Set the projected period off from the actuals with a shaded band + a\n // divider at the hand-off.\n const forecastStart = showForecastRegion ? forecastX[0] : undefined;\n const lastX = data[data.length - 1]?.[xKey];\n\n const renderForecastTick = createForecastTick(\n new Set(forecastX),\n `var(--color-${plotted[0]?.actualKey})`,\n xTickFormatter\n );\n\n const referenceLines = referenceLine\n ? Array.isArray(referenceLine)\n ? referenceLine\n : [referenceLine]\n : [];\n\n // Everything from here to the `return` is lifted out of the returned tree\n // only to keep it readable as a flat list of chart children. Nothing in\n // recharts forces the `render*` helpers to be plain functions: axes and\n // series register themselves with the chart's store, and `<Cell>` is the\n // only child still looked up by element type — a component wrapper renders\n // fine (see AreaChart's `AreaFillGradients`). They stay functions because\n // they are declared inside the render body, where a component would get a\n // fresh element type on every render and remount its subtree.\n\n const renderAxes = () => (\n <>\n <XAxis\n dataKey={xKey}\n type=\"category\"\n hide={!showXAxis}\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n tickFormatter={xTickFormatter}\n tick={styleForecastTicks ? renderForecastTick : undefined}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={resolveRotatedTickAnchor(xAxisAngle)}\n height={xAxisHeight}\n label={xAxisTitle}\n />\n <YAxis\n type=\"number\"\n hide={!showYAxis}\n tickLine={false}\n axisLine={false}\n unit={yUnit}\n tickFormatter={yTickFormatter}\n tickCount={yAxisTickCount}\n domain={yDomain}\n width={yAxisLabel ? 72 : undefined}\n label={yAxisTitle}\n />\n </>\n );\n\n // Set the forecast region off from the actuals (behind everything).\n const renderForecastRegion = () => (\n <>\n {forecastStart != null && lastX != null && (\n <ReferenceArea\n x1={forecastStart}\n x2={lastX}\n fill=\"var(--ui-background-surface-secondary)\"\n fillOpacity={0.5}\n ifOverflow=\"extendDomain\"\n />\n )}\n {forecastStart != null && (\n <ReferenceLine\n x={forecastStart}\n stroke=\"var(--ui-border-on-surface-border)\"\n strokeDasharray=\"4 4\"\n />\n )}\n </>\n );\n\n const renderThreshold = (\n threshold: ConfidenceConeReferenceLine,\n index: number\n ) => (\n <ReferenceLine\n key={`${threshold.label ?? 'threshold'}-${index}`}\n y={threshold.value}\n stroke=\"var(--ui-text-on-surface-secondary)\"\n strokeDasharray=\"4 4\"\n // extendDomain so a threshold beyond the data max stays visible.\n ifOverflow=\"extendDomain\"\n label={\n threshold.label\n ? {\n value: threshold.label,\n position: 'insideTopRight',\n fill: 'var(--ui-text-on-surface-secondary)',\n fontSize: CHART_LABEL_FONT_SIZE,\n }\n : undefined\n }\n />\n );\n\n const renderTooltip = () =>\n customTooltip ? (\n // Strips the synthetic band before the caller's tooltip sees it — the\n // `__cone` series feeds the Area, not the tooltip.\n <ChartTooltip content={customTooltip} />\n ) : (\n <ChartTooltip\n content={(tp) => (\n <ChartTooltipContent\n active={tp.active}\n label={tp.label}\n // The synthetic band feeds the Area, not the tooltip.\n payload={\n dropConeBand(tp.payload) as ChartTooltipContentProps['payload']\n }\n />\n )}\n />\n );\n\n const renderLegend = () => (\n <ChartLegend\n content={(lp) => (\n <ChartLegendContent\n verticalAlign={lp.verticalAlign}\n payload={\n keepMetricSeries(\n lp.payload,\n plotted.map((s) => s.actualKey)\n ) as ChartLegendContentProps['payload']\n }\n />\n )}\n />\n );\n\n // One color per metric — actual and forecast differ by line style, not hue\n // — so a cone reuses its series' actual color.\n const renderConeBand = ({\n actualKey: aKey,\n lowerKey: lKey,\n upperKey: uKey,\n }: ConfidenceConeSeries) =>\n lKey && uKey ? (\n <Area\n key={bandKeyFor(aKey)}\n // The band paints in the same hue, at the same opacity, as the\n // actual series' own area, so nothing on the rendered path tells\n // the two apart. recharts forwards `data-*` onto the path it\n // draws; the tests select the band through this.\n data-slot=\"confidence-cone-band\"\n dataKey={bandKeyFor(aKey)}\n type=\"monotone\"\n stroke=\"none\"\n fill={`var(--color-${aKey})`}\n fillOpacity={0.15}\n connectNulls={false}\n dot={false}\n activeDot={false}\n {...animation}\n legendType=\"none\"\n tooltipType=\"none\"\n />\n ) : null;\n\n const renderActualMark = ({ actualKey: aKey }: ConfidenceConeSeries) => {\n // An area and a line take the same props here; only the region under the\n // curve (and the mark recharts draws) differ. A `Line` gets no fill at\n // all — `fillOpacity: 0` would also erase its dots.\n const ActualMark = actualType === 'line' ? Line : Area;\n const areaFill =\n actualType === 'line'\n ? undefined\n : { fill: `var(--color-${aKey})`, fillOpacity: 0.15 };\n // Observed points read as measured: LineChart's dot geometry (r 3, 2px\n // ring) filled with the metric hue. The ring is that same hue, so the\n // mark is solid — and wide enough against the 2px line not to read as a\n // mere thickening of it. `fillOpacity: 1` is load-bearing: recharts\n // merges the parent mark's own presentation props into every dot it\n // draws, so an `<Area>`'s 0.15 would otherwise wash the dot out to a halo.\n const dot = showDots\n ? {\n r: 3,\n fill: `var(--color-${aKey})`,\n fillOpacity: 1,\n stroke: `var(--color-${aKey})`,\n strokeWidth: 2,\n }\n : false;\n return (\n <ActualMark\n key={aKey}\n dataKey={aKey}\n type=\"monotone\"\n stroke={`var(--color-${aKey})`}\n strokeWidth={strokeWidth}\n {...areaFill}\n dot={dot}\n activeDot={showDots ? { r: 5 } : false}\n connectNulls\n {...animation}\n // The legend names the metric once, so it carries the swatch that\n // stands for the whole series rather than the actual line's style.\n legendType=\"rect\"\n />\n );\n };\n\n const renderForecastLine = ({\n actualKey: aKey,\n forecastKey: fKey,\n }: ConfidenceConeSeries) => {\n // Projected points read as predicted: the same LineChart dot, inverted —\n // the metric's hue as the ring, the surface color as the fill, so the\n // dashed line doesn't show through the middle. (LineChart leaves the fill\n // to recharts, whose `Line` defaults it to `#fff`; the token is that same\n // white in the light theme and also holds up in the dark one.)\n // `strokeDasharray: 'none'` is load-bearing: recharts merges the parent\n // mark's presentation props into every dot, so this line's `5 5` would\n // otherwise break each dot's ring into two arcs.\n const dot = showDots\n ? {\n r: 3,\n fill: 'var(--ui-background-surface-primary)',\n stroke: `var(--color-${aKey})`,\n strokeWidth: 2,\n strokeDasharray: 'none',\n }\n : false;\n return (\n <Line\n key={fKey}\n dataKey={fKey}\n type=\"monotone\"\n stroke={`var(--color-${aKey})`}\n strokeWidth={strokeWidth}\n strokeDasharray=\"5 5\"\n dot={dot}\n // Paired with `dot` the way every other chart does it — left unset,\n // the projection would keep recharts' default active dot while the\n // actuals had none (and a different radius when on).\n activeDot={showDots ? { r: 5 } : false}\n connectNulls\n {...animation}\n />\n );\n };\n\n return (\n <div ref={ref} className={cn(className)} {...props}>\n <ChartContainer\n config={seriesConfig}\n palette={palette}\n className=\"size-full [&_.recharts-label]:fill-foreground\"\n >\n <ComposedChart data={chartData as readonly unknown[]}>\n {showGrid && (\n <CartesianGrid\n horizontal={gridHorizontal ?? true}\n vertical={gridVertical ?? false}\n strokeDasharray={gridDashed ? '3 3' : undefined}\n />\n )}\n {renderAxes()}\n {renderForecastRegion()}\n {referenceLines.map(renderThreshold)}\n {showTooltip && renderTooltip()}\n {showLegend && renderLegend()}\n {/* Every cone renders before any line, so the lines draw on top of\n all of them. */}\n {plotted.map(renderConeBand)}\n {plotted.map(renderActualMark)}\n {plotted.map(renderForecastLine)}\n </ComposedChart>\n </ChartContainer>\n </div>\n );\n }\n);\nConfidenceCone.displayName = 'ConfidenceCone';\n\nexport { ConfidenceCone };\n"],"names":["BAND_PREFIX","bandKeyFor","actualKey","dropConeBand","payload","item","keepMetricSeries","actualKeys","createConeTooltip","tooltipContent","props","merged","React","forecastPeriodX","data","series","xKey","row","forecastKey","createForecastTick","forecastX","color","tickFormatter","index","tickProps","value","jsx","Text","ConfidenceCone","className","config","palette","lowerKey","upperKey","xAxisLabel","yAxisLabel","yUnit","actualType","strokeWidth","showDots","styleForecastTicks","referenceLine","showForecastRegion","showGrid","showTooltip","showLegend","showXAxis","showYAxis","xTickFormatter","yTickFormatter","xAxisAngle","xAxisInterval","yAxisTickCount","yAxisDomain","gridDashed","gridHorizontal","gridVertical","animate","animationDuration","animationBegin","animationEasing","ref","plotted","animation","resolveAnimation","customTooltip","xAxisTitle","resolveXAxisTitle","yAxisTitle","resolveYAxisTitle","yDomain","resolveAxisDomain","seriesConfig","next","aKey","fKey","actual","forecast","xAxisHeight","resolveXAxisHeight","chartData","lKey","uKey","lower","upper","forecastStart","lastX","_a","renderForecastTick","_b","referenceLines","renderAxes","jsxs","Fragment","XAxis","resolveRotatedTickAnchor","YAxis","renderForecastRegion","ReferenceArea","ReferenceLine","renderThreshold","threshold","CHART_LABEL_FONT_SIZE","renderTooltip","ChartTooltip","tp","ChartTooltipContent","renderLegend","ChartLegend","lp","ChartLegendContent","s","renderConeBand","Area","renderActualMark","ActualMark","Line","areaFill","dot","renderForecastLine","cn","ChartContainer","ComposedChart","CartesianGrid"],"mappings":"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"}
@@ -25,6 +25,8 @@ function de(n) {
25
25
  };
26
26
  }
27
27
  function ue(n, l) {
28
+ if (n.id === "select")
29
+ return 48;
28
30
  if (l || n.columnDef.size !== void 0)
29
31
  return n.getSize();
30
32
  }
@@ -208,7 +210,7 @@ function qo({
208
210
  children: [
209
211
  /* @__PURE__ */ t(yo, { children: /* @__PURE__ */ t(po, { children: i.getHeaderGroups().map((e) => /* @__PURE__ */ t(h, { className: "hover:bg-transparent", children: e.headers.map((o) => {
210
212
  var w;
211
- const r = o.column.getIsPinned(), d = D && o.column.getCanResize(), m = Qe && !o.isPlaceholder && !r, x = !o.isPlaceholder && o.column.getCanSort(), s = [
213
+ const r = o.column.getIsPinned(), d = D && o.column.getCanResize() && o.column.id !== "select", m = Qe && !o.isPlaceholder && !r, x = !o.isPlaceholder && o.column.getCanSort(), s = [
212
214
  x && H.sort,
213
215
  m && H.reorder,
214
216
  d && H.resize
@@ -250,7 +252,7 @@ function qo({
250
252
  // pointer drags across neighboring `<th>`s and would
251
253
  // otherwise tint them via native `:hover`.
252
254
  x && !y && "transition-colors hover:bg-[var(--ui-table-header-cell-color-hover)] active:bg-[var(--ui-table-header-cell-color-active)]",
253
- m && !y && "cursor-(--ui-draggable-cursor) select-none active:cursor-(--ui-draggable-cursor-active)",
255
+ m && !y && "cursor-grab select-none active:cursor-grabbing",
254
256
  m && C === o.column.id && "opacity-50",
255
257
  r && te
256
258
  ),
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.js","sources":["../../../../src/components/ui/data-table/data-table.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type DragEvent,\n Fragment,\n type KeyboardEvent,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n type Cell,\n type Column,\n type ColumnDef,\n type ColumnFiltersState,\n type ColumnOrderState,\n type ColumnSizingState,\n type ExpandedState,\n type Header,\n type OnChangeFn,\n type Row,\n type RowData,\n type RowSelectionState,\n type SortingState,\n type Table as TanstackTable,\n type VisibilityState,\n flexRender,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from '@tanstack/react-table';\n\nimport { EllipsisIcon } from '@acronis-platform/icons-react/stroke-mono';\n\nimport { useIntersectionObserver } from '@/hooks';\nimport { cn } from '@/lib/utils';\nimport { ButtonIcon } from '../button-icon';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from '../dropdown-menu';\nimport {\n Table,\n TableActionsCell,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n TableSettingsCell,\n} from '../table';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '../tooltip';\nimport { isBulkSelectionActive } from './data-table-selection';\nimport { DataTableViewOptions } from './data-table-view-options';\n\n// Ported from `@acronis-platform/shadcn-uikit`'s `data-table`\n// (packages/ui-legacy/src/components/ui/data-table/). A TanStack-react-table v8\n// data grid composed over the ui-react Table primitives — sorting, filtering,\n// column visibility, row selection, pagination, and optional row expansion. The\n// presentational flags (`striped`, `bordered`, `skeleton`, `highlightCurrentRow`)\n// are borrowed from the Vue `AvTable`; behavioral features come from TanStack.\n// Pair with DataTableToolbar / DataTablePagination / DataTableColumnHeader, which\n// take the `table` instance returned to column cells via TanStack context.\n// The grid cells/rows/headers are themed by the Table primitives' `--ui-table-*`\n// tier; DataTable's own chrome reuses that tier too — the wrapper border matches\n// the cell borders (`--ui-table-global-row-border-color`), the empty-state uses\n// the muted table-value color, the current row the active-row color, and stripes\n// the secondary surface.\n//\n// Advanced-grid opt-ins built on native TanStack features:\n// • Column resizing -> `enableColumnResizing` + `columnResizing` state, with a\n// drag handle rendered from `header.getResizeHandler()`.\n// • Sticky columns -> `ColumnDef.meta.pin: 'left' | 'right'` drives TanStack's\n// native column-pinning API (`column.pin()` / `getStart()` / `getAfter()`),\n// surfaced as `position: sticky` cells with an opaque row-token background.\n// • Column reorder -> `enableColumnReordering` + `columnOrder` state, with\n// native HTML5 drag-and-drop on the header cells (the grab/grabbing cursors\n// come from `--ui-draggable-cursor[-active]`, the counterpart of the resize\n// handle's `--ui-resizable-cursor`).\n\n// Extend TanStack's per-column `meta` with the flags DataTable reads. Augmenting\n// the module keeps `ColumnDef.meta.pin` type-safe at the call site.\ndeclare module '@tanstack/react-table' {\n // Type params must match TanStack's `ColumnMeta<TData, TValue>` arity/names for\n // declaration merging, even though this augmentation doesn't reference them.\n // eslint-disable-next-line unused-imports/no-unused-vars\n interface ColumnMeta<TData extends RowData, TValue> {\n /** Pin the column to a table edge (sticky while the grid scrolls horizontally). */\n pin?: 'left' | 'right';\n /**\n * Let the column's header + cells wrap onto multiple lines (drops the fixed\n * row height); mirrors the `Table` primitives' `wrap` prop on TableHead/TableCell.\n */\n wrap?: boolean;\n }\n}\n\n// Sticky offset + stacking for a pinned column, computed from TanStack's own\n// pinning geometry rather than hand-rolled CSS math. A subtle edge shadow (facing\n// the scrollable columns) separates the pinned column from content sliding\n// underneath it — the opaque background that actually hides that content lives\n// in the caller's className (see `headerPinnedBg`/`rowBg` below), not here.\nexport function getPinnedStyle<TData>(\n column: Column<TData, unknown>\n): CSSProperties | undefined {\n const pinned = column.getIsPinned();\n if (!pinned) return undefined;\n return {\n position: 'sticky',\n left: pinned === 'left' ? column.getStart('left') : undefined,\n right: pinned === 'right' ? column.getAfter('right') : undefined,\n zIndex: 1,\n // Derived from the same border token every other table divider uses (not a\n // hardcoded color), so the separator theme-adapts automatically.\n boxShadow:\n pinned === 'left'\n ? '4px 0 4px -4px var(--ui-table-global-row-border-color)'\n : '-4px 0 4px -4px var(--ui-table-global-row-border-color)',\n };\n}\n\n// A column's rendered width tracks TanStack's size model once the consumer has\n// opted in — either explicitly (a `size` set on the `ColumnDef`) or implicitly\n// (column resizing enabled, which needs every column's width to be deterministic\n// for the drag math to work). Without either, columns stay in native `<table>`\n// auto-layout so `size`'s internal default (TanStack falls back to 150) never\n// forces every untouched column to a fixed width.\nexport function getColumnWidth<TData>(\n column: Column<TData, unknown>,\n enableColumnResizing: boolean\n): number | undefined {\n if (enableColumnResizing || column.columnDef.size !== undefined) {\n return column.getSize();\n }\n return undefined;\n}\n\nfunction getHeaderStyle<TData>(\n header: Header<TData, unknown>,\n enableColumnResizing: boolean\n): CSSProperties | undefined {\n const pin = getPinnedStyle(header.column);\n const width = getColumnWidth(header.column, enableColumnResizing);\n if (!pin && width === undefined) return undefined;\n return { ...pin, width };\n}\n\nexport function getCellStyle<TData>(\n cell: Cell<TData, unknown>,\n enableColumnResizing: boolean\n): CSSProperties | undefined {\n const pin = getPinnedStyle(cell.column);\n const width = getColumnWidth(cell.column, enableColumnResizing);\n if (!pin && width === undefined) return undefined;\n return { ...pin, width };\n}\n\n// Matches TanStack's own `defaultColumnSizing` fallback bounds — the same\n// range `column.getSize()` already clamps to internally when a column\n// doesn't set its own `minSize`/`maxSize`.\nconst DEFAULT_MIN_COLUMN_SIZE = 20;\nconst DEFAULT_MAX_COLUMN_SIZE = Number.MAX_SAFE_INTEGER;\n\n/**\n * Computes the next column width for an Arrow-key resize step (Shift = larger\n * step), clamped to `[min, max]` regardless of which bound `currentSize`\n * started outside of. Returns `undefined` for any other key, so the caller\n * knows not to `preventDefault()`/resize.\n */\nexport function getResizeKeyboardStep(\n key: string,\n currentSize: number,\n { shiftKey, min, max }: { shiftKey: boolean; min: number; max: number }\n): number | undefined {\n const step = shiftKey ? 50 : 10;\n if (key === 'ArrowLeft')\n return Math.min(max, Math.max(min, currentSize - step));\n if (key === 'ArrowRight')\n return Math.max(min, Math.min(max, currentSize + step));\n return undefined;\n}\n\n/**\n * Moves `from` to `to`'s position in a `columnOrder` array (the drop semantics\n * of the header drag gesture: the dragged column lands where the drop target\n * sits, pushing it aside). Returns `order` unchanged when either id is absent,\n * so a drop on a column that isn't part of the order (e.g. one added while the\n * gesture was in flight) is a no-op rather than a reshuffle.\n */\nexport function reorderColumn(\n order: string[],\n from: string,\n to: string\n): string[] {\n const fromIndex = order.indexOf(from);\n const toIndex = order.indexOf(to);\n if (fromIndex === -1 || toIndex === -1 || fromIndex === toIndex) return order;\n const next = [...order];\n next.splice(toIndex, 0, next.splice(fromIndex, 1)[0]);\n return next;\n}\n\n/** One line of the header hover tooltip: a capability and the gesture for it. */\nexport interface DataTableHeaderHint {\n /** The capability, rendered in bold (e.g. `Sort column`). */\n label: string;\n /** The gesture that triggers it (e.g. `Click`). */\n action: string;\n}\n\n/** Copy of the header hover tooltip, one entry per column capability. */\nexport interface DataTableHeaderHints {\n sort: DataTableHeaderHint;\n reorder: DataTableHeaderHint;\n resize: DataTableHeaderHint;\n}\n\nconst DEFAULT_HEADER_HINTS: DataTableHeaderHints = {\n sort: { label: 'Sort column', action: 'Click' },\n reorder: { label: 'Reorder column', action: 'Drag' },\n resize: { label: 'Resize column', action: 'Drag border' },\n};\n\n// `columns`/`data` build DataTable's own table instance; `table` renders an\n// externally-built one instead. At least one of the two forms is required —\n// omitting both would otherwise silently render an empty table — but `table`\n// may still be passed alongside `columns`/`data` (e.g. to also drive a\n// composed toolbar/pagination from the same instance DataTable renders).\ntype DataTableDataSourceProps<TData, TValue> =\n | {\n columns: ColumnDef<TData, TValue>[];\n data: TData[];\n /**\n * Also drive an externally-built TanStack `table` instance (e.g. a\n * composed toolbar/pagination) from the same state as this DataTable.\n */\n table?: TanstackTable<TData>;\n }\n | {\n columns?: ColumnDef<TData, TValue>[];\n data?: TData[];\n /**\n * Render from an externally-built TanStack `table` instance instead of\n * DataTable's own — DataTable then owns no state and renders the caller's\n * instance as-is (sorting, filtering, pagination, row models, etc. are all\n * configured on that instance). Makes `columns`/`data` unnecessary (they're\n * only used to build DataTable's own instance) and the following props\n * no-ops (configure the equivalent directly on the external instance\n * instead): `columnVisibility`, `onColumnVisibilityChange`,\n * `onColumnSizingChange`, `enableColumnResizing`,\n * `enableColumnReordering`, `columnOrder`, `onColumnOrderChange`,\n * `getRowCanExpand`,\n * `manualSorting`, `sorting`, `onSortingChange`, `paginationMode`,\n * `onLoadMore`, `loadMoreRootMargin`, `hasNextPage`, `isLoadingMore`.\n * `meta.pin`-driven column pinning is also skipped — pin/unpin the\n * caller's own instance via TanStack's `column.pin()` directly.\n */\n table: TanstackTable<TData>;\n };\n\ninterface DataTableOwnProps<TData> {\n /** Enables row expansion for rows that return true. Pair with `renderExpandedRow`. */\n getRowCanExpand?: (row: Row<TData>) => boolean;\n /**\n * Renders expanded content for an expanded row. Used together with\n * `getRowCanExpand`.\n */\n renderExpandedRow?: (row: Row<TData>) => ReactNode;\n /** Alternating row backgrounds. */\n striped?: boolean;\n /** Vertical borders between columns (rows already have horizontal borders). */\n bordered?: boolean;\n /** Highlight the row the user last clicked (the \"current\" row). */\n highlightCurrentRow?: boolean;\n /** Render placeholder skeleton rows instead of data (loading state). */\n skeleton?: boolean;\n /** Number of skeleton rows to render when `skeleton` is set. */\n skeletonRows?: number;\n /**\n * Opt in to interactive column resizing. Renders a drag handle at the trailing\n * edge of each resizable header cell (TanStack's native `columnResizing`).\n */\n enableColumnResizing?: boolean;\n /** Passthrough for the `columnSizing` state so a consumer can persist widths. */\n onColumnSizingChange?: OnChangeFn<ColumnSizingState>;\n /**\n * Opt in to column reordering by dragging a header cell onto another one\n * (native HTML5 drag-and-drop driving TanStack's `columnOrder`). Pinned\n * columns are excluded — they're anchored to a table edge by definition.\n * Pointer-only, matching the design: there is no keyboard equivalent yet.\n */\n enableColumnReordering?: boolean;\n /**\n * Controlled column-order state — pass this (with `onColumnOrderChange`) to\n * persist or share the order. Uncontrolled (internal state) when omitted.\n */\n columnOrder?: ColumnOrderState;\n /** Passthrough for the `columnOrder` state; pairs with `columnOrder`. */\n onColumnOrderChange?: OnChangeFn<ColumnOrderState>;\n /**\n * Controlled column-visibility state — pass this (with\n * `onColumnVisibilityChange`) to share one visibility state with an\n * external `useReactTable` instance (e.g. a composed toolbar). Uncontrolled\n * (internal state) when omitted.\n */\n columnVisibility?: VisibilityState;\n /** Passthrough for the `columnVisibility` state; pairs with `columnVisibility`. */\n onColumnVisibilityChange?: OnChangeFn<VisibilityState>;\n /**\n * Controlled row-selection state — pass this (with `onRowSelectionChange`)\n * to share one selection state with an external `useReactTable` instance\n * (e.g. a composed toolbar/bulk-actions bar). Uncontrolled (internal state)\n * when omitted.\n */\n rowSelection?: RowSelectionState;\n /** Passthrough for the `rowSelection` state; pairs with `rowSelection`. */\n onRowSelectionChange?: OnChangeFn<RowSelectionState>;\n /**\n * Opt out of client-side sorting — pass already-sorted `data` and drive\n * sorting via `sorting`/`onSortingChange` (e.g. mapped to a server query by\n * the caller). Mapping sort state to a query and refetching stays the\n * caller's job; DataTable only skips its own comparator.\n */\n manualSorting?: boolean;\n /**\n * Controlled sorting state — pass this (with `onSortingChange`) to drive\n * sorting externally. Uncontrolled (internal state) when omitted.\n */\n sorting?: SortingState;\n /** Passthrough for the `sorting` state; pairs with `sorting`. */\n onSortingChange?: OnChangeFn<SortingState>;\n /**\n * Renders a full row, bypassing DataTable's default per-cell `flexRender`\n * path entirely (no `<TableRow>`/cell-styling/pinning of DataTable's own).\n * Use to swap in a custom, independently memoizable row component. The\n * caller owns the row's markup and equality semantics — reuse the exported\n * `getCellStyle`/`getPinnedStyle`/`getColumnWidth` helpers to match\n * DataTable's default cell styling if desired.\n *\n * Also bypasses DataTable's `renderExpandedRow` handling — a row rendered\n * via `renderRow` never gets an expanded-content row appended, even when\n * `getRowCanExpand` returns true for it. Read `row.getIsExpanded()` and\n * render the expanded content yourself if you need both.\n */\n renderRow?: (row: Row<TData>, rowIndex: number) => ReactNode;\n /**\n * Renders a custom empty state instead of the default \"No results.\" row.\n * Receives `hasFilters` (whether any column filter is currently applied) so\n * the caller can distinguish \"no data at all\" from \"no matches\" — the\n * actual copy/wording/localization stays the caller's job.\n */\n renderEmptyState?: (context: { hasFilters: boolean }) => ReactNode;\n /**\n * `'page'` (default) keeps today's client-paginated behavior. `'infinite'`\n * omits the paginated row model — `data` is assumed to be the full\n * accumulated array the caller appends to on each `onLoadMore` — and\n * renders a sentinel row that calls `onLoadMore` once it scrolls into view.\n * Does not compose with virtualization; for a large accumulated list, use\n * the `VirtualScrolling` recipe over the raw `Table` primitives instead.\n */\n paginationMode?: 'page' | 'infinite';\n /**\n * Called when the infinite-scroll sentinel intersects the viewport.\n * `paginationMode=\"infinite\"` only. The fetch-more call, cursor/offset\n * tracking, dedup, and accumulating `data` stay the caller's job. Requires\n * at least one row already rendered — an empty table with `data={[]}`\n * cannot use the sentinel to drive its very first fetch; seed the first\n * page yourself (e.g. on mount) and use `onLoadMore` for subsequent pages.\n */\n onLoadMore?: () => void;\n /**\n * Expands the sentinel's `IntersectionObserver` root margin (native CSS\n * margin syntax, e.g. `'400px'`) so `onLoadMore` fires before the sentinel\n * is literally visible — the closer the caller's fetch is to finishing by\n * the time the user actually scrolls there, the less often the trailing\n * loading row is seen. `paginationMode=\"infinite\"` only; no-op when `table`\n * is passed. How far this actually prefetches also depends on page size —\n * a large margin with small pages can trigger several `onLoadMore` calls\n * back-to-back as the user scrolls normally, which is expected.\n */\n loadMoreRootMargin?: string;\n /** Whether more rows are available to load. `paginationMode=\"infinite\"` only. */\n hasNextPage?: boolean;\n /**\n * Accessible name of a column's resize handle. Override to localize.\n * `enableColumnResizing` only.\n */\n resizeColumnLabel?: string;\n /**\n * Text of the default empty-state row. Ignored when `renderEmptyState` is\n * given. Override to localize.\n */\n emptyLabel?: string;\n /**\n * Whether a load is in flight — suppresses further `onLoadMore` calls and\n * renders a trailing loading row. `paginationMode=\"infinite\"` only.\n */\n isLoadingMore?: boolean;\n /**\n * Hide the trailing sticky action column — the column-visibility cog in the\n * header and each row's overflow-actions ellipsis. Shown by default. A\n * no-op when an external `table` is passed (build the column into that\n * instance's own `columns` instead).\n */\n hideActionColumn?: boolean;\n /**\n * Renders the content of a row's overflow-actions menu (e.g. `Edit`/\n * `Delete` items), opened from the ellipsis trigger in the trailing action\n * column. Omit to render that row without a trigger — the 48px column is\n * still reserved. Suppressed (like the trigger itself) while a bulk\n * selection is active, per `TableActionsCell`.\n */\n renderRowActions?: (row: Row<TData>) => ReactNode;\n /** Accessible name of a row's overflow-actions trigger. Override to localize. */\n rowActionsLabel?: string;\n /**\n * Accessible name of the action column's column-visibility trigger.\n * Override to localize.\n */\n columnSettingsLabel?: string;\n /**\n * Copy of the tooltip shown while a header cell is hovered/focused — one\n * line per capability that column actually has (sort/reorder/resize).\n * Override (per capability) to localize; a column with no capability shows\n * no tooltip at all.\n */\n headerHints?: Partial<DataTableHeaderHints>;\n}\n\nexport type DataTableProps<TData, TValue = unknown> = DataTableOwnProps<TData> &\n DataTableDataSourceProps<TData, TValue>;\n\nexport function DataTable<TData, TValue = unknown>({\n columns = [],\n data = [],\n table: externalTable,\n getRowCanExpand,\n renderExpandedRow,\n striped = false,\n bordered = false,\n highlightCurrentRow = false,\n skeleton = false,\n skeletonRows = 5,\n enableColumnResizing = false,\n onColumnSizingChange,\n enableColumnReordering = false,\n columnOrder: controlledColumnOrder,\n onColumnOrderChange,\n columnVisibility: controlledColumnVisibility,\n onColumnVisibilityChange,\n rowSelection: controlledRowSelection,\n onRowSelectionChange,\n manualSorting = false,\n sorting: controlledSorting,\n onSortingChange,\n renderRow,\n renderEmptyState,\n paginationMode = 'page',\n onLoadMore,\n loadMoreRootMargin,\n hasNextPage = false,\n resizeColumnLabel = 'Resize column',\n emptyLabel = 'No results.',\n isLoadingMore = false,\n hideActionColumn = false,\n renderRowActions,\n rowActionsLabel = 'Row actions',\n columnSettingsLabel,\n headerHints,\n}: DataTableProps<TData, TValue>) {\n const resolvedHeaderHints: DataTableHeaderHints = {\n ...DEFAULT_HEADER_HINTS,\n ...headerHints,\n };\n const [internalSorting, setInternalSorting] = useState<SortingState>([]);\n const sorting = controlledSorting ?? internalSorting;\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);\n const [internalColumnVisibility, setInternalColumnVisibility] =\n useState<VisibilityState>({});\n const columnVisibility =\n controlledColumnVisibility ?? internalColumnVisibility;\n const [internalRowSelection, setInternalRowSelection] =\n useState<RowSelectionState>({});\n const rowSelection = controlledRowSelection ?? internalRowSelection;\n const [expanded, setExpanded] = useState<ExpandedState>({});\n const [columnSizing, setColumnSizing] = useState<ColumnSizingState>({});\n const [internalColumnOrder, setInternalColumnOrder] =\n useState<ColumnOrderState>([]);\n const columnOrder = controlledColumnOrder ?? internalColumnOrder;\n // The header cell the user is currently dragging, so the source cell can dim\n // while the gesture is in flight.\n const [draggedColumnId, setDraggedColumnId] = useState<string>();\n const [currentRowId, setCurrentRowId] = useState<string>();\n // Roving tabindex over the data rows: exactly one row is a Tab stop at a\n // time (the rest are `tabIndex={-1}`, still focusable programmatically),\n // and Arrow Up/Down move both the DOM focus and which row that is. Clamped\n // against the live row count below rather than reset via an effect, so a\n // filter/page change that shrinks `rows` can't leave it pointing past the\n // end.\n const [focusedRowIndex, setFocusedRowIndex] = useState(0);\n const rowRefs = useRef<Array<HTMLTableRowElement | null>>([]);\n\n const handleColumnSizingChange: OnChangeFn<ColumnSizingState> = (updater) => {\n setColumnSizing(updater);\n onColumnSizingChange?.(updater);\n };\n\n const handleColumnOrderChange: OnChangeFn<ColumnOrderState> = (updater) => {\n if (controlledColumnOrder === undefined) {\n setInternalColumnOrder(updater);\n }\n onColumnOrderChange?.(updater);\n };\n\n const handleColumnVisibilityChange: OnChangeFn<VisibilityState> = (\n updater\n ) => {\n setInternalColumnVisibility(updater);\n onColumnVisibilityChange?.(updater);\n };\n\n const handleSortingChange: OnChangeFn<SortingState> = (updater) => {\n if (controlledSorting === undefined) {\n setInternalSorting(updater);\n }\n onSortingChange?.(updater);\n };\n\n const handleRowSelectionChange: OnChangeFn<RowSelectionState> = (\n updater\n ) => {\n if (controlledRowSelection === undefined) {\n setInternalRowSelection(updater);\n }\n onRowSelectionChange?.(updater);\n };\n\n // The trailing sticky action column (cog + per-row ellipsis) is a no-op\n // with an external `table` — that instance's own `columns` already decide\n // what renders, DataTable doesn't own its state in that mode (see the\n // `table` prop's tsdoc).\n const showActionColumn = !hideActionColumn && !externalTable;\n // A real `ColumnDef` (rather than chrome bolted onto the render loop) so\n // TanStack's own pinning geometry measures and offsets it like any other\n // pinned column — `header`/`cell` are never read (see the header/body\n // render loops below, which special-case this id), only `size`/`meta.pin`.\n const actionColumns = useMemo<ColumnDef<TData, TValue>[]>(\n () =>\n showActionColumn\n ? [\n {\n id: '__actions',\n size: 48,\n enableSorting: false,\n enableHiding: false,\n meta: { pin: 'right' },\n header: () => null,\n cell: () => null,\n },\n ]\n : [],\n [showActionColumn]\n );\n const tableColumns = useMemo(\n () => [...columns, ...actionColumns],\n [columns, actionColumns]\n );\n // The pinned action cell's own hover (its ellipsis/cog trigger) should be\n // the only thing that tints while it's hovered — not the row underneath it\n // (see `hover:bg-transparent` below). Tracked by id (rather than a boolean)\n // because it's set from the action cell of whichever row is currently under\n // the pointer.\n const [actionHoveredRowId, setActionHoveredRowId] = useState<string>();\n\n // Built unconditionally — hooks can't be conditionally called — but only\n // feeds the render path below when no external `table` is passed (see\n // `table` below).\n const internalTable = useReactTable({\n data,\n columns: tableColumns,\n enableColumnResizing,\n columnResizeMode: 'onChange',\n getCoreRowModel: getCoreRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n ...(paginationMode === 'page'\n ? { getPaginationRowModel: getPaginationRowModel() }\n : {}),\n getRowCanExpand,\n onExpandedChange: setExpanded,\n manualSorting,\n onSortingChange: handleSortingChange,\n ...(manualSorting ? {} : { getSortedRowModel: getSortedRowModel() }),\n onColumnFiltersChange: setColumnFilters,\n getFilteredRowModel: getFilteredRowModel(),\n onColumnVisibilityChange: handleColumnVisibilityChange,\n onRowSelectionChange: handleRowSelectionChange,\n onColumnSizingChange: handleColumnSizingChange,\n onColumnOrderChange: handleColumnOrderChange,\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n rowSelection,\n expanded,\n columnSizing,\n columnOrder,\n },\n });\n\n // The caller's instance is the single source of truth when passed — it\n // configures its own row models/state, so DataTable just renders from it.\n const table = externalTable ?? internalTable;\n const isInfiniteScroll = !externalTable && paginationMode === 'infinite';\n // `enableColumnResizing` is documented as a no-op with an external `table`\n // (the caller owns that instance's ColumnSizing state), but ColumnSizing is\n // a built-in TanStack feature present on any instance — reading the raw\n // prop below would still render live resize handles that mutate the\n // caller's own instance. Gate it the same way as `isInfiniteScroll`.\n const resizingEnabled = enableColumnResizing && !externalTable;\n // Same reasoning as `resizingEnabled`: ColumnOrdering is a built-in TanStack\n // feature present on any instance, so reading the raw prop would let the\n // header drag mutate a caller-owned instance DataTable doesn't manage.\n const reorderingEnabled = enableColumnReordering && !externalTable;\n // A resize drag necessarily moves the pointer off the (few-px-wide) resize\n // handle and onto the header cell itself. If that cell is still\n // `draggable`, the browser arms a native HTML5 reorder drag mid-resize —\n // native drag then swallows the mousemove/mouseup TanStack's resize\n // handler relies on, so the cursor flips to the reorder \"grab\" icon and\n // releasing the mouse doesn't cleanly end the resize. Reading this back\n // from TanStack's own resize state (rather than pointer position) keeps\n // every header cell non-draggable for the *entire* gesture, regardless of\n // where the pointer ends up.\n const isAnyColumnResizing = Boolean(\n table.getState().columnSizingInfo.isResizingColumn\n );\n // The resize handle only shows its `ew-resize` cursor while the pointer is\n // directly over its thin 4px hit area — once a drag starts, fast pointer\n // movement leaves that area and the browser shows whatever cursor the\n // element underneath declares (e.g. a sortable header's `cursor-pointer`).\n // This attribute + the `html[data-ui-column-resizing] *` rule in\n // styles/index.css force `ew-resize` everywhere for the duration of the\n // drag — a plain `<body>` inline cursor loses to a descendant's own\n // `cursor` declaration, so it isn't enough on its own.\n useEffect(() => {\n if (!isAnyColumnResizing) return;\n document.documentElement.setAttribute('data-ui-column-resizing', '');\n return () => {\n document.documentElement.removeAttribute('data-ui-column-resizing');\n };\n }, [isAnyColumnResizing]);\n const sentinelRef = useIntersectionObserver<HTMLTableRowElement>({\n onIntersect: () => onLoadMore?.(),\n disabled: !isInfiniteScroll || !hasNextPage || isLoadingMore,\n rootMargin: loadMoreRootMargin,\n });\n\n // Arrow-key resize on the drag handle (see `canResize` below). Ignores any\n // modifier besides Shift so it doesn't hijack browser/OS shortcuts bound to\n // Ctrl/Alt/Cmd+Arrow (e.g. back navigation) while the handle has focus.\n const handleResizeKeyDown = (\n event: KeyboardEvent<HTMLDivElement>,\n header: Header<TData, unknown>\n ) => {\n if (event.ctrlKey || event.altKey || event.metaKey) return;\n const nextSize = getResizeKeyboardStep(event.key, header.column.getSize(), {\n shiftKey: event.shiftKey,\n min: header.column.columnDef.minSize ?? DEFAULT_MIN_COLUMN_SIZE,\n max: header.column.columnDef.maxSize ?? DEFAULT_MAX_COLUMN_SIZE,\n });\n if (nextSize === undefined) return;\n event.preventDefault();\n table.setColumnSizing((old) => ({ ...old, [header.column.id]: nextSize }));\n };\n\n // Native HTML5 drag-and-drop on the header cells. `columnOrder` starts empty\n // (TanStack reads that as \"the declared order\"), so the first drop seeds it\n // from the live leaf columns before moving anything.\n const handleColumnDragStart = (\n event: DragEvent<HTMLTableCellElement>,\n columnId: string\n ) => {\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n // Firefox requires setData() during dragstart to actually initiate a\n // native drag; the value itself is unused (drop reads draggedColumnId).\n event.dataTransfer.setData('text/plain', columnId);\n }\n setDraggedColumnId(columnId);\n };\n\n const handleColumnDragOver = (event: DragEvent<HTMLTableCellElement>) => {\n // Without this the browser rejects the drop and no `onDrop` ever fires.\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';\n };\n\n const handleColumnDrop = (\n event: DragEvent<HTMLTableCellElement>,\n targetColumnId: string\n ) => {\n event.preventDefault();\n if (!draggedColumnId) return;\n const current = table.getState().columnOrder;\n const base = current.length\n ? current\n : table.getAllLeafColumns().map((column) => column.id);\n table.setColumnOrder(reorderColumn(base, draggedColumnId, targetColumnId));\n setDraggedColumnId(undefined);\n };\n\n // Read each column's `meta.pin` and drive TanStack's native pinning state.\n // Always calls `pin()` (rather than only when truthy) so a column whose\n // `meta.pin` is removed dynamically actually un-pins. Skipped for an\n // external `table` — DataTable owns no state in that mode (see the `table`\n // prop's tsdoc), so the caller's own pinning setup is left alone.\n useEffect(() => {\n if (externalTable) return;\n table.getAllLeafColumns().forEach((column) => {\n column.pin(column.columnDef.meta?.pin ?? false);\n });\n }, [table, columns, externalTable]);\n\n const rows = table.getRowModel().rows;\n // Derived from the selection state, so it's the same for every row — compute\n // it once instead of per row inside the render loop below.\n const bulkSelectionActive = isBulkSelectionActive(table);\n const activeRowIndex = rows.length\n ? Math.min(focusedRowIndex, rows.length - 1)\n : 0;\n\n // Mouse/pointer clicks still focus a `tabIndex={-1}` row (browsers allow\n // programmatic/click focus regardless of tabIndex value) — syncing the\n // roving index on focus makes that row the next Tab stop too, matching how\n // users expect the last-interacted row to keep focus.\n const handleRowFocus = (rowIndex: number) => {\n setFocusedRowIndex(rowIndex);\n };\n\n const handleRowKeyDown = (\n event: KeyboardEvent<HTMLTableRowElement>,\n rowIndex: number\n ) => {\n // Keydown bubbles, so arrow keys from an interactive control inside a cell\n // (number spinner, textarea caret, native select) would otherwise be\n // hijacked to move row focus. Only roam when the row itself is focused.\n if (event.target !== event.currentTarget) return;\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;\n const nextIndex =\n event.key === 'ArrowDown'\n ? Math.min(rowIndex + 1, rows.length - 1)\n : Math.max(rowIndex - 1, 0);\n if (nextIndex === rowIndex) return;\n event.preventDefault();\n setFocusedRowIndex(nextIndex);\n rowRefs.current[nextIndex]?.focus();\n };\n // Vertical borders are opt-in; a trailing border on the last cell would\n // double up with the wrapper, so suppress it.\n const borderedClass = bordered\n ? '[&_th:not(:last-child)]:border-e [&_td:not(:last-child)]:border-e [&_th]:border-[var(--ui-table-global-row-border-color)] [&_td]:border-[var(--ui-table-global-row-border-color)]'\n : undefined;\n\n // A pinned header/body cell must be opaque so the cells scrolling under it\n // (same row) aren't visible. `--ui-table-data-row-color-idle` is\n // *transparent by design* (an idle row shows the page/card surface through\n // it), so it can't be reused here — pinned idle cells need the actual\n // resolved surface color instead (`--ui-background-surface-primary`, bridged\n // to `bg-background`). Non-idle states (selected/current/striped) already use\n // real opaque tokens and are safe to mirror as-is (see `rowBg` below).\n const headerPinnedBg = 'bg-background';\n\n return (\n <div\n className={cn(\n 'rounded-md border border-[var(--ui-table-global-row-border-color)]',\n borderedClass\n )}\n >\n <Table\n style={\n resizingEnabled ? { width: table.getCenterTotalSize() } : undefined\n }\n >\n {/* One provider for the whole header row so the capability hints share\n a single open/close delay group (Provider renders no DOM, so the\n table markup is unaffected). */}\n <TooltipProvider>\n <TableHeader>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n {headerGroup.headers.map((header) => {\n const isPinned = header.column.getIsPinned();\n const canResize =\n resizingEnabled && header.column.getCanResize();\n // A pinned column is anchored to a table edge, so dragging it\n // out of that edge would contradict its own pinning.\n const canReorder =\n reorderingEnabled && !header.isPlaceholder && !isPinned;\n const canSort =\n !header.isPlaceholder && header.column.getCanSort();\n // One tooltip line per capability the column actually has, in\n // the design's order; a column with none gets no tooltip.\n const hints = [\n canSort && resolvedHeaderHints.sort,\n canReorder && resolvedHeaderHints.reorder,\n canResize && resolvedHeaderHints.resize,\n ].filter((hint): hint is DataTableHeaderHint =>\n Boolean(hint)\n );\n if (header.column.id === '__actions') {\n return (\n <TableSettingsCell\n key={header.id}\n style={getHeaderStyle(header, resizingEnabled)}\n className={headerPinnedBg}\n >\n <DataTableViewOptions\n table={table}\n iconOnly\n triggerAriaLabel={columnSettingsLabel}\n />\n </TableSettingsCell>\n );\n }\n const headerCell = (\n <TableHead\n wrap={header.column.columnDef.meta?.wrap}\n style={getHeaderStyle(header, resizingEnabled)}\n draggable={\n (canReorder && !isAnyColumnResizing) || undefined\n }\n onDragStart={\n canReorder\n ? (event) =>\n handleColumnDragStart(event, header.column.id)\n : undefined\n }\n onDragOver={canReorder ? handleColumnDragOver : undefined}\n onDrop={\n canReorder\n ? (event) =>\n handleColumnDrop(event, header.column.id)\n : undefined\n }\n onDragEnd={\n canReorder\n ? () => setDraggedColumnId(undefined)\n : undefined\n }\n className={cn(\n canResize && 'relative',\n // Per the design, a sortable header tints the whole\n // cell on hover/press, not just the inner sort button.\n // Suppressed while any column is resizing, since the\n // pointer drags across neighboring `<th>`s and would\n // otherwise tint them via native `:hover`.\n canSort &&\n !isAnyColumnResizing &&\n 'transition-colors hover:bg-[var(--ui-table-header-cell-color-hover)] active:bg-[var(--ui-table-header-cell-color-active)]',\n canReorder &&\n !isAnyColumnResizing &&\n 'cursor-(--ui-draggable-cursor) select-none active:cursor-(--ui-draggable-cursor-active)',\n canReorder &&\n draggedColumnId === header.column.id &&\n 'opacity-50',\n isPinned && headerPinnedBg\n )}\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n {canResize && (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={resizeColumnLabel}\n aria-valuenow={header.column.getSize()}\n aria-valuemin={\n header.column.columnDef.minSize ??\n DEFAULT_MIN_COLUMN_SIZE\n }\n aria-valuemax={\n header.column.columnDef.maxSize ??\n DEFAULT_MAX_COLUMN_SIZE\n }\n tabIndex={0}\n // Keeps a press on the handle from starting the header\n // cell's reorder drag instead of a resize when both\n // features are enabled.\n draggable={false}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n onKeyDown={(event) =>\n handleResizeKeyDown(event, header)\n }\n className={cn(\n 'absolute end-0 top-0 h-full w-1 cursor-(--ui-resizable-cursor) touch-none select-none bg-[var(--ui-table-global-row-border-color)] opacity-0 transition-[opacity,background-color] hover:bg-[var(--ui-resizable-border-color-hover)] hover:opacity-100 focus-visible:bg-[var(--ui-resizable-border-color-hover)] focus-visible:opacity-100 focus-visible:outline-[3px] focus-visible:outline-(--ui-focus-primary)',\n header.column.getIsResizing() &&\n 'bg-[var(--ui-resizable-border-color-active)] opacity-100'\n )}\n />\n )}\n </TableHead>\n );\n if (hints.length === 0) {\n return <Fragment key={header.id}>{headerCell}</Fragment>;\n }\n return (\n <Tooltip\n key={header.id}\n disabled={\n isAnyColumnResizing || draggedColumnId !== undefined\n }\n >\n {/* The whole header cell is the trigger (not just its sort\n button), so the hint covers the reorder/resize gestures\n that live on the cell itself. Disabled mid-drag/resize\n so the hint doesn't pop up over a neighboring cell\n while the pointer passes through it. */}\n <TooltipTrigger render={headerCell} />\n <TooltipContent className=\"flex flex-col gap-1\">\n {hints.map((hint) => (\n <span key={hint.label}>\n <span className=\"font-semibold\">{hint.label}:</span>{' '}\n {hint.action}\n </span>\n ))}\n </TooltipContent>\n </Tooltip>\n );\n })}\n </TableRow>\n ))}\n </TableHeader>\n </TooltipProvider>\n <TableBody>\n {skeleton ? (\n Array.from({ length: skeletonRows }).map((_, rowIndex) => (\n <TableRow\n key={`skeleton-${rowIndex}`}\n className=\"hover:bg-transparent\"\n >\n {table.getVisibleLeafColumns().map((column) => (\n <TableCell key={column.id}>\n <div className=\"h-4 w-full animate-pulse rounded bg-[var(--ui-background-surface-secondary)]\" />\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : rows?.length ? (\n rows.map((row, rowIndex) => {\n if (renderRow) {\n return (\n <Fragment key={row.id}>{renderRow(row, rowIndex)}</Fragment>\n );\n }\n const isSelected = row.getIsSelected();\n const isCurrent = highlightCurrentRow && currentRowId === row.id;\n // Opaque background applied to pinned cells so sibling cells don't\n // show through while the grid scrolls horizontally. Mirrors the\n // row's own resolved background across selection/current/stripe —\n // the idle case falls back to the real surface color\n // (`bg-background`) since the row's own idle token is transparent\n // by design (see `headerPinnedBg` above).\n // The idle case mirrors the row's own hover tint via `group` (see\n // the row's `group` class below) so the pinned action column\n // doesn't look \"stuck\" idle while the rest of the row is\n // hovered — the row's native `hover:` can't reach it since it\n // needs its own opaque background (see `headerPinnedBg` above).\n const rowBg =\n isSelected || isCurrent\n ? 'bg-[var(--ui-table-data-row-color-active)]'\n : striped && rowIndex % 2 === 1\n ? 'bg-[var(--ui-background-surface-secondary)]'\n : 'bg-background group-hover:bg-[var(--ui-table-data-row-color-hover)]';\n // While a selection is in play the action cell renders nothing and\n // carries no tint of its own, so suppressing the row's hover tint\n // for it would leave the pointer over a row that reacts to\n // nothing. Also covers a row hovered just before the selection\n // started, whose id is still in `actionHoveredRowId`.\n const isActionCellHovered =\n !bulkSelectionActive && actionHoveredRowId === row.id;\n return (\n <Fragment key={row.id}>\n <TableRow\n ref={(node) => {\n rowRefs.current[rowIndex] = node;\n }}\n tabIndex={rowIndex === activeRowIndex ? 0 : -1}\n onFocus={() => handleRowFocus(rowIndex)}\n onKeyDown={(event) => handleRowKeyDown(event, rowIndex)}\n selected={isSelected}\n onClick={\n highlightCurrentRow\n ? () => setCurrentRowId(row.id)\n : undefined\n }\n className={cn(\n 'group',\n highlightCurrentRow && 'cursor-pointer',\n striped &&\n rowIndex % 2 === 1 &&\n !isSelected &&\n !isCurrent &&\n 'bg-[var(--ui-background-surface-secondary)]',\n isCurrent &&\n !isSelected &&\n 'bg-[var(--ui-table-data-row-color-active)]',\n // The action cell's own hover tint (its ellipsis/cog\n // trigger) should be the only thing that reacts while\n // it's hovered — not the rest of the row underneath it.\n isActionCellHovered && 'hover:bg-transparent'\n )}\n >\n {row.getVisibleCells().map((cell) => {\n const isPinned = cell.column.getIsPinned();\n if (cell.column.id === '__actions') {\n return (\n <TableActionsCell\n key={cell.id}\n style={getCellStyle(cell, resizingEnabled)}\n className={rowBg}\n bulkSelectionActive={bulkSelectionActive}\n onMouseEnter={\n bulkSelectionActive\n ? undefined\n : () => setActionHoveredRowId(row.id)\n }\n onMouseLeave={\n bulkSelectionActive\n ? undefined\n : () =>\n setActionHoveredRowId((id) =>\n id === row.id ? undefined : id\n )\n }\n >\n {renderRowActions && (\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <ButtonIcon aria-label={rowActionsLabel} />\n }\n >\n <EllipsisIcon />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {renderRowActions(row)}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </TableActionsCell>\n );\n }\n return (\n <TableCell\n key={cell.id}\n wrap={cell.column.columnDef.meta?.wrap}\n style={getCellStyle(cell, resizingEnabled)}\n className={cn(isPinned && rowBg)}\n >\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext()\n )}\n </TableCell>\n );\n })}\n </TableRow>\n {renderExpandedRow && row.getIsExpanded() && (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell\n className=\"h-auto py-3\"\n colSpan={row.getVisibleCells().length}\n >\n {renderExpandedRow(row)}\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n );\n })\n ) : renderEmptyState ? (\n <TableRow>\n <TableCell\n colSpan={table.getVisibleLeafColumns().length}\n className=\"h-24 text-center\"\n >\n {renderEmptyState({\n hasFilters: table.getState().columnFilters.length > 0,\n })}\n </TableCell>\n </TableRow>\n ) : (\n <TableRow>\n <TableCell\n colSpan={table.getVisibleLeafColumns().length}\n className=\"h-24 text-center text-[var(--ui-table-data-value-color-disabled)]\"\n >\n {emptyLabel}\n </TableCell>\n </TableRow>\n )}\n {isInfiniteScroll && !skeleton && rows.length > 0 && hasNextPage && (\n <TableRow\n ref={sentinelRef}\n aria-hidden\n className=\"hover:bg-transparent\"\n >\n <TableCell\n colSpan={table.getVisibleLeafColumns().length}\n className=\"h-1 p-0\"\n />\n </TableRow>\n )}\n {isInfiniteScroll &&\n !skeleton &&\n rows.length > 0 &&\n isLoadingMore && (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell colSpan={table.getVisibleLeafColumns().length}>\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"h-4 w-full animate-pulse rounded bg-[var(--ui-background-surface-secondary)]\"\n >\n <span className=\"sr-only\">Loading more rows…</span>\n </div>\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n );\n}\n"],"names":["getPinnedStyle","column","pinned","getColumnWidth","enableColumnResizing","getHeaderStyle","header","pin","width","getCellStyle","cell","DEFAULT_MIN_COLUMN_SIZE","DEFAULT_MAX_COLUMN_SIZE","getResizeKeyboardStep","key","currentSize","shiftKey","min","max","step","reorderColumn","order","from","to","fromIndex","toIndex","next","DEFAULT_HEADER_HINTS","DataTable","columns","data","externalTable","getRowCanExpand","renderExpandedRow","striped","bordered","highlightCurrentRow","skeleton","skeletonRows","onColumnSizingChange","enableColumnReordering","controlledColumnOrder","onColumnOrderChange","controlledColumnVisibility","onColumnVisibilityChange","controlledRowSelection","onRowSelectionChange","manualSorting","controlledSorting","onSortingChange","renderRow","renderEmptyState","paginationMode","onLoadMore","loadMoreRootMargin","hasNextPage","resizeColumnLabel","emptyLabel","isLoadingMore","hideActionColumn","renderRowActions","rowActionsLabel","columnSettingsLabel","headerHints","resolvedHeaderHints","internalSorting","setInternalSorting","useState","sorting","columnFilters","setColumnFilters","internalColumnVisibility","setInternalColumnVisibility","columnVisibility","internalRowSelection","setInternalRowSelection","rowSelection","expanded","setExpanded","columnSizing","setColumnSizing","internalColumnOrder","setInternalColumnOrder","columnOrder","draggedColumnId","setDraggedColumnId","currentRowId","setCurrentRowId","focusedRowIndex","setFocusedRowIndex","rowRefs","useRef","handleColumnSizingChange","updater","handleColumnOrderChange","handleColumnVisibilityChange","handleSortingChange","handleRowSelectionChange","showActionColumn","actionColumns","useMemo","tableColumns","actionHoveredRowId","setActionHoveredRowId","internalTable","useReactTable","getCoreRowModel","getExpandedRowModel","getPaginationRowModel","getSortedRowModel","getFilteredRowModel","table","isInfiniteScroll","resizingEnabled","reorderingEnabled","isAnyColumnResizing","useEffect","sentinelRef","useIntersectionObserver","handleResizeKeyDown","event","nextSize","old","handleColumnDragStart","columnId","handleColumnDragOver","handleColumnDrop","targetColumnId","current","base","_a","rows","bulkSelectionActive","isBulkSelectionActive","activeRowIndex","handleRowFocus","rowIndex","handleRowKeyDown","nextIndex","borderedClass","headerPinnedBg","jsx","cn","jsxs","Table","TooltipProvider","TableHeader","headerGroup","TableRow","isPinned","canResize","canReorder","canSort","hints","hint","TableSettingsCell","DataTableViewOptions","headerCell","TableHead","flexRender","Fragment","Tooltip","TooltipTrigger","TooltipContent","TableBody","_","TableCell","row","isSelected","isCurrent","rowBg","isActionCellHovered","node","TableActionsCell","id","DropdownMenu","DropdownMenuTrigger","ButtonIcon","EllipsisIcon","DropdownMenuContent"],"mappings":"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"}
1
+ {"version":3,"file":"data-table.js","sources":["../../../../src/components/ui/data-table/data-table.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type DragEvent,\n Fragment,\n type KeyboardEvent,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n type Cell,\n type Column,\n type ColumnDef,\n type ColumnFiltersState,\n type ColumnOrderState,\n type ColumnSizingState,\n type ExpandedState,\n type Header,\n type OnChangeFn,\n type Row,\n type RowData,\n type RowSelectionState,\n type SortingState,\n type Table as TanstackTable,\n type VisibilityState,\n flexRender,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from '@tanstack/react-table';\n\nimport { EllipsisIcon } from '@acronis-platform/icons-react/stroke-mono';\n\nimport { useIntersectionObserver } from '@/hooks';\nimport { cn } from '@/lib/utils';\nimport { ButtonIcon } from '../button-icon';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from '../dropdown-menu';\nimport {\n Table,\n TableActionsCell,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n TableSettingsCell,\n} from '../table';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '../tooltip';\nimport { isBulkSelectionActive } from './data-table-selection';\nimport { DataTableViewOptions } from './data-table-view-options';\n\n// Ported from `@acronis-platform/shadcn-uikit`'s `data-table`\n// (packages/ui-legacy/src/components/ui/data-table/). A TanStack-react-table v8\n// data grid composed over the ui-react Table primitives — sorting, filtering,\n// column visibility, row selection, pagination, and optional row expansion. The\n// presentational flags (`striped`, `bordered`, `skeleton`, `highlightCurrentRow`)\n// are borrowed from the Vue `AvTable`; behavioral features come from TanStack.\n// Pair with DataTableToolbar / DataTablePagination / DataTableColumnHeader, which\n// take the `table` instance returned to column cells via TanStack context.\n// The grid cells/rows/headers are themed by the Table primitives' `--ui-table-*`\n// tier; DataTable's own chrome reuses that tier too — the wrapper border matches\n// the cell borders (`--ui-table-global-row-border-color`), the empty-state uses\n// the muted table-value color, the current row the active-row color, and stripes\n// the secondary surface.\n//\n// Advanced-grid opt-ins built on native TanStack features:\n// • Column resizing -> `enableColumnResizing` + `columnResizing` state, with a\n// drag handle rendered from `header.getResizeHandler()`.\n// • Sticky columns -> `ColumnDef.meta.pin: 'left' | 'right'` drives TanStack's\n// native column-pinning API (`column.pin()` / `getStart()` / `getAfter()`),\n// surfaced as `position: sticky` cells with an opaque row-token background.\n// • Column reorder -> `enableColumnReordering` + `columnOrder` state, with\n// native HTML5 drag-and-drop on the header cells (plain `cursor-grab`/\n// `active:cursor-grabbing` utilities, since there's no dedicated Figma\n// \"Draggable\" token yet, unlike the resize handle's generated\n// `--ui-resizable-cursor`).\n\n// Extend TanStack's per-column `meta` with the flags DataTable reads. Augmenting\n// the module keeps `ColumnDef.meta.pin` type-safe at the call site.\ndeclare module '@tanstack/react-table' {\n // Type params must match TanStack's `ColumnMeta<TData, TValue>` arity/names for\n // declaration merging, even though this augmentation doesn't reference them.\n // eslint-disable-next-line unused-imports/no-unused-vars\n interface ColumnMeta<TData extends RowData, TValue> {\n /** Pin the column to a table edge (sticky while the grid scrolls horizontally). */\n pin?: 'left' | 'right';\n /**\n * Let the column's header + cells wrap onto multiple lines (drops the fixed\n * row height); mirrors the `Table` primitives' `wrap` prop on TableHead/TableCell.\n */\n wrap?: boolean;\n }\n}\n\n// Sticky offset + stacking for a pinned column, computed from TanStack's own\n// pinning geometry rather than hand-rolled CSS math. A subtle edge shadow (facing\n// the scrollable columns) separates the pinned column from content sliding\n// underneath it — the opaque background that actually hides that content lives\n// in the caller's className (see `headerPinnedBg`/`rowBg` below), not here.\nexport function getPinnedStyle<TData>(\n column: Column<TData, unknown>\n): CSSProperties | undefined {\n const pinned = column.getIsPinned();\n if (!pinned) return undefined;\n return {\n position: 'sticky',\n left: pinned === 'left' ? column.getStart('left') : undefined,\n right: pinned === 'right' ? column.getAfter('right') : undefined,\n zIndex: 1,\n // Derived from the same border token every other table divider uses (not a\n // hardcoded color), so the separator theme-adapts automatically.\n boxShadow:\n pinned === 'left'\n ? '4px 0 4px -4px var(--ui-table-global-row-border-color)'\n : '-4px 0 4px -4px var(--ui-table-global-row-border-color)',\n };\n}\n\n// A column's rendered width tracks TanStack's size model once the consumer has\n// opted in — either explicitly (a `size` set on the `ColumnDef`) or implicitly\n// (column resizing enabled, which needs every column's width to be deterministic\n// for the drag math to work). Without either, columns stay in native `<table>`\n// auto-layout so `size`'s internal default (TanStack falls back to 150) never\n// forces every untouched column to a fixed width.\nexport function getColumnWidth<TData>(\n column: Column<TData, unknown>,\n enableColumnResizing: boolean\n): number | undefined {\n if (column.id === 'select') {\n // Matches the trailing `__actions` column's fixed 48px: symmetric gutters.\n return 48;\n }\n if (enableColumnResizing || column.columnDef.size !== undefined) {\n return column.getSize();\n }\n return undefined;\n}\n\nfunction getHeaderStyle<TData>(\n header: Header<TData, unknown>,\n enableColumnResizing: boolean\n): CSSProperties | undefined {\n const pin = getPinnedStyle(header.column);\n const width = getColumnWidth(header.column, enableColumnResizing);\n if (!pin && width === undefined) return undefined;\n return { ...pin, width };\n}\n\nexport function getCellStyle<TData>(\n cell: Cell<TData, unknown>,\n enableColumnResizing: boolean\n): CSSProperties | undefined {\n const pin = getPinnedStyle(cell.column);\n const width = getColumnWidth(cell.column, enableColumnResizing);\n if (!pin && width === undefined) return undefined;\n return { ...pin, width };\n}\n\n// Matches TanStack's own `defaultColumnSizing` fallback bounds — the same\n// range `column.getSize()` already clamps to internally when a column\n// doesn't set its own `minSize`/`maxSize`.\nconst DEFAULT_MIN_COLUMN_SIZE = 20;\nconst DEFAULT_MAX_COLUMN_SIZE = Number.MAX_SAFE_INTEGER;\n\n/**\n * Computes the next column width for an Arrow-key resize step (Shift = larger\n * step), clamped to `[min, max]` regardless of which bound `currentSize`\n * started outside of. Returns `undefined` for any other key, so the caller\n * knows not to `preventDefault()`/resize.\n */\nexport function getResizeKeyboardStep(\n key: string,\n currentSize: number,\n { shiftKey, min, max }: { shiftKey: boolean; min: number; max: number }\n): number | undefined {\n const step = shiftKey ? 50 : 10;\n if (key === 'ArrowLeft')\n return Math.min(max, Math.max(min, currentSize - step));\n if (key === 'ArrowRight')\n return Math.max(min, Math.min(max, currentSize + step));\n return undefined;\n}\n\n/**\n * Moves `from` to `to`'s position in a `columnOrder` array (the drop semantics\n * of the header drag gesture: the dragged column lands where the drop target\n * sits, pushing it aside). Returns `order` unchanged when either id is absent,\n * so a drop on a column that isn't part of the order (e.g. one added while the\n * gesture was in flight) is a no-op rather than a reshuffle.\n */\nexport function reorderColumn(\n order: string[],\n from: string,\n to: string\n): string[] {\n const fromIndex = order.indexOf(from);\n const toIndex = order.indexOf(to);\n if (fromIndex === -1 || toIndex === -1 || fromIndex === toIndex) return order;\n const next = [...order];\n next.splice(toIndex, 0, next.splice(fromIndex, 1)[0]);\n return next;\n}\n\n/** One line of the header hover tooltip: a capability and the gesture for it. */\nexport interface DataTableHeaderHint {\n /** The capability, rendered in bold (e.g. `Sort column`). */\n label: string;\n /** The gesture that triggers it (e.g. `Click`). */\n action: string;\n}\n\n/** Copy of the header hover tooltip, one entry per column capability. */\nexport interface DataTableHeaderHints {\n sort: DataTableHeaderHint;\n reorder: DataTableHeaderHint;\n resize: DataTableHeaderHint;\n}\n\nconst DEFAULT_HEADER_HINTS: DataTableHeaderHints = {\n sort: { label: 'Sort column', action: 'Click' },\n reorder: { label: 'Reorder column', action: 'Drag' },\n resize: { label: 'Resize column', action: 'Drag border' },\n};\n\n// `columns`/`data` build DataTable's own table instance; `table` renders an\n// externally-built one instead. At least one of the two forms is required —\n// omitting both would otherwise silently render an empty table — but `table`\n// may still be passed alongside `columns`/`data` (e.g. to also drive a\n// composed toolbar/pagination from the same instance DataTable renders).\ntype DataTableDataSourceProps<TData, TValue> =\n | {\n columns: ColumnDef<TData, TValue>[];\n data: TData[];\n /**\n * Also drive an externally-built TanStack `table` instance (e.g. a\n * composed toolbar/pagination) from the same state as this DataTable.\n */\n table?: TanstackTable<TData>;\n }\n | {\n columns?: ColumnDef<TData, TValue>[];\n data?: TData[];\n /**\n * Render from an externally-built TanStack `table` instance instead of\n * DataTable's own — DataTable then owns no state and renders the caller's\n * instance as-is (sorting, filtering, pagination, row models, etc. are all\n * configured on that instance). Makes `columns`/`data` unnecessary (they're\n * only used to build DataTable's own instance) and the following props\n * no-ops (configure the equivalent directly on the external instance\n * instead): `columnVisibility`, `onColumnVisibilityChange`,\n * `onColumnSizingChange`, `enableColumnResizing`,\n * `enableColumnReordering`, `columnOrder`, `onColumnOrderChange`,\n * `getRowCanExpand`,\n * `manualSorting`, `sorting`, `onSortingChange`, `paginationMode`,\n * `onLoadMore`, `loadMoreRootMargin`, `hasNextPage`, `isLoadingMore`.\n * `meta.pin`-driven column pinning is also skipped — pin/unpin the\n * caller's own instance via TanStack's `column.pin()` directly.\n */\n table: TanstackTable<TData>;\n };\n\ninterface DataTableOwnProps<TData> {\n /** Enables row expansion for rows that return true. Pair with `renderExpandedRow`. */\n getRowCanExpand?: (row: Row<TData>) => boolean;\n /**\n * Renders expanded content for an expanded row. Used together with\n * `getRowCanExpand`.\n */\n renderExpandedRow?: (row: Row<TData>) => ReactNode;\n /** Alternating row backgrounds. */\n striped?: boolean;\n /** Vertical borders between columns (rows already have horizontal borders). */\n bordered?: boolean;\n /** Highlight the row the user last clicked (the \"current\" row). */\n highlightCurrentRow?: boolean;\n /** Render placeholder skeleton rows instead of data (loading state). */\n skeleton?: boolean;\n /** Number of skeleton rows to render when `skeleton` is set. */\n skeletonRows?: number;\n /**\n * Opt in to interactive column resizing. Renders a drag handle at the trailing\n * edge of each resizable header cell (TanStack's native `columnResizing`).\n */\n enableColumnResizing?: boolean;\n /** Passthrough for the `columnSizing` state so a consumer can persist widths. */\n onColumnSizingChange?: OnChangeFn<ColumnSizingState>;\n /**\n * Opt in to column reordering by dragging a header cell onto another one\n * (native HTML5 drag-and-drop driving TanStack's `columnOrder`). Pinned\n * columns are excluded — they're anchored to a table edge by definition.\n * Pointer-only, matching the design: there is no keyboard equivalent yet.\n */\n enableColumnReordering?: boolean;\n /**\n * Controlled column-order state — pass this (with `onColumnOrderChange`) to\n * persist or share the order. Uncontrolled (internal state) when omitted.\n */\n columnOrder?: ColumnOrderState;\n /** Passthrough for the `columnOrder` state; pairs with `columnOrder`. */\n onColumnOrderChange?: OnChangeFn<ColumnOrderState>;\n /**\n * Controlled column-visibility state — pass this (with\n * `onColumnVisibilityChange`) to share one visibility state with an\n * external `useReactTable` instance (e.g. a composed toolbar). Uncontrolled\n * (internal state) when omitted.\n */\n columnVisibility?: VisibilityState;\n /** Passthrough for the `columnVisibility` state; pairs with `columnVisibility`. */\n onColumnVisibilityChange?: OnChangeFn<VisibilityState>;\n /**\n * Controlled row-selection state — pass this (with `onRowSelectionChange`)\n * to share one selection state with an external `useReactTable` instance\n * (e.g. a composed toolbar/bulk-actions bar). Uncontrolled (internal state)\n * when omitted.\n */\n rowSelection?: RowSelectionState;\n /** Passthrough for the `rowSelection` state; pairs with `rowSelection`. */\n onRowSelectionChange?: OnChangeFn<RowSelectionState>;\n /**\n * Opt out of client-side sorting — pass already-sorted `data` and drive\n * sorting via `sorting`/`onSortingChange` (e.g. mapped to a server query by\n * the caller). Mapping sort state to a query and refetching stays the\n * caller's job; DataTable only skips its own comparator.\n */\n manualSorting?: boolean;\n /**\n * Controlled sorting state — pass this (with `onSortingChange`) to drive\n * sorting externally. Uncontrolled (internal state) when omitted.\n */\n sorting?: SortingState;\n /** Passthrough for the `sorting` state; pairs with `sorting`. */\n onSortingChange?: OnChangeFn<SortingState>;\n /**\n * Renders a full row, bypassing DataTable's default per-cell `flexRender`\n * path entirely (no `<TableRow>`/cell-styling/pinning of DataTable's own).\n * Use to swap in a custom, independently memoizable row component. The\n * caller owns the row's markup and equality semantics — reuse the exported\n * `getCellStyle`/`getPinnedStyle`/`getColumnWidth` helpers to match\n * DataTable's default cell styling if desired.\n *\n * Also bypasses DataTable's `renderExpandedRow` handling — a row rendered\n * via `renderRow` never gets an expanded-content row appended, even when\n * `getRowCanExpand` returns true for it. Read `row.getIsExpanded()` and\n * render the expanded content yourself if you need both.\n */\n renderRow?: (row: Row<TData>, rowIndex: number) => ReactNode;\n /**\n * Renders a custom empty state instead of the default \"No results.\" row.\n * Receives `hasFilters` (whether any column filter is currently applied) so\n * the caller can distinguish \"no data at all\" from \"no matches\" — the\n * actual copy/wording/localization stays the caller's job.\n */\n renderEmptyState?: (context: { hasFilters: boolean }) => ReactNode;\n /**\n * `'page'` (default) keeps today's client-paginated behavior. `'infinite'`\n * omits the paginated row model — `data` is assumed to be the full\n * accumulated array the caller appends to on each `onLoadMore` — and\n * renders a sentinel row that calls `onLoadMore` once it scrolls into view.\n * Does not compose with virtualization; for a large accumulated list, use\n * the `VirtualScrolling` recipe over the raw `Table` primitives instead.\n */\n paginationMode?: 'page' | 'infinite';\n /**\n * Called when the infinite-scroll sentinel intersects the viewport.\n * `paginationMode=\"infinite\"` only. The fetch-more call, cursor/offset\n * tracking, dedup, and accumulating `data` stay the caller's job. Requires\n * at least one row already rendered — an empty table with `data={[]}`\n * cannot use the sentinel to drive its very first fetch; seed the first\n * page yourself (e.g. on mount) and use `onLoadMore` for subsequent pages.\n */\n onLoadMore?: () => void;\n /**\n * Expands the sentinel's `IntersectionObserver` root margin (native CSS\n * margin syntax, e.g. `'400px'`) so `onLoadMore` fires before the sentinel\n * is literally visible — the closer the caller's fetch is to finishing by\n * the time the user actually scrolls there, the less often the trailing\n * loading row is seen. `paginationMode=\"infinite\"` only; no-op when `table`\n * is passed. How far this actually prefetches also depends on page size —\n * a large margin with small pages can trigger several `onLoadMore` calls\n * back-to-back as the user scrolls normally, which is expected.\n */\n loadMoreRootMargin?: string;\n /** Whether more rows are available to load. `paginationMode=\"infinite\"` only. */\n hasNextPage?: boolean;\n /**\n * Accessible name of a column's resize handle. Override to localize.\n * `enableColumnResizing` only.\n */\n resizeColumnLabel?: string;\n /**\n * Text of the default empty-state row. Ignored when `renderEmptyState` is\n * given. Override to localize.\n */\n emptyLabel?: string;\n /**\n * Whether a load is in flight — suppresses further `onLoadMore` calls and\n * renders a trailing loading row. `paginationMode=\"infinite\"` only.\n */\n isLoadingMore?: boolean;\n /**\n * Hide the trailing sticky action column — the column-visibility cog in the\n * header and each row's overflow-actions ellipsis. Shown by default. A\n * no-op when an external `table` is passed (build the column into that\n * instance's own `columns` instead).\n */\n hideActionColumn?: boolean;\n /**\n * Renders the content of a row's overflow-actions menu (e.g. `Edit`/\n * `Delete` items), opened from the ellipsis trigger in the trailing action\n * column. Omit to render that row without a trigger — the 48px column is\n * still reserved. Suppressed (like the trigger itself) while a bulk\n * selection is active, per `TableActionsCell`.\n */\n renderRowActions?: (row: Row<TData>) => ReactNode;\n /** Accessible name of a row's overflow-actions trigger. Override to localize. */\n rowActionsLabel?: string;\n /**\n * Accessible name of the action column's column-visibility trigger.\n * Override to localize.\n */\n columnSettingsLabel?: string;\n /**\n * Copy of the tooltip shown while a header cell is hovered/focused — one\n * line per capability that column actually has (sort/reorder/resize).\n * Override (per capability) to localize; a column with no capability shows\n * no tooltip at all.\n */\n headerHints?: Partial<DataTableHeaderHints>;\n}\n\nexport type DataTableProps<TData, TValue = unknown> = DataTableOwnProps<TData> &\n DataTableDataSourceProps<TData, TValue>;\n\nexport function DataTable<TData, TValue = unknown>({\n columns = [],\n data = [],\n table: externalTable,\n getRowCanExpand,\n renderExpandedRow,\n striped = false,\n bordered = false,\n highlightCurrentRow = false,\n skeleton = false,\n skeletonRows = 5,\n enableColumnResizing = false,\n onColumnSizingChange,\n enableColumnReordering = false,\n columnOrder: controlledColumnOrder,\n onColumnOrderChange,\n columnVisibility: controlledColumnVisibility,\n onColumnVisibilityChange,\n rowSelection: controlledRowSelection,\n onRowSelectionChange,\n manualSorting = false,\n sorting: controlledSorting,\n onSortingChange,\n renderRow,\n renderEmptyState,\n paginationMode = 'page',\n onLoadMore,\n loadMoreRootMargin,\n hasNextPage = false,\n resizeColumnLabel = 'Resize column',\n emptyLabel = 'No results.',\n isLoadingMore = false,\n hideActionColumn = false,\n renderRowActions,\n rowActionsLabel = 'Row actions',\n columnSettingsLabel,\n headerHints,\n}: DataTableProps<TData, TValue>) {\n const resolvedHeaderHints: DataTableHeaderHints = {\n ...DEFAULT_HEADER_HINTS,\n ...headerHints,\n };\n const [internalSorting, setInternalSorting] = useState<SortingState>([]);\n const sorting = controlledSorting ?? internalSorting;\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);\n const [internalColumnVisibility, setInternalColumnVisibility] =\n useState<VisibilityState>({});\n const columnVisibility =\n controlledColumnVisibility ?? internalColumnVisibility;\n const [internalRowSelection, setInternalRowSelection] =\n useState<RowSelectionState>({});\n const rowSelection = controlledRowSelection ?? internalRowSelection;\n const [expanded, setExpanded] = useState<ExpandedState>({});\n const [columnSizing, setColumnSizing] = useState<ColumnSizingState>({});\n const [internalColumnOrder, setInternalColumnOrder] =\n useState<ColumnOrderState>([]);\n const columnOrder = controlledColumnOrder ?? internalColumnOrder;\n // The header cell the user is currently dragging, so the source cell can dim\n // while the gesture is in flight.\n const [draggedColumnId, setDraggedColumnId] = useState<string>();\n const [currentRowId, setCurrentRowId] = useState<string>();\n // Roving tabindex over the data rows: exactly one row is a Tab stop at a\n // time (the rest are `tabIndex={-1}`, still focusable programmatically),\n // and Arrow Up/Down move both the DOM focus and which row that is. Clamped\n // against the live row count below rather than reset via an effect, so a\n // filter/page change that shrinks `rows` can't leave it pointing past the\n // end.\n const [focusedRowIndex, setFocusedRowIndex] = useState(0);\n const rowRefs = useRef<Array<HTMLTableRowElement | null>>([]);\n\n const handleColumnSizingChange: OnChangeFn<ColumnSizingState> = (updater) => {\n setColumnSizing(updater);\n onColumnSizingChange?.(updater);\n };\n\n const handleColumnOrderChange: OnChangeFn<ColumnOrderState> = (updater) => {\n if (controlledColumnOrder === undefined) {\n setInternalColumnOrder(updater);\n }\n onColumnOrderChange?.(updater);\n };\n\n const handleColumnVisibilityChange: OnChangeFn<VisibilityState> = (\n updater\n ) => {\n setInternalColumnVisibility(updater);\n onColumnVisibilityChange?.(updater);\n };\n\n const handleSortingChange: OnChangeFn<SortingState> = (updater) => {\n if (controlledSorting === undefined) {\n setInternalSorting(updater);\n }\n onSortingChange?.(updater);\n };\n\n const handleRowSelectionChange: OnChangeFn<RowSelectionState> = (\n updater\n ) => {\n if (controlledRowSelection === undefined) {\n setInternalRowSelection(updater);\n }\n onRowSelectionChange?.(updater);\n };\n\n // The trailing sticky action column (cog + per-row ellipsis) is a no-op\n // with an external `table` — that instance's own `columns` already decide\n // what renders, DataTable doesn't own its state in that mode (see the\n // `table` prop's tsdoc).\n const showActionColumn = !hideActionColumn && !externalTable;\n // A real `ColumnDef` (rather than chrome bolted onto the render loop) so\n // TanStack's own pinning geometry measures and offsets it like any other\n // pinned column — `header`/`cell` are never read (see the header/body\n // render loops below, which special-case this id), only `size`/`meta.pin`.\n const actionColumns = useMemo<ColumnDef<TData, TValue>[]>(\n () =>\n showActionColumn\n ? [\n {\n id: '__actions',\n size: 48,\n enableSorting: false,\n enableHiding: false,\n meta: { pin: 'right' },\n header: () => null,\n cell: () => null,\n },\n ]\n : [],\n [showActionColumn]\n );\n const tableColumns = useMemo(\n () => [...columns, ...actionColumns],\n [columns, actionColumns]\n );\n // The pinned action cell's own hover (its ellipsis/cog trigger) should be\n // the only thing that tints while it's hovered — not the row underneath it\n // (see `hover:bg-transparent` below). Tracked by id (rather than a boolean)\n // because it's set from the action cell of whichever row is currently under\n // the pointer.\n const [actionHoveredRowId, setActionHoveredRowId] = useState<string>();\n\n // Built unconditionally — hooks can't be conditionally called — but only\n // feeds the render path below when no external `table` is passed (see\n // `table` below).\n const internalTable = useReactTable({\n data,\n columns: tableColumns,\n enableColumnResizing,\n columnResizeMode: 'onChange',\n getCoreRowModel: getCoreRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n ...(paginationMode === 'page'\n ? { getPaginationRowModel: getPaginationRowModel() }\n : {}),\n getRowCanExpand,\n onExpandedChange: setExpanded,\n manualSorting,\n onSortingChange: handleSortingChange,\n ...(manualSorting ? {} : { getSortedRowModel: getSortedRowModel() }),\n onColumnFiltersChange: setColumnFilters,\n getFilteredRowModel: getFilteredRowModel(),\n onColumnVisibilityChange: handleColumnVisibilityChange,\n onRowSelectionChange: handleRowSelectionChange,\n onColumnSizingChange: handleColumnSizingChange,\n onColumnOrderChange: handleColumnOrderChange,\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n rowSelection,\n expanded,\n columnSizing,\n columnOrder,\n },\n });\n\n // The caller's instance is the single source of truth when passed — it\n // configures its own row models/state, so DataTable just renders from it.\n const table = externalTable ?? internalTable;\n const isInfiniteScroll = !externalTable && paginationMode === 'infinite';\n // `enableColumnResizing` is documented as a no-op with an external `table`\n // (the caller owns that instance's ColumnSizing state), but ColumnSizing is\n // a built-in TanStack feature present on any instance — reading the raw\n // prop below would still render live resize handles that mutate the\n // caller's own instance. Gate it the same way as `isInfiniteScroll`.\n const resizingEnabled = enableColumnResizing && !externalTable;\n // Same reasoning as `resizingEnabled`: ColumnOrdering is a built-in TanStack\n // feature present on any instance, so reading the raw prop would let the\n // header drag mutate a caller-owned instance DataTable doesn't manage.\n const reorderingEnabled = enableColumnReordering && !externalTable;\n // A resize drag necessarily moves the pointer off the (few-px-wide) resize\n // handle and onto the header cell itself. If that cell is still\n // `draggable`, the browser arms a native HTML5 reorder drag mid-resize —\n // native drag then swallows the mousemove/mouseup TanStack's resize\n // handler relies on, so the cursor flips to the reorder \"grab\" icon and\n // releasing the mouse doesn't cleanly end the resize. Reading this back\n // from TanStack's own resize state (rather than pointer position) keeps\n // every header cell non-draggable for the *entire* gesture, regardless of\n // where the pointer ends up.\n const isAnyColumnResizing = Boolean(\n table.getState().columnSizingInfo.isResizingColumn\n );\n // The resize handle only shows its `ew-resize` cursor while the pointer is\n // directly over its thin 4px hit area — once a drag starts, fast pointer\n // movement leaves that area and the browser shows whatever cursor the\n // element underneath declares (e.g. a sortable header's `cursor-pointer`).\n // This attribute + the `html[data-ui-column-resizing] *` rule in\n // styles/index.css force `ew-resize` everywhere for the duration of the\n // drag — a plain `<body>` inline cursor loses to a descendant's own\n // `cursor` declaration, so it isn't enough on its own.\n useEffect(() => {\n if (!isAnyColumnResizing) return;\n document.documentElement.setAttribute('data-ui-column-resizing', '');\n return () => {\n document.documentElement.removeAttribute('data-ui-column-resizing');\n };\n }, [isAnyColumnResizing]);\n const sentinelRef = useIntersectionObserver<HTMLTableRowElement>({\n onIntersect: () => onLoadMore?.(),\n disabled: !isInfiniteScroll || !hasNextPage || isLoadingMore,\n rootMargin: loadMoreRootMargin,\n });\n\n // Arrow-key resize on the drag handle (see `canResize` below). Ignores any\n // modifier besides Shift so it doesn't hijack browser/OS shortcuts bound to\n // Ctrl/Alt/Cmd+Arrow (e.g. back navigation) while the handle has focus.\n const handleResizeKeyDown = (\n event: KeyboardEvent<HTMLDivElement>,\n header: Header<TData, unknown>\n ) => {\n if (event.ctrlKey || event.altKey || event.metaKey) return;\n const nextSize = getResizeKeyboardStep(event.key, header.column.getSize(), {\n shiftKey: event.shiftKey,\n min: header.column.columnDef.minSize ?? DEFAULT_MIN_COLUMN_SIZE,\n max: header.column.columnDef.maxSize ?? DEFAULT_MAX_COLUMN_SIZE,\n });\n if (nextSize === undefined) return;\n event.preventDefault();\n table.setColumnSizing((old) => ({ ...old, [header.column.id]: nextSize }));\n };\n\n // Native HTML5 drag-and-drop on the header cells. `columnOrder` starts empty\n // (TanStack reads that as \"the declared order\"), so the first drop seeds it\n // from the live leaf columns before moving anything.\n const handleColumnDragStart = (\n event: DragEvent<HTMLTableCellElement>,\n columnId: string\n ) => {\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n // Firefox requires setData() during dragstart to actually initiate a\n // native drag; the value itself is unused (drop reads draggedColumnId).\n event.dataTransfer.setData('text/plain', columnId);\n }\n setDraggedColumnId(columnId);\n };\n\n const handleColumnDragOver = (event: DragEvent<HTMLTableCellElement>) => {\n // Without this the browser rejects the drop and no `onDrop` ever fires.\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';\n };\n\n const handleColumnDrop = (\n event: DragEvent<HTMLTableCellElement>,\n targetColumnId: string\n ) => {\n event.preventDefault();\n if (!draggedColumnId) return;\n const current = table.getState().columnOrder;\n const base = current.length\n ? current\n : table.getAllLeafColumns().map((column) => column.id);\n table.setColumnOrder(reorderColumn(base, draggedColumnId, targetColumnId));\n setDraggedColumnId(undefined);\n };\n\n // Read each column's `meta.pin` and drive TanStack's native pinning state.\n // Always calls `pin()` (rather than only when truthy) so a column whose\n // `meta.pin` is removed dynamically actually un-pins. Skipped for an\n // external `table` — DataTable owns no state in that mode (see the `table`\n // prop's tsdoc), so the caller's own pinning setup is left alone.\n useEffect(() => {\n if (externalTable) return;\n table.getAllLeafColumns().forEach((column) => {\n column.pin(column.columnDef.meta?.pin ?? false);\n });\n }, [table, columns, externalTable]);\n\n const rows = table.getRowModel().rows;\n // Derived from the selection state, so it's the same for every row — compute\n // it once instead of per row inside the render loop below.\n const bulkSelectionActive = isBulkSelectionActive(table);\n const activeRowIndex = rows.length\n ? Math.min(focusedRowIndex, rows.length - 1)\n : 0;\n\n // Mouse/pointer clicks still focus a `tabIndex={-1}` row (browsers allow\n // programmatic/click focus regardless of tabIndex value) — syncing the\n // roving index on focus makes that row the next Tab stop too, matching how\n // users expect the last-interacted row to keep focus.\n const handleRowFocus = (rowIndex: number) => {\n setFocusedRowIndex(rowIndex);\n };\n\n const handleRowKeyDown = (\n event: KeyboardEvent<HTMLTableRowElement>,\n rowIndex: number\n ) => {\n // Keydown bubbles, so arrow keys from an interactive control inside a cell\n // (number spinner, textarea caret, native select) would otherwise be\n // hijacked to move row focus. Only roam when the row itself is focused.\n if (event.target !== event.currentTarget) return;\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;\n const nextIndex =\n event.key === 'ArrowDown'\n ? Math.min(rowIndex + 1, rows.length - 1)\n : Math.max(rowIndex - 1, 0);\n if (nextIndex === rowIndex) return;\n event.preventDefault();\n setFocusedRowIndex(nextIndex);\n rowRefs.current[nextIndex]?.focus();\n };\n // Vertical borders are opt-in; a trailing border on the last cell would\n // double up with the wrapper, so suppress it.\n const borderedClass = bordered\n ? '[&_th:not(:last-child)]:border-e [&_td:not(:last-child)]:border-e [&_th]:border-[var(--ui-table-global-row-border-color)] [&_td]:border-[var(--ui-table-global-row-border-color)]'\n : undefined;\n\n // A pinned header/body cell must be opaque so the cells scrolling under it\n // (same row) aren't visible. `--ui-table-data-row-color-idle` is\n // *transparent by design* (an idle row shows the page/card surface through\n // it), so it can't be reused here — pinned idle cells need the actual\n // resolved surface color instead (`--ui-background-surface-primary`, bridged\n // to `bg-background`). Non-idle states (selected/current/striped) already use\n // real opaque tokens and are safe to mirror as-is (see `rowBg` below).\n const headerPinnedBg = 'bg-background';\n\n return (\n <div\n className={cn(\n 'rounded-md border border-[var(--ui-table-global-row-border-color)]',\n borderedClass\n )}\n >\n <Table\n style={\n resizingEnabled ? { width: table.getCenterTotalSize() } : undefined\n }\n >\n {/* One provider for the whole header row so the capability hints share\n a single open/close delay group (Provider renders no DOM, so the\n table markup is unaffected). */}\n <TooltipProvider>\n <TableHeader>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n {headerGroup.headers.map((header) => {\n const isPinned = header.column.getIsPinned();\n const canResize =\n resizingEnabled &&\n header.column.getCanResize() &&\n header.column.id !== 'select';\n // A pinned column is anchored to a table edge, so dragging it\n // out of that edge would contradict its own pinning.\n const canReorder =\n reorderingEnabled && !header.isPlaceholder && !isPinned;\n const canSort =\n !header.isPlaceholder && header.column.getCanSort();\n // One tooltip line per capability the column actually has, in\n // the design's order; a column with none gets no tooltip.\n const hints = [\n canSort && resolvedHeaderHints.sort,\n canReorder && resolvedHeaderHints.reorder,\n canResize && resolvedHeaderHints.resize,\n ].filter((hint): hint is DataTableHeaderHint =>\n Boolean(hint)\n );\n if (header.column.id === '__actions') {\n return (\n <TableSettingsCell\n key={header.id}\n style={getHeaderStyle(header, resizingEnabled)}\n className={headerPinnedBg}\n >\n <DataTableViewOptions\n table={table}\n iconOnly\n triggerAriaLabel={columnSettingsLabel}\n />\n </TableSettingsCell>\n );\n }\n const headerCell = (\n <TableHead\n wrap={header.column.columnDef.meta?.wrap}\n style={getHeaderStyle(header, resizingEnabled)}\n draggable={\n (canReorder && !isAnyColumnResizing) || undefined\n }\n onDragStart={\n canReorder\n ? (event) =>\n handleColumnDragStart(event, header.column.id)\n : undefined\n }\n onDragOver={canReorder ? handleColumnDragOver : undefined}\n onDrop={\n canReorder\n ? (event) =>\n handleColumnDrop(event, header.column.id)\n : undefined\n }\n onDragEnd={\n canReorder\n ? () => setDraggedColumnId(undefined)\n : undefined\n }\n className={cn(\n canResize && 'relative',\n // Per the design, a sortable header tints the whole\n // cell on hover/press, not just the inner sort button.\n // Suppressed while any column is resizing, since the\n // pointer drags across neighboring `<th>`s and would\n // otherwise tint them via native `:hover`.\n canSort &&\n !isAnyColumnResizing &&\n 'transition-colors hover:bg-[var(--ui-table-header-cell-color-hover)] active:bg-[var(--ui-table-header-cell-color-active)]',\n canReorder &&\n !isAnyColumnResizing &&\n 'cursor-grab select-none active:cursor-grabbing',\n canReorder &&\n draggedColumnId === header.column.id &&\n 'opacity-50',\n isPinned && headerPinnedBg\n )}\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n {canResize && (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={resizeColumnLabel}\n aria-valuenow={header.column.getSize()}\n aria-valuemin={\n header.column.columnDef.minSize ??\n DEFAULT_MIN_COLUMN_SIZE\n }\n aria-valuemax={\n header.column.columnDef.maxSize ??\n DEFAULT_MAX_COLUMN_SIZE\n }\n tabIndex={0}\n // Keeps a press on the handle from starting the header\n // cell's reorder drag instead of a resize when both\n // features are enabled.\n draggable={false}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n onKeyDown={(event) =>\n handleResizeKeyDown(event, header)\n }\n className={cn(\n 'absolute end-0 top-0 h-full w-1 cursor-(--ui-resizable-cursor) touch-none select-none bg-[var(--ui-table-global-row-border-color)] opacity-0 transition-[opacity,background-color] hover:bg-[var(--ui-resizable-border-color-hover)] hover:opacity-100 focus-visible:bg-[var(--ui-resizable-border-color-hover)] focus-visible:opacity-100 focus-visible:outline-[3px] focus-visible:outline-(--ui-focus-primary)',\n header.column.getIsResizing() &&\n 'bg-[var(--ui-resizable-border-color-active)] opacity-100'\n )}\n />\n )}\n </TableHead>\n );\n if (hints.length === 0) {\n return <Fragment key={header.id}>{headerCell}</Fragment>;\n }\n return (\n <Tooltip\n key={header.id}\n disabled={\n isAnyColumnResizing || draggedColumnId !== undefined\n }\n >\n {/* The whole header cell is the trigger (not just its sort\n button), so the hint covers the reorder/resize gestures\n that live on the cell itself. Disabled mid-drag/resize\n so the hint doesn't pop up over a neighboring cell\n while the pointer passes through it. */}\n <TooltipTrigger render={headerCell} />\n <TooltipContent className=\"flex flex-col gap-1\">\n {hints.map((hint) => (\n <span key={hint.label}>\n <span className=\"font-semibold\">{hint.label}:</span>{' '}\n {hint.action}\n </span>\n ))}\n </TooltipContent>\n </Tooltip>\n );\n })}\n </TableRow>\n ))}\n </TableHeader>\n </TooltipProvider>\n <TableBody>\n {skeleton ? (\n Array.from({ length: skeletonRows }).map((_, rowIndex) => (\n <TableRow\n key={`skeleton-${rowIndex}`}\n className=\"hover:bg-transparent\"\n >\n {table.getVisibleLeafColumns().map((column) => (\n <TableCell key={column.id}>\n <div className=\"h-4 w-full animate-pulse rounded bg-[var(--ui-background-surface-secondary)]\" />\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : rows?.length ? (\n rows.map((row, rowIndex) => {\n if (renderRow) {\n return (\n <Fragment key={row.id}>{renderRow(row, rowIndex)}</Fragment>\n );\n }\n const isSelected = row.getIsSelected();\n const isCurrent = highlightCurrentRow && currentRowId === row.id;\n // Opaque background applied to pinned cells so sibling cells don't\n // show through while the grid scrolls horizontally. Mirrors the\n // row's own resolved background across selection/current/stripe —\n // the idle case falls back to the real surface color\n // (`bg-background`) since the row's own idle token is transparent\n // by design (see `headerPinnedBg` above).\n // The idle case mirrors the row's own hover tint via `group` (see\n // the row's `group` class below) so the pinned action column\n // doesn't look \"stuck\" idle while the rest of the row is\n // hovered — the row's native `hover:` can't reach it since it\n // needs its own opaque background (see `headerPinnedBg` above).\n const rowBg =\n isSelected || isCurrent\n ? 'bg-[var(--ui-table-data-row-color-active)]'\n : striped && rowIndex % 2 === 1\n ? 'bg-[var(--ui-background-surface-secondary)]'\n : 'bg-background group-hover:bg-[var(--ui-table-data-row-color-hover)]';\n // While a selection is in play the action cell renders nothing and\n // carries no tint of its own, so suppressing the row's hover tint\n // for it would leave the pointer over a row that reacts to\n // nothing. Also covers a row hovered just before the selection\n // started, whose id is still in `actionHoveredRowId`.\n const isActionCellHovered =\n !bulkSelectionActive && actionHoveredRowId === row.id;\n return (\n <Fragment key={row.id}>\n <TableRow\n ref={(node) => {\n rowRefs.current[rowIndex] = node;\n }}\n tabIndex={rowIndex === activeRowIndex ? 0 : -1}\n onFocus={() => handleRowFocus(rowIndex)}\n onKeyDown={(event) => handleRowKeyDown(event, rowIndex)}\n selected={isSelected}\n onClick={\n highlightCurrentRow\n ? () => setCurrentRowId(row.id)\n : undefined\n }\n className={cn(\n 'group',\n highlightCurrentRow && 'cursor-pointer',\n striped &&\n rowIndex % 2 === 1 &&\n !isSelected &&\n !isCurrent &&\n 'bg-[var(--ui-background-surface-secondary)]',\n isCurrent &&\n !isSelected &&\n 'bg-[var(--ui-table-data-row-color-active)]',\n // The action cell's own hover tint (its ellipsis/cog\n // trigger) should be the only thing that reacts while\n // it's hovered — not the rest of the row underneath it.\n isActionCellHovered && 'hover:bg-transparent'\n )}\n >\n {row.getVisibleCells().map((cell) => {\n const isPinned = cell.column.getIsPinned();\n if (cell.column.id === '__actions') {\n return (\n <TableActionsCell\n key={cell.id}\n style={getCellStyle(cell, resizingEnabled)}\n className={rowBg}\n bulkSelectionActive={bulkSelectionActive}\n onMouseEnter={\n bulkSelectionActive\n ? undefined\n : () => setActionHoveredRowId(row.id)\n }\n onMouseLeave={\n bulkSelectionActive\n ? undefined\n : () =>\n setActionHoveredRowId((id) =>\n id === row.id ? undefined : id\n )\n }\n >\n {renderRowActions && (\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <ButtonIcon aria-label={rowActionsLabel} />\n }\n >\n <EllipsisIcon />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {renderRowActions(row)}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </TableActionsCell>\n );\n }\n return (\n <TableCell\n key={cell.id}\n wrap={cell.column.columnDef.meta?.wrap}\n style={getCellStyle(cell, resizingEnabled)}\n className={cn(isPinned && rowBg)}\n >\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext()\n )}\n </TableCell>\n );\n })}\n </TableRow>\n {renderExpandedRow && row.getIsExpanded() && (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell\n className=\"h-auto py-3\"\n colSpan={row.getVisibleCells().length}\n >\n {renderExpandedRow(row)}\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n );\n })\n ) : renderEmptyState ? (\n <TableRow>\n <TableCell\n colSpan={table.getVisibleLeafColumns().length}\n className=\"h-24 text-center\"\n >\n {renderEmptyState({\n hasFilters: table.getState().columnFilters.length > 0,\n })}\n </TableCell>\n </TableRow>\n ) : (\n <TableRow>\n <TableCell\n colSpan={table.getVisibleLeafColumns().length}\n className=\"h-24 text-center text-[var(--ui-table-data-value-color-disabled)]\"\n >\n {emptyLabel}\n </TableCell>\n </TableRow>\n )}\n {isInfiniteScroll && !skeleton && rows.length > 0 && hasNextPage && (\n <TableRow\n ref={sentinelRef}\n aria-hidden\n className=\"hover:bg-transparent\"\n >\n <TableCell\n colSpan={table.getVisibleLeafColumns().length}\n className=\"h-1 p-0\"\n />\n </TableRow>\n )}\n {isInfiniteScroll &&\n !skeleton &&\n rows.length > 0 &&\n isLoadingMore && (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell colSpan={table.getVisibleLeafColumns().length}>\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"h-4 w-full animate-pulse rounded bg-[var(--ui-background-surface-secondary)]\"\n >\n <span className=\"sr-only\">Loading more rows…</span>\n </div>\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n );\n}\n"],"names":["getPinnedStyle","column","pinned","getColumnWidth","enableColumnResizing","getHeaderStyle","header","pin","width","getCellStyle","cell","DEFAULT_MIN_COLUMN_SIZE","DEFAULT_MAX_COLUMN_SIZE","getResizeKeyboardStep","key","currentSize","shiftKey","min","max","step","reorderColumn","order","from","to","fromIndex","toIndex","next","DEFAULT_HEADER_HINTS","DataTable","columns","data","externalTable","getRowCanExpand","renderExpandedRow","striped","bordered","highlightCurrentRow","skeleton","skeletonRows","onColumnSizingChange","enableColumnReordering","controlledColumnOrder","onColumnOrderChange","controlledColumnVisibility","onColumnVisibilityChange","controlledRowSelection","onRowSelectionChange","manualSorting","controlledSorting","onSortingChange","renderRow","renderEmptyState","paginationMode","onLoadMore","loadMoreRootMargin","hasNextPage","resizeColumnLabel","emptyLabel","isLoadingMore","hideActionColumn","renderRowActions","rowActionsLabel","columnSettingsLabel","headerHints","resolvedHeaderHints","internalSorting","setInternalSorting","useState","sorting","columnFilters","setColumnFilters","internalColumnVisibility","setInternalColumnVisibility","columnVisibility","internalRowSelection","setInternalRowSelection","rowSelection","expanded","setExpanded","columnSizing","setColumnSizing","internalColumnOrder","setInternalColumnOrder","columnOrder","draggedColumnId","setDraggedColumnId","currentRowId","setCurrentRowId","focusedRowIndex","setFocusedRowIndex","rowRefs","useRef","handleColumnSizingChange","updater","handleColumnOrderChange","handleColumnVisibilityChange","handleSortingChange","handleRowSelectionChange","showActionColumn","actionColumns","useMemo","tableColumns","actionHoveredRowId","setActionHoveredRowId","internalTable","useReactTable","getCoreRowModel","getExpandedRowModel","getPaginationRowModel","getSortedRowModel","getFilteredRowModel","table","isInfiniteScroll","resizingEnabled","reorderingEnabled","isAnyColumnResizing","useEffect","sentinelRef","useIntersectionObserver","handleResizeKeyDown","event","nextSize","old","handleColumnDragStart","columnId","handleColumnDragOver","handleColumnDrop","targetColumnId","current","base","_a","rows","bulkSelectionActive","isBulkSelectionActive","activeRowIndex","handleRowFocus","rowIndex","handleRowKeyDown","nextIndex","borderedClass","headerPinnedBg","jsx","cn","jsxs","Table","TooltipProvider","TableHeader","headerGroup","TableRow","isPinned","canResize","canReorder","canSort","hints","hint","TableSettingsCell","DataTableViewOptions","headerCell","TableHead","flexRender","Fragment","Tooltip","TooltipTrigger","TooltipContent","TableBody","_","TableCell","row","isSelected","isCurrent","rowBg","isActionCellHovered","node","TableActionsCell","id","DropdownMenu","DropdownMenuTrigger","ButtonIcon","EllipsisIcon","DropdownMenuContent"],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { jsx as a, jsxs as l } from "react/jsx-runtime";
2
+ import * as u from "react";
3
+ import { cva as s } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
4
+ import { cn as t } from "../../../lib/utils.js";
5
+ const f = s(
6
+ "flex size-16 shrink-0 items-center justify-center rounded-full [&>svg]:size-6",
7
+ {
8
+ variants: {
9
+ color: {
10
+ teal: "bg-[var(--ui-avatar-color-teal)] text-[var(--ui-avatar-label-color-teal)]",
11
+ violet: "bg-[var(--ui-avatar-color-violet)] text-[var(--ui-avatar-label-color-violet)]",
12
+ red: "bg-[var(--ui-avatar-color-red)] text-[var(--ui-avatar-label-color-red)]",
13
+ yellow: "bg-[var(--ui-avatar-color-yellow)] text-[var(--ui-avatar-label-color-yellow)]",
14
+ orange: "bg-[var(--ui-avatar-color-orange)] text-[var(--ui-avatar-label-color-orange)]",
15
+ blue: "bg-[var(--ui-avatar-color-blue)] text-[var(--ui-avatar-label-color-blue)]",
16
+ gray: "bg-[var(--ui-avatar-color-gray)] text-[var(--ui-avatar-label-color-gray)]",
17
+ green: "bg-[var(--ui-avatar-color-green)] text-[var(--ui-avatar-label-color-green)]"
18
+ }
19
+ },
20
+ defaultVariants: {
21
+ color: "green"
22
+ }
23
+ }
24
+ ), m = u.forwardRef(
25
+ ({ className: o, icon: e, title: i, description: r, color: v, ...c }, n) => /* @__PURE__ */ a(
26
+ "div",
27
+ {
28
+ ref: n,
29
+ className: t(
30
+ "flex size-full flex-col items-center justify-center overflow-hidden bg-linear-to-b from-transparent to-muted to-[51.481%] p-12 text-center",
31
+ o
32
+ ),
33
+ ...c,
34
+ children: /* @__PURE__ */ l("div", { className: "flex w-full max-w-lg flex-col items-center justify-center gap-3", children: [
35
+ e ? /* @__PURE__ */ a("div", { className: t(f({ color: v })), children: e }) : null,
36
+ /* @__PURE__ */ l("div", { className: "flex w-full flex-col items-center gap-1", children: [
37
+ /* @__PURE__ */ a("h3", { className: "w-full text-2xl font-normal leading-8 text-foreground", children: i }),
38
+ r ? /* @__PURE__ */ a("p", { className: "w-full text-sm leading-6 text-muted-foreground", children: r }) : null
39
+ ] })
40
+ ] })
41
+ }
42
+ )
43
+ );
44
+ m.displayName = "EmptyOverlay";
45
+ export {
46
+ m as EmptyOverlay,
47
+ f as emptyOverlayIconVariants
48
+ };
49
+ //# sourceMappingURL=empty-overlay.js.map