react-resource-ui 0.1.1 → 0.1.3
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/dist/index.cjs +110 -66
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +110 -66
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -73,64 +73,84 @@ function useResource(config) {
|
|
|
73
73
|
const getData = (0, import_react.useMemo)(() => normalizeSource(source), [source]);
|
|
74
74
|
const prevScrollTop = (0, import_react.useRef)(0);
|
|
75
75
|
const scrollRef = (0, import_react.useRef)(null);
|
|
76
|
-
const
|
|
77
|
-
|
|
76
|
+
const [hasNext, setHasNext] = (0, import_react.useState)(true);
|
|
77
|
+
const total = (0, import_react.useRef)(null);
|
|
78
|
+
async function asyncNormalize(localPage) {
|
|
78
79
|
const params = {
|
|
79
|
-
page,
|
|
80
|
+
page: localPage,
|
|
80
81
|
pageSize
|
|
81
82
|
};
|
|
82
|
-
setLoading(true);
|
|
83
|
-
requestTracker.current += 1;
|
|
84
|
-
const currentRequestId = requestTracker.current;
|
|
85
|
-
setError(null);
|
|
86
83
|
try {
|
|
87
84
|
const rawData = await getData(params);
|
|
88
|
-
|
|
89
|
-
setLoading(false);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
;
|
|
93
|
-
setLoading(false);
|
|
94
|
-
return rawData;
|
|
85
|
+
return { data: rawData, error: null };
|
|
95
86
|
} catch (err) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
setError(new Error("unknown error"));
|
|
101
|
-
}
|
|
102
|
-
setLoading(false);
|
|
103
|
-
}
|
|
87
|
+
return {
|
|
88
|
+
data: null,
|
|
89
|
+
error: err instanceof Error ? err : new Error("unknown error")
|
|
90
|
+
};
|
|
104
91
|
}
|
|
105
92
|
}
|
|
106
93
|
async function orchestrator() {
|
|
107
94
|
const isPageMode = pagination?.type === "page";
|
|
108
95
|
prevScrollTop.current = scrollTop;
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
96
|
+
const localPage = page;
|
|
97
|
+
const cached = cache.current[localPage];
|
|
98
|
+
if (isPageMode && cached) {
|
|
99
|
+
setData(cached);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
setHasNext(true);
|
|
103
|
+
total.current = null;
|
|
104
|
+
requestTracker.current += 1;
|
|
105
|
+
const currentRequestId = requestTracker.current;
|
|
106
|
+
setLoading(true);
|
|
107
|
+
setError(null);
|
|
108
|
+
const result = await asyncNormalize(localPage);
|
|
109
|
+
if (currentRequestId !== requestTracker.current) {
|
|
110
|
+
setLoading(false);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
;
|
|
114
|
+
setLoading(false);
|
|
115
|
+
if (result.error) {
|
|
116
|
+
setError(result.error);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
let rawData;
|
|
120
|
+
if (Array.isArray(result.data)) {
|
|
121
|
+
rawData = result.data;
|
|
122
|
+
} else {
|
|
123
|
+
total.current = result.data.total;
|
|
124
|
+
rawData = result.data.data;
|
|
125
|
+
}
|
|
126
|
+
if (total.current !== null) {
|
|
127
|
+
setHasNext(localPage < Math.ceil(total.current / pageSize));
|
|
128
|
+
} else {
|
|
129
|
+
if (rawData.length < pageSize) {
|
|
130
|
+
setHasNext(false);
|
|
114
131
|
}
|
|
115
132
|
}
|
|
116
|
-
const rawData = await asyncNormalize();
|
|
117
133
|
if (!rawData) return;
|
|
118
|
-
if (rawData.length < pageSize) hasMore.current = false;
|
|
119
134
|
setData((prev) => {
|
|
120
135
|
if (isPageMode) return rawData;
|
|
121
|
-
|
|
136
|
+
const indexStart = (localPage - 1) * pageSize;
|
|
137
|
+
const newData = [...prev];
|
|
138
|
+
for (let i = 0; i < rawData.length; i++) {
|
|
139
|
+
newData[indexStart + i] = rawData[i];
|
|
140
|
+
}
|
|
141
|
+
return newData;
|
|
122
142
|
});
|
|
123
143
|
if (isPageMode) {
|
|
124
|
-
cache.current[
|
|
144
|
+
cache.current[localPage] = rawData;
|
|
125
145
|
Object.keys(cache.current).forEach((val) => {
|
|
126
|
-
if (Math.abs(
|
|
146
|
+
if (Math.abs(localPage - +val) > 1) {
|
|
127
147
|
delete cache.current[+val];
|
|
128
148
|
}
|
|
129
149
|
});
|
|
130
150
|
}
|
|
131
151
|
}
|
|
132
152
|
(0, import_react.useEffect)(() => {
|
|
133
|
-
if (!
|
|
153
|
+
if (!hasNext) return;
|
|
134
154
|
if (pagination?.type !== "infinite") return;
|
|
135
155
|
const el = scrollRef.current;
|
|
136
156
|
if (!el) return;
|
|
@@ -140,7 +160,7 @@ function useResource(config) {
|
|
|
140
160
|
setPage((prev) => prev + 1);
|
|
141
161
|
})();
|
|
142
162
|
}
|
|
143
|
-
}, [scrollTop, pagination?.type, loading]);
|
|
163
|
+
}, [scrollTop, pagination?.type, loading, hasNext]);
|
|
144
164
|
(0, import_react.useEffect)(() => {
|
|
145
165
|
orchestrator();
|
|
146
166
|
}, [page, pageSize, source, pagination?.type]);
|
|
@@ -163,39 +183,59 @@ function useResource(config) {
|
|
|
163
183
|
let offsetY = 0;
|
|
164
184
|
let totalHeight = 0;
|
|
165
185
|
if (shouldVirtualize) {
|
|
166
|
-
const
|
|
186
|
+
const total2 = data.length;
|
|
167
187
|
const rawStart = Math.floor(scrollTop / itemHeight);
|
|
168
188
|
const startIndex = Math.max(0, rawStart - 2);
|
|
169
189
|
const visibleCount = Math.ceil(containerHeight / itemHeight);
|
|
170
|
-
const endIndex = Math.min(startIndex + visibleCount + 4,
|
|
190
|
+
const endIndex = Math.min(startIndex + visibleCount + 4, total2);
|
|
171
191
|
finalData = data.slice(startIndex, endIndex);
|
|
172
192
|
offsetY = itemHeight * startIndex;
|
|
173
|
-
totalHeight =
|
|
193
|
+
totalHeight = total2 * itemHeight;
|
|
174
194
|
}
|
|
175
|
-
return { data: finalData, loading, error, page, setPage, setScrollTop, offsetY, totalHeight, totalItems: data.length, scrollRef };
|
|
195
|
+
return { data: finalData, loading, error, page, setPage, setScrollTop, offsetY, totalHeight, totalItems: data.length, scrollRef, hasNext };
|
|
176
196
|
}
|
|
177
197
|
|
|
178
198
|
// src/components/DataTable.tsx
|
|
179
|
-
var import_react2 = require("react");
|
|
180
199
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
181
200
|
function DataTable(props) {
|
|
182
|
-
const {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
201
|
+
const {
|
|
202
|
+
data,
|
|
203
|
+
loading,
|
|
204
|
+
error,
|
|
205
|
+
page,
|
|
206
|
+
setPage,
|
|
207
|
+
setScrollTop,
|
|
208
|
+
type,
|
|
209
|
+
virtualization,
|
|
210
|
+
hasNext
|
|
211
|
+
} = props;
|
|
212
|
+
const offsetY = props.offsetY ?? 0;
|
|
213
|
+
const totalHeight = props.totalHeight ?? 0;
|
|
214
|
+
const itemHeight = 50;
|
|
215
|
+
const colCount = data[0] ? Object.keys(data[0]).length : 1;
|
|
187
216
|
if (loading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading..." });
|
|
188
217
|
if (error) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: error.message });
|
|
189
|
-
if ((props.totalItems ?? data.length) === 0)
|
|
218
|
+
if ((props.totalItems ?? data.length) === 0)
|
|
219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "No Data to create Table" });
|
|
190
220
|
const content = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { children: [
|
|
191
221
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: Object.keys(data[0]).map((val) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: val }, val)) }) }),
|
|
192
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
222
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tbody", { children: [
|
|
223
|
+
virtualization && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { style: { height: offsetY }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { colSpan: colCount }) }),
|
|
224
|
+
data.map((val, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: Object.keys(val).map((key) => {
|
|
225
|
+
const value = val[key];
|
|
226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "cell", children: value != null ? value.toString() : "-" }) }, key);
|
|
227
|
+
}) }, index)),
|
|
228
|
+
virtualization && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
229
|
+
"tr",
|
|
230
|
+
{
|
|
231
|
+
style: {
|
|
232
|
+
height: totalHeight - offsetY - data.length * itemHeight
|
|
233
|
+
},
|
|
234
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { colSpan: colCount })
|
|
235
|
+
}
|
|
236
|
+
)
|
|
237
|
+
] })
|
|
196
238
|
] });
|
|
197
|
-
const offsetY = props.offsetY ?? 0;
|
|
198
|
-
const totalHeight = props.totalHeight ?? 0;
|
|
199
239
|
const finalTable = virtualization ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
200
240
|
"div",
|
|
201
241
|
{
|
|
@@ -204,29 +244,33 @@ function DataTable(props) {
|
|
|
204
244
|
onScroll: (e) => {
|
|
205
245
|
setScrollTop(e.currentTarget.scrollTop);
|
|
206
246
|
},
|
|
207
|
-
children:
|
|
208
|
-
"div",
|
|
209
|
-
{
|
|
210
|
-
style: {
|
|
211
|
-
transform: `translateY(${offsetY}px)`,
|
|
212
|
-
position: "absolute",
|
|
213
|
-
top: 0,
|
|
214
|
-
left: 0,
|
|
215
|
-
right: 0
|
|
216
|
-
},
|
|
217
|
-
children: content
|
|
218
|
-
}
|
|
219
|
-
) })
|
|
247
|
+
children: content
|
|
220
248
|
}
|
|
221
249
|
) : content;
|
|
222
250
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
223
251
|
type === "page" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
224
252
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => setPage((prev) => Math.max(prev - 1, 1)), children: "prev" }),
|
|
225
253
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: page }),
|
|
226
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
254
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
255
|
+
"button",
|
|
256
|
+
{
|
|
257
|
+
onClick: () => setPage((prev) => {
|
|
258
|
+
if (hasNext) return prev + 1;
|
|
259
|
+
return prev;
|
|
260
|
+
}),
|
|
261
|
+
children: "next"
|
|
262
|
+
}
|
|
263
|
+
)
|
|
227
264
|
] }),
|
|
228
265
|
finalTable,
|
|
229
|
-
type === "loadmore" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
266
|
+
type === "loadmore" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
267
|
+
"button",
|
|
268
|
+
{
|
|
269
|
+
disabled: !hasNext,
|
|
270
|
+
onClick: () => setPage((prev) => prev + 1),
|
|
271
|
+
children: "load more"
|
|
272
|
+
}
|
|
273
|
+
)
|
|
230
274
|
] });
|
|
231
275
|
}
|
|
232
276
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.d.cts
CHANGED
|
@@ -5,7 +5,10 @@ type ResourceParams = {
|
|
|
5
5
|
page?: number;
|
|
6
6
|
pageSize?: number;
|
|
7
7
|
};
|
|
8
|
-
type Source<T> = T[] | string | ((params: ResourceParams) => Promise<T[]
|
|
8
|
+
type Source<T> = T[] | string | ((params: ResourceParams) => Promise<T[] | {
|
|
9
|
+
data: T[];
|
|
10
|
+
total: number;
|
|
11
|
+
}>);
|
|
9
12
|
|
|
10
13
|
type PaginationConfig = {
|
|
11
14
|
type: "page" | "loadmore" | "infinite";
|
|
@@ -32,6 +35,7 @@ declare function useResource<T>(config: Config<T>): {
|
|
|
32
35
|
totalHeight: number;
|
|
33
36
|
totalItems: number;
|
|
34
37
|
scrollRef: react.RefObject<HTMLDivElement | null>;
|
|
38
|
+
hasNext: boolean;
|
|
35
39
|
};
|
|
36
40
|
|
|
37
41
|
type DataTableProps<T extends Record<string, unknown>> = {
|
|
@@ -47,6 +51,7 @@ type DataTableProps<T extends Record<string, unknown>> = {
|
|
|
47
51
|
totalHeight?: number;
|
|
48
52
|
totalItems?: number;
|
|
49
53
|
scrollRef?: React.RefObject<HTMLDivElement> | null;
|
|
54
|
+
hasNext: boolean;
|
|
50
55
|
};
|
|
51
56
|
declare function DataTable<T extends Record<string, unknown>>(props: DataTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
52
57
|
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,10 @@ type ResourceParams = {
|
|
|
5
5
|
page?: number;
|
|
6
6
|
pageSize?: number;
|
|
7
7
|
};
|
|
8
|
-
type Source<T> = T[] | string | ((params: ResourceParams) => Promise<T[]
|
|
8
|
+
type Source<T> = T[] | string | ((params: ResourceParams) => Promise<T[] | {
|
|
9
|
+
data: T[];
|
|
10
|
+
total: number;
|
|
11
|
+
}>);
|
|
9
12
|
|
|
10
13
|
type PaginationConfig = {
|
|
11
14
|
type: "page" | "loadmore" | "infinite";
|
|
@@ -32,6 +35,7 @@ declare function useResource<T>(config: Config<T>): {
|
|
|
32
35
|
totalHeight: number;
|
|
33
36
|
totalItems: number;
|
|
34
37
|
scrollRef: react.RefObject<HTMLDivElement | null>;
|
|
38
|
+
hasNext: boolean;
|
|
35
39
|
};
|
|
36
40
|
|
|
37
41
|
type DataTableProps<T extends Record<string, unknown>> = {
|
|
@@ -47,6 +51,7 @@ type DataTableProps<T extends Record<string, unknown>> = {
|
|
|
47
51
|
totalHeight?: number;
|
|
48
52
|
totalItems?: number;
|
|
49
53
|
scrollRef?: React.RefObject<HTMLDivElement> | null;
|
|
54
|
+
hasNext: boolean;
|
|
50
55
|
};
|
|
51
56
|
declare function DataTable<T extends Record<string, unknown>>(props: DataTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
52
57
|
|
package/dist/index.js
CHANGED
|
@@ -46,64 +46,84 @@ function useResource(config) {
|
|
|
46
46
|
const getData = useMemo(() => normalizeSource(source), [source]);
|
|
47
47
|
const prevScrollTop = useRef(0);
|
|
48
48
|
const scrollRef = useRef(null);
|
|
49
|
-
const
|
|
50
|
-
|
|
49
|
+
const [hasNext, setHasNext] = useState(true);
|
|
50
|
+
const total = useRef(null);
|
|
51
|
+
async function asyncNormalize(localPage) {
|
|
51
52
|
const params = {
|
|
52
|
-
page,
|
|
53
|
+
page: localPage,
|
|
53
54
|
pageSize
|
|
54
55
|
};
|
|
55
|
-
setLoading(true);
|
|
56
|
-
requestTracker.current += 1;
|
|
57
|
-
const currentRequestId = requestTracker.current;
|
|
58
|
-
setError(null);
|
|
59
56
|
try {
|
|
60
57
|
const rawData = await getData(params);
|
|
61
|
-
|
|
62
|
-
setLoading(false);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
;
|
|
66
|
-
setLoading(false);
|
|
67
|
-
return rawData;
|
|
58
|
+
return { data: rawData, error: null };
|
|
68
59
|
} catch (err) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
setError(new Error("unknown error"));
|
|
74
|
-
}
|
|
75
|
-
setLoading(false);
|
|
76
|
-
}
|
|
60
|
+
return {
|
|
61
|
+
data: null,
|
|
62
|
+
error: err instanceof Error ? err : new Error("unknown error")
|
|
63
|
+
};
|
|
77
64
|
}
|
|
78
65
|
}
|
|
79
66
|
async function orchestrator() {
|
|
80
67
|
const isPageMode = pagination?.type === "page";
|
|
81
68
|
prevScrollTop.current = scrollTop;
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
69
|
+
const localPage = page;
|
|
70
|
+
const cached = cache.current[localPage];
|
|
71
|
+
if (isPageMode && cached) {
|
|
72
|
+
setData(cached);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
setHasNext(true);
|
|
76
|
+
total.current = null;
|
|
77
|
+
requestTracker.current += 1;
|
|
78
|
+
const currentRequestId = requestTracker.current;
|
|
79
|
+
setLoading(true);
|
|
80
|
+
setError(null);
|
|
81
|
+
const result = await asyncNormalize(localPage);
|
|
82
|
+
if (currentRequestId !== requestTracker.current) {
|
|
83
|
+
setLoading(false);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
;
|
|
87
|
+
setLoading(false);
|
|
88
|
+
if (result.error) {
|
|
89
|
+
setError(result.error);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
let rawData;
|
|
93
|
+
if (Array.isArray(result.data)) {
|
|
94
|
+
rawData = result.data;
|
|
95
|
+
} else {
|
|
96
|
+
total.current = result.data.total;
|
|
97
|
+
rawData = result.data.data;
|
|
98
|
+
}
|
|
99
|
+
if (total.current !== null) {
|
|
100
|
+
setHasNext(localPage < Math.ceil(total.current / pageSize));
|
|
101
|
+
} else {
|
|
102
|
+
if (rawData.length < pageSize) {
|
|
103
|
+
setHasNext(false);
|
|
87
104
|
}
|
|
88
105
|
}
|
|
89
|
-
const rawData = await asyncNormalize();
|
|
90
106
|
if (!rawData) return;
|
|
91
|
-
if (rawData.length < pageSize) hasMore.current = false;
|
|
92
107
|
setData((prev) => {
|
|
93
108
|
if (isPageMode) return rawData;
|
|
94
|
-
|
|
109
|
+
const indexStart = (localPage - 1) * pageSize;
|
|
110
|
+
const newData = [...prev];
|
|
111
|
+
for (let i = 0; i < rawData.length; i++) {
|
|
112
|
+
newData[indexStart + i] = rawData[i];
|
|
113
|
+
}
|
|
114
|
+
return newData;
|
|
95
115
|
});
|
|
96
116
|
if (isPageMode) {
|
|
97
|
-
cache.current[
|
|
117
|
+
cache.current[localPage] = rawData;
|
|
98
118
|
Object.keys(cache.current).forEach((val) => {
|
|
99
|
-
if (Math.abs(
|
|
119
|
+
if (Math.abs(localPage - +val) > 1) {
|
|
100
120
|
delete cache.current[+val];
|
|
101
121
|
}
|
|
102
122
|
});
|
|
103
123
|
}
|
|
104
124
|
}
|
|
105
125
|
useEffect(() => {
|
|
106
|
-
if (!
|
|
126
|
+
if (!hasNext) return;
|
|
107
127
|
if (pagination?.type !== "infinite") return;
|
|
108
128
|
const el = scrollRef.current;
|
|
109
129
|
if (!el) return;
|
|
@@ -113,7 +133,7 @@ function useResource(config) {
|
|
|
113
133
|
setPage((prev) => prev + 1);
|
|
114
134
|
})();
|
|
115
135
|
}
|
|
116
|
-
}, [scrollTop, pagination?.type, loading]);
|
|
136
|
+
}, [scrollTop, pagination?.type, loading, hasNext]);
|
|
117
137
|
useEffect(() => {
|
|
118
138
|
orchestrator();
|
|
119
139
|
}, [page, pageSize, source, pagination?.type]);
|
|
@@ -136,39 +156,59 @@ function useResource(config) {
|
|
|
136
156
|
let offsetY = 0;
|
|
137
157
|
let totalHeight = 0;
|
|
138
158
|
if (shouldVirtualize) {
|
|
139
|
-
const
|
|
159
|
+
const total2 = data.length;
|
|
140
160
|
const rawStart = Math.floor(scrollTop / itemHeight);
|
|
141
161
|
const startIndex = Math.max(0, rawStart - 2);
|
|
142
162
|
const visibleCount = Math.ceil(containerHeight / itemHeight);
|
|
143
|
-
const endIndex = Math.min(startIndex + visibleCount + 4,
|
|
163
|
+
const endIndex = Math.min(startIndex + visibleCount + 4, total2);
|
|
144
164
|
finalData = data.slice(startIndex, endIndex);
|
|
145
165
|
offsetY = itemHeight * startIndex;
|
|
146
|
-
totalHeight =
|
|
166
|
+
totalHeight = total2 * itemHeight;
|
|
147
167
|
}
|
|
148
|
-
return { data: finalData, loading, error, page, setPage, setScrollTop, offsetY, totalHeight, totalItems: data.length, scrollRef };
|
|
168
|
+
return { data: finalData, loading, error, page, setPage, setScrollTop, offsetY, totalHeight, totalItems: data.length, scrollRef, hasNext };
|
|
149
169
|
}
|
|
150
170
|
|
|
151
171
|
// src/components/DataTable.tsx
|
|
152
|
-
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
153
172
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
154
173
|
function DataTable(props) {
|
|
155
|
-
const {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
174
|
+
const {
|
|
175
|
+
data,
|
|
176
|
+
loading,
|
|
177
|
+
error,
|
|
178
|
+
page,
|
|
179
|
+
setPage,
|
|
180
|
+
setScrollTop,
|
|
181
|
+
type,
|
|
182
|
+
virtualization,
|
|
183
|
+
hasNext
|
|
184
|
+
} = props;
|
|
185
|
+
const offsetY = props.offsetY ?? 0;
|
|
186
|
+
const totalHeight = props.totalHeight ?? 0;
|
|
187
|
+
const itemHeight = 50;
|
|
188
|
+
const colCount = data[0] ? Object.keys(data[0]).length : 1;
|
|
160
189
|
if (loading) return /* @__PURE__ */ jsx("div", { children: "Loading..." });
|
|
161
190
|
if (error) return /* @__PURE__ */ jsx("div", { children: error.message });
|
|
162
|
-
if ((props.totalItems ?? data.length) === 0)
|
|
191
|
+
if ((props.totalItems ?? data.length) === 0)
|
|
192
|
+
return /* @__PURE__ */ jsx("p", { children: "No Data to create Table" });
|
|
163
193
|
const content = /* @__PURE__ */ jsxs("table", { children: [
|
|
164
194
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: Object.keys(data[0]).map((val) => /* @__PURE__ */ jsx("th", { children: val }, val)) }) }),
|
|
165
|
-
/* @__PURE__ */
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
195
|
+
/* @__PURE__ */ jsxs("tbody", { children: [
|
|
196
|
+
virtualization && /* @__PURE__ */ jsx("tr", { style: { height: offsetY }, children: /* @__PURE__ */ jsx("td", { colSpan: colCount }) }),
|
|
197
|
+
data.map((val, index) => /* @__PURE__ */ jsx("tr", { children: Object.keys(val).map((key) => {
|
|
198
|
+
const value = val[key];
|
|
199
|
+
return /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("div", { className: "cell", children: value != null ? value.toString() : "-" }) }, key);
|
|
200
|
+
}) }, index)),
|
|
201
|
+
virtualization && /* @__PURE__ */ jsx(
|
|
202
|
+
"tr",
|
|
203
|
+
{
|
|
204
|
+
style: {
|
|
205
|
+
height: totalHeight - offsetY - data.length * itemHeight
|
|
206
|
+
},
|
|
207
|
+
children: /* @__PURE__ */ jsx("td", { colSpan: colCount })
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
] })
|
|
169
211
|
] });
|
|
170
|
-
const offsetY = props.offsetY ?? 0;
|
|
171
|
-
const totalHeight = props.totalHeight ?? 0;
|
|
172
212
|
const finalTable = virtualization ? /* @__PURE__ */ jsx(
|
|
173
213
|
"div",
|
|
174
214
|
{
|
|
@@ -177,29 +217,33 @@ function DataTable(props) {
|
|
|
177
217
|
onScroll: (e) => {
|
|
178
218
|
setScrollTop(e.currentTarget.scrollTop);
|
|
179
219
|
},
|
|
180
|
-
children:
|
|
181
|
-
"div",
|
|
182
|
-
{
|
|
183
|
-
style: {
|
|
184
|
-
transform: `translateY(${offsetY}px)`,
|
|
185
|
-
position: "absolute",
|
|
186
|
-
top: 0,
|
|
187
|
-
left: 0,
|
|
188
|
-
right: 0
|
|
189
|
-
},
|
|
190
|
-
children: content
|
|
191
|
-
}
|
|
192
|
-
) })
|
|
220
|
+
children: content
|
|
193
221
|
}
|
|
194
222
|
) : content;
|
|
195
223
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
196
224
|
type === "page" && /* @__PURE__ */ jsxs("div", { children: [
|
|
197
225
|
/* @__PURE__ */ jsx("button", { onClick: () => setPage((prev) => Math.max(prev - 1, 1)), children: "prev" }),
|
|
198
226
|
/* @__PURE__ */ jsx("span", { children: page }),
|
|
199
|
-
/* @__PURE__ */ jsx(
|
|
227
|
+
/* @__PURE__ */ jsx(
|
|
228
|
+
"button",
|
|
229
|
+
{
|
|
230
|
+
onClick: () => setPage((prev) => {
|
|
231
|
+
if (hasNext) return prev + 1;
|
|
232
|
+
return prev;
|
|
233
|
+
}),
|
|
234
|
+
children: "next"
|
|
235
|
+
}
|
|
236
|
+
)
|
|
200
237
|
] }),
|
|
201
238
|
finalTable,
|
|
202
|
-
type === "loadmore" && /* @__PURE__ */ jsx(
|
|
239
|
+
type === "loadmore" && /* @__PURE__ */ jsx(
|
|
240
|
+
"button",
|
|
241
|
+
{
|
|
242
|
+
disabled: !hasNext,
|
|
243
|
+
onClick: () => setPage((prev) => prev + 1),
|
|
244
|
+
children: "load more"
|
|
245
|
+
}
|
|
246
|
+
)
|
|
203
247
|
] });
|
|
204
248
|
}
|
|
205
249
|
export {
|