schummar-table 1.0.0-beta.0 → 1.0.0-beta.2
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/LICENSE +15 -0
- package/README.md +221 -0
- package/dist/csvExporter.d.cts +1 -1
- package/dist/csvExporter.d.ts +1 -1
- package/dist/excelExporter.cjs +10 -7
- package/dist/excelExporter.cjs.map +1 -1
- package/dist/excelExporter.d.cts +14 -4
- package/dist/excelExporter.d.ts +12 -2
- package/dist/excelExporter.js +8 -7
- package/dist/excelExporter.js.map +1 -1
- package/dist/{exporter-BT2ehIIU.d.ts → exporter-Dv2Vqqth.d.cts} +2 -2
- package/dist/{exporter-BT2ehIIU.d.cts → exporter-Dv2Vqqth.d.ts} +2 -2
- package/dist/index.cjs +13 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -6
- package/dist/index.js.map +1 -1
- package/dist/mui4Theme.d.cts +1 -1
- package/dist/mui4Theme.d.ts +1 -1
- package/dist/mui5Theme.d.cts +1 -1
- package/dist/mui5Theme.d.ts +1 -1
- package/dist/rolldown-runtime-C0BPl7ul.cjs +43 -0
- package/dist/{types-R0UPOoXw.d.cts → types-Cppu6jsI.d.cts} +6 -4
- package/dist/{types-Bl56VGEh.d.ts → types-ZTz8TVGe.d.ts} +6 -4
- package/package.json +25 -9
- package/skills/schummar-table-upgrade/SKILL.md +10 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021-2026 Marco Schumacher
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,4 +1,225 @@
|
|
|
1
1
|
# schummar-table
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/schummar-table)
|
|
4
|
+
[](https://www.npmjs.com/package/schummar-table/v/next)
|
|
4
5
|
[](https://bundlephobia.com/package/schummar-table)
|
|
6
|
+
|
|
7
|
+
A fast, fully typed table for React. Sorting, filtering, selection, trees, column resizing,
|
|
8
|
+
virtualization, persistence and exports work out of the box. Every piece of state can be left to
|
|
9
|
+
the table or controlled from outside.
|
|
10
|
+
|
|
11
|
+
- **Typed end to end.** Column values flow into `renderCell`, `sortBy` and `filterBy`, and filters
|
|
12
|
+
are type checked against the column they sit on.
|
|
13
|
+
- **Fast.** Rows and cells are memoized, virtualization uses
|
|
14
|
+
[TanStack Virtual](https://tanstack.com/virtual), and expensive cells can render progressively.
|
|
15
|
+
- **Unopinionated styling.** Plain class names or emotion styles for every part, with built-in
|
|
16
|
+
styles that your overrides always win against. Themes for MUI 4 and 5 are included.
|
|
17
|
+
|
|
18
|
+
**[Live examples](https://schummar.github.io/schummar-table/)**
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install schummar-table @emotion/react
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
React 19 or newer is required. `write-excel-file` is only needed for the Excel exporter, `@mui/material` or
|
|
27
|
+
`@material-ui/core` only for the matching theme.
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { Table, selectFilter, textFilter } from 'schummar-table';
|
|
33
|
+
|
|
34
|
+
interface Person {
|
|
35
|
+
id: number;
|
|
36
|
+
name: string;
|
|
37
|
+
job: string;
|
|
38
|
+
birthday: Date;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function People({ people }: { people: Person[] }) {
|
|
42
|
+
return (
|
|
43
|
+
<Table
|
|
44
|
+
items={people}
|
|
45
|
+
id="id"
|
|
46
|
+
columns={(col) => [
|
|
47
|
+
col((person) => person.name, { header: 'Name', filter: textFilter() }),
|
|
48
|
+
col((person) => person.job, { header: 'Job', filter: selectFilter() }),
|
|
49
|
+
col((person) => person.birthday, {
|
|
50
|
+
header: 'Birthday',
|
|
51
|
+
renderCell: (birthday) => birthday.toLocaleDateString(),
|
|
52
|
+
}),
|
|
53
|
+
]}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`col(value, options)` infers the column value from its first argument, so `birthday` above is a
|
|
60
|
+
`Date` everywhere.
|
|
61
|
+
|
|
62
|
+
## Columns
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
col((person) => person.birthday, {
|
|
66
|
+
id: 'birthday', // stable id for persistence and controlled state; defaults to the index
|
|
67
|
+
header: 'Birthday',
|
|
68
|
+
renderCell: (birthday, person) => birthday.toLocaleDateString(),
|
|
69
|
+
sortBy: [(birthday) => birthday.getTime()],
|
|
70
|
+
exportCell: (birthday) => birthday.toISOString(),
|
|
71
|
+
width: '12ch', // any CSS grid width; defaults to max-content
|
|
72
|
+
displaySize: 'desktop', // only show on some screen sizes
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Columns can be hidden by the user (`enableColumnSelection`, on by default) and resized by dragging
|
|
77
|
+
the header separators (`enableColumnResize`).
|
|
78
|
+
|
|
79
|
+
## Filters
|
|
80
|
+
|
|
81
|
+
A filter is created with a factory and put on a column. Its UI opens from the column header.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
col((person) => person.name, { filter: textFilter({ compare: 'prefix' }) });
|
|
85
|
+
col((person) => person.tags, { filter: selectFilter() }); // string[] works too
|
|
86
|
+
col((person) => person.age, { filter: rangeFilter({ min: 0 }) });
|
|
87
|
+
col((person) => person.birthday, { filter: dateFilter({ maxDate: new Date() }) });
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
| Filter | Accepts |
|
|
91
|
+
| -------------- | -------------------------------------------- |
|
|
92
|
+
| `textFilter` | `string`, `number`, `bigint` |
|
|
93
|
+
| `selectFilter` | anything; `options`, `render` etc. narrow it |
|
|
94
|
+
| `rangeFilter` | `number`, `bigint` |
|
|
95
|
+
| `dateFilter` | `Date`, `DateRange`, ISO date strings |
|
|
96
|
+
|
|
97
|
+
Each also accepts `null`/`undefined`, arrays and Sets (an item matches if one of the values
|
|
98
|
+
does). A filter that doesn't fit the column value is a type error. Use `filterBy` to filter by
|
|
99
|
+
something else:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
col((person) => person.birthday, {
|
|
103
|
+
filterBy: (birthday) => birthday.getFullYear(),
|
|
104
|
+
filter: rangeFilter(),
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Every filter takes `defaultValue`, `value` and `onChange` (typed by the filter's own value), and
|
|
109
|
+
`external` to leave the actual filtering to you, e.g. on the server. All filter values can also be
|
|
110
|
+
controlled at once with `filterValues` / `onFilterValuesChange` on the table.
|
|
111
|
+
|
|
112
|
+
Custom filters are made with `defineFilter`:
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
const flagFilter = defineFilter<boolean, boolean>({
|
|
116
|
+
isActive: (value) => value,
|
|
117
|
+
test: (value, input) => input === value,
|
|
118
|
+
Component: ({ value, onChange }) => (
|
|
119
|
+
<label>
|
|
120
|
+
<input type="checkbox" checked={!!value} onChange={(e) => onChange(e.target.checked)} />
|
|
121
|
+
Only flagged
|
|
122
|
+
</label>
|
|
123
|
+
),
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## State
|
|
128
|
+
|
|
129
|
+
The table manages its state on its own. Every part can be initialized or controlled instead, the
|
|
130
|
+
same way as React inputs:
|
|
131
|
+
|
|
132
|
+
| State | Initial | Controlled | Change |
|
|
133
|
+
| -------------- | ---------------------- | --------------- | ----------------------- |
|
|
134
|
+
| Sort | `defaultSort` | `sort` | `onSortChange` |
|
|
135
|
+
| Selection | `defaultSelection` | `selection` | `onSelectionChange` |
|
|
136
|
+
| Expanded rows | `defaultExpanded` | `expanded` | `onExpandedChange` |
|
|
137
|
+
| Hidden columns | `defaultHiddenColumns` | `hiddenColumns` | `onHiddenColumnsChange` |
|
|
138
|
+
| Filter values | `defaultFilterValues` | `filterValues` | `onFilterValuesChange` |
|
|
139
|
+
|
|
140
|
+
Use `externalSort` when the items arrive sorted already. A `ref` gives imperative access, and
|
|
141
|
+
`useTableActions()` / `useTableContext()` do the same from components inside the table.
|
|
142
|
+
|
|
143
|
+
## Trees and row details
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
<Table items={items} id="id" parentId="parentId" columns={columns} />
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Items with a `parentId` become collapsible children of their parent. `hasDeferredChildren` marks
|
|
150
|
+
items whose children load on expand, and `revealFiltered` expands parents of matching children.
|
|
151
|
+
`rowDetails` renders an expandable area below each row instead.
|
|
152
|
+
|
|
153
|
+
## Large tables
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
<Table virtual items={items} ... />
|
|
157
|
+
<Table virtual={{ rowHeight: 40, overscan: 10, deferCells: true }} items={items} ... />
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`virtual` only renders the rows in view. It works inside any scroll container or with the window.
|
|
161
|
+
`deferCells` renders expensive cells progressively: rows that don't fit the frame budget show a
|
|
162
|
+
placeholder first, and visible rows are revealed first. Use `deferred` on single columns instead.
|
|
163
|
+
|
|
164
|
+
## Persistence
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
<Table persist={{ storage: localStorage, id: 'people' }} ... />
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Sort, selection, expanded rows, hidden columns, column widths and filter values are saved and
|
|
171
|
+
restored. `include` and `exclude` narrow this down, including single filters with
|
|
172
|
+
`{ filterValues: ['name'] }`. Any storage with `getItem`/`setItem`/`removeItem` works, including
|
|
173
|
+
async ones like localForage.
|
|
174
|
+
|
|
175
|
+
## Export
|
|
176
|
+
|
|
177
|
+
`enableExport` adds copy and download buttons for the visible (or selected) rows as CSV. More
|
|
178
|
+
exporters are registered through a provider:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import ExcelExporter from 'schummar-table/excelExporter';
|
|
182
|
+
|
|
183
|
+
<TableSettingsProvider
|
|
184
|
+
additionalExporters={[{ action: 'download', exporter: new ExcelExporter() }]}
|
|
185
|
+
>
|
|
186
|
+
<App />
|
|
187
|
+
</TableSettingsProvider>;
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Styling and themes
|
|
191
|
+
|
|
192
|
+
Every part accepts class names and emotion styles, per table or per column:
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
<Table
|
|
196
|
+
classes={{ table: 'people', headerCell: 'people-header', evenCell: 'even' }}
|
|
197
|
+
styles={{ cell: { padding: '0.5em 1em' } }}
|
|
198
|
+
...
|
|
199
|
+
/>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The built-in styles are inserted before all other styles, so an override of equal specificity
|
|
203
|
+
always wins. `classes.row/cell` and `styles.row/cell` also take a function of the item. Prefer
|
|
204
|
+
class names or constant styles there: function styles run for every cell render.
|
|
205
|
+
|
|
206
|
+
Components, icons, texts and colors are replaced through a theme, per table or for all tables via
|
|
207
|
+
`TableSettingsProvider`. MUI themes ship as separate entry points:
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
import { Mui5TableThemeProvider } from 'schummar-table/mui5Theme';
|
|
211
|
+
|
|
212
|
+
<Mui5TableThemeProvider>
|
|
213
|
+
<App />
|
|
214
|
+
</Mui5TableThemeProvider>;
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Upgrading from 0.x
|
|
218
|
+
|
|
219
|
+
1.0 changes the filter API, the `virtual` options and a few others. The package ships an agent
|
|
220
|
+
skill that walks through the migration: point your coding agent at
|
|
221
|
+
`node_modules/schummar-table/skills/schummar-table-upgrade/SKILL.md`.
|
|
222
|
+
|
|
223
|
+
## License
|
|
224
|
+
|
|
225
|
+
ISC
|
package/dist/csvExporter.d.cts
CHANGED
package/dist/csvExporter.d.ts
CHANGED
package/dist/excelExporter.cjs
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
2
|
+
let write_excel_file_browser = require("write-excel-file/browser");
|
|
3
|
+
write_excel_file_browser = require_rolldown_runtime.__toESM(write_excel_file_browser, 1);
|
|
2
4
|
//#region src/exporters/excelExporter.ts
|
|
3
5
|
var ExcelExporter = class {
|
|
4
|
-
constructor() {
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
this.options = options;
|
|
5
8
|
this.type = "xlsx";
|
|
6
9
|
this.fileEnding = "xlsx";
|
|
7
10
|
}
|
|
8
11
|
exportToBlob(columns, rows) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const { dateFormat = "yyyy-mm-dd", sheet = "Sheet1" } = this.options;
|
|
13
|
+
return (0, write_excel_file_browser.default)([columns, ...rows], {
|
|
14
|
+
sheet,
|
|
15
|
+
dateFormat
|
|
16
|
+
}).toBlob();
|
|
14
17
|
}
|
|
15
18
|
};
|
|
16
19
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"excelExporter.cjs","names":["
|
|
1
|
+
{"version":3,"file":"excelExporter.cjs","names":["writeXlsxFile"],"sources":["../src/exporters/excelExporter.ts"],"sourcesContent":["import writeXlsxFile from 'write-excel-file/browser';\nimport type { BlobExporter } from './exporter';\n\nexport interface ExcelExporterOptions {\n /** Excel number format for date cells.\n * @default 'yyyy-mm-dd'\n */\n dateFormat?: string;\n /** @default 'Sheet1' */\n sheet?: string;\n}\n\nexport default class ExcelExporter implements BlobExporter {\n readonly type = 'xlsx';\n readonly fileEnding = 'xlsx';\n\n constructor(private readonly options: ExcelExporterOptions = {}) {}\n\n exportToBlob(\n columns: (string | number | Date)[],\n rows: (string | number | Date)[][],\n ): Promise<Blob> {\n const { dateFormat = 'yyyy-mm-dd', sheet = 'Sheet1' } = this.options;\n return writeXlsxFile([columns, ...rows], { sheet, dateFormat }).toBlob();\n }\n}\n"],"mappings":";;;;AAYA,IAAqB,gBAArB,MAA2D;CAIzD,YAAY,UAAiD,CAAC,GAAG;EAApC,KAAA,UAAA;EAHb,KAAA,OAAA;EACM,KAAA,aAAA;CAE4C;CAElE,aACE,SACA,MACe;EACf,MAAM,EAAE,aAAa,cAAc,QAAQ,aAAa,KAAK;EAC7D,QAAA,GAAOA,yBAAAA,QAAAA,CAAc,CAAC,SAAS,GAAG,IAAI,GAAG;GAAE;GAAO;EAAW,CAAC,CAAC,CAAC,OAAO;CACzE;AACF"}
|
package/dist/excelExporter.d.cts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
import { t as BlobExporter } from "./exporter-
|
|
1
|
+
import { t as BlobExporter } from "./exporter-Dv2Vqqth.cjs";
|
|
2
2
|
//#region src/exporters/excelExporter.d.ts
|
|
3
|
-
|
|
3
|
+
export interface ExcelExporterOptions {
|
|
4
|
+
/** Excel number format for date cells.
|
|
5
|
+
* @default 'yyyy-mm-dd'
|
|
6
|
+
*/
|
|
7
|
+
dateFormat?: string;
|
|
8
|
+
/** @default 'Sheet1' */
|
|
9
|
+
sheet?: string;
|
|
10
|
+
}
|
|
11
|
+
export default class ExcelExporter implements BlobExporter {
|
|
12
|
+
private readonly options;
|
|
4
13
|
readonly type = "xlsx";
|
|
5
14
|
readonly fileEnding = "xlsx";
|
|
6
|
-
|
|
15
|
+
constructor(options?: ExcelExporterOptions);
|
|
16
|
+
exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Promise<Blob>;
|
|
7
17
|
}
|
|
8
|
-
|
|
18
|
+
//#endregion
|
|
9
19
|
//# sourceMappingURL=excelExporter.d.cts.map
|
package/dist/excelExporter.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
import { t as BlobExporter } from "./exporter-
|
|
1
|
+
import { t as BlobExporter } from "./exporter-Dv2Vqqth.js";
|
|
2
2
|
//#region src/exporters/excelExporter.d.ts
|
|
3
|
+
export interface ExcelExporterOptions {
|
|
4
|
+
/** Excel number format for date cells.
|
|
5
|
+
* @default 'yyyy-mm-dd'
|
|
6
|
+
*/
|
|
7
|
+
dateFormat?: string;
|
|
8
|
+
/** @default 'Sheet1' */
|
|
9
|
+
sheet?: string;
|
|
10
|
+
}
|
|
3
11
|
export default class ExcelExporter implements BlobExporter {
|
|
12
|
+
private readonly options;
|
|
4
13
|
readonly type = "xlsx";
|
|
5
14
|
readonly fileEnding = "xlsx";
|
|
6
|
-
|
|
15
|
+
constructor(options?: ExcelExporterOptions);
|
|
16
|
+
exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Promise<Blob>;
|
|
7
17
|
}
|
|
8
18
|
//#endregion
|
|
9
19
|
//# sourceMappingURL=excelExporter.d.ts.map
|
package/dist/excelExporter.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import writeXlsxFile from "write-excel-file/browser";
|
|
2
2
|
//#region src/exporters/excelExporter.ts
|
|
3
3
|
var ExcelExporter = class {
|
|
4
|
-
constructor() {
|
|
4
|
+
constructor(options = {}) {
|
|
5
|
+
this.options = options;
|
|
5
6
|
this.type = "xlsx";
|
|
6
7
|
this.fileEnding = "xlsx";
|
|
7
8
|
}
|
|
8
9
|
exportToBlob(columns, rows) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const { dateFormat = "yyyy-mm-dd", sheet = "Sheet1" } = this.options;
|
|
11
|
+
return writeXlsxFile([columns, ...rows], {
|
|
12
|
+
sheet,
|
|
13
|
+
dateFormat
|
|
14
|
+
}).toBlob();
|
|
14
15
|
}
|
|
15
16
|
};
|
|
16
17
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"excelExporter.js","names":[],"sources":["../src/exporters/excelExporter.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"excelExporter.js","names":[],"sources":["../src/exporters/excelExporter.ts"],"sourcesContent":["import writeXlsxFile from 'write-excel-file/browser';\nimport type { BlobExporter } from './exporter';\n\nexport interface ExcelExporterOptions {\n /** Excel number format for date cells.\n * @default 'yyyy-mm-dd'\n */\n dateFormat?: string;\n /** @default 'Sheet1' */\n sheet?: string;\n}\n\nexport default class ExcelExporter implements BlobExporter {\n readonly type = 'xlsx';\n readonly fileEnding = 'xlsx';\n\n constructor(private readonly options: ExcelExporterOptions = {}) {}\n\n exportToBlob(\n columns: (string | number | Date)[],\n rows: (string | number | Date)[][],\n ): Promise<Blob> {\n const { dateFormat = 'yyyy-mm-dd', sheet = 'Sheet1' } = this.options;\n return writeXlsxFile([columns, ...rows], { sheet, dateFormat }).toBlob();\n }\n}\n"],"mappings":";;AAYA,IAAqB,gBAArB,MAA2D;CAIzD,YAAY,UAAiD,CAAC,GAAG;EAApC,KAAA,UAAA;EAHb,KAAA,OAAA;EACM,KAAA,aAAA;CAE4C;CAElE,aACE,SACA,MACe;EACf,MAAM,EAAE,aAAa,cAAc,QAAQ,aAAa,KAAK;EAC7D,OAAO,cAAc,CAAC,SAAS,GAAG,IAAI,GAAG;GAAE;GAAO;EAAW,CAAC,CAAC,CAAC,OAAO;CACzE;AACF"}
|
|
@@ -6,7 +6,7 @@ interface StringExporter {
|
|
|
6
6
|
interface BlobExporter {
|
|
7
7
|
type: string;
|
|
8
8
|
fileEnding: string;
|
|
9
|
-
exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Blob
|
|
9
|
+
exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Blob | Promise<Blob>;
|
|
10
10
|
}
|
|
11
11
|
type ExporterEntry = {
|
|
12
12
|
action: 'copy';
|
|
@@ -21,4 +21,4 @@ interface ExportOptions {
|
|
|
21
21
|
}
|
|
22
22
|
//#endregion
|
|
23
23
|
export { StringExporter as i, ExportOptions as n, ExporterEntry as r, BlobExporter as t };
|
|
24
|
-
//# sourceMappingURL=exporter-
|
|
24
|
+
//# sourceMappingURL=exporter-Dv2Vqqth.d.cts.map
|
|
@@ -6,7 +6,7 @@ interface StringExporter {
|
|
|
6
6
|
interface BlobExporter {
|
|
7
7
|
type: string;
|
|
8
8
|
fileEnding: string;
|
|
9
|
-
exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Blob
|
|
9
|
+
exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Blob | Promise<Blob>;
|
|
10
10
|
}
|
|
11
11
|
type ExporterEntry = {
|
|
12
12
|
action: 'copy';
|
|
@@ -21,4 +21,4 @@ interface ExportOptions {
|
|
|
21
21
|
}
|
|
22
22
|
//#endregion
|
|
23
23
|
export { StringExporter as i, ExportOptions as n, ExporterEntry as r, BlobExporter as t };
|
|
24
|
-
//# sourceMappingURL=exporter-
|
|
24
|
+
//# sourceMappingURL=exporter-Dv2Vqqth.d.ts.map
|
package/dist/index.cjs
CHANGED
|
@@ -1,41 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __exportAll = (all, no_symbols) => {
|
|
10
|
-
let target = {};
|
|
11
|
-
for (var name in all) __defProp(target, name, {
|
|
12
|
-
get: all[name],
|
|
13
|
-
enumerable: true
|
|
14
|
-
});
|
|
15
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
16
|
-
return target;
|
|
17
|
-
};
|
|
18
|
-
var __copyProps = (to, from, except, desc) => {
|
|
19
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
20
|
-
key = keys[i];
|
|
21
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
22
|
-
get: ((k) => from[k]).bind(null, key),
|
|
23
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
return to;
|
|
27
|
-
};
|
|
28
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
29
|
-
value: mod,
|
|
30
|
-
enumerable: true
|
|
31
|
-
}) : target, mod));
|
|
32
|
-
//#endregion
|
|
2
|
+
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
33
3
|
const require_tableTheme = require("./tableTheme-CSqMIpLB.cjs");
|
|
34
4
|
let react = require("react");
|
|
35
5
|
let _emotion_react_jsx_runtime = require("@emotion/react/jsx-runtime");
|
|
36
6
|
let _emotion_react = require("@emotion/react");
|
|
37
7
|
let _emotion_cache = require("@emotion/cache");
|
|
38
|
-
_emotion_cache = __toESM(_emotion_cache, 1);
|
|
8
|
+
_emotion_cache = require_rolldown_runtime.__toESM(_emotion_cache, 1);
|
|
39
9
|
let _emotion_serialize = require("@emotion/serialize");
|
|
40
10
|
let _emotion_utils = require("@emotion/utils");
|
|
41
11
|
let react_dom = require("react-dom");
|
|
@@ -191,7 +161,7 @@ const Button = ({ startIcon, children, variant = "text", ...props }) => {
|
|
|
191
161
|
};
|
|
192
162
|
//#endregion
|
|
193
163
|
//#region src/misc/helpers.ts
|
|
194
|
-
var helpers_exports = /* @__PURE__ */ __exportAll({
|
|
164
|
+
var helpers_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
195
165
|
asNumber: () => asNumber,
|
|
196
166
|
asNumberOrArray: () => asNumberOrArray,
|
|
197
167
|
asString: () => asString,
|
|
@@ -269,8 +239,9 @@ const getDescendants = (...items) => {
|
|
|
269
239
|
const identity$1 = (x) => x;
|
|
270
240
|
const asString = (x) => {
|
|
271
241
|
if (Array.isArray(x)) return x.map(asString).join(", ");
|
|
242
|
+
if (x === null || x === void 0) return "";
|
|
272
243
|
if (x instanceof Object) return JSON.stringify(x);
|
|
273
|
-
return String(x
|
|
244
|
+
return String(x);
|
|
274
245
|
};
|
|
275
246
|
const asStringOrArray = (x) => {
|
|
276
247
|
if (Array.isArray(x)) return x.map(asString);
|
|
@@ -2388,7 +2359,7 @@ const defaultProps = {
|
|
|
2388
2359
|
} }
|
|
2389
2360
|
};
|
|
2390
2361
|
const identity = (value) => value;
|
|
2391
|
-
const defaultSortBy = (v) => typeof v === "number" || v instanceof Date ? v :
|
|
2362
|
+
const defaultSortBy = (v) => typeof v === "number" || v instanceof Date ? v : asString(v);
|
|
2392
2363
|
function normalizeId(id) {
|
|
2393
2364
|
return id instanceof Function ? id : (item) => item[id];
|
|
2394
2365
|
}
|
|
@@ -3545,9 +3516,10 @@ function Export() {
|
|
|
3545
3516
|
const rows = exportedItems.map((item) => activeColumns.map((column) => column.exportCell(column.value(item.value), item.value)));
|
|
3546
3517
|
if (action === "copy") {
|
|
3547
3518
|
const data = exporter.exportToString(columns, rows);
|
|
3548
|
-
navigator.clipboard.writeText(data)
|
|
3549
|
-
|
|
3550
|
-
|
|
3519
|
+
navigator.clipboard.writeText(data).catch((error) => {
|
|
3520
|
+
console.error("Failed to copy the export to the clipboard:", error);
|
|
3521
|
+
});
|
|
3522
|
+
} else Promise.resolve(exporter.exportToBlob(columns, rows)).then((blob) => {
|
|
3551
3523
|
const url = URL.createObjectURL(blob);
|
|
3552
3524
|
const a = document.createElement("a");
|
|
3553
3525
|
a.href = url;
|
|
@@ -3556,7 +3528,9 @@ function Export() {
|
|
|
3556
3528
|
a.click();
|
|
3557
3529
|
a.remove();
|
|
3558
3530
|
URL.revokeObjectURL(url);
|
|
3559
|
-
}
|
|
3531
|
+
}).catch((error) => {
|
|
3532
|
+
console.error("Failed to export:", error);
|
|
3533
|
+
});
|
|
3560
3534
|
}
|
|
3561
3535
|
return /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsxs)(_emotion_react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(IconButton, {
|
|
3562
3536
|
onClick: (event) => setAnchor(anchor ? null : event.currentTarget),
|