@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.
- package/dist/actions-D7LB9DvT.js +1161 -0
- package/dist/actions-D7LB9DvT.js.map +1 -0
- package/dist/category-Ca5XDx0N.js +839 -0
- package/dist/category-Ca5XDx0N.js.map +1 -0
- package/dist/{download-C7he8mSh.js → download--wRRnf19.js} +81 -80
- package/dist/download--wRRnf19.js.map +1 -0
- package/dist/{echart-BnJYXH7H.js → echart-CgOQw9XB.js} +3 -2
- package/dist/echart-CgOQw9XB.js.map +1 -0
- package/dist/{formula-Cqj84ZGX.js → formula-DRuMIVo8.js} +6 -6
- package/dist/formula-DRuMIVo8.js.map +1 -0
- package/dist/{markdown-CV_KP-at.js → markdown-C3OX9jyy.js} +6 -6
- package/dist/markdown-C3OX9jyy.js.map +1 -0
- package/dist/{spread-C8T12Nfh.js → spread-BT07rCJw.js} +7 -7
- package/dist/spread-BT07rCJw.js.map +1 -0
- package/dist/{table-CNQijNNB.js → table-CRG9eOs9.js} +3 -3
- package/dist/table-CRG9eOs9.js.map +1 -0
- package/dist/types/widgets-v2/actions/download/csv-item.d.ts +3 -3
- package/dist/types/widgets-v2/actions/download/index.d.ts +1 -1
- package/dist/types/widgets-v2/actions/download/png-item.d.ts +2 -2
- package/dist/types/widgets-v2/actions/download/types.d.ts +12 -1
- package/dist/types/widgets-v2/actions/fullscreen/fullscreen.d.ts +20 -13
- package/dist/types/widgets-v2/actions/index.d.ts +1 -1
- package/dist/types/widgets-v2/bar/download.d.ts +3 -3
- package/dist/types/widgets-v2/category/category-ui.d.ts +9 -1
- package/dist/types/widgets-v2/category/download.d.ts +3 -3
- package/dist/types/widgets-v2/echart/style.d.ts +1 -0
- package/dist/types/widgets-v2/formula/download.d.ts +3 -3
- package/dist/types/widgets-v2/histogram/download.d.ts +3 -3
- package/dist/types/widgets-v2/index.d.ts +1 -1
- package/dist/types/widgets-v2/markdown/download.d.ts +3 -3
- package/dist/types/widgets-v2/pie/download.d.ts +3 -3
- package/dist/types/widgets-v2/scatterplot/download.d.ts +3 -3
- package/dist/types/widgets-v2/spread/download.d.ts +3 -3
- package/dist/types/widgets-v2/table/download.d.ts +3 -3
- package/dist/types/widgets-v2/timeseries/download.d.ts +3 -3
- package/dist/types/widgets-v2/toolbox/toolbox.d.ts +1 -1
- package/dist/widgets-v2/actions.js +2 -2
- package/dist/widgets-v2/bar.js +7 -7
- package/dist/widgets-v2/bar.js.map +1 -1
- package/dist/widgets-v2/category.js +1 -1
- package/dist/widgets-v2/echart.js +1 -1
- package/dist/widgets-v2/formula.js +1 -1
- package/dist/widgets-v2/histogram.js +10 -10
- package/dist/widgets-v2/histogram.js.map +1 -1
- package/dist/widgets-v2/markdown.js +1 -1
- package/dist/widgets-v2/pie.js +10 -10
- package/dist/widgets-v2/pie.js.map +1 -1
- package/dist/widgets-v2/scatterplot.js +9 -9
- package/dist/widgets-v2/scatterplot.js.map +1 -1
- package/dist/widgets-v2/spread.js +1 -1
- package/dist/widgets-v2/table.js +1 -1
- package/dist/widgets-v2/timeseries.js +12 -12
- package/dist/widgets-v2/timeseries.js.map +1 -1
- package/dist/widgets-v2.js +274 -333
- package/dist/widgets-v2.js.map +1 -1
- package/package.json +3 -3
- package/src/widgets-v2/actions/download/csv-item.test.tsx +3 -3
- package/src/widgets-v2/actions/download/csv-item.tsx +6 -6
- package/src/widgets-v2/actions/download/download.tsx +5 -3
- package/src/widgets-v2/actions/download/index.ts +1 -1
- package/src/widgets-v2/actions/download/png-item.test.tsx +5 -3
- package/src/widgets-v2/actions/download/png-item.tsx +4 -4
- package/src/widgets-v2/actions/download/types.ts +15 -1
- package/src/widgets-v2/actions/fullscreen/fullscreen-store.test.tsx +155 -0
- package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +39 -41
- package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +211 -96
- package/src/widgets-v2/actions/index.ts +1 -0
- package/src/widgets-v2/actions/searcher/searcher.tsx +17 -2
- package/src/widgets-v2/bar/download.test.tsx +5 -3
- package/src/widgets-v2/bar/download.tsx +5 -4
- package/src/widgets-v2/category/category-ui.tsx +20 -9
- package/src/widgets-v2/category/category.tsx +37 -2
- package/src/widgets-v2/category/download.test.ts +4 -2
- package/src/widgets-v2/category/download.ts +5 -4
- package/src/widgets-v2/echart/style.ts +6 -0
- package/src/widgets-v2/formula/download.test.tsx +3 -1
- package/src/widgets-v2/formula/download.tsx +5 -4
- package/src/widgets-v2/histogram/download.test.ts +6 -4
- package/src/widgets-v2/histogram/download.ts +5 -4
- package/src/widgets-v2/index.ts +1 -0
- package/src/widgets-v2/markdown/download.test.ts +2 -2
- package/src/widgets-v2/markdown/download.tsx +5 -4
- package/src/widgets-v2/pie/download.test.ts +7 -3
- package/src/widgets-v2/pie/download.ts +5 -4
- package/src/widgets-v2/scatterplot/download.test.ts +4 -2
- package/src/widgets-v2/scatterplot/download.ts +5 -4
- package/src/widgets-v2/spread/download.test.ts +3 -1
- package/src/widgets-v2/spread/download.ts +5 -4
- package/src/widgets-v2/table/download.test.ts +5 -3
- package/src/widgets-v2/table/download.ts +4 -3
- package/src/widgets-v2/timeseries/download.test.ts +6 -4
- package/src/widgets-v2/timeseries/download.ts +5 -4
- package/src/widgets-v2/toolbox/toolbox.tsx +1 -1
- package/dist/actions-iN1jwyxA.js +0 -1024
- package/dist/actions-iN1jwyxA.js.map +0 -1
- package/dist/category-DZt6yiST.js +0 -826
- package/dist/category-DZt6yiST.js.map +0 -1
- package/dist/download-C7he8mSh.js.map +0 -1
- package/dist/echart-BnJYXH7H.js.map +0 -1
- package/dist/formula-Cqj84ZGX.js.map +0 -1
- package/dist/markdown-CV_KP-at.js.map +0 -1
- package/dist/spread-C8T12Nfh.js.map +0 -1
- 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
|
|
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
|
|
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']
|
package/src/widgets-v2/index.ts
CHANGED
|
@@ -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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
*
|