react-cheminfo 0.33.0 → 0.35.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/README.md +28 -28
- package/lib/about/core/about.d.ts +1 -30
- package/lib/about/core/about.d.ts.map +1 -1
- package/lib/about/core/about.js +0 -16
- package/lib/about/core/about.js.map +1 -1
- package/lib/about/core/index.d.ts +0 -1
- package/lib/about/core/index.d.ts.map +1 -1
- package/lib/about/core/index.js +0 -1
- package/lib/about/core/index.js.map +1 -1
- package/lib/about/ui/AboutBuild.d.ts +2 -5
- package/lib/about/ui/AboutBuild.d.ts.map +1 -1
- package/lib/about/ui/AboutBuild.js +7 -19
- package/lib/about/ui/AboutBuild.js.map +1 -1
- package/lib/about/ui/AboutPage.d.ts +2 -2
- package/lib/about/ui/AboutPage.d.ts.map +1 -1
- package/lib/about/ui/AboutPage.js +3 -14
- package/lib/about/ui/AboutPage.js.map +1 -1
- package/lib/about/ui/AboutVersion.d.ts +0 -4
- package/lib/about/ui/AboutVersion.d.ts.map +1 -1
- package/lib/about/ui/AboutVersion.js +3 -31
- package/lib/about/ui/AboutVersion.js.map +1 -1
- package/lib/axis/core/axisMarks.d.ts +54 -0
- package/lib/axis/core/axisMarks.d.ts.map +1 -0
- package/lib/axis/core/axisMarks.js +69 -0
- package/lib/axis/core/axisMarks.js.map +1 -0
- package/lib/axis/core/axisScale.d.ts +31 -0
- package/lib/axis/core/axisScale.d.ts.map +1 -0
- package/lib/axis/core/axisScale.js +31 -0
- package/lib/axis/core/axisScale.js.map +1 -0
- package/lib/axis/core/index.d.ts +16 -0
- package/lib/axis/core/index.d.ts.map +1 -0
- package/lib/axis/core/index.js +13 -0
- package/lib/axis/core/index.js.map +1 -0
- package/lib/axis/core/logAxisBounds.d.ts +78 -0
- package/lib/axis/core/logAxisBounds.d.ts.map +1 -0
- package/lib/axis/core/logAxisBounds.js +129 -0
- package/lib/axis/core/logAxisBounds.js.map +1 -0
- package/lib/axis/ui/AxisScaleControl.d.ts +66 -0
- package/lib/axis/ui/AxisScaleControl.d.ts.map +1 -0
- package/lib/axis/ui/AxisScaleControl.js +26 -0
- package/lib/axis/ui/AxisScaleControl.js.map +1 -0
- package/lib/axis/ui/index.d.ts +6 -0
- package/lib/axis/ui/index.d.ts.map +1 -0
- package/lib/axis/ui/index.js +5 -0
- package/lib/axis/ui/index.js.map +1 -0
- package/lib/core.d.ts +1 -0
- package/lib/core.d.ts.map +1 -1
- package/lib/core.js +1 -0
- package/lib/core.js.map +1 -1
- package/lib/delimited/core/index.d.ts +2 -0
- package/lib/delimited/core/index.d.ts.map +1 -1
- package/lib/delimited/core/index.js +1 -0
- package/lib/delimited/core/index.js.map +1 -1
- package/lib/delimited/core/tableRows.d.ts +49 -0
- package/lib/delimited/core/tableRows.d.ts.map +1 -0
- package/lib/delimited/core/tableRows.js +63 -0
- package/lib/delimited/core/tableRows.js.map +1 -0
- package/lib/delimited/ui/DelimitedTextPanel.d.ts +9 -0
- package/lib/delimited/ui/DelimitedTextPanel.d.ts.map +1 -1
- package/lib/delimited/ui/DelimitedTextPanel.js +3 -2
- package/lib/delimited/ui/DelimitedTextPanel.js.map +1 -1
- package/lib/delimited/ui/TableDataButton.d.ts +96 -0
- package/lib/delimited/ui/TableDataButton.d.ts.map +1 -0
- package/lib/delimited/ui/TableDataButton.js +39 -0
- package/lib/delimited/ui/TableDataButton.js.map +1 -0
- package/lib/delimited/ui/index.d.ts +2 -0
- package/lib/delimited/ui/index.d.ts.map +1 -1
- package/lib/delimited/ui/index.js +1 -0
- package/lib/delimited/ui/index.js.map +1 -1
- package/lib/download/core/index.d.ts +0 -5
- package/lib/download/core/index.d.ts.map +1 -1
- package/lib/download/core/index.js +0 -3
- package/lib/download/core/index.js.map +1 -1
- package/lib/download/ui/FigureDownload.d.ts +4 -55
- package/lib/download/ui/FigureDownload.d.ts.map +1 -1
- package/lib/download/ui/FigureDownload.js +6 -66
- package/lib/download/ui/FigureDownload.js.map +1 -1
- package/lib/download/ui/FigureDownloadPanel.d.ts +16 -2
- package/lib/download/ui/FigureDownloadPanel.d.ts.map +1 -1
- package/lib/download/ui/FigureDownloadPanel.js +11 -30
- package/lib/download/ui/FigureDownloadPanel.js.map +1 -1
- package/lib/download/ui/figureDownloadHint.d.ts +30 -0
- package/lib/download/ui/figureDownloadHint.d.ts.map +1 -0
- package/lib/download/ui/figureDownloadHint.js +33 -0
- package/lib/download/ui/figureDownloadHint.js.map +1 -0
- package/lib/download/ui/index.d.ts +3 -10
- package/lib/download/ui/index.d.ts.map +1 -1
- package/lib/download/ui/index.js +1 -5
- package/lib/download/ui/index.js.map +1 -1
- package/lib/download/ui/useFigureActions.d.ts +50 -0
- package/lib/download/ui/useFigureActions.d.ts.map +1 -0
- package/lib/download/ui/useFigureActions.js +58 -0
- package/lib/download/ui/useFigureActions.js.map +1 -0
- package/lib/download/ui/useFigureDownload.d.ts +85 -0
- package/lib/download/ui/useFigureDownload.d.ts.map +1 -0
- package/lib/download/ui/useFigureDownload.js +75 -0
- package/lib/download/ui/useFigureDownload.js.map +1 -0
- package/lib/ecosystem/core/sites.d.ts.map +1 -1
- package/lib/ecosystem/core/sites.js +0 -40
- package/lib/ecosystem/core/sites.js.map +1 -1
- package/lib/ecosystem/core/types.d.ts +0 -10
- package/lib/ecosystem/core/types.d.ts.map +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
- package/lib/ir/core/irCommands.d.ts +2 -2
- package/lib/ir/core/irCommands.js +2 -2
- package/lib/ir/core/irCommands.js.map +1 -1
- package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -1
- package/lib/ir/ui/IrAboutDialog.js +1 -1
- package/lib/ir/ui/IrAboutDialog.js.map +1 -1
- package/lib/ir/ui/IrCanvas.d.ts +6 -0
- package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
- package/lib/ir/ui/IrCanvas.js +2 -2
- package/lib/ir/ui/IrCanvas.js.map +1 -1
- package/lib/ir/ui/IrShell.d.ts.map +1 -1
- package/lib/ir/ui/IrShell.js +16 -11
- package/lib/ir/ui/IrShell.js.map +1 -1
- package/lib/ir/ui/IrToolbar.d.ts +11 -1
- package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
- package/lib/ir/ui/IrToolbar.js +12 -2
- package/lib/ir/ui/IrToolbar.js.map +1 -1
- package/lib/ir/ui/index.d.ts +1 -0
- package/lib/ir/ui/index.d.ts.map +1 -1
- package/lib/ir/ui/index.js.map +1 -1
- package/lib/locales/de.json +8 -4
- package/lib/locales/en.json +8 -4
- package/lib/locales/es.json +8 -4
- package/lib/locales/fr.json +8 -4
- package/lib/locales/it.json +8 -4
- package/lib/overlay/ui/OverlayPanel.d.ts +6 -0
- package/lib/overlay/ui/OverlayPanel.d.ts.map +1 -1
- package/lib/overlay/ui/OverlayPanel.js +2 -2
- package/lib/overlay/ui/OverlayPanel.js.map +1 -1
- package/lib/overlay/ui/overlayPanelStyles.d.ts +2 -1
- package/lib/overlay/ui/overlayPanelStyles.d.ts.map +1 -1
- package/lib/overlay/ui/overlayPanelStyles.js +3 -1
- package/lib/overlay/ui/overlayPanelStyles.js.map +1 -1
- package/lib/periodic/core/index.d.ts +1 -1
- package/lib/periodic/core/index.d.ts.map +1 -1
- package/lib/periodic/core/index.js +1 -1
- package/lib/periodic/core/index.js.map +1 -1
- package/lib/periodic/core/layout.d.ts +18 -0
- package/lib/periodic/core/layout.d.ts.map +1 -1
- package/lib/periodic/core/layout.js +9 -0
- package/lib/periodic/core/layout.js.map +1 -1
- package/lib/periodic/ui/ElementCell.d.ts +0 -6
- package/lib/periodic/ui/ElementCell.d.ts.map +1 -1
- package/lib/periodic/ui/ElementCell.js +35 -19
- package/lib/periodic/ui/ElementCell.js.map +1 -1
- package/lib/periodic/ui/PeriodicTable.d.ts +12 -1
- package/lib/periodic/ui/PeriodicTable.d.ts.map +1 -1
- package/lib/periodic/ui/PeriodicTable.js +34 -15
- package/lib/periodic/ui/PeriodicTable.js.map +1 -1
- package/lib/ui.d.ts +1 -0
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +1 -0
- package/lib/ui.js.map +1 -1
- package/package.json +1 -1
- package/src/about/core/about.ts +1 -51
- package/src/about/core/index.ts +0 -1
- package/src/about/ui/AboutBuild.tsx +8 -37
- package/src/about/ui/AboutPage.tsx +8 -64
- package/src/about/ui/AboutVersion.tsx +5 -45
- package/src/axis/core/axisMarks.ts +114 -0
- package/src/axis/core/axisScale.ts +41 -0
- package/src/axis/core/index.ts +20 -0
- package/src/axis/core/logAxisBounds.ts +198 -0
- package/src/axis/ui/AxisScaleControl.tsx +103 -0
- package/src/axis/ui/index.ts +9 -0
- package/src/core.ts +1 -0
- package/src/delimited/core/index.ts +2 -0
- package/src/delimited/core/tableRows.ts +93 -0
- package/src/delimited/ui/DelimitedTextPanel.tsx +25 -9
- package/src/delimited/ui/TableDataButton.tsx +162 -0
- package/src/delimited/ui/index.ts +2 -0
- package/src/download/core/index.ts +0 -25
- package/src/download/ui/FigureDownload.tsx +11 -148
- package/src/download/ui/FigureDownloadPanel.tsx +46 -45
- package/src/download/ui/figureDownloadHint.ts +52 -0
- package/src/download/ui/index.ts +6 -10
- package/src/download/ui/useFigureActions.ts +113 -0
- package/src/download/ui/useFigureDownload.tsx +191 -0
- package/src/ecosystem/core/sites.ts +0 -40
- package/src/ecosystem/core/types.ts +0 -10
- package/src/ir/core/irCommands.ts +2 -2
- package/src/ir/ui/IrAboutDialog.tsx +0 -13
- package/src/ir/ui/IrCanvas.tsx +8 -2
- package/src/ir/ui/IrShell.tsx +23 -25
- package/src/ir/ui/IrToolbar.tsx +36 -6
- package/src/ir/ui/index.ts +1 -0
- package/src/locales/de.json +8 -4
- package/src/locales/en.json +8 -4
- package/src/locales/es.json +8 -4
- package/src/locales/fr.json +8 -4
- package/src/locales/it.json +8 -4
- package/src/overlay/ui/OverlayPanel.tsx +8 -2
- package/src/overlay/ui/overlayPanelStyles.ts +3 -0
- package/src/periodic/core/index.ts +1 -0
- package/src/periodic/core/layout.ts +19 -0
- package/src/periodic/ui/ElementCell.tsx +35 -26
- package/src/periodic/ui/PeriodicTable.tsx +55 -16
- package/src/ui.ts +1 -0
- package/styles/chrome.css +71 -0
- package/lib/about/core/repository.d.ts +0 -14
- package/lib/about/core/repository.d.ts.map +0 -1
- package/lib/about/core/repository.js +0 -21
- package/lib/about/core/repository.js.map +0 -1
- package/lib/download/core/exportStyles.d.ts +0 -22
- package/lib/download/core/exportStyles.d.ts.map +0 -1
- package/lib/download/core/exportStyles.js +0 -19
- package/lib/download/core/exportStyles.js.map +0 -1
- package/lib/download/core/imageResolution.d.ts +0 -88
- package/lib/download/core/imageResolution.d.ts.map +0 -1
- package/lib/download/core/imageResolution.js +0 -77
- package/lib/download/core/imageResolution.js.map +0 -1
- package/lib/download/core/pictureExport.d.ts +0 -93
- package/lib/download/core/pictureExport.d.ts.map +0 -1
- package/lib/download/core/pictureExport.js +0 -116
- package/lib/download/core/pictureExport.js.map +0 -1
- package/lib/download/ui/ExportDialogFrame.d.ts +0 -46
- package/lib/download/ui/ExportDialogFrame.d.ts.map +0 -1
- package/lib/download/ui/ExportDialogFrame.js +0 -24
- package/lib/download/ui/ExportDialogFrame.js.map +0 -1
- package/lib/download/ui/ExportImageDialog.d.ts +0 -47
- package/lib/download/ui/ExportImageDialog.d.ts.map +0 -1
- package/lib/download/ui/ExportImageDialog.js +0 -25
- package/lib/download/ui/ExportImageDialog.js.map +0 -1
- package/lib/download/ui/ExportNameField.d.ts +0 -29
- package/lib/download/ui/ExportNameField.d.ts.map +0 -1
- package/lib/download/ui/ExportNameField.js +0 -99
- package/lib/download/ui/ExportNameField.js.map +0 -1
- package/lib/download/ui/ExportPictureSection.d.ts +0 -38
- package/lib/download/ui/ExportPictureSection.d.ts.map +0 -1
- package/lib/download/ui/ExportPictureSection.js +0 -48
- package/lib/download/ui/ExportPictureSection.js.map +0 -1
- package/lib/download/ui/useDrawingBox.d.ts +0 -23
- package/lib/download/ui/useDrawingBox.d.ts.map +0 -1
- package/lib/download/ui/useDrawingBox.js +0 -21
- package/lib/download/ui/useDrawingBox.js.map +0 -1
- package/src/about/core/repository.ts +0 -22
- package/src/download/core/exportStyles.ts +0 -20
- package/src/download/core/imageResolution.ts +0 -118
- package/src/download/core/pictureExport.ts +0 -207
- package/src/download/ui/ExportDialogFrame.tsx +0 -86
- package/src/download/ui/ExportImageDialog.tsx +0 -91
- package/src/download/ui/ExportNameField.tsx +0 -148
- package/src/download/ui/ExportPictureSection.tsx +0 -142
- package/src/download/ui/useDrawingBox.ts +0 -37
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tableRows.d.ts","sourceRoot":"","sources":["../../../src/delimited/core/tableRows.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,uEAAuE;AACvE,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElD,kCAAkC;AAClC,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CACrD;AAED,6CAA6C;AAC7C,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,qCAAqC;IACrC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,OAAO,GAAE,gBAAqB,GAC7B,SAAS,CAUX;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,EAAE,CAWnE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning a list of records into the cells a table is handed over as.
|
|
3
|
+
*
|
|
4
|
+
* Most pages hold their data as one object per row — a query result, a list of
|
|
5
|
+
* peaks, a row of properties — while a delimited table is cells. Every site
|
|
6
|
+
* that exports such a list wrote the same two loops, so they are here once.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The records as the header and cells of a table.
|
|
10
|
+
* @param records - The records, in the order they are shown.
|
|
11
|
+
* @param options - See {@link TableRowsOptions}.
|
|
12
|
+
* @returns See {@link TableRows}.
|
|
13
|
+
*/
|
|
14
|
+
export function tableRows(records, options = {}) {
|
|
15
|
+
const { columns, format = defaultCell } = options;
|
|
16
|
+
const header = [...(columns ?? columnsOf(records))];
|
|
17
|
+
const rows = [];
|
|
18
|
+
for (const record of records) {
|
|
19
|
+
const cells = [];
|
|
20
|
+
for (const column of header)
|
|
21
|
+
cells.push(format(record[column], column));
|
|
22
|
+
rows.push(cells);
|
|
23
|
+
}
|
|
24
|
+
return { header, rows };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Every column the records carry, each named once, in the order first seen.
|
|
28
|
+
*
|
|
29
|
+
* Every record is read rather than only the first, because a list whose later
|
|
30
|
+
* records carry a field the first one happens to lack would otherwise be
|
|
31
|
+
* handed over with that column silently missing.
|
|
32
|
+
* @param records - The records.
|
|
33
|
+
* @returns The column names.
|
|
34
|
+
*/
|
|
35
|
+
export function columnsOf(records) {
|
|
36
|
+
const columns = [];
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
for (const record of records) {
|
|
39
|
+
for (const column of Object.keys(record)) {
|
|
40
|
+
if (seen.has(column))
|
|
41
|
+
continue;
|
|
42
|
+
seen.add(column);
|
|
43
|
+
columns.push(column);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return columns;
|
|
47
|
+
}
|
|
48
|
+
function defaultCell(value) {
|
|
49
|
+
if (value === null || value === undefined)
|
|
50
|
+
return '';
|
|
51
|
+
if (typeof value === 'string')
|
|
52
|
+
return value;
|
|
53
|
+
if (typeof value === 'number' ||
|
|
54
|
+
typeof value === 'bigint' ||
|
|
55
|
+
typeof value === 'boolean') {
|
|
56
|
+
return String(value);
|
|
57
|
+
}
|
|
58
|
+
// Anything else left in a cell has no honest text form, and `[object Object]`
|
|
59
|
+
// is the one answer a spreadsheet can do nothing with. JSON at least says
|
|
60
|
+
// what was there; a caller who wants better passes `format`.
|
|
61
|
+
return JSON.stringify(value) ?? '';
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=tableRows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tableRows.js","sourceRoot":"","sources":["../../../src/delimited/core/tableRows.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA6BH;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CACvB,OAA+B,EAC/B,UAA4B,EAAE;IAE9B,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC;IAClD,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,MAAM,IAAI,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,OAA+B;IACvD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,SAAS;YAC/B,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,SAAS,EAC1B,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,8EAA8E;IAC9E,0EAA0E;IAC1E,6DAA6D;IAC7D,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -41,6 +41,15 @@ export interface DelimitedTextPanelProps {
|
|
|
41
41
|
* @default 320
|
|
42
42
|
*/
|
|
43
43
|
height?: number;
|
|
44
|
+
/**
|
|
45
|
+
* What is shown in place of the text area. A caller with more rows than a
|
|
46
|
+
* text area can hold — a spectrum of a hundred thousand points — passes its
|
|
47
|
+
* own virtualized table here; what is copied and what is saved stay the
|
|
48
|
+
* serialized text either way, so the preview can shorten a number the file
|
|
49
|
+
* keeps in full.
|
|
50
|
+
* @default undefined — the text itself, in a read-only text area
|
|
51
|
+
*/
|
|
52
|
+
preview?: ReactNode;
|
|
44
53
|
/**
|
|
45
54
|
* Class names added to the root element, after the component's own.
|
|
46
55
|
* @default undefined
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DelimitedTextPanel.d.ts","sourceRoot":"","sources":["../../../src/delimited/ui/DelimitedTextPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAUpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIzD,8CAA8C;AAC9C,MAAM,WAAW,uBAAuB;IACtC,qCAAqC;IACrC,IAAI,EAAE,aAAa,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IACvC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,uBAAuB,GAC7B,YAAY,
|
|
1
|
+
{"version":3,"file":"DelimitedTextPanel.d.ts","sourceRoot":"","sources":["../../../src/delimited/ui/DelimitedTextPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAUpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIzD,8CAA8C;AAC9C,MAAM,WAAW,uBAAuB;IACtC,qCAAqC;IACrC,IAAI,EAAE,aAAa,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IACvC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,uBAAuB,GAC7B,YAAY,CAiFd"}
|
|
@@ -21,7 +21,7 @@ import { toDelimited } from "../core/toDelimited.js";
|
|
|
21
21
|
* @returns The panel.
|
|
22
22
|
*/
|
|
23
23
|
export function DelimitedTextPanel(props) {
|
|
24
|
-
const { className, rows, header, description, fileName = 'table', defaultDelimiter = 'tab', downloadable = true, label, height = 320, } = props;
|
|
24
|
+
const { className, rows, header, description, fileName = 'table', defaultDelimiter = 'tab', downloadable = true, label, height = 320, preview, } = props;
|
|
25
25
|
const t = useChromeT();
|
|
26
26
|
const [delimiterId, setDelimiterId] = useState(defaultDelimiter);
|
|
27
27
|
const choice = delimiterChoice(delimiterId);
|
|
@@ -32,7 +32,7 @@ export function DelimitedTextPanel(props) {
|
|
|
32
32
|
: 'delimited.descriptionMany', { count: formatInteger(rows.length) }) }), _jsxs("div", { style: CONTROLS_STYLE, children: [_jsx("span", { style: LABEL_STYLE, children: t('delimited.separator') }), _jsx(SegmentedControl, { size: "small", options: DELIMITER_CHOICES.map((option) => ({
|
|
33
33
|
label: option.label,
|
|
34
34
|
value: option.id,
|
|
35
|
-
})), value: choice.id, onValueChange: setDelimiterId }), _jsx("span", { style: SPACER_STYLE }), downloadable ? (_jsx(Button, { icon: "download", text: t('delimited.save'), size: "small", onClick: () => downloadText(text, `${sanitizeFileName(fileName, 'table')}.${choice.extension}`, `${choice.mimeType};charset=utf-8`) })) : null, _jsx(CopyButton, { content: text, label: t('delimited.copy'), icon: "clipboard", small: true })] }), _jsx("textarea", { readOnly: true, value: text, spellCheck: false, "aria-label": label ?? t('delimited.tableAsText'), className: Classes.INPUT, style: { ...TEXT_STYLE, height }, onFocus: (event) => event.currentTarget.select() })] }));
|
|
35
|
+
})), value: choice.id, onValueChange: setDelimiterId }), _jsx("span", { style: SPACER_STYLE }), downloadable ? (_jsx(Button, { icon: "download", text: t('delimited.save'), size: "small", onClick: () => downloadText(text, `${sanitizeFileName(fileName, 'table')}.${choice.extension}`, `${choice.mimeType};charset=utf-8`) })) : null, _jsx(CopyButton, { content: text, label: t('delimited.copy'), icon: "clipboard", small: true })] }), preview === undefined ? (_jsx("textarea", { readOnly: true, value: text, spellCheck: false, "aria-label": label ?? t('delimited.tableAsText'), className: Classes.INPUT, style: { ...TEXT_STYLE, height }, onFocus: (event) => event.currentTarget.select() })) : (_jsx("div", { style: PREVIEW_STYLE, children: preview }))] }));
|
|
36
36
|
}
|
|
37
37
|
const CONTROLS_STYLE = {
|
|
38
38
|
display: 'flex',
|
|
@@ -46,6 +46,7 @@ const LABEL_STYLE = {
|
|
|
46
46
|
fontSize: 12,
|
|
47
47
|
};
|
|
48
48
|
const SPACER_STYLE = { flex: 1 };
|
|
49
|
+
const PREVIEW_STYLE = { marginTop: 12 };
|
|
49
50
|
const TEXT_STYLE = {
|
|
50
51
|
width: '100%',
|
|
51
52
|
marginTop: 12,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DelimitedTextPanel.js","sourceRoot":"","sources":["../../../src/delimited/ui/DelimitedTextPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE/E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAmC,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"DelimitedTextPanel.js","sourceRoot":"","sources":["../../../src/delimited/ui/DelimitedTextPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE/E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAmC,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AA2DrD;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAA8B;IAE9B,MAAM,EACJ,SAAS,EACT,IAAI,EACJ,MAAM,EACN,WAAW,EACX,QAAQ,GAAG,OAAO,EAClB,gBAAgB,GAAG,KAAK,EACxB,YAAY,GAAG,IAAI,EACnB,KAAK,EACL,MAAM,GAAG,GAAG,EACZ,OAAO,GACR,GAAG,KAAK,CAAC;IACV,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IACvB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAS,gBAAgB,CAAC,CAAC;IAEzE,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,OAAO,CAClB,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,EAChE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CACjC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAE,cAAc,CAAC,gBAAgB,EAAE,SAAS,CAAC,aACzD,KAAC,OAAO,IAAC,MAAM,EAAC,SAAS,EAAC,OAAO,QAAC,IAAI,EAAC,WAAW,YAC/C,WAAW;oBACV,CAAC,CACC,IAAI,CAAC,MAAM,KAAK,CAAC;wBACf,CAAC,CAAC,0BAA0B;wBAC5B,CAAC,CAAC,2BAA2B,EAC/B,EAAE,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CACtC,GACK,EACV,eAAK,KAAK,EAAE,cAAc,aACxB,eAAM,KAAK,EAAE,WAAW,YAAG,CAAC,CAAC,qBAAqB,CAAC,GAAQ,EAC3D,KAAC,gBAAgB,IACf,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;4BAC1C,KAAK,EAAE,MAAM,CAAC,KAAK;4BACnB,KAAK,EAAE,MAAM,CAAC,EAAE;yBACjB,CAAC,CAAC,EACH,KAAK,EAAE,MAAM,CAAC,EAAE,EAChB,aAAa,EAAE,cAAc,GAC7B,EACF,eAAM,KAAK,EAAE,YAAY,GAAI,EAC5B,YAAY,CAAC,CAAC,CAAC,CACd,KAAC,MAAM,IACL,IAAI,EAAC,UAAU,EACf,IAAI,EAAE,CAAC,CAAC,gBAAgB,CAAC,EACzB,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,GAAG,EAAE,CACZ,YAAY,CACV,IAAI,EACJ,GAAG,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,EAC5D,GAAG,MAAM,CAAC,QAAQ,gBAAgB,CACnC,GAEH,CACH,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,UAAU,IACT,OAAO,EAAE,IAAI,EACb,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,EAC1B,IAAI,EAAC,WAAW,EAChB,KAAK,SACL,IACE,EACL,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CACvB,mBACE,QAAQ,QACR,KAAK,EAAE,IAAI,EACX,UAAU,EAAE,KAAK,gBACL,KAAK,IAAI,CAAC,CAAC,uBAAuB,CAAC,EAC/C,SAAS,EAAE,OAAO,CAAC,KAAK,EACxB,KAAK,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,EAChC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,GAChD,CACH,CAAC,CAAC,CAAC,CACF,cAAK,KAAK,EAAE,aAAa,YAAG,OAAO,GAAO,CAC3C,IACG,CACP,CAAC;AACJ,CAAC;AAED,MAAM,cAAc,GAAG;IACrB,OAAO,EAAE,MAAM;IACf,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,QAAQ;IACpB,GAAG,EAAE,CAAC;IACN,SAAS,EAAE,EAAE;CACmB,CAAC;AAEnC,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,KAAK,CAAC,SAAS;IACtB,QAAQ,EAAE,EAAE;CACoB,CAAC;AAEnC,MAAM,YAAY,GAAG,EAAE,IAAI,EAAE,CAAC,EAAmC,CAAC;AAElE,MAAM,aAAa,GAAG,EAAE,SAAS,EAAE,EAAE,EAAmC,CAAC;AAEzE,MAAM,UAAU,GAAG;IACjB,KAAK,EAAE,MAAM;IACb,SAAS,EAAE,EAAE;IACb,SAAS,EAAE,YAAY;IACvB,UAAU,EAAE,gDAAgD;IAC5D,QAAQ,EAAE,EAAE;IACZ,SAAS,EAAE,MAAM;IACjB,YAAY,EAAE,QAAQ;IACtB,UAAU,EAAE,KAAK;CACe,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { IconName } from '@blueprintjs/core';
|
|
2
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
3
|
+
import type { DelimitedTextDialogProps } from './DelimitedTextDialog.tsx';
|
|
4
|
+
/** The cells of a table, one array per line. */
|
|
5
|
+
type TableRows = ReadonlyArray<readonly string[]>;
|
|
6
|
+
/** What {@link TableDataButton} hands over, and how the button reads. */
|
|
7
|
+
export interface TableDataButtonProps extends Omit<DelimitedTextDialogProps, 'isOpen' | 'onClose' | 'rows'> {
|
|
8
|
+
/**
|
|
9
|
+
* The cells, one array per line. A function is called when the dialog opens
|
|
10
|
+
* and not before, which is what a table built out of a computation has to
|
|
11
|
+
* be: formatting a thousand points into strings on every render, for a
|
|
12
|
+
* button nobody may press, is a page that stutters while it is used.
|
|
13
|
+
*/
|
|
14
|
+
rows: TableRows | (() => TableRows);
|
|
15
|
+
/**
|
|
16
|
+
* Text of the button. Left out for an icon-only button, which is what a
|
|
17
|
+
* dense toolbar over a table wants.
|
|
18
|
+
* @default undefined — the button is reduced to its icon
|
|
19
|
+
*/
|
|
20
|
+
text?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Glyph on the button.
|
|
23
|
+
* @default 'th'
|
|
24
|
+
*/
|
|
25
|
+
icon?: IconName;
|
|
26
|
+
/**
|
|
27
|
+
* Whether the button drops its background, for a toolbar or a card header.
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
minimal?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Whether the button is the small size.
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
small?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* What the pointer and a screen reader are told. The dialog's own `title`
|
|
38
|
+
* names the table — `Titration curve as a table` — while this names the
|
|
39
|
+
* affordance, and the two are deliberately not the same string: the heading
|
|
40
|
+
* is the site's to write, the button's name is the family's, so the control
|
|
41
|
+
* reads the same on every tool a visitor opens that week.
|
|
42
|
+
* @default the chrome's own line, in the language of the page
|
|
43
|
+
*/
|
|
44
|
+
tooltip?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Whether there is nothing to hand over. A table that has not been computed
|
|
47
|
+
* yet says so by being greyed rather than by opening an empty dialog.
|
|
48
|
+
* @default whether there are no rows — and `false` where `rows` is a
|
|
49
|
+
* function, which is not called to find out
|
|
50
|
+
*/
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Class the button carries, so a site can reach it from its stylesheet — a
|
|
54
|
+
* terminal whose green the chrome's muted grey is unreadable against, a
|
|
55
|
+
* toolbar with its own metrics.
|
|
56
|
+
* @default undefined
|
|
57
|
+
*/
|
|
58
|
+
buttonClassName?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Value of the `data-testid` attribute of the button.
|
|
61
|
+
* @default undefined
|
|
62
|
+
*/
|
|
63
|
+
testId?: string;
|
|
64
|
+
/**
|
|
65
|
+
* The control in place of the Blueprint button, for a page whose chrome is
|
|
66
|
+
* not Blueprint's — a `react-science` toolbar, a site's own toolbar button.
|
|
67
|
+
* It is handed the function that opens the dialog.
|
|
68
|
+
*
|
|
69
|
+
* It exists so the dialog, the separator, the copy, the save and the wording
|
|
70
|
+
* are shared even where the button cannot be: a site that keeps its own
|
|
71
|
+
* trigger should not also be keeping its own dialog.
|
|
72
|
+
* @default a Blueprint button carrying the glyph and the text
|
|
73
|
+
*/
|
|
74
|
+
trigger?: (open: () => void) => ReactNode;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The one control that takes a table off the page: copy it, or save it.
|
|
78
|
+
*
|
|
79
|
+
* It is a button and a dialog together rather than a dialog a site has to hold
|
|
80
|
+
* open itself, because the state behind it is the same three lines in every
|
|
81
|
+
* site and because the wording is not a site's to choose. An audit in
|
|
82
|
+
* September 2026 found the same affordance spelled `Export as TSV` on one
|
|
83
|
+
* site, `Copy as TSV` on another and `Copy or download data` on a third, which
|
|
84
|
+
* reads as three different features to anybody who uses two of our tools in a
|
|
85
|
+
* week.
|
|
86
|
+
*
|
|
87
|
+
* It is also deliberately not named after a separator. The dialog behind it
|
|
88
|
+
* writes tab-, comma- or semicolon-separated text, so a button that says TSV
|
|
89
|
+
* is wrong two times out of three — and a reader looking for CSV concludes the
|
|
90
|
+
* tool cannot give it to them.
|
|
91
|
+
* @param props - See {@link TableDataButtonProps}.
|
|
92
|
+
* @returns The button and its dialog.
|
|
93
|
+
*/
|
|
94
|
+
export declare function TableDataButton(props: TableDataButtonProps): ReactElement;
|
|
95
|
+
export {};
|
|
96
|
+
//# sourceMappingURL=TableDataButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableDataButton.d.ts","sourceRoot":"","sources":["../../../src/delimited/ui/TableDataButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAG1E,gDAAgD;AAChD,KAAK,SAAS,GAAG,aAAa,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;AAKlD,yEAAyE;AACzE,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,wBAAwB,EACxB,QAAQ,GAAG,SAAS,GAAG,MAAM,CAC9B;IACC;;;;;OAKG;IACH,IAAI,EAAE,SAAS,GAAG,CAAC,MAAM,SAAS,CAAC,CAAC;IACpC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CAqDzE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@blueprintjs/core';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { useChromeT } from "../../i18n/ui/useT.js";
|
|
5
|
+
import { DelimitedTextDialog } from "./DelimitedTextDialog.js";
|
|
6
|
+
/** What the shut dialog is handed, so it holds no copy of the last table. */
|
|
7
|
+
const EMPTY = [];
|
|
8
|
+
/**
|
|
9
|
+
* The one control that takes a table off the page: copy it, or save it.
|
|
10
|
+
*
|
|
11
|
+
* It is a button and a dialog together rather than a dialog a site has to hold
|
|
12
|
+
* open itself, because the state behind it is the same three lines in every
|
|
13
|
+
* site and because the wording is not a site's to choose. An audit in
|
|
14
|
+
* September 2026 found the same affordance spelled `Export as TSV` on one
|
|
15
|
+
* site, `Copy as TSV` on another and `Copy or download data` on a third, which
|
|
16
|
+
* reads as three different features to anybody who uses two of our tools in a
|
|
17
|
+
* week.
|
|
18
|
+
*
|
|
19
|
+
* It is also deliberately not named after a separator. The dialog behind it
|
|
20
|
+
* writes tab-, comma- or semicolon-separated text, so a button that says TSV
|
|
21
|
+
* is wrong two times out of three — and a reader looking for CSV concludes the
|
|
22
|
+
* tool cannot give it to them.
|
|
23
|
+
* @param props - See {@link TableDataButtonProps}.
|
|
24
|
+
* @returns The button and its dialog.
|
|
25
|
+
*/
|
|
26
|
+
export function TableDataButton(props) {
|
|
27
|
+
const { rows, text, icon = 'th', minimal = true, small = false, tooltip, disabled, testId, trigger, buttonClassName, ...dialog } = props;
|
|
28
|
+
const t = useChromeT();
|
|
29
|
+
// The cells are held rather than read on every render, so a `rows` function
|
|
30
|
+
// is called once per opening and the closed button costs nothing at all.
|
|
31
|
+
const [shown, setShown] = useState(null);
|
|
32
|
+
const told = tooltip ?? t('delimited.copyOrDownload');
|
|
33
|
+
const nothing = disabled ?? (typeof rows === 'function' ? false : rows.length === 0);
|
|
34
|
+
function show() {
|
|
35
|
+
setShown(typeof rows === 'function' ? rows() : rows);
|
|
36
|
+
}
|
|
37
|
+
return (_jsxs(_Fragment, { children: [trigger ? (trigger(show)) : (_jsx(Button, { className: buttonClassName, icon: icon, text: text, variant: minimal ? 'minimal' : 'solid', size: small ? 'small' : 'medium', disabled: nothing, title: told, "aria-label": text ?? told, "data-testid": testId, onClick: show })), _jsx(DelimitedTextDialog, { ...dialog, rows: shown ?? EMPTY, isOpen: shown !== null, onClose: () => setShown(null) })] }));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=TableDataButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableDataButton.js","sourceRoot":"","sources":["../../../src/delimited/ui/TableDataButton.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA2B,CAAC;AAKhE,6EAA6E;AAC7E,MAAM,KAAK,GAAc,EAAE,CAAC;AA4E5B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,GAAG,IAAI,EACX,OAAO,GAAG,IAAI,EACd,KAAK,GAAG,KAAK,EACb,OAAO,EACP,QAAQ,EACR,MAAM,EACN,OAAO,EACP,eAAe,EACf,GAAG,MAAM,EACV,GAAG,KAAK,CAAC;IACV,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IACvB,4EAA4E;IAC5E,yEAAyE;IACzE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAmB,IAAI,CAAC,CAAC;IAE3D,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC,0BAA0B,CAAC,CAAC;IACtD,MAAM,OAAO,GACX,QAAQ,IAAI,CAAC,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IAEvE,SAAS,IAAI;QACX,QAAQ,CAAC,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,CACL,8BACG,OAAO,CAAC,CAAC,CAAC,CACT,OAAO,CAAC,IAAI,CAAC,CACd,CAAC,CAAC,CAAC,CACF,KAAC,MAAM,IACL,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EACtC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAChC,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,IAAI,gBACC,IAAI,IAAI,IAAI,iBACX,MAAM,EACnB,OAAO,EAAE,IAAI,GACb,CACH,EACD,KAAC,mBAAmB,OACd,MAAM,EACV,IAAI,EAAE,KAAK,IAAI,KAAK,EACpB,MAAM,EAAE,KAAK,KAAK,IAAI,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAC7B,IACD,CACJ,CAAC;AACJ,CAAC"}
|
|
@@ -2,4 +2,6 @@ export type { DelimitedTextDialogProps } from './DelimitedTextDialog.tsx';
|
|
|
2
2
|
export { DelimitedTextDialog } from './DelimitedTextDialog.tsx';
|
|
3
3
|
export type { DelimitedTextPanelProps } from './DelimitedTextPanel.tsx';
|
|
4
4
|
export { DelimitedTextPanel } from './DelimitedTextPanel.tsx';
|
|
5
|
+
export type { TableDataButtonProps } from './TableDataButton.tsx';
|
|
6
|
+
export { TableDataButton } from './TableDataButton.tsx';
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/delimited/ui/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/delimited/ui/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/delimited/ui/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA2B,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/delimited/ui/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA2B,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAA0B,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAuB,CAAC"}
|
|
@@ -19,11 +19,6 @@ export { figureLegendMarkup } from './figureLegend.ts';
|
|
|
19
19
|
export type { FigureBounds } from './figureTarget.ts';
|
|
20
20
|
export { figureBounds, figureDrawings, figureElement, figureLegends, figureSize, } from './figureTarget.ts';
|
|
21
21
|
export { sanitizeFileName } from './sanitizeFileName.ts';
|
|
22
|
-
export { exportButtonsStyle, exportNoteStyle, exportSectionStyle, } from './exportStyles.ts';
|
|
23
|
-
export type { ImageResolution, ImageResolutionId, ImageSize, } from './imageResolution.ts';
|
|
24
|
-
export { DEFAULT_IMAGE_RESOLUTION, IMAGE_RESOLUTIONS, formatImageSize, imageResolution, imageSize, } from './imageResolution.ts';
|
|
25
|
-
export type { PictureFrame, PictureOptions } from './pictureExport.ts';
|
|
26
|
-
export { PICTURE_PADDING, copyPicture, pictureSize, savePngPicture, saveSvgPicture, } from './pictureExport.ts';
|
|
27
22
|
export { drawingIn, stackDrawings } from './stackedDrawing.ts';
|
|
28
23
|
export type { SvgBox } from './svgBounds.ts';
|
|
29
24
|
export { CONTENT_ATTRIBUTE, contentBox, elementBox } from './svgBounds.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/download/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EACV,WAAW,EACX,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,aAAa,EACb,UAAU,GACX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/download/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EACV,WAAW,EACX,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,aAAa,EACb,UAAU,GACX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC/D,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -11,9 +11,6 @@ export { figureSvgDocument } from "./figureSvgDocument.js";
|
|
|
11
11
|
export { figureLegendMarkup } from "./figureLegend.js";
|
|
12
12
|
export { figureBounds, figureDrawings, figureElement, figureLegends, figureSize, } from "./figureTarget.js";
|
|
13
13
|
export { sanitizeFileName } from "./sanitizeFileName.js";
|
|
14
|
-
export { exportButtonsStyle, exportNoteStyle, exportSectionStyle, } from "./exportStyles.js";
|
|
15
|
-
export { DEFAULT_IMAGE_RESOLUTION, IMAGE_RESOLUTIONS, formatImageSize, imageResolution, imageSize, } from "./imageResolution.js";
|
|
16
|
-
export { PICTURE_PADDING, copyPicture, pictureSize, savePngPicture, saveSvgPicture, } from "./pictureExport.js";
|
|
17
14
|
export { drawingIn, stackDrawings } from "./stackedDrawing.js";
|
|
18
15
|
export { CONTENT_ATTRIBUTE, contentBox, elementBox } from "./svgBounds.js";
|
|
19
16
|
export { SVG_NAMESPACE } from "./svgNamespace.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/download/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAK5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAO3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,aAAa,EACb,UAAU,GACX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/download/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAK5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAO3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,aAAa,EACb,UAAU,GACX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -1,55 +1,13 @@
|
|
|
1
1
|
import type { IconName } from '@blueprintjs/core';
|
|
2
2
|
import type { ReactElement } from 'react';
|
|
3
|
-
import type {
|
|
4
|
-
import type { FigureRenderer } from './useFigureRedraw.tsx';
|
|
3
|
+
import type { FigureDownloadOptions } from './useFigureDownload.tsx';
|
|
5
4
|
/** What {@link FigureDownload} needs. */
|
|
6
|
-
export interface FigureDownloadProps {
|
|
7
|
-
/**
|
|
8
|
-
* The `id` of the box the figure is mounted in. Everything drawn inside it
|
|
9
|
-
* is saved — sixteen charts of a pair grid as readily as one scatter plot —
|
|
10
|
-
* and the controls floating over it are left behind.
|
|
11
|
-
*/
|
|
12
|
-
targetId: string;
|
|
13
|
-
/**
|
|
14
|
-
* What the saved file is called, without its extension. Name it after the
|
|
15
|
-
* data rather than after the tool: a reader with four of these in a
|
|
16
|
-
* downloads folder cannot tell four `figure.png` apart.
|
|
17
|
-
* @default 'figure'
|
|
18
|
-
*/
|
|
19
|
-
fileName?: string;
|
|
20
|
-
/**
|
|
21
|
-
* The format it opens on.
|
|
22
|
-
* @default 'png'
|
|
23
|
-
*/
|
|
24
|
-
defaultFormat?: FigureFormat;
|
|
25
|
-
/**
|
|
26
|
-
* The resolution a PNG opens on, as a multiple of the figure on screen. An
|
|
27
|
-
* SVG opens at 1×, the size it has on screen, and each format keeps the
|
|
28
|
-
* multiple the reader last picked for it.
|
|
29
|
-
* @default 2
|
|
30
|
-
*/
|
|
31
|
-
defaultScale?: number;
|
|
32
|
-
/**
|
|
33
|
-
* The resolutions offered.
|
|
34
|
-
* @default [1, 2, 3, 4]
|
|
35
|
-
*/
|
|
36
|
-
scales?: readonly number[];
|
|
37
|
-
/**
|
|
38
|
-
* What is painted under the figure. `transparent` leaves it unpainted, for a
|
|
39
|
-
* figure going onto a coloured slide.
|
|
40
|
-
* @default the surface the figure is drawn on
|
|
41
|
-
*/
|
|
42
|
-
background?: string;
|
|
5
|
+
export interface FigureDownloadProps extends FigureDownloadOptions {
|
|
43
6
|
/**
|
|
44
7
|
* What the glyph is called, for the pointer and for a screen reader.
|
|
45
8
|
* @default the chrome's own line, in the language of the page
|
|
46
9
|
*/
|
|
47
10
|
label?: string;
|
|
48
|
-
/**
|
|
49
|
-
* What the panel behind it is called.
|
|
50
|
-
* @default the chrome's own line, in the language of the page
|
|
51
|
-
*/
|
|
52
|
-
title?: string;
|
|
53
11
|
/**
|
|
54
12
|
* Its glyph.
|
|
55
13
|
* @default 'download'
|
|
@@ -60,19 +18,10 @@ export interface FigureDownloadProps {
|
|
|
60
18
|
* @default undefined
|
|
61
19
|
*/
|
|
62
20
|
testId?: string;
|
|
63
|
-
/**
|
|
64
|
-
* Draws the figure at a size, for a file. When it is given the panel offers
|
|
65
|
-
* a size — as shown, 4:3, 16:9, a journal column, or typed — and a figure
|
|
66
|
-
* saved at a size other than its own is drawn again at that size, off the
|
|
67
|
-
* page, so its axes and labels are laid out for the new shape rather than
|
|
68
|
-
* stretched into it. Draw exactly what is on screen, with the same data,
|
|
69
|
-
* zoom and colours; only the box changes.
|
|
70
|
-
* @default undefined — the figure is saved at the size it has on screen
|
|
71
|
-
*/
|
|
72
|
-
renderFigure?: FigureRenderer;
|
|
73
21
|
}
|
|
74
22
|
/**
|
|
75
|
-
* The glyph that takes the figure off the page as a file
|
|
23
|
+
* The glyph that takes the figure off the page, as a file or onto the
|
|
24
|
+
* clipboard.
|
|
76
25
|
*
|
|
77
26
|
* It works from the `id` of the box the figure is mounted in rather than from
|
|
78
27
|
* the figure itself, so the control is free to sit in the bar above the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FigureDownload.d.ts","sourceRoot":"","sources":["../../../src/download/ui/FigureDownload.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAK1C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"FigureDownload.d.ts","sourceRoot":"","sources":["../../../src/download/ui/FigureDownload.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAK1C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGrE,yCAAyC;AACzC,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB;IAChE;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CAyBvE"}
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PopoverNext } from '@blueprintjs/core';
|
|
3
|
-
import { useState } from 'react';
|
|
4
3
|
import { useChromeT } from "../../i18n/ui/useT.js";
|
|
5
4
|
import { OverlayIconButton } from "../../overlay/ui/OverlayIconButton.js";
|
|
6
|
-
import {
|
|
7
|
-
import { figureLayoutRedraws, figureLayoutSize } from "../core/figureLayout.js";
|
|
8
|
-
import { DEFAULT_FIGURE_SCALE, FIGURE_SCALES, defaultFigureScale, } from "../core/figureScale.js";
|
|
9
|
-
import { figureSize } from "../core/figureTarget.js";
|
|
10
|
-
import { FigureDownloadPanel } from "./FigureDownloadPanel.js";
|
|
11
|
-
import { useFigureRedraw } from "./useFigureRedraw.js";
|
|
5
|
+
import { useFigureDownload } from "./useFigureDownload.js";
|
|
12
6
|
/**
|
|
13
|
-
* The glyph that takes the figure off the page as a file
|
|
7
|
+
* The glyph that takes the figure off the page, as a file or onto the
|
|
8
|
+
* clipboard.
|
|
14
9
|
*
|
|
15
10
|
* It works from the `id` of the box the figure is mounted in rather than from
|
|
16
11
|
* the figure itself, so the control is free to sit in the bar above the
|
|
@@ -30,64 +25,9 @@ import { useFigureRedraw } from "./useFigureRedraw.js";
|
|
|
30
25
|
* @returns The glyph and its panel.
|
|
31
26
|
*/
|
|
32
27
|
export function FigureDownload(props) {
|
|
33
|
-
const {
|
|
34
|
-
const { defaultFormat = 'png', defaultScale = DEFAULT_FIGURE_SCALE } = props;
|
|
35
|
-
const { label, title } = props;
|
|
36
|
-
const { icon = 'download', testId, renderFigure } = props;
|
|
28
|
+
const { label, icon = 'download', testId, ...options } = props;
|
|
37
29
|
const t = useChromeT();
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
const [picked, setPicked] = useState(() => ({
|
|
41
|
-
png: defaultScale,
|
|
42
|
-
svg: defaultFigureScale('svg'),
|
|
43
|
-
}));
|
|
44
|
-
const scale = picked[format];
|
|
45
|
-
const [size, setSize] = useState(null);
|
|
46
|
-
const [failure, setFailure] = useState(null);
|
|
47
|
-
const [saving, setSaving] = useState(false);
|
|
48
|
-
const [layout, setLayout] = useState('screen');
|
|
49
|
-
const [custom, setCustom] = useState(null);
|
|
50
|
-
const { redraw, portal } = useFigureRedraw(renderFigure);
|
|
51
|
-
// The panel is held open from here rather than left to itself, because the
|
|
52
|
-
// figure has to be measured at the moment it opens: its size is what the
|
|
53
|
-
// panel writes out, and reading a bounding box on every render would cost a
|
|
54
|
-
// layout pass on a bar that is re-rendered on every pointer move.
|
|
55
|
-
function interact(next) {
|
|
56
|
-
setOpen(next);
|
|
57
|
-
if (!next)
|
|
58
|
-
return;
|
|
59
|
-
setSize(figureSize(targetId));
|
|
60
|
-
setFailure(null);
|
|
61
|
-
}
|
|
62
|
-
async function save() {
|
|
63
|
-
setSaving(true);
|
|
64
|
-
try {
|
|
65
|
-
const options = { format, scale, fileName, background };
|
|
66
|
-
if (renderFigure !== undefined &&
|
|
67
|
-
size !== null &&
|
|
68
|
-
figureLayoutRedraws(layout, size, custom ?? size)) {
|
|
69
|
-
const drawn = figureLayoutSize(layout, size, custom ?? size);
|
|
70
|
-
await redraw(targetId, drawn, (box) => downloadFigure(box, options));
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
await downloadFigure(targetId, options);
|
|
74
|
-
}
|
|
75
|
-
setFailure(null);
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
setFailure(error instanceof Error ? error.message : String(error));
|
|
79
|
-
}
|
|
80
|
-
finally {
|
|
81
|
-
setSaving(false);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return (_jsxs(_Fragment, { children: [_jsx(PopoverNext, { isOpen: open, placement: "bottom-end", onInteraction: interact, content: _jsx(FigureDownloadPanel, { title: title ?? t('download.saveFigure'), format: format, scale: scale, scales: scales, size: size, failure: failure, saving: saving, onFormatChange: setFormat, onScaleChange: (next) => setPicked((current) => ({ ...current, [format]: next })), onSave: () => void save(), sizing: renderFigure === undefined
|
|
85
|
-
? undefined
|
|
86
|
-
: {
|
|
87
|
-
layout,
|
|
88
|
-
custom,
|
|
89
|
-
onLayoutChange: setLayout,
|
|
90
|
-
onCustomChange: setCustom,
|
|
91
|
-
} }), children: _jsx(OverlayIconButton, { icon: icon, label: label ?? t('download.saveThisFigure'), value: format.toUpperCase(), active: open, testId: testId, opensMenu: true }) }), portal] }));
|
|
30
|
+
const { isOpen, setOpen, panel, format, portal } = useFigureDownload(options);
|
|
31
|
+
return (_jsxs(_Fragment, { children: [_jsx(PopoverNext, { isOpen: isOpen, placement: "bottom-end", onInteraction: setOpen, content: panel, children: _jsx(OverlayIconButton, { icon: icon, label: label ?? t('download.saveThisFigure'), value: format.toUpperCase(), active: isOpen, testId: testId, opensMenu: true }) }), portal] }));
|
|
92
32
|
}
|
|
93
33
|
//# sourceMappingURL=FigureDownload.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FigureDownload.js","sourceRoot":"","sources":["../../../src/download/ui/FigureDownload.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"FigureDownload.js","sourceRoot":"","sources":["../../../src/download/ui/FigureDownload.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAwC,CAAC;AAG3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAyB,CAAC;AAqB5D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,cAAc,CAAC,KAA0B;IACvD,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC;IAC/D,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE9E,OAAO,CACL,8BACE,KAAC,WAAW,IACV,MAAM,EAAE,MAAM,EACd,SAAS,EAAC,YAAY,EACtB,aAAa,EAAE,OAAO,EACtB,OAAO,EAAE,KAAK,YAEd,KAAC,iBAAiB,IAChB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC,yBAAyB,CAAC,EAC5C,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,EAC3B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,SACT,GACU,EACb,MAAM,IACN,CACJ,CAAC;AACJ,CAAC"}
|
|
@@ -2,6 +2,7 @@ import type { ReactElement } from 'react';
|
|
|
2
2
|
import type { FigureFormat } from '../core/downloadFigure.ts';
|
|
3
3
|
import type { FigurePixels } from '../core/figureScale.ts';
|
|
4
4
|
import type { FigureSizing } from './FigureSizeRows.tsx';
|
|
5
|
+
import type { FigureNotice } from './useFigureActions.ts';
|
|
5
6
|
/** What {@link FigureDownloadPanel} is drawn from. */
|
|
6
7
|
export interface FigureDownloadPanelProps {
|
|
7
8
|
/** What the panel is called. */
|
|
@@ -16,7 +17,13 @@ export interface FigureDownloadPanelProps {
|
|
|
16
17
|
size: FigurePixels | null;
|
|
17
18
|
/** What went wrong the last time save was pressed, if anything. */
|
|
18
19
|
failure: string | null;
|
|
19
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* What the last copy came to, while the choices it was made with still
|
|
22
|
+
* stand.
|
|
23
|
+
* @default null
|
|
24
|
+
*/
|
|
25
|
+
notice?: FigureNotice | null;
|
|
26
|
+
/** Whether a file or a copy is being written right now. */
|
|
20
27
|
saving: boolean;
|
|
21
28
|
/** Called with the format the reader picked. */
|
|
22
29
|
onFormatChange: (format: FigureFormat) => void;
|
|
@@ -24,6 +31,12 @@ export interface FigureDownloadPanelProps {
|
|
|
24
31
|
onScaleChange: (scale: number) => void;
|
|
25
32
|
/** Called when they press save. */
|
|
26
33
|
onSave: () => void;
|
|
34
|
+
/**
|
|
35
|
+
* Called when they press copy, which puts a PNG at the resolution picked on
|
|
36
|
+
* the clipboard.
|
|
37
|
+
* @default undefined — no copy is offered
|
|
38
|
+
*/
|
|
39
|
+
onCopy?: () => void;
|
|
27
40
|
/**
|
|
28
41
|
* Whether the SVG holds a rendered picture rather than vector drawings, as
|
|
29
42
|
* for a WebGL scene: its resolution is then the pixels of that picture, it
|
|
@@ -40,7 +53,8 @@ export interface FigureDownloadPanelProps {
|
|
|
40
53
|
sizing?: FigureSizing;
|
|
41
54
|
}
|
|
42
55
|
/**
|
|
43
|
-
* The choices behind the save glyph, and the
|
|
56
|
+
* The choices behind the save glyph, and the buttons that write the file and
|
|
57
|
+
* copy the picture.
|
|
44
58
|
*
|
|
45
59
|
* The resolution applies to both formats, and means what the reader needs it
|
|
46
60
|
* to: a PNG is painted with that many more pixels, and an SVG, drawn the same,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FigureDownloadPanel.d.ts","sourceRoot":"","sources":["../../../src/download/ui/FigureDownloadPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"FigureDownloadPanel.d.ts","sourceRoot":"","sources":["../../../src/download/ui/FigureDownloadPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAO1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAQ3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,sDAAsD;AACtD,MAAM,WAAW,wBAAwB;IACvC,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,MAAM,EAAE,YAAY,CAAC;IACrB,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,wEAAwE;IACxE,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,mEAAmE;IACnE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,2DAA2D;IAC3D,MAAM,EAAE,OAAO,CAAC;IAChB,gDAAgD;IAChD,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/C,4CAA4C;IAC5C,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,mCAAmC;IACnC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,wBAAwB,GAC9B,YAAY,CAuEd"}
|