@nexgrid/react 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,944 @@
1
+ "use client";
2
+ "use strict";
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 __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ DEFAULT_LOCALE: () => import_core4.DEFAULT_LOCALE,
35
+ DEFAULT_PAGE_SIZE: () => import_core4.DEFAULT_PAGE_SIZE,
36
+ NexGrid: () => NexGrid,
37
+ PAGE_SIZES: () => import_core4.PAGE_SIZES,
38
+ buildODataUrl: () => import_core4.buildODataUrl,
39
+ buildQueryUrl: () => import_core4.buildQueryUrl,
40
+ defaultQuery: () => import_core4.defaultQuery,
41
+ fromODataResponse: () => import_core4.fromODataResponse,
42
+ isPageSize: () => import_core4.isPageSize,
43
+ parseQuery: () => import_core4.parseQuery,
44
+ primarySort: () => import_core4.primarySort,
45
+ queryClientData: () => import_core4.queryClientData,
46
+ resolveLocale: () => import_core4.resolveLocale,
47
+ serializeQuery: () => import_core4.serializeQuery,
48
+ toODataParams: () => import_core4.toODataParams,
49
+ totalPagesFor: () => import_core4.totalPagesFor,
50
+ useClientNexGrid: () => useClientNexGrid,
51
+ withFilter: () => import_core4.withFilter,
52
+ withPage: () => import_core4.withPage,
53
+ withPageSize: () => import_core4.withPageSize,
54
+ withSearch: () => import_core4.withSearch,
55
+ withSort: () => import_core4.withSort,
56
+ withToggledSort: () => import_core4.withToggledSort
57
+ });
58
+ module.exports = __toCommonJS(index_exports);
59
+
60
+ // src/nex-grid.tsx
61
+ var React4 = __toESM(require("react"), 1);
62
+ var import_core2 = require("@nexgrid/core");
63
+
64
+ // src/icons.tsx
65
+ var import_jsx_runtime = require("react/jsx-runtime");
66
+ function Icon({
67
+ className,
68
+ size,
69
+ children
70
+ }) {
71
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
72
+ "svg",
73
+ {
74
+ xmlns: "http://www.w3.org/2000/svg",
75
+ viewBox: "0 0 24 24",
76
+ fill: "none",
77
+ stroke: "currentColor",
78
+ strokeWidth: 2,
79
+ strokeLinecap: "round",
80
+ strokeLinejoin: "round",
81
+ "aria-hidden": "true",
82
+ focusable: "false",
83
+ className,
84
+ width: size,
85
+ height: size,
86
+ children
87
+ }
88
+ );
89
+ }
90
+ function SearchIcon(props) {
91
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { ...props, children: [
92
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
93
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21 21-4.3-4.3" })
94
+ ] });
95
+ }
96
+ function XIcon(props) {
97
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { ...props, children: [
98
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 6 6 18" }),
99
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m6 6 12 12" })
100
+ ] });
101
+ }
102
+ function SlidersIcon(props) {
103
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { ...props, children: [
104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "21", x2: "14", y1: "4", y2: "4" }),
105
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "10", x2: "3", y1: "4", y2: "4" }),
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "21", x2: "12", y1: "12", y2: "12" }),
107
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "8", x2: "3", y1: "12", y2: "12" }),
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "21", x2: "16", y1: "20", y2: "20" }),
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", x2: "3", y1: "20", y2: "20" }),
110
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "14", x2: "14", y1: "2", y2: "6" }),
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "8", x2: "8", y1: "10", y2: "14" }),
112
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "16", x2: "16", y1: "18", y2: "22" })
113
+ ] });
114
+ }
115
+ function FilterIcon(props) {
116
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: "22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3" }) });
117
+ }
118
+ function DownloadIcon(props) {
119
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { ...props, children: [
120
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
121
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "7 10 12 15 17 10" }),
122
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", x2: "12", y1: "15", y2: "3" })
123
+ ] });
124
+ }
125
+ function FileSpreadsheetIcon(props) {
126
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { ...props, children: [
127
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 13h2" }),
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 13h2" }),
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 17h2" }),
132
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 17h2" })
133
+ ] });
134
+ }
135
+ function FileTextIcon(props) {
136
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { ...props, children: [
137
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
139
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 9H8" }),
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M16 13H8" }),
141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M16 17H8" })
142
+ ] });
143
+ }
144
+ function ChevronLeftIcon(props) {
145
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m15 18-6-6 6-6" }) });
146
+ }
147
+ function ChevronRightIcon(props) {
148
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m9 18 6-6-6-6" }) });
149
+ }
150
+ function ArrowUpIcon(props) {
151
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { ...props, children: [
152
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m5 12 7-7 7 7" }),
153
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 19V5" })
154
+ ] });
155
+ }
156
+ function ArrowDownIcon(props) {
157
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { ...props, children: [
158
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 5v14" }),
159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m19 12-7 7-7-7" })
160
+ ] });
161
+ }
162
+ function ArrowUpDownIcon(props) {
163
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Icon, { ...props, children: [
164
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21 16-4 4-4-4" }),
165
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M17 20V4" }),
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m3 8 4-4 4 4" }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7 4v16" })
168
+ ] });
169
+ }
170
+ function CheckIcon(props) {
171
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 6 9 17l-5-5" }) });
172
+ }
173
+
174
+ // src/render.tsx
175
+ var React = __toESM(require("react"), 1);
176
+ var import_core = require("@nexgrid/core");
177
+ var import_jsx_runtime2 = require("react/jsx-runtime");
178
+ var DEFAULT_MIN_WIDTH = 120;
179
+ function renderColumnHeader(col) {
180
+ const header = col.header;
181
+ if (typeof header === "function") return header({});
182
+ if (typeof header === "string") return header;
183
+ return (0, import_core.getColumnId)(col);
184
+ }
185
+ function renderCellContent(col, row, labels) {
186
+ const cell = col.cell;
187
+ if (typeof cell === "function") {
188
+ return cell({ row: { original: row }, getValue: () => (0, import_core.getCellValue)(col, row) });
189
+ }
190
+ return (0, import_core.getCellText)((0, import_core.getCellValue)(col, row), labels);
191
+ }
192
+ function headerCellStyle(col) {
193
+ const meta = col.meta;
194
+ const style = meta?.width === void 0 ? { minWidth: `${meta?.minWidth ?? DEFAULT_MIN_WIDTH}px` } : { width: `${meta.width}px` };
195
+ if (meta?.align !== void 0) style.textAlign = meta.align;
196
+ return style;
197
+ }
198
+ function bodyCellStyle(col) {
199
+ const align = col.meta?.align;
200
+ return align === void 0 ? void 0 : { textAlign: align };
201
+ }
202
+ function headerInnerClass(col) {
203
+ const align = col.meta?.align;
204
+ if (align === "center") return "nxg-th-inner nxg-th-inner--center";
205
+ if (align === "right") return "nxg-th-inner nxg-th-inner--right";
206
+ return "nxg-th-inner";
207
+ }
208
+ function renderTemplate(template, values) {
209
+ const parts = [];
210
+ const pattern = /\{(\w+)\}/g;
211
+ let cursor = 0;
212
+ for (let match = pattern.exec(template); match !== null; match = pattern.exec(template)) {
213
+ const key = match[1];
214
+ const replacement = key === void 0 ? void 0 : values[key];
215
+ if (replacement === void 0) continue;
216
+ if (match.index > cursor) parts.push(template.slice(cursor, match.index));
217
+ parts.push(replacement);
218
+ cursor = match.index + match[0].length;
219
+ }
220
+ if (cursor < template.length) parts.push(template.slice(cursor));
221
+ return parts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(React.Fragment, { children: part }, index));
222
+ }
223
+
224
+ // src/use-debounced-search.ts
225
+ var React2 = __toESM(require("react"), 1);
226
+ var SEARCH_DEBOUNCE_MS = 350;
227
+ function useDebouncedSearch(value, commit, delayMs = SEARCH_DEBOUNCE_MS) {
228
+ const [text, setText] = React2.useState(value);
229
+ const commitRef = React2.useRef(commit);
230
+ React2.useEffect(() => {
231
+ commitRef.current = commit;
232
+ });
233
+ const lastExternal = React2.useRef(value);
234
+ React2.useEffect(() => {
235
+ if (lastExternal.current === value) return;
236
+ lastExternal.current = value;
237
+ setText(value);
238
+ }, [value]);
239
+ React2.useEffect(() => {
240
+ if (text === value) return;
241
+ const timer = setTimeout(() => commitRef.current(text), delayMs);
242
+ return () => clearTimeout(timer);
243
+ }, [text, value, delayMs]);
244
+ return [text, setText];
245
+ }
246
+
247
+ // src/use-dropdown.ts
248
+ var React3 = __toESM(require("react"), 1);
249
+ function useDropdown() {
250
+ const [isOpen, setIsOpen] = React3.useState(false);
251
+ const containerRef = React3.useRef(null);
252
+ const triggerRef = React3.useRef(null);
253
+ React3.useEffect(() => {
254
+ if (!isOpen) return;
255
+ const onPointerDown = (event) => {
256
+ const container = containerRef.current;
257
+ const target = event.target;
258
+ if (container && target instanceof Node && container.contains(target)) return;
259
+ setIsOpen(false);
260
+ };
261
+ const onKeyDown = (event) => {
262
+ if (event.key !== "Escape") return;
263
+ setIsOpen(false);
264
+ triggerRef.current?.focus();
265
+ };
266
+ document.addEventListener("pointerdown", onPointerDown, true);
267
+ document.addEventListener("keydown", onKeyDown);
268
+ return () => {
269
+ document.removeEventListener("pointerdown", onPointerDown, true);
270
+ document.removeEventListener("keydown", onKeyDown);
271
+ };
272
+ }, [isOpen]);
273
+ const toggle = React3.useCallback(() => setIsOpen((open) => !open), []);
274
+ const close = React3.useCallback(() => setIsOpen(false), []);
275
+ return { isOpen, toggle, close, containerRef, triggerRef };
276
+ }
277
+
278
+ // src/nex-grid.tsx
279
+ var import_jsx_runtime3 = require("react/jsx-runtime");
280
+ function defaultRowId(row) {
281
+ const record = row;
282
+ const id = record === null || record === void 0 ? void 0 : record["id"];
283
+ return String(id ?? row);
284
+ }
285
+ var DENSITY_LABEL_KEY = {
286
+ compact: "densityCompact",
287
+ default: "densityDefault",
288
+ comfortable: "densityComfortable"
289
+ };
290
+ function NexGrid({
291
+ columns,
292
+ data,
293
+ total,
294
+ query,
295
+ onQueryChange,
296
+ caption,
297
+ density: initialDensity = "default",
298
+ isLoading = false,
299
+ error = false,
300
+ onRetry,
301
+ enableSelection = false,
302
+ onSelectionChange,
303
+ enableSearch = true,
304
+ searchPlaceholder,
305
+ toolbarActions,
306
+ onRowClick,
307
+ getRowId = defaultRowId,
308
+ className,
309
+ showSerialNumber = true,
310
+ enableExport = true,
311
+ exportFileName,
312
+ onExportAll,
313
+ fetchEndpoint,
314
+ badgeRules,
315
+ locale: localeOverrides,
316
+ onNotify,
317
+ theme = "light"
318
+ }) {
319
+ const locale = (0, import_core2.resolveLocale)(localeOverrides);
320
+ const boolLabels = { yes: locale.booleanYes, no: locale.booleanNo };
321
+ const [density, setDensity] = React4.useState(initialDensity);
322
+ const [hiddenCols, setHiddenCols] = React4.useState(
323
+ () => (0, import_core2.initialHiddenColumns)(columns)
324
+ );
325
+ const [selectedIds, setSelectedIds] = React4.useState(
326
+ () => /* @__PURE__ */ new Set()
327
+ );
328
+ const [isExporting, setIsExporting] = React4.useState(false);
329
+ const columnsMenu = useDropdown();
330
+ const densityMenu = useDropdown();
331
+ const exportMenu = useDropdown();
332
+ const instanceId = React4.useId();
333
+ const columnsButtonId = `${instanceId}-columns`;
334
+ const densityButtonId = `${instanceId}-density`;
335
+ const exportButtonId = `${instanceId}-export`;
336
+ const jumpInputId = `${instanceId}-jump`;
337
+ const notify = (type, message) => {
338
+ onNotify?.({ type, message });
339
+ };
340
+ const currentPage = Math.max(1, query.page);
341
+ const pageSize = query.pageSize;
342
+ const totalPages = (0, import_core2.totalPagesFor)(total, pageSize);
343
+ const range = (0, import_core2.getRecordRange)(currentPage, pageSize, total);
344
+ const sort = (0, import_core2.primarySort)(query);
345
+ const visible = React4.useMemo(
346
+ () => (0, import_core2.visibleColumns)(columns, hiddenCols),
347
+ [columns, hiddenCols]
348
+ );
349
+ const hideable = React4.useMemo(() => columns.filter(import_core2.isHideable), [columns]);
350
+ const pageItems = React4.useMemo(
351
+ () => (0, import_core2.getPageNumbers)(currentPage, totalPages),
352
+ [currentPage, totalPages]
353
+ );
354
+ const pageRowIds = React4.useMemo(() => data.map((row) => getRowId(row)), [data, getRowId]);
355
+ const columnCount = visible.length + (showSerialNumber ? 1 : 0) + (enableSelection ? 1 : 0);
356
+ const [searchText, setSearchText] = useDebouncedSearch(query.q ?? "", (text) => {
357
+ onQueryChange((0, import_core2.withSearch)(query, text));
358
+ });
359
+ const [jumpText, setJumpText] = React4.useState(() => String(currentPage));
360
+ React4.useEffect(() => setJumpText(String(currentPage)), [currentPage]);
361
+ const submitJump = (event) => {
362
+ event?.preventDefault();
363
+ const parsed = Number.parseInt(jumpText, 10);
364
+ if (Number.isFinite(parsed) && parsed >= 1 && parsed <= totalPages) {
365
+ setJumpText(String(parsed));
366
+ if (parsed !== currentPage) onQueryChange((0, import_core2.withPage)(query, parsed, totalPages));
367
+ return;
368
+ }
369
+ setJumpText(String(currentPage));
370
+ };
371
+ const toggleSort = (columnId) => {
372
+ onQueryChange((0, import_core2.withToggledSort)(query, columnId));
373
+ };
374
+ const selectedOnPage = pageRowIds.filter((id) => selectedIds.has(id)).length;
375
+ const allPageSelected = pageRowIds.length > 0 && selectedOnPage === pageRowIds.length;
376
+ const somePageSelected = selectedOnPage > 0 && !allPageSelected;
377
+ const commitSelection = (next) => {
378
+ setSelectedIds(next);
379
+ onSelectionChange?.(Array.from(next), false);
380
+ };
381
+ const toggleSelectAll = () => {
382
+ const next = new Set(selectedIds);
383
+ for (const id of pageRowIds) {
384
+ if (allPageSelected) next.delete(id);
385
+ else next.add(id);
386
+ }
387
+ commitSelection(next);
388
+ };
389
+ const toggleSelectRow = (id) => {
390
+ const next = new Set(selectedIds);
391
+ if (next.has(id)) next.delete(id);
392
+ else next.add(id);
393
+ commitSelection(next);
394
+ };
395
+ const toggleColumn = (columnId) => {
396
+ setHiddenCols((prev) => ({ ...prev, [columnId]: prev[columnId] !== true }));
397
+ };
398
+ const collectExportRows = async () => {
399
+ if (data.length >= total || !fetchEndpoint) return data;
400
+ notify("info", (0, import_core2.formatMessage)(locale.exportFetchingAll, { total: total.toLocaleString() }));
401
+ try {
402
+ const result = await (0, import_core2.fetchAllPages)(async (page, size) => {
403
+ const url = (0, import_core2.buildQueryUrl)(fetchEndpoint, {
404
+ ...query,
405
+ page,
406
+ pageSize: (0, import_core2.isPageSize)(size) ? size : query.pageSize
407
+ });
408
+ const response = await fetch(url, { cache: "no-store" });
409
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
410
+ return await response.json();
411
+ });
412
+ return result.items;
413
+ } catch {
414
+ notify("error", locale.exportFetchFailed);
415
+ return data;
416
+ }
417
+ };
418
+ const handleExport = async (format) => {
419
+ exportMenu.close();
420
+ if (onExportAll) {
421
+ void onExportAll();
422
+ return;
423
+ }
424
+ setIsExporting(true);
425
+ try {
426
+ const rows = await collectExportRows();
427
+ if (rows.length === 0) {
428
+ notify("error", locale.exportNoData);
429
+ return;
430
+ }
431
+ const exportColumns = (0, import_core2.toExportColumns)(visible, boolLabels);
432
+ const prefix = exportFileName ?? (0, import_core2.filePrefixFromCaption)(caption);
433
+ if (format === "excel") {
434
+ const count = (0, import_core2.downloadExcel)({
435
+ filename: prefix,
436
+ caption,
437
+ rows,
438
+ columns: exportColumns,
439
+ badgeRules,
440
+ serialHeader: locale.serialHeader
441
+ });
442
+ notify(
443
+ "success",
444
+ (0, import_core2.formatMessage)(locale.exportExcelSuccess, { count: count.toLocaleString() })
445
+ );
446
+ } else {
447
+ const count = (0, import_core2.downloadCsv)((0, import_core2.timestampedFilename)(prefix), rows, exportColumns);
448
+ notify(
449
+ "success",
450
+ (0, import_core2.formatMessage)(locale.exportCsvSuccess, { count: count.toLocaleString() })
451
+ );
452
+ }
453
+ } finally {
454
+ setIsExporting(false);
455
+ }
456
+ };
457
+ const rootClassName = [
458
+ "nxg-root",
459
+ theme === "dark" ? "nxg-dark" : theme === "auto" ? "nxg-auto" : void 0,
460
+ className
461
+ ].filter((part) => Boolean(part)).join(" ");
462
+ if (error) {
463
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: rootClassName, "data-density": density, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-state-card", children: [
464
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "nxg-state-text", children: locale.errorText }),
465
+ onRetry ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "nxg-btn", onClick: onRetry, children: locale.retryButton }) : null
466
+ ] }) });
467
+ }
468
+ const rowIsClickable = typeof onRowClick === "function";
469
+ const activateRow = (row) => () => {
470
+ onRowClick?.(row);
471
+ };
472
+ const rowKeyDown = (row) => (event) => {
473
+ if (event.key !== "Enter") return;
474
+ event.preventDefault();
475
+ onRowClick?.(row);
476
+ };
477
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: rootClassName, "data-density": density, children: [
478
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-toolbar", children: [
479
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-toolbar-group", children: [
480
+ enableSearch ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-search", children: [
481
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SearchIcon, { className: "nxg-search-icon" }),
482
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
483
+ "input",
484
+ {
485
+ type: "search",
486
+ className: "nxg-search-input",
487
+ value: searchText,
488
+ onChange: (event) => setSearchText(event.target.value),
489
+ placeholder: searchPlaceholder ?? locale.searchPlaceholder,
490
+ "aria-label": `Search ${caption}`
491
+ }
492
+ ),
493
+ searchText ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
494
+ "button",
495
+ {
496
+ type: "button",
497
+ className: "nxg-search-clear",
498
+ onClick: () => setSearchText(""),
499
+ "aria-label": locale.clearSearch,
500
+ children: [
501
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(XIcon, { className: "nxg-icon" }),
502
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "nxg-sr-only", children: locale.clearSearch })
503
+ ]
504
+ }
505
+ ) : null
506
+ ] }) : null,
507
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-menu-wrap", ref: columnsMenu.containerRef, children: [
508
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
509
+ "button",
510
+ {
511
+ type: "button",
512
+ id: columnsButtonId,
513
+ className: "nxg-btn",
514
+ ref: columnsMenu.triggerRef,
515
+ "aria-haspopup": "menu",
516
+ "aria-expanded": columnsMenu.isOpen,
517
+ onClick: columnsMenu.toggle,
518
+ children: [
519
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SlidersIcon, { className: "nxg-icon" }),
520
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: locale.columnsButton })
521
+ ]
522
+ }
523
+ ),
524
+ columnsMenu.isOpen ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-menu", role: "menu", "aria-labelledby": columnsButtonId, children: [
525
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "nxg-menu-label", children: locale.toggleColumnsLabel }),
526
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "nxg-menu-separator" }),
527
+ hideable.map((col) => {
528
+ const id = (0, import_core2.getColumnId)(col);
529
+ const checked = hiddenCols[id] !== true;
530
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
531
+ "button",
532
+ {
533
+ type: "button",
534
+ className: "nxg-menu-item",
535
+ role: "menuitemcheckbox",
536
+ "aria-checked": checked,
537
+ onClick: () => toggleColumn(id),
538
+ children: [
539
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CheckIcon, { className: "nxg-check" }),
540
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: (0, import_core2.getColumnTitle)(col) || id })
541
+ ]
542
+ },
543
+ id
544
+ );
545
+ })
546
+ ] }) : null
547
+ ] }),
548
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-menu-wrap", ref: densityMenu.containerRef, children: [
549
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
550
+ "button",
551
+ {
552
+ type: "button",
553
+ id: densityButtonId,
554
+ className: "nxg-btn nxg-capitalize",
555
+ ref: densityMenu.triggerRef,
556
+ "aria-haspopup": "menu",
557
+ "aria-expanded": densityMenu.isOpen,
558
+ onClick: densityMenu.toggle,
559
+ children: [
560
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FilterIcon, { className: "nxg-icon" }),
561
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: (0, import_core2.formatMessage)(locale.densityButton, { density }) })
562
+ ]
563
+ }
564
+ ),
565
+ densityMenu.isOpen ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "nxg-menu", role: "menu", "aria-labelledby": densityButtonId, children: import_core2.DENSITIES.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
566
+ "button",
567
+ {
568
+ type: "button",
569
+ className: "nxg-menu-item",
570
+ role: "menuitemcheckbox",
571
+ "aria-checked": density === option,
572
+ onClick: () => {
573
+ setDensity(option);
574
+ densityMenu.close();
575
+ },
576
+ children: [
577
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CheckIcon, { className: "nxg-check" }),
578
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: locale[DENSITY_LABEL_KEY[option]] })
579
+ ]
580
+ },
581
+ option
582
+ )) }) : null
583
+ ] })
584
+ ] }),
585
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-toolbar-group nxg-toolbar-group--end", children: [
586
+ enableExport ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-menu-wrap", ref: exportMenu.containerRef, children: [
587
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
588
+ "button",
589
+ {
590
+ type: "button",
591
+ id: exportButtonId,
592
+ className: "nxg-btn nxg-btn--export",
593
+ ref: exportMenu.triggerRef,
594
+ disabled: isExporting,
595
+ "aria-haspopup": "menu",
596
+ "aria-expanded": exportMenu.isOpen,
597
+ onClick: exportMenu.toggle,
598
+ children: [
599
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DownloadIcon, { className: "nxg-icon" }),
600
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: isExporting ? locale.exportingButton : locale.exportButton })
601
+ ]
602
+ }
603
+ ),
604
+ exportMenu.isOpen ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
605
+ "div",
606
+ {
607
+ className: "nxg-menu nxg-menu--end",
608
+ role: "menu",
609
+ "aria-labelledby": exportButtonId,
610
+ children: [
611
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
612
+ "button",
613
+ {
614
+ type: "button",
615
+ className: "nxg-menu-item",
616
+ role: "menuitem",
617
+ onClick: () => void handleExport("excel"),
618
+ children: [
619
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FileSpreadsheetIcon, { className: "nxg-icon--excel" }),
620
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-menu-item-title", children: [
621
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: locale.exportExcelTitle }),
622
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("small", { children: locale.exportExcelSubtitle })
623
+ ] })
624
+ ]
625
+ }
626
+ ),
627
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
628
+ "button",
629
+ {
630
+ type: "button",
631
+ className: "nxg-menu-item",
632
+ role: "menuitem",
633
+ onClick: () => void handleExport("csv"),
634
+ children: [
635
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FileTextIcon, { className: "nxg-icon--csv" }),
636
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-menu-item-title", children: [
637
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: locale.exportCsvTitle }),
638
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("small", { children: locale.exportCsvSubtitle })
639
+ ] })
640
+ ]
641
+ }
642
+ )
643
+ ]
644
+ }
645
+ ) : null
646
+ ] }) : null,
647
+ toolbarActions
648
+ ] })
649
+ ] }),
650
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "nxg-table-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("table", { className: "nxg-table", "aria-label": caption, children: [
651
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
652
+ showSerialNumber ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { className: "nxg-th nxg-th--serial", scope: "col", children: locale.serialHeader }) : null,
653
+ enableSelection ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { className: "nxg-th nxg-th--select", scope: "col", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
654
+ "input",
655
+ {
656
+ type: "checkbox",
657
+ className: "nxg-checkbox",
658
+ checked: allPageSelected,
659
+ ref: (el) => {
660
+ if (el) el.indeterminate = somePageSelected;
661
+ },
662
+ onChange: toggleSelectAll,
663
+ "aria-label": locale.selectAllLabel
664
+ }
665
+ ) }) : null,
666
+ visible.map((col, index) => {
667
+ const id = (0, import_core2.getColumnId)(col);
668
+ const sortable = (0, import_core2.isSortable)(col);
669
+ const sorted = sortable && id !== "" && sort?.field === id;
670
+ const title = (0, import_core2.getColumnTitle)(col) || id;
671
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
672
+ "th",
673
+ {
674
+ scope: "col",
675
+ className: sortable ? "nxg-th nxg-th--sortable" : "nxg-th",
676
+ style: headerCellStyle(col),
677
+ "aria-sort": sorted ? sort?.dir === "asc" ? "ascending" : "descending" : sortable ? "none" : void 0,
678
+ "aria-label": title || void 0,
679
+ tabIndex: sortable ? 0 : void 0,
680
+ onClick: sortable ? () => toggleSort(id) : void 0,
681
+ onKeyDown: sortable ? (event) => {
682
+ if (event.key !== "Enter" && event.key !== " ") return;
683
+ event.preventDefault();
684
+ toggleSort(id);
685
+ } : void 0,
686
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: headerInnerClass(col), children: [
687
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: renderColumnHeader(col) }),
688
+ sortable ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: sorted ? sort?.dir === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ArrowUpIcon, { className: "nxg-sort-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ArrowDownIcon, { className: "nxg-sort-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ArrowUpDownIcon, { className: "nxg-sort-icon nxg-sort-icon--idle" }) }) : null
689
+ ] })
690
+ },
691
+ id || `col-${index}`
692
+ );
693
+ })
694
+ ] }) }),
695
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tbody", { children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("td", { className: "nxg-state", colSpan: Math.max(1, columnCount), children: [
696
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "nxg-spinner", "aria-hidden": "true" }),
697
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "aria-live": "polite", children: locale.loadingText })
698
+ ] }) }) : data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { className: "nxg-state", colSpan: Math.max(1, columnCount), children: locale.emptyText }) }) : data.map((row, index) => {
699
+ const id = pageRowIds[index] ?? String(index);
700
+ const isSelected = selectedIds.has(id);
701
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
702
+ "tr",
703
+ {
704
+ className: [
705
+ "nxg-row",
706
+ isSelected ? "nxg-row--selected" : void 0,
707
+ rowIsClickable ? "nxg-row--clickable" : void 0
708
+ ].filter(Boolean).join(" "),
709
+ onClick: rowIsClickable ? activateRow(row) : void 0,
710
+ onKeyDown: rowIsClickable ? rowKeyDown(row) : void 0,
711
+ tabIndex: rowIsClickable ? 0 : void 0,
712
+ children: [
713
+ showSerialNumber ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { className: "nxg-td nxg-td--serial", children: (0, import_core2.serialNumber)(currentPage, pageSize, index) }) : null,
714
+ enableSelection ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
715
+ "td",
716
+ {
717
+ className: "nxg-td nxg-td--select",
718
+ onClick: (event) => event.stopPropagation(),
719
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
720
+ "input",
721
+ {
722
+ type: "checkbox",
723
+ className: "nxg-checkbox",
724
+ checked: isSelected,
725
+ onChange: () => toggleSelectRow(id),
726
+ onClick: (event) => event.stopPropagation(),
727
+ "aria-label": (0, import_core2.formatMessage)(locale.selectRowLabel, { id })
728
+ }
729
+ )
730
+ }
731
+ ) : null,
732
+ visible.map((col, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
733
+ "td",
734
+ {
735
+ className: "nxg-td",
736
+ style: bodyCellStyle(col),
737
+ children: renderCellContent(col, row, boolLabels)
738
+ },
739
+ (0, import_core2.getColumnId)(col) || `col-${colIndex}`
740
+ ))
741
+ ]
742
+ },
743
+ id || index
744
+ );
745
+ }) })
746
+ ] }) }),
747
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "nxg-cards", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "nxg-card", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-state", children: [
748
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "nxg-spinner", "aria-hidden": "true" }),
749
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "aria-live": "polite", children: locale.loadingText })
750
+ ] }) }) : data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "nxg-card", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "nxg-state", children: locale.emptyText }) }) : data.map((row, index) => {
751
+ const id = pageRowIds[index] ?? String(index);
752
+ const isSelected = selectedIds.has(id);
753
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
754
+ "div",
755
+ {
756
+ className: [
757
+ "nxg-card",
758
+ isSelected ? "nxg-card--selected" : void 0,
759
+ rowIsClickable ? "nxg-card--clickable" : void 0
760
+ ].filter(Boolean).join(" "),
761
+ onClick: rowIsClickable ? activateRow(row) : void 0,
762
+ onKeyDown: rowIsClickable ? rowKeyDown(row) : void 0,
763
+ tabIndex: rowIsClickable ? 0 : void 0,
764
+ children: [
765
+ showSerialNumber || enableSelection ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-card-head", children: [
766
+ showSerialNumber ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "nxg-card-serial", children: [
767
+ "#",
768
+ (0, import_core2.serialNumber)(currentPage, pageSize, index)
769
+ ] }) : null,
770
+ enableSelection ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
771
+ "span",
772
+ {
773
+ className: "nxg-card-select",
774
+ onClick: (event) => event.stopPropagation(),
775
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
776
+ "input",
777
+ {
778
+ type: "checkbox",
779
+ className: "nxg-checkbox",
780
+ checked: isSelected,
781
+ onChange: () => toggleSelectRow(id),
782
+ onClick: (event) => event.stopPropagation(),
783
+ "aria-label": (0, import_core2.formatMessage)(locale.selectRowLabel, { id })
784
+ }
785
+ )
786
+ }
787
+ ) : null
788
+ ] }) : null,
789
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dl", { className: "nxg-card-rows", children: visible.map((col, colIndex) => {
790
+ const colId = (0, import_core2.getColumnId)(col);
791
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-card-row", children: [
792
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dt", { children: (0, import_core2.getColumnTitle)(col) || colId }),
793
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dd", { children: renderCellContent(col, row, boolLabels) })
794
+ ] }, colId || `col-${colIndex}`);
795
+ }) })
796
+ ]
797
+ },
798
+ id || index
799
+ );
800
+ }) }),
801
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-footer", children: [
802
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-range", children: [
803
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: renderTemplate(locale.showingRange, {
804
+ start: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: range.start }),
805
+ end: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: range.end }),
806
+ total: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { className: "nxg-range-total", children: total.toLocaleString() })
807
+ }) }),
808
+ selectedIds.size > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "nxg-selected-badge", children: (0, import_core2.formatMessage)(locale.selectedBadge, { count: selectedIds.size }) }) : null
809
+ ] }),
810
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-pagination", children: [
811
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-rows-per-page", children: [
812
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: locale.rowsPerPage }),
813
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
814
+ "select",
815
+ {
816
+ className: "nxg-rows-select",
817
+ value: String(pageSize),
818
+ onChange: (event) => {
819
+ onQueryChange((0, import_core2.withPageSize)(query, Number.parseInt(event.target.value, 10)));
820
+ },
821
+ "aria-label": locale.rowsPerPage,
822
+ children: import_core2.PAGE_SIZES.map((size) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: size, children: size }, size))
823
+ }
824
+ )
825
+ ] }),
826
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "nxg-pager", children: [
827
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
828
+ "button",
829
+ {
830
+ type: "button",
831
+ className: "nxg-page-nav",
832
+ disabled: currentPage <= 1,
833
+ onClick: () => onQueryChange((0, import_core2.withPage)(query, currentPage - 1, totalPages)),
834
+ "aria-label": locale.previousPage,
835
+ children: [
836
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChevronLeftIcon, { size: 16 }),
837
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "nxg-sr-only", children: locale.previousPage })
838
+ ]
839
+ }
840
+ ),
841
+ pageItems.map(
842
+ (item, index) => item === "..." ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "nxg-page-ellipsis", children: "\u2026" }, `gap-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
843
+ "button",
844
+ {
845
+ type: "button",
846
+ className: item === currentPage ? "nxg-page-btn nxg-page-btn--current" : "nxg-page-btn",
847
+ onClick: () => onQueryChange((0, import_core2.withPage)(query, item, totalPages)),
848
+ "aria-label": (0, import_core2.formatMessage)(locale.pageLabel, { page: item }),
849
+ "aria-current": item === currentPage ? "page" : void 0,
850
+ children: item
851
+ },
852
+ `page-${item}`
853
+ )
854
+ ),
855
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
856
+ "button",
857
+ {
858
+ type: "button",
859
+ className: "nxg-page-nav",
860
+ disabled: currentPage >= totalPages,
861
+ onClick: () => onQueryChange((0, import_core2.withPage)(query, currentPage + 1, totalPages)),
862
+ "aria-label": locale.nextPage,
863
+ children: [
864
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChevronRightIcon, { size: 16 }),
865
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "nxg-sr-only", children: locale.nextPage })
866
+ ]
867
+ }
868
+ )
869
+ ] }),
870
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { className: "nxg-jump", onSubmit: submitJump, children: [
871
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "nxg-jump-label", htmlFor: jumpInputId, children: locale.goToPage }),
872
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
873
+ "input",
874
+ {
875
+ id: jumpInputId,
876
+ type: "number",
877
+ className: "nxg-jump-input",
878
+ min: 1,
879
+ max: totalPages,
880
+ value: jumpText,
881
+ onChange: (event) => setJumpText(event.target.value),
882
+ onBlur: () => submitJump(),
883
+ "aria-label": locale.goToPageOf
884
+ }
885
+ )
886
+ ] })
887
+ ] })
888
+ ] })
889
+ ] });
890
+ }
891
+
892
+ // src/use-client-nex-grid.ts
893
+ var import_react = require("react");
894
+ var import_core3 = require("@nexgrid/core");
895
+ function useClientNexGrid(allData, options) {
896
+ const [query, setQuery] = (0, import_react.useState)(() => ({
897
+ ...(0, import_core3.defaultQuery)(),
898
+ ...options?.initialQuery
899
+ }));
900
+ const page = (0, import_react.useMemo)(
901
+ () => (0, import_core3.queryClientData)(allData, query, options),
902
+ [allData, query, options]
903
+ );
904
+ return {
905
+ data: page.items,
906
+ total: page.total,
907
+ query,
908
+ onQueryChange: setQuery,
909
+ page: page.page,
910
+ pageSize: page.pageSize,
911
+ totalPages: page.totalPages,
912
+ setQuery
913
+ };
914
+ }
915
+
916
+ // src/index.ts
917
+ var import_core4 = require("@nexgrid/core");
918
+ // Annotate the CommonJS export names for ESM import in node:
919
+ 0 && (module.exports = {
920
+ DEFAULT_LOCALE,
921
+ DEFAULT_PAGE_SIZE,
922
+ NexGrid,
923
+ PAGE_SIZES,
924
+ buildODataUrl,
925
+ buildQueryUrl,
926
+ defaultQuery,
927
+ fromODataResponse,
928
+ isPageSize,
929
+ parseQuery,
930
+ primarySort,
931
+ queryClientData,
932
+ resolveLocale,
933
+ serializeQuery,
934
+ toODataParams,
935
+ totalPagesFor,
936
+ useClientNexGrid,
937
+ withFilter,
938
+ withPage,
939
+ withPageSize,
940
+ withSearch,
941
+ withSort,
942
+ withToggledSort
943
+ });
944
+ //# sourceMappingURL=index.cjs.map