nillud-data-table 1.2.9 → 1.3.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/README.md CHANGED
@@ -161,6 +161,7 @@ const columns = [
161
161
  | [headerFilter](#headerFilter) | - | func | Кастомный фильтр, принимает в себя функуцию, описание далее |
162
162
  | [sortable](#sortable) | - | sortable | Убирает возможность сортировки, по умолчанию true |
163
163
  | [filterable](#filterable) | - | filterable | Убирает возможность фильтрации, по умолчанию true |
164
+ | [selectable](#selectable) | - | selectable | Добавляет возможность отмечать строки таблицы |
164
165
 
165
166
  #### field
166
167
 
@@ -301,6 +302,29 @@ const headerFilterAddress = (headerValue, rowValue) => {
301
302
 
302
303
  Отображение поля фильтрации. По умолчанию **true**
303
304
 
305
+ #### selectable
306
+
307
+ Добавляет возможность отметить строку. По умолчанию **false**
308
+
309
+ Пример вызова:
310
+ ```tsx
311
+ [
312
+ ...,
313
+ {
314
+ field: '',
315
+ title: '',
316
+ selectable: true,
317
+ width: 50
318
+ },
319
+ ...
320
+ ]
321
+ ```
322
+
323
+ Получить отмеченные строки:
324
+ ```tsx
325
+ const selectedData = tableRef.current.getSelectedData()
326
+ ```
327
+
304
328
  ### tableData
305
329
 
306
330
  Обязательный параметр, принимает в себя массив объектов. В простой реализации таблицы в массиве **tableData** объекты должны содержать ключи равные значениям ключа **field** объекта в массиве **columns**
@@ -456,6 +480,7 @@ const tableRef = useRef<DataTableRef>(null);
456
480
  const func = () => {
457
481
  const data = tableRef.current.getData() // Получить текущие данные, после сортировки и фильтрации
458
482
  const currData = tableRef.current.getCurrentData() // Получить данные с текущей таблицы пагинации
483
+ const selectedData = tableRef.current.getSelectedData() // Получить отмеченные строки
459
484
  }
460
485
 
461
486
  ```
package/dist/index.d.ts CHANGED
@@ -15,6 +15,7 @@ type Column = {
15
15
  headerFilter?: (headerValue: string, rowValue: string) => boolean;
16
16
  sortable?: boolean;
17
17
  filterable?: boolean;
18
+ selectable?: boolean;
18
19
  filterPlaceholder?: string;
19
20
  };
20
21
  type TableProps = {
@@ -37,6 +38,7 @@ type TableProps = {
37
38
  type DataTableRef = {
38
39
  getData: () => TableData;
39
40
  getCurrentData: () => TableData;
41
+ getSelectedData: () => TableData;
40
42
  };
41
43
 
42
44
  declare const DataTable: React.ForwardRefExoticComponent<TableProps & React.RefAttributes<DataTableRef>>;
package/dist/index.js CHANGED
@@ -22,8 +22,8 @@ var SortUp = () => {
22
22
  var SortUp_default = SortUp;
23
23
 
24
24
  // components/data-table/Column.tsx
25
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
26
- var Column = ({ column, getSortField, sortBy, getFilters, filters }) => {
25
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
26
+ var Column = ({ column, getSortField, sortBy, getFilters, filters, selectedRows, toggleAllSelection, displayData }) => {
27
27
  var _a;
28
28
  const currentSort = useMemo(() => {
29
29
  return sortBy.col === column.field ? sortBy.type : null;
@@ -35,10 +35,32 @@ var Column = ({ column, getSortField, sortBy, getFilters, filters }) => {
35
35
  const onFilterChange = (e) => {
36
36
  getFilters({ ...filters, [column.field]: e.target.value });
37
37
  };
38
- return /* @__PURE__ */ jsxs("div", { className: "ndt-column", children: [
38
+ const renderSelectable = () => {
39
+ return /* @__PURE__ */ jsx3("div", { className: "ndt-column ndt-checkbox-column", children: /* @__PURE__ */ jsx3(
40
+ "input",
41
+ {
42
+ type: "checkbox",
43
+ checked: selectedRows.size === displayData.length && displayData.length > 0,
44
+ onChange: toggleAllSelection
45
+ }
46
+ ) });
47
+ };
48
+ const renderColumnHead = () => {
49
+ if (column.headerFormatter) {
50
+ return column.headerFormatter(column.title);
51
+ }
52
+ return /* @__PURE__ */ jsx3("span", { children: column.title });
53
+ };
54
+ const renderColumnSort = () => {
55
+ if (typeof column.autoinc === "undefined" && (typeof column.sortable === "undefined" || column.sortable)) {
56
+ return /* @__PURE__ */ jsx3("div", { className: "ndt-sorter", onClick: toggleSort, children: currentSort === "asc" ? /* @__PURE__ */ jsx3(SortDown_default, {}) : currentSort === "desc" ? /* @__PURE__ */ jsx3(SortUp_default, {}) : /* @__PURE__ */ jsx3(SortDown_default, {}) });
57
+ }
58
+ return /* @__PURE__ */ jsx3(Fragment, {});
59
+ };
60
+ return /* @__PURE__ */ jsx3(Fragment, { children: column.selectable ? renderSelectable() : /* @__PURE__ */ jsxs("div", { className: "ndt-column", children: [
39
61
  /* @__PURE__ */ jsxs("div", { className: "ndt-column-head", children: [
40
- column.headerFormatter ? column.headerFormatter(column.title) : /* @__PURE__ */ jsx3("span", { children: column.title }),
41
- typeof column.autoinc === "undefined" && (typeof column.sortable === "undefined" || column.sortable) && /* @__PURE__ */ jsx3("div", { className: "ndt-sorter", onClick: toggleSort, children: currentSort === "asc" ? /* @__PURE__ */ jsx3(SortDown_default, {}) : currentSort === "desc" ? /* @__PURE__ */ jsx3(SortUp_default, {}) : /* @__PURE__ */ jsx3(SortDown_default, {}) })
62
+ renderColumnHead(),
63
+ renderColumnSort()
42
64
  ] }),
43
65
  /* @__PURE__ */ jsx3("div", { className: "ndt-column-footer", children: typeof column.autoinc === "undefined" && (typeof column.filterable === "undefined" || column.filterable) && /* @__PURE__ */ jsx3(
44
66
  "input",
@@ -49,13 +71,13 @@ var Column = ({ column, getSortField, sortBy, getFilters, filters }) => {
49
71
  placeholder: column.filterPlaceholder || ""
50
72
  }
51
73
  ) })
52
- ] });
74
+ ] }) });
53
75
  };
54
76
  var Column_default = Column;
55
77
 
56
78
  // components/data-table/TableHeader.tsx
57
- import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
58
- var Header = ({ columns, getSortField, sortBy, getFilters, filters, widths, headerGroup }) => {
79
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
80
+ var Header = ({ columns, getSortField, sortBy, getFilters, filters, widths, headerGroup, selectedRows, toggleAllSelection, displayData }) => {
59
81
  const renderHeaderGroup = () => headerGroup && /* @__PURE__ */ jsx4("div", { className: "ndt-table-columns", style: { gridTemplateColumns: widths || "auto" }, children: headerGroup.map((col, id) => /* @__PURE__ */ jsx4("div", { className: "ndt-column", style: { gridColumn: `span ${col.cols || 1}` }, children: /* @__PURE__ */ jsx4("div", { className: "ndt-column-head", children: /* @__PURE__ */ jsx4("span", { children: col.title }) }) }, `header-group-${id}`)) });
60
82
  const renderColumns = () => columns && columns.length > 0 ? columns.map((column, id) => /* @__PURE__ */ jsx4(
61
83
  Column_default,
@@ -64,11 +86,14 @@ var Header = ({ columns, getSortField, sortBy, getFilters, filters, widths, head
64
86
  getSortField,
65
87
  sortBy,
66
88
  getFilters,
67
- filters
89
+ filters,
90
+ selectedRows,
91
+ toggleAllSelection,
92
+ displayData
68
93
  },
69
94
  `column-${id}`
70
95
  )) : /* @__PURE__ */ jsx4("div", { className: "ndt-data-error", children: "\u041E\u0448\u0438\u0431\u043A\u0430: columns is undefined" });
71
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
96
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
72
97
  renderHeaderGroup(),
73
98
  /* @__PURE__ */ jsx4("div", { className: "ndt-table-columns", style: { gridTemplateColumns: widths || "auto" }, children: renderColumns() })
74
99
  ] });
@@ -79,17 +104,20 @@ var TableHeader_default = React.memo(Header);
79
104
  import React2 from "react";
80
105
 
81
106
  // components/data-table/Cell.tsx
82
- import { jsx as jsx5 } from "react/jsx-runtime";
107
+ import { Fragment as Fragment3, jsx as jsx5 } from "react/jsx-runtime";
83
108
  var Cell = ({
84
109
  row,
85
110
  column,
86
- rowId,
87
- isTitles
111
+ // rowId,
112
+ displayId,
113
+ isTitles,
114
+ isRowSelected,
115
+ onRowSelect
88
116
  }) => {
89
117
  const rawValue = row[column.field];
90
118
  const stringValue = typeof rawValue !== "undefined" && rawValue !== null ? String(rawValue) : "";
91
- const content = column.formatter ? column.formatter(stringValue, row, column) : typeof column.autoinc !== "undefined" ? /* @__PURE__ */ jsx5("span", { children: rowId + 1 }) : /* @__PURE__ */ jsx5("span", { children: stringValue });
92
- return /* @__PURE__ */ jsx5(
119
+ const content = column.formatter ? column.formatter(stringValue, row, column) : column.autoinc ? /* @__PURE__ */ jsx5("span", { children: displayId + 1 }) : /* @__PURE__ */ jsx5("span", { children: stringValue });
120
+ const renderCell = () => /* @__PURE__ */ jsx5(
93
121
  "div",
94
122
  {
95
123
  className: "ndt-cell",
@@ -97,21 +125,36 @@ var Cell = ({
97
125
  children: content
98
126
  }
99
127
  );
128
+ const renderSelectableCell = () => /* @__PURE__ */ jsx5("div", { className: "ndt-cell ndt-checkbox-cell", children: /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: !!isRowSelected, onChange: onRowSelect }) });
129
+ return /* @__PURE__ */ jsx5(Fragment3, { children: column.selectable ? renderSelectableCell() : renderCell() });
100
130
  };
101
131
  var Cell_default = Cell;
102
132
 
103
133
  // components/data-table/Row.tsx
104
134
  import { jsx as jsx6 } from "react/jsx-runtime";
105
- var Row = ({ rowId, columns, row, widths, isTitles }) => /* @__PURE__ */ jsx6("div", { className: "ndt-table-row", style: { gridTemplateColumns: widths }, children: columns.map((column, id) => /* @__PURE__ */ jsx6(
106
- Cell_default,
107
- {
108
- row,
109
- column,
110
- rowId,
111
- isTitles
112
- },
113
- `cell-${rowId}-${id}`
114
- )) });
135
+ var Row = ({
136
+ rowId,
137
+ displayId,
138
+ columns,
139
+ row,
140
+ widths,
141
+ isTitles,
142
+ isRowSelected,
143
+ onRowSelect
144
+ }) => {
145
+ return /* @__PURE__ */ jsx6("div", { className: "ndt-table-row", style: { gridTemplateColumns: widths }, children: columns.map((column, id) => /* @__PURE__ */ jsx6(
146
+ Cell_default,
147
+ {
148
+ row,
149
+ column,
150
+ displayId,
151
+ isTitles,
152
+ isRowSelected,
153
+ onRowSelect
154
+ },
155
+ `cell-${rowId}-${id}`
156
+ )) });
157
+ };
115
158
  var Row_default = Row;
116
159
 
117
160
  // components/data-table/utils/groupDataBy.ts
@@ -132,55 +175,91 @@ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
132
175
  var TableBody = ({
133
176
  columns,
134
177
  tableData,
178
+ // groupedData,
135
179
  scrollable,
136
180
  scrollHeight,
137
181
  widths,
138
182
  groupBy,
139
183
  collapsedGroups = {},
140
184
  toggleGroup,
141
- isTitles
185
+ isTitles,
186
+ selectedRows,
187
+ toggleRowSelection,
188
+ rowIdMap,
189
+ paginationSize,
190
+ paginationPage
142
191
  }) => {
143
192
  const grouped = groupBy ? groupDataBy(tableData, groupBy) : [];
144
193
  if (!tableData || tableData.length === 0) {
145
194
  return /* @__PURE__ */ jsx7("div", { className: `ndt-table-body${scrollable ? " ndt-table-body-scrollable" : ""}`, style: scrollable ? { height: scrollHeight } : {}, children: /* @__PURE__ */ jsx7("div", { className: "ndt-table-row", style: { height: "100%" }, children: /* @__PURE__ */ jsx7("div", { className: "ndt-row-item", style: { margin: "auto", padding: 20, fontWeight: "bold" }, children: "\u0414\u0430\u043D\u043D\u044B\u0445 \u043D\u0435\u0442" }) }) });
146
195
  }
147
- const renderGroupedRows = () => grouped.map((group, id) => /* @__PURE__ */ jsxs3(React2.Fragment, { children: [
148
- /* @__PURE__ */ jsxs3(
149
- "div",
150
- {
151
- className: "ndt-group-header",
152
- onClick: () => toggleGroup == null ? void 0 : toggleGroup(group.key),
153
- children: [
154
- /* @__PURE__ */ jsx7("span", { style: { marginRight: 8 }, children: collapsedGroups[group.key] ? "\u25B6" : "\u25BC" }),
155
- group.key,
156
- " (",
157
- group.items.length,
158
- ")"
159
- ]
160
- }
161
- ),
162
- !collapsedGroups[group.key] && group.items.map((element, id2) => /* @__PURE__ */ jsx7(
163
- Row_default,
164
- {
165
- rowId: id2,
166
- row: element,
167
- columns,
168
- widths,
169
- isTitles
170
- },
171
- `row-${group.key}-${id2}`
172
- ))
173
- ] }, `row-${group.key}-${id}`));
174
- const renderFlatRows = () => tableData.map((element, id) => /* @__PURE__ */ jsx7(
175
- Row_default,
176
- {
177
- rowId: id,
178
- row: element,
179
- columns,
180
- widths
181
- },
182
- `row-${id}`
183
- ));
196
+ const renderGroupedRows = () => {
197
+ let currentIndex = 0;
198
+ return grouped.map((group) => {
199
+ const groupHeader = /* @__PURE__ */ jsxs3(
200
+ "div",
201
+ {
202
+ className: "ndt-group-header",
203
+ onClick: () => toggleGroup == null ? void 0 : toggleGroup(group.key),
204
+ children: [
205
+ /* @__PURE__ */ jsx7("span", { style: { marginRight: 8 }, children: collapsedGroups[group.key] ? "\u25B6" : "\u25BC" }),
206
+ group.key,
207
+ " (",
208
+ group.items.length,
209
+ ")"
210
+ ]
211
+ },
212
+ `group-header-${group.key}`
213
+ );
214
+ const rows = !collapsedGroups[group.key] ? group.items.map((element) => {
215
+ const globalIndex = rowIdMap.get(element);
216
+ if (globalIndex === void 0) return null;
217
+ const localIndex = currentIndex++;
218
+ const displayIndex = paginationSize === 0 ? localIndex : paginationPage * paginationSize + localIndex;
219
+ return /* @__PURE__ */ jsx7(
220
+ Row_default,
221
+ {
222
+ rowId: globalIndex,
223
+ displayId: displayIndex,
224
+ row: element,
225
+ columns,
226
+ widths,
227
+ isTitles,
228
+ isRowSelected: selectedRows.has(globalIndex),
229
+ onRowSelect: () => toggleRowSelection(globalIndex)
230
+ },
231
+ `row-${group.key}-${globalIndex}`
232
+ );
233
+ }) : null;
234
+ return /* @__PURE__ */ jsxs3(React2.Fragment, { children: [
235
+ groupHeader,
236
+ rows
237
+ ] }, `group-${group.key}`);
238
+ });
239
+ };
240
+ const renderFlatRows = () => {
241
+ let currentIndex = 0;
242
+ return tableData.map((element) => {
243
+ const globalIndex = rowIdMap.get(element);
244
+ if (globalIndex === void 0) return null;
245
+ const localIndex = currentIndex++;
246
+ const displayIndex = paginationSize === 0 ? localIndex : paginationPage * paginationSize + localIndex;
247
+ return /* @__PURE__ */ jsx7(
248
+ Row_default,
249
+ {
250
+ rowId: globalIndex,
251
+ displayId: displayIndex,
252
+ row: element,
253
+ columns,
254
+ widths,
255
+ isTitles,
256
+ isRowSelected: selectedRows.has(globalIndex),
257
+ onRowSelect: () => toggleRowSelection(globalIndex)
258
+ },
259
+ `row-${globalIndex}`
260
+ );
261
+ });
262
+ };
184
263
  return /* @__PURE__ */ jsx7("div", { className: `ndt-table-body${scrollable ? " ndt-table-body-scrollable" : ""}`, style: scrollable ? { height: scrollHeight } : {}, children: groupBy ? renderGroupedRows() : renderFlatRows() });
185
264
  };
186
265
  var TableBody_default = TableBody;
@@ -418,12 +497,31 @@ var DataTable = forwardRef(({
418
497
  groupBy = null,
419
498
  isTitles = false
420
499
  }, ref) => {
421
- const [isInitialLoad, setIsInitialLoad] = useState(true);
422
500
  const [filters, setFilters] = useState({});
423
501
  const [sortBy, setSortBy] = useState({ col: "", type: "asc" });
424
502
  const [paginationSize, setPaginationSize] = useState((paginationCounts == null ? void 0 : paginationCounts[0]) || 0);
425
503
  const [paginationPage, setPaginationPage] = useState(0);
426
504
  const [collapsedGroups, setCollapsedGroups] = useState({});
505
+ const [selectedRows, setSelectedRows] = useState(/* @__PURE__ */ new Set());
506
+ const toggleRowSelection = (index) => {
507
+ setSelectedRows((prev) => {
508
+ const updated = new Set(prev);
509
+ if (updated.has(index)) {
510
+ updated.delete(index);
511
+ } else {
512
+ updated.add(index);
513
+ }
514
+ return updated;
515
+ });
516
+ };
517
+ const toggleAllSelection = () => {
518
+ if (selectedRows.size === processedData.length) {
519
+ setSelectedRows(/* @__PURE__ */ new Set());
520
+ } else {
521
+ const all = new Set(processedData.map((_, i) => i));
522
+ setSelectedRows(all);
523
+ }
524
+ };
427
525
  const toggleGroup = (groupKey) => {
428
526
  setCollapsedGroups((prev) => ({
429
527
  ...prev,
@@ -450,7 +548,6 @@ var DataTable = forwardRef(({
450
548
  setPaginationSize((paginationCounts == null ? void 0 : paginationCounts[0]) || 0);
451
549
  setPaginationPage(0);
452
550
  } finally {
453
- setIsInitialLoad(false);
454
551
  }
455
552
  }, [tableName, paginationCounts]);
456
553
  useEffect2(() => {
@@ -476,6 +573,11 @@ var DataTable = forwardRef(({
476
573
  const start = paginationPage * paginationSize;
477
574
  return processedData.slice(start, start + paginationSize);
478
575
  }, [processedData, paginationPage, paginationSize]);
576
+ const rowIdMap = useMemo2(() => {
577
+ const map = /* @__PURE__ */ new Map();
578
+ processedData.forEach((row, i) => map.set(row, i));
579
+ return map;
580
+ }, [processedData]);
479
581
  useEffect2(() => {
480
582
  if (Object.values(filters).some((value) => {
481
583
  return value !== null && value !== void 0 && value !== "";
@@ -495,8 +597,9 @@ var DataTable = forwardRef(({
495
597
  }, [paginationPage, tableName]);
496
598
  useImperativeHandle(ref, () => ({
497
599
  getData: () => processedData,
498
- getCurrentData: () => displayData
499
- }), [processedData, displayData]);
600
+ getCurrentData: () => displayData,
601
+ getSelectedData: () => Array.from(selectedRows).map((i) => processedData[i])
602
+ }), [processedData, displayData, selectedRows]);
500
603
  return /* @__PURE__ */ jsx13("div", { className: "ndt-table-container", children: /* @__PURE__ */ jsxs5("div", { className: "ndt-table", children: [
501
604
  /* @__PURE__ */ jsx13(
502
605
  TableHeader_default,
@@ -507,7 +610,10 @@ var DataTable = forwardRef(({
507
610
  filters,
508
611
  getFilters: setFilters,
509
612
  widths,
510
- headerGroup
613
+ headerGroup,
614
+ selectedRows,
615
+ toggleAllSelection,
616
+ displayData: processedData
511
617
  }
512
618
  ),
513
619
  loading ? loadingElement !== null ? loadingElement : /* @__PURE__ */ jsx13("span", { style: { marginLeft: 10, fontWeight: "bold" }, children: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0434\u0430\u043D\u043D\u044B\u0445..." }) : /* @__PURE__ */ jsx13(
@@ -521,7 +627,12 @@ var DataTable = forwardRef(({
521
627
  groupBy,
522
628
  collapsedGroups,
523
629
  toggleGroup,
524
- isTitles
630
+ isTitles,
631
+ selectedRows,
632
+ toggleRowSelection,
633
+ rowIdMap,
634
+ paginationSize,
635
+ paginationPage
525
636
  }
526
637
  ),
527
638
  isFooter && /* @__PURE__ */ jsx13(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nillud-data-table",
3
- "version": "1.2.9",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",