@iyulab/flex-table 0.58.0 → 0.60.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.
@@ -131,9 +131,13 @@ Enter/Escape and blur-to-commit behavior.
131
131
  | `setComment(dataIndex, colKey, text)` | `null` or `''` removes; undoable |
132
132
  | `getComment(dataIndex, colKey)` / `clearComments()` | |
133
133
  | `importFromFile(file)` | `Promise<void>`; `.xlsx`, `.csv`, `.tsv`; fires `data-import` |
134
- | `exportToString(format, { selectionOnly? })` | `string \| Uint8Array`; format `'csv' \| 'tsv' \| 'json' \| 'xlsx'` (xlsx returns uncompressed bytes — synchronous) |
135
- | `exportToBlob(format, { selectionOnly? })` | `Promise<Blob>` typed with the format's MIME; xlsx is DEFLATE-compressed |
136
- | `exportToFile(format, filename?)` | `Promise<void>` — triggers a download (xlsx compressed) |
134
+ | `exportToString(format, { selectionOnly? } \| { rows })` | `string \| Uint8Array`; format `'csv' \| 'tsv' \| 'json' \| 'xlsx'` (xlsx returns uncompressed bytes — synchronous). `rows`: export these rows with the visible columns |
135
+ | `exportToBlob(format, options?)` | `Promise<Blob>` typed with the format's MIME; xlsx is DEFLATE-compressed |
136
+ | `exportToFile(format, filename?, options?)` | `Promise<void>` — triggers a download (xlsx compressed) |
137
+
138
+ A server-paged table holds one page. Export the list's whole result with
139
+ `table.exportToFile('xlsx', 'x.xlsx', { rows: await source.fetchAll() })` — never the table's own rows there.
140
+ Table-less: `exportDataBlob(rows, columns, format)` + `downloadBlob(blob, name)` from the root entry.
137
141
 
138
142
  ## Events
139
143
 
@@ -143,14 +147,14 @@ cast, and the React `on*` props carry the same types.
143
147
 
144
148
  | Event | `detail` |
145
149
  |---|---|
146
- | `cell-select` | `{ row, col }` (or `null`) |
150
+ | `cell-select` | `{ row, col, id }` (or `null`) — focus moved (also when the keyboard arrives); `row`/`col` visible positions |
147
151
  | `cell-edit-start` | `{ row, col, key, value }` |
148
152
  | `cell-edit-commit` | `{ row, col, key, oldValue, newValue }` |
149
153
  | `cell-edit-cancel` | `{ row, col }` — `row`: data index (`-1` once the row left `data`) |
150
154
  | `validation-error` | `{ row, col, key, value, error }` |
151
155
  | `row-add` | `{ row, index }` |
152
156
  | `row-delete` | `{ indices, rows }` |
153
- | `row-activate` | `{ row, id, index, col, key }` — Enter on a non-editable cell |
157
+ | `row-activate` | `{ row, id, via, index, col, key }` — a plain click on a cell (`via: 'click'`) or Enter on a non-editable cell (`'keyboard'`); not a Shift/Ctrl/Cmd click, a drag, or a control in the cell |
154
158
  | `row-reorder` | `{ from, to }` |
155
159
  | `batch-update` | `{ changes }` |
156
160
  | `column-add` | `{ column, index }` |
@@ -114,6 +114,7 @@ function Orders() {
114
114
  | `sortCriteria`, `onSortChange` | Pass `onSortChange` to the table's `sort-change` (resets to page 0) |
115
115
  | `search`, `setSearch` | Literal text (resets to page 0) |
116
116
  | `refresh` | Re-run the current request |
117
+ | `fetchAll(options?)` | The whole result of the current sort/search/filter (no paging, follows `@odata.nextLink`) — for export. `maxRows` (default 100000) rejects with `RowLimitError` rather than cutting; `signal`, `onProgress` |
117
118
 
118
119
  Search is literal: each whitespace-separated token becomes a quoted phrase joined with `AND`
119
120
  (`red shirt` → `"red" AND "shirt"`); double quotes are stripped. If the result set shrinks below
@@ -159,7 +160,7 @@ Differences: `totalCount` is the count after search, `loading` is always `false`
159
160
 
160
161
  `useODataSource` adapts a framework-neutral source with the same options and state:
161
162
  `createODataSource(url, options)` → `getState()` · `subscribe(listener)` (the first subscriber starts loading, the last
162
- unsubscribe cancels) · `setPage` · `setPageSize` · `setSort(criteria)` · `setSearch` · `refresh` · `update(url, options)`. Changes in one
163
+ unsubscribe cancels) · `setPage` · `setPageSize` · `setSort(criteria)` · `setSearch` · `refresh` · `update(url, options)` · `fetchAll(options?)`. Changes in one
163
164
  tick become one request. For Lit, `ODataSourceController` subscribes on connect, cancels on disconnect and re-renders
164
165
  the host — from a URL, or from a source you already have (`new ODataSourceController(this, source)`, so a table and a pager share it):
165
166
 
@@ -1,37 +0,0 @@
1
- import e from "odata-query";
2
- //#region src/odata/query.ts
3
- function t(e) {
4
- let t = e.split(/\s+/).map((e) => e.replace(/"/g, "")).filter((e) => e.length > 0);
5
- if (t.length !== 0) return t.map((e) => `"${e}"`).join(" AND ");
6
- }
7
- function n(e) {
8
- let { defaultOrderBy: t, initialPage: n = 0, initialSearch: i = "", initialSort: a } = e;
9
- return {
10
- page: n,
11
- search: i,
12
- sortCriteria: a ?? (t ? r(t) : [])
13
- };
14
- }
15
- function r(e) {
16
- return e.split(",").map((e) => {
17
- let t = e.trim().split(/\s+/);
18
- return {
19
- key: t[0],
20
- direction: t[1]?.toLowerCase() === "desc" ? "desc" : "asc"
21
- };
22
- });
23
- }
24
- function i(n) {
25
- let { page: r, pageSize: i, sortCriteria: a = [], defaultOrderBy: o, search: s, fixedFilter: c } = n, l = a.length > 0 ? a.map((e) => `${e.key} ${e.direction}`).join(", ") : o, u = {
26
- top: i,
27
- skip: r * i,
28
- count: !0
29
- };
30
- if (l && (u.orderBy = l), c && (u.filter = c), s) {
31
- let e = t(s);
32
- e && (u.search = e);
33
- }
34
- return e(u);
35
- }
36
- //#endregion
37
- export { n as i, t as n, r, i as t };
@@ -1,223 +0,0 @@
1
- import { n as e } from "./locale-Cfm-vJji.js";
2
- import { i as t, t as n } from "./query-Dw4iO0ir.js";
3
- //#region src/core/source-error.ts
4
- async function r(t) {
5
- let n = await t.text().catch(() => ""), r = {
6
- message: e("requestFailed", { status: t.status }),
7
- status: t.status
8
- };
9
- if (!n) return r;
10
- let a = n;
11
- try {
12
- a = JSON.parse(n);
13
- } catch {}
14
- if (r.body = a, !a || typeof a != "object") return r;
15
- let o = a, s = o.error && typeof o.error == "object" ? o.error : o;
16
- typeof s.message == "string" && s.message ? r.message = s.message : typeof o.message == "string" && o.message && (r.message = o.message), typeof s.code == "string" && s.code && (r.code = s.code);
17
- let c = i(s.details);
18
- return c && (r.details = c), r;
19
- }
20
- function i(e) {
21
- if (!Array.isArray(e)) return;
22
- let t = e.filter((e) => {
23
- if (!e || typeof e != "object") return !1;
24
- let t = e;
25
- return typeof t.code == "string" && typeof t.message == "string";
26
- });
27
- return t.length > 0 ? t : void 0;
28
- }
29
- var a = class extends Error {
30
- constructor(e) {
31
- super(e.message), this.name = "SourceRequestError", this.failure = e;
32
- }
33
- };
34
- function o(t) {
35
- return new a({
36
- message: e("networkFailed"),
37
- cause: t
38
- });
39
- }
40
- function s(e) {
41
- return e instanceof a ? e.failure : e instanceof Error ? { message: e.message } : { message: String(e) };
42
- }
43
- //#endregion
44
- //#region src/odata/source.ts
45
- function c(e, i = {}) {
46
- let c = e, u = i, d = l(i.fixedFilter), f = t({
47
- defaultOrderBy: i.defaultOrderBy,
48
- initialPage: i.initialPage ?? 0,
49
- initialSearch: i.initialSearch ?? "",
50
- initialSort: i.initialSort
51
- }), p = {
52
- data: [],
53
- totalCount: 0,
54
- loading: !0,
55
- error: null,
56
- page: f.page,
57
- pageSize: i.pageSize ?? 20,
58
- sortCriteria: f.sortCriteria,
59
- search: f.search
60
- }, m = x(), h = /* @__PURE__ */ new Set(), g = null, _ = !1, v = null;
61
- function y() {
62
- return u.enabled ?? !0;
63
- }
64
- function b() {
65
- return p.pageSize;
66
- }
67
- function x() {
68
- return {
69
- ...p,
70
- loading: p.loading || !y()
71
- };
72
- }
73
- function S(e) {
74
- p = {
75
- ...p,
76
- ...e
77
- }, C();
78
- }
79
- function C() {
80
- let e = x();
81
- if (!Object.keys(e).every((t) => e[t] === m[t])) {
82
- m = e;
83
- for (let e of [...h]) e();
84
- }
85
- }
86
- function w() {
87
- return JSON.stringify([
88
- c,
89
- u.baseUrl,
90
- b(),
91
- u.defaultOrderBy,
92
- d,
93
- p.page,
94
- p.sortCriteria,
95
- p.search
96
- ]);
97
- }
98
- function T() {
99
- _ || (_ = !0, queueMicrotask(() => {
100
- _ = !1, E();
101
- }));
102
- }
103
- function E() {
104
- if (h.size === 0) return;
105
- if (!y()) {
106
- g?.abort(), g = null, v = null, C();
107
- return;
108
- }
109
- let e = w();
110
- e !== v && (v = e, D());
111
- }
112
- function D() {
113
- g?.abort();
114
- let e = new AbortController();
115
- g = e;
116
- let { page: t, sortCriteria: i, search: l } = p, d = b(), f = u.fetcher ?? fetch, m = u.onUnauthorized;
117
- S({
118
- loading: !0,
119
- error: null
120
- });
121
- let h = n({
122
- page: t,
123
- pageSize: d,
124
- sortCriteria: i,
125
- defaultOrderBy: u.defaultOrderBy,
126
- search: l,
127
- fixedFilter: u.fixedFilter
128
- }), _ = `${u.baseUrl ?? window.location.origin}${c}${h}`, v = async (t) => {
129
- let n;
130
- try {
131
- n = await f(t, { signal: e.signal });
132
- } catch (e) {
133
- throw e?.name === "AbortError" ? e : o(e);
134
- }
135
- if (!n.ok) throw n.status === 401 && m && m(n), new a(await r(n));
136
- return n.json();
137
- };
138
- (async () => {
139
- let e = await v(_), t = [...e.value ?? e], n = new URL(_).origin, r = /* @__PURE__ */ new Set([_]), i = _, a = e["@odata.nextLink"];
140
- for (; typeof a == "string" && a && t.length < d;) {
141
- let e = new URL(a, i);
142
- if (e.origin !== n) throw Error(`OData nextLink points outside the source origin (${e.origin})`);
143
- if (i = e.toString(), r.has(i)) throw Error(`OData nextLink repeats an already-read page (${i})`);
144
- r.add(i);
145
- let o = await v(i);
146
- t.push(...o.value ?? []), a = o["@odata.nextLink"];
147
- }
148
- return {
149
- count: e["@odata.count"],
150
- rows: t
151
- };
152
- })().then(({ count: n, rows: r }) => {
153
- if (e.signal.aborted) return;
154
- let i = n ?? 0, a = i === 0 ? 0 : Math.ceil(i / d) - 1;
155
- t > a ? (S({
156
- data: r,
157
- totalCount: i,
158
- error: null,
159
- page: a
160
- }), T()) : S({
161
- data: r,
162
- totalCount: i,
163
- error: null
164
- });
165
- }).catch((t) => {
166
- e.signal.aborted || t?.name !== "AbortError" && S({
167
- error: s(t),
168
- data: [],
169
- totalCount: 0
170
- });
171
- }).finally(() => {
172
- e.signal.aborted || S({ loading: !1 });
173
- });
174
- }
175
- return {
176
- getState: () => m,
177
- subscribe(e) {
178
- return h.add(e), h.size === 1 && T(), () => {
179
- !h.delete(e) || h.size > 0 || (g?.abort(), g = null, v = null);
180
- };
181
- },
182
- setPage(e) {
183
- S({ page: e }), T();
184
- },
185
- setPageSize(e) {
186
- e !== p.pageSize && (S({
187
- pageSize: e,
188
- page: 0
189
- }), T());
190
- },
191
- setSort(e) {
192
- S({
193
- sortCriteria: e,
194
- page: 0
195
- }), T();
196
- },
197
- setSearch(e) {
198
- S({
199
- search: e,
200
- page: 0
201
- }), T();
202
- },
203
- refresh() {
204
- y() && (v = null, T());
205
- },
206
- update(e, t = {}) {
207
- let n = l(t.fixedFilter), r = n !== d, i = t.pageSize !== void 0 && t.pageSize !== u.pageSize;
208
- c = e, u = t, d = n, r && (p = {
209
- ...p,
210
- page: 0
211
- }), i && t.pageSize !== p.pageSize && (p = {
212
- ...p,
213
- pageSize: t.pageSize,
214
- page: 0
215
- }), C(), T();
216
- }
217
- };
218
- }
219
- function l(e) {
220
- return e ? JSON.stringify(e) : "";
221
- }
222
- //#endregion
223
- export { c as t };