@oscarpalmer/tabela 0.12.0 → 0.14.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 (65) hide show
  1. package/dist/tabela.full.js +146 -18
  2. package/package.json +45 -37
  3. package/src/components/body.component.ts +11 -7
  4. package/src/components/column.component.ts +23 -24
  5. package/src/components/footer.component.ts +7 -5
  6. package/src/components/group.component.ts +73 -9
  7. package/src/components/header.component.ts +6 -4
  8. package/src/components/row.component.ts +28 -18
  9. package/src/helpers/dom.helpers.ts +27 -29
  10. package/src/helpers/misc.helpers.ts +5 -0
  11. package/src/helpers/style.helper.ts +1 -1
  12. package/src/managers/column.manager.ts +4 -0
  13. package/src/managers/data.manager.ts +197 -124
  14. package/src/managers/event.manager.ts +27 -17
  15. package/src/managers/filter.manager.ts +49 -25
  16. package/src/managers/group.manager.ts +73 -12
  17. package/src/managers/navigation.manager.ts +48 -50
  18. package/src/managers/render.manager.ts +56 -29
  19. package/src/managers/row.manager.ts +22 -10
  20. package/src/managers/selection.manager.ts +40 -31
  21. package/src/managers/sort.manager.ts +58 -43
  22. package/src/managers/style.manager.ts +171 -0
  23. package/src/models/column.model.ts +2 -6
  24. package/src/models/data.model.ts +12 -10
  25. package/src/models/dom.model.ts +33 -0
  26. package/src/models/event.model.ts +7 -0
  27. package/src/models/filter.model.ts +20 -0
  28. package/src/models/group.model.ts +10 -2
  29. package/src/models/sort.model.ts +4 -0
  30. package/src/models/style.model.ts +51 -0
  31. package/src/models/tabela.model.ts +11 -8
  32. package/src/tabela.ts +67 -37
  33. package/types/components/body.component.d.ts +0 -6
  34. package/types/components/column.component.d.ts +0 -13
  35. package/types/components/footer.component.d.ts +0 -8
  36. package/types/components/group.component.d.ts +0 -14
  37. package/types/components/header.component.d.ts +0 -8
  38. package/types/components/row.component.d.ts +0 -11
  39. package/types/helpers/dom.helpers.d.ts +0 -10
  40. package/types/helpers/misc.helpers.d.ts +0 -2
  41. package/types/helpers/style.helper.d.ts +0 -1
  42. package/types/index.d.ts +0 -4
  43. package/types/managers/column.manager.d.ts +0 -12
  44. package/types/managers/data.manager.d.ts +0 -29
  45. package/types/managers/event.manager.d.ts +0 -7
  46. package/types/managers/filter.manager.d.ts +0 -19
  47. package/types/managers/group.manager.d.ts +0 -17
  48. package/types/managers/navigation.manager.d.ts +0 -10
  49. package/types/managers/render.manager.d.ts +0 -17
  50. package/types/managers/row.manager.d.ts +0 -13
  51. package/types/managers/selection.manager.d.ts +0 -24
  52. package/types/managers/sort.manager.d.ts +0 -28
  53. package/types/models/body.model.d.ts +0 -4
  54. package/types/models/column.model.d.ts +0 -13
  55. package/types/models/data.model.d.ts +0 -24
  56. package/types/models/filter.model.d.ts +0 -13
  57. package/types/models/footer.model.d.ts +0 -5
  58. package/types/models/group.model.d.ts +0 -4
  59. package/types/models/header.model.d.ts +0 -4
  60. package/types/models/render.model.d.ts +0 -13
  61. package/types/models/selection.model.d.ts +0 -8
  62. package/types/models/sort.model.d.ts +0 -12
  63. package/types/models/tabela.model.d.ts +0 -39
  64. package/types/models/tabela.options.d.ts +0 -10
  65. package/types/tabela.d.ts +0 -15
@@ -1,75 +1,94 @@
1
- import {select, sort} from '@oscarpalmer/atoms/array';
1
+ import {chunk, select, sort} from '@oscarpalmer/atoms/array';
2
2
  import {toMap} from '@oscarpalmer/atoms/array/to-map';
3
3
  import {toRecord} from '@oscarpalmer/atoms/array/to-record';
4
+ import {isPlainObject} from '@oscarpalmer/atoms/is';
4
5
  import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
5
- import type {DataValues, TabelaData} from '../models/data.model';
6
+ import {delay} from '@oscarpalmer/atoms/promise/delay';
7
+ import {getValue} from '@oscarpalmer/atoms/value/handle';
8
+ import type {ColumnComponent} from '../components/column.component';
9
+ import {GroupComponent, updateGroup} from '../components/group.component';
10
+ import type {DataState, DataValue, TabelaData} from '../models/data.model';
11
+ import {SORT_ASCENDING} from '../models/sort.model';
6
12
  import type {State} from '../models/tabela.model';
7
- import {GroupComponent} from '../components/group.component';
8
13
  import {sortWithGroups} from './sort.manager';
9
- import {isPlainObject} from '@oscarpalmer/atoms/is';
14
+ import {isGroupKey} from '../helpers/misc.helpers';
10
15
 
11
16
  export class DataManager {
12
- handlers = Object.freeze({
17
+ handlers: TabelaData = {
13
18
  add: data => void this.add(data, true),
14
- clear: () => void this.clear(),
19
+ clear: () => this.clear(),
15
20
  get: active => this.get(active),
16
21
  remove: items => void this.remove(items, true),
17
- synchronize: (data, remove) => void this.synchronize(data, remove),
18
- update: data => void this.update(data),
19
- } satisfies TabelaData);
20
-
21
- values: DataValues = {
22
- keys: {
23
- original: [],
24
- },
25
- objects: {
26
- mapped: new Map(),
27
- array: [],
28
- },
22
+ synchronize: (data, remove) => void this.synchronize(data, remove === true),
23
+ update: data => void this.update(data, true),
29
24
  };
30
25
 
31
- get keys(): Array<GroupComponent | Key> {
32
- return this.values.keys.active ?? this.values.keys.original;
26
+ state: DataState;
27
+
28
+ get keys(): Key[] {
29
+ return this.state.keys.active ?? this.state.keys.original;
33
30
  }
34
31
 
35
32
  get size(): number {
36
33
  return this.keys.length;
37
34
  }
38
35
 
39
- constructor(public state: State) {}
36
+ constructor(state: State) {
37
+ this.state = {
38
+ ...state,
39
+ keys: {
40
+ original: [],
41
+ },
42
+ values: {
43
+ array: [],
44
+ mapped: new Map(),
45
+ },
46
+ };
47
+ }
40
48
 
41
49
  async add(data: PlainObject[], render: boolean): Promise<void> {
42
- const {state, values} = this;
43
- const {length} = data;
50
+ const {state} = this;
44
51
 
52
+ const groups: GroupComponent[] = [];
45
53
  const updates: PlainObject[] = [];
46
54
 
55
+ let groupColumn: ColumnComponent | undefined;
56
+ let {length} = data;
57
+
58
+ let added = 0;
59
+
47
60
  for (let index = 0; index < length; index += 1) {
48
61
  const item = data[index];
49
- const key = item[state.key] as Key;
62
+ const key = getValue(item, state.key) as Key;
50
63
 
51
- if (values.objects.mapped.has(key)) {
64
+ if (state.values.mapped.has(key)) {
52
65
  updates.push(item);
53
66
 
54
67
  continue;
55
68
  }
56
69
 
57
- values.objects.array.push(item);
58
- values.objects.mapped.set(key, item);
70
+ state.values.array.push(item);
71
+ state.values.mapped.set(key, item);
72
+
73
+ added += 1;
59
74
 
60
75
  if (!state.managers.group.enabled) {
61
76
  continue;
62
77
  }
63
78
 
64
- const groupKey = item[state.managers.group.field] as unknown;
79
+ const groupValue = getValue(item, state.managers.group.field) as Key;
65
80
 
66
- let group = state.managers.group.get(groupKey);
81
+ let group = state.managers.group.getForValue(groupValue);
67
82
 
68
83
  if (group == null) {
69
- group = new GroupComponent(String(groupKey), String(groupKey), groupKey);
84
+ groupColumn ??= state.managers.column.get(state.managers.group.field);
70
85
 
71
- values.objects.array.push(group);
86
+ group = new GroupComponent(
87
+ `${groupColumn?.options.label ?? state.managers.group.field}: ${groupValue}`,
88
+ groupValue,
89
+ );
72
90
 
91
+ state.values.array.push(group.key);
73
92
  state.managers.group.add(group);
74
93
  }
75
94
 
@@ -78,145 +97,192 @@ export class DataManager {
78
97
  }
79
98
 
80
99
  group.total += 1;
100
+
101
+ groups.push(group);
102
+ }
103
+
104
+ length = groups.length;
105
+
106
+ for (let index = 0; index < length; index += 1) {
107
+ updateGroup(state, groups[index]);
81
108
  }
82
109
 
83
- if (updates.length > 0) {
84
- void this.update(updates);
85
- } else if (render) {
110
+ await this.update(updates, added === 0);
111
+
112
+ if (added > 0 && render) {
86
113
  this.render();
87
114
  }
88
115
  }
89
116
 
90
117
  clear(): void {
91
- if (this.values.objects.array.length > 0) {
92
- this.set([]);
118
+ if (this.state.values.array.length > 0) {
119
+ void this.removeItems([], true, true);
93
120
  }
94
121
  }
95
122
 
96
123
  destroy(): void {
97
- const {values} = this;
124
+ const {state} = this;
98
125
 
99
- values.objects.mapped.clear();
126
+ state.values.mapped.clear();
100
127
 
101
- values.keys.active = undefined;
102
- values.keys.original.length = 0;
103
- values.objects.array.length = 0;
128
+ state.keys.active = undefined;
129
+ state.keys.original.length = 0;
130
+ state.values.array.length = 0;
104
131
 
105
132
  this.handlers = undefined as never;
106
133
  this.state = undefined as never;
107
- this.values = undefined as never;
108
134
  }
109
135
 
110
136
  get(active?: boolean): PlainObject[] {
111
- const {values} = this;
137
+ const {state} = this;
112
138
 
113
139
  return (active ?? false)
114
140
  ? select(
115
- values.keys.active ?? [],
116
- key => !(key instanceof GroupComponent),
117
- key => values.objects.mapped.get(key as Key)!,
141
+ state.keys.active ?? [],
142
+ key => !isGroupKey(key),
143
+ key => state.values.mapped.get(key as Key)!,
118
144
  )
119
- : (values.objects.array.filter(item => !(item instanceof GroupComponent)) as PlainObject[]);
145
+ : (state.values.array.filter(item => !isGroupKey(item)) as PlainObject[]);
120
146
  }
121
147
 
122
- getIndex(key: Key): number {
123
- return this.keys.indexOf(key);
148
+ getIndex(item: Key): number {
149
+ return this.keys.indexOf(item);
124
150
  }
125
151
 
126
152
  async remove(items: Array<Key | PlainObject>, render: boolean): Promise<void> {
127
- const {state, values} = this;
153
+ const {state} = this;
128
154
 
129
155
  const keys = items
130
- .map(value => (isPlainObject(value) ? value[state.key] : value) as Key)
131
- .filter(key => values.objects.mapped.has(key)) as Key[];
156
+ .map(value => (isPlainObject(value) ? getValue(value, state.key) : value) as Key)
157
+ .filter(key => !isGroupKey(key));
132
158
 
133
159
  const {length} = keys;
134
160
 
135
- if (length === 0) {
136
- return;
161
+ if (length > 0) {
162
+ return this.removeItems(keys, false, render === true);
137
163
  }
164
+ }
138
165
 
139
- for (let keyIndex = 0; keyIndex < length; keyIndex += 1) {
140
- const key = keys[keyIndex];
166
+ async removeItems(keys: Key[], clear: boolean, render: boolean): Promise<void> {
167
+ const {state} = this;
141
168
 
142
- values.objects.mapped.delete(key);
169
+ if (clear) {
170
+ state.keys.active = undefined;
171
+ state.keys.original = [];
172
+ state.values.array = [];
143
173
 
144
- const arrayIndex = values.objects.array.findIndex(
145
- item => !(item instanceof GroupComponent) && item[state.key] === key,
146
- );
174
+ state.values.mapped.clear();
147
175
 
148
- let item: PlainObject | undefined;
176
+ state.managers.row.clear();
149
177
 
150
- if (arrayIndex > -1) {
151
- [item] = values.objects.array.splice(arrayIndex, 1) as PlainObject[];
178
+ if (state.managers.group.enabled) {
179
+ state.managers.group.clear();
152
180
  }
153
181
 
154
- values.keys.original.splice(values.keys.original.indexOf(key), 1);
182
+ return this.render();
183
+ }
155
184
 
156
- state.managers.row.remove(key);
185
+ const groups: GroupComponent[] = [];
157
186
 
158
- if (!state.managers.group.enabled || item == null) {
159
- continue;
160
- }
187
+ const chunked = chunk(keys);
188
+ const chunkedLength = chunked.length;
161
189
 
162
- state.managers.group.collapsed.delete(key);
190
+ for (let chunkedIndex = 0; chunkedIndex < chunkedLength; chunkedIndex += 1) {
191
+ const chunk = chunked[chunkedIndex];
192
+ const chunkLength = chunk.length;
163
193
 
164
- const groupKey = item[state.managers.group.field] as unknown;
194
+ for (let keyIndex = 0; keyIndex < chunkLength; keyIndex += 1) {
195
+ const key = chunk[keyIndex];
196
+ const dataIndex = state.keys.original.indexOf(key);
165
197
 
166
- const group = state.managers.group.get(groupKey);
198
+ let dataValue: PlainObject | undefined;
167
199
 
168
- if (group == null) {
169
- continue;
170
- }
200
+ [dataValue] = state.values.array.splice(dataIndex, 1) as PlainObject[];
171
201
 
172
- group.total -= 1;
202
+ state.keys.original.splice(dataIndex, 1);
203
+ state.managers.row.remove(key as never);
204
+ state.values.mapped.delete(key as Key);
173
205
 
174
- if (group.total > 0) {
175
- continue;
176
- }
206
+ if (!state.managers.group.enabled || isGroupKey(key)) {
207
+ continue;
208
+ }
209
+
210
+ state.managers.group.collapsed.delete(key as never);
177
211
 
178
- const groupIndex = values.objects.array.findIndex(
179
- item => item instanceof GroupComponent && item.value === groupKey,
180
- );
212
+ const groupValue = getValue(dataValue, state.managers.group.field) as unknown;
181
213
 
182
- if (groupIndex > -1) {
183
- values.objects.array.splice(groupIndex, 1);
214
+ const group = state.managers.group.getForValue(groupValue);
215
+
216
+ if (group == null) {
217
+ continue;
218
+ }
219
+
220
+ group.total -= 1;
221
+
222
+ if (group.total > 0) {
223
+ groups.push(group);
224
+
225
+ continue;
226
+ }
227
+
228
+ let groupIndex = groups.indexOf(group);
229
+
230
+ if (groupIndex > -1) {
231
+ groups.splice(groupIndex, 1);
232
+ }
233
+
234
+ groupIndex = state.values.array.indexOf(group.key);
235
+
236
+ if (groupIndex > -1) {
237
+ state.keys.original.splice(groupIndex, 1);
238
+ state.values.array.splice(groupIndex, 1);
239
+ }
240
+
241
+ state.managers.group.remove(group);
242
+
243
+ if (keys.length >= 10_000) {
244
+ await delay(25);
245
+ }
184
246
  }
247
+ }
248
+
249
+ const {length} = groups;
185
250
 
186
- state.managers.group.remove(group);
251
+ for (let index = 0; index < length; index += 1) {
252
+ updateGroup(state, groups[index]);
187
253
  }
188
254
 
189
255
  if (render) {
190
- this.render();
256
+ return this.render();
191
257
  }
192
258
  }
193
259
 
194
260
  render(): void {
195
- const {state, values} = this;
261
+ const {state} = this;
196
262
 
197
263
  if (state.managers.group.enabled) {
198
- sortWithGroups(state, values.objects.array, [
264
+ sortWithGroups(state, state.values.array, [
199
265
  {
200
- direction: 'ascending',
266
+ direction: SORT_ASCENDING,
201
267
  key: state.key,
202
268
  },
203
269
  ]);
204
270
  } else {
205
- sort(values.objects.array as PlainObject[], [
271
+ sort(state.values.array as PlainObject[], [
206
272
  {
207
- direction: 'ascending',
273
+ direction: SORT_ASCENDING,
208
274
  key: state.key,
209
275
  },
210
276
  ]);
211
277
  }
212
278
 
213
- values.keys.original = values.objects.array.map(item =>
214
- item instanceof GroupComponent ? item : (item[state.key] as Key),
279
+ state.keys.original = state.values.array.map(item =>
280
+ typeof item === 'string' ? item : (getValue(item, state.key) as Key),
215
281
  );
216
282
 
217
- values.objects.mapped = toMap(
218
- values.objects.array.filter(item => !(item instanceof GroupComponent)) as PlainObject[],
219
- item => item[state.key] as Key,
283
+ state.values.mapped = toMap(
284
+ state.values.array.filter(item => !isGroupKey(item)) as PlainObject[],
285
+ item => getValue(item, state.key) as Key,
220
286
  );
221
287
 
222
288
  if (Object.keys(state.managers.filter.items).length > 0) {
@@ -229,11 +295,13 @@ export class DataManager {
229
295
  }
230
296
 
231
297
  set(data: PlainObject[]): void {
232
- const {state, values} = this;
298
+ const {state} = this;
233
299
 
234
- const array: Array<GroupComponent | PlainObject> = data.slice();
300
+ const array: DataValue[] = data.slice();
235
301
 
236
302
  if (state.managers.group.enabled) {
303
+ const column = state.managers.column.get(state.managers.group.field);
304
+
237
305
  const grouped = toRecord.arrays(data, state.managers.group.field) as Record<
238
306
  string,
239
307
  PlainObject[]
@@ -247,29 +315,30 @@ export class DataManager {
247
315
  for (let index = 0; index < length; index += 1) {
248
316
  const [value, items] = entries[index];
249
317
 
250
- const key = String(value);
251
-
252
- const group = new GroupComponent(key, key, value);
318
+ const group = new GroupComponent(
319
+ `${column?.options.label ?? state.managers.group.field}: ${value}`,
320
+ value,
321
+ );
253
322
 
254
323
  group.total = items.length;
255
324
 
256
325
  groups.push(group);
257
326
 
258
- array.push(group);
327
+ array.push(group.key);
259
328
  }
260
329
 
261
330
  state.managers.group.set(groups);
262
331
  }
263
332
 
264
- values.objects.array = array;
333
+ state.values.array = array;
265
334
 
266
335
  this.render();
267
336
  }
268
337
 
269
- async synchronize(data: PlainObject[], remove?: boolean): Promise<void> {
270
- const {state, values} = this;
338
+ async synchronize(data: PlainObject[], remove: boolean): Promise<void> {
339
+ const {state} = this;
271
340
 
272
- const add: PlainObject[] = [];
341
+ const added: PlainObject[] = [];
273
342
  const updated: PlainObject[] = [];
274
343
 
275
344
  const keys = new Set<Key>([]);
@@ -278,12 +347,12 @@ export class DataManager {
278
347
 
279
348
  for (let index = 0; index < length; index += 1) {
280
349
  const object = data[index];
281
- const key = object[state.key] as Key;
350
+ const key = getValue(object, state.key) as Key;
282
351
 
283
- if (values.objects.mapped.has(key)) {
352
+ if (state.values.mapped.has(key)) {
284
353
  updated.push(object);
285
354
  } else {
286
- add.push(object);
355
+ added.push(object);
287
356
  }
288
357
 
289
358
  keys.add(key);
@@ -293,9 +362,9 @@ export class DataManager {
293
362
  return;
294
363
  }
295
364
 
296
- if (remove ?? false) {
297
- const toRemove = values.keys.original.filter(
298
- key => !(key instanceof GroupComponent) && !keys.has(key),
365
+ if (remove) {
366
+ const toRemove = state.keys.original.filter(
367
+ key => !isGroupKey(key) && !keys.has(key),
299
368
  ) as Key[];
300
369
 
301
370
  if (toRemove.length > 0) {
@@ -303,30 +372,34 @@ export class DataManager {
303
372
  }
304
373
  }
305
374
 
306
- await this.update(updated);
375
+ await this.update(updated, added.length === 0);
307
376
 
308
- if (add.length > 0) {
309
- await this.add(add, false);
310
- }
377
+ await this.add(added, false);
311
378
 
312
- if (add.length > 0 || (remove ?? false)) {
379
+ if (added.length > 0 || remove) {
313
380
  this.render();
314
381
  }
315
382
  }
316
383
 
317
- async update(data: PlainObject[]): Promise<void> {
318
- const {state, values} = this;
384
+ async update(data: PlainObject[], render: boolean): Promise<void> {
385
+ const {state} = this;
319
386
 
320
387
  const {length} = data;
321
388
 
322
- for (let index = 0; index < length; index += 1) {
323
- const object = data[index];
324
- const key = object[state.key] as Key;
325
- const value = values.objects.mapped.get(key);
389
+ for (let dataIndex = 0; dataIndex < length; dataIndex += 1) {
390
+ const dataItem = data[dataIndex];
391
+
392
+ const key = getValue(dataItem, state.key) as Key;
393
+
394
+ const keyIndex = state.keys.original.indexOf(key);
395
+
396
+ if (keyIndex === -1) {
397
+ continue;
398
+ }
326
399
 
327
- if (value != null) {
328
- values.objects.mapped.set(key, {...value, ...object} as PlainObject);
400
+ Object.assign(state.values.array[keyIndex], dataItem);
329
401
 
402
+ if (render) {
330
403
  state.managers.row.update(key);
331
404
  }
332
405
  }
@@ -1,6 +1,13 @@
1
1
  import {on} from '@oscarpalmer/toretto/event';
2
2
  import {findAncestor} from '@oscarpalmer/toretto/find';
3
3
  import type {State} from '../models/tabela.model';
4
+ import {
5
+ ATTRIBUTE_DATA_EVENT,
6
+ ATTRIBUTE_DATA_FIELD,
7
+ ATTRIBUTE_DATA_SORT_DIRECTION,
8
+ } from '../models/dom.model';
9
+ import {CSS_TABLE} from '../models/style.model';
10
+ import {EVENT_GROUP, EVENT_HEADING, EVENT_ROW} from '../models/event.model';
4
11
 
5
12
  export class EventManager {
6
13
  constructor(public state: State) {
@@ -14,8 +21,8 @@ export class EventManager {
14
21
  }
15
22
 
16
23
  onSort(event: MouseEvent, target: HTMLElement): void {
17
- const direction = target.getAttribute('data-sort-direction');
18
- const field = target.getAttribute('data-field');
24
+ const direction = target.getAttribute(ATTRIBUTE_DATA_SORT_DIRECTION);
25
+ const field = target.getAttribute(ATTRIBUTE_DATA_FIELD);
19
26
 
20
27
  if (field != null) {
21
28
  this.state.managers.sort.toggle(event, field, direction);
@@ -24,8 +31,8 @@ export class EventManager {
24
31
  }
25
32
 
26
33
  function onClick(event: MouseEvent): void {
27
- const target = findAncestor(event, '[data-event]');
28
- const table = findAncestor(event, '.tabela');
34
+ const target = findAncestor(event, eventAttribute);
35
+ const table = findAncestor(event, tableClassName);
29
36
 
30
37
  if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) {
31
38
  return;
@@ -37,18 +44,18 @@ function onClick(event: MouseEvent): void {
37
44
  return;
38
45
  }
39
46
 
40
- const type = target?.getAttribute('data-event');
47
+ const type = target?.getAttribute(ATTRIBUTE_DATA_EVENT);
41
48
 
42
49
  switch (type) {
43
- case 'group':
50
+ case EVENT_GROUP:
44
51
  manager.state.managers.group.handle(target);
45
52
  break;
46
53
 
47
- case 'heading':
54
+ case EVENT_HEADING:
48
55
  manager.onSort(event, target);
49
56
  break;
50
57
 
51
- case 'row':
58
+ case EVENT_ROW:
52
59
  manager.state.managers.selection.handle(event, target);
53
60
  break;
54
61
 
@@ -58,8 +65,8 @@ function onClick(event: MouseEvent): void {
58
65
  }
59
66
 
60
67
  function onKeydown(event: KeyboardEvent): void {
61
- const target = findAncestor(event, '[data-event]');
62
- const table = findAncestor(event, '.tabela');
68
+ const target = findAncestor(event, eventAttribute);
69
+ const table = findAncestor(event, tableClassName);
63
70
 
64
71
  if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) {
65
72
  return;
@@ -71,19 +78,22 @@ function onKeydown(event: KeyboardEvent): void {
71
78
  return;
72
79
  }
73
80
 
74
- const type = target?.getAttribute('data-event');
81
+ if (event.key === ' ') {
82
+ event.preventDefault();
75
83
 
76
- switch (type) {
77
- case 'body':
78
- manager.state.managers.navigation.handle(event);
79
- break;
84
+ // TODO: it's on the way
80
85
 
81
- default:
82
- break;
86
+ return;
83
87
  }
88
+
89
+ manager.state.managers.navigation.handle(event);
84
90
  }
85
91
 
92
+ const eventAttribute = `[${ATTRIBUTE_DATA_EVENT}]`;
93
+
86
94
  const mapped = new WeakMap<HTMLElement, EventManager>();
87
95
 
96
+ const tableClassName = `.${CSS_TABLE}`;
97
+
88
98
  on(document, 'click', onClick);
89
99
  on(document, 'keydown', onKeydown, {passive: false});