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 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://badgen.net/npm/v/schummar-table)](https://www.npmjs.com/package/schummar-table)
4
+ [![](https://badgen.net/npm/v/schummar-table/next)](https://www.npmjs.com/package/schummar-table/v/next)
4
5
  [![](https://badgen.net/bundlephobia/minzip/schummar-table)](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
@@ -1,4 +1,4 @@
1
- import { i as StringExporter, t as BlobExporter } from "./exporter-BT2ehIIU.cjs";
1
+ import { i as StringExporter, t as BlobExporter } from "./exporter-Dv2Vqqth.cjs";
2
2
  //#region src/exporters/csvExporter.d.ts
3
3
  export interface CsvExporterOptions {
4
4
  sepPrefix?: boolean;
@@ -1,4 +1,4 @@
1
- import { i as StringExporter, t as BlobExporter } from "./exporter-BT2ehIIU.js";
1
+ import { i as StringExporter, t as BlobExporter } from "./exporter-Dv2Vqqth.js";
2
2
  //#region src/exporters/csvExporter.d.ts
3
3
  export interface CsvExporterOptions {
4
4
  sepPrefix?: boolean;
@@ -1,16 +1,19 @@
1
- let xlsx = require("xlsx");
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 worksheet = xlsx.utils.aoa_to_sheet([columns, ...rows]);
10
- const workbook = xlsx.utils.book_new();
11
- xlsx.utils.book_append_sheet(workbook, worksheet, "Sheet1");
12
- const data = (0, xlsx.write)(workbook, { type: "buffer" });
13
- return new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
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":["utils","write"],"sources":["../src/exporters/excelExporter.ts"],"sourcesContent":["import { utils, write } from 'xlsx';\nimport { BlobExporter } from './exporter';\n\nexport default class ExcelExporter implements BlobExporter {\n readonly type = 'xlsx';\n readonly fileEnding = 'xlsx';\n\n exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Blob {\n const worksheet = utils.aoa_to_sheet([columns, ...rows]);\n const workbook = utils.book_new();\n utils.book_append_sheet(workbook, worksheet, 'Sheet1');\n\n const data = write(workbook, { type: 'buffer' });\n return new Blob([data], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n }\n}\n"],"mappings":";;AAGA,IAAqB,gBAArB,MAA2D;;EACzC,KAAA,OAAA;EACM,KAAA,aAAA;;CAEtB,aAAa,SAAqC,MAA0C;EAC1F,MAAM,YAAYA,KAAAA,MAAM,aAAa,CAAC,SAAS,GAAG,IAAI,CAAC;EACvD,MAAM,WAAWA,KAAAA,MAAM,SAAS;EAChC,KAAA,MAAM,kBAAkB,UAAU,WAAW,QAAQ;EAErD,MAAM,QAAA,GAAOC,KAAAA,MAAAA,CAAM,UAAU,EAAE,MAAM,SAAS,CAAC;EAC/C,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EACtB,MAAM,oEACR,CAAC;CACH;AACF"}
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"}
@@ -1,9 +1,19 @@
1
- import { t as BlobExporter } from "./exporter-BT2ehIIU.cjs";
1
+ import { t as BlobExporter } from "./exporter-Dv2Vqqth.cjs";
2
2
  //#region src/exporters/excelExporter.d.ts
3
- declare class ExcelExporter implements BlobExporter {
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
- exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Blob;
15
+ constructor(options?: ExcelExporterOptions);
16
+ exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Promise<Blob>;
7
17
  }
8
- export = ExcelExporter;
18
+ //#endregion
9
19
  //# sourceMappingURL=excelExporter.d.cts.map
@@ -1,9 +1,19 @@
1
- import { t as BlobExporter } from "./exporter-BT2ehIIU.js";
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
- exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Blob;
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
@@ -1,16 +1,17 @@
1
- import { utils, write } from "xlsx";
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 worksheet = utils.aoa_to_sheet([columns, ...rows]);
10
- const workbook = utils.book_new();
11
- utils.book_append_sheet(workbook, worksheet, "Sheet1");
12
- const data = write(workbook, { type: "buffer" });
13
- return new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
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 { utils, write } from 'xlsx';\nimport { BlobExporter } from './exporter';\n\nexport default class ExcelExporter implements BlobExporter {\n readonly type = 'xlsx';\n readonly fileEnding = 'xlsx';\n\n exportToBlob(columns: (string | number | Date)[], rows: (string | number | Date)[][]): Blob {\n const worksheet = utils.aoa_to_sheet([columns, ...rows]);\n const workbook = utils.book_new();\n utils.book_append_sheet(workbook, worksheet, 'Sheet1');\n\n const data = write(workbook, { type: 'buffer' });\n return new Blob([data], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n }\n}\n"],"mappings":";;AAGA,IAAqB,gBAArB,MAA2D;;EACzC,KAAA,OAAA;EACM,KAAA,aAAA;;CAEtB,aAAa,SAAqC,MAA0C;EAC1F,MAAM,YAAY,MAAM,aAAa,CAAC,SAAS,GAAG,IAAI,CAAC;EACvD,MAAM,WAAW,MAAM,SAAS;EAChC,MAAM,kBAAkB,UAAU,WAAW,QAAQ;EAErD,MAAM,OAAO,MAAM,UAAU,EAAE,MAAM,SAAS,CAAC;EAC/C,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EACtB,MAAM,oEACR,CAAC;CACH;AACF"}
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-BT2ehIIU.d.ts.map
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-BT2ehIIU.d.cts.map
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
- //#region \0rolldown/runtime.js
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 : v === null || v === void 0 ? "" : String(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
- } else {
3550
- const blob = exporter.exportToBlob(columns, rows);
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),