@iyulab/flex-table 0.63.0 → 0.64.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 +10 -0
- package/README.md +1 -0
- package/dist/array/types.d.ts +5 -0
- package/dist/odata/types.d.ts +3 -1
- package/dist/react.js +93 -51
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.64.0] - 2026-10-08
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`useODataSource` and `useArraySource` return `source`** — the source the hook binds, the same object every render.
|
|
8
|
+
A React screen hands it to a list skeleton that binds its views itself (`<ListPage source={orders.source}>`,
|
|
9
|
+
`bindSource(orders.source, el)`) and keeps its options as props, instead of building the source with `useMemo`,
|
|
10
|
+
reading it with `useSyncExternalStore` and calling `update` from an effect. `useArraySource`'s `source` reads the
|
|
11
|
+
hook's state and notifies its subscribers after each commit.
|
|
12
|
+
|
|
3
13
|
## [0.63.0] - 2026-10-08
|
|
4
14
|
|
|
5
15
|
### Added
|
package/README.md
CHANGED
|
@@ -911,6 +911,7 @@ The hook returns:
|
|
|
911
911
|
| `search` / `setSearch` | Current search term and its setter (resets to page 0) |
|
|
912
912
|
| `refresh` | Re-run the current request |
|
|
913
913
|
| `fetchAll` | The whole result of the current conditions — the source's `fetchAll` (below), for exporting what the list shows |
|
|
914
|
+
| `source` | The source the hook binds (the same object every render) — hand it to a list skeleton that binds views itself: `<ListPage source={orders.source}>` (`@iyulab/enterprise/react`) or `bindSource(orders.source, element)`. `useArraySource` returns one too, over its own state |
|
|
914
915
|
|
|
915
916
|
#### Search semantics
|
|
916
917
|
|
package/dist/array/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SortCriteria } from '../core/sorting.js';
|
|
2
2
|
import type { SourceError } from '../core/source-error.js';
|
|
3
3
|
import type { FetchAllOptions } from '../core/fetch-all.js';
|
|
4
|
+
import type { ArraySource } from './source.js';
|
|
4
5
|
export interface UseArraySourceOptions<T> {
|
|
5
6
|
/** 페이지당 행 수. `useODataSource`와 동일 기본값. */
|
|
6
7
|
pageSize?: number;
|
|
@@ -30,7 +31,11 @@ export interface UseArraySourceOptions<T> {
|
|
|
30
31
|
*/
|
|
31
32
|
searchFields?: (row: T) => Array<string | number | boolean | null | undefined>;
|
|
32
33
|
}
|
|
34
|
+
/** `useArraySource` 의 `source` — 목록 골격(`ListPage` · `bindSource`)에 넘기는 소스. 이 훅의 상태를 읽고 조작은 훅으로 간다. */
|
|
35
|
+
export type HookArraySource<T> = Omit<ArraySource<T>, 'update'>;
|
|
33
36
|
export interface UseArraySourceResult<T> {
|
|
37
|
+
/** 이 훅의 상태를 소스 모양으로 — `<ListPage source={orders.source}>` · `bindSource(orders.source, el)`. 늘 같은 객체다. */
|
|
38
|
+
source: HookArraySource<T>;
|
|
34
39
|
/** 현재 페이지의 행(검색+정렬 적용 후 slice). */
|
|
35
40
|
data: T[];
|
|
36
41
|
/** 검색+정렬 적용 후, 페이지 나누기 전의 총 건수(`useODataSource`의 `@odata.count`와 동일 의미). */
|
package/dist/odata/types.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { SortCriteria } from '../core/sorting.js';
|
|
2
|
-
import type { ODataSourceOptions, ODataSourceState } from './source.js';
|
|
2
|
+
import type { ODataSource, ODataSourceOptions, ODataSourceState } from './source.js';
|
|
3
3
|
import type { FetchAllOptions } from '../core/fetch-all.js';
|
|
4
4
|
/** `useODataSource` 의 옵션 — 프레임워크 중립 소스(`createODataSource`)의 설정과 같다. `initial*` 은 첫 렌더에서만 읽힌다. */
|
|
5
5
|
export type UseODataSourceOptions = ODataSourceOptions;
|
|
6
6
|
export interface UseODataSourceResult<T> extends ODataSourceState<T> {
|
|
7
|
+
/** 이 훅이 묶은 소스 — 목록 골격(`<ListPage source={orders.source}>` · `bindSource`)에 넘긴다. 늘 같은 객체다. */
|
|
8
|
+
source: ODataSource<T>;
|
|
7
9
|
setPage: (page: number) => void;
|
|
8
10
|
/** 페이지 크기를 바꾸고 첫 장으로 간다. */
|
|
9
11
|
setPageSize: (size: number) => void;
|
package/dist/react.js
CHANGED
|
@@ -2,20 +2,21 @@ import { t as e } from "./flex-table-BufHlQ2v.js";
|
|
|
2
2
|
import { n as t, r as n, u as r } from "./fetch-all-DkdNzWrF.js";
|
|
3
3
|
import { t as i } from "./source-dm6qXFh1.js";
|
|
4
4
|
import { n as a, t as o } from "./view-DuDIMoXV.js";
|
|
5
|
-
import s, { useCallback as c, useEffect as l,
|
|
6
|
-
import { createComponent as
|
|
5
|
+
import s, { useCallback as c, useEffect as l, useLayoutEffect as u, useMemo as d, useRef as f, useState as p, useSyncExternalStore as m } from "react";
|
|
6
|
+
import { createComponent as h } from "@lit/react";
|
|
7
7
|
//#region src/odata/use-odata-source.ts
|
|
8
|
-
function
|
|
9
|
-
let [n] =
|
|
8
|
+
function g(e, t = {}) {
|
|
9
|
+
let [n] = p(() => i(e, t));
|
|
10
10
|
l(() => {
|
|
11
11
|
n.update(e, t);
|
|
12
12
|
});
|
|
13
|
-
let r =
|
|
13
|
+
let r = m(n.subscribe, n.getState, n.getState), a = c((e) => {
|
|
14
14
|
let t = e.detail?.criteria;
|
|
15
15
|
t && n.setSort(t);
|
|
16
16
|
}, [n]);
|
|
17
17
|
return {
|
|
18
18
|
...r,
|
|
19
|
+
source: n,
|
|
19
20
|
setPage: n.setPage,
|
|
20
21
|
setPageSize: n.setPageSize,
|
|
21
22
|
onSortChange: a,
|
|
@@ -26,66 +27,107 @@ function m(e, t = {}) {
|
|
|
26
27
|
}
|
|
27
28
|
//#endregion
|
|
28
29
|
//#region src/array/use-array-source.ts
|
|
29
|
-
function
|
|
30
|
-
let { pageSize: n = 20, defaultOrderBy: i, initialPage: s = 0, initialSearch: l = "", initialSort:
|
|
30
|
+
function _(e, t = {}) {
|
|
31
|
+
let { pageSize: n = 20, defaultOrderBy: i, initialPage: s = 0, initialSearch: l = "", initialSort: m, columns: h, searchFields: g } = t, _ = r({
|
|
31
32
|
defaultOrderBy: i,
|
|
32
33
|
initialPage: s,
|
|
33
34
|
initialSearch: l,
|
|
34
|
-
initialSort:
|
|
35
|
-
}), [
|
|
36
|
-
n !==
|
|
37
|
-
let
|
|
38
|
-
|
|
39
|
-
}, []),
|
|
40
|
-
|
|
41
|
-
}, []),
|
|
35
|
+
initialSort: m
|
|
36
|
+
}), [v, y] = p(_.page), [b, x] = p(_.sortCriteria), [S, C] = p(_.search), [w, T] = p(n), [E, D] = p(n);
|
|
37
|
+
n !== E && (D(n), T(n), y(0));
|
|
38
|
+
let O = c((e) => {
|
|
39
|
+
T(e), y(0);
|
|
40
|
+
}, []), k = c((e) => {
|
|
41
|
+
C(e), y(0);
|
|
42
|
+
}, []), A = c((e) => {
|
|
42
43
|
let t = e.detail?.criteria;
|
|
43
|
-
t && (
|
|
44
|
-
}, []),
|
|
45
|
-
search:
|
|
46
|
-
sortCriteria:
|
|
47
|
-
columns:
|
|
48
|
-
searchFields:
|
|
44
|
+
t && (x(t), y(0));
|
|
45
|
+
}, []), j = c(() => {}, []), M = c((t) => a(e, {
|
|
46
|
+
search: S,
|
|
47
|
+
sortCriteria: b,
|
|
48
|
+
columns: h,
|
|
49
|
+
searchFields: g
|
|
49
50
|
}, t), [
|
|
50
51
|
e,
|
|
52
|
+
S,
|
|
51
53
|
b,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
searchFields: m
|
|
54
|
+
h,
|
|
55
|
+
g
|
|
56
|
+
]), { data: N, totalCount: P } = d(() => o(e, {
|
|
57
|
+
search: S,
|
|
58
|
+
sortCriteria: b,
|
|
59
|
+
page: v,
|
|
60
|
+
pageSize: w,
|
|
61
|
+
columns: h,
|
|
62
|
+
searchFields: g
|
|
62
63
|
}), [
|
|
63
64
|
e,
|
|
65
|
+
S,
|
|
64
66
|
b,
|
|
65
67
|
v,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
data:
|
|
73
|
-
totalCount:
|
|
68
|
+
w,
|
|
69
|
+
h,
|
|
70
|
+
g
|
|
71
|
+
]), F = P === 0 ? 0 : Math.ceil(P / w) - 1;
|
|
72
|
+
v > F && y(F);
|
|
73
|
+
let I = d(() => ({
|
|
74
|
+
data: N,
|
|
75
|
+
totalCount: P,
|
|
76
|
+
loading: !1,
|
|
77
|
+
error: null,
|
|
78
|
+
page: v,
|
|
79
|
+
pageSize: w,
|
|
80
|
+
sortCriteria: b,
|
|
81
|
+
search: S
|
|
82
|
+
}), [
|
|
83
|
+
N,
|
|
84
|
+
P,
|
|
85
|
+
v,
|
|
86
|
+
w,
|
|
87
|
+
b,
|
|
88
|
+
S
|
|
89
|
+
]), L = f(I), R = f(M), z = f(/* @__PURE__ */ new Set());
|
|
90
|
+
u(() => {
|
|
91
|
+
if (R.current = M, L.current !== I) {
|
|
92
|
+
L.current = I;
|
|
93
|
+
for (let e of [...z.current]) e();
|
|
94
|
+
}
|
|
95
|
+
}, [I, M]);
|
|
96
|
+
let [B] = p(() => ({
|
|
97
|
+
getState: () => L.current,
|
|
98
|
+
subscribe(e) {
|
|
99
|
+
return z.current.add(e), () => {
|
|
100
|
+
z.current.delete(e);
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
setPage: y,
|
|
104
|
+
setPageSize: O,
|
|
105
|
+
setSort(e) {
|
|
106
|
+
x(e), y(0);
|
|
107
|
+
},
|
|
108
|
+
setSearch: k,
|
|
109
|
+
refresh: j,
|
|
110
|
+
fetchAll: (e) => R.current(e)
|
|
111
|
+
}));
|
|
112
|
+
return {
|
|
113
|
+
source: B,
|
|
114
|
+
data: N,
|
|
115
|
+
totalCount: P,
|
|
74
116
|
loading: !1,
|
|
75
117
|
error: null,
|
|
76
|
-
page:
|
|
77
|
-
setPage:
|
|
78
|
-
pageSize:
|
|
79
|
-
setPageSize:
|
|
80
|
-
sortCriteria:
|
|
81
|
-
onSortChange:
|
|
82
|
-
search:
|
|
83
|
-
setSearch:
|
|
84
|
-
refresh:
|
|
85
|
-
fetchAll:
|
|
118
|
+
page: v,
|
|
119
|
+
setPage: y,
|
|
120
|
+
pageSize: w,
|
|
121
|
+
setPageSize: O,
|
|
122
|
+
sortCriteria: b,
|
|
123
|
+
onSortChange: A,
|
|
124
|
+
search: S,
|
|
125
|
+
setSearch: k,
|
|
126
|
+
refresh: j,
|
|
127
|
+
fetchAll: M
|
|
86
128
|
};
|
|
87
129
|
}
|
|
88
|
-
var
|
|
130
|
+
var v = h({
|
|
89
131
|
tagName: "flex-table",
|
|
90
132
|
elementClass: e,
|
|
91
133
|
react: s,
|
|
@@ -124,4 +166,4 @@ var g = p({
|
|
|
124
166
|
}
|
|
125
167
|
});
|
|
126
168
|
//#endregion
|
|
127
|
-
export {
|
|
169
|
+
export { v as FlexTableReact, t as RowLimitError, n as SourceRequestError, _ as useArraySource, g as useODataSource };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/flex-table",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.64.0",
|
|
4
4
|
"description": "A minimalist, input-centric data grid web component",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/flex-table.js",
|
|
@@ -89,8 +89,8 @@
|
|
|
89
89
|
"devDependencies": {
|
|
90
90
|
"@lit/react": "^1.0.8",
|
|
91
91
|
"@types/node": "^26.1.1",
|
|
92
|
-
"@types/react": "^19.
|
|
93
|
-
"@types/react-dom": "^19.
|
|
92
|
+
"@types/react": "^19.3.0",
|
|
93
|
+
"@types/react-dom": "^19.3.0",
|
|
94
94
|
"@typescript-eslint/eslint-plugin": "^8.64.0",
|
|
95
95
|
"@typescript-eslint/parser": "^8.64.0",
|
|
96
96
|
"@vitest/browser-playwright": "^5.0.0",
|