apex-grid 1.1.0 → 3.0.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.
Files changed (231) hide show
  1. package/LICENSE +76 -5
  2. package/README.md +523 -10
  3. package/components/cell.d.ts +39 -0
  4. package/components/cell.js +334 -5
  5. package/components/cell.js.map +1 -1
  6. package/components/filter-row.d.ts +7 -5
  7. package/components/filter-row.js +151 -68
  8. package/components/filter-row.js.map +1 -1
  9. package/components/grid.d.ts +955 -4
  10. package/components/grid.js +412 -40
  11. package/components/grid.js.map +1 -1
  12. package/components/header-row.d.ts +21 -1
  13. package/components/header-row.js +140 -7
  14. package/components/header-row.js.map +1 -1
  15. package/components/header.d.ts +7 -0
  16. package/components/header.js +151 -31
  17. package/components/header.js.map +1 -1
  18. package/components/paginator.d.ts +56 -0
  19. package/components/paginator.js +148 -0
  20. package/components/paginator.js.map +1 -0
  21. package/components/row.d.ts +21 -2
  22. package/components/row.js +185 -10
  23. package/components/row.js.map +1 -1
  24. package/components/toolbar.d.ts +60 -0
  25. package/components/toolbar.js +259 -0
  26. package/components/toolbar.js.map +1 -0
  27. package/components/virtualizer.js +1 -1
  28. package/components/virtualizer.js.map +1 -1
  29. package/controllers/data-operation.d.ts +14 -0
  30. package/controllers/data-operation.js +19 -2
  31. package/controllers/data-operation.js.map +1 -1
  32. package/controllers/dom.d.ts +37 -1
  33. package/controllers/dom.js +176 -9
  34. package/controllers/dom.js.map +1 -1
  35. package/controllers/editing.d.ts +130 -0
  36. package/controllers/editing.js +197 -0
  37. package/controllers/editing.js.map +1 -0
  38. package/controllers/expansion.d.ts +68 -0
  39. package/controllers/expansion.js +126 -0
  40. package/controllers/expansion.js.map +1 -0
  41. package/controllers/navigation.d.ts +17 -6
  42. package/controllers/navigation.js +24 -8
  43. package/controllers/navigation.js.map +1 -1
  44. package/controllers/pagination.d.ts +102 -0
  45. package/controllers/pagination.js +106 -0
  46. package/controllers/pagination.js.map +1 -0
  47. package/controllers/reorder.d.ts +78 -0
  48. package/controllers/reorder.js +124 -0
  49. package/controllers/reorder.js.map +1 -0
  50. package/controllers/selection.d.ts +109 -0
  51. package/controllers/selection.js +168 -0
  52. package/controllers/selection.js.map +1 -0
  53. package/controllers/sort.js +28 -0
  54. package/controllers/sort.js.map +1 -1
  55. package/controllers/state.d.ts +47 -1
  56. package/controllers/state.js +48 -1
  57. package/controllers/state.js.map +1 -1
  58. package/controllers/tree.d.ts +87 -0
  59. package/controllers/tree.js +0 -0
  60. package/controllers/tree.js.map +1 -0
  61. package/custom-elements.json +6491 -1355
  62. package/define.js.map +1 -1
  63. package/docs/assets/hierarchy.js +1 -1
  64. package/docs/assets/highlight.css +77 -14
  65. package/docs/assets/icons.js +1 -1
  66. package/docs/assets/icons.svg +1 -1
  67. package/docs/assets/main.js +4 -4
  68. package/docs/assets/navigation.js +1 -1
  69. package/docs/assets/search.js +1 -1
  70. package/docs/assets/style.css +3 -3
  71. package/docs/classes/ApexGrid.html +320 -24
  72. package/docs/functions/setup.html +16 -0
  73. package/docs/hierarchy.html +1 -1
  74. package/docs/index.html +543 -9
  75. package/docs/interfaces/ApexCellValueChangedEvent.html +11 -0
  76. package/docs/interfaces/ApexCellValueChangingEvent.html +13 -0
  77. package/docs/interfaces/ApexColumnMovedEvent.html +8 -0
  78. package/docs/interfaces/ApexColumnMovingEvent.html +11 -0
  79. package/docs/interfaces/ApexColumnPinnedEvent.html +6 -0
  80. package/docs/interfaces/ApexColumnPinningEvent.html +8 -0
  81. package/docs/interfaces/ApexDetailContext.html +8 -0
  82. package/docs/interfaces/ApexFilteredEvent.html +4 -4
  83. package/docs/interfaces/ApexFilteringEvent.html +4 -4
  84. package/docs/interfaces/ApexGridEventMap.html +60 -9
  85. package/docs/interfaces/ApexHeaderContext.html +4 -4
  86. package/docs/interfaces/ApexPageChangedEvent.html +10 -0
  87. package/docs/interfaces/ApexPageChangingEvent.html +10 -0
  88. package/docs/interfaces/ApexQuickFilterChangedEvent.html +4 -0
  89. package/docs/interfaces/ApexQuickFilterChangingEvent.html +6 -0
  90. package/docs/interfaces/ApexRowEditEndedEvent.html +6 -0
  91. package/docs/interfaces/ApexRowEditStartedEvent.html +4 -0
  92. package/docs/interfaces/ApexRowExpandedEvent.html +8 -0
  93. package/docs/interfaces/ApexRowExpandingEvent.html +11 -0
  94. package/docs/interfaces/ApexRowSelectedEvent.html +8 -0
  95. package/docs/interfaces/ApexRowSelectingEvent.html +11 -0
  96. package/docs/interfaces/ApexTreeRowExpandedEvent.html +8 -0
  97. package/docs/interfaces/ApexTreeRowExpandingEvent.html +10 -0
  98. package/docs/interfaces/BaseApexCellContext.html +12 -6
  99. package/docs/interfaces/BaseApexEditorContext.html +19 -0
  100. package/docs/interfaces/BaseColumnConfiguration.html +88 -14
  101. package/docs/interfaces/BaseColumnSortConfiguration.html +4 -4
  102. package/docs/interfaces/BaseFilterExpression.html +5 -5
  103. package/docs/interfaces/BaseSortExpression.html +4 -4
  104. package/docs/interfaces/CSVExportOptions.html +22 -0
  105. package/docs/interfaces/ColumnFilterConfiguration.html +3 -3
  106. package/docs/interfaces/DataPipelineConfiguration.html +13 -4
  107. package/docs/interfaces/ExportFormat.html +10 -0
  108. package/docs/interfaces/ExportOptions.html +15 -0
  109. package/docs/interfaces/GridEditingConfiguration.html +10 -0
  110. package/docs/interfaces/GridExpansionConfiguration.html +15 -0
  111. package/docs/interfaces/GridSelectionConfiguration.html +11 -0
  112. package/docs/interfaces/GridSortConfiguration.html +4 -4
  113. package/docs/interfaces/GridTreeConfiguration.html +33 -0
  114. package/docs/interfaces/PaginationConfiguration.html +18 -0
  115. package/docs/interfaces/PaginationState.html +10 -0
  116. package/docs/media/LICENSE +80 -0
  117. package/docs/media/_tokens.scss +106 -0
  118. package/docs/media/package.json +85 -0
  119. package/docs/modules.html +1 -1
  120. package/docs/types/ApexCellContext.html +2 -2
  121. package/docs/types/ApexEditorContext.html +2 -0
  122. package/docs/types/BasePropertyType.html +2 -2
  123. package/docs/types/BaseSortComparer.html +2 -2
  124. package/docs/types/ColumnConfiguration.html +2 -2
  125. package/docs/types/ColumnDropPosition.html +2 -0
  126. package/docs/types/ColumnSortConfiguration.html +2 -2
  127. package/docs/types/DataPipelineHook.html +2 -2
  128. package/docs/types/DataPipelineParams.html +5 -5
  129. package/docs/types/DataType.html +47 -2
  130. package/docs/types/EditMode.html +6 -0
  131. package/docs/types/EditTrigger.html +4 -0
  132. package/docs/types/ExportCellValue.html +5 -0
  133. package/docs/types/ExportSource.html +8 -0
  134. package/docs/types/FilterCriteria.html +2 -2
  135. package/docs/types/FilterExpression.html +2 -2
  136. package/docs/types/Keys.html +2 -2
  137. package/docs/types/PaginationMode.html +6 -0
  138. package/docs/types/PinPosition.html +5 -0
  139. package/docs/types/PropertyType.html +2 -2
  140. package/docs/types/SelectionMode.html +7 -0
  141. package/docs/types/SortComparer.html +2 -2
  142. package/docs/types/SortExpression.html +2 -2
  143. package/docs/types/SortState.html +2 -2
  144. package/docs/types/SortingDirection.html +1 -1
  145. package/index.d.ts +5 -2
  146. package/index.js +1 -0
  147. package/index.js.map +1 -1
  148. package/internal/column-types.d.ts +94 -0
  149. package/internal/column-types.js +428 -0
  150. package/internal/column-types.js.map +1 -0
  151. package/internal/export.d.ts +114 -0
  152. package/internal/export.js +122 -0
  153. package/internal/export.js.map +1 -0
  154. package/internal/feature-module.d.ts +27 -0
  155. package/internal/feature-module.js +2 -0
  156. package/internal/feature-module.js.map +1 -0
  157. package/internal/flip.d.ts +80 -0
  158. package/internal/flip.js +52 -0
  159. package/internal/flip.js.map +1 -0
  160. package/internal/icons.d.ts +31 -0
  161. package/internal/icons.js +145 -0
  162. package/internal/icons.js.map +1 -0
  163. package/internal/index.d.ts +20 -0
  164. package/internal/index.js +6 -0
  165. package/internal/index.js.map +1 -0
  166. package/internal/tags.d.ts +2 -0
  167. package/internal/tags.js +2 -0
  168. package/internal/tags.js.map +1 -1
  169. package/internal/types.d.ts +473 -3
  170. package/internal/types.js.map +1 -1
  171. package/internal/utils.d.ts +24 -1
  172. package/internal/utils.js +48 -7
  173. package/internal/utils.js.map +1 -1
  174. package/operations/filter/tree.d.ts +1 -1
  175. package/operations/filter/types.js.map +1 -1
  176. package/operations/pagination.d.ts +19 -0
  177. package/operations/pagination.js +12 -0
  178. package/operations/pagination.js.map +1 -0
  179. package/operations/quick-filter.d.ts +21 -0
  180. package/operations/quick-filter.js +26 -0
  181. package/operations/quick-filter.js.map +1 -0
  182. package/operations/sort/types.js.map +1 -1
  183. package/package.json +10 -5
  184. package/setup.d.ts +51 -0
  185. package/setup.js +31 -0
  186. package/setup.js.map +1 -0
  187. package/styles/_checkbox.css.js +3 -0
  188. package/styles/_checkbox.css.js.map +1 -0
  189. package/styles/_tokens.css.js +3 -0
  190. package/styles/_tokens.css.js.map +1 -0
  191. package/styles/body-cell/body-cell.css.js +1 -1
  192. package/styles/body-cell/body-cell.css.js.map +1 -1
  193. package/styles/body-cell/cell-renderers.css.js +3 -0
  194. package/styles/body-cell/cell-renderers.css.js.map +1 -0
  195. package/styles/body-row/body-row.css.js +1 -1
  196. package/styles/body-row/body-row.css.js.map +1 -1
  197. package/styles/filter-row/filter-row.css.js +1 -1
  198. package/styles/filter-row/filter-row.css.js.map +1 -1
  199. package/styles/grid/_grid.base.css.js +1 -1
  200. package/styles/grid/_grid.base.css.js.map +1 -1
  201. package/styles/grid/grid.css.js +3 -0
  202. package/styles/grid/grid.css.js.map +1 -0
  203. package/styles/header-cell/header-cell.css.js +1 -1
  204. package/styles/header-cell/header-cell.css.js.map +1 -1
  205. package/styles/header-row/header-row.base.css.js +1 -1
  206. package/styles/header-row/header-row.base.css.js.map +1 -1
  207. package/styles/paginator/paginator.css.d.ts +1 -0
  208. package/styles/paginator/paginator.css.js +3 -0
  209. package/styles/paginator/paginator.css.js.map +1 -0
  210. package/styles/toolbar/toolbar.css.d.ts +1 -0
  211. package/styles/toolbar/toolbar.css.js +3 -0
  212. package/styles/toolbar/toolbar.css.js.map +1 -0
  213. package/styles.css +17 -0
  214. package/internal/icon-registry.d.ts +0 -1
  215. package/internal/icon-registry.js +0 -29
  216. package/internal/icon-registry.js.map +0 -1
  217. package/internal/theming.d.ts +0 -34
  218. package/internal/theming.js +0 -123
  219. package/internal/theming.js.map +0 -1
  220. package/styles/grid/themes/light/grid.bootstrap.css.js +0 -3
  221. package/styles/grid/themes/light/grid.bootstrap.css.js.map +0 -1
  222. package/styles/grid/themes/light/grid.fluent.css.js +0 -3
  223. package/styles/grid/themes/light/grid.fluent.css.js.map +0 -1
  224. package/styles/grid/themes/light/grid.indigo.css.js +0 -3
  225. package/styles/grid/themes/light/grid.indigo.css.js.map +0 -1
  226. package/styles/grid/themes/light/grid.material.css.js +0 -3
  227. package/styles/grid/themes/light/grid.material.css.js.map +0 -1
  228. /package/styles/{grid/themes/light/grid.bootstrap.css.d.ts → _checkbox.css.d.ts} +0 -0
  229. /package/styles/{grid/themes/light/grid.fluent.css.d.ts → _tokens.css.d.ts} +0 -0
  230. /package/styles/{grid/themes/light/grid.indigo.css.d.ts → body-cell/cell-renderers.css.d.ts} +0 -0
  231. /package/styles/grid/{themes/light/grid.material.css.d.ts → grid.css.d.ts} +0 -0
@@ -5,7 +5,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { ContextProvider } from '@lit/context';
8
- import { IgcButtonComponent, IgcChipComponent, IgcDropdownComponent, IgcInputComponent, } from 'igniteui-webcomponents';
9
8
  import { html, nothing } from 'lit';
10
9
  import { eventOptions, property, query, queryAll, state } from 'lit/decorators.js';
11
10
  import { styleMap } from 'lit/directives/style-map.js';
@@ -13,28 +12,118 @@ import { DataOperationsController } from '../controllers/data-operation.js';
13
12
  import { GridDOMController } from '../controllers/dom.js';
14
13
  import { gridStateContext, StateController } from '../controllers/state.js';
15
14
  import { DEFAULT_COLUMN_CONFIG, PIPELINE } from '../internal/constants.js';
15
+ import { buildCSV, downloadBlob, } from '../internal/export.js';
16
16
  import { EventEmitterBase } from '../internal/mixins/event-emitter.js';
17
17
  import { registerComponent } from '../internal/register.js';
18
18
  import { GRID_TAG } from '../internal/tags.js';
19
- import { addThemingController } from '../internal/theming.js';
20
- import { asArray, autoGenerateColumns, getFilterOperandsFor } from '../internal/utils.js';
19
+ import { asArray, autoGenerateColumns, getDisplayColumns, getFilterOperandsFor, } from '../internal/utils.js';
21
20
  import { watch } from '../internal/watch.js';
22
- import { styles as bootstrap } from '../styles/grid/themes/light/grid.bootstrap.css.js';
23
- import { styles as fluent } from '../styles/grid/themes/light/grid.fluent.css.js';
24
- import { styles as indigo } from '../styles/grid/themes/light/grid.indigo.css.js';
25
- import { styles as material } from '../styles/grid/themes/light/grid.material.css.js';
21
+ import { styles as gridStyles } from '../styles/grid/grid.css.js';
26
22
  import ApexGridCell from './cell.js';
27
23
  import ApexFilterRow from './filter-row.js';
28
24
  import ApexGridHeaderRow from './header-row.js';
25
+ import ApexGridPaginator from './paginator.js';
29
26
  import ApexGridRow from './row.js';
27
+ import ApexGridToolbar from './toolbar.js';
30
28
  import ApexVirtualizer from './virtualizer.js';
31
29
  export class ApexGrid extends EventEmitterBase {
30
+ constructor() {
31
+ super(...arguments);
32
+ this.stateController = this.createStateController();
33
+ this.DOM = new GridDOMController(this, this.stateController);
34
+ this.dataController = new DataOperationsController(this);
35
+ this.stateProvider = new ContextProvider(this, {
36
+ context: gridStateContext,
37
+ initialValue: this.stateController,
38
+ });
39
+ this.dataState = [];
40
+ this.columns = [];
41
+ this.data = [];
42
+ this.autoGenerate = false;
43
+ this.sortConfiguration = {
44
+ multiple: true,
45
+ triState: true,
46
+ };
47
+ this.quickFilter = '';
48
+ this.showQuickFilter = false;
49
+ this.showExport = false;
50
+ this.columnReordering = false;
51
+ }
32
52
  static get tagName() {
33
53
  return GRID_TAG;
34
54
  }
35
- static { this.styles = bootstrap; }
55
+ static { this.styles = gridStyles; }
36
56
  static register() {
37
- registerComponent(ApexGrid, ApexVirtualizer, ApexGridRow, ApexGridHeaderRow, ApexFilterRow, IgcButtonComponent, IgcChipComponent, IgcInputComponent, IgcDropdownComponent);
57
+ registerComponent(ApexGrid, ApexVirtualizer, ApexGridRow, ApexGridHeaderRow, ApexFilterRow, ApexGridPaginator, ApexGridToolbar);
58
+ }
59
+ createStateController() {
60
+ return new StateController(this);
61
+ }
62
+ get selectedRows() {
63
+ return this.stateController.selection.selectedRows();
64
+ }
65
+ set selectedRows(rows) {
66
+ void this.stateController.selection.replaceSelection(rows);
67
+ }
68
+ selectRow(row) {
69
+ return this.stateController.selection.selectRow(row);
70
+ }
71
+ deselectRow(row) {
72
+ return this.stateController.selection.deselectRow(row);
73
+ }
74
+ toggleRowSelection(row) {
75
+ return this.stateController.selection.toggleRow(row);
76
+ }
77
+ selectAllRows() {
78
+ return this.stateController.selection.selectAll();
79
+ }
80
+ clearSelection() {
81
+ return this.stateController.selection.clear();
82
+ }
83
+ isRowSelected(row) {
84
+ return this.stateController.selection.isSelected(row);
85
+ }
86
+ get expandedRows() {
87
+ return this.stateController.expansion.expandedRows();
88
+ }
89
+ set expandedRows(rows) {
90
+ void this.stateController.expansion.replaceExpansion(rows);
91
+ }
92
+ expandRow(row) {
93
+ return this.stateController.expansion.expandRow(row);
94
+ }
95
+ collapseRow(row) {
96
+ return this.stateController.expansion.collapseRow(row);
97
+ }
98
+ toggleRowExpansion(row) {
99
+ return this.stateController.expansion.toggleRow(row);
100
+ }
101
+ expandAllRows() {
102
+ return this.stateController.expansion.expandAll();
103
+ }
104
+ collapseAllRows() {
105
+ return this.stateController.expansion.collapseAll();
106
+ }
107
+ isRowExpanded(row) {
108
+ return this.stateController.expansion.isExpanded(row);
109
+ }
110
+ toggleTreeRow(row) {
111
+ return this.stateController.tree.toggleRow(row);
112
+ }
113
+ expandTreeRow(row) {
114
+ return this.stateController.tree.expandRow(row);
115
+ }
116
+ collapseTreeRow(row) {
117
+ return this.stateController.tree.collapseRow(row);
118
+ }
119
+ expandAllTreeRows() {
120
+ return this.stateController.tree.expandAll();
121
+ }
122
+ collapseAllTreeRows() {
123
+ return this.stateController.tree.collapseAll();
124
+ }
125
+ isTreeRowExpanded(row) {
126
+ return this.stateController.tree.isExpanded(row);
38
127
  }
39
128
  set sortExpressions(expressions) {
40
129
  if (expressions.length) {
@@ -62,43 +151,97 @@ export class ApexGrid extends EventEmitterBase {
62
151
  get dataView() {
63
152
  return this.dataState;
64
153
  }
154
+ get displayColumns() {
155
+ return getDisplayColumns(this.columns);
156
+ }
65
157
  get totalItems() {
158
+ if (this.pagination?.mode === 'remote') {
159
+ return Math.max(0, this.pagination?.totalItems ?? 0);
160
+ }
66
161
  return this.dataState.length;
67
162
  }
163
+ get pageItems() {
164
+ if (!this.stateController.pagination.enabled)
165
+ return this.dataState;
166
+ if (this.pagination?.mode === 'remote')
167
+ return this.dataState;
168
+ const { page, pageSize } = this.stateController.pagination;
169
+ if (!pageSize)
170
+ return this.dataState;
171
+ const start = page * pageSize;
172
+ return this.dataState.slice(start, start + pageSize);
173
+ }
174
+ get page() {
175
+ return this.stateController.pagination.page;
176
+ }
177
+ set page(value) {
178
+ this.stateController.pagination.gotoPage(value);
179
+ }
180
+ get pageSize() {
181
+ return this.stateController.pagination.pageSize;
182
+ }
183
+ set pageSize(value) {
184
+ this.stateController.pagination.setPageSize(value);
185
+ }
186
+ get pageCount() {
187
+ return this.stateController.pagination.pageCount;
188
+ }
68
189
  watchColumns(_, newConfig = []) {
69
190
  this.columns = newConfig.map((config) => ({ ...DEFAULT_COLUMN_CONFIG, ...config }));
70
191
  }
71
192
  dataChanged() {
72
- this.dataState = structuredClone(this.data);
193
+ let next = [...this.data];
73
194
  autoGenerateColumns(this);
195
+ this.stateController?.tree?.resetForDataChange();
196
+ if (this.stateController?.tree?.enabled) {
197
+ next = this.stateController.tree.process(next);
198
+ }
199
+ this.dataState = next;
74
200
  if (this.hasUpdated) {
75
201
  this.pipeline();
76
202
  }
77
203
  }
78
204
  async pipeline() {
79
- this.dataState = await this.dataController.apply(structuredClone(this.data), this.stateController);
205
+ this.dataState = await this.dataController.apply([...this.data], this.stateController);
206
+ this.stateController.pagination.reclamp();
80
207
  }
81
- constructor() {
82
- super();
83
- this.stateController = new StateController(this);
84
- this.DOM = new GridDOMController(this, this.stateController);
85
- this.dataController = new DataOperationsController(this);
86
- this.stateProvider = new ContextProvider(this, {
87
- context: gridStateContext,
88
- initialValue: this.stateController,
89
- });
90
- this.dataState = [];
91
- this.columns = [];
92
- this.data = [];
93
- this.autoGenerate = false;
94
- this.sortConfiguration = {
95
- multiple: true,
96
- triState: true,
97
- };
98
- addThemingController(this, {
99
- light: { bootstrap, material, fluent, indigo },
100
- dark: { bootstrap, material, fluent, indigo },
101
- });
208
+ paginationChanged() {
209
+ const ctrl = this.stateController?.pagination;
210
+ if (!ctrl)
211
+ return;
212
+ const next = this.pagination ?? {};
213
+ if (typeof next.pageSize === 'number' && next.pageSize > 0) {
214
+ ctrl.pageSize = next.pageSize;
215
+ }
216
+ if (typeof next.page === 'number') {
217
+ ctrl.page = next.page;
218
+ }
219
+ if (this.hasUpdated) {
220
+ this.pipeline();
221
+ }
222
+ }
223
+ quickFilterChanged() {
224
+ if (this.hasUpdated) {
225
+ this.pipeline();
226
+ }
227
+ }
228
+ updated() {
229
+ this.setAttribute('role', this.stateController.tree.enabled ? 'treegrid' : 'grid');
230
+ const hasFilter = this.columns.some((column) => column.filter);
231
+ const headerRows = hasFilter ? 2 : 1;
232
+ this.setAttribute('aria-rowcount', String(headerRows + this.pageItems.length));
233
+ const visibleColumns = this.columns.filter((column) => !column.hidden).length;
234
+ const extras = (this.stateController.selection.showCheckboxColumn ? 1 : 0) +
235
+ (this.stateController.expansion.showToggleColumn ? 1 : 0);
236
+ this.setAttribute('aria-colcount', String(visibleColumns + extras));
237
+ }
238
+ firstUpdated() {
239
+ if (typeof getComputedStyle === 'function' && getComputedStyle(this).display !== 'grid') {
240
+ console.warn('[apex-grid] Host `display` has been overridden. The grid requires ' +
241
+ '`display: grid` for its internal track layout and will not render correctly. ' +
242
+ 'Remove any CSS rule that sets `display` on <apex-grid>. ' +
243
+ 'See: https://github.com/apexcharts/apexgrid#4-size-the-host');
244
+ }
102
245
  }
103
246
  filter(config) {
104
247
  this.stateController.filtering.filter(asArray(config).map((each) => typeof each.condition === 'string'
@@ -119,20 +262,165 @@ export class ApexGrid extends EventEmitterBase {
119
262
  this.stateController.filtering.reset(key);
120
263
  this.requestUpdate(PIPELINE);
121
264
  }
265
+ gotoPage(page) {
266
+ return this.stateController.pagination.gotoPage(page);
267
+ }
268
+ setPageSize(size) {
269
+ return this.stateController.pagination.setPageSize(size);
270
+ }
271
+ nextPage() {
272
+ return this.stateController.pagination.nextPage();
273
+ }
274
+ previousPage() {
275
+ return this.stateController.pagination.previousPage();
276
+ }
277
+ firstPage() {
278
+ return this.stateController.pagination.firstPage();
279
+ }
280
+ lastPage() {
281
+ return this.stateController.pagination.lastPage();
282
+ }
283
+ async setQuickFilter(value) {
284
+ const next = value ?? '';
285
+ if (next === this.quickFilter)
286
+ return false;
287
+ const proceed = this.emitEvent('quickFilterChanging', {
288
+ detail: { value: this.quickFilter, nextValue: next },
289
+ cancelable: true,
290
+ });
291
+ if (!proceed)
292
+ return false;
293
+ this.quickFilter = next;
294
+ this.stateController.pagination.page = 0;
295
+ await this.updateComplete;
296
+ this.emitEvent('quickFilterChanged', { detail: { value: this.quickFilter } });
297
+ return true;
298
+ }
122
299
  getColumn(id) {
123
300
  return typeof id === 'number'
124
301
  ? this.columns.at(id)
125
302
  : this.columns.find(({ key }) => key === id);
126
303
  }
127
304
  updateColumns(columns) {
128
- for (const column of asArray(columns)) {
129
- const instance = this.columns.find((curr) => curr.key === column.key);
130
- if (instance) {
131
- Object.assign(instance, column);
132
- }
133
- }
305
+ const updates = new Map(asArray(columns).map((c) => [c.key, c]));
306
+ if (updates.size === 0)
307
+ return;
308
+ let touched = false;
309
+ const next = this.columns.map((column) => {
310
+ const patch = updates.get(column.key);
311
+ if (!patch)
312
+ return column;
313
+ touched = true;
314
+ return { ...column, ...patch };
315
+ });
316
+ if (!touched)
317
+ return;
318
+ this.columns = next;
134
319
  this.requestUpdate(PIPELINE);
135
320
  }
321
+ async pinColumn(key, position) {
322
+ const column = this.getColumn(key);
323
+ if (!column)
324
+ return false;
325
+ const previous = column.pinned ?? null;
326
+ const next = position ?? null;
327
+ if (previous === next)
328
+ return false;
329
+ const proceed = this.emitEvent('columnPinning', {
330
+ detail: { key, previous, next },
331
+ cancelable: true,
332
+ });
333
+ if (!proceed)
334
+ return false;
335
+ column.pinned = next ?? undefined;
336
+ this.columns = [...this.columns];
337
+ await this.updateComplete;
338
+ this.emitEvent('columnPinned', { detail: { key, pinned: next } });
339
+ return true;
340
+ }
341
+ unpinColumn(key) {
342
+ return this.pinColumn(key, null);
343
+ }
344
+ get editingCell() {
345
+ const active = this.stateController.editing.activeCell;
346
+ return active ? { rowIndex: active.rowIndex, columnKey: active.columnKey } : null;
347
+ }
348
+ get editingRow() {
349
+ return this.stateController.editing.activeRow?.rowIndex ?? null;
350
+ }
351
+ editCell(rowIndex, columnKey) {
352
+ return this.stateController.editing.editCell(rowIndex, columnKey);
353
+ }
354
+ editRow(rowIndex) {
355
+ return this.stateController.editing.editRow(rowIndex);
356
+ }
357
+ commitEdit() {
358
+ const editing = this.stateController.editing;
359
+ return editing.mode === 'row' ? editing.commitRow() : editing.commitCell();
360
+ }
361
+ cancelEdit() {
362
+ const editing = this.stateController.editing;
363
+ if (editing.mode === 'row') {
364
+ editing.cancelRow();
365
+ }
366
+ else {
367
+ editing.cancelCell();
368
+ }
369
+ }
370
+ exportToCSV(options = {}) {
371
+ const csv = buildCSV(this, options);
372
+ const filename = options.filename;
373
+ if (filename) {
374
+ downloadBlob(`${filename}.csv`, csv, 'text/csv;charset=utf-8;');
375
+ }
376
+ else if (filename === undefined) {
377
+ downloadBlob('data.csv', csv, 'text/csv;charset=utf-8;');
378
+ }
379
+ return csv;
380
+ }
381
+ get exportFormats() {
382
+ return [{ id: 'csv', label: 'Export CSV' }];
383
+ }
384
+ exportAs(formatId, options = {}) {
385
+ if (formatId === 'csv') {
386
+ this.exportToCSV(options);
387
+ }
388
+ }
389
+ async moveColumn(fromKey, toKey, position = 'before') {
390
+ if (fromKey === toKey)
391
+ return false;
392
+ const fromIndex = this.columns.findIndex((column) => column.key === fromKey);
393
+ const toIndex = this.columns.findIndex((column) => column.key === toKey);
394
+ if (fromIndex < 0 || toIndex < 0)
395
+ return false;
396
+ const source = this.columns[fromIndex];
397
+ const target = this.columns[toIndex];
398
+ if ((source.pinned ?? null) !== (target.pinned ?? null))
399
+ return false;
400
+ const proceed = this.emitEvent('columnMoving', {
401
+ detail: { key: fromKey, fromIndex, toKey, position },
402
+ cancelable: true,
403
+ });
404
+ if (!proceed)
405
+ return false;
406
+ const next = this.columns.slice();
407
+ const [moved] = next.splice(fromIndex, 1);
408
+ let insertIndex = next.findIndex((column) => column.key === toKey);
409
+ if (insertIndex < 0)
410
+ return false;
411
+ if (position === 'after')
412
+ insertIndex += 1;
413
+ next.splice(insertIndex, 0, moved);
414
+ if (next.every((column, index) => column === this.columns[index]))
415
+ return false;
416
+ this.columns = next;
417
+ await this.updateComplete;
418
+ const resolvedIndex = this.columns.findIndex((column) => column.key === fromKey);
419
+ this.emitEvent('columnMoved', {
420
+ detail: { key: fromKey, fromIndex, toIndex: resolvedIndex },
421
+ });
422
+ return true;
423
+ }
136
424
  bodyClickHandler(event) {
137
425
  const target = event.composedPath().find((el) => el instanceof ApexGridCell);
138
426
  if (target) {
@@ -151,14 +439,15 @@ export class ApexGrid extends EventEmitterBase {
151
439
  return html `
152
440
  <apex-grid-header-row
153
441
  style=${styleMap(this.DOM.columnSizes)}
154
- .columns=${this.columns}
442
+ .columns=${this.DOM.displayColumns}
443
+ .pinOffsets=${this.DOM.pinOffsets}
155
444
  ></apex-grid-header-row>
156
445
  `;
157
446
  }
158
447
  renderBody() {
159
448
  return html `
160
449
  <apex-virtualizer
161
- .items=${this.dataState}
450
+ .items=${this.pageItems}
162
451
  .renderItem=${this.DOM.rowRenderer}
163
452
  @click=${this.bodyClickHandler}
164
453
  @keydown=${this.bodyKeydownHandler}
@@ -170,14 +459,52 @@ export class ApexGrid extends EventEmitterBase {
170
459
  ? html `<apex-filter-row style=${styleMap(this.DOM.columnSizes)}></apex-filter-row>`
171
460
  : nothing;
172
461
  }
462
+ renderToolbar() {
463
+ if (!this.showQuickFilter && !this.showExport)
464
+ return nothing;
465
+ return html `<apex-grid-toolbar
466
+ .value=${this.quickFilter}
467
+ .showQuickFilter=${this.showQuickFilter}
468
+ .showExport=${this.showExport}
469
+ @apex-quick-filter=${(event) => {
470
+ event.stopPropagation();
471
+ this.setQuickFilter(event.detail);
472
+ }}
473
+ ></apex-grid-toolbar>`;
474
+ }
475
+ renderPaginator() {
476
+ if (!this.stateController.pagination.enabled)
477
+ return nothing;
478
+ const options = this.pagination?.pageSizeOptions && this.pagination.pageSizeOptions.length > 0
479
+ ? this.pagination.pageSizeOptions
480
+ : [10, 25, 50, 100];
481
+ return html `<apex-grid-paginator .pageSizeOptions=${options}></apex-grid-paginator>`;
482
+ }
483
+ renderLiveRegion() {
484
+ return html `<div
485
+ part="live-region"
486
+ role="status"
487
+ aria-live="polite"
488
+ aria-atomic="true"
489
+ style="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;"
490
+ >
491
+ ${this.stateController.announcement}
492
+ </div>`;
493
+ }
173
494
  render() {
174
495
  return html `
175
496
  ${this.stateController.resizing.renderIndicator()}
497
+ ${this.renderToolbar()}
176
498
  ${this.renderHeaderRow()}
177
499
  ${this.renderFilterRow()}
178
500
  ${this.renderBody()}
501
+ ${this.renderPaginator()}
502
+ ${this.renderLiveRegion()}
179
503
  `;
180
504
  }
505
+ announce(message) {
506
+ this.stateController.setAnnouncement(message);
507
+ }
181
508
  }
182
509
  __decorate([
183
510
  query(ApexVirtualizer.tagName)
@@ -188,6 +515,12 @@ __decorate([
188
515
  __decorate([
189
516
  query(ApexFilterRow.tagName)
190
517
  ], ApexGrid.prototype, "filterRow", void 0);
518
+ __decorate([
519
+ query(ApexGridPaginator.tagName)
520
+ ], ApexGrid.prototype, "paginator", void 0);
521
+ __decorate([
522
+ query(ApexGridToolbar.tagName)
523
+ ], ApexGrid.prototype, "toolbar", void 0);
191
524
  __decorate([
192
525
  state()
193
526
  ], ApexGrid.prototype, "dataState", void 0);
@@ -209,12 +542,45 @@ __decorate([
209
542
  __decorate([
210
543
  property({ attribute: false })
211
544
  ], ApexGrid.prototype, "dataPipelineConfiguration", void 0);
545
+ __decorate([
546
+ property({ attribute: false })
547
+ ], ApexGrid.prototype, "pagination", void 0);
548
+ __decorate([
549
+ property({ type: String, attribute: 'quick-filter' })
550
+ ], ApexGrid.prototype, "quickFilter", void 0);
551
+ __decorate([
552
+ property({ type: Boolean, attribute: 'show-quick-filter' })
553
+ ], ApexGrid.prototype, "showQuickFilter", void 0);
554
+ __decorate([
555
+ property({ type: Boolean, attribute: 'show-export' })
556
+ ], ApexGrid.prototype, "showExport", void 0);
557
+ __decorate([
558
+ property({ type: Boolean, attribute: 'column-reordering' })
559
+ ], ApexGrid.prototype, "columnReordering", void 0);
560
+ __decorate([
561
+ property({ attribute: false })
562
+ ], ApexGrid.prototype, "editing", void 0);
563
+ __decorate([
564
+ property({ attribute: false })
565
+ ], ApexGrid.prototype, "selection", void 0);
566
+ __decorate([
567
+ property({ attribute: false })
568
+ ], ApexGrid.prototype, "expansion", void 0);
569
+ __decorate([
570
+ property({ attribute: false })
571
+ ], ApexGrid.prototype, "tree", void 0);
212
572
  __decorate([
213
573
  property({ attribute: false })
214
574
  ], ApexGrid.prototype, "sortExpressions", null);
215
575
  __decorate([
216
576
  property({ attribute: false })
217
577
  ], ApexGrid.prototype, "filterExpressions", null);
578
+ __decorate([
579
+ property({ attribute: false })
580
+ ], ApexGrid.prototype, "page", null);
581
+ __decorate([
582
+ property({ attribute: false })
583
+ ], ApexGrid.prototype, "pageSize", null);
218
584
  __decorate([
219
585
  watch('columns')
220
586
  ], ApexGrid.prototype, "watchColumns", null);
@@ -224,6 +590,12 @@ __decorate([
224
590
  __decorate([
225
591
  watch(PIPELINE)
226
592
  ], ApexGrid.prototype, "pipeline", null);
593
+ __decorate([
594
+ watch('pagination')
595
+ ], ApexGrid.prototype, "paginationChanged", null);
596
+ __decorate([
597
+ watch('quickFilter')
598
+ ], ApexGrid.prototype, "quickFilterChanged", null);
227
599
  __decorate([
228
600
  eventOptions({ capture: true })
229
601
  ], ApexGrid.prototype, "bodyClickHandler", null);