nillud-data-table 1.3.5 → 1.4.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
@@ -3,11 +3,14 @@
3
3
  ## Возможности
4
4
 
5
5
  ✅ Сортировка и фильтрация
6
- ✅ Поддержка экспорта в Excel и Word
6
+ ✅ Поддержка кастомных фильтров
7
+ ✅ Редактируемые ячейки
8
+ ✅ Кастомизация контента в ячейках, возможность внедрять React-компоненты
9
+ ✅ Открытые стили, свободное редактирование
7
10
  ✅ Группировка строк и заголовков
8
- ✅ Поддержка кастомных ячеек и фильтров
9
11
  ✅ Локальное сохранение состояния (localStorage)
10
12
  ✅ Поддержка React и TypeScript
13
+ ✅ Поддержка экспорта в Excel и Word (Необходимо подключить отдельные модули)
11
14
 
12
15
  ## Установка
13
16
 
@@ -20,7 +23,6 @@ yarn add nillud-data-table
20
23
  ## Начало работы
21
24
 
22
25
  #### **Быстрый пример (Quick Start)**
23
- Сделай короткий рабочий пример (без кастомных кнопок, модалок и т. д.) — для тех, кто просто хочет запустить:
24
26
 
25
27
  ```tsx
26
28
  import { DataTable } from 'nillud-data-table'
@@ -34,8 +36,6 @@ const data = [{ name: 'Иван' }]
34
36
 
35
37
  #### **Развернутый пример**
36
38
 
37
- Вызов со всеми пропсами:
38
-
39
39
  ```tsx
40
40
  import { DataTable } from 'nillud-data-table'
41
41
  import 'nillud-data-table/styles.css'
@@ -47,26 +47,15 @@ const columns = [{ field: 'name', title: 'Имя' }]
47
47
  const data = [{ name: 'Иван' }]
48
48
 
49
49
  <DataTable
50
+ tableData={tableData}
51
+ columns={columns}
50
52
  tableName='custom-modal'
51
53
  loading={loading}
52
- loadingElement={loadingElement}
53
- columns={columns}
54
- tableData={tableData}
55
- isFooter
56
- paginationCounts={[10, 20, 30, 40, 50, 0]}
57
- scrollable
54
+ loadingElement={<div>Loading...</div>}
55
+ isFooter={true}
56
+ paginationCounts={[10, 50, 100, 0]}
57
+ scrollable={true}
58
58
  scrollHeight={410}
59
- excelBtn
60
- wordBtn
61
- WordExportComponent={WordExport}
62
- ExportExcelComponent={ExportExcel}
63
- downloadSectionLeftSideContent={<button className='base-button' onClick={() => setCanvas(true)}>OffCanvas</button>}
64
- excelCustomColumns={[
65
- {
66
- key: 'name',
67
- width: 50
68
- }
69
- ]}
70
59
  headerGroup={[{title: 'Личные данные', cols: 3}, {title: 'Объект', cols: 3}]}
71
60
  groupBy={'status'}
72
61
  isTitles={true}
@@ -75,25 +64,20 @@ const data = [{ name: 'Иван' }]
75
64
 
76
65
  Доступные пропсы компонента:
77
66
 
78
- | props | required | type | Описание |
79
- | :--- | :---: | :---: | :--- |
80
- | [columns](#columns) | true | array [\{\}] | Принимает в себя массив объектов |
81
- | [tableData](#tabledata) | true | array [\{\}] | Принимает в себя массив объектов |
82
- | [tableName](#tablename) | true | string | Наименование таблицы для хранения значений в localStorage |
83
- | [loading](#loading) | - | boolean | Состояние загрузки, принимает в себя state типа boolean |
84
- | [loadingElement](#loadingelement) | - | React Element| Кастомный лоадер |
85
- | [isFooter](#isfooter) | - | boolean | Отображение footer |
86
- | [paginationCounts](#paginationcounts) | - | array<number> | Принимает массив чисел, число - количество строк для пагинации, (0 это все) |
87
- | [scrollable](#scrollable) | - | boolean | Зафиксировать высоту таблицы и добавить скролл |
88
- | [scrollHeight](#scrollheight) | - | number | Высота тела таблицы, работает, если scrollable: true |
89
- | [exportSectionComponent](#exportsectioncomponent) | - | import module| Необходимо импортировать модуль ExportSection
90
- | [exportCustomColumns](#exportcustomcolumns) | - | array [\{\}] | Принимает в себя массив объектов (\{\ key: string, width: number \}\) |
91
- | [excelBtn](#excelbtn) | - | boolean | Показывать кнопку экспорта Excel |
92
- | [wordBtn](#wordbtn) | - | boolean | Показывать кнопку экспорта Word |
93
- | [downloadSectionLeftSideContent](#downloadsectionleftsidecontent) | - | React Element| Отображать контент с левой стороны от кнопок экспорта |
94
- | [headerGroup](#headergroup) | - | array [\{\}] | Группировка столбцов (\{\ title: string, cols: number \}\) |
67
+ | props | required | type | Описание |
68
+ | :--- | :---: | :---: | :--- |
69
+ | [columns](#columns) | true | array [\{\}] | Принимает в себя массив объектов |
70
+ | [tableData](#tabledata) | true | array [\{\}] | Принимает в себя массив объектов |
71
+ | [tableName](#tablename) | true | string | Наименование таблицы для хранения значений в localStorage |
72
+ | [loading](#loading) | - | boolean | Состояние загрузки, принимает в себя state типа boolean |
73
+ | [loadingElement](#loadingelement) | - | React Element| Кастомный лоадер |
74
+ | [isFooter](#isfooter) | - | boolean | Отображение footer |
75
+ | [paginationCounts](#paginationcounts) | - | array<number> | Принимает массив чисел, число - количество строк для пагинации, (0 это все) |
76
+ | [scrollable](#scrollable) | - | boolean | Зафиксировать высоту таблицы и добавить скролл |
77
+ | [scrollHeight](#scrollheight) | - | number | Высота тела таблицы, работает, если scrollable: true |
78
+ | [headerGroup](#headergroup) | - | array [\{\}] | Группировка столбцов (\{\ title: string, cols: number \}\) |
95
79
  | [groupBy](#groupby) | - | string | Группировка данных, указывается заголовок столбца, по которому нужна группировка |
96
- | [isTitles](#istitles) | - | boolean | Заголовки при наведении на ячейку, по умолчанию false |
80
+ | [isTitles](#istitles) | - | boolean | Заголовки при наведении на ячейку, по умолчанию false |
97
81
 
98
82
  Типы описаны components/data-table/DataTable.types.ts
99
83
 
@@ -113,6 +97,12 @@ const data = [{ name: 'Иван' }]
113
97
 
114
98
  ```tsx
115
99
  const columns = [
100
+ {
101
+ field: '',
102
+ title: '',
103
+ width: 50,
104
+ selectable: true
105
+ },
116
106
  {
117
107
  field: 'id',
118
108
  title: '№',
@@ -123,6 +113,7 @@ const columns = [
123
113
  field: 'name',
124
114
  title: 'Наименование',
125
115
  filterable: false,
116
+ isSelectableCell: false,
126
117
  formatter: function (cell, row) {
127
118
  return (
128
119
  <div style={{ display: 'flex', alignItems: 'center' }}>
@@ -131,14 +122,12 @@ const columns = [
131
122
  </div>
132
123
  )
133
124
  },
134
- exportCustomCell: function (cell, row) {
135
- return `${cell} - ${row.date_to}`
136
- },
137
125
  },
138
126
  {
139
127
  field: 'address',
140
128
  title: 'Адрес',
141
- headerFilter: headerFilterAddress
129
+ headerFilter: headerFilterAddress,
130
+ editable: true
142
131
  },
143
132
  {
144
133
  field: 'obj',
@@ -150,18 +139,22 @@ const columns = [
150
139
 
151
140
  Доступные ключи объекта:
152
141
 
153
- | key | required | type | description |
154
- | :--- | :---: | :---: | :--- |
155
- | [field](#field) | true | string | Устанавливает связь по ключу в массиве данных tableData |
156
- | [title](#title) | true | string | Устанавливает заголовок столбца |
157
- | [width](#width) | - | number | Принимает числовое значение, ограничивает ширину столбца в пикселях |
158
- | [autoinc](#autoinc) | - | bool | Форматирует значения в столбце по порядку в таблице, начиная с 1 |
159
- | [formatter](#formatter) | - | func | Кастомное форматирование, принимает в себя функцию, описание далее |
160
- | [exportCustomCell](#exportCustomCell) | - | func | Кастомное форматирование для Excel и Word, принимает в себя функцию, описание далее |
161
- | [headerFilter](#headerFilter) | - | func | Кастомный фильтр, принимает в себя функуцию, описание далее |
162
- | [sortable](#sortable) | - | sortable | Убирает возможность сортировки, по умолчанию true |
163
- | [filterable](#filterable) | - | filterable | Убирает возможность фильтрации, по умолчанию true |
164
- | [selectable](#selectable) | - | selectable | Добавляет возможность отмечать строки таблицы |
142
+ | key | required | type | description |
143
+ | :--- | :---: | :---: | :--- |
144
+ | [field](#field) | true | string | Устанавливает связь по ключу в массиве данных tableData |
145
+ | [title](#title) | true | string | Устанавливает заголовок столбца |
146
+ | [width](#width) | - | number | Принимает числовое значение, ограничивает ширину столбца в пикселях |
147
+ | [autoinc](#autoinc) | - | bool | Форматирует значения в столбце по порядку в таблице, начиная с 1 |
148
+ | [formatter](#formatter) | - | func | Кастомное форматирование, принимает в себя функцию, описание далее |
149
+ | [headerFormatter](#headerFormatter) | - | func | Кастомное форматирование заголовка колонки, принимает в себя функцию, описание далее |
150
+ | [exportCustomCell](#exportCustomCell) | - | func | Кастомное форматирование для Excel и Word, принимает в себя функцию, описание далее |
151
+ | [headerFilter](#headerFilter) | - | func | Кастомный фильтр, принимает в себя функуцию, описание далее |
152
+ | [sortable](#sortable) | - | bool | Убирает возможность сортировки, по умолчанию true |
153
+ | [filterable](#filterable) | - | bool | Убирает возможность фильтрации, по умолчанию true |
154
+ | [selectable](#selectable) | - | bool | Добавляет возможность отмечать строки таблицы |
155
+ | [isSelectableCell](#isSelectableCell) | - | bool | При активном selectable убирает у ячейки функцию отметить строку при нажатии |
156
+ | [filterPlaceholder](#filterPlaceholder)| - | string | Задать плейсхолдер для фильтра в инпуте колонки |
157
+ | [editable](#editable) | - | bool | Добавляет возможность редактирования ячейки |
165
158
 
166
159
  #### field
167
160
 
@@ -233,7 +226,24 @@ const columns = [
233
226
  return (
234
227
  <div style={{ display: 'flex', alignItems: 'center' }}>
235
228
  <span style={{ marginBottom: 3 }}>{cell}</span>
236
- <span style={{ marginLeft: 5, cursor: 'pointer' }} onClick={() => { setModalShow(true); setRowData(row) }}><PenEdit /></span>
229
+ <span style={{ marginLeft: 5, cursor: 'pointer' }} onClick={() => { setModalShow(true); setRowData(row); }}><PenEdit /></span>
230
+ </div>
231
+ )
232
+ },
233
+ }
234
+ ```
235
+
236
+ #### headerFormatter
237
+
238
+ Кастомное отображение заголовка таблицы. Принимает в себя функцию с аргументом column.title, должна возвращать React Component.
239
+
240
+ ```tsx
241
+ {
242
+ ...,
243
+ headerFormatter: function (column) {
244
+ return (
245
+ <div style={{ display: 'flex', alignItems: 'center' }}>
246
+ <div>Something {column} <Icon size={20} /></div>
237
247
  </div>
238
248
  )
239
249
  },
@@ -325,6 +335,18 @@ const headerFilterAddress = (headerValue, rowValue) => {
325
335
  const selectedData = tableRef.current.getSelectedData()
326
336
  ```
327
337
 
338
+ #### isSelectableCell
339
+
340
+ Наличие функции выбора строки при активном **selectable**, в случе если есть логика кнопки или какого то действия, при котором не надо выполнять select строки
341
+
342
+ #### filterPlaceholder
343
+
344
+ Добавление плейсхолдера для инпута фильтрации в заголовке колонки
345
+
346
+ #### editable
347
+
348
+ Добавляет возможность редактирования строки. По умолчанию **false**
349
+
328
350
  ### tableData
329
351
 
330
352
  Обязательный параметр, принимает в себя массив объектов. В простой реализации таблицы в массиве **tableData** объекты должны содержать ключи равные значениям ключа **field** объекта в массиве **columns**
@@ -576,12 +598,4 @@ options = {{
576
598
  exportCustomColumns={[{...}, {...}]}
577
599
  wordOptions={{...}}
578
600
  />
579
- ```
580
-
581
- ##### downloadSectionLeftSideContent
582
-
583
- Необязательный параметр. Передается **React.Component**. Отображает компонент с левой стороны от кнопок экспорта. Создано для экономии места
584
-
585
- ```tsx
586
- downloadSectionLeftSideContent={<button className='base-button' onClick={() => setCanvas(true)}>OffCanvas</button>}
587
601
  ```
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ type Column = {
18
18
  selectable?: boolean;
19
19
  isSelectableCell?: boolean;
20
20
  filterPlaceholder?: string;
21
+ editable?: boolean;
21
22
  };
22
23
  type Columns = Column[];
23
24
  type TableProps = {
package/dist/index.js CHANGED
@@ -104,7 +104,7 @@ var TableHeader_default = React.memo(Header);
104
104
  import React2 from "react";
105
105
 
106
106
  // components/data-table/Cell.tsx
107
- import { Fragment as Fragment3, jsx as jsx5 } from "react/jsx-runtime";
107
+ import { jsx as jsx5 } from "react/jsx-runtime";
108
108
  var Cell = ({
109
109
  row,
110
110
  column,
@@ -112,23 +112,50 @@ var Cell = ({
112
112
  displayId,
113
113
  isTitles,
114
114
  isRowSelected,
115
- onRowSelect
115
+ onRowSelect,
116
+ isSelectable
116
117
  }) => {
117
118
  const rawValue = row[column.field];
118
119
  const stringValue = typeof rawValue !== "undefined" && rawValue !== null ? String(rawValue) : "";
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(
120
+ const isAutoinc = !!column.autoinc;
121
+ const isFormatted = typeof column.formatter !== "undefined";
122
+ const isEditable = !!column.editable;
123
+ const isColumnSelectable = !!column.selectable;
124
+ const formattedContent = column.formatter && column.formatter(stringValue, row, column);
125
+ const CellWithData = ({ children }) => /* @__PURE__ */ jsx5(
121
126
  "div",
122
127
  {
123
128
  className: "ndt-cell",
124
129
  title: isTitles && stringValue ? stringValue : "",
125
- onClick: typeof column.isSelectableCell === "undefined" || column.isSelectableCell ? onRowSelect : () => {
130
+ onClick: isSelectable && (typeof column.isSelectableCell === "undefined" || column.isSelectableCell || column.editable) ? onRowSelect : () => {
126
131
  },
127
- children: content
132
+ children
133
+ }
134
+ );
135
+ const EditableCell = () => /* @__PURE__ */ jsx5(
136
+ "input",
137
+ {
138
+ className: "ndt-cell ndt-cell-editable",
139
+ defaultValue: stringValue ? String(stringValue) : "",
140
+ onChange: (e) => {
141
+ row[column.field] = e.target.value;
142
+ }
128
143
  }
129
144
  );
130
- const renderSelectableCell = () => /* @__PURE__ */ jsx5("div", { className: "ndt-cell ndt-checkbox-cell", children: /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: !!isRowSelected }) });
131
- return /* @__PURE__ */ jsx5(Fragment3, { children: column.selectable ? renderSelectableCell() : renderCell() });
145
+ const SelectableCell = () => /* @__PURE__ */ jsx5("div", { className: "ndt-cell ndt-checkbox-cell", onClick: onRowSelect, children: /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: !!isRowSelected, onChange: () => {
146
+ } }) });
147
+ switch (true) {
148
+ case isAutoinc:
149
+ return /* @__PURE__ */ jsx5(CellWithData, { children: displayId + 1 });
150
+ case isFormatted:
151
+ return /* @__PURE__ */ jsx5(CellWithData, { children: formattedContent });
152
+ case isEditable:
153
+ return /* @__PURE__ */ jsx5(EditableCell, {});
154
+ case isColumnSelectable:
155
+ return /* @__PURE__ */ jsx5(SelectableCell, {});
156
+ default:
157
+ return /* @__PURE__ */ jsx5(CellWithData, { children: stringValue });
158
+ }
132
159
  };
133
160
  var Cell_default = Cell;
134
161
 
@@ -158,7 +185,8 @@ var Row = ({
158
185
  displayId,
159
186
  isTitles,
160
187
  isRowSelected,
161
- onRowSelect
188
+ onRowSelect,
189
+ isSelectable: !!isSelectable
162
190
  },
163
191
  `cell-${rowId}-${id}`
164
192
  ))
package/dist/styles.css CHANGED
@@ -110,6 +110,15 @@
110
110
  font-size: 16px;
111
111
  font-weight: 400;
112
112
  }
113
+ .ndt-table-container .ndt-table .ndt-table-body .ndt-table-row .ndt-cell.ndt-cell-editable {
114
+ border: none;
115
+ background-color: transparent;
116
+ }
117
+ .ndt-table-container .ndt-table .ndt-table-body .ndt-table-row .ndt-cell.ndt-cell-editable:focus, .ndt-table-container .ndt-table .ndt-table-body .ndt-table-row .ndt-cell.ndt-cell-editable:focus-visible, .ndt-table-container .ndt-table .ndt-table-body .ndt-table-row .ndt-cell.ndt-cell-editable:active {
118
+ outline: 1px solid rgba(34, 34, 34, 0.6);
119
+ border: none;
120
+ box-shadow: none;
121
+ }
113
122
  .ndt-table-container .ndt-table .ndt-table-body .ndt-table-row .ndt-cell:not(:last-child) {
114
123
  border-right: 1px solid #ddd;
115
124
  }
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../components/data-table/styles/data-table.scss"],"names":[],"mappings":";AACI;EACI;EACA;;AAEA;AAAA;EAEI;;AAGJ;AAAA;EAEI;;AAGJ;EACI;;AAEA;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAMR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMhB;EACI;;AAEA;EACI;EACA;EACA;;AAGA;EACI;AACA;;AAGJ;EACI;AACA;EACA;AACA;;AAGJ;EACI;AACA;EACA;AACA;;AAGJ;EACI;AACA;;AAKJ;EACI;;AAGJ;EACI;;AAGJ;EAEI;;AAGJ;EACI;;AAEA;EAEI;;AAIR;EAEI;;AAGJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAMhB;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGI;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EAGI;;AAGJ;EACI;EACA;;AAIR;EACI;EACA;;AAEA;EACI;;AAEA;EACI;EACA;EACA;;;AAUhC;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAEA;EAGI;EACA;EACA;;AAIR;EACI;;AAEA;EAGI;EACA;EACA;;;AAKZ;EACI;EACA;EACA;EACA;EACA;;AAIA;EACI","file":"styles.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../components/data-table/styles/data-table.scss"],"names":[],"mappings":";AACI;EACI;EACA;;AAEA;AAAA;EAEI;;AAGJ;AAAA;EAEI;;AAGJ;EACI;;AAEA;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAMR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMhB;EACI;;AAEA;EACI;EACA;EACA;;AAGA;EACI;AACA;;AAGJ;EACI;AACA;EACA;AACA;;AAGJ;EACI;AACA;EACA;AACA;;AAGJ;EACI;AACA;;AAKJ;EACI;;AAGJ;EACI;;AAGJ;EAEI;;AAGJ;EACI;;AAEA;EAEI;;AAIR;EAEI;;AAGJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAEA;EAGI;EACA;EACA;;AAIR;EACI;;AAMhB;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGI;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EAGI;;AAGJ;EACI;EACA;;AAIR;EACI;EACA;;AAEA;EACI;;AAEA;EACI;EACA;EACA;;;AAUhC;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAEA;EAGI;EACA;EACA;;AAIR;EACI;;AAEA;EAGI;EACA;EACA;;;AAKZ;EACI;EACA;EACA;EACA;EACA;;AAIA;EACI","file":"styles.css"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nillud-data-table",
3
- "version": "1.3.5",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",