@iyulab/flex-table 0.56.1 → 0.58.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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.58.0] - 2026-10-07
4
+
5
+ ### Added
6
+
7
+ - **Page size is source state.** `createODataSource` / `createArraySource` state (and `useODataSource` /
8
+ `useArraySource`) carries `pageSize`, and `setPageSize(size)` changes it and goes back to page 0 — a pager's «rows per
9
+ page» had no way to reach the source. An `update` (or a render) that passes the same `pageSize` option again keeps the
10
+ size `setPageSize` set; a changed option value takes effect.
11
+ - **`ODataSourceController` and `ArraySourceController` take an existing source** —
12
+ `new ODataSourceController(this, source)` — so several elements (a table, a pager) share one source. Created from a
13
+ URL (or rows) as before.
14
+
15
+ ## [0.57.0] - 2026-10-07
16
+
17
+ ### Changed (breaking)
18
+
19
+ - **`getSelectedRows()` returns the selected rows** (`DataRow[]` — the rows `data` holds, in `data` order), the same
20
+ shape as `u-rich-table`'s `getSelectedRows()`. It returned `{ selectedIds, selectedIndices, selectedRows }`, so code
21
+ written for one table read `undefined` from the other (`getSelectedRows().length`). Every selected id, on every page,
22
+ is `selectedRowIds`; positions in `data` come with `selection-change` (`selectedIndices`), whose detail is unchanged.
23
+
24
+ **Migrating**: `getSelectedRows().selectedRows` → `getSelectedRows()` · `.selectedIds` → `[...selectedRowIds]` ·
25
+ `.selectedIndices` → the `selection-change` detail, or `getSelectedRows().map((r) => table.data.indexOf(r))`.
26
+
3
27
  ## [0.56.1] - 2026-10-07
4
28
 
5
29
  ### Fixed
package/README.md CHANGED
@@ -258,7 +258,7 @@ Every row keeps its own value. Sorting, filtering, copying, CSV/XLSX export and
258
258
  | `deselectAll()` | `void` | Deselect every row, on every page |
259
259
  | `selectWhere(predicate)` | `void` | Add the rows in view for which `predicate(row, dataIndex)` is true |
260
260
  | `setSelection(ids)` | `void` | Replace the selection with these row ids. The same set again does nothing and fires nothing |
261
- | `getSelectedRows()` | `{ selectedIds, selectedIndices, selectedRows }` | `selectedIds`: every selected row (all pages). `selectedRows` / `selectedIndices`: the selected rows `data` holds, and their positions in it |
261
+ | `getSelectedRows()` | `DataRow[]` | The selected rows `data` holds, in `data` order — the same shape as `u-rich-table`'s. Every selected id (all pages) is `selectedRowIds`; positions come with `selection-change` (`selectedIndices`) |
262
262
  | `getRowId(row)` | `string` | The id selection keeps for a row |
263
263
  | `selectedRowIds` (getter) | `ReadonlySet<string>` | Ids of the selected rows, all pages (a copy) |
264
264
 
@@ -268,7 +268,7 @@ Row selection is kept by **row id**, not by position, so a checkmark stays on it
268
268
  table.rowKey = 'orderNo'; // or: table.rowKey = (row) => `${row.site}/${row.no}`
269
269
  ```
270
270
 
271
- A keyed row stays selected when `data` is replaced, so in a server-paged grid the selection spans pages (`selectedIds` names them all; `selectedRows` holds the ones on this page). A row without a key is named by the row object itself (a session-local id `#n`): it follows the row while the same object is in `data` and leaves the selection when it is gone. Set `clear-selection-on-data-change` when every new `data` should start a new selection (a new search):
271
+ A keyed row stays selected when `data` is replaced, so in a server-paged grid the selection spans pages (`selectedRowIds` names them all; `getSelectedRows()` holds the ones on this page). A row without a key is named by the row object itself (a session-local id `#n`): it follows the row while the same object is in `data` and leaves the selection when it is gone. Set `clear-selection-on-data-change` when every new `data` should start a new selection (a new search):
272
272
 
273
273
  ```html
274
274
  <flex-table selectable clear-selection-on-data-change></flex-table>
@@ -830,6 +830,7 @@ The hook returns:
830
830
  | `loading` | A request is in flight, or none has answered yet (true from the first render until the first response settles, and while `enabled: false`) |
831
831
  | `error` | The last failed request, or `null`: `{ message, status?, code?, details?, body? }`. **Pass it to the table** (`error={source.error}`) or render `error.message` yourself — a failed request otherwise leaves the grid silently empty. Branch on `status` (HTTP), `code` (the server's rejection code, OData `error.code`) and `details` (OData `error.details`); `body` is the parsed response (or its text). A failure with no response — a network error, or a `@odata.nextLink` the hook refused — has a `message` only |
832
832
  | `page` / `setPage` | Zero-based page index |
833
+ | `pageSize` / `setPageSize` | Rows per page — starts at the `pageSize` option (20); `setPageSize` changes it and goes back to page 0. Passing the same `pageSize` option again on the next render keeps the size `setPageSize` set |
833
834
  | `sortCriteria` / `onSortChange` | Bind `onSortChange` to the table's `sort-change` event |
834
835
  | `search` / `setSearch` | Current search term and its setter (resets to page 0) |
835
836
  | `refresh` | Re-run the current request |
@@ -880,16 +881,17 @@ off(); // the last unsu
880
881
 
881
882
  | Member | Description |
882
883
  |---|---|
883
- | `getState()` | `{ data, totalCount, loading, error, page, sortCriteria, search }` — the same fields the hook returns. A new object only when something changed |
884
+ | `getState()` | `{ data, totalCount, loading, error, page, pageSize, sortCriteria, search }` — the same fields the hook returns. A new object only when something changed |
884
885
  | `subscribe(listener)` | Called on every change; returns the unsubscribe function. Requests go out only while someone is subscribed |
885
886
  | `setPage(page)` | Zero-based |
887
+ | `setPageSize(size)` | Rows per page; goes back to page 0 |
886
888
  | `setSort(criteria)` / `setSearch(term)` | Change the sort or search and go back to page 0 |
887
889
  | `refresh()` | Re-read with the same conditions (nothing while `enabled: false`) |
888
- | `update(url, options)` | New options. Only a changed request re-reads; a changed `fixedFilter` value goes back to page 0; `initial*` are read at creation only |
890
+ | `update(url, options)` | New options. Only a changed request re-reads; a changed `fixedFilter` value goes back to page 0; a changed `pageSize` value takes effect (page 0), the same value again keeps the size `setPageSize` set; `initial*` are read at creation only |
889
891
 
890
892
  Changes made in the same tick become one request with the final conditions, so `setSearch` followed by `setPage` does not send the intermediate one.
891
893
 
892
- For a Lit element, `ODataSourceController` ties a source to the element's lifecycle — it subscribes when the element connects, cancels when it disconnects, and re-renders it on every change:
894
+ For a Lit element, `ODataSourceController` ties a source to the element's lifecycle — it subscribes when the element connects, cancels when it disconnects, and re-renders it on every change. Give it a URL to create the source, or **a source you already have** (`new ODataSourceController(this, source)`) so several elements — a table, a pager — share one:
893
895
 
894
896
  ```ts
895
897
  import { LitElement, html } from 'lit';
@@ -952,8 +954,8 @@ count after search (not a server-reported total), and `loading`/`error` are alwa
952
954
  "refresh" button wired unconditionally against either hook doesn't need a branch.
953
955
 
954
956
  Without React, `createArraySource(rows, options)` (`@iyulab/flex-table/array`) is the same source with the same
955
- members as `createODataSource` — `getState()`, `subscribe()`, `setPage`, `setSort`, `setSearch`, `refresh` (no-op) —
956
- plus `update(rows, options)` when the rows change. `ArraySourceController` binds it to a Lit element:
957
+ members as `createODataSource` — `getState()`, `subscribe()`, `setPage`, `setPageSize`, `setSort`, `setSearch`, `refresh` (no-op) —
958
+ plus `update(rows, options)` when the rows change. `ArraySourceController` binds it to a Lit element (from rows, or an existing source):
957
959
 
958
960
  ```ts
959
961
  import { LitElement } from 'lit';
@@ -7,55 +7,59 @@ function n(n, r = {}) {
7
7
  initialPage: r.initialPage ?? 0,
8
8
  initialSearch: r.initialSearch ?? "",
9
9
  initialSort: r.initialSort
10
- }), s = o.page, c = o.sortCriteria, l = o.search, u = f(), d = /* @__PURE__ */ new Set();
11
- function f() {
12
- let e = a.pageSize ?? 20, n = t(i, {
10
+ }), s = o.page, c = o.sortCriteria, l = o.search, u = r.pageSize ?? 20, d = p(), f = /* @__PURE__ */ new Set();
11
+ function p() {
12
+ let e = t(i, {
13
13
  search: l,
14
14
  sortCriteria: c,
15
15
  page: s,
16
- pageSize: e,
16
+ pageSize: u,
17
17
  columns: a.columns,
18
18
  searchFields: a.searchFields
19
- }), r = n.totalCount === 0 ? 0 : Math.ceil(n.totalCount / e) - 1;
20
- return s > r && (s = r), {
21
- data: n.data,
22
- totalCount: n.totalCount,
19
+ }), n = e.totalCount === 0 ? 0 : Math.ceil(e.totalCount / u) - 1;
20
+ return s > n && (s = n), {
21
+ data: e.data,
22
+ totalCount: e.totalCount,
23
23
  loading: !1,
24
24
  error: null,
25
25
  page: s,
26
+ pageSize: u,
26
27
  sortCriteria: c,
27
28
  search: l
28
29
  };
29
30
  }
30
- function p() {
31
- u = f();
32
- for (let e of [...d]) e();
31
+ function m() {
32
+ d = p();
33
+ for (let e of [...f]) e();
33
34
  }
34
35
  return {
35
- getState: () => u,
36
+ getState: () => d,
36
37
  subscribe(e) {
37
- return d.add(e), () => {
38
- d.delete(e);
38
+ return f.add(e), () => {
39
+ f.delete(e);
39
40
  };
40
41
  },
41
42
  setPage(e) {
42
- s = e, p();
43
+ s = e, m();
44
+ },
45
+ setPageSize(e) {
46
+ e !== u && (u = e, s = 0, m());
43
47
  },
44
48
  setSort(e) {
45
- c = e, s = 0, p();
49
+ c = e, s = 0, m();
46
50
  },
47
51
  setSearch(e) {
48
- l = e, s = 0, p();
52
+ l = e, s = 0, m();
49
53
  },
50
54
  refresh() {},
51
55
  update(e, t = {}) {
52
- i = e, a = t, p();
56
+ t.pageSize !== void 0 && t.pageSize !== a.pageSize && t.pageSize !== u && (u = t.pageSize, s = 0), i = e, a = t, m();
53
57
  }
54
58
  };
55
59
  }
56
60
  var r = class {
57
61
  constructor(e, t, r = {}) {
58
- this.host = e, this.source = n(t, r), e.addController(this);
62
+ this.host = e, this.source = Array.isArray(t) ? n(t, r) : t, e.addController(this);
59
63
  }
60
64
  get state() {
61
65
  return this.source.getState();
@@ -13,6 +13,8 @@ export interface ArraySource<T> {
13
13
  subscribe(listener: () => void): () => void;
14
14
  /** 0-based 페이지로 옮긴다(범위를 넘으면 마지막 페이지). */
15
15
  setPage(page: number): void;
16
+ /** 페이지 크기를 바꾸고 첫 장으로 간다. */
17
+ setPageSize(size: number): void;
16
18
  /** 정렬을 바꾸고 첫 장으로 간다. */
17
19
  setSort(criteria: SortCriteria[]): void;
18
20
  /** 검색어를 바꾸고 첫 장으로 간다. */
@@ -35,6 +37,10 @@ export declare class ArraySourceController<T extends DataRow = DataRow> implemen
35
37
  /** 소스 — 조작(`setPage`·`setSort`·`setSearch`·`update`)은 이것으로 한다. */
36
38
  readonly source: ArraySource<T>;
37
39
  private unsubscribe?;
40
+ /**
41
+ * 행으로 소스를 만들거나, **이미 있는 소스**를 받는다 — 같은 소스를 여러 요소(표 · 페이저 · 목록 골격)가 함께 쓴다.
42
+ */
43
+ constructor(host: ReactiveControllerHost, source: ArraySource<T>);
38
44
  constructor(host: ReactiveControllerHost, data: T[], options?: ArraySourceOptions<T>);
39
45
  /** 현재 상태. */
40
46
  get state(): ODataSourceState<T>;
@@ -40,6 +40,10 @@ export interface UseArraySourceResult<T> {
40
40
  error: SourceError | null;
41
41
  page: number;
42
42
  setPage: (page: number) => void;
43
+ /** 한 페이지의 행 수 — `pageSize` 옵션으로 시작하고 `setPageSize` 로 바뀐다. */
44
+ pageSize: number;
45
+ /** 페이지 크기를 바꾸고 첫 장으로 간다. */
46
+ setPageSize: (size: number) => void;
43
47
  sortCriteria: SortCriteria[];
44
48
  onSortChange: (e: CustomEvent) => void;
45
49
  setSearch: (term: string) => void;
@@ -1844,6 +1844,9 @@ var K = {
1844
1844
  return this._filteredIndices.length;
1845
1845
  }
1846
1846
  getSelectedRows() {
1847
+ return this._selectionSnapshot().selectedRows;
1848
+ }
1849
+ _selectionSnapshot() {
1847
1850
  let e = [];
1848
1851
  if (this._rowSelection.selectedCount > 0) for (let t = 0; t < this.data.length; t++) this._rowSelection.isSelected(this.getRowId(this.data[t])) && e.push(t);
1849
1852
  return {
@@ -1880,7 +1883,7 @@ var K = {
1880
1883
  }
1881
1884
  }
1882
1885
  _dispatchRowSelectionEvent() {
1883
- this._emit("selection-change", this.getSelectedRows());
1886
+ this._emit("selection-change", this._selectionSnapshot());
1884
1887
  }
1885
1888
  _visibleRowIds() {
1886
1889
  let e = this._visibleIdsCache;
@@ -2081,7 +2084,7 @@ var K = {
2081
2084
  }), this._dispatchUndoStateEvent(), n;
2082
2085
  }
2083
2086
  deleteRows(e) {
2084
- let t = e ?? (this.selectable ? this.getSelectedRows().selectedIndices : this._getSelectedDataRows());
2087
+ let t = e ?? (this.selectable ? this._selectionSnapshot().selectedIndices : this._getSelectedDataRows());
2085
2088
  if (t.length === 0) return;
2086
2089
  let n = [...t].sort((e, t) => t - e), r = [];
2087
2090
  for (let e of n) e >= 0 && e < this.data.length && (r.push({
@@ -192,15 +192,13 @@ export declare class FlexTable extends LitElement {
192
192
  /** Number of rows after filtering (before pagination). */
193
193
  get filteredRowCount(): number;
194
194
  /**
195
- * The row selection. `selectedIds` is every selected row — on every page, including rows not in
196
- * `data` now. `selectedRows` and `selectedIndices` are the selected rows that `data` holds (in
197
- * `data` order, filtered-out rows included) and their positions in it.
198
- */
199
- getSelectedRows(): {
200
- selectedIds: string[];
201
- selectedIndices: number[];
202
- selectedRows: DataRow[];
203
- };
195
+ * The selected rows that `data` holds, in `data` order (filtered-out rows included) — the same shape
196
+ * as `u-rich-table`'s. Every selected id, on every page, is `selectedRowIds`; positions in `data` come
197
+ * with `selection-change` (`selectedIndices`).
198
+ */
199
+ getSelectedRows(): DataRow[];
200
+ /** The selection as `selection-change` reports it. */
201
+ private _selectionSnapshot;
204
202
  /** The id row selection keeps for `row` — its `rowKey` value as a string, or `#n` for a row without one. */
205
203
  getRowId(row: DataRow): string;
206
204
  /** Ids of the selected rows — every page, including rows not in `data` now. A copy. */
@@ -1,3 +1,3 @@
1
- import { a as e, i as t, n, o as r, r as i, t as a } from "./flex-table-DKBcfNA4.js";
1
+ import { a as e, i as t, n, o as r, r as i, t as a } from "./flex-table-B1W8VEBa.js";
2
2
  import { t as o } from "./locale-Cfm-vJji.js";
3
3
  export { a as FlexTable, e as RowSelectionState, t as UndoStack, n as effectiveAlign, i as exportData, o as flexTableLocale, r as renderCell };
@@ -21,6 +21,10 @@ export declare class ODataSourceController<T = Record<string, unknown>> implemen
21
21
  /** 소스 — 조작(`setPage`·`setSort`·`setSearch`·`refresh`·`update`)은 이것으로 한다. */
22
22
  readonly source: ODataSource<T>;
23
23
  private unsubscribe?;
24
+ /**
25
+ * 주소로 소스를 만들거나, **이미 있는 소스**를 받는다 — 같은 소스를 여러 요소(표 · 페이저 · 목록 골격)가 함께 쓴다.
26
+ */
27
+ constructor(host: ReactiveControllerHost, source: ODataSource<T>);
24
28
  constructor(host: ReactiveControllerHost, url: string, options?: ODataSourceOptions);
25
29
  /** 현재 상태. */
26
30
  get state(): ODataSourceState<T>;
@@ -1,9 +1,9 @@
1
1
  import { n as e, r as t, t as n } from "../query-Dw4iO0ir.js";
2
- import { t as r } from "../source--q5s2Oti.js";
2
+ import { t as r } from "../source-DOue0Ti3.js";
3
3
  //#region src/odata/controller.ts
4
4
  var i = class {
5
5
  constructor(e, t, n = {}) {
6
- this.host = e, this.source = r(t, n), e.addController(this);
6
+ this.host = e, this.source = typeof t == "string" ? r(t, n) : t, e.addController(this);
7
7
  }
8
8
  get state() {
9
9
  return this.source.getState();
@@ -50,6 +50,8 @@ export interface ODataSourceState<T> {
50
50
  error: SourceError | null;
51
51
  /** 0-based. */
52
52
  page: number;
53
+ /** 한 페이지의 행 수 — `pageSize` 옵션으로 시작하고(기본 20) `setPageSize` 로 바뀐다. */
54
+ pageSize: number;
53
55
  sortCriteria: SortCriteria[];
54
56
  search: string;
55
57
  }
@@ -66,6 +68,8 @@ export interface ODataSource<T> {
66
68
  subscribe(listener: () => void): () => void;
67
69
  /** 0-based 페이지로 옮긴다. */
68
70
  setPage(page: number): void;
71
+ /** 페이지 크기를 바꾸고 첫 장으로 간다(페이저의 «페이지당 행 수»). */
72
+ setPageSize(size: number): void;
69
73
  /** 정렬을 바꾸고 첫 장으로 간다. */
70
74
  setSort(criteria: SortCriteria[]): void;
71
75
  /** 검색어를 바꾸고 첫 장으로 간다. */
@@ -4,6 +4,8 @@ import type { ODataSourceOptions, ODataSourceState } from './source.js';
4
4
  export type UseODataSourceOptions = ODataSourceOptions;
5
5
  export interface UseODataSourceResult<T> extends ODataSourceState<T> {
6
6
  setPage: (page: number) => void;
7
+ /** 페이지 크기를 바꾸고 첫 장으로 간다. */
8
+ setPageSize: (size: number) => void;
7
9
  /** flex-table 의 `sort-change` 를 받는다(`detail.criteria`) — 정렬을 바꾸고 첫 장으로 간다. */
8
10
  onSortChange: (e: CustomEvent) => void;
9
11
  /** 검색어를 바꾸고 첫 장으로 간다. */
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
- import { t as e } from "./flex-table-DKBcfNA4.js";
1
+ import { t as e } from "./flex-table-B1W8VEBa.js";
2
2
  import { i as t } from "./query-Dw4iO0ir.js";
3
- import { t as n } from "./source--q5s2Oti.js";
3
+ import { t as n } from "./source-DOue0Ti3.js";
4
4
  import { t as r } from "./view-DiLr-TdY.js";
5
5
  import i, { useCallback as a, useEffect as o, useMemo as s, useState as c, useSyncExternalStore as l } from "react";
6
6
  import { createComponent as u } from "@lit/react";
@@ -17,6 +17,7 @@ function d(e, t = {}) {
17
17
  return {
18
18
  ...i,
19
19
  setPage: r.setPage,
20
+ setPageSize: r.setPageSize,
20
21
  onSortChange: s,
21
22
  setSearch: r.setSearch,
22
23
  refresh: r.refresh
@@ -30,16 +31,20 @@ function f(e, n = {}) {
30
31
  initialPage: l,
31
32
  initialSearch: u,
32
33
  initialSort: d
33
- }), [h, g] = c(m.page), [_, v] = c(m.sortCriteria), [y, b] = c(m.search), x = a((e) => {
34
+ }), [h, g] = c(m.page), [_, v] = c(m.sortCriteria), [y, b] = c(m.search), [x, S] = c(i), [C, w] = c(i);
35
+ i !== C && (w(i), S(i), g(0));
36
+ let T = a((e) => {
37
+ S(e), g(0);
38
+ }, []), E = a((e) => {
34
39
  b(e), g(0);
35
- }, []), S = a((e) => {
40
+ }, []), D = a((e) => {
36
41
  let t = e.detail?.criteria;
37
42
  t && (v(t), g(0));
38
- }, []), C = a(() => {}, []), { data: w, totalCount: T } = s(() => r(e, {
43
+ }, []), O = a(() => {}, []), { data: k, totalCount: A } = s(() => r(e, {
39
44
  search: y,
40
45
  sortCriteria: _,
41
46
  page: h,
42
- pageSize: i,
47
+ pageSize: x,
43
48
  columns: f,
44
49
  searchFields: p
45
50
  }), [
@@ -47,22 +52,24 @@ function f(e, n = {}) {
47
52
  y,
48
53
  _,
49
54
  h,
50
- i,
55
+ x,
51
56
  f,
52
57
  p
53
- ]), E = T === 0 ? 0 : Math.ceil(T / i) - 1;
54
- return h > E && g(E), {
55
- data: w,
56
- totalCount: T,
58
+ ]), j = A === 0 ? 0 : Math.ceil(A / x) - 1;
59
+ return h > j && g(j), {
60
+ data: k,
61
+ totalCount: A,
57
62
  loading: !1,
58
63
  error: null,
59
64
  page: h,
60
65
  setPage: g,
66
+ pageSize: x,
67
+ setPageSize: T,
61
68
  sortCriteria: _,
62
- onSortChange: S,
69
+ onSortChange: D,
63
70
  search: y,
64
- setSearch: x,
65
- refresh: C
71
+ setSearch: E,
72
+ refresh: O
66
73
  };
67
74
  }
68
75
  var p = u({
@@ -54,6 +54,7 @@ function c(e, i = {}) {
54
54
  loading: !0,
55
55
  error: null,
56
56
  page: f.page,
57
+ pageSize: i.pageSize ?? 20,
57
58
  sortCriteria: f.sortCriteria,
58
59
  search: f.search
59
60
  }, m = x(), h = /* @__PURE__ */ new Set(), g = null, _ = !1, v = null;
@@ -61,7 +62,7 @@ function c(e, i = {}) {
61
62
  return u.enabled ?? !0;
62
63
  }
63
64
  function b() {
64
- return u.pageSize ?? 20;
65
+ return p.pageSize;
65
66
  }
66
67
  function x() {
67
68
  return {
@@ -181,6 +182,12 @@ function c(e, i = {}) {
181
182
  setPage(e) {
182
183
  S({ page: e }), T();
183
184
  },
185
+ setPageSize(e) {
186
+ e !== p.pageSize && (S({
187
+ pageSize: e,
188
+ page: 0
189
+ }), T());
190
+ },
184
191
  setSort(e) {
185
192
  S({
186
193
  sortCriteria: e,
@@ -197,10 +204,14 @@ function c(e, i = {}) {
197
204
  y() && (v = null, T());
198
205
  },
199
206
  update(e, t = {}) {
200
- let n = l(t.fixedFilter), r = n !== d;
207
+ let n = l(t.fixedFilter), r = n !== d, i = t.pageSize !== void 0 && t.pageSize !== u.pageSize;
201
208
  c = e, u = t, d = n, r && (p = {
202
209
  ...p,
203
210
  page: 0
211
+ }), i && t.pageSize !== p.pageSize && (p = {
212
+ ...p,
213
+ pageSize: t.pageSize,
214
+ page: 0
204
215
  }), C(), T();
205
216
  }
206
217
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iyulab/flex-table",
3
- "version": "0.56.1",
3
+ "version": "0.58.0",
4
4
  "description": "A minimalist, input-centric data grid web component",
5
5
  "type": "module",
6
6
  "main": "./dist/flex-table.js",
@@ -119,7 +119,7 @@ Enter/Escape and blur-to-commit behavior.
119
119
  | `selectAll()` / `deselectAll()` | `selectAll`: the rows in view (multi mode only) · `deselectAll`: every page |
120
120
  | `selectWhere(predicate)` | `(row, dataIndex) => boolean` over the visible rows |
121
121
  | `setSelection(ids)` | Replace with these row ids; the same set again fires nothing |
122
- | `getSelectedRows()` | `{ selectedIds, selectedIndices, selectedRows }` — ids: all pages · rows: the ones `data` holds |
122
+ | `getSelectedRows()` | `DataRow[]` — the selected rows `data` holds (as `u-rich-table`) · ids of every page: `selectedRowIds` |
123
123
  | `getRowId(row)` · `selectedRowIds` | A row's id · the selected ids (all pages) |
124
124
 
125
125
  ### Filtering, undo, comments, import/export
@@ -110,6 +110,7 @@ function Orders() {
110
110
  | `loading` | Request in flight, or no answer yet (true from the first render until the first response settles, and while `enabled: false`) — so `!loading && totalCount === 0` means "no results" |
111
111
  | `error` | `SourceError \| null` — `{ message, status?, code?, details?, body?, cause? }`; pass it to the table (`error`) or render `error.message`; branch on `status` / `code` (OData `error.code`). `message` is the server's sentence when it sent one; otherwise this package's, in the `flexTableLocale` language — `requestFailed` (`Request failed ({status})`) when a response came back, `networkFailed` when none did (the transport's exception is in `cause`) |
112
112
  | `page`, `setPage` | Zero-based |
113
+ | `pageSize`, `setPageSize` | Rows per page (the `pageSize` option, then `setPageSize` — resets to page 0) |
113
114
  | `sortCriteria`, `onSortChange` | Pass `onSortChange` to the table's `sort-change` (resets to page 0) |
114
115
  | `search`, `setSearch` | Literal text (resets to page 0) |
115
116
  | `refresh` | Re-run the current request |
@@ -158,9 +159,9 @@ Differences: `totalCount` is the count after search, `loading` is always `false`
158
159
 
159
160
  `useODataSource` adapts a framework-neutral source with the same options and state:
160
161
  `createODataSource(url, options)` → `getState()` · `subscribe(listener)` (the first subscriber starts loading, the last
161
- unsubscribe cancels) · `setPage` · `setSort(criteria)` · `setSearch` · `refresh` · `update(url, options)`. Changes in one
162
+ unsubscribe cancels) · `setPage` · `setPageSize` · `setSort(criteria)` · `setSearch` · `refresh` · `update(url, options)`. Changes in one
162
163
  tick become one request. For Lit, `ODataSourceController` subscribes on connect, cancels on disconnect and re-renders
163
- the host:
164
+ the host — from a URL, or from a source you already have (`new ODataSourceController(this, source)`, so a table and a pager share it):
164
165
 
165
166
  ```ts
166
167
  import { LitElement, html } from 'lit';