@keenthemes/ktui 1.2.4 → 1.2.6

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 (152) hide show
  1. package/dist/ktui.js +2551 -2817
  2. package/dist/ktui.min.js +1 -1
  3. package/dist/ktui.min.js.map +1 -1
  4. package/dist/styles.css +136 -40
  5. package/lib/cjs/components/datatable/datatable-checkbox.d.ts.map +1 -1
  6. package/lib/cjs/components/datatable/datatable-checkbox.js +34 -15
  7. package/lib/cjs/components/datatable/datatable-checkbox.js.map +1 -1
  8. package/lib/cjs/components/datatable/datatable-contracts.d.ts +3 -3
  9. package/lib/cjs/components/datatable/datatable-contracts.d.ts.map +1 -1
  10. package/lib/cjs/components/datatable/datatable-layout-plugin.d.ts +7 -0
  11. package/lib/cjs/components/datatable/datatable-layout-plugin.d.ts.map +1 -0
  12. package/lib/cjs/components/datatable/datatable-layout-plugin.js +328 -0
  13. package/lib/cjs/components/datatable/datatable-layout-plugin.js.map +1 -0
  14. package/lib/cjs/components/datatable/datatable-local-provider.d.ts +2 -2
  15. package/lib/cjs/components/datatable/datatable-local-provider.d.ts.map +1 -1
  16. package/lib/cjs/components/datatable/datatable-local-provider.js +18 -10
  17. package/lib/cjs/components/datatable/datatable-local-provider.js.map +1 -1
  18. package/lib/cjs/components/datatable/datatable-pagination-renderer.d.ts.map +1 -1
  19. package/lib/cjs/components/datatable/datatable-pagination-renderer.js +40 -25
  20. package/lib/cjs/components/datatable/datatable-pagination-renderer.js.map +1 -1
  21. package/lib/cjs/components/datatable/datatable-remote-provider.d.ts.map +1 -1
  22. package/lib/cjs/components/datatable/datatable-remote-provider.js +3 -0
  23. package/lib/cjs/components/datatable/datatable-remote-provider.js.map +1 -1
  24. package/lib/cjs/components/datatable/datatable-table-renderer.d.ts.map +1 -1
  25. package/lib/cjs/components/datatable/datatable-table-renderer.js +14 -6
  26. package/lib/cjs/components/datatable/datatable-table-renderer.js.map +1 -1
  27. package/lib/cjs/components/datatable/datatable.d.ts +9 -0
  28. package/lib/cjs/components/datatable/datatable.d.ts.map +1 -1
  29. package/lib/cjs/components/datatable/datatable.js +200 -61
  30. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  31. package/lib/cjs/components/datatable/index.d.ts +1 -1
  32. package/lib/cjs/components/datatable/index.d.ts.map +1 -1
  33. package/lib/cjs/components/datatable/types.d.ts +27 -0
  34. package/lib/cjs/components/datatable/types.d.ts.map +1 -1
  35. package/lib/cjs/components/dropdown/dropdown.d.ts +2 -2
  36. package/lib/cjs/components/dropdown/dropdown.d.ts.map +1 -1
  37. package/lib/cjs/components/dropdown/dropdown.js +68 -31
  38. package/lib/cjs/components/dropdown/dropdown.js.map +1 -1
  39. package/lib/cjs/components/input-number/index.d.ts +7 -0
  40. package/lib/cjs/components/input-number/index.d.ts.map +1 -0
  41. package/lib/cjs/components/input-number/index.js +10 -0
  42. package/lib/cjs/components/input-number/index.js.map +1 -0
  43. package/lib/cjs/components/input-number/input-number.d.ts +40 -0
  44. package/lib/cjs/components/input-number/input-number.d.ts.map +1 -0
  45. package/lib/cjs/components/input-number/input-number.js +248 -0
  46. package/lib/cjs/components/input-number/input-number.js.map +1 -0
  47. package/lib/cjs/components/input-number/types.d.ts +30 -0
  48. package/lib/cjs/components/input-number/types.d.ts.map +1 -0
  49. package/lib/cjs/components/input-number/types.js +7 -0
  50. package/lib/cjs/components/input-number/types.js.map +1 -0
  51. package/lib/cjs/components/select/config.d.ts +1 -0
  52. package/lib/cjs/components/select/config.d.ts.map +1 -1
  53. package/lib/cjs/components/select/config.js +2 -1
  54. package/lib/cjs/components/select/config.js.map +1 -1
  55. package/lib/cjs/components/select/select.d.ts +8 -1
  56. package/lib/cjs/components/select/select.d.ts.map +1 -1
  57. package/lib/cjs/components/select/select.js +14 -1
  58. package/lib/cjs/components/select/select.js.map +1 -1
  59. package/lib/cjs/components/select/tags.d.ts.map +1 -1
  60. package/lib/cjs/components/select/tags.js +10 -0
  61. package/lib/cjs/components/select/tags.js.map +1 -1
  62. package/lib/cjs/index.d.ts +5 -1
  63. package/lib/cjs/index.d.ts.map +1 -1
  64. package/lib/cjs/index.js +5 -1
  65. package/lib/cjs/index.js.map +1 -1
  66. package/lib/esm/components/datatable/datatable-checkbox.d.ts.map +1 -1
  67. package/lib/esm/components/datatable/datatable-checkbox.js +34 -15
  68. package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
  69. package/lib/esm/components/datatable/datatable-contracts.d.ts +3 -3
  70. package/lib/esm/components/datatable/datatable-contracts.d.ts.map +1 -1
  71. package/lib/esm/components/datatable/datatable-layout-plugin.d.ts +7 -0
  72. package/lib/esm/components/datatable/datatable-layout-plugin.d.ts.map +1 -0
  73. package/lib/esm/components/datatable/datatable-layout-plugin.js +324 -0
  74. package/lib/esm/components/datatable/datatable-layout-plugin.js.map +1 -0
  75. package/lib/esm/components/datatable/datatable-local-provider.d.ts +2 -2
  76. package/lib/esm/components/datatable/datatable-local-provider.d.ts.map +1 -1
  77. package/lib/esm/components/datatable/datatable-local-provider.js +18 -10
  78. package/lib/esm/components/datatable/datatable-local-provider.js.map +1 -1
  79. package/lib/esm/components/datatable/datatable-pagination-renderer.d.ts.map +1 -1
  80. package/lib/esm/components/datatable/datatable-pagination-renderer.js +40 -25
  81. package/lib/esm/components/datatable/datatable-pagination-renderer.js.map +1 -1
  82. package/lib/esm/components/datatable/datatable-remote-provider.d.ts.map +1 -1
  83. package/lib/esm/components/datatable/datatable-remote-provider.js +3 -0
  84. package/lib/esm/components/datatable/datatable-remote-provider.js.map +1 -1
  85. package/lib/esm/components/datatable/datatable-table-renderer.d.ts.map +1 -1
  86. package/lib/esm/components/datatable/datatable-table-renderer.js +14 -6
  87. package/lib/esm/components/datatable/datatable-table-renderer.js.map +1 -1
  88. package/lib/esm/components/datatable/datatable.d.ts +9 -0
  89. package/lib/esm/components/datatable/datatable.d.ts.map +1 -1
  90. package/lib/esm/components/datatable/datatable.js +200 -61
  91. package/lib/esm/components/datatable/datatable.js.map +1 -1
  92. package/lib/esm/components/datatable/index.d.ts +1 -1
  93. package/lib/esm/components/datatable/index.d.ts.map +1 -1
  94. package/lib/esm/components/datatable/types.d.ts +27 -0
  95. package/lib/esm/components/datatable/types.d.ts.map +1 -1
  96. package/lib/esm/components/dropdown/dropdown.d.ts +2 -2
  97. package/lib/esm/components/dropdown/dropdown.d.ts.map +1 -1
  98. package/lib/esm/components/dropdown/dropdown.js +68 -31
  99. package/lib/esm/components/dropdown/dropdown.js.map +1 -1
  100. package/lib/esm/components/input-number/index.d.ts +7 -0
  101. package/lib/esm/components/input-number/index.d.ts.map +1 -0
  102. package/lib/esm/components/input-number/index.js +6 -0
  103. package/lib/esm/components/input-number/index.js.map +1 -0
  104. package/lib/esm/components/input-number/input-number.d.ts +40 -0
  105. package/lib/esm/components/input-number/input-number.d.ts.map +1 -0
  106. package/lib/esm/components/input-number/input-number.js +245 -0
  107. package/lib/esm/components/input-number/input-number.js.map +1 -0
  108. package/lib/esm/components/input-number/types.d.ts +30 -0
  109. package/lib/esm/components/input-number/types.d.ts.map +1 -0
  110. package/lib/esm/components/input-number/types.js +6 -0
  111. package/lib/esm/components/input-number/types.js.map +1 -0
  112. package/lib/esm/components/select/config.d.ts +1 -0
  113. package/lib/esm/components/select/config.d.ts.map +1 -1
  114. package/lib/esm/components/select/config.js +2 -1
  115. package/lib/esm/components/select/config.js.map +1 -1
  116. package/lib/esm/components/select/select.d.ts +8 -1
  117. package/lib/esm/components/select/select.d.ts.map +1 -1
  118. package/lib/esm/components/select/select.js +14 -1
  119. package/lib/esm/components/select/select.js.map +1 -1
  120. package/lib/esm/components/select/tags.d.ts.map +1 -1
  121. package/lib/esm/components/select/tags.js +11 -1
  122. package/lib/esm/components/select/tags.js.map +1 -1
  123. package/lib/esm/index.d.ts +5 -1
  124. package/lib/esm/index.d.ts.map +1 -1
  125. package/lib/esm/index.js +3 -0
  126. package/lib/esm/index.js.map +1 -1
  127. package/package.json +5 -11
  128. package/src/components/datatable/__tests__/locked-layout.test.ts +257 -0
  129. package/src/components/datatable/__tests__/pagination-reset.test.ts +18 -0
  130. package/src/components/datatable/datatable-checkbox.ts +35 -27
  131. package/src/components/datatable/datatable-contracts.ts +3 -3
  132. package/src/components/datatable/datatable-layout-plugin.ts +449 -0
  133. package/src/components/datatable/datatable-local-provider.ts +21 -14
  134. package/src/components/datatable/datatable-pagination-renderer.ts +40 -29
  135. package/src/components/datatable/datatable-remote-provider.ts +3 -0
  136. package/src/components/datatable/datatable-table-renderer.ts +40 -32
  137. package/src/components/datatable/datatable.css +98 -0
  138. package/src/components/datatable/datatable.ts +223 -86
  139. package/src/components/datatable/index.ts +5 -0
  140. package/src/components/datatable/types.ts +33 -0
  141. package/src/components/dropdown/dropdown.ts +86 -58
  142. package/src/components/input/input-group.css +14 -1
  143. package/src/components/input-number/__tests__/input-number.test.ts +278 -0
  144. package/src/components/input-number/index.ts +11 -0
  145. package/src/components/input-number/input-number.ts +267 -0
  146. package/src/components/input-number/types.ts +32 -0
  147. package/src/components/select/__tests__/ux-behaviors.test.ts +72 -0
  148. package/src/components/select/config.ts +3 -1
  149. package/src/components/select/select.css +23 -20
  150. package/src/components/select/select.ts +15 -1
  151. package/src/components/select/tags.ts +14 -1
  152. package/src/index.ts +14 -0
@@ -0,0 +1,257 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { KTDataTable } from '../datatable';
3
+
4
+ type DataRow = {
5
+ id: string;
6
+ name: string;
7
+ status: string;
8
+ };
9
+
10
+ const rows: DataRow[] = [
11
+ { id: '1', name: 'Alpha', status: 'Active' },
12
+ { id: '2', name: 'Beta', status: 'Pending' },
13
+ { id: '3', name: 'Gamma', status: 'Disabled' },
14
+ ];
15
+
16
+ const createDatatableFixture = () => {
17
+ const wrapper = document.createElement('div');
18
+ wrapper.className = 'kt-table-wrapper';
19
+
20
+ const container = document.createElement('div');
21
+ container.id = 'kt_datatable_locked_layout';
22
+ container.setAttribute('data-kt-datatable', 'true');
23
+
24
+ const table = document.createElement('table');
25
+ table.setAttribute('data-kt-datatable-table', 'true');
26
+
27
+ const thead = document.createElement('thead');
28
+ thead.innerHTML = `
29
+ <tr>
30
+ <th data-kt-datatable-column="id">ID</th>
31
+ <th data-kt-datatable-column="name">Name</th>
32
+ <th data-kt-datatable-column="status">Status</th>
33
+ </tr>
34
+ `;
35
+ table.appendChild(thead);
36
+
37
+ const tbody = document.createElement('tbody');
38
+ rows.forEach((row) => {
39
+ const tr = document.createElement('tr');
40
+ tr.innerHTML = `<td>${row.id}</td><td>${row.name}</td><td>${row.status}</td>`;
41
+ tbody.appendChild(tr);
42
+ });
43
+ table.appendChild(tbody);
44
+
45
+ wrapper.appendChild(table);
46
+ container.appendChild(wrapper);
47
+
48
+ const info = document.createElement('span');
49
+ info.setAttribute('data-kt-datatable-info', 'true');
50
+ const size = document.createElement('select');
51
+ size.setAttribute('data-kt-datatable-size', 'true');
52
+ const pagination = document.createElement('div');
53
+ pagination.setAttribute('data-kt-datatable-pagination', 'true');
54
+
55
+ container.appendChild(info);
56
+ container.appendChild(size);
57
+ container.appendChild(pagination);
58
+ document.body.appendChild(container);
59
+
60
+ const sizedCells = table.querySelectorAll<HTMLTableCellElement>('th, td');
61
+ sizedCells.forEach((cell) => {
62
+ Object.defineProperty(cell, 'getBoundingClientRect', {
63
+ value: () =>
64
+ ({
65
+ width: 120,
66
+ height: 40,
67
+ top: 0,
68
+ left: 0,
69
+ right: 0,
70
+ bottom: 0,
71
+ x: 0,
72
+ y: 0,
73
+ toJSON: () => ({}),
74
+ }) as DOMRect,
75
+ });
76
+ });
77
+
78
+ return { container, table };
79
+ };
80
+
81
+ describe('KTDataTable locked layout plugin', () => {
82
+ beforeEach(() => {
83
+ vi.useFakeTimers();
84
+ });
85
+
86
+ it('applies locked header, rows and columns in local mode and keeps them after sorting', async () => {
87
+ const { container, table } = createDatatableFixture();
88
+
89
+ const datatable = new KTDataTable<DataRow>(container, {
90
+ stateSave: false,
91
+ columns: {
92
+ id: { title: 'ID' },
93
+ name: { title: 'Name' },
94
+ status: { title: 'Status' },
95
+ },
96
+ lockedLayout: {
97
+ stickyHeader: true,
98
+ stickyRows: { top: 1, bottom: 1 },
99
+ stickyColumns: { left: ['id'], right: ['status'] },
100
+ },
101
+ });
102
+
103
+ await vi.runAllTimersAsync();
104
+
105
+ expect(
106
+ table.querySelectorAll('.kt-datatable-locked-header').length,
107
+ ).toBeGreaterThan(0);
108
+ expect(
109
+ table.querySelectorAll('.kt-datatable-locked-top-row').length,
110
+ ).toBeGreaterThan(0);
111
+ expect(
112
+ table.querySelectorAll('.kt-datatable-locked-bottom-row').length,
113
+ ).toBeGreaterThan(0);
114
+ expect(
115
+ table.querySelectorAll('.kt-datatable-locked-left').length,
116
+ ).toBeGreaterThan(0);
117
+ expect(
118
+ table.querySelectorAll('.kt-datatable-locked-right').length,
119
+ ).toBeGreaterThan(0);
120
+
121
+ datatable.sort('name');
122
+ await vi.runAllTimersAsync();
123
+
124
+ expect(
125
+ table.querySelectorAll('.kt-datatable-locked-cell').length,
126
+ ).toBeGreaterThan(0);
127
+ });
128
+
129
+ it('reapplies locked layout after remote fetch redraw', async () => {
130
+ const { container, table } = createDatatableFixture();
131
+ const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
132
+ new Response(JSON.stringify({ data: rows, totalCount: rows.length }), {
133
+ status: 200,
134
+ headers: { 'Content-Type': 'application/json' },
135
+ }),
136
+ );
137
+
138
+ new KTDataTable<DataRow>(container, {
139
+ stateSave: false,
140
+ apiEndpoint: 'https://example.test/datatable',
141
+ requestMethod: 'GET',
142
+ mapResponse: (data) => data,
143
+ lockedLayout: {
144
+ stickyHeader: true,
145
+ stickyColumns: { left: ['id'] },
146
+ },
147
+ });
148
+
149
+ await vi.runAllTimersAsync();
150
+
151
+ expect(fetchMock).toHaveBeenCalled();
152
+ expect(
153
+ table.querySelectorAll('.kt-datatable-locked-header').length,
154
+ ).toBeGreaterThan(0);
155
+ expect(
156
+ table.querySelectorAll('.kt-datatable-locked-left').length,
157
+ ).toBeGreaterThan(0);
158
+ });
159
+
160
+ it('keeps pagination state when using locked columns in local mode', async () => {
161
+ const { container } = createDatatableFixture();
162
+
163
+ const datatable = new KTDataTable<DataRow>(container, {
164
+ stateSave: false,
165
+ pageSize: 2,
166
+ columns: {
167
+ id: { title: 'ID' },
168
+ name: { title: 'Name' },
169
+ status: { title: 'Status' },
170
+ },
171
+ lockedLayout: {
172
+ stickyHeader: true,
173
+ stickyColumns: { left: ['id'] },
174
+ },
175
+ });
176
+
177
+ await vi.runAllTimersAsync();
178
+ expect(datatable.getState().totalPages).toBe(2);
179
+
180
+ datatable.goPage(2);
181
+ await vi.runAllTimersAsync();
182
+ expect(datatable.getState().page).toBe(2);
183
+ expect(datatable.getState().totalPages).toBe(2);
184
+ expect(datatable.getState().totalItems).toBe(rows.length);
185
+ });
186
+
187
+ it('uses collapsed table borders for row-only locked layout', async () => {
188
+ const { container, table } = createDatatableFixture();
189
+
190
+ new KTDataTable<DataRow>(container, {
191
+ stateSave: false,
192
+ lockedLayout: {
193
+ stickyHeader: true,
194
+ stickyRows: { top: 1, bottom: 1 },
195
+ },
196
+ });
197
+
198
+ await vi.runAllTimersAsync();
199
+
200
+ expect(table.classList.contains('kt-datatable-locked-layout')).toBe(true);
201
+ expect(
202
+ table.classList.contains('kt-datatable-locked-layout-separate'),
203
+ ).toBe(false);
204
+ expect(table.style.borderCollapse).not.toBe('separate');
205
+ expect(
206
+ table.tHead?.classList.contains('kt-datatable-locked-header-section'),
207
+ ).toBe(true);
208
+ const stickyHeaderCell = table.querySelector(
209
+ 'th.kt-datatable-locked-header',
210
+ ) as HTMLTableCellElement | null;
211
+ expect(stickyHeaderCell?.style.position).not.toBe('sticky');
212
+ });
213
+
214
+ it('uses separate table borders when sticky columns are enabled', async () => {
215
+ const { container, table } = createDatatableFixture();
216
+
217
+ new KTDataTable<DataRow>(container, {
218
+ stateSave: false,
219
+ lockedLayout: {
220
+ stickyHeader: true,
221
+ stickyColumns: { left: ['id'] },
222
+ },
223
+ });
224
+
225
+ await vi.runAllTimersAsync();
226
+
227
+ expect(
228
+ table.classList.contains('kt-datatable-locked-layout-separate'),
229
+ ).toBe(true);
230
+ expect(table.style.borderCollapse).toBe('separate');
231
+ });
232
+
233
+ it('does not set inline background color for locked header columns', async () => {
234
+ const { container, table } = createDatatableFixture();
235
+
236
+ new KTDataTable<DataRow>(container, {
237
+ stateSave: false,
238
+ columns: {
239
+ id: { title: 'ID' },
240
+ name: { title: 'Name' },
241
+ status: { title: 'Status' },
242
+ },
243
+ lockedLayout: {
244
+ stickyHeader: true,
245
+ stickyColumns: { left: ['id'] },
246
+ },
247
+ });
248
+
249
+ await vi.runAllTimersAsync();
250
+
251
+ const lockedHeaderCell = table.querySelector(
252
+ 'th.kt-datatable-locked-left',
253
+ ) as HTMLTableCellElement | null;
254
+ expect(lockedHeaderCell).not.toBeNull();
255
+ expect(lockedHeaderCell?.style.backgroundColor).toBe('');
256
+ });
257
+ });
@@ -552,6 +552,24 @@ describe('KTDataTable - Pagination Reset', () => {
552
552
  });
553
553
 
554
554
  describe('Edge Cases', () => {
555
+ it('keeps total pages stable when navigating to page 2 in local mode', () => {
556
+ const { container } = createMockDataTable(6);
557
+ datatable = new KTDataTable(container, {
558
+ pageSize: 5,
559
+ stateSave: false,
560
+ });
561
+
562
+ expect(datatable.getState().totalPages).toBe(2);
563
+ datatable.goPage(2);
564
+ expect(datatable.getState().page).toBe(2);
565
+ expect(datatable.getState().totalPages).toBe(2);
566
+
567
+ // Trigger another redraw cycle to ensure local mode does not shrink original data.
568
+ datatable.reload();
569
+ expect(datatable.getState().page).toBe(2);
570
+ expect(datatable.getState().totalPages).toBe(2);
571
+ });
572
+
555
573
  it('should handle search reset on page 1 (no-op)', () => {
556
574
  const { container } = createMockDataTable(25);
557
575
  datatable = new KTDataTable(container, {
@@ -8,8 +8,10 @@
8
8
  import {
9
9
  KTDataTableConfigInterface,
10
10
  KTDataTableCheckChangePayloadInterface,
11
+ KTDataTableStateInterface,
11
12
  } from './types';
12
13
  import KTEventHandler from '../../helpers/event-handler';
14
+ import { KTCallableType } from '../../types';
13
15
 
14
16
  export interface KTDataTableCheckboxAPI {
15
17
  init(): void;
@@ -29,25 +31,31 @@ export function createCheckboxHandler(
29
31
  ): KTDataTableCheckboxAPI {
30
32
  let headerChecked = false;
31
33
  let headerCheckElement: HTMLInputElement | null = null;
32
- let targetElements: NodeListOf<HTMLInputElement> = null;
34
+ let targetElements: NodeListOf<HTMLInputElement> | null = null;
33
35
 
34
36
  // Default: preserve selection across all pages
35
37
  const preserveSelection = config.checkbox?.preserveSelection !== false;
36
38
 
39
+ function ensureState(): KTDataTableStateInterface {
40
+ let state = config._state;
41
+ if (!state) {
42
+ state = {} as KTDataTableStateInterface;
43
+ config._state = state;
44
+ }
45
+ return state;
46
+ }
47
+
37
48
  // Helper: get selectedRows from state, always as string[]
38
49
  function getSelectedRows(): string[] {
39
- if (!config._state)
40
- config._state = {} as unknown as KTDataTableConfigInterface['_state'];
41
- if (!Array.isArray(config._state.selectedRows))
42
- config._state.selectedRows = [];
43
- return config._state.selectedRows.map(String);
50
+ const state = ensureState();
51
+ if (!Array.isArray(state.selectedRows)) state.selectedRows = [];
52
+ return state.selectedRows.map(String);
44
53
  }
45
54
 
46
55
  // Helper: set selectedRows in state
47
56
  function setSelectedRows(rows: string[]) {
48
- if (!config._state)
49
- config._state = {} as unknown as KTDataTableConfigInterface['_state'];
50
- config._state.selectedRows = Array.from(new Set(rows.map(String)));
57
+ const state = ensureState();
58
+ state.selectedRows = Array.from(new Set(rows.map(String)));
51
59
  }
52
60
 
53
61
  // Helper: get all visible row IDs (values)
@@ -64,14 +72,14 @@ export function createCheckboxHandler(
64
72
  };
65
73
 
66
74
  function init() {
67
- headerCheckElement = element.querySelector<HTMLInputElement>(
68
- config.attributes.check,
69
- );
75
+ const attrs = config.attributes;
76
+ if (!attrs?.check || !attrs.checkbox) {
77
+ return;
78
+ }
79
+ headerCheckElement = element.querySelector<HTMLInputElement>(attrs.check);
70
80
  if (!headerCheckElement) return;
71
81
  headerChecked = headerCheckElement.checked;
72
- targetElements = element.querySelectorAll(
73
- config.attributes.checkbox,
74
- ) as NodeListOf<HTMLInputElement>;
82
+ targetElements = element.querySelectorAll<HTMLInputElement>(attrs.checkbox);
75
83
  checkboxHandler();
76
84
  reapplyCheckedStates();
77
85
  updateHeaderCheckboxState();
@@ -79,15 +87,14 @@ export function createCheckboxHandler(
79
87
 
80
88
  function checkboxHandler() {
81
89
  if (!headerCheckElement) return;
90
+ const rowCheckboxSelector = config.attributes?.checkbox;
91
+ if (!rowCheckboxSelector) return;
82
92
  headerCheckElement.addEventListener('click', checkboxListener);
83
- KTEventHandler.on(
84
- document.body,
85
- config.attributes.checkbox,
86
- 'input',
87
- (event: Event) => {
88
- handleRowCheckboxChange(event as InputEvent);
89
- },
90
- );
93
+ KTEventHandler.on(document.body, rowCheckboxSelector, 'input', ((
94
+ event?: Event,
95
+ ) => {
96
+ if (event) handleRowCheckboxChange(event);
97
+ }) as KTCallableType);
91
98
  }
92
99
 
93
100
  // When a row checkbox is changed
@@ -233,10 +240,11 @@ export function createCheckboxHandler(
233
240
  }
234
241
 
235
242
  function updateState() {
236
- // Called after redraw/pagination
237
- targetElements = element.querySelectorAll(
238
- config.attributes.checkbox,
239
- ) as NodeListOf<HTMLInputElement>;
243
+ const rowCheckSel = config.attributes?.checkbox;
244
+ if (!rowCheckSel) {
245
+ return;
246
+ }
247
+ targetElements = element.querySelectorAll<HTMLInputElement>(rowCheckSel);
240
248
  reapplyCheckedStates();
241
249
  updateHeaderCheckboxState();
242
250
  }
@@ -83,11 +83,11 @@ export interface KTDataTableTableRenderer<T extends KTDataTableDataInterface> {
83
83
  export interface KTDataTablePaginationRendererInput {
84
84
  config: KTDataTableConfigInterface;
85
85
  dataLength: number;
86
- infoElement: HTMLElement;
86
+ infoElement?: HTMLElement | null;
87
87
  paginateData: (page: number) => void;
88
- paginationElement: HTMLElement;
88
+ paginationElement?: HTMLElement | null;
89
89
  reloadPageSize: (pageSize: number, page?: number) => void;
90
- sizeElement: HTMLSelectElement;
90
+ sizeElement?: HTMLSelectElement | null;
91
91
  state: KTDataTableStateInterface;
92
92
  }
93
93