@carto/ps-react-ui 4.22.0 → 4.23.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 (103) hide show
  1. package/dist/actions-D7LB9DvT.js +1161 -0
  2. package/dist/actions-D7LB9DvT.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/{markdown-CV_KP-at.js → markdown-C3OX9jyy.js} +6 -6
  12. package/dist/markdown-C3OX9jyy.js.map +1 -0
  13. package/dist/{spread-C8T12Nfh.js → spread-BT07rCJw.js} +7 -7
  14. package/dist/spread-BT07rCJw.js.map +1 -0
  15. package/dist/{table-CNQijNNB.js → table-CRG9eOs9.js} +3 -3
  16. package/dist/table-CRG9eOs9.js.map +1 -0
  17. package/dist/types/widgets-v2/actions/download/csv-item.d.ts +3 -3
  18. package/dist/types/widgets-v2/actions/download/index.d.ts +1 -1
  19. package/dist/types/widgets-v2/actions/download/png-item.d.ts +2 -2
  20. package/dist/types/widgets-v2/actions/download/types.d.ts +12 -1
  21. package/dist/types/widgets-v2/actions/fullscreen/fullscreen.d.ts +20 -13
  22. package/dist/types/widgets-v2/actions/index.d.ts +1 -1
  23. package/dist/types/widgets-v2/bar/download.d.ts +3 -3
  24. package/dist/types/widgets-v2/category/category-ui.d.ts +9 -1
  25. package/dist/types/widgets-v2/category/download.d.ts +3 -3
  26. package/dist/types/widgets-v2/echart/style.d.ts +1 -0
  27. package/dist/types/widgets-v2/formula/download.d.ts +3 -3
  28. package/dist/types/widgets-v2/histogram/download.d.ts +3 -3
  29. package/dist/types/widgets-v2/index.d.ts +1 -1
  30. package/dist/types/widgets-v2/markdown/download.d.ts +3 -3
  31. package/dist/types/widgets-v2/pie/download.d.ts +3 -3
  32. package/dist/types/widgets-v2/scatterplot/download.d.ts +3 -3
  33. package/dist/types/widgets-v2/spread/download.d.ts +3 -3
  34. package/dist/types/widgets-v2/table/download.d.ts +3 -3
  35. package/dist/types/widgets-v2/timeseries/download.d.ts +3 -3
  36. package/dist/types/widgets-v2/toolbox/toolbox.d.ts +1 -1
  37. package/dist/widgets-v2/actions.js +2 -2
  38. package/dist/widgets-v2/bar.js +7 -7
  39. package/dist/widgets-v2/bar.js.map +1 -1
  40. package/dist/widgets-v2/category.js +1 -1
  41. package/dist/widgets-v2/echart.js +1 -1
  42. package/dist/widgets-v2/formula.js +1 -1
  43. package/dist/widgets-v2/histogram.js +10 -10
  44. package/dist/widgets-v2/histogram.js.map +1 -1
  45. package/dist/widgets-v2/markdown.js +1 -1
  46. package/dist/widgets-v2/pie.js +10 -10
  47. package/dist/widgets-v2/pie.js.map +1 -1
  48. package/dist/widgets-v2/scatterplot.js +9 -9
  49. package/dist/widgets-v2/scatterplot.js.map +1 -1
  50. package/dist/widgets-v2/spread.js +1 -1
  51. package/dist/widgets-v2/table.js +1 -1
  52. package/dist/widgets-v2/timeseries.js +12 -12
  53. package/dist/widgets-v2/timeseries.js.map +1 -1
  54. package/dist/widgets-v2.js +274 -333
  55. package/dist/widgets-v2.js.map +1 -1
  56. package/package.json +3 -3
  57. package/src/widgets-v2/actions/download/csv-item.test.tsx +3 -3
  58. package/src/widgets-v2/actions/download/csv-item.tsx +6 -6
  59. package/src/widgets-v2/actions/download/download.tsx +5 -3
  60. package/src/widgets-v2/actions/download/index.ts +1 -1
  61. package/src/widgets-v2/actions/download/png-item.test.tsx +5 -3
  62. package/src/widgets-v2/actions/download/png-item.tsx +4 -4
  63. package/src/widgets-v2/actions/download/types.ts +15 -1
  64. package/src/widgets-v2/actions/fullscreen/fullscreen-store.test.tsx +155 -0
  65. package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +39 -41
  66. package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +211 -96
  67. package/src/widgets-v2/actions/index.ts +1 -0
  68. package/src/widgets-v2/actions/searcher/searcher.tsx +17 -2
  69. package/src/widgets-v2/bar/download.test.tsx +5 -3
  70. package/src/widgets-v2/bar/download.tsx +5 -4
  71. package/src/widgets-v2/category/category-ui.tsx +20 -9
  72. package/src/widgets-v2/category/category.tsx +37 -2
  73. package/src/widgets-v2/category/download.test.ts +4 -2
  74. package/src/widgets-v2/category/download.ts +5 -4
  75. package/src/widgets-v2/echart/style.ts +6 -0
  76. package/src/widgets-v2/formula/download.test.tsx +3 -1
  77. package/src/widgets-v2/formula/download.tsx +5 -4
  78. package/src/widgets-v2/histogram/download.test.ts +6 -4
  79. package/src/widgets-v2/histogram/download.ts +5 -4
  80. package/src/widgets-v2/index.ts +1 -0
  81. package/src/widgets-v2/markdown/download.test.ts +2 -2
  82. package/src/widgets-v2/markdown/download.tsx +5 -4
  83. package/src/widgets-v2/pie/download.test.ts +7 -3
  84. package/src/widgets-v2/pie/download.ts +5 -4
  85. package/src/widgets-v2/scatterplot/download.test.ts +4 -2
  86. package/src/widgets-v2/scatterplot/download.ts +5 -4
  87. package/src/widgets-v2/spread/download.test.ts +3 -1
  88. package/src/widgets-v2/spread/download.ts +5 -4
  89. package/src/widgets-v2/table/download.test.ts +5 -3
  90. package/src/widgets-v2/table/download.ts +4 -3
  91. package/src/widgets-v2/timeseries/download.test.ts +6 -4
  92. package/src/widgets-v2/timeseries/download.ts +5 -4
  93. package/src/widgets-v2/toolbox/toolbox.tsx +1 -1
  94. package/dist/actions-iN1jwyxA.js +0 -1024
  95. package/dist/actions-iN1jwyxA.js.map +0 -1
  96. package/dist/category-DZt6yiST.js +0 -826
  97. package/dist/category-DZt6yiST.js.map +0 -1
  98. package/dist/download-C7he8mSh.js.map +0 -1
  99. package/dist/echart-BnJYXH7H.js.map +0 -1
  100. package/dist/formula-Cqj84ZGX.js.map +0 -1
  101. package/dist/markdown-CV_KP-at.js.map +0 -1
  102. package/dist/spread-C8T12Nfh.js.map +0 -1
  103. package/dist/table-CNQijNNB.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  buildCsvDownloadItem,
3
3
  buildPngDownloadItem,
4
+ type DownloadContext,
4
5
  type DownloadItem,
5
6
  } from '../actions/download'
6
7
  import type { CategoryWidgetData } from './types'
@@ -13,9 +14,9 @@ import type { CategoryWidgetData } from './types'
13
14
  */
14
15
  export function createCategoryDownloadConfig(args: {
15
16
  filename: string
16
- getData: () => CategoryWidgetData
17
+ getData: (ctx: DownloadContext) => CategoryWidgetData
17
18
  seriesNames?: readonly string[]
18
- getCaptureEl?: () => HTMLElement | null
19
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null
19
20
  pngPixelRatio?: number
20
21
  pngBackgroundColor?: string | null
21
22
  }): DownloadItem[] {
@@ -33,8 +34,8 @@ export function createCategoryDownloadConfig(args: {
33
34
  items.push(
34
35
  buildCsvDownloadItem({
35
36
  filename: args.filename,
36
- getRows: () => {
37
- const data = args.getData()
37
+ getRows: (ctx) => {
38
+ const data = args.getData(ctx)
38
39
  const rows: unknown[][] = [['series', 'name', 'value']]
39
40
  for (const [i, series] of data.entries()) {
40
41
  const seriesName = args.seriesNames?.[i] ?? `series_${i + 1}`
@@ -13,5 +13,11 @@ export const styles = {
13
13
  // with `<Widget.Echart sx={{ minHeight }} />`.
14
14
  flex: 1,
15
15
  minHeight: 304,
16
+ // ECharts puts its tooltip inside this box at `z-index: 9999999`. With
17
+ // no stacking context of its own, that number competes page-wide and
18
+ // beats MUI's modal layer — under `FullScreen.Slot` the card's chart
19
+ // mirrors the dialog's tooltip (echarts.connect) and it painted over
20
+ // the dialog. Isolating keeps the tooltip above its own chart only.
21
+ isolation: 'isolate',
16
22
  },
17
23
  } satisfies Record<string, SxProps<Theme>>
@@ -56,7 +56,9 @@ describe('createFormulaDownloadConfig', () => {
56
56
  filename: 'f',
57
57
  getData: () => data,
58
58
  })
59
- const handle = await items.find((i) => i.id === 'csv')!.resolve()
59
+ const handle = await items
60
+ .find((i) => i.id === 'csv')!
61
+ .resolve({ id: null })
60
62
  expect(handle.filename).toBe('f.csv')
61
63
  expect(csvText).toBe(
62
64
  'series,prefix,value,suffix,note,delta\nRev,$,42,k,q1,12\n,,10,,,',
@@ -1,18 +1,19 @@
1
1
  import {
2
2
  buildCsvDownloadItem,
3
3
  buildPngDownloadItem,
4
+ type DownloadContext,
4
5
  type DownloadItem,
5
6
  } from '../actions/download'
6
7
  import type { FormulaWidgetData } from './types'
7
8
 
8
9
  export interface FormulaDownloadConfigArgs {
9
10
  filename: string
10
- getData: () => FormulaWidgetData
11
+ getData: (ctx: DownloadContext) => FormulaWidgetData
11
12
  /**
12
13
  * Optional getter for the widget's capture element (registered by
13
14
  * `Widget.State`). When provided, a PNG item is prepended.
14
15
  */
15
- getCaptureEl?: () => HTMLElement | null
16
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null
16
17
  pngPixelRatio?: number
17
18
  pngBackgroundColor?: string | null
18
19
  }
@@ -40,8 +41,8 @@ export function createFormulaDownloadConfig(
40
41
  items.push(
41
42
  buildCsvDownloadItem({
42
43
  filename: args.filename,
43
- getRows: () => {
44
- const data = args.getData()
44
+ getRows: (ctx) => {
45
+ const data = args.getData(ctx)
45
46
  const rows: unknown[][] = [
46
47
  ['series', 'prefix', 'value', 'suffix', 'note', 'delta'],
47
48
  ]
@@ -52,7 +52,9 @@ describe('createHistogramDownloadConfig', () => {
52
52
  getData: () => data,
53
53
  getTicks: () => ticks,
54
54
  })
55
- const handle = await items.find((i) => i.id === 'csv')!.resolve()
55
+ const handle = await items
56
+ .find((i) => i.id === 'csv')!
57
+ .resolve({ id: null })
56
58
  expect(handle.filename).toBe('h.csv')
57
59
  expect(csvText).toBe(
58
60
  'bin_low,bin_high,series_1,series_2\n0,10,1,4\n10,20,2,5\n20,30,3,6',
@@ -66,7 +68,7 @@ describe('createHistogramDownloadConfig', () => {
66
68
  getTicks: () => ticks,
67
69
  seriesNames: ['lo', 'hi'],
68
70
  })
69
- await items.find((i) => i.id === 'csv')!.resolve()
71
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
70
72
  expect(csvText.startsWith('bin_low,bin_high,lo,hi')).toBe(true)
71
73
  })
72
74
 
@@ -76,7 +78,7 @@ describe('createHistogramDownloadConfig', () => {
76
78
  getData: () => data,
77
79
  getTicks: () => [0],
78
80
  })
79
- await items.find((i) => i.id === 'csv')!.resolve()
81
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
80
82
  expect(csvText).toBe('bin_low,bin_high,series_1,series_2')
81
83
  })
82
84
 
@@ -87,7 +89,7 @@ describe('createHistogramDownloadConfig', () => {
87
89
  getData: () => sparse,
88
90
  getTicks: () => ticks,
89
91
  })
90
- await items.find((i) => i.id === 'csv')!.resolve()
92
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
91
93
  expect(csvText).toContain('0,10,1,0')
92
94
  expect(csvText).toContain('10,20,2,0')
93
95
  })
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  buildCsvDownloadItem,
3
3
  buildPngDownloadItem,
4
+ type DownloadContext,
4
5
  type DownloadItem,
5
6
  } from '../actions/download'
6
7
  import type { HistogramWidgetData } from './types'
@@ -13,10 +14,10 @@ import type { HistogramWidgetData } from './types'
13
14
  */
14
15
  export function createHistogramDownloadConfig(args: {
15
16
  filename: string
16
- getData: () => HistogramWidgetData
17
+ getData: (ctx: DownloadContext) => HistogramWidgetData
17
18
  getTicks: () => readonly number[]
18
19
  seriesNames?: readonly string[]
19
- getCaptureEl?: () => HTMLElement | null
20
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null
20
21
  pngPixelRatio?: number
21
22
  pngBackgroundColor?: string | null
22
23
  }): DownloadItem[] {
@@ -34,8 +35,8 @@ export function createHistogramDownloadConfig(args: {
34
35
  items.push(
35
36
  buildCsvDownloadItem({
36
37
  filename: args.filename,
37
- getRows: () => {
38
- const data = args.getData()
38
+ getRows: (ctx) => {
39
+ const data = args.getData(ctx)
39
40
  const ticks = args.getTicks()
40
41
  const seriesCount = data.length
41
42
  const header: unknown[] = ['bin_low', 'bin_high']
@@ -157,6 +157,7 @@ export type {
157
157
  RelativeDataProps,
158
158
  DownloadProps,
159
159
  DownloadItem,
160
+ DownloadContext,
160
161
  FullScreenTriggerProps,
161
162
  FullScreenSlotProps,
162
163
  LockSelectionProps,
@@ -46,7 +46,7 @@ describe('createMarkdownDownloadConfig', () => {
46
46
  filename: 'doc',
47
47
  getData: () => ({ content: '# title\n\nbody' }),
48
48
  })
49
- const handle = await items.find((i) => i.id === 'md')!.resolve()
49
+ const handle = await items.find((i) => i.id === 'md')!.resolve({ id: null })
50
50
  expect(handle.url).toBe('blob:mock')
51
51
  expect(handle.filename).toBe('doc.md')
52
52
  expect(mdText).toBe('# title\n\nbody')
@@ -60,7 +60,7 @@ describe('createMarkdownDownloadConfig', () => {
60
60
  // missing content field — exercise the `?? ''` branch
61
61
  getData: () => ({}) as { content: string },
62
62
  })
63
- await items.find((i) => i.id === 'md')!.resolve()
63
+ await items.find((i) => i.id === 'md')!.resolve({ id: null })
64
64
  expect(mdText).toBe('')
65
65
  })
66
66
  })
@@ -4,6 +4,7 @@ import {
4
4
  buildPngDownloadItem,
5
5
  toCsvString,
6
6
  triggerLinkDownload,
7
+ type DownloadContext,
7
8
  type DownloadItem,
8
9
  } from '../actions/download'
9
10
  import type { MarkdownWidgetData } from './types'
@@ -16,8 +17,8 @@ import type { MarkdownWidgetData } from './types'
16
17
  */
17
18
  export function createMarkdownDownloadConfig(args: {
18
19
  filename: string
19
- getData: () => MarkdownWidgetData
20
- getCaptureEl?: () => HTMLElement | null
20
+ getData: (ctx: DownloadContext) => MarkdownWidgetData
21
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null
21
22
  pngPixelRatio?: number
22
23
  pngBackgroundColor?: string | null
23
24
  }): DownloadItem[] {
@@ -36,8 +37,8 @@ export function createMarkdownDownloadConfig(args: {
36
37
  id: DOWNLOAD_ITEM_IDS.markdown,
37
38
  label: 'Markdown',
38
39
  icon: <MarkdownIcon fontSize='small' />,
39
- resolve: () => {
40
- const data = args.getData()
40
+ resolve: (ctx) => {
41
+ const data = args.getData(ctx)
41
42
  const blob = new Blob([data.content ?? ''], {
42
43
  type: 'text/markdown;charset=utf-8;',
43
44
  })
@@ -51,7 +51,9 @@ describe('createPieDownloadConfig', () => {
51
51
  getCaptureEl: () => null,
52
52
  })
53
53
  expect(items.map((i) => i.id)).toEqual(['png', 'csv'])
54
- await expect(items[0]!.resolve()).rejects.toThrow(/No PNG capture element/)
54
+ await expect(items[0]!.resolve({ id: null })).rejects.toThrow(
55
+ /No PNG capture element/,
56
+ )
55
57
  })
56
58
 
57
59
  it('CSV resolve uses default series_<n> when seriesNames is absent', async () => {
@@ -59,7 +61,9 @@ describe('createPieDownloadConfig', () => {
59
61
  filename: 'p',
60
62
  getData: () => multi,
61
63
  })
62
- const handle = await items.find((i) => i.id === 'csv')!.resolve()
64
+ const handle = await items
65
+ .find((i) => i.id === 'csv')!
66
+ .resolve({ id: null })
63
67
  expect(handle.filename).toBe('p.csv')
64
68
  expect(csvText).toBe('series,name,value\nseries_1,a,1\nseries_2,c,3')
65
69
  handle.revoke?.()
@@ -72,7 +76,7 @@ describe('createPieDownloadConfig', () => {
72
76
  getData: () => multi,
73
77
  seriesNames: ['alpha', 'beta'],
74
78
  })
75
- await items.find((i) => i.id === 'csv')!.resolve()
79
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
76
80
  expect(csvText).toBe('series,name,value\nalpha,a,1\nbeta,c,3')
77
81
  })
78
82
  })
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  buildCsvDownloadItem,
3
3
  buildPngDownloadItem,
4
+ type DownloadContext,
4
5
  type DownloadItem,
5
6
  } from '../actions/download'
6
7
  import type { PieWidgetData } from './types'
@@ -14,9 +15,9 @@ import type { PieWidgetData } from './types'
14
15
  */
15
16
  export function createPieDownloadConfig(args: {
16
17
  filename: string
17
- getData: () => PieWidgetData
18
+ getData: (ctx: DownloadContext) => PieWidgetData
18
19
  seriesNames?: readonly string[]
19
- getCaptureEl?: () => HTMLElement | null
20
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null
20
21
  pngPixelRatio?: number
21
22
  pngBackgroundColor?: string | null
22
23
  }): DownloadItem[] {
@@ -34,8 +35,8 @@ export function createPieDownloadConfig(args: {
34
35
  items.push(
35
36
  buildCsvDownloadItem({
36
37
  filename: args.filename,
37
- getRows: () => {
38
- const data = args.getData()
38
+ getRows: (ctx) => {
39
+ const data = args.getData(ctx)
39
40
  const rows: unknown[][] = [['series', 'name', 'value']]
40
41
  for (const [i, series] of data.entries()) {
41
42
  const seriesName = args.seriesNames?.[i] ?? `series_${i + 1}`
@@ -52,7 +52,9 @@ describe('createScatterplotDownloadConfig', () => {
52
52
  filename: 's',
53
53
  getData: () => data,
54
54
  })
55
- const handle = await items.find((i) => i.id === 'csv')!.resolve()
55
+ const handle = await items
56
+ .find((i) => i.id === 'csv')!
57
+ .resolve({ id: null })
56
58
  expect(handle.filename).toBe('s.csv')
57
59
  expect(csvText).toBe(
58
60
  'series,x,y\nseries_1,1,10\nseries_1,2,20\nseries_2,3,30',
@@ -65,7 +67,7 @@ describe('createScatterplotDownloadConfig', () => {
65
67
  getData: () => data,
66
68
  seriesNames: ['A', 'B'],
67
69
  })
68
- await items.find((i) => i.id === 'csv')!.resolve()
70
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
69
71
  expect(csvText.split('\n')[1]).toBe('A,1,10')
70
72
  })
71
73
  })
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  buildCsvDownloadItem,
3
3
  buildPngDownloadItem,
4
+ type DownloadContext,
4
5
  type DownloadItem,
5
6
  } from '../actions/download'
6
7
  import type { ScatterplotWidgetData } from './types'
@@ -13,9 +14,9 @@ import type { ScatterplotWidgetData } from './types'
13
14
  */
14
15
  export function createScatterplotDownloadConfig(args: {
15
16
  filename: string
16
- getData: () => ScatterplotWidgetData
17
+ getData: (ctx: DownloadContext) => ScatterplotWidgetData
17
18
  seriesNames?: readonly string[]
18
- getCaptureEl?: () => HTMLElement | null
19
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null
19
20
  pngPixelRatio?: number
20
21
  pngBackgroundColor?: string | null
21
22
  }): DownloadItem[] {
@@ -33,8 +34,8 @@ export function createScatterplotDownloadConfig(args: {
33
34
  items.push(
34
35
  buildCsvDownloadItem({
35
36
  filename: args.filename,
36
- getRows: () => {
37
- const data = args.getData()
37
+ getRows: (ctx) => {
38
+ const data = args.getData(ctx)
38
39
  const rows: unknown[][] = [['series', 'x', 'y']]
39
40
  for (const [i, series] of data.entries()) {
40
41
  const seriesName = args.seriesNames?.[i] ?? `series_${i + 1}`
@@ -55,7 +55,9 @@ describe('createSpreadDownloadConfig', () => {
55
55
  filename: 's',
56
56
  getData: () => data,
57
57
  })
58
- const handle = await items.find((i) => i.id === 'csv')!.resolve()
58
+ const handle = await items
59
+ .find((i) => i.id === 'csv')!
60
+ .resolve({ id: null })
59
61
  expect(handle.filename).toBe('s.csv')
60
62
  expect(csvText).toBe(
61
63
  'series,prefix,min,max,suffix,note\nRevenue,$,1,9,k,q1\n,,0,10,,',
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  buildCsvDownloadItem,
3
3
  buildPngDownloadItem,
4
+ type DownloadContext,
4
5
  type DownloadItem,
5
6
  } from '../actions/download'
6
7
  import type { SpreadWidgetData } from './types'
@@ -13,8 +14,8 @@ import type { SpreadWidgetData } from './types'
13
14
  */
14
15
  export function createSpreadDownloadConfig(args: {
15
16
  filename: string
16
- getData: () => SpreadWidgetData
17
- getCaptureEl?: () => HTMLElement | null
17
+ getData: (ctx: DownloadContext) => SpreadWidgetData
18
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null
18
19
  pngPixelRatio?: number
19
20
  pngBackgroundColor?: string | null
20
21
  }): DownloadItem[] {
@@ -32,8 +33,8 @@ export function createSpreadDownloadConfig(args: {
32
33
  items.push(
33
34
  buildCsvDownloadItem({
34
35
  filename: args.filename,
35
- getRows: () => {
36
- const data = args.getData()
36
+ getRows: (ctx) => {
37
+ const data = args.getData(ctx)
37
38
  const rows: unknown[][] = [
38
39
  ['series', 'prefix', 'min', 'max', 'suffix', 'note'],
39
40
  ]
@@ -56,7 +56,9 @@ describe('createTableDownloadConfig', () => {
56
56
  getData: () => data,
57
57
  columns,
58
58
  })
59
- const handle = await items.find((i) => i.id === 'csv')!.resolve()
59
+ const handle = await items
60
+ .find((i) => i.id === 'csv')!
61
+ .resolve({ id: null })
60
62
  expect(handle.filename).toBe('t.csv')
61
63
  expect(csvText).toBe('Name,Score\nAlpha,10\nBeta,20')
62
64
  })
@@ -67,7 +69,7 @@ describe('createTableDownloadConfig', () => {
67
69
  getData: () => [{ id: 1, name: '=HYPERLINK("x")', score: 1 }],
68
70
  columns,
69
71
  })
70
- await items.find((i) => i.id === 'csv')!.resolve()
72
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
71
73
  expect(csvText).toBe('Name,Score\n"\'=HYPERLINK(""x"")",1')
72
74
  })
73
75
 
@@ -79,7 +81,7 @@ describe('createTableDownloadConfig', () => {
79
81
  columns,
80
82
  })
81
83
  snapshot = [{ id: 9, name: 'Gamma', score: 99 }]
82
- await items.find((i) => i.id === 'csv')!.resolve()
84
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
83
85
  expect(csvText).toBe('Name,Score\nGamma,99')
84
86
  })
85
87
  })
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  buildCsvDownloadItem,
3
3
  buildPngDownloadItem,
4
+ type DownloadContext,
4
5
  type DownloadItem,
5
6
  } from '../actions/download'
6
7
  import { tableDataToCsv } from './helpers'
@@ -16,9 +17,9 @@ import type { TableColumn, TableWidgetData } from './types'
16
17
  */
17
18
  export function createTableDownloadConfig(opts: {
18
19
  filename: string
19
- getData: () => TableWidgetData
20
+ getData: (ctx: DownloadContext) => TableWidgetData
20
21
  columns: readonly TableColumn[]
21
- getCaptureEl?: () => HTMLElement | null
22
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null
22
23
  pngPixelRatio?: number
23
24
  pngBackgroundColor?: string | null
24
25
  }): DownloadItem[] {
@@ -36,7 +37,7 @@ export function createTableDownloadConfig(opts: {
36
37
  items.push(
37
38
  buildCsvDownloadItem({
38
39
  filename: opts.filename,
39
- getCsv: () => tableDataToCsv(opts.getData(), opts.columns),
40
+ getCsv: (ctx) => tableDataToCsv(opts.getData(ctx), opts.columns),
40
41
  }),
41
42
  )
42
43
  return items
@@ -53,7 +53,9 @@ describe('createTimeseriesDownloadConfig', () => {
53
53
  filename: 't',
54
54
  getData: () => data,
55
55
  })
56
- const handle = await items.find((i) => i.id === 'csv')!.resolve()
56
+ const handle = await items
57
+ .find((i) => i.id === 'csv')!
58
+ .resolve({ id: null })
57
59
  expect(handle.filename).toBe('t.csv')
58
60
  expect(csvText).toBe(
59
61
  'time,series_1,series_2\n' +
@@ -69,7 +71,7 @@ describe('createTimeseriesDownloadConfig', () => {
69
71
  filename: 't',
70
72
  getData: () => data,
71
73
  })
72
- await items.find((i) => i.id === 'csv')!.resolve()
74
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
73
75
  expect(csvText).toContain('2024-01-01T00:00:00.000Z,7')
74
76
  })
75
77
 
@@ -79,7 +81,7 @@ describe('createTimeseriesDownloadConfig', () => {
79
81
  filename: 't',
80
82
  getData: () => data,
81
83
  })
82
- await items.find((i) => i.id === 'csv')!.resolve()
84
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
83
85
  expect(csvText).toContain('2024-Q1,1')
84
86
  })
85
87
 
@@ -89,7 +91,7 @@ describe('createTimeseriesDownloadConfig', () => {
89
91
  getData: () => [[{ name: '2024', value: 1 }]],
90
92
  seriesNames: ['revenue'],
91
93
  })
92
- await items.find((i) => i.id === 'csv')!.resolve()
94
+ await items.find((i) => i.id === 'csv')!.resolve({ id: null })
93
95
  expect(csvText.split('\n')[0]).toBe('time,revenue')
94
96
  })
95
97
  })
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  buildCsvDownloadItem,
3
3
  buildPngDownloadItem,
4
+ type DownloadContext,
4
5
  type DownloadItem,
5
6
  } from '../actions/download'
6
7
  import type { TimeseriesWidgetData } from './types'
@@ -14,9 +15,9 @@ import type { TimeseriesWidgetData } from './types'
14
15
  */
15
16
  export function createTimeseriesDownloadConfig(args: {
16
17
  filename: string
17
- getData: () => TimeseriesWidgetData
18
+ getData: (ctx: DownloadContext) => TimeseriesWidgetData
18
19
  seriesNames?: readonly string[]
19
- getCaptureEl?: () => HTMLElement | null
20
+ getCaptureEl?: (ctx: DownloadContext) => HTMLElement | null
20
21
  pngPixelRatio?: number
21
22
  pngBackgroundColor?: string | null
22
23
  }): DownloadItem[] {
@@ -34,8 +35,8 @@ export function createTimeseriesDownloadConfig(args: {
34
35
  items.push(
35
36
  buildCsvDownloadItem({
36
37
  filename: args.filename,
37
- getRows: () => {
38
- const data = args.getData()
38
+ getRows: (ctx) => {
39
+ const data = args.getData(ctx)
39
40
  const seriesCount = data.length
40
41
 
41
42
  // Collect every unique time, preserving insertion order.
@@ -56,7 +56,7 @@ export interface ToolboxProps {
56
56
  * Smart overflow toolbar with **single-mount** items. Children mount once
57
57
  * into a stable, hidden host element and are *physically reparented* via
58
58
  * `appendChild` between the inline preview area and the overflow `<Paper>`
59
- * as the popper opens / closes — same pattern as `Widget.FullScreen.Slot`.
59
+ * as the popper opens / closes.
60
60
  * Items with no inline space when closed are kept mounted but visually
61
61
  * hidden via `display: none`.
62
62
  *