@carto/ps-react-ui 4.22.0 → 4.24.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 (121) hide show
  1. package/dist/actions-B1ss030_.js +1167 -0
  2. package/dist/actions-B1ss030_.js.map +1 -0
  3. package/dist/category-Ca5XDx0N.js +839 -0
  4. package/dist/category-Ca5XDx0N.js.map +1 -0
  5. package/dist/{download-C7he8mSh.js → download--wRRnf19.js} +81 -80
  6. package/dist/download--wRRnf19.js.map +1 -0
  7. package/dist/{echart-BnJYXH7H.js → echart-CgOQw9XB.js} +3 -2
  8. package/dist/echart-CgOQw9XB.js.map +1 -0
  9. package/dist/{formula-Cqj84ZGX.js → formula-DRuMIVo8.js} +6 -6
  10. package/dist/formula-DRuMIVo8.js.map +1 -0
  11. package/dist/legend.js +34 -21
  12. package/dist/legend.js.map +1 -1
  13. package/dist/{markdown-CV_KP-at.js → markdown-C3OX9jyy.js} +6 -6
  14. package/dist/markdown-C3OX9jyy.js.map +1 -0
  15. package/dist/{spread-C8T12Nfh.js → spread-BT07rCJw.js} +7 -7
  16. package/dist/spread-BT07rCJw.js.map +1 -0
  17. package/dist/{table-CNQijNNB.js → table-CRG9eOs9.js} +3 -3
  18. package/dist/table-CRG9eOs9.js.map +1 -0
  19. package/dist/types/legend/stores/types.d.ts +4 -2
  20. package/dist/types/widgets-v2/actions/download/csv-item.d.ts +3 -3
  21. package/dist/types/widgets-v2/actions/download/index.d.ts +1 -1
  22. package/dist/types/widgets-v2/actions/download/png-item.d.ts +2 -2
  23. package/dist/types/widgets-v2/actions/download/types.d.ts +12 -1
  24. package/dist/types/widgets-v2/actions/fullscreen/fullscreen.d.ts +20 -13
  25. package/dist/types/widgets-v2/actions/index.d.ts +1 -1
  26. package/dist/types/widgets-v2/actions/searcher/filter.d.ts +3 -2
  27. package/dist/types/widgets-v2/bar/download.d.ts +3 -3
  28. package/dist/types/widgets-v2/category/category-ui.d.ts +9 -1
  29. package/dist/types/widgets-v2/category/download.d.ts +3 -3
  30. package/dist/types/widgets-v2/echart/style.d.ts +1 -0
  31. package/dist/types/widgets-v2/formula/download.d.ts +3 -3
  32. package/dist/types/widgets-v2/histogram/download.d.ts +3 -3
  33. package/dist/types/widgets-v2/index.d.ts +1 -1
  34. package/dist/types/widgets-v2/markdown/download.d.ts +3 -3
  35. package/dist/types/widgets-v2/pie/download.d.ts +3 -3
  36. package/dist/types/widgets-v2/scatterplot/download.d.ts +3 -3
  37. package/dist/types/widgets-v2/spread/download.d.ts +3 -3
  38. package/dist/types/widgets-v2/table/download.d.ts +3 -3
  39. package/dist/types/widgets-v2/timeseries/download.d.ts +3 -3
  40. package/dist/types/widgets-v2/toolbox/toolbox.d.ts +1 -1
  41. package/dist/types/widgets-v2/wrapper/style.d.ts +31 -2
  42. package/dist/types/widgets-v2/wrapper/widget-actions.d.ts +2 -2
  43. package/dist/types/widgets-v2/wrapper/widget-wrapper.d.ts +2 -2
  44. package/dist/widgets-v2/actions.js +2 -2
  45. package/dist/widgets-v2/bar.js +7 -7
  46. package/dist/widgets-v2/bar.js.map +1 -1
  47. package/dist/widgets-v2/category.js +1 -1
  48. package/dist/widgets-v2/echart.js +1 -1
  49. package/dist/widgets-v2/formula.js +1 -1
  50. package/dist/widgets-v2/histogram.js +10 -10
  51. package/dist/widgets-v2/histogram.js.map +1 -1
  52. package/dist/widgets-v2/markdown.js +1 -1
  53. package/dist/widgets-v2/pie.js +10 -10
  54. package/dist/widgets-v2/pie.js.map +1 -1
  55. package/dist/widgets-v2/scatterplot.js +9 -9
  56. package/dist/widgets-v2/scatterplot.js.map +1 -1
  57. package/dist/widgets-v2/spread.js +1 -1
  58. package/dist/widgets-v2/table.js +1 -1
  59. package/dist/widgets-v2/timeseries.js +12 -12
  60. package/dist/widgets-v2/timeseries.js.map +1 -1
  61. package/dist/widgets-v2.js +364 -376
  62. package/dist/widgets-v2.js.map +1 -1
  63. package/package.json +3 -3
  64. package/src/legend/components/legend-item/legend-item-ui.test.tsx +22 -1
  65. package/src/legend/components/legend-ramp/legend-ramp-ui.tsx +22 -6
  66. package/src/legend/stores/types.ts +6 -11
  67. package/src/widgets-v2/actions/download/csv-item.test.tsx +3 -3
  68. package/src/widgets-v2/actions/download/csv-item.tsx +6 -6
  69. package/src/widgets-v2/actions/download/download.tsx +5 -3
  70. package/src/widgets-v2/actions/download/index.ts +1 -1
  71. package/src/widgets-v2/actions/download/png-item.test.tsx +5 -3
  72. package/src/widgets-v2/actions/download/png-item.tsx +4 -4
  73. package/src/widgets-v2/actions/download/types.ts +15 -1
  74. package/src/widgets-v2/actions/fullscreen/fullscreen-store.test.tsx +155 -0
  75. package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +39 -41
  76. package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +211 -96
  77. package/src/widgets-v2/actions/index.ts +1 -0
  78. package/src/widgets-v2/actions/searcher/filter.test.ts +28 -0
  79. package/src/widgets-v2/actions/searcher/filter.ts +22 -4
  80. package/src/widgets-v2/actions/searcher/searcher-toggle.tsx +9 -4
  81. package/src/widgets-v2/actions/searcher/searcher.test.tsx +22 -0
  82. package/src/widgets-v2/actions/searcher/searcher.tsx +17 -2
  83. package/src/widgets-v2/bar/download.test.tsx +5 -3
  84. package/src/widgets-v2/bar/download.tsx +5 -4
  85. package/src/widgets-v2/category/category-ui.tsx +20 -9
  86. package/src/widgets-v2/category/category.tsx +37 -2
  87. package/src/widgets-v2/category/download.test.ts +4 -2
  88. package/src/widgets-v2/category/download.ts +5 -4
  89. package/src/widgets-v2/echart/style.ts +6 -0
  90. package/src/widgets-v2/formula/download.test.tsx +3 -1
  91. package/src/widgets-v2/formula/download.tsx +5 -4
  92. package/src/widgets-v2/histogram/download.test.ts +6 -4
  93. package/src/widgets-v2/histogram/download.ts +5 -4
  94. package/src/widgets-v2/index.ts +1 -0
  95. package/src/widgets-v2/markdown/download.test.ts +2 -2
  96. package/src/widgets-v2/markdown/download.tsx +5 -4
  97. package/src/widgets-v2/pie/download.test.ts +7 -3
  98. package/src/widgets-v2/pie/download.ts +5 -4
  99. package/src/widgets-v2/scatterplot/download.test.ts +4 -2
  100. package/src/widgets-v2/scatterplot/download.ts +5 -4
  101. package/src/widgets-v2/spread/download.test.ts +3 -1
  102. package/src/widgets-v2/spread/download.ts +5 -4
  103. package/src/widgets-v2/table/download.test.ts +5 -3
  104. package/src/widgets-v2/table/download.ts +4 -3
  105. package/src/widgets-v2/timeseries/download.test.ts +6 -4
  106. package/src/widgets-v2/timeseries/download.ts +5 -4
  107. package/src/widgets-v2/toolbox/toolbox.tsx +1 -1
  108. package/src/widgets-v2/wrapper/style.ts +38 -2
  109. package/src/widgets-v2/wrapper/widget-actions.tsx +2 -2
  110. package/src/widgets-v2/wrapper/widget-wrapper.test.tsx +32 -2
  111. package/src/widgets-v2/wrapper/widget-wrapper.tsx +58 -32
  112. package/dist/actions-iN1jwyxA.js +0 -1024
  113. package/dist/actions-iN1jwyxA.js.map +0 -1
  114. package/dist/category-DZt6yiST.js +0 -826
  115. package/dist/category-DZt6yiST.js.map +0 -1
  116. package/dist/download-C7he8mSh.js.map +0 -1
  117. package/dist/echart-BnJYXH7H.js.map +0 -1
  118. package/dist/formula-Cqj84ZGX.js.map +0 -1
  119. package/dist/markdown-CV_KP-at.js.map +0 -1
  120. package/dist/spread-C8T12Nfh.js.map +0 -1
  121. package/dist/table-CNQijNNB.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { S as e, T as t } from "./stores-BVFMfgyo.js";
2
2
  import { t as n } from "./markdown-content-BzKoX3eu.js";
3
- import { a as r, n as i, r as a } from "./download-C7he8mSh.js";
3
+ import { a as r, n as i, r as a } from "./download--wRRnf19.js";
4
4
  import { c as o } from "react/compiler-runtime";
5
5
  import { Box as s, Skeleton as c, Typography as l } from "@mui/material";
6
6
  import { jsx as u } from "react/jsx-runtime";
@@ -149,12 +149,12 @@ function y(e) {
149
149
  id: a.markdown,
150
150
  label: "Markdown",
151
151
  icon: /* @__PURE__ */ u(r, { fontSize: "small" }),
152
- resolve: () => {
153
- let t = e.getData(), n = new Blob([t.content ?? ""], { type: "text/markdown;charset=utf-8;" }), r = URL.createObjectURL(n);
152
+ resolve: (t) => {
153
+ let n = e.getData(t), r = new Blob([n.content ?? ""], { type: "text/markdown;charset=utf-8;" }), i = URL.createObjectURL(r);
154
154
  return Promise.resolve({
155
- url: r,
155
+ url: i,
156
156
  filename: `${e.filename}.md`,
157
- revoke: () => URL.revokeObjectURL(r)
157
+ revoke: () => URL.revokeObjectURL(i)
158
158
  });
159
159
  }
160
160
  }), t;
@@ -162,4 +162,4 @@ function y(e) {
162
162
  //#endregion
163
163
  export { m as i, v as n, h as r, y as t };
164
164
 
165
- //# sourceMappingURL=markdown-CV_KP-at.js.map
165
+ //# sourceMappingURL=markdown-C3OX9jyy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-C3OX9jyy.js","names":["SxProps","Theme","styles","root","color","bgcolor","px","borderRadius","fontFamily","fontSize","p","overflowX","borderLeft","borderColor","pl","ml","fontStyle","my","border","borderTop","borderCollapse","width","py","textAlign","paragraph","heading","mt","mb","fontWeight","Record","Box","Typography","TypographyProps","Components","MarkdownContent","styles","MarkdownUIProps","content","components","h1","props","mdHeading","h2","h3","h4","h5","h6","p","children","paragraph","React","ReactNode","variant","heading","MarkdownUI","t0","$","_c","t1","root","useWidgetId","useWidget","MarkdownUI","MarkdownWidgetData","Markdown","$","_c","id","content","_temp","t0","s","data","Box","Skeleton","SxProps","Theme","styles","root","display","flexDirection","gap","py","line","width","height","const","MarkdownSkeletonProps","lines","MarkdownSkeleton","t0","$","_c","t1","undefined","t2","widths","Array","from","length","map","_","i","DOWNLOAD_ITEM_IDS","MarkdownIcon","buildPngDownloadItem","toCsvString","triggerLinkDownload","DownloadContext","DownloadItem","MarkdownWidgetData","createMarkdownDownloadConfig","args","filename","getData","ctx","getCaptureEl","HTMLElement","pngPixelRatio","pngBackgroundColor","items","push","pixelRatio","backgroundColor","id","markdown","label","icon","resolve","data","blob","Blob","content","type","url","URL","createObjectURL","Promise","revoke","revokeObjectURL"],"sources":["../src/widgets-v2/markdown/style.ts","../src/widgets-v2/markdown/markdown-ui.tsx","../src/widgets-v2/markdown/markdown.tsx","../src/widgets-v2/markdown/skeleton.tsx","../src/widgets-v2/markdown/download.tsx"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material'\n\nexport const styles = {\n root: {\n color: 'text.primary',\n '& a': { color: 'primary.main' },\n '& code': {\n bgcolor: 'action.hover',\n px: 0.5,\n borderRadius: 0.5,\n fontFamily: 'monospace',\n fontSize: '0.875em',\n },\n '& pre': {\n bgcolor: 'action.hover',\n p: 1.5,\n borderRadius: 1,\n overflowX: 'auto',\n },\n '& blockquote': {\n borderLeft: '3px solid',\n borderColor: 'divider',\n pl: 1.5,\n ml: 0,\n color: 'text.secondary',\n fontStyle: 'italic',\n },\n '& ul, & ol': { pl: 3, my: 1 },\n '& li': { my: 0.25 },\n '& hr': {\n border: 'none',\n borderTop: '1px solid',\n borderColor: 'divider',\n my: 1.5,\n },\n '& table': { borderCollapse: 'collapse', width: '100%' },\n '& th, & td': {\n border: '1px solid',\n borderColor: 'divider',\n px: 1,\n py: 0.5,\n textAlign: 'left',\n },\n },\n paragraph: {\n my: 1,\n },\n heading: {\n mt: 2,\n mb: 1,\n fontWeight: 600,\n },\n} satisfies Record<string, SxProps<Theme>>\n","import { Box, Typography, type TypographyProps } from '@mui/material'\nimport type { Components } from 'react-markdown'\nimport { MarkdownContent } from './markdown-content'\nimport { styles } from './style'\n\nexport interface MarkdownUIProps {\n content: string\n}\n\n/** MUI-styled element mapping for `react-markdown`. */\nconst components: Components = {\n h1: (props) => mdHeading(props, 'h4'),\n h2: (props) => mdHeading(props, 'h5'),\n h3: (props) => mdHeading(props, 'h6'),\n h4: (props) => mdHeading(props, 'subtitle1'),\n h5: (props) => mdHeading(props, 'subtitle2'),\n h6: (props) => mdHeading(props, 'subtitle2'),\n p: ({ children }) => (\n <Typography variant='body2' component='p' sx={styles.paragraph}>\n {children}\n </Typography>\n ),\n}\n\nfunction mdHeading(\n props: { children?: React.ReactNode },\n variant: TypographyProps['variant'],\n) {\n return (\n <Typography variant={variant} component='div' sx={styles.heading}>\n {props.children}\n </Typography>\n )\n}\n\n/**\n * Pure presentational component for the Markdown widget. Delegates the\n * `react-markdown` engine to {@link MarkdownContent} and supplies a\n * document-style MUI element mapping (body2 paragraphs, real heading\n * typography). Opts INTO raw HTML and inline images — the Markdown widget is\n * the one slot in the library where authors can ship rich content. Caption\n * slots like `Note` keep the conservative defaults.\n */\nexport function MarkdownUI({ content }: MarkdownUIProps) {\n return (\n <Box sx={styles.root}>\n <MarkdownContent\n content={content}\n components={components}\n allowHtml\n allowImages\n />\n </Box>\n )\n}\n","import { useWidgetId, useWidget } from '../stores'\nimport { MarkdownUI } from './markdown-ui'\nimport type { MarkdownWidgetData } from './types'\n\n/**\n * Stateful Markdown bridge — reads `data.content` (post-pipeline) from the\n * per-widget store and forwards it to the pure {@link MarkdownUI}. Sits\n * inside `<Widget.Provider>`.\n */\nexport function Markdown() {\n const id = useWidgetId()\n const content = useWidget(id, (s) => {\n const data = s.data as MarkdownWidgetData | undefined\n return data?.content ?? ''\n })\n return <MarkdownUI content={content} />\n}\n","import { Box, Skeleton } from '@mui/material'\nimport type { SxProps, Theme } from '@mui/material'\n\nconst styles = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n py: 1,\n },\n line: (width: string): SxProps<Theme> => ({ width, height: 18 }),\n} as const\n\nexport interface MarkdownSkeletonProps {\n lines?: number\n}\n\nexport function MarkdownSkeleton({ lines = 5 }: MarkdownSkeletonProps) {\n // Vary widths to mimic prose.\n const widths = ['100%', '95%', '90%', '85%', '70%']\n return (\n <Box sx={styles.root}>\n {Array.from({ length: lines }).map((_, i) => (\n <Skeleton\n key={`line-${i}`}\n variant='rectangular'\n sx={styles.line(widths[i % widths.length] ?? '85%')}\n />\n ))}\n </Box>\n )\n}\n","import {\n DOWNLOAD_ITEM_IDS,\n MarkdownIcon,\n buildPngDownloadItem,\n toCsvString,\n triggerLinkDownload,\n type DownloadContext,\n type DownloadItem,\n} from '../actions/download'\nimport type { MarkdownWidgetData } from './types'\n\n/**\n * Download menu items for the Markdown widget. Always includes a `.md`\n * item that saves the markdown source verbatim. When `getCaptureEl` is\n * supplied, prepends a PNG item that rasterises the captured element via\n * `html2canvas`.\n */\nexport function createMarkdownDownloadConfig(args: {\n filename: string\n getData: (ctx: DownloadContext) => MarkdownWidgetData\n getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null\n pngPixelRatio?: number\n pngBackgroundColor?: string | null\n}): DownloadItem[] {\n const items: DownloadItem[] = []\n if (args.getCaptureEl) {\n items.push(\n buildPngDownloadItem({\n filename: args.filename,\n getCaptureEl: args.getCaptureEl,\n pixelRatio: args.pngPixelRatio,\n backgroundColor: args.pngBackgroundColor,\n }),\n )\n }\n items.push({\n id: DOWNLOAD_ITEM_IDS.markdown,\n label: 'Markdown',\n icon: <MarkdownIcon fontSize='small' />,\n resolve: (ctx) => {\n const data = args.getData(ctx)\n const blob = new Blob([data.content ?? ''], {\n type: 'text/markdown;charset=utf-8;',\n })\n const url = URL.createObjectURL(blob)\n return Promise.resolve({\n url,\n filename: `${args.filename}.md`,\n revoke: () => URL.revokeObjectURL(url),\n })\n },\n })\n return items\n}\n\n// Re-export pure helpers consumers may want when building a custom Download item.\nexport { toCsvString, triggerLinkDownload }\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { C as e, T as t } from "./stores-BVFMfgyo.js";
2
- import { n, t as r } from "./download-C7he8mSh.js";
3
- import { a as i, c as a, l as o, o as s, s as c, u as l } from "./formula-Cqj84ZGX.js";
2
+ import { n, t as r } from "./download--wRRnf19.js";
3
+ import { a as i, c as a, l as o, o as s, s as c, u as l } from "./formula-DRuMIVo8.js";
4
4
  import { c as u } from "react/compiler-runtime";
5
5
  import { Box as d, Skeleton as f } from "@mui/material";
6
6
  import { jsx as p, jsxs as m } from "react/jsx-runtime";
@@ -113,8 +113,8 @@ function w(e) {
113
113
  backgroundColor: e.pngBackgroundColor
114
114
  })), t.push(r({
115
115
  filename: e.filename,
116
- getRows: () => {
117
- let t = e.getData(), n = [[
116
+ getRows: (t) => {
117
+ let n = e.getData(t), r = [[
118
118
  "series",
119
119
  "prefix",
120
120
  "min",
@@ -122,7 +122,7 @@ function w(e) {
122
122
  "suffix",
123
123
  "note"
124
124
  ]];
125
- for (let e of t) n.push([
125
+ for (let e of n) r.push([
126
126
  e.series?.name ?? "",
127
127
  e.prefix ?? "",
128
128
  e.min,
@@ -130,7 +130,7 @@ function w(e) {
130
130
  e.suffix ?? "",
131
131
  e.note ?? ""
132
132
  ]);
133
- return n;
133
+ return r;
134
134
  }
135
135
  })), t;
136
136
  }
@@ -146,4 +146,4 @@ function T({ value: e, spread: t, variant: n = "percentage" }) {
146
146
  //#endregion
147
147
  export { g as a, b as i, w as n, h as o, S as r, T as t };
148
148
 
149
- //# sourceMappingURL=spread-C8T12Nfh.js.map
149
+ //# sourceMappingURL=spread-BT07rCJw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spread-BT07rCJw.js","names":["Value","Separator","$","_c","t0","Symbol","for","Box","Ref","Note","Prefix","Series","Suffix","Value","styles","Separator","SpreadDataItem","SpreadUIProps","items","formatter","value","ref","HTMLDivElement","SpreadUI","t0","$","_c","fmt","_temp","t1","t2","item","i","series","name","min","max","row","color","body","valueRow","prefix","suffix","note","map","root","n","String","useWidgetId","useWidgetShallow","SpreadUI","SpreadWidgetData","SpreadSlice","data","formatter","value","EMPTY_DATA","Object","freeze","spreadSelector","s","Spread","$","_c","id","slice","t0","Box","Skeleton","SxProps","Theme","styles","root","display","flexDirection","gap","py","row","alignItems","block","width","height","Record","SpreadSkeletonProps","count","SpreadSkeleton","t0","$","_c","t1","undefined","t2","Array","from","length","map","_temp","_","i","buildCsvDownloadItem","buildPngDownloadItem","DownloadContext","DownloadItem","SpreadWidgetData","createSpreadDownloadConfig","args","filename","getData","ctx","getCaptureEl","HTMLElement","pngPixelRatio","pngBackgroundColor","items","push","pixelRatio","backgroundColor","getRows","data","rows","item","series","name","prefix","min","max","suffix","note","SpreadVariant","GetSpreadBandOptions","value","spread","variant","getSpreadBand","min","max","offset","width","Math","abs"],"sources":["../src/widgets-v2/spread/separator.tsx","../src/widgets-v2/spread/spread-ui.tsx","../src/widgets-v2/spread/spread.tsx","../src/widgets-v2/spread/skeleton.tsx","../src/widgets-v2/spread/download.ts","../src/widgets-v2/spread/band.ts"],"sourcesContent":["import { Value } from '../formula'\n\n/**\n * Em-dash separator placed between a Spread row's `min` and `max` values.\n * Built from the Formula {@link Value} primitive so typography (h5/600,\n * baseline alignment) matches the numbers around it. Renders with\n * `text.secondary` so it visually recedes between the two bounds.\n */\nexport function Separator() {\n return <Value color='inherit'>-</Value>\n}\n","import { Box } from '@mui/material'\nimport type { Ref } from 'react'\nimport { Note, Prefix, Series, Suffix, Value } from '../formula'\nimport { styles } from '../formula/style'\nimport { Separator } from './separator'\nimport type { SpreadDataItem } from './types'\n\nexport interface SpreadUIProps {\n items: readonly SpreadDataItem[]\n /** Number formatter — applied to each item's `min` and `max`. */\n formatter?: (value: number) => string\n /** Forwarded to the root `<Box>` so consumers can capture the DOM (PNG export). */\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * Pure presentational component for the Spread widget. Each item renders as\n * a row containing (in order): optional `Series` avatar, a body with\n * `[prefix] min — max [suffix]` plus optional `Note`. Reuses the Formula\n * primitives ({@link Series}, {@link Prefix}, {@link Value}, {@link Suffix},\n * {@link Note}) and the Formula row styles so Spread and Formula stay\n * visually aligned when used together.\n */\nexport function SpreadUI({ items, formatter, ref }: SpreadUIProps) {\n const fmt = formatter ?? ((n: number) => String(n))\n return (\n <Box ref={ref} sx={styles.root}>\n {items.map((item, i) => (\n // Composite of series name + min/max bounds for stability across\n // reorders; falls back to the index when bounds happen to collide.\n <Box\n key={`spread-${item.series?.name ?? ''}-${item.min}-${item.max}-${i}`}\n sx={styles.row}\n >\n {item.series ? (\n <Series name={item.series.name} color={item.series.color} />\n ) : null}\n <Box sx={styles.body}>\n <Box sx={styles.valueRow}>\n {item.prefix ? <Prefix>{item.prefix}</Prefix> : null}\n <Value color={item.color}>{fmt(item.min)}</Value>\n <Separator />\n <Value color={item.color}>{fmt(item.max)}</Value>\n {item.suffix ? <Suffix>{item.suffix}</Suffix> : null}\n </Box>\n {item.note ? <Note>{item.note}</Note> : null}\n </Box>\n </Box>\n ))}\n </Box>\n )\n}\n","import { useWidgetId, useWidgetShallow } from '../stores'\nimport { SpreadUI } from './spread-ui'\nimport type { SpreadWidgetData } from './types'\n\ninterface SpreadSlice {\n data: SpreadWidgetData\n formatter?: (value: number) => string\n}\n\n// Stable empty-data sentinel — keeps the slice's `data` reference stable\n// when the underlying store value is null/undefined so the shallow-equality\n// gate in `useWidgetShallow` doesn't re-render every commit.\nconst EMPTY_DATA: SpreadWidgetData = Object.freeze([]) as SpreadWidgetData\n\nconst spreadSelector = (s: {\n data: unknown\n formatter?: (value: number) => string\n}): SpreadSlice => ({\n data: (s.data ?? EMPTY_DATA) as SpreadWidgetData,\n formatter: s.formatter,\n})\n\n/**\n * Stateful Spread bridge — reads `data` (post-pipeline) and `formatter` from\n * the per-widget store and forwards them to the pure {@link SpreadUI}.\n */\nexport function Spread() {\n const id = useWidgetId()\n const slice = useWidgetShallow(id, spreadSelector)\n return <SpreadUI items={slice.data} formatter={slice.formatter} />\n}\n","import { Box, Skeleton } from '@mui/material'\nimport type { SxProps, Theme } from '@mui/material'\n\nconst styles = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n py: 1,\n },\n row: {\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n },\n block: { width: 200, height: 32 },\n} satisfies Record<string, SxProps<Theme>>\n\nexport interface SpreadSkeletonProps {\n count?: number\n}\n\n/**\n * Loading placeholder for the Spread widget. Renders `count` rows, each\n * sized for the `min — max` pair so the layout doesn't jump once data\n * resolves. Mirrors the row-per-item structure of {@link SpreadUI}.\n */\nexport function SpreadSkeleton({ count = 1 }: SpreadSkeletonProps) {\n return (\n <Box sx={styles.root}>\n {Array.from({ length: count }).map((_, i) => (\n <Box key={`row-${i}`} sx={styles.row}>\n <Skeleton variant='rectangular' sx={styles.block} />\n </Box>\n ))}\n </Box>\n )\n}\n","import {\n buildCsvDownloadItem,\n buildPngDownloadItem,\n type DownloadContext,\n type DownloadItem,\n} from '../actions/download'\nimport type { SpreadWidgetData } from './types'\n\n/**\n * Download menu items for the Spread widget. Always includes a CSV item\n * with `series, prefix, min, max, suffix, note` columns (one row per\n * entry). When `getCaptureEl` is supplied, prepends a PNG item that\n * rasterises the captured element via `html2canvas`.\n */\nexport function createSpreadDownloadConfig(args: {\n filename: string\n getData: (ctx: DownloadContext) => SpreadWidgetData\n getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null\n pngPixelRatio?: number\n pngBackgroundColor?: string | null\n}): DownloadItem[] {\n const items: DownloadItem[] = []\n if (args.getCaptureEl) {\n items.push(\n buildPngDownloadItem({\n filename: args.filename,\n getCaptureEl: args.getCaptureEl,\n pixelRatio: args.pngPixelRatio,\n backgroundColor: args.pngBackgroundColor,\n }),\n )\n }\n items.push(\n buildCsvDownloadItem({\n filename: args.filename,\n getRows: (ctx) => {\n const data = args.getData(ctx)\n const rows: unknown[][] = [\n ['series', 'prefix', 'min', 'max', 'suffix', 'note'],\n ]\n for (const item of data) {\n rows.push([\n item.series?.name ?? '',\n item.prefix ?? '',\n item.min,\n item.max,\n item.suffix ?? '',\n item.note ?? '',\n ])\n }\n return rows\n },\n }),\n )\n return items\n}\n","/**\n * How a `spread` amount is applied to a centre value.\n *\n * - `percentage` — `spread` is a whole-number percentage of the centre\n * value, so `5` means +/-5%.\n * - `absolute` — `spread` is a raw offset in the value's own units.\n */\nexport type SpreadVariant = 'percentage' | 'absolute'\n\nexport interface GetSpreadBandOptions {\n /** The centre value the band is drawn around. */\n value: number\n /** Half-width of the band, read according to `variant`. */\n spread: number\n /** Defaults to `percentage`. */\n variant?: SpreadVariant\n}\n\n/**\n * Derives the `min` / `max` band around a centre value, for feeding a\n * {@link SpreadDataItem} from a single aggregated number (a prediction, a\n * target) plus a tolerance — rather than from a real column range.\n *\n * `spread` is read as a percentage by default, which is what a tolerance\n * almost always is: an absolute offset is meaningless without knowing the\n * value's magnitude, and gets visually lost on large values (+/-5 on a\n * prediction of 204,113 renders as a range indistinguishable from a single\n * number).\n *\n * @example\n * getSpreadBand({ value: 1000, spread: 5 })\n * // -> { min: 950, max: 1050 }\n * getSpreadBand({ value: 1000, spread: 5, variant: 'absolute' })\n * // -> { min: 995, max: 1005 }\n */\nexport function getSpreadBand({\n value,\n spread,\n variant = 'percentage',\n}: GetSpreadBandOptions): { min: number; max: number } {\n const offset = variant === 'absolute' ? spread : (spread / 100) * value\n // Keep `min <= max`: a percentage of a negative centre value (or a negative\n // `spread`) yields a negative offset, which would invert the band.\n const width = Math.abs(offset)\n\n return { min: value - width, max: value + width }\n}\n"],"mappings":";;;;;;;AAQA,SAAOC,IAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GAAAC;CACkC,OADlCF,EAAA,OAAAG,OAAAC,IAAA,2BAAA,KACEF,IAAA,kBAAC,GAAD;EAAa,OAAA;EAAU,UAAA;CAAjB,CAAA,GAA0BF,EAAA,KAAAE,KAAAA,IAAAF,EAAA,IAAhCE;AAAgC;;;ACczC,SAAOmB,EAAAC,GAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GAAkB,EAAAR,UAAAC,cAAAE,WAAAG,GACvBG,IAAYR,KAAAS,GAAuCC;CAAA,IAAAJ,EAAA,OAAAE,KAAAF,EAAA,OAAAP,GAAA;EAAA,IAAAY;EAwB7CL,AAxB6CA,EAAA,OAAAE,IAwB9CG,IAAAL,EAAA,MArBUK,KAAAC,GAAAC,MAGT,kBAAC,GAAD;GAEM,IAAAlB,EAAMuB;GAFZ,UAAA,CAIGN,EAAIE,SACH,kBAAC,GAAD;IAAc,MAAAF,EAAIE,OAAOC;IAAc,OAAAH,EAAIE,OAAOK;GAAM,CAAA,IADzD,MAGD,kBAAC,GAAD;IAAS,IAAAxB,EAAMyB;IAAf,UAAA,CACE,kBAAC,GAAD;KAAS,IAAAzB,EAAM0B;KAAf,UAAA;MACGT,EAAIU,SAAU,kBAAC,GAAD,EAAA,UAASV,EAAIU,OAAN,CAAA,IAArB;MACD,kBAAC,GAAD;OAAc,OAAAV,EAAIO;OAASX,UAAAA,EAAII,EAAII,GAAI;MAAjC,CAAA;MACN,kBAAC,GAAD,CAAU,CAAA;MACV,kBAAC,GAAD;OAAc,OAAAJ,EAAIO;OAASX,UAAAA,EAAII,EAAIK,GAAI;MAAjC,CAAA;MACLL,EAAIW,SAAU,kBAAC,GAAD,EAAA,UAASX,EAAIW,OAAN,CAAA,IAArB;KALC;IAOHX,CAAAA,GAAAA,EAAIY,OAAQ,kBAAC,GAAD,EAAA,UAAOZ,EAAIY,KAAN,CAAA,IAAjB,IARC;GAPF,CAAA,CAAA;EACG,GAAA,UAAUZ,EAAIE,QAAaC,QAAjB,GAAuB,GAAIH,EAAII,IAAI,GAAIJ,EAAIK,IAAI,GAAIJ,GADhE,GAkBLP,EAAA,KAAAE,GAAAF,EAAA,KAAAK,IArBAD,IAAAX,EAAK0B,IAAKd,CAqBV,GAACL,EAAA,KAAAE,GAAAF,EAAA,KAAAP,GAAAO,EAAA,KAAAI;CAAA,OAAAA,IAAAJ,EAAA;CAAA,IAAAK;CACE,OADFL,EAAA,OAAAJ,KAAAI,EAAA,OAAAI,KAtBJC,IAAA,kBAAC,GAAD;EAAUT;EAAS,IAAAP,EAAM+B;EACtBhB,UAAAA;CADC,CAAA,GAuBEJ,EAAA,KAAAJ,GAAAI,EAAA,KAAAI,GAAAJ,EAAA,KAAAK,KAAAA,IAAAL,EAAA,IAvBNK;AAuBM;AA1BH,SAAAF,EAAAkB,GAAA;CAAA,OACoCC,OAAOD,CAAC;AAAC;;;ACZpD,IAAMU,IAA+BC,OAAOC,OAAO,CAAA,CAAE,GAE/CC,KAAkBC,OAGJ;CAClBP,MAAOO,EAAEP,QAAQG;CACjBF,WAAWM,EAAEN;AACf;AAMA,SAAOO,IAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GACLC,IAAWhB,EAAY,GACvBiB,IAAchB,EAAiBe,GAAIL,CAAc,GAACO;CACgB,OADhBJ,EAAA,OAAAG,EAAAZ,QAAAS,EAAA,OAAAG,EAAAX,aAC3CY,IAAA,kBAAC,GAAD;EAAiB,OAAAD,EAAKZ;EAAkB,WAAAY,EAAKX;CAAU,CAAA,GAAIQ,EAAA,KAAAG,EAAAZ,MAAAS,EAAA,KAAAG,EAAAX,WAAAQ,EAAA,KAAAI,KAAAA,IAAAJ,EAAA,IAA3DI;AAA2D;;;AC1BpE,IAAMK,IAAS;CACbC,MAAM;EACJC,SAAS;EACTC,eAAe;EACfC,KAAK;EACLC,IAAI;CACN;CACAC,KAAK;EACHJ,SAAS;EACTK,YAAY;EACZH,KAAK;CACP;CACAI,OAAO;EAAEC,OAAO;EAAKC,QAAQ;CAAG;AAClC;AAWA,SAAOI,EAAAC,GAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GAAwB,EAAAJ,OAAAK,MAAAH,GAAEF,IAAAK,MAAAC,KAAAA,IAAA,IAAAD,GAASE;CAQhC,OARgCJ,EAAA,OAAAH,IAQhCO,IAAAJ,EAAA,MANNI,IAAA,kBAAC,GAAD;EAAS,IAAApB,EAAMC;EACZoB,UAAAA,MAAKC,KAAM,EAAAC,QAAUV,EAAM,CAAC,CAAC,CAAAW,IAAKC,CAIlC;CALC,CAAA,GAMET,EAAA,KAAAH,GAAAG,EAAA,KAAAI,IANNA;AAMM;AARH,SAAAK,EAAAC,GAAAC,GAAA;CAAA,OAIC,kBAAC,GAAD;EAA0B,IAAA3B,EAAMM;EAC9B,UAAA,kBAAC,GAAD;GAAkB,SAAA;GAAkB,IAAAN,EAAMQ;EAAM,CAAA;CAD9C,GAAM,OAAOmB,GAAb;AAEE;;;ACnBd,SAAgBM,EAA2BC,GAMxB;CACjB,IAAMQ,IAAwB,CAAA;CAiC9B,OAhCIR,EAAKI,gBACPI,EAAMC,KACJd,EAAqB;EACnBM,UAAUD,EAAKC;EACfG,cAAcJ,EAAKI;EACnBM,YAAYV,EAAKM;EACjBK,iBAAiBX,EAAKO;CACxB,CAAC,CACH,GAEFC,EAAMC,KACJf,EAAqB;EACnBO,UAAUD,EAAKC;EACfW,UAAUT,MAAQ;GAChB,IAAMU,IAAOb,EAAKE,QAAQC,CAAG,GACvBW,IAAoB,CACxB;IAAC;IAAU;IAAU;IAAO;IAAO;IAAU;GAAM,CAAC;GAEtD,KAAK,IAAMC,KAAQF,GACjBC,EAAKL,KAAK;IACRM,EAAKC,QAAQC,QAAQ;IACrBF,EAAKG,UAAU;IACfH,EAAKI;IACLJ,EAAKK;IACLL,EAAKM,UAAU;IACfN,EAAKO,QAAQ;GAAE,CAChB;GAEH,OAAOR;EACT;CACF,CAAC,CACH,GACON;AACT;;;ACpBA,SAAgBoB,EAAc,EAC5BH,UACAC,WACAC,aAAU,gBAC2C;CACrD,IAAMI,IAASJ,MAAY,aAAaD,IAAUA,IAAS,MAAOD,GAG5DO,IAAQC,KAAKC,IAAIH,CAAM;CAE7B,OAAO;EAAEF,KAAKJ,IAAQO;EAAOF,KAAKL,IAAQO;CAAM;AAClD"}
@@ -1,5 +1,5 @@
1
1
  import { C as e, S as t, T as n, p as r } from "./stores-BVFMfgyo.js";
2
- import { d as i, n as a, t as o } from "./download-C7he8mSh.js";
2
+ import { d as i, n as a, t as o } from "./download--wRRnf19.js";
3
3
  import { c as ee } from "react/compiler-runtime";
4
4
  import "react";
5
5
  import { Box as s, Checkbox as c, IconButton as l, Skeleton as u, Table as d, TableBody as f, TableCell as p, TableContainer as m, TableHead as h, TablePagination as g, TableRow as _, TableSortLabel as v } from "@mui/material";
@@ -419,7 +419,7 @@ function V(e) {
419
419
  backgroundColor: e.pngBackgroundColor
420
420
  })), t.push(o({
421
421
  filename: e.filename,
422
- getCsv: () => L(e.getData(), e.columns)
422
+ getCsv: (t) => L(e.getData(t), e.columns)
423
423
  })), t;
424
424
  }
425
425
  //#endregion
@@ -436,4 +436,4 @@ function oe(e, t, n = "id") {
436
436
  //#endregion
437
437
  export { M as a, F as c, j as d, O as f, B as i, N as l, D as m, V as n, I as o, k as p, ie as r, P as s, oe as t, L as u };
438
438
 
439
- //# sourceMappingURL=table-CNQijNNB.js.map
439
+ //# sourceMappingURL=table-CRG9eOs9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-CRG9eOs9.js","names":["Box","SxProps","Theme","ReactNode","TableLabels","selectAll","selectRow","rowId","rowsPerPage","paginationOf","from","to","total","firstPage","previousPage","nextPage","lastPage","boldRange","fontWeight","color","DEFAULT_TABLE_LABELS","id","ReactNode","WidgetState","TableRow","Record","id","TableWidgetData","TableSortDirection","TableSortState","columnId","direction","TableColumn","label","align","width","sortable","formatter","value","row","TableWidgetState","columnOrder","sort","page","pageSize","DEFAULT_TABLE_PAGE_SIZE","DEFAULT_TABLE_PAGE_SIZE_OPTIONS","const","SxProps","Theme","styles","container","width","overflowX","table","minWidth","headerCell","fontWeight","backgroundColor","row","border","rowClickable","cursor","pagination","borderTop","borderColor","paginationActions","display","alignItems","gap","ml","empty","textAlign","color","py","Record","useCallback","useMemo","Box","Checkbox","IconButton","Table","MuiTable","TableBody","TableCell","TableContainer","TableHead","TablePagination","TableRow","MuiTableRow","TableSortLabel","TableProps","MuiTableProps","TablePaginationActionsProps","FirstPage","FirstPageIcon","KeyboardArrowLeft","KeyboardArrowRight","LastPage","LastPageIcon","DEFAULT_TABLE_LABELS","TableLabels","DEFAULT_TABLE_PAGE_SIZE_OPTIONS","TableColumn","TableSortDirection","TableSortState","styles","TableUIProps","columns","rows","T","total","page","pageSize","pageSizeOptions","sort","keyColumn","selection","selectable","onSortChange","next","onPageChange","onPageSizeChange","onSelectionChange","onRowClick","row","onRowHover","labels","Partial","emptyContent","React","ReactNode","size","TableUI","t0","$","_c","t1","t2","t3","undefined","process","env","NODE_ENV","missing","some","r","console","error","t4","_labels","minPageSize","Math","min","showPagination","t5","makePaginationActions","PaginationActions","t6","t7","Set","selectionSet","t8","index","resolveRowId","t9","map","pageRowIds","t10","length","every","id","has","allOnPageSelected","t11","id_0","someOnPageSelected","t12","columnId","direction","sameCol","nextDir","handleSort","t13","filter","id_1","includes","merged","id_2","add","handleSelectAllOnPage","t14","rowId","delete","handleSelectRow","t15","headerCell","selectAll","t16","t17","column","isSorted","align","width","sortable","label","t18","empty","row_0","index_0","rowId_0","isSelected","rowClickable","e","stopPropagation","selectRow","column_0","formatter","stringifyCell","t19","t20","table","t21","_","next_0","e_0","next_1","parseInt","target","value","rowsPerPage","t22","from","to","count","paginationOf","pagination","container","String","Array","isArray","JSON","stringify","lastPage","max","ceil","paginationActions","firstPage","previousPage","nextPage","toCsvString","TableColumn","TableRow","TableSortDirection","TableWidgetData","compareValues","a","b","direction","cmp","localeCompare","JSON","stringify","sortRows","rows","T","columnId","sort","paginateRows","page","pageSize","slice","start","resolveColumns","columns","columnOrder","length","byId","Map","map","c","id","ordered","seen","Set","get","has","push","add","deriveVisibleRows","options","sorted","visible","tableDataToCsv","data","stringifyHeader","label","row","stringifyCell","String","value","Array","isArray","useCallback","useMemo","getWidgetStore","useWidget","useWidgetId","useWidgetShallow","TableUI","TableUIProps","DEFAULT_TABLE_PAGE_SIZE","TableColumn","TableRow","TableSortState","TableWidgetState","deriveVisibleRows","resolveColumns","TableProps","Pick","T","columns","visibleColumns","initialPageSize","selection","onSelectionChange","next","onRowClick","row","onRowHover","remote","total","onSortChange","onPageChange","page","onPageSizeChange","pageSize","Table","t0","$","_c","remoteTotal","t1","t2","uiProps","undefined","id","data","_temp","t3","s_0","sort","s","columnOrder","ui","t4","reordered","slice","orderedColumns","t5","bb0","t6","t7","t8","rows","totalRows","sorted","visible","length","setState","Partial","handleSortChange","handlePageChange","handlePageSizeChange","t9","Box","Skeleton","Table","MuiTable","TableBody","TableCell","TableHead","TableRow","MuiTableRow","TableProps","MuiTableProps","styles","TableSkeletonProps","rows","columns","size","TableSkeleton","t0","$","_c","t1","t2","undefined","t3","Array","from","length","map","_temp","t4","t5","__0","r","row","__","c_0","c","t6","container","table","_","headerCell","buildCsvDownloadItem","buildPngDownloadItem","DownloadContext","DownloadItem","tableDataToCsv","TableColumn","TableWidgetData","createTableDownloadConfig","opts","filename","getData","ctx","columns","getCaptureEl","HTMLElement","pngPixelRatio","pngBackgroundColor","items","push","pixelRatio","backgroundColor","getCsv","filterTableByLockedRows","input","lockedItems","keyColumn","length","Array","isArray","locked","Set","filter","row","index","id","Record","has"],"sources":["../src/widgets-v2/table/labels.tsx","../src/widgets-v2/table/types.ts","../src/widgets-v2/table/style.ts","../src/widgets-v2/table/table-ui.tsx","../src/widgets-v2/table/helpers.ts","../src/widgets-v2/table/table.tsx","../src/widgets-v2/table/skeleton.tsx","../src/widgets-v2/table/download.ts","../src/widgets-v2/table/transforms.ts"],"sourcesContent":["import { Box, type SxProps, type Theme } from '@mui/material'\nimport type { ReactNode } from 'react'\n\nexport interface TableLabels {\n selectAll: string\n selectRow: (rowId: string | number) => string\n rowsPerPage: string\n /**\n * Renders the displayed-rows summary in the pagination footer. Returns\n * a `ReactNode` so the default can emphasise the active range\n * (`from-to`) with a bolder weight while keeping the trailing\n * ` of total` muted. Override to localise wording or restyle.\n */\n paginationOf: (from: number, to: number, total: number) => ReactNode\n /** aria-label for the first-page pagination button. */\n firstPage: string\n /** aria-label for the previous-page pagination button. */\n previousPage: string\n /** aria-label for the next-page pagination button. */\n nextPage: string\n /** aria-label for the last-page pagination button. */\n lastPage: string\n}\n\nconst boldRange: SxProps<Theme> = { fontWeight: 600, color: 'text.primary' }\n\nexport const DEFAULT_TABLE_LABELS: TableLabels = {\n selectAll: 'Select all rows',\n selectRow: (id) => `Select row ${id}`,\n rowsPerPage: 'Rows per page:',\n paginationOf: (from, to, total) => (\n <>\n <Box component='span' sx={boldRange}>{`${from}–${to}`}</Box>\n {` of ${total}`}\n </>\n ),\n firstPage: 'First page',\n previousPage: 'Previous page',\n nextPage: 'Next page',\n lastPage: 'Last page',\n}\n","import type { ReactNode } from 'react'\nimport type { WidgetState } from '../stores'\n\n/**\n * Single row of tabular data.\n *\n * The default row-identity column is `id`. Consumers that don't have a\n * literal `id` field can point `<Table>` / `<TableUI>` at a different\n * column via the `keyColumn` prop; the library reads `row[keyColumn]`\n * for selection lookup, React keys, and aria labels.\n */\nexport interface TableRow extends Record<string, unknown> {\n /**\n * Default row identity. Required when no `keyColumn` is configured.\n * Omit when wiring `keyColumn` to a different column.\n */\n id?: string | number\n}\n\nexport type TableWidgetData = readonly TableRow[]\n\nexport type TableSortDirection = 'asc' | 'desc'\n\nexport interface TableSortState {\n columnId: string | null\n direction: TableSortDirection\n}\n\nexport interface TableColumn {\n /** Unique column identifier; matches the field name on each row. */\n id: string\n /** Header label. */\n label: ReactNode\n align?: 'left' | 'center' | 'right'\n width?: number | string\n sortable?: boolean\n /** Custom cell renderer. Falls back to a string-cast of the raw value. */\n formatter?: (value: unknown, row: TableRow) => ReactNode\n}\n\n/**\n * State extension carrying Table-specific UI state on the per-widget store.\n * Per R12: widget-specific UI state lives in widget-specific extensions of\n * `WidgetState`, not on the base type.\n */\nexport interface TableWidgetState extends WidgetState {\n /** Optional reordered column list driven by ChangeColumn. Falls back to props. */\n columnOrder?: readonly string[]\n sort?: TableSortState\n page: number\n pageSize: number\n}\n\nexport const DEFAULT_TABLE_PAGE_SIZE = 10\nexport const DEFAULT_TABLE_PAGE_SIZE_OPTIONS = [10, 25, 50, 100] as const\n","import type { SxProps, Theme } from '@mui/material'\n\nexport const styles = {\n container: {\n width: '100%',\n overflowX: 'auto',\n },\n\n table: {\n minWidth: 0,\n },\n headerCell: {\n fontWeight: 600,\n backgroundColor: 'background.paper',\n },\n /**\n * Strip the bottom border from the last body row so the body flushes\n * against the pagination border instead of doubling it up. Mirrors v1.\n */\n row: {\n '&:last-child td, &:last-child th': {\n border: 0,\n },\n },\n rowClickable: {\n cursor: 'pointer',\n },\n pagination: {\n borderTop: '1px solid',\n borderColor: 'divider',\n },\n paginationActions: {\n display: 'flex',\n alignItems: 'center',\n gap: 0.25,\n ml: 1,\n },\n empty: {\n textAlign: 'center',\n color: 'text.secondary',\n py: 3,\n },\n} satisfies Record<string, SxProps<Theme>>\n","import { useCallback, useMemo } from 'react'\nimport {\n Box,\n Checkbox,\n IconButton,\n Table as MuiTable,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TablePagination,\n TableRow as MuiTableRow,\n TableSortLabel,\n type TableProps as MuiTableProps,\n} from '@mui/material'\nimport type { TablePaginationActionsProps } from '@mui/material/TablePagination/TablePaginationActions'\nimport { FirstPage as FirstPageIcon } from '@mui/icons-material'\nimport { KeyboardArrowLeft } from '@mui/icons-material'\nimport { KeyboardArrowRight } from '@mui/icons-material'\nimport { LastPage as LastPageIcon } from '@mui/icons-material'\nimport { DEFAULT_TABLE_LABELS, type TableLabels } from './labels'\nimport {\n DEFAULT_TABLE_PAGE_SIZE_OPTIONS,\n type TableColumn,\n type TableRow,\n type TableSortDirection,\n type TableSortState,\n} from './types'\nimport { styles } from './style'\n\nexport interface TableUIProps<T extends TableRow = TableRow> {\n columns: readonly TableColumn[]\n /** Already-paginated, already-sorted rows for the current view. */\n rows: readonly T[]\n /** Total row count (across all pages). Required for pagination footer. */\n total: number\n page: number\n pageSize: number\n pageSizeOptions?: readonly number[]\n sort?: TableSortState\n /**\n * Column name to use as the row identity. Drives selection lookup,\n * React keys, and aria labels. Defaults to `'id'` — point it at\n * another column when your rows don't carry an `id` field.\n */\n keyColumn?: string\n /** Selected row ids. Destination-owned. */\n selection?: readonly (string | number)[]\n selectable?: boolean\n onSortChange?: (next: TableSortState) => void\n onPageChange?: (page: number) => void\n onPageSizeChange?: (pageSize: number) => void\n onSelectionChange?: (next: readonly (string | number)[]) => void\n onRowClick?: (row: T) => void\n onRowHover?: (row: T | null) => void\n labels?: Partial<TableLabels>\n /** Row rendered when `rows` is empty for the current page. */\n emptyContent?: React.ReactNode\n /**\n * Forwarded to MUI's `<Table size>` — `'small'` for compact rows,\n * `'medium'` for the default density. Leave `undefined` (the default)\n * to let MUI's own default kick in.\n */\n size?: MuiTableProps['size']\n}\n\n/**\n * Pure renderer for a paginated, sortable, optionally-selectable table.\n * Has no widget-store coupling — `<Table>` (the bridge) reads from the store\n * and feeds this UI with already-projected data.\n */\nexport function TableUI<T extends TableRow = TableRow>({\n columns,\n rows,\n total,\n page,\n pageSize,\n pageSizeOptions = DEFAULT_TABLE_PAGE_SIZE_OPTIONS,\n sort,\n keyColumn = 'id',\n selection,\n selectable = false,\n onSortChange,\n onPageChange,\n onPageSizeChange,\n onSelectionChange,\n onRowClick,\n onRowHover,\n labels,\n emptyContent,\n size,\n}: TableUIProps<T>) {\n if (process.env.NODE_ENV !== 'production') {\n // Dev-time guard: a nullish identity collapses every row into the\n // same selection-set entry, which manifests as \"click one → all\n // appear selected\". Surface it loudly instead of silently degrading.\n const missing = rows.some((r) => r[keyColumn] == null)\n if (missing) {\n // eslint-disable-next-line no-console\n console.error(\n `<TableUI>: rows are missing the identity column \\`${keyColumn}\\`. ` +\n 'Set the `keyColumn` prop to a column present on every row, or ' +\n 'add the column to the data.',\n )\n }\n }\n const _labels = useMemo(\n () => ({ ...DEFAULT_TABLE_LABELS, ...labels }),\n [labels],\n )\n // Auto-hide the pagination footer when every row already fits in the\n // smallest available page size — the Rows-per-page selector + prev /\n // next buttons would just be inert noise. Consumers force the footer\n // on by passing a smaller `pageSizeOptions[0]` than `total`.\n const minPageSize = Math.min(...pageSizeOptions)\n const showPagination = total > minPageSize\n // Own the `ActionsComponent` slot ourselves so the Meridian theme's\n // `theme.components.MuiTablePagination.defaultProps.ActionsComponent`\n // (which depends on `react-intl`) doesn't leak into the library. The\n // MUI / Meridian style overrides for `MuiIconButton` /\n // `MuiTablePagination` still apply.\n const PaginationActions = useMemo(\n () => makePaginationActions(_labels),\n [_labels],\n )\n const selectionSet = useMemo(\n () => new Set<string | number>(selection ?? []),\n [selection],\n )\n // Resolve each row's identity from `keyColumn`, falling back to the row's\n // index when the cell is nullish. The dev-time guard above surfaces the\n // misconfiguration loudly, but in production we must NOT collapse every\n // nullish-keyed row into the same selection-set entry (that's the\n // \"click one → all selected\" bug) — a per-index fallback keeps ids\n // distinct and React keys stable for a given page.\n const resolveRowId = useCallback(\n (row: T, index: number): string | number =>\n (row[keyColumn] ?? index) as string | number,\n [keyColumn],\n )\n const pageRowIds = useMemo(() => rows.map(resolveRowId), [rows, resolveRowId])\n const allOnPageSelected =\n pageRowIds.length > 0 && pageRowIds.every((id) => selectionSet.has(id))\n const someOnPageSelected =\n !allOnPageSelected && pageRowIds.some((id) => selectionSet.has(id))\n\n const handleSort = (columnId: string) => {\n if (!onSortChange) return\n const sameCol = sort?.columnId === columnId\n const nextDir: TableSortDirection =\n sameCol && sort?.direction === 'asc' ? 'desc' : 'asc'\n onSortChange({ columnId, direction: nextDir })\n }\n\n const handleSelectAllOnPage = () => {\n if (!onSelectionChange) return\n if (allOnPageSelected) {\n onSelectionChange(\n (selection ?? []).filter((id) => !pageRowIds.includes(id)),\n )\n } else {\n const merged = new Set<string | number>(selection ?? [])\n for (const id of pageRowIds) merged.add(id)\n onSelectionChange([...merged])\n }\n }\n\n const handleSelectRow = (rowId: string | number) => {\n if (!onSelectionChange) return\n const next = new Set<string | number>(selection ?? [])\n if (next.has(rowId)) next.delete(rowId)\n else next.add(rowId)\n onSelectionChange([...next])\n }\n\n return (\n <Box sx={styles.container}>\n <TableContainer>\n <MuiTable stickyHeader size={size} sx={styles.table}>\n <TableHead>\n <MuiTableRow>\n {selectable ? (\n <TableCell padding='checkbox' sx={styles.headerCell}>\n <Checkbox\n checked={allOnPageSelected}\n indeterminate={someOnPageSelected}\n onChange={handleSelectAllOnPage}\n inputProps={{ 'aria-label': _labels.selectAll }}\n />\n </TableCell>\n ) : null}\n {columns.map((column) => {\n const isSorted = sort?.columnId === column.id\n const direction = isSorted ? sort?.direction : undefined\n return (\n <TableCell\n key={column.id}\n align={column.align}\n sortDirection={direction}\n sx={styles.headerCell}\n style={\n column.width != null ? { width: column.width } : undefined\n }\n >\n {column.sortable && onSortChange ? (\n <TableSortLabel\n active={isSorted}\n direction={direction ?? 'asc'}\n onClick={() => handleSort(column.id)}\n >\n {column.label}\n </TableSortLabel>\n ) : (\n column.label\n )}\n </TableCell>\n )\n })}\n </MuiTableRow>\n </TableHead>\n <TableBody>\n {rows.length === 0 ? (\n <MuiTableRow>\n <TableCell\n colSpan={columns.length + (selectable ? 1 : 0)}\n sx={styles.empty}\n >\n {emptyContent ?? null}\n </TableCell>\n </MuiTableRow>\n ) : (\n rows.map((row, index) => {\n const rowId = resolveRowId(row, index)\n const isSelected = selectionSet.has(rowId)\n return (\n <MuiTableRow\n key={rowId}\n hover\n selected={isSelected}\n onClick={() => onRowClick?.(row)}\n onMouseEnter={() => onRowHover?.(row)}\n onMouseLeave={() => onRowHover?.(null)}\n sx={{\n ...styles.row,\n ...(onRowClick ? styles.rowClickable : null),\n }}\n >\n {selectable ? (\n <TableCell padding='checkbox'>\n <Checkbox\n checked={isSelected}\n onClick={(e) => {\n e.stopPropagation()\n handleSelectRow(rowId)\n }}\n inputProps={{\n 'aria-label': _labels.selectRow(rowId),\n }}\n />\n </TableCell>\n ) : null}\n {columns.map((column) => (\n <TableCell key={column.id} align={column.align}>\n {column.formatter\n ? column.formatter(row[column.id], row)\n : stringifyCell(row[column.id])}\n </TableCell>\n ))}\n </MuiTableRow>\n )\n })\n )}\n </TableBody>\n </MuiTable>\n </TableContainer>\n {showPagination ? (\n <TablePagination\n component='div'\n count={total}\n page={page}\n rowsPerPage={pageSize}\n rowsPerPageOptions={[...pageSizeOptions]}\n onPageChange={(_, next) => onPageChange?.(next)}\n onRowsPerPageChange={(e) => {\n const next = parseInt(e.target.value, 10)\n onPageSizeChange?.(next)\n }}\n labelRowsPerPage={_labels.rowsPerPage}\n labelDisplayedRows={({ from, to, count }) =>\n _labels.paginationOf(from, to, count)\n }\n ActionsComponent={PaginationActions}\n sx={styles.pagination}\n />\n ) : null}\n </Box>\n )\n}\n\nfunction stringifyCell(value: unknown): React.ReactNode {\n if (value == null) return ''\n if (typeof value === 'string' || typeof value === 'number') return value\n if (typeof value === 'boolean') return String(value)\n if (Array.isArray(value) || typeof value === 'object') {\n return JSON.stringify(value)\n }\n return ''\n}\n\n/**\n * Build the `ActionsComponent` used by `<TablePagination>` — four MUI\n * `IconButton`s for first / previous / next / last. We provide this\n * ourselves so the Meridian theme's `defaultProps.ActionsComponent`\n * (which depends on `react-intl`) is bypassed at the call site without\n * disturbing the rest of the Meridian theme. The factory closes over\n * the merged label set so aria-labels stay consistent with the rest\n * of the table's i18n surface.\n */\nfunction makePaginationActions(labels: TableLabels) {\n return function PaginationActions({\n count,\n page,\n rowsPerPage,\n onPageChange,\n }: TablePaginationActionsProps) {\n const lastPage = Math.max(0, Math.ceil(count / rowsPerPage) - 1)\n return (\n <Box sx={styles.paginationActions}>\n <IconButton\n size='small'\n onClick={(e) => onPageChange(e, 0)}\n disabled={page === 0}\n aria-label={labels.firstPage}\n >\n <FirstPageIcon fontSize='small' />\n </IconButton>\n <IconButton\n size='small'\n onClick={(e) => onPageChange(e, page - 1)}\n disabled={page === 0}\n aria-label={labels.previousPage}\n >\n <KeyboardArrowLeft fontSize='small' />\n </IconButton>\n <IconButton\n size='small'\n onClick={(e) => onPageChange(e, page + 1)}\n disabled={page >= lastPage}\n aria-label={labels.nextPage}\n >\n <KeyboardArrowRight fontSize='small' />\n </IconButton>\n <IconButton\n size='small'\n onClick={(e) => onPageChange(e, lastPage)}\n disabled={page >= lastPage}\n aria-label={labels.lastPage}\n >\n <LastPageIcon fontSize='small' />\n </IconButton>\n </Box>\n )\n }\n}\n","import { toCsvString } from '../actions/download'\nimport type {\n TableColumn,\n TableRow,\n TableSortDirection,\n TableWidgetData,\n} from './types'\n\n/**\n * Compares two values with a consistent ordering across primitive types.\n * Strings use locale comparison; numbers subtract; booleans rank false < true;\n * objects/arrays compare by JSON serialization. Null/undefined sort to the end\n * regardless of direction.\n */\nexport function compareValues(\n a: unknown,\n b: unknown,\n direction: TableSortDirection,\n): number {\n if (a == null && b == null) return 0\n if (a == null) return 1\n if (b == null) return -1\n let cmp = 0\n if (typeof a === 'string' && typeof b === 'string') {\n cmp = a.localeCompare(b)\n } else if (typeof a === 'number' && typeof b === 'number') {\n cmp = a - b\n } else if (typeof a === 'boolean' && typeof b === 'boolean') {\n cmp = a === b ? 0 : a ? 1 : -1\n } else if (typeof a === 'object' || typeof b === 'object') {\n cmp = JSON.stringify(a).localeCompare(JSON.stringify(b))\n }\n return direction === 'asc' ? cmp : -cmp\n}\n\n/** Returns a new array sorted by the named column. Does not mutate the input. */\nexport function sortRows<T extends TableRow>(\n rows: readonly T[],\n columnId: string,\n direction: TableSortDirection,\n): T[] {\n return [...rows].sort((a, b) =>\n compareValues(a[columnId], b[columnId], direction),\n )\n}\n\n/** Returns the slice for the requested page. Out-of-range pages return []. */\nexport function paginateRows<T>(\n rows: readonly T[],\n page: number,\n pageSize: number,\n): T[] {\n if (pageSize <= 0) return rows.slice()\n const start = page * pageSize\n return rows.slice(start, start + pageSize)\n}\n\n/**\n * Resolves the effective column list. When the widget store has a\n * `columnOrder` set (e.g. ChangeColumn was used), the column array is\n * reordered to match. Unknown ids in the order are skipped; columns not\n * present in the order keep their original relative position at the end.\n */\nexport function resolveColumns(\n columns: readonly TableColumn[],\n columnOrder: readonly string[] | undefined,\n): readonly TableColumn[] {\n if (!columnOrder || columnOrder.length === 0) return columns\n const byId = new Map(columns.map((c) => [c.id, c]))\n const ordered: TableColumn[] = []\n const seen = new Set<string>()\n for (const id of columnOrder) {\n const c = byId.get(id)\n if (c && !seen.has(id)) {\n ordered.push(c)\n seen.add(id)\n }\n }\n for (const c of columns) {\n if (!seen.has(c.id)) ordered.push(c)\n }\n return ordered\n}\n\n/** Applies sort and pagination to the input data. Pure. */\nexport function deriveVisibleRows<T extends TableRow>(\n rows: readonly T[],\n options: {\n sort?: { columnId: string | null; direction: TableSortDirection }\n page: number\n pageSize: number\n },\n): { sorted: readonly T[]; visible: T[] } {\n const sorted =\n options.sort?.columnId != null\n ? sortRows(rows, options.sort.columnId, options.sort.direction)\n : rows\n const visible = paginateRows(sorted, options.page, options.pageSize)\n return { sorted, visible }\n}\n\nexport function tableDataToCsv(\n data: TableWidgetData,\n columns: readonly TableColumn[],\n): string {\n // Pre-stringify with the table's own header/cell rules, then delegate the\n // CSV assembly (quoting + spreadsheet formula-injection guard) to the shared\n // `toCsvString` so escaping stays identical to every other widget's export.\n const rows: string[][] = [columns.map((c) => stringifyHeader(c.label))]\n for (const row of data) {\n rows.push(columns.map((c) => stringifyCell(row[c.id])))\n }\n return toCsvString(rows)\n}\n\nfunction stringifyHeader(label: unknown): string {\n if (typeof label === 'string') return label\n if (typeof label === 'number' || typeof label === 'boolean')\n return String(label)\n return ''\n}\n\nfunction stringifyCell(value: unknown): string {\n if (value == null) return ''\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value)\n if (Array.isArray(value) || typeof value === 'object')\n return JSON.stringify(value)\n return ''\n}\n","import { useCallback, useMemo } from 'react'\nimport {\n getWidgetStore,\n useWidget,\n useWidgetId,\n useWidgetShallow,\n} from '../stores'\nimport { TableUI, type TableUIProps } from './table-ui'\nimport {\n DEFAULT_TABLE_PAGE_SIZE,\n type TableColumn,\n type TableRow,\n type TableSortState,\n type TableWidgetState,\n} from './types'\nimport { deriveVisibleRows, resolveColumns } from './helpers'\n\nexport interface TableProps<T extends TableRow = TableRow> extends Pick<\n TableUIProps<T>,\n | 'pageSizeOptions'\n | 'selectable'\n | 'labels'\n | 'emptyContent'\n | 'size'\n | 'keyColumn'\n> {\n /**\n * Column definitions. Order can be overridden by ChangeColumn via the\n * `columnOrder` field on the extended widget state.\n */\n columns: readonly TableColumn[]\n /**\n * When set, render only the first `visibleColumns` entries **after**\n * applying the user's `columnOrder` from the store. Useful for showing\n * a compact projection while letting consumers (e.g. `Widget.ChangeColumn`)\n * see the full column list. When omitted, every column renders.\n */\n visibleColumns?: number\n /** Initial page size (only on first mount; afterwards lives on the store). */\n initialPageSize?: number\n /** Selected row ids (destination-owned). */\n selection?: readonly (string | number)[]\n onSelectionChange?: (next: readonly (string | number)[]) => void\n onRowClick?: (row: T) => void\n onRowHover?: (row: T | null) => void\n /**\n * When `true`, the bridge stops sorting and paginating locally and\n * renders `data` as-is — the consumer is then responsible for\n * refetching the slice that matches the active `page` / `pageSize` /\n * `sort` from the outbound callbacks below. `total` is required in\n * this mode (the server already knows the full row count; the\n * widget can't infer it from a partial page).\n */\n remote?: boolean\n /**\n * Server-reported total row count. Required when `remote === true`;\n * ignored in local mode (where the bridge derives total from the\n * sorted result of `deriveVisibleRows`).\n */\n total?: number\n /** Fires after the store-level sort write so the consumer can refetch. */\n onSortChange?: (next: TableSortState) => void\n /** Fires after the store-level page write so the consumer can refetch. */\n onPageChange?: (page: number) => void\n /** Fires after the store-level pageSize write so the consumer can refetch. */\n onPageSizeChange?: (pageSize: number) => void\n}\n\n/**\n * Bridge component — reads the widget store's `data`, applies sort + pagination\n * locally, and feeds `<TableUI />`. Sort, page, and pageSize live on the\n * extended widget state ({@link TableWidgetState}).\n */\nexport function Table<T extends TableRow = TableRow>({\n columns,\n visibleColumns,\n initialPageSize = DEFAULT_TABLE_PAGE_SIZE,\n selection,\n onSelectionChange,\n onRowClick,\n onRowHover,\n remote = false,\n total: remoteTotal,\n onSortChange,\n onPageChange,\n onPageSizeChange,\n ...uiProps\n}: TableProps<T>) {\n const id = useWidgetId()\n const data = useWidget(id, (s) => s.data as readonly T[] | undefined)\n const ui = useWidgetShallow<\n {\n sort: TableSortState | undefined\n page: number\n pageSize: number\n columnOrder: readonly string[] | undefined\n },\n TableWidgetState\n >(id, (s) => ({\n sort: s.sort,\n page: s.page ?? 0,\n pageSize: s.pageSize ?? initialPageSize,\n columnOrder: s.columnOrder,\n }))\n\n const orderedColumns = useMemo(() => {\n const reordered = resolveColumns(columns, ui.columnOrder)\n return visibleColumns == null\n ? reordered\n : reordered.slice(0, visibleColumns)\n }, [columns, ui.columnOrder, visibleColumns])\n\n // In remote mode the consumer already paginated / sorted server-side,\n // so pass `data` and `total` straight through. Local mode keeps the\n // bridge-driven sort + slice via `deriveVisibleRows`.\n const { rows, totalRows } = useMemo(() => {\n if (remote) {\n return {\n rows: data ?? [],\n totalRows: remoteTotal ?? 0,\n }\n }\n const { sorted, visible } = deriveVisibleRows(data ?? [], {\n sort: ui.sort,\n page: ui.page,\n pageSize: ui.pageSize,\n })\n return { rows: visible, totalRows: sorted.length }\n }, [remote, data, remoteTotal, ui.sort, ui.page, ui.pageSize])\n\n const handleSortChange = useCallback(\n (next: TableSortState) => {\n getWidgetStore(id).setState({\n sort: next,\n page: 0,\n } as Partial<TableWidgetState>)\n onSortChange?.(next)\n },\n [id, onSortChange],\n )\n\n const handlePageChange = useCallback(\n (page: number) => {\n getWidgetStore(id).setState({ page } as Partial<TableWidgetState>)\n onPageChange?.(page)\n },\n [id, onPageChange],\n )\n\n const handlePageSizeChange = useCallback(\n (pageSize: number) => {\n getWidgetStore(id).setState({\n pageSize,\n page: 0,\n } as Partial<TableWidgetState>)\n onPageSizeChange?.(pageSize)\n },\n [id, onPageSizeChange],\n )\n\n return (\n <TableUI\n {...uiProps}\n columns={orderedColumns}\n rows={rows}\n total={totalRows}\n page={ui.page}\n pageSize={ui.pageSize}\n sort={ui.sort}\n selection={selection}\n onSortChange={handleSortChange}\n onPageChange={handlePageChange}\n onPageSizeChange={handlePageSizeChange}\n onSelectionChange={onSelectionChange}\n onRowClick={onRowClick}\n onRowHover={onRowHover}\n />\n )\n}\n","import {\n Box,\n Skeleton,\n Table as MuiTable,\n TableBody,\n TableCell,\n TableHead,\n TableRow as MuiTableRow,\n type TableProps as MuiTableProps,\n} from '@mui/material'\nimport { styles } from './style'\n\nexport interface TableSkeletonProps {\n /** Number of body rows to render. Defaults to `5` (matches v1). */\n rows?: number\n /** Number of columns to render. Defaults to `4` (matches v1). */\n columns?: number\n /**\n * Forwarded to MUI's `<Table size>` so the loading layout matches the\n * size you'll render in {@link TableUI}. Leave `undefined` (the\n * default) to use MUI's own default density.\n */\n size?: MuiTableProps['size']\n}\n\n/**\n * Loading placeholder for the Table widget. Renders the same MUI table\n * primitives that {@link TableUI} uses so the loading layout (column\n * widths, header band, row density) doesn't shift when data resolves.\n *\n * Mirrors the v1 widget's `<TableSkeleton>` structure with v2's themed\n * `styles.headerCell`.\n */\nexport function TableSkeleton({\n rows = 5,\n columns = 4,\n size,\n}: TableSkeletonProps) {\n return (\n <Box sx={styles.container} aria-label='Table skeleton'>\n <MuiTable size={size} sx={styles.table} stickyHeader>\n <TableHead>\n <MuiTableRow>\n {Array.from({ length: columns }).map((_, c) => (\n <TableCell key={`head-${c}`} sx={styles.headerCell}>\n <Skeleton variant='text' width='80%' height={24} />\n </TableCell>\n ))}\n </MuiTableRow>\n </TableHead>\n <TableBody>\n {Array.from({ length: rows }).map((_, r) => (\n <MuiTableRow key={`row-${r}`} sx={styles.row}>\n {Array.from({ length: columns }).map((__, c) => (\n <TableCell key={`cell-${r}-${c}`}>\n <Skeleton variant='text' width='70%' height={20} />\n </TableCell>\n ))}\n </MuiTableRow>\n ))}\n </TableBody>\n </MuiTable>\n </Box>\n )\n}\n","import {\n buildCsvDownloadItem,\n buildPngDownloadItem,\n type DownloadContext,\n type DownloadItem,\n} from '../actions/download'\nimport { tableDataToCsv } from './helpers'\nimport type { TableColumn, TableWidgetData } from './types'\n\n/**\n * Download menu items for the Table widget. Always includes a CSV item\n * that pulls the latest data from the widget store via `getData()` (so\n * locked / sorted / filtered state is honored); headers come from\n * `column.label`, cells from `row[column.id]`. When `getCaptureEl` is\n * supplied, prepends a PNG item that rasterises the captured element via\n * `html2canvas`.\n */\nexport function createTableDownloadConfig(opts: {\n filename: string\n getData: (ctx: DownloadContext) => TableWidgetData\n columns: readonly TableColumn[]\n getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null\n pngPixelRatio?: number\n pngBackgroundColor?: string | null\n}): DownloadItem[] {\n const items: DownloadItem[] = []\n if (opts.getCaptureEl) {\n items.push(\n buildPngDownloadItem({\n filename: opts.filename,\n getCaptureEl: opts.getCaptureEl,\n pixelRatio: opts.pngPixelRatio,\n backgroundColor: opts.pngBackgroundColor,\n }),\n )\n }\n items.push(\n buildCsvDownloadItem({\n filename: opts.filename,\n getCsv: (ctx) => tableDataToCsv(opts.getData(ctx), opts.columns),\n }),\n )\n return items\n}\n","/**\n * `LockSelection` filter for Table. Data is a FLAT `TableRow[]` (unlike every\n * other widget's `X[][]` series shape) and row identity comes from\n * `row[keyColumn]` (default `'id'`), not `name` — so `filterByLockedItems`\n * doesn't apply here (its outer `.map` treats each row as a \"series\", and a\n * plain row object isn't an array, so it would silently pass everything\n * through unfiltered). Falls back to the row's index when the identity\n * column is nullish, mirroring `TableUI`'s own `resolveRowId`.\n *\n * `keyColumn` isn't part of `LockSelection`'s generic `filterFn` signature —\n * close over it: `filterFn={(data, locked) => filterTableByLockedRows(data, locked, keyColumn)}`.\n */\nexport function filterTableByLockedRows(\n input: unknown,\n lockedItems: readonly (string | number)[],\n keyColumn = 'id',\n): unknown {\n if (lockedItems.length === 0) return input\n if (!Array.isArray(input)) return input\n const locked = new Set<string | number>(lockedItems)\n return input.filter((row: unknown, index: number): boolean => {\n if (row == null || typeof row !== 'object') return false\n const id = (row as Record<string, unknown>)[keyColumn] ?? index\n return (typeof id === 'string' || typeof id === 'number') && locked.has(id)\n })\n}\n"],"mappings":"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"}
@@ -72,7 +72,8 @@ export interface LegendRampVariable {
72
72
  * Ordered low→high stops. Discrete ramps **require `colors.length + 1`**
73
73
  * stops — the boundaries between color steps, including both outer edges —
74
74
  * and each label is centered on its boundary line (keep labels short, e.g.
75
- * `20K`; there is no collision handling). A discrete ramp with any other
75
+ * `20K`; there is no collision handling; pass `''` to hide one — each step's
76
+ * tooltip still shows its full range). A discrete ramp with any other
76
77
  * stop count is incoherent and renders an inline error instead of the bar.
77
78
  * Continuous ramps show only the first/last endpoints.
78
79
  */
@@ -86,7 +87,8 @@ export interface LegendRampVariable {
86
87
  */
87
88
  avg?: number;
88
89
  /**
89
- * Formats `avg` for its tooltip. Default `String(avg)` — pass e.g.
90
+ * Formats `avg` and, on discrete ramps, the stop values shown in each
91
+ * step's range tooltip. Default `String(value)` — pass e.g.
90
92
  * `(v) => formatNumber(v, 'es-ES')` or `(v) => `${v}%``. Use a stable
91
93
  * reference (same contract as the other variable fields).
92
94
  */
@@ -1,4 +1,4 @@
1
- import { DownloadItem } from './types.js';
1
+ import { DownloadContext, DownloadItem } from './types.js';
2
2
  interface BuildCsvDownloadItemBase {
3
3
  /** Base filename (without extension). The item appends `.csv`. */
4
4
  filename: string;
@@ -17,7 +17,7 @@ export type BuildCsvDownloadItemArgs = (BuildCsvDownloadItemBase & {
17
17
  * through `toCsvString` so escaping (incl. the spreadsheet
18
18
  * formula-injection guard) stays consistent across widgets.
19
19
  */
20
- getRows: () => readonly (readonly unknown[])[];
20
+ getRows: (ctx: DownloadContext) => readonly (readonly unknown[])[];
21
21
  getCsv?: never;
22
22
  }) | (BuildCsvDownloadItemBase & {
23
23
  /**
@@ -25,7 +25,7 @@ export type BuildCsvDownloadItemArgs = (BuildCsvDownloadItemBase & {
25
25
  * (e.g. Table) that already serialise their own CSV with bespoke
26
26
  * header/cell handling.
27
27
  */
28
- getCsv: () => string;
28
+ getCsv: (ctx: DownloadContext) => string;
29
29
  getRows?: never;
30
30
  });
31
31
  /**
@@ -4,5 +4,5 @@ export { CSVIcon, PNGIcon, MarkdownIcon } from './icons.js';
4
4
  export { buildPngDownloadItem, type BuildPngDownloadItemArgs } from './png-item.js';
5
5
  export { buildCsvDownloadItem, type BuildCsvDownloadItemArgs } from './csv-item.js';
6
6
  export { DOWNLOAD_ITEM_IDS, type DownloadItemId } from './constants.js';
7
- export type { DownloadItem } from './types.js';
7
+ export type { DownloadItem, DownloadContext } from './types.js';
8
8
  export { DEFAULT_DOWNLOAD_LABELS, type DownloadLabels } from './labels.js';
@@ -1,4 +1,4 @@
1
- import { DownloadItem } from './types.js';
1
+ import { DownloadContext, DownloadItem } from './types.js';
2
2
  export interface BuildPngDownloadItemArgs {
3
3
  /** Base filename (without extension). The item appends `.png`. */
4
4
  filename: string;
@@ -7,7 +7,7 @@ export interface BuildPngDownloadItemArgs {
7
7
  * download config doesn't capture a stale reference. Wire it to
8
8
  * `() => getCaptureEl(id)` from `widgets-v2/stores`.
9
9
  */
10
- getCaptureEl: () => HTMLElement | null;
10
+ getCaptureEl: (ctx: DownloadContext) => HTMLElement | null;
11
11
  /** html2canvas `scale`. Default 2. */
12
12
  pixelRatio?: number;
13
13
  /** html2canvas `backgroundColor`. Default transparent (`null`). */
@@ -1,4 +1,15 @@
1
1
  import { ReactElement } from 'react';
2
+ /**
3
+ * Passed to {@link DownloadItem.resolve} by `<Widget.Download>`.
4
+ */
5
+ export interface DownloadContext {
6
+ /**
7
+ * Id of the widget store the menu was opened from — the dialog's own
8
+ * store when opened from `FullScreen.Slot`'s header, so an export matches
9
+ * what the user is looking at. `null` outside a `<Widget.Provider>`.
10
+ */
11
+ id: string | null;
12
+ }
2
13
  export interface DownloadItem {
3
14
  /** Unique key (also used as menu label key). */
4
15
  id: string;
@@ -27,7 +38,7 @@ export interface DownloadItem {
27
38
  * Resolves to a Blob URL the trigger will click. Optional `revoke` is
28
39
  * called after the click is dispatched.
29
40
  */
30
- resolve: () => Promise<{
41
+ resolve: (ctx: DownloadContext) => Promise<{
31
42
  url: string;
32
43
  filename: string;
33
44
  revoke?: () => void;
@@ -9,11 +9,18 @@ export interface FullScreenTriggerProps {
9
9
  }
10
10
  export interface FullScreenSlotProps {
11
11
  /**
12
- * Render-prop body. Receives the live `isFullScreen` flag so the consumer
13
- * can branch per-mode props (e.g., `Widget.Toolbox visibleCount`) without
14
- * duplicating the JSX.
12
+ * The widget body. Rendered twice, identically: in the card, and again in
13
+ * the dialog while it's open. The components inside don't know which copy
14
+ * they are; the dialog's just runs on a widget store of its own — a copy
15
+ * of the card's taken on open, handed back to the card on close — so read
16
+ * the widget id with `useWidgetId()` inside the body rather than closing
17
+ * over the card's `id`.
18
+ *
19
+ * @deprecated The function form `(isFullScreen) => ReactNode` still works
20
+ * (`false` for the card, `true` for the dialog copy) but will be removed
21
+ * in the next major: pass the body as plain children.
15
22
  */
16
- children: (isFullScreen: boolean) => ReactNode;
23
+ children: ReactNode | ((isFullScreen: boolean) => ReactNode);
17
24
  /** Header text rendered above the body when the modal is open. */
18
25
  title?: ReactNode;
19
26
  /**
@@ -46,15 +53,15 @@ export interface FullScreenSlotProps {
46
53
  * `<Widget.Content>`).
47
54
  */
48
55
  declare function FullScreenTrigger({ labels, enterIcon: EnterIcon, exitIcon: ExitIcon, iconProps, }: FullScreenTriggerProps): import("react").JSX.Element;
56
+ /** Id of the widget store the dialog copy runs on. */
57
+ export declare function fullScreenStoreId(id: string): string;
49
58
  /**
50
- * Body wrapper. Renders its render-prop children once, via a single
51
- * `createPortal` call whose container is a stable `<div>` we hold as a ref.
52
- * That div is moved imperatively between an inline placeholder and the
53
- * `<DialogContent>` of an MUI `<Dialog keepMounted>`. Because both the
54
- * React parent (the portal call site) AND the portal container are
55
- * identical across the toggle, the subtree keeps its fiber identity and
56
- * ECharts (or any other heavy child) stays mounted while only its DOM
57
- * parent changes.
59
+ * Body wrapper. The card keeps its copy of the body while the dialog is
60
+ * open, and the dialog mounts a second one on a store of its own: a copy
61
+ * of the card's UI state taken on open, and handed back to the card when
62
+ * the dialog closes. While open the two don't affect each other. MUI
63
+ * mounts the dialog copy on open and unmounts it after the close
64
+ * transition, which drops its store.
58
65
  */
59
66
  declare function FullScreenSlot({ children, title, actions, paperSx, labels, closeIcon: CloseSvg, iconProps, }: FullScreenSlotProps): import("react").JSX.Element;
60
67
  /**
@@ -66,7 +73,7 @@ declare function FullScreenSlot({ children, title, actions, paperSx, labels, clo
66
73
  * </Widget.Actions>
67
74
  * <Widget.Content>
68
75
  * <Widget.FullScreen.Slot title={title} actions={<Widget.Download items={items} />}>
69
- * {(isFullScreen) => <Body visibleCount={isFullScreen ? undefined : 2} />}
76
+ * <Body />
70
77
  * </Widget.FullScreen.Slot>
71
78
  * </Widget.Content>
72
79
  * ```
@@ -4,7 +4,7 @@ export { ShowAllToggle, setShowAll, SHOW_ALL_ID, DEFAULT_SHOW_ALL_LABELS, type S
4
4
  export { ZoomToggle, addZoom, createAddZoom, ZOOM_LAYOUT, DEFAULT_ZOOM_TOGGLE_LABELS, type ZoomToggleProps, type ZoomToggleLabels, } from './zoom-toggle/index.js';
5
5
  export { BrushToggle, addBrush, DEFAULT_BRUSH_TOGGLE_LABELS, type BrushToggleProps, type BrushToggleLabels, } from './brush-toggle/index.js';
6
6
  export { RelativeData, toRelativeData, createPercentFormatter, DEFAULT_RELATIVE_DATA_LABELS, type RelativeDataProps, type RelativeDataLabels, } from './relative-data/index.js';
7
- export { Download, downloadToCSV, downloadDOMToPNG, toCsvString, triggerLinkDownload, buildPngDownloadItem, buildCsvDownloadItem, CSVIcon, PNGIcon, MarkdownIcon, DEFAULT_DOWNLOAD_LABELS, DOWNLOAD_ITEM_IDS, type DownloadProps, type DownloadItem, type DownloadItemId, type DownloadHandle, type DownloadDOMToPNGOptions, type BuildPngDownloadItemArgs, type BuildCsvDownloadItemArgs, type DownloadLabels, } from './download/index.js';
7
+ export { Download, downloadToCSV, downloadDOMToPNG, toCsvString, triggerLinkDownload, buildPngDownloadItem, buildCsvDownloadItem, CSVIcon, PNGIcon, MarkdownIcon, DEFAULT_DOWNLOAD_LABELS, DOWNLOAD_ITEM_IDS, type DownloadProps, type DownloadItem, type DownloadContext, type DownloadItemId, type DownloadHandle, type DownloadDOMToPNGOptions, type BuildPngDownloadItemArgs, type BuildCsvDownloadItemArgs, type DownloadLabels, } from './download/index.js';
8
8
  export { FullScreen, DEFAULT_FULLSCREEN_LABELS, type FullScreenTriggerProps, type FullScreenSlotProps, type FullScreenLabels, type FullScreenWidgetState, } from './fullscreen/index.js';
9
9
  export { LockSelection, filterByLockedItems, DEFAULT_LOCK_SELECTION_LABELS, type LockSelectionProps, type LockSelectionKey, type LockSelectionLabels, } from './lock-selection/index.js';
10
10
  export { ChangeColumn, DEFAULT_CHANGE_COLUMN_LABELS, type ChangeColumnProps, type ChangeColumnItem, type ChangeColumnLabels, type ChangeColumnWidgetState, } from './change-column/index.js';
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Filters a 2D series of `{name, ...}` records by case-insensitive substring on
3
- * the `name` field. Keeps the dataset shape (one inner array per series).
3
+ * the label the user sees: `labelFormatter(name)` when a formatter is given,
4
+ * `name` otherwise. Keeps the dataset shape (one inner array per series).
4
5
  * Used by the Searcher action's data transform.
5
6
  */
6
- export declare function filterBySearchText(input: unknown, search: string): unknown;
7
+ export declare function filterBySearchText(input: unknown, search: string, labelFormatter?: (value: string | number) => string | number): unknown;
@@ -1,15 +1,15 @@
1
- import { DownloadItem } from '../actions/download/index.js';
1
+ import { DownloadContext, DownloadItem } from '../actions/download/index.js';
2
2
  import { BarWidgetData } from './types.js';
3
3
  export interface BarDownloadConfigArgs {
4
4
  filename: string;
5
- getData: () => BarWidgetData;
5
+ getData: (ctx: DownloadContext) => BarWidgetData;
6
6
  /**
7
7
  * Optional getter for the widget's capture element (registered by
8
8
  * `Widget.State` on its success path). When provided, a PNG item is
9
9
  * prepended to the returned list. Wire it to
10
10
  * `() => getCaptureEl(id)`.
11
11
  */
12
- getCaptureEl?: () => HTMLElement | null;
12
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null;
13
13
  /** PNG `pixelRatio` (default 2). */
14
14
  pngPixelRatio?: number;
15
15
  /** PNG `backgroundColor` (default transparent). */
@@ -69,6 +69,14 @@ export interface CategoryUIProps {
69
69
  * No-op for single-series data — same convention as the legend.
70
70
  */
71
71
  stacked?: boolean;
72
+ /**
73
+ * Series indices hidden via the legend. Leave both this and
74
+ * `onHiddenSeriesChange` unset and CategoryUI keeps the set itself; pass
75
+ * them to own it — `Category` does, so the card and the fullscreen copy
76
+ * share it through the widget store.
77
+ */
78
+ hiddenSeries?: ReadonlySet<number>;
79
+ onHiddenSeriesChange?: (next: ReadonlySet<number>) => void;
72
80
  }
73
81
  /**
74
82
  * Pure presentational component for the Category widget. Renders
@@ -85,4 +93,4 @@ export interface CategoryUIProps {
85
93
  * Returns `null` when there's nothing to render — `Widget.State` is the
86
94
  * empty-state authority in the canonical compositor.
87
95
  */
88
- export declare function CategoryUI({ data, selection, onSelectionChange, formatter, labelFormatter, series, maxItems, labels, onShowAll, maxOverride, size, stacked, }: CategoryUIProps): import("react").JSX.Element | null;
96
+ export declare function CategoryUI({ data, selection, onSelectionChange, formatter, labelFormatter, series, maxItems, labels, onShowAll, maxOverride, size, stacked, hiddenSeries: hiddenSeriesProp, onHiddenSeriesChange, }: CategoryUIProps): import("react").JSX.Element | null;
@@ -1,4 +1,4 @@
1
- import { DownloadItem } from '../actions/download/index.js';
1
+ import { DownloadContext, DownloadItem } from '../actions/download/index.js';
2
2
  import { CategoryWidgetData } from './types.js';
3
3
  /**
4
4
  * Download menu items for the Category widget. Always includes a CSV item
@@ -8,9 +8,9 @@ import { CategoryWidgetData } from './types.js';
8
8
  */
9
9
  export declare function createCategoryDownloadConfig(args: {
10
10
  filename: string;
11
- getData: () => CategoryWidgetData;
11
+ getData: (ctx: DownloadContext) => CategoryWidgetData;
12
12
  seriesNames?: readonly string[];
13
- getCaptureEl?: () => HTMLElement | null;
13
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null;
14
14
  pngPixelRatio?: number;
15
15
  pngBackgroundColor?: string | null;
16
16
  }): DownloadItem[];
@@ -3,5 +3,6 @@ export declare const styles: {
3
3
  width: string;
4
4
  flex: number;
5
5
  minHeight: number;
6
+ isolation: "isolate";
6
7
  };
7
8
  };
@@ -1,13 +1,13 @@
1
- import { DownloadItem } from '../actions/download/index.js';
1
+ import { DownloadContext, DownloadItem } from '../actions/download/index.js';
2
2
  import { FormulaWidgetData } from './types.js';
3
3
  export interface FormulaDownloadConfigArgs {
4
4
  filename: string;
5
- getData: () => FormulaWidgetData;
5
+ getData: (ctx: DownloadContext) => FormulaWidgetData;
6
6
  /**
7
7
  * Optional getter for the widget's capture element (registered by
8
8
  * `Widget.State`). When provided, a PNG item is prepended.
9
9
  */
10
- getCaptureEl?: () => HTMLElement | null;
10
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null;
11
11
  pngPixelRatio?: number;
12
12
  pngBackgroundColor?: string | null;
13
13
  }
@@ -1,4 +1,4 @@
1
- import { DownloadItem } from '../actions/download/index.js';
1
+ import { DownloadContext, DownloadItem } from '../actions/download/index.js';
2
2
  import { HistogramWidgetData } from './types.js';
3
3
  /**
4
4
  * Download menu items for histograms. Always includes a CSV item with
@@ -8,10 +8,10 @@ import { HistogramWidgetData } from './types.js';
8
8
  */
9
9
  export declare function createHistogramDownloadConfig(args: {
10
10
  filename: string;
11
- getData: () => HistogramWidgetData;
11
+ getData: (ctx: DownloadContext) => HistogramWidgetData;
12
12
  getTicks: () => readonly number[];
13
13
  seriesNames?: readonly string[];
14
- getCaptureEl?: () => HTMLElement | null;
14
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null;
15
15
  pngPixelRatio?: number;
16
16
  pngBackgroundColor?: string | null;
17
17
  }): DownloadItem[];
@@ -96,7 +96,7 @@ export type { ToolboxLabels } from './toolbox/labels.js';
96
96
  export type { EchartProps, EchartUIProps, EchartsEventHandler } from './echart/index.js';
97
97
  export type { NoteProps, NoteMarkdownProps } from './note/widget-note.js';
98
98
  export type { NoteLabels } from './note/labels.js';
99
- export type { SearcherProps, SearcherToggleProps, StackToggleProps, ShowAllToggleProps, ZoomToggleProps, BrushToggleProps, RelativeDataProps, DownloadProps, DownloadItem, FullScreenTriggerProps, FullScreenSlotProps, LockSelectionProps, LockSelectionKey, ChangeColumnProps, ChangeColumnItem, } from './actions/index.js';
99
+ export type { SearcherProps, SearcherToggleProps, StackToggleProps, ShowAllToggleProps, ZoomToggleProps, BrushToggleProps, RelativeDataProps, DownloadProps, DownloadItem, DownloadContext, FullScreenTriggerProps, FullScreenSlotProps, LockSelectionProps, LockSelectionKey, ChangeColumnProps, ChangeColumnItem, } from './actions/index.js';
100
100
  export type { FormulaUIProps, FormulaDataItem, FormulaWidgetData, } from './formula/index.js';
101
101
  export type { MarkdownUIProps, MarkdownWidgetData } from './markdown/index.js';
102
102
  export type { PieDatum, PieWidgetData } from './pie/index.js';