@highcharts/grid-pro 2.0.1 → 2.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.
Files changed (164) hide show
  1. package/css/grid-pro.css +69 -85
  2. package/es-modules/Accessibility/Components/SeriesComponent/ForcedMarkers.js +2 -0
  3. package/es-modules/Accessibility/Options/LangDefaults.js +6 -1
  4. package/es-modules/Accessibility/Utils/ChartUtilities.js +3 -3
  5. package/es-modules/Core/Color/ColorString.d.ts +25 -0
  6. package/es-modules/Core/Color/ColorType.d.ts +43 -0
  7. package/es-modules/Core/Color/GradientColor.d.ts +57 -0
  8. package/es-modules/Core/Globals.js +1 -1
  9. package/es-modules/Core/Renderer/AlignObject.d.ts +37 -0
  10. package/es-modules/Core/Renderer/BBoxObject.d.ts +40 -0
  11. package/es-modules/Core/Renderer/CSSObject.d.ts +130 -0
  12. package/es-modules/Core/Renderer/DOMElementType.d.ts +36 -0
  13. package/es-modules/Core/Renderer/DashStyleValue.d.ts +28 -0
  14. package/es-modules/Core/Renderer/FontMetricsObject.d.ts +38 -0
  15. package/es-modules/Core/Renderer/HTML/HTMLAttributes.d.ts +57 -0
  16. package/es-modules/Core/Renderer/PolygonBoxObject.d.ts +19 -0
  17. package/es-modules/Core/Renderer/Position3DObject.d.ts +35 -0
  18. package/es-modules/Core/Renderer/PositionObject.d.ts +28 -0
  19. package/es-modules/Core/Renderer/RectangleObject.d.ts +35 -0
  20. package/es-modules/Core/Renderer/RendererType.d.ts +53 -0
  21. package/es-modules/Core/Renderer/SVG/ButtonThemeObject.d.ts +43 -0
  22. package/es-modules/Core/Renderer/SVG/SVGArc3D.d.ts +44 -0
  23. package/es-modules/Core/Renderer/SVG/SVGAttributes.d.ts +147 -0
  24. package/es-modules/Core/Renderer/SVG/SVGAttributes3D.d.ts +42 -0
  25. package/es-modules/Core/Renderer/SVG/SVGCuboid.d.ts +42 -0
  26. package/es-modules/Core/Renderer/SVG/SVGElementBase.d.ts +31 -0
  27. package/es-modules/Core/Renderer/SVG/SVGPath.d.ts +97 -0
  28. package/es-modules/Core/Renderer/SVG/SVGPath3D.d.ts +40 -0
  29. package/es-modules/Core/Renderer/SVG/SVGRendererBase.d.ts +31 -0
  30. package/es-modules/Core/Renderer/SVG/SymbolOptions.d.ts +41 -0
  31. package/es-modules/Core/Renderer/SVG/SymbolType.d.ts +50 -0
  32. package/es-modules/Core/Renderer/ShadowOptionsObject.d.ts +40 -0
  33. package/es-modules/Core/Renderer/SizeObject.d.ts +28 -0
  34. package/es-modules/Core/Templating.js +6 -7
  35. package/es-modules/Data/Connectors/DataConnector.js +3 -2
  36. package/es-modules/Data/Connectors/DataConnectorOptions.d.ts +1 -1
  37. package/es-modules/Data/DataTable.d.ts +1 -1
  38. package/es-modules/Data/DataTable.js +3 -2
  39. package/es-modules/Data/DataTableCore.js +15 -6
  40. package/es-modules/Grid/Core/Accessibility/Accessibility.d.ts +13 -15
  41. package/es-modules/Grid/Core/Credits.d.ts +0 -2
  42. package/es-modules/Grid/Core/Defaults.d.ts +20 -17
  43. package/es-modules/Grid/Core/Defaults.js +116 -114
  44. package/es-modules/Grid/Core/Globals.d.ts +108 -32
  45. package/es-modules/Grid/Core/Globals.js +98 -111
  46. package/es-modules/Grid/Core/Grid.d.ts +51 -17
  47. package/es-modules/Grid/Core/Grid.js +369 -79
  48. package/es-modules/Grid/Core/GridUtils.d.ts +96 -89
  49. package/es-modules/Grid/Core/GridUtils.js +143 -155
  50. package/es-modules/Grid/Core/Options.d.ts +3 -7
  51. package/es-modules/Grid/Core/Pagination/Icons.d.ts +4 -4
  52. package/es-modules/Grid/Core/Pagination/Pagination.d.ts +32 -57
  53. package/es-modules/Grid/Core/Pagination/Pagination.js +206 -214
  54. package/es-modules/Grid/Core/Pagination/PaginationOptions.d.ts +22 -15
  55. package/es-modules/Grid/Core/Querying/PaginationController.d.ts +32 -9
  56. package/es-modules/Grid/Core/Querying/PaginationController.js +58 -18
  57. package/es-modules/Grid/Core/Querying/SortingController.d.ts +7 -15
  58. package/es-modules/Grid/Core/Querying/SortingController.js +2 -3
  59. package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/ColumnFiltering.d.ts +1 -1
  60. package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/ColumnFiltering.js +32 -4
  61. package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/FilteringTypes.d.ts +3 -3
  62. package/es-modules/Grid/Core/Table/Actions/ColumnSorting.d.ts +3 -5
  63. package/es-modules/Grid/Core/Table/Actions/ColumnSorting.js +1 -5
  64. package/es-modules/Grid/Core/Table/Body/TableCell.d.ts +14 -10
  65. package/es-modules/Grid/Core/Table/Body/TableCell.js +19 -21
  66. package/es-modules/Grid/Core/Table/Body/TableRow.d.ts +0 -2
  67. package/es-modules/Grid/Core/Table/Cell.js +30 -0
  68. package/es-modules/Grid/Core/Table/CellContent/TextContent.d.ts +2 -7
  69. package/es-modules/Grid/Core/Table/CellContent/TextContent.js +25 -14
  70. package/es-modules/Grid/Core/Table/Column.d.ts +7 -9
  71. package/es-modules/Grid/Core/Table/Column.js +23 -1
  72. package/es-modules/Grid/Core/Table/ColumnResizing/AdjacentResizingMode.js +2 -2
  73. package/es-modules/Grid/Core/Table/ColumnResizing/ColumnResizing.d.ts +30 -23
  74. package/es-modules/Grid/Core/Table/ColumnResizing/ColumnResizing.js +39 -39
  75. package/es-modules/Grid/Core/Table/ColumnResizing/DistributedResizingMode.js +1 -1
  76. package/es-modules/Grid/Core/Table/ColumnResizing/IndependentResizingMode.js +2 -2
  77. package/es-modules/Grid/Core/Table/ColumnResizing/ResizingMode.d.ts +6 -1
  78. package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ColumnToolbar.js +10 -0
  79. package/es-modules/Grid/Core/Table/Header/ColumnToolbar/FilterPopup.d.ts +2 -2
  80. package/es-modules/Grid/Core/Table/Header/ColumnToolbar/StateHelpers.d.ts +26 -24
  81. package/es-modules/Grid/Core/Table/Header/ColumnToolbar/StateHelpers.js +37 -39
  82. package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ToolbarButtons/FilterToolbarButton.d.ts +1 -1
  83. package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ToolbarButtons/MenuToolbarButton.d.ts +1 -1
  84. package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ToolbarButtons/SortToolbarButton.d.ts +1 -1
  85. package/es-modules/Grid/Core/Table/Header/HeaderRow.d.ts +0 -2
  86. package/es-modules/Grid/Core/Table/Header/TableHeader.d.ts +0 -2
  87. package/es-modules/Grid/Core/Table/Table.d.ts +11 -13
  88. package/es-modules/Grid/Core/Table/Table.js +9 -5
  89. package/es-modules/Grid/Core/UI/Button.d.ts +1 -1
  90. package/es-modules/Grid/Core/UI/ContextMenu.d.ts +1 -1
  91. package/es-modules/Grid/Core/UI/ContextMenu.js +1 -1
  92. package/es-modules/Grid/Core/UI/ContextMenuButton.d.ts +39 -44
  93. package/es-modules/Grid/Core/UI/ContextMenuButton.js +4 -4
  94. package/es-modules/Grid/Core/UI/Popup.d.ts +17 -19
  95. package/es-modules/Grid/Core/UI/Popup.js +2 -1
  96. package/es-modules/Grid/Core/UI/SvgIcons.d.ts +49 -50
  97. package/es-modules/Grid/Core/UI/SvgIcons.js +114 -123
  98. package/es-modules/Grid/Core/UI/ToolbarButton.d.ts +46 -52
  99. package/es-modules/Grid/Core/UI/ToolbarButton.js +4 -3
  100. package/es-modules/Grid/Pro/CellEditing/CellEditing.d.ts +6 -8
  101. package/es-modules/Grid/Pro/CellEditing/CellEditing.js +8 -11
  102. package/es-modules/Grid/Pro/CellEditing/CellEditingComposition.d.ts +27 -1
  103. package/es-modules/Grid/Pro/CellEditing/CellEditingComposition.js +149 -149
  104. package/es-modules/Grid/Pro/CellRendering/CellRenderer.d.ts +18 -20
  105. package/es-modules/Grid/Pro/CellRendering/CellRenderer.js +1 -1
  106. package/es-modules/Grid/Pro/CellRendering/CellRendererRegistry.d.ts +19 -17
  107. package/es-modules/Grid/Pro/CellRendering/CellRendererRegistry.js +28 -34
  108. package/es-modules/Grid/Pro/CellRendering/CellRenderersComposition.d.ts +12 -1
  109. package/es-modules/Grid/Pro/CellRendering/CellRenderersComposition.js +41 -46
  110. package/es-modules/Grid/Pro/CellRendering/ContentTypes/CheckboxContent.js +2 -2
  111. package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateInputContent.d.ts +2 -2
  112. package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateInputContentBase.d.ts +2 -2
  113. package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateInputContentBase.js +4 -2
  114. package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateTimeInputContent.d.ts +2 -2
  115. package/es-modules/Grid/Pro/CellRendering/ContentTypes/NumberInputContent.js +3 -1
  116. package/es-modules/Grid/Pro/CellRendering/ContentTypes/SelectContent.js +3 -1
  117. package/es-modules/Grid/Pro/CellRendering/ContentTypes/SparklineContent.d.ts +19 -8
  118. package/es-modules/Grid/Pro/CellRendering/ContentTypes/SparklineContent.js +17 -13
  119. package/es-modules/Grid/Pro/CellRendering/ContentTypes/TextInputContent.js +3 -1
  120. package/es-modules/Grid/Pro/CellRendering/ContentTypes/TimeInputContent.d.ts +2 -2
  121. package/es-modules/Grid/Pro/CellRendering/Renderers/CheckboxRenderer.d.ts +18 -20
  122. package/es-modules/Grid/Pro/CellRendering/Renderers/CheckboxRenderer.js +3 -3
  123. package/es-modules/Grid/Pro/CellRendering/Renderers/DateInputRenderer.d.ts +10 -12
  124. package/es-modules/Grid/Pro/CellRendering/Renderers/DateInputRenderer.js +3 -3
  125. package/es-modules/Grid/Pro/CellRendering/Renderers/DateInputRendererBase.d.ts +17 -20
  126. package/es-modules/Grid/Pro/CellRendering/Renderers/DateTimeInputRenderer.d.ts +10 -12
  127. package/es-modules/Grid/Pro/CellRendering/Renderers/DateTimeInputRenderer.js +3 -3
  128. package/es-modules/Grid/Pro/CellRendering/Renderers/NumberInputRenderer.d.ts +20 -22
  129. package/es-modules/Grid/Pro/CellRendering/Renderers/NumberInputRenderer.js +3 -3
  130. package/es-modules/Grid/Pro/CellRendering/Renderers/SelectRenderer.d.ts +40 -42
  131. package/es-modules/Grid/Pro/CellRendering/Renderers/SelectRenderer.js +3 -3
  132. package/es-modules/Grid/Pro/CellRendering/Renderers/SparklineRenderer.d.ts +16 -18
  133. package/es-modules/Grid/Pro/CellRendering/Renderers/SparklineRenderer.js +14 -22
  134. package/es-modules/Grid/Pro/CellRendering/Renderers/TextInputRenderer.d.ts +22 -24
  135. package/es-modules/Grid/Pro/CellRendering/Renderers/TextInputRenderer.js +3 -3
  136. package/es-modules/Grid/Pro/CellRendering/Renderers/TextRenderer.d.ts +10 -12
  137. package/es-modules/Grid/Pro/CellRendering/Renderers/TextRenderer.js +3 -3
  138. package/es-modules/Grid/Pro/CellRendering/Renderers/TimeInputRenderer.d.ts +10 -12
  139. package/es-modules/Grid/Pro/CellRendering/Renderers/TimeInputRenderer.js +3 -3
  140. package/es-modules/Grid/Pro/ColumnTypes/Validator.d.ts +46 -51
  141. package/es-modules/Grid/Pro/ColumnTypes/Validator.js +62 -77
  142. package/es-modules/Grid/Pro/ColumnTypes/ValidatorComposition.d.ts +16 -3
  143. package/es-modules/Grid/Pro/ColumnTypes/ValidatorComposition.js +26 -31
  144. package/es-modules/Grid/Pro/Credits/CreditsPro.d.ts +0 -2
  145. package/es-modules/Grid/Pro/Credits/CreditsProComposition.d.ts +12 -11
  146. package/es-modules/Grid/Pro/Credits/CreditsProComposition.js +29 -31
  147. package/es-modules/Grid/Pro/Export/Exporting.d.ts +3 -3
  148. package/es-modules/Grid/Pro/Export/Exporting.js +35 -29
  149. package/es-modules/Grid/Pro/Export/ExportingComposition.d.ts +12 -11
  150. package/es-modules/Grid/Pro/Export/ExportingComposition.js +24 -26
  151. package/es-modules/Grid/Pro/GridEvents.d.ts +19 -1
  152. package/es-modules/Grid/Pro/GridEvents.js +6 -2
  153. package/es-modules/Grid/Pro/Pagination/PaginationComposition.d.ts +4 -11
  154. package/es-modules/Grid/Pro/Pagination/PaginationComposition.js +44 -45
  155. package/es-modules/Grid/index.d.ts +1 -0
  156. package/es-modules/masters/grid-pro.src.d.ts +62 -37
  157. package/es-modules/masters/grid-pro.src.js +37 -39
  158. package/grid-pro.d.ts +122 -48
  159. package/grid-pro.js +3 -6
  160. package/grid-pro.js.map +1 -1
  161. package/grid-pro.src.d.ts +122 -48
  162. package/grid-pro.src.js +6645 -6270
  163. package/package.json +13 -4
  164. package/es-modules/Grid/Pro/ColumnTypes/ColumnDataType.d.ts +0 -29
@@ -14,13 +14,12 @@
14
14
  * */
15
15
  'use strict';
16
16
  import Icons from './Icons.js';
17
- import Defaults from '../Defaults.js';
18
17
  import Globals from '../Globals.js';
19
18
  import GridUtils from '../GridUtils.js';
20
19
  import Utilities from '../../../Core/Utilities.js';
21
20
  import AST from '../../../Core/Renderer/HTML/AST.js';
22
21
  const { makeHTMLElement, formatText } = GridUtils;
23
- const { merge, fireEvent, isObject, defined } = Utilities;
22
+ const { defined, fireEvent, isObject, merge } = Utilities;
24
23
  /**
25
24
  * Representing the pagination functionalities for the Grid.
26
25
  */
@@ -35,35 +34,10 @@ class Pagination {
35
34
  *
36
35
  * @param grid
37
36
  * The Grid Table instance which the pagination controller belongs to.
38
- *
39
- * @param options
40
- * The Pagination user options.
41
- *
42
- * @param state
43
- * The Pagination state. Used to restore the previous state after the Grid
44
- * is destroyed.
45
- */
46
- constructor(grid, options, state = {}) {
47
- /**
48
- * Current page number, starting from 1.
49
- */
50
- this.currentPage = 1;
37
+ */
38
+ constructor(grid) {
51
39
  this.grid = grid;
52
- this.options = merge(Pagination.defaultOptions, options);
53
- const pageSizeSelector = this.options.controls.pageSizeSelector;
54
- this.pageSizeOptions = isObject(pageSizeSelector) ?
55
- pageSizeSelector.options :
56
- Pagination.defaultOptions.controls.pageSizeSelector.options; // eslint-disable-line
57
- this.currentPageSize =
58
- state.currentPageSize ||
59
- this.options.pageSize ||
60
- this.pageSizeOptions[0];
61
- // Lang pack
62
- this.lang = merge(Defaults.defaultOptions.pagination, this.grid.options?.lang?.pagination);
63
- // Set state
64
- if (state.currentPage) {
65
- this.currentPage = state.currentPage;
66
- }
40
+ this.controller = grid.querying.pagination;
67
41
  }
68
42
  /* *
69
43
  *
@@ -71,16 +45,48 @@ class Pagination {
71
45
  *
72
46
  * */
73
47
  /**
74
- * Total number of items (rows)
48
+ * Returns the reference to the pagination options.
49
+ */
50
+ get options() {
51
+ return this.grid.options?.pagination;
52
+ }
53
+ /**
54
+ * Returns the language options for pagination text.
55
+ */
56
+ get lang() {
57
+ return this.grid.options?.lang?.pagination;
58
+ }
59
+ /**
60
+ * Returns the page size selector options.
75
61
  */
76
- get totalItems() {
77
- return this.grid.querying.pagination.totalItems || 0;
62
+ get pageSizeSelectorOptions() {
63
+ const raw = this.options?.controls?.pageSizeSelector;
64
+ if (isObject(raw)) {
65
+ return raw.options ?? [];
66
+ }
67
+ return (Pagination.defaultOptions
68
+ .controls?.pageSizeSelector).options ?? [];
78
69
  }
79
70
  /**
80
- * Total number of pages
71
+ * Internal method to set the dirty flags for the pagination based on the
72
+ * options differences.
73
+ *
74
+ * @param diff
75
+ * The differences between the previous and the new options.
76
+ *
77
+ * @internal
81
78
  */
82
- get totalPages() {
83
- return Math.ceil(this.totalItems / this.currentPageSize) || 1;
79
+ update(diff) {
80
+ if ('page' in diff ||
81
+ 'pageSize' in diff) {
82
+ this.isDirtyQuerying = true;
83
+ delete diff.page;
84
+ delete diff.pageSize;
85
+ }
86
+ // TODO: Optimize more options here.
87
+ if (Object.keys(diff).length > 0) {
88
+ this.grid.dirtyFlags.add('grid');
89
+ }
84
90
  }
85
91
  /**
86
92
  * Render the pagination container.
@@ -93,12 +99,12 @@ class Pagination {
93
99
  * the specified ID.
94
100
  */
95
101
  render() {
96
- const position = this.options.position;
102
+ const position = this.options?.position;
97
103
  const grid = this.grid;
98
- this.oldTotalItems = this.totalItems;
104
+ this.oldTotalItems = this.controller.totalItems;
99
105
  // Set row count for a11y
100
106
  grid.tableElement?.setAttribute('aria-current', 'page');
101
- this.updateA11yRowsCount(this.currentPageSize);
107
+ this.updateA11yRowsCount(this.controller.currentPageSize);
102
108
  // Render pagination container
103
109
  if (typeof position === 'string' && position.startsWith('#')) {
104
110
  this.renderCustomContainer(position);
@@ -113,8 +119,6 @@ class Pagination {
113
119
  this.paginationContainer : grid.contentWrapper);
114
120
  this.contentWrapper.setAttribute('aria-label', 'Results pagination');
115
121
  }
116
- // Clamps the current page to the valid range
117
- this.clampCurrentPage();
118
122
  // Render all components
119
123
  this.renderPageInfo();
120
124
  this.renderControls();
@@ -161,7 +165,7 @@ class Pagination {
161
165
  * Render the page information text.
162
166
  */
163
167
  renderPageInfo() {
164
- const pageInfo = this.options.controls?.pageInfo;
168
+ const pageInfo = this.options?.controls?.pageInfo;
165
169
  if (pageInfo === false ||
166
170
  (isObject(pageInfo) && pageInfo.enabled === false)) {
167
171
  return;
@@ -178,14 +182,15 @@ class Pagination {
178
182
  if (!this.pageInfoElement) {
179
183
  return;
180
184
  }
181
- const startItem = (this.currentPage - 1) * this.currentPageSize + 1;
182
- const endItem = Math.min(this.currentPage * this.currentPageSize, this.totalItems);
183
- const pageInfoText = formatText(this.lang.pageInfo, {
185
+ const { currentPage, currentPageSize, totalItems, totalPages } = this.controller;
186
+ const startItem = (currentPage - 1) * currentPageSize + 1;
187
+ const endItem = Math.min(currentPage * currentPageSize, totalItems);
188
+ const pageInfoText = formatText(this.lang?.pageInfo ?? '', {
184
189
  start: startItem,
185
190
  end: endItem,
186
- total: this.totalItems,
187
- currentPage: this.currentPage,
188
- totalPages: this.totalPages
191
+ total: totalItems,
192
+ currentPage: currentPage,
193
+ totalPages: totalPages
189
194
  });
190
195
  this.pageInfoElement.innerHTML = pageInfoText;
191
196
  }
@@ -194,43 +199,50 @@ class Pagination {
194
199
  */
195
200
  renderControls() {
196
201
  const navContainer = makeHTMLElement('div', {
197
- className: Globals.getClassName('paginationControls')
202
+ className: Globals.getClassName('paginationControlsContainer')
198
203
  }, this.contentWrapper);
204
+ const controls = this.options?.controls || {};
199
205
  // Render first/previous buttons
200
- if (this.options.controls?.firstLastButtons) {
206
+ if (controls.firstLastButtons) {
201
207
  this.renderFirstButton(navContainer);
202
208
  }
203
209
  // Render previous button
204
- if (this.options.controls?.previousNextButtons) {
210
+ if (controls.previousNextButtons) {
205
211
  this.renderPrevButton(navContainer);
206
212
  }
207
213
  // Render page numbers
208
- if (this.options.controls?.pageButtons) {
214
+ if (controls.pageButtons) {
209
215
  this.renderPageNumbers(navContainer);
210
216
  }
211
- // Render mobile page selector
212
- this.renderMobilePageSelector(navContainer);
217
+ // Render dropdown page selector
218
+ this.renderDropdownPageSelector(navContainer);
213
219
  // Render next button
214
- if (this.options.controls?.previousNextButtons) {
220
+ if (controls.previousNextButtons) {
215
221
  this.renderNextButton(navContainer);
216
222
  }
217
223
  // Render last/first buttons
218
- if (this.options.controls?.firstLastButtons) {
224
+ if (controls.firstLastButtons) {
219
225
  this.renderLastButton(navContainer);
220
226
  }
221
227
  }
222
228
  /**
223
229
  * Update the pagination controls.
230
+ *
231
+ * @param force
232
+ * Whether to force update the controls.
233
+ *
234
+ * @internal
224
235
  */
225
- updateControls() {
226
- if (this.oldTotalItems === this.totalItems) {
236
+ updateControls(force = false) {
237
+ const { totalItems, currentPageSize } = this.controller;
238
+ if (this.oldTotalItems === this.controller.totalItems && !force) {
227
239
  return;
228
240
  }
229
241
  this.updatePageInfo();
230
242
  this.updatePageNumbers();
231
243
  this.updateButtonStates();
232
- this.updateA11yRowsCount(this.currentPageSize);
233
- this.oldTotalItems = this.totalItems;
244
+ this.updateA11yRowsCount(currentPageSize);
245
+ this.oldTotalItems = totalItems;
234
246
  }
235
247
  /**
236
248
  * Render the first page button.
@@ -240,25 +252,24 @@ class Pagination {
240
252
  *
241
253
  */
242
254
  renderFirstButton(container) {
243
- const firstLastButtons = this.options.controls?.firstLastButtons;
255
+ const firstLastButtons = this.options?.controls?.firstLastButtons;
244
256
  if (firstLastButtons === false ||
245
257
  (isObject(firstLastButtons) && firstLastButtons.enabled === false)) {
246
258
  return;
247
259
  }
248
260
  // Create first button
249
261
  this.firstButton = makeHTMLElement('button', {
250
- innerHTML: Icons.first,
251
- className: Globals.getClassName('paginationButton') + ' ' +
252
- Globals.getClassName('paginationFirstButton')
262
+ className: Globals.getClassName('button'),
263
+ innerHTML: Icons.first
253
264
  }, container);
254
- this.firstButton.title = this.lang.firstPage;
265
+ this.firstButton.title = this.lang?.firstPage ?? '';
255
266
  // Set aria-label for a11y
256
- this.firstButton.setAttribute('aria-label', this.lang.firstPage);
267
+ this.firstButton.setAttribute('aria-label', this.lang?.firstPage ?? '');
257
268
  // Add click event
258
269
  this.firstButton.addEventListener('click', () => {
259
270
  void this.goToPage(1);
260
271
  });
261
- this.setButtonState(this.firstButton, this.currentPage === 1);
272
+ this.setButtonState(this.firstButton, this.controller.currentPage === 1);
262
273
  }
263
274
  /**
264
275
  * Render the previous page button.
@@ -267,7 +278,7 @@ class Pagination {
267
278
  * The container element for the previous page button.
268
279
  */
269
280
  renderPrevButton(container) {
270
- const previousNextButtons = this.options.controls?.previousNextButtons;
281
+ const previousNextButtons = this.options?.controls?.previousNextButtons;
271
282
  if (previousNextButtons === false ||
272
283
  (isObject(previousNextButtons) &&
273
284
  previousNextButtons.enabled === false)) {
@@ -275,18 +286,17 @@ class Pagination {
275
286
  }
276
287
  // Create previous button
277
288
  this.prevButton = makeHTMLElement('button', {
278
- innerHTML: Icons.previous,
279
- className: Globals.getClassName('paginationButton') + ' ' +
280
- Globals.getClassName('paginationPrevButton')
289
+ className: Globals.getClassName('button'),
290
+ innerHTML: Icons.previous
281
291
  }, container);
282
- this.prevButton.title = this.lang.previousPage;
292
+ this.prevButton.title = this.lang?.previousPage ?? '';
283
293
  // Set aria-label for a11y
284
- this.prevButton.setAttribute('aria-label', this.lang.previousPage);
294
+ this.prevButton.setAttribute('aria-label', this.lang?.previousPage ?? '');
285
295
  // Add click event
286
296
  this.prevButton.addEventListener('click', () => {
287
- void this.goToPage(this.currentPage - 1);
297
+ void this.goToPage(this.controller.currentPage - 1);
288
298
  });
289
- this.setButtonState(this.prevButton, this.currentPage === 1);
299
+ this.setButtonState(this.prevButton, this.controller.currentPage === 1);
290
300
  }
291
301
  /**
292
302
  * Render the next page button.
@@ -295,7 +305,7 @@ class Pagination {
295
305
  * The container element for the next page button.
296
306
  */
297
307
  renderNextButton(container) {
298
- const previousNextButtons = this.options.controls?.previousNextButtons;
308
+ const previousNextButtons = this.options?.controls?.previousNextButtons;
299
309
  if (previousNextButtons === false ||
300
310
  (isObject(previousNextButtons) &&
301
311
  previousNextButtons.enabled === false)) {
@@ -303,18 +313,17 @@ class Pagination {
303
313
  }
304
314
  // Create next button
305
315
  this.nextButton = makeHTMLElement('button', {
306
- innerHTML: Icons.next,
307
- className: Globals.getClassName('paginationButton') + ' ' +
308
- Globals.getClassName('paginationNextButton')
316
+ className: Globals.getClassName('button'),
317
+ innerHTML: Icons.next
309
318
  }, container);
310
- this.nextButton.title = this.lang.nextPage;
319
+ this.nextButton.title = this.lang?.nextPage ?? '';
311
320
  // Set aria-label for a11y
312
- this.nextButton.setAttribute('aria-label', this.lang.nextPage);
321
+ this.nextButton.setAttribute('aria-label', this.lang?.nextPage ?? '');
313
322
  // Add click event
314
323
  this.nextButton.addEventListener('click', () => {
315
- void this.goToPage(this.currentPage + 1);
324
+ void this.goToPage(this.controller.currentPage + 1);
316
325
  });
317
- this.setButtonState(this.nextButton, this.currentPage >= this.totalPages);
326
+ this.setButtonState(this.nextButton, this.controller.currentPage >= this.controller.totalPages);
318
327
  }
319
328
  /**
320
329
  * Render the last page button.
@@ -323,25 +332,24 @@ class Pagination {
323
332
  * The container element for the last page button.
324
333
  */
325
334
  renderLastButton(container) {
326
- const firstLastButtons = this.options.controls?.firstLastButtons;
335
+ const firstLastButtons = this.options?.controls?.firstLastButtons;
327
336
  if (firstLastButtons === false ||
328
337
  (isObject(firstLastButtons) && firstLastButtons.enabled === false)) {
329
338
  return;
330
339
  }
331
340
  // Create last button
332
341
  this.lastButton = makeHTMLElement('button', {
333
- innerHTML: Icons.last,
334
- className: Globals.getClassName('paginationButton') + ' ' +
335
- Globals.getClassName('paginationLastButton')
342
+ className: Globals.getClassName('button'),
343
+ innerHTML: Icons.last
336
344
  }, container);
337
- this.lastButton.title = this.lang.lastPage;
345
+ this.lastButton.title = this.lang?.lastPage ?? '';
338
346
  // Set aria-label for a11y
339
- this.lastButton.setAttribute('aria-label', this.lang.lastPage);
347
+ this.lastButton.setAttribute('aria-label', this.lang?.lastPage ?? '');
340
348
  // Add click event
341
349
  this.lastButton.addEventListener('click', () => {
342
- void this.goToPage(this.totalPages);
350
+ void this.goToPage(this.controller.totalPages);
343
351
  });
344
- this.setButtonState(this.lastButton, this.currentPage >= this.totalPages);
352
+ this.setButtonState(this.lastButton, this.controller.currentPage >= this.controller.totalPages);
345
353
  }
346
354
  /**
347
355
  * Render page number buttons with ellipsis.
@@ -350,13 +358,13 @@ class Pagination {
350
358
  * The container element for the page number buttons.
351
359
  */
352
360
  renderPageNumbers(container) {
353
- const pageButtons = this.options.controls?.pageButtons;
361
+ const pageButtons = this.options?.controls?.pageButtons;
354
362
  if (pageButtons === false ||
355
363
  (isObject(pageButtons) && pageButtons.enabled === false)) {
356
364
  return;
357
365
  }
358
366
  this.pageNumbersContainer = makeHTMLElement('div', {
359
- className: Globals.getClassName('paginationPageButton')
367
+ className: Globals.getClassName('paginationNavButtonsContainer')
360
368
  }, container);
361
369
  this.updatePageNumbers();
362
370
  }
@@ -369,12 +377,14 @@ class Pagination {
369
377
  }
370
378
  // Clear existing page numbers
371
379
  this.pageNumbersContainer.innerHTML = AST.emptyHTML;
372
- const pageButtons = this.options.controls?.pageButtons;
380
+ const pageButtons = this.options?.controls?.pageButtons;
373
381
  const maxPageNumbers = isObject(pageButtons) ?
374
382
  pageButtons.count :
375
- Pagination.defaultOptions.controls.pageButtons.count; // eslint-disable-line
376
- const totalPages = this.totalPages;
377
- const currentPage = this.currentPage;
383
+ (Pagination.defaultOptions.controls?.pageButtons).count; // eslint-disable-line
384
+ if (!maxPageNumbers) {
385
+ return;
386
+ }
387
+ const { totalPages, currentPage } = this.controller;
378
388
  if (totalPages <= maxPageNumbers) {
379
389
  // Show all page numbers if total pages is less than max
380
390
  for (let i = 1; i <= totalPages; i++) {
@@ -471,10 +481,8 @@ class Pagination {
471
481
  }
472
482
  });
473
483
  }
474
- // Update mobile selector if it exists
475
- if (this.mobilePageSelector) {
476
- this.mobilePageSelector.value = this.currentPage.toString();
477
- }
484
+ // Update dropdown selector if it exists
485
+ this.updateDropdownPageSelector();
478
486
  }
479
487
  /**
480
488
  * Create a page number button.
@@ -490,12 +498,16 @@ class Pagination {
490
498
  return;
491
499
  }
492
500
  const button = makeHTMLElement('button', {
493
- innerHTML: pageNumber.toString(),
494
- className: Globals.getClassName(isActive ? 'paginationPageButtonActive' : 'paginationPageButton')
501
+ className: Globals.getClassName('button'),
502
+ innerHTML: pageNumber.toString()
495
503
  }, this.pageNumbersContainer);
496
- button.title = formatText(this.lang.pageNumber, { page: pageNumber });
504
+ if (isActive) {
505
+ button.classList.add(Globals.getClassName('buttonSelected'));
506
+ button.setAttribute('aria-current', 'page');
507
+ }
508
+ button.title = formatText(this.lang?.pageNumber ?? '', { page: pageNumber });
497
509
  // Set aria-label for a11y
498
- button.setAttribute('aria-label', formatText(this.lang.pageNumber, { page: pageNumber }));
510
+ button.setAttribute('aria-label', formatText(this.lang?.pageNumber ?? '', { page: pageNumber }));
499
511
  // Add click event
500
512
  button.addEventListener('click', () => {
501
513
  void this.goToPage(pageNumber);
@@ -509,10 +521,9 @@ class Pagination {
509
521
  return;
510
522
  }
511
523
  const ellipsisElement = makeHTMLElement('span', {
512
- innerHTML: '...',
513
- className: Globals.getClassName('paginationEllipsis')
524
+ innerHTML: '...'
514
525
  }, this.pageNumbersContainer);
515
- ellipsisElement.title = this.lang.ellipsis;
526
+ ellipsisElement.title = this.lang?.ellipsis ?? '';
516
527
  // Set aria-label for a11y
517
528
  ellipsisElement.setAttribute('aria-hidden', true);
518
529
  }
@@ -520,26 +531,27 @@ class Pagination {
520
531
  * Render the page size selector.
521
532
  */
522
533
  renderPageSizeSelector() {
523
- const pageSizeSelector = this.options.controls.pageSizeSelector;
534
+ const pageSizeSelector = this.options?.controls?.pageSizeSelector;
524
535
  if (pageSizeSelector === false ||
525
536
  (isObject(pageSizeSelector) &&
526
537
  pageSizeSelector.enabled === false)) {
527
538
  return;
528
539
  }
529
540
  const container = makeHTMLElement('div', {
530
- className: Globals.getClassName('paginationPageSizeContainer')
541
+ className: Globals.getClassName('paginationPageSize')
531
542
  }, this.contentWrapper);
532
543
  makeHTMLElement('span', {
533
- innerHTML: this.lang.pageSizeLabel
544
+ innerHTML: this.lang?.pageSizeLabel ?? ''
534
545
  }, container);
535
546
  this.pageSizeSelect = makeHTMLElement('select', {
536
- className: Globals.getClassName('paginationPageSizeSelect')
547
+ className: Globals.getClassName('input'),
548
+ id: Globals.getClassName('paginationPageSize')
537
549
  }, container);
538
- this.pageSizeOptions.forEach((option) => {
550
+ this.pageSizeSelectorOptions.forEach((option) => {
539
551
  const optionElement = document.createElement('option');
540
552
  optionElement.value = option.toString();
541
553
  optionElement.innerHTML = option.toString();
542
- if (option === this.currentPageSize) {
554
+ if (option === this.controller.currentPageSize) {
543
555
  optionElement.selected = true;
544
556
  }
545
557
  this.pageSizeSelect?.appendChild(optionElement);
@@ -550,8 +562,19 @@ class Pagination {
550
562
  }
551
563
  void this.setPageSize(parseInt(this.pageSizeSelect.value, 10));
552
564
  });
553
- // Render mobile page size selector in the same container
554
- this.renderMobilePageSizeSelector(container);
565
+ }
566
+ /**
567
+ * Sets the new options for the pagination.
568
+ *
569
+ * @param newOptions
570
+ * The new options to set.
571
+ */
572
+ setOptions(newOptions) {
573
+ var _a, _b, _c;
574
+ const userOptions = (_a = this.grid.userOptions).pagination ?? (_a.pagination = {});
575
+ const options = ((_c = ((_b = this.grid).options ?? (_b.options = {}))).pagination ?? (_c.pagination = {}));
576
+ merge(true, userOptions, newOptions);
577
+ merge(true, options, newOptions);
555
578
  }
556
579
  /**
557
580
  * Set the page size and recalculate pagination.
@@ -560,15 +583,18 @@ class Pagination {
560
583
  * The new page size to set.
561
584
  */
562
585
  async setPageSize(newPageSize) {
563
- const pageSize = this.currentPageSize;
586
+ const oldPageSize = this.controller.currentPageSize;
564
587
  const langAccessibility = this.grid.options?.lang?.accessibility;
565
588
  fireEvent(this, 'beforePageSizeChange', {
566
- pageSize: pageSize,
589
+ pageSize: oldPageSize,
567
590
  newPageSize: newPageSize
568
591
  });
569
- this.currentPageSize = newPageSize;
570
- // Reset to first page when changing page size
571
- this.currentPage = 1;
592
+ this.controller.setPageSize(newPageSize);
593
+ this.controller.setPage(1);
594
+ this.setOptions({
595
+ pageSize: newPageSize,
596
+ page: 1
597
+ });
572
598
  // Update the grid's pagination range
573
599
  await this.updateGridPagination();
574
600
  // Update UI
@@ -576,17 +602,13 @@ class Pagination {
576
602
  this.updatePageNumbers();
577
603
  this.updateButtonStates();
578
604
  // Update row count for a11y
579
- this.updateA11yRowsCount(this.currentPageSize);
605
+ this.updateA11yRowsCount(this.controller.currentPageSize);
580
606
  // Announce the page size change
581
607
  this.grid.accessibility?.announce(langAccessibility?.pagination?.announcements?.pageSizeChange +
582
608
  ' ' + newPageSize);
583
- // Update mobile page size selector if it exists
584
- if (this.mobilePageSizeSelector) {
585
- this.mobilePageSizeSelector.value = this.currentPageSize.toString();
586
- }
587
609
  fireEvent(this, 'afterPageSizeChange', {
588
610
  pageSize: newPageSize,
589
- previousPageSize: pageSize
611
+ previousPageSize: oldPageSize
590
612
  });
591
613
  }
592
614
  /**
@@ -597,82 +619,64 @@ class Pagination {
597
619
  */
598
620
  async goToPage(pageNumber) {
599
621
  const langAccessibility = this.grid.options?.lang?.accessibility;
622
+ const { totalPages, currentPage, currentPageSize } = this.controller;
600
623
  if (pageNumber < 1 ||
601
- pageNumber > this.totalPages ||
602
- pageNumber === this.currentPage) {
624
+ pageNumber > totalPages ||
625
+ pageNumber === currentPage) {
603
626
  return;
604
627
  }
605
- const previousPage = this.currentPage;
628
+ const previousPage = currentPage;
606
629
  fireEvent(this, 'beforePageChange', {
607
- currentPage: this.currentPage,
630
+ currentPage: currentPage,
608
631
  nextPage: pageNumber,
609
- pageSize: this.currentPageSize
632
+ pageSize: currentPageSize
633
+ });
634
+ this.controller.setPage(pageNumber);
635
+ const newPage = this.controller.currentPage; // Take clamped page
636
+ this.setOptions({
637
+ page: newPage
610
638
  });
611
- this.currentPage = pageNumber;
612
639
  await this.updateGridPagination();
613
640
  this.updatePageInfo();
614
641
  this.updatePageNumbers();
615
642
  this.updateButtonStates();
616
643
  // Announce the page change
617
644
  this.grid.accessibility?.announce(langAccessibility?.pagination?.announcements?.pageChange +
618
- ' ' + this.currentPage);
645
+ ' ' + newPage);
619
646
  fireEvent(this, 'afterPageChange', {
620
- currentPage: this.currentPage,
647
+ currentPage: newPage,
621
648
  previousPage: previousPage,
622
- pageSize: this.currentPageSize
649
+ pageSize: currentPageSize
623
650
  });
624
651
  }
625
652
  /**
626
653
  * Update the grid's pagination state.
627
- *
628
- * @param ignoreDataRange
629
- * Whether to ignore the data range update. Used when updating the data
630
- * range is not needed, for example when updating the data range from
631
- * the server.
632
- * @internal
633
654
  */
634
- async updateGridPagination(ignoreDataRange = false) {
635
- if (!this.grid.querying?.pagination) {
636
- return;
637
- }
638
- this.grid.querying.pagination.setRange(ignoreDataRange ? 1 : this.currentPage);
639
- // Trigger the grid to update its data and viewport
640
- this.grid.querying.shouldBeUpdated = true;
641
- // Force the querying controller to proceed with updates
642
- await this.grid.querying.proceed(true);
655
+ async updateGridPagination() {
643
656
  // Update the viewport to reflect the new data
644
657
  await this.grid.viewport?.updateRows();
645
- this.grid.viewport?.header?.reflow();
646
658
  // Scroll to top after page change
647
659
  const tBody = this.grid.viewport?.tbodyElement;
648
660
  if (tBody) {
649
661
  tBody.scrollTop = 0;
650
662
  }
651
663
  }
652
- /**
653
- * Ensures the current page is within valid range.
654
- */
655
- clampCurrentPage() {
656
- if (this.currentPage > this.totalPages) {
657
- this.currentPage = this.totalPages;
658
- this.grid.querying.pagination.setRange(this.currentPage);
659
- }
660
- }
661
664
  /**
662
665
  * Update button states based on current page.
663
666
  */
664
667
  updateButtonStates() {
668
+ const { currentPage, totalPages } = this.controller;
665
669
  if (this.firstButton) {
666
- this.setButtonState(this.firstButton, this.currentPage === 1);
670
+ this.setButtonState(this.firstButton, currentPage === 1);
667
671
  }
668
672
  if (this.prevButton) {
669
- this.setButtonState(this.prevButton, this.currentPage === 1);
673
+ this.setButtonState(this.prevButton, currentPage === 1);
670
674
  }
671
675
  if (this.nextButton) {
672
- this.setButtonState(this.nextButton, this.currentPage >= this.totalPages);
676
+ this.setButtonState(this.nextButton, currentPage >= totalPages);
673
677
  }
674
678
  if (this.lastButton) {
675
- this.setButtonState(this.lastButton, this.currentPage >= this.totalPages);
679
+ this.setButtonState(this.lastButton, currentPage >= totalPages);
676
680
  }
677
681
  }
678
682
  /**
@@ -683,7 +687,8 @@ class Pagination {
683
687
  * @returns
684
688
  */
685
689
  async updatePage(isNextPage = true) {
686
- const newPage = isNextPage ? this.currentPage + 1 : this.currentPage - 1;
690
+ const { currentPage } = this.controller;
691
+ const newPage = isNextPage ? currentPage + 1 : currentPage - 1;
687
692
  await this.goToPage(newPage);
688
693
  }
689
694
  /**
@@ -697,11 +702,9 @@ class Pagination {
697
702
  */
698
703
  setButtonState(button, disabled) {
699
704
  if (disabled) {
700
- button.classList.add(Globals.getClassName('paginationButtonDisabled'));
701
705
  button.setAttribute('disabled', 'disabled');
702
706
  }
703
707
  else {
704
- button.classList.remove(Globals.getClassName('paginationButtonDisabled'));
705
708
  button.removeAttribute('disabled');
706
709
  }
707
710
  }
@@ -709,7 +712,7 @@ class Pagination {
709
712
  * Reflow the pagination container.
710
713
  */
711
714
  reflow() {
712
- const position = this.options.position;
715
+ const position = this.options?.position;
713
716
  if (!this.paginationContainer) {
714
717
  return;
715
718
  }
@@ -724,7 +727,7 @@ class Pagination {
724
727
  * Destroy the pagination instance.
725
728
  */
726
729
  destroy() {
727
- const position = this.options.position;
730
+ const position = this.options?.position;
728
731
  if (position === 'footer') {
729
732
  // For footer position, remove the entire tfoot element.
730
733
  this.paginationContainer?.parentElement?.parentElement?.remove();
@@ -732,64 +735,52 @@ class Pagination {
732
735
  else {
733
736
  this.contentWrapper?.remove();
734
737
  }
735
- this.grid.querying.pagination.reset();
736
738
  }
737
739
  /**
738
- * Render the mobile page selector (select dropdown).
740
+ * Render the dropdown page selector (select dropdown).
739
741
  *
740
742
  * @param container
741
- * The container element for the mobile page selector.
743
+ * The container element for the dropdown page selector.
742
744
  */
743
- renderMobilePageSelector(container) {
744
- const totalPages = this.totalPages;
745
- if (totalPages <= 1) {
745
+ renderDropdownPageSelector(container) {
746
+ if (this.controller.totalPages <= 1) {
746
747
  return;
747
748
  }
748
- const mobileSelect = makeHTMLElement('select', {
749
- className: Globals.getClassName('paginationMobileSelector')
749
+ const wrapper = makeHTMLElement('div', {
750
+ className: Globals.getClassName('paginationNavDropdown')
750
751
  }, container);
751
- // Add options for each page
752
- for (let i = 1; i <= totalPages; i++) {
753
- const option = makeHTMLElement('option', {}, mobileSelect);
754
- option.value = i.toString();
755
- option.textContent = `Page ${i} of ${totalPages}`;
756
- }
757
- // Set current page as selected
758
- mobileSelect.value = this.currentPage.toString();
759
- this.mobilePageSelector = mobileSelect;
752
+ const select = makeHTMLElement('select', {
753
+ className: Globals.getClassName('input'),
754
+ id: Globals.getClassName('paginationNavDropdown')
755
+ }, wrapper);
756
+ this.dropdownPageSelector = select;
757
+ this.updateDropdownPageSelector();
760
758
  // Add event listener for page change
761
- mobileSelect.addEventListener('change', () => {
762
- const newPage = parseInt(mobileSelect.value, 10);
763
- if (newPage !== this.currentPage) {
759
+ select.addEventListener('change', () => {
760
+ const newPage = parseInt(select.value, 10);
761
+ if (newPage !== this.controller.currentPage) {
764
762
  void this.goToPage(newPage);
765
763
  }
766
764
  });
767
765
  }
768
766
  /**
769
- * Render the mobile page size selector (select dropdown).
770
- *
771
- * @param container
772
- * The container element for the mobile page size selector.
767
+ * Updates the dropdown page selector DOM elements.
773
768
  */
774
- renderMobilePageSizeSelector(container) {
775
- const mobilePageSizeSelect = makeHTMLElement('select', {
776
- className: Globals.getClassName('paginationMobilePageSizeSelector')
777
- }, container);
778
- this.pageSizeOptions.forEach((option) => {
779
- const optionElement = makeHTMLElement('option', {}, mobilePageSizeSelect);
780
- optionElement.value = option.toString();
781
- optionElement.textContent = `${option} ${this.lang.pageSizeLabel}`;
782
- if (option === this.currentPageSize) {
783
- optionElement.selected = true;
784
- }
785
- });
786
- this.mobilePageSizeSelector = mobilePageSizeSelect;
787
- mobilePageSizeSelect.addEventListener('change', () => {
788
- if (!this.mobilePageSizeSelector) {
789
- return;
790
- }
791
- void this.setPageSize(parseInt(this.mobilePageSizeSelector.value, 10));
792
- });
769
+ updateDropdownPageSelector() {
770
+ const select = this.dropdownPageSelector;
771
+ if (!select) {
772
+ return;
773
+ }
774
+ const { totalPages, currentPage } = this.controller;
775
+ select.innerHTML = AST.emptyHTML;
776
+ // Add options for each page
777
+ for (let i = 1; i <= totalPages; i++) {
778
+ const option = makeHTMLElement('option', {}, select);
779
+ option.value = i.toString();
780
+ option.textContent = `Page ${i} of ${totalPages}`;
781
+ }
782
+ // Set current page as selected
783
+ select.value = currentPage.toString();
793
784
  }
794
785
  /**
795
786
  * Update the row count for a11y.
@@ -799,7 +790,7 @@ class Pagination {
799
790
  */
800
791
  updateA11yRowsCount(currentPageSize) {
801
792
  const grid = this.grid;
802
- grid.tableElement?.setAttribute('aria-rowcount', currentPageSize || this.totalItems);
793
+ grid.tableElement?.setAttribute('aria-rowcount', currentPageSize || this.controller.totalItems);
803
794
  }
804
795
  }
805
796
  /* *
@@ -812,6 +803,7 @@ class Pagination {
812
803
  */
813
804
  Pagination.defaultOptions = {
814
805
  enabled: false,
806
+ page: 1,
815
807
  pageSize: 10,
816
808
  position: 'bottom',
817
809
  controls: {