@oscarpalmer/tabela 0.10.0 → 0.11.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 (40) hide show
  1. package/dist/components/body.component.js +1 -0
  2. package/dist/components/row.component.js +11 -8
  3. package/dist/managers/column.manager.js +9 -8
  4. package/dist/managers/data.manager.js +26 -22
  5. package/dist/managers/event.manager.js +39 -23
  6. package/dist/managers/filter.manager.js +11 -10
  7. package/dist/managers/navigation.manager.js +73 -0
  8. package/dist/managers/render.manager.js +30 -25
  9. package/dist/managers/row.manager.js +7 -7
  10. package/dist/managers/selection.manager.js +19 -21
  11. package/dist/managers/sort.manager.js +9 -8
  12. package/dist/tabela.full.js +535 -410
  13. package/dist/tabela.js +27 -9
  14. package/package.json +1 -1
  15. package/src/components/body.component.ts +2 -0
  16. package/src/components/row.component.ts +14 -9
  17. package/src/managers/column.manager.ts +11 -13
  18. package/src/managers/data.manager.ts +31 -27
  19. package/src/managers/event.manager.ts +65 -42
  20. package/src/managers/filter.manager.ts +12 -11
  21. package/src/managers/navigation.manager.ts +145 -0
  22. package/src/managers/render.manager.ts +34 -28
  23. package/src/managers/row.manager.ts +9 -14
  24. package/src/managers/selection.manager.ts +24 -30
  25. package/src/managers/sort.manager.ts +14 -14
  26. package/src/models/render.model.ts +3 -1
  27. package/src/models/tabela.model.ts +12 -0
  28. package/src/tabela.ts +34 -9
  29. package/types/components/row.component.d.ts +2 -2
  30. package/types/managers/column.manager.d.ts +4 -5
  31. package/types/managers/data.manager.d.ts +5 -6
  32. package/types/managers/event.manager.d.ts +3 -6
  33. package/types/managers/filter.manager.d.ts +3 -3
  34. package/types/managers/navigation.manager.d.ts +10 -0
  35. package/types/managers/render.manager.d.ts +4 -6
  36. package/types/managers/row.manager.d.ts +4 -5
  37. package/types/managers/selection.manager.d.ts +3 -4
  38. package/types/managers/sort.manager.d.ts +4 -4
  39. package/types/models/render.model.d.ts +2 -1
  40. package/types/models/tabela.model.d.ts +11 -0
@@ -0,0 +1,145 @@
1
+ import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
2
+ import type {Key} from '@oscarpalmer/atoms/models';
3
+ import {clamp} from '@oscarpalmer/atoms/number';
4
+ import {getKey} from '../helpers/misc.helpers';
5
+ import type {TabelaState} from '../models/tabela.model';
6
+
7
+ export class NavigationManager {
8
+ active: Key | undefined;
9
+
10
+ constructor(public state: TabelaState) {}
11
+
12
+ destroy(): void {
13
+ this.state = undefined as never;
14
+ }
15
+
16
+ handle(event: KeyboardEvent): void {
17
+ if (!allKeys.has(event.key)) {
18
+ return;
19
+ }
20
+
21
+ event.preventDefault();
22
+
23
+ const {components, id, managers} = this.state;
24
+
25
+ const activeDescendant = components.body.elements.group.getAttribute('aria-activedescendant');
26
+
27
+ const keys = managers.data.values.keys.active ?? managers.data.values.keys.original;
28
+ const {length} = keys;
29
+
30
+ let next: number;
31
+
32
+ if (isNullableOrWhitespace(activeDescendant)) {
33
+ next = getDefaultIndex(event.key, length);
34
+ } else {
35
+ next = getIndex(event, activeDescendant, id, keys)!;
36
+ }
37
+
38
+ if (next != null) {
39
+ this.setActive(keys.at(next)!);
40
+ }
41
+ }
42
+
43
+ setActive(key: Key | undefined, scroll?: boolean): void {
44
+ const {components, managers, options} = this.state;
45
+
46
+ this.active = key;
47
+
48
+ const active = components.body.elements.group.querySelectorAll('[data-active="true"]');
49
+
50
+ for (const item of active) {
51
+ item.setAttribute('data-active', 'false');
52
+ }
53
+
54
+ const row = managers.row.get(key!);
55
+
56
+ if (row != null) {
57
+ row.element?.setAttribute('data-active', 'true');
58
+
59
+ if (scroll ?? true) {
60
+ if (row.element == null) {
61
+ components.body.elements.group.scrollTo({
62
+ top: managers.data.getIndex(key!) * options.rowHeight,
63
+ behavior: 'smooth',
64
+ });
65
+ } else {
66
+ row.element.scrollIntoView({
67
+ block: 'nearest',
68
+ });
69
+ }
70
+ }
71
+ }
72
+
73
+ components.body.elements.group.setAttribute(
74
+ 'aria-activedescendant',
75
+ row == null ? '' : `tabela_${this.state.id}_row_${key}`,
76
+ );
77
+ }
78
+ }
79
+
80
+ function getDefaultIndex(key: string, max: number): number {
81
+ switch (true) {
82
+ case negativeDefaultKeys.has(key):
83
+ return -1;
84
+
85
+ case key === 'PageDown':
86
+ return Math.min(9, max - 1);
87
+
88
+ case key === 'PageUp':
89
+ return max < 10 ? 0 : max - 10;
90
+
91
+ default:
92
+ return 0;
93
+ }
94
+ }
95
+
96
+ function getIndex(
97
+ event: KeyboardEvent,
98
+ active: string,
99
+ id: number,
100
+ keys: Key[],
101
+ ): number | undefined {
102
+ const key = getKey(active.replace(`tabela_${id}_row_`, ''));
103
+
104
+ if (key == null) {
105
+ return;
106
+ }
107
+
108
+ if (absoluteKeys.has(event.key)) {
109
+ return event.key === 'Home' ? 0 : keys.length - 1;
110
+ }
111
+
112
+ const index = keys.indexOf(key);
113
+ const offset = getOffset(event.key);
114
+
115
+ return clamp(index + offset, 0, keys.length - 1, true);
116
+ }
117
+
118
+ function getOffset(key: string): number {
119
+ switch (key) {
120
+ case 'ArrowDown':
121
+ return 1;
122
+
123
+ case 'ArrowUp':
124
+ return -1;
125
+
126
+ case 'PageDown':
127
+ return 10;
128
+
129
+ case 'PageUp':
130
+ return -10;
131
+
132
+ default:
133
+ return 0;
134
+ }
135
+ }
136
+
137
+ const absoluteKeys = new Set(['End', 'Home']);
138
+
139
+ const arrowKeys = new Set(['ArrowDown', 'ArrowUp']);
140
+
141
+ const negativeDefaultKeys = new Set(['ArrowUp', 'End']);
142
+
143
+ const pageKeys = new Set(['PageDown', 'PageUp']);
144
+
145
+ const allKeys = new Set([...absoluteKeys, ...arrowKeys, ...pageKeys]);
@@ -3,21 +3,21 @@ import {on} from '@oscarpalmer/toretto/event';
3
3
  import type {RemovableEventListener} from '@oscarpalmer/toretto/models';
4
4
  import {removeRow, renderRow} from '../components/row.component';
5
5
  import type {RenderElementPool, RenderRange, RenderState} from '../models/render.model';
6
- import type {TabelaComponents, TabelaManagers} from '../models/tabela.model';
6
+ import type {TabelaState} from '../models/tabela.model';
7
7
 
8
8
  function getRange(this: RenderManager, down: boolean): RenderRange {
9
- const {components, managers} = this;
9
+ const {components, managers, options} = this.state;
10
10
  const {clientHeight, scrollTop} = components.body.elements.group;
11
11
 
12
- const first = Math.floor(scrollTop / managers.row.height);
12
+ const first = Math.floor(scrollTop / options.rowHeight);
13
13
 
14
14
  const last = Math.min(
15
15
  (managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length) - 1,
16
- Math.ceil((scrollTop + clientHeight) / managers.row.height) - 1,
16
+ Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1,
17
17
  );
18
18
 
19
- const before = Math.ceil(clientHeight / managers.row.height) * (down ? 1 : 2);
20
- const after = Math.ceil(clientHeight / managers.row.height) * (down ? 2 : 1);
19
+ const before = Math.ceil(clientHeight / options.rowHeight) * (down ? 1 : 2);
20
+ const after = Math.ceil(clientHeight / options.rowHeight) * (down ? 2 : 1);
21
21
 
22
22
  const start = Math.max(0, first - before);
23
23
 
@@ -30,17 +30,19 @@ function getRange(this: RenderManager, down: boolean): RenderRange {
30
30
  }
31
31
 
32
32
  function onScroll(this: RenderManager): void {
33
- if (!this.state.active) {
33
+ const {state} = this;
34
+
35
+ if (!state.active) {
34
36
  requestAnimationFrame(() => {
35
- const top = this.components.body.elements.group.scrollTop;
37
+ const top = state.components.body.elements.group.scrollTop;
36
38
 
37
- this.update(top > this.state.top);
39
+ this.update(top > state.top);
38
40
 
39
- this.state.active = false;
40
- this.state.top = top;
41
+ state.active = false;
42
+ state.top = top;
41
43
  });
42
44
 
43
- this.state.active = true;
45
+ state.active = true;
44
46
  }
45
47
  }
46
48
 
@@ -49,23 +51,23 @@ export class RenderManager {
49
51
 
50
52
  listener: RemovableEventListener;
51
53
 
52
- readonly pool: RenderElementPool = {
54
+ pool: RenderElementPool = {
53
55
  cells: {},
54
56
  rows: [],
55
57
  };
56
58
 
57
- readonly state: RenderState = {
58
- active: false,
59
- top: 0,
60
- };
59
+ state: RenderState;
61
60
 
62
61
  visible = new Map<number, Key>();
63
62
 
64
- constructor(
65
- public managers: TabelaManagers,
66
- public components: TabelaComponents,
67
- ) {
68
- this.listener = on(components.body.elements.group, 'scroll', onScroll.bind(this));
63
+ constructor(state: TabelaState) {
64
+ this.listener = on(state.components.body.elements.group, 'scroll', onScroll.bind(this));
65
+
66
+ this.state = {
67
+ ...state,
68
+ active: false,
69
+ top: 0,
70
+ };
69
71
  }
70
72
 
71
73
  destroy(): void {
@@ -77,12 +79,15 @@ export class RenderManager {
77
79
  pool.cells = {};
78
80
  pool.rows = [];
79
81
 
82
+ this.fragment = undefined as never;
80
83
  this.listener = undefined as never;
84
+ this.pool = undefined as never;
85
+ this.state = undefined as never;
81
86
  this.visible = undefined as never;
82
87
  }
83
88
 
84
89
  removeCells(fields: string[]): void {
85
- const {managers, pool, visible} = this;
90
+ const {pool, state, visible} = this;
86
91
  const {length} = fields;
87
92
 
88
93
  for (let index = 0; index < length; index += 1) {
@@ -90,7 +95,7 @@ export class RenderManager {
90
95
  }
91
96
 
92
97
  for (const [, key] of visible) {
93
- const row = managers.row.get(key);
98
+ const row = state.managers.row.get(key);
94
99
 
95
100
  if (row == null || row.element == null) {
96
101
  continue;
@@ -115,9 +120,10 @@ export class RenderManager {
115
120
  }
116
121
 
117
122
  update(down: boolean, rerender?: boolean): void {
118
- const {components, managers, pool, visible} = this;
123
+ const {state, pool, visible} = this;
124
+ const {components, managers, options} = state;
119
125
 
120
- components.body.elements.faker.style.height = `${managers.data.size * managers.row.height}px`;
126
+ components.body.elements.faker.style.height = `${managers.data.size * options.rowHeight}px`;
121
127
 
122
128
  const indices = new Set<number>();
123
129
  const range = getRange.call(this, down);
@@ -160,12 +166,12 @@ export class RenderManager {
160
166
 
161
167
  count += 1;
162
168
 
163
- renderRow(managers, row);
169
+ renderRow(state, row);
164
170
 
165
171
  visible.set(index, key);
166
172
 
167
173
  if (row.element != null) {
168
- row.element.style.transform = `translateY(${index * managers.row.height}px)`;
174
+ row.element.style.transform = `translateY(${index * options.rowHeight}px)`;
169
175
 
170
176
  fragment.append(row.element);
171
177
  }
@@ -1,29 +1,24 @@
1
1
  import type {Key} from '@oscarpalmer/atoms/models';
2
2
  import {removeRow, renderRow, RowComponent} from '../components/row.component';
3
- import type {TabelaManagers} from '../models/tabela.model';
3
+ import type {TabelaState} from '../models/tabela.model';
4
4
 
5
5
  export class RowManager {
6
- readonly components: Map<Key, RowComponent> = new Map();
6
+ components = new Map<Key, RowComponent>();
7
7
 
8
- readonly height: number;
9
-
10
- constructor(
11
- readonly managers: TabelaManagers,
12
- rowHeight: number,
13
- ) {
14
- this.height = rowHeight;
15
- }
8
+ constructor(public state: TabelaState) {}
16
9
 
17
10
  destroy(): void {
18
11
  const components = [...this.components.values()];
19
-
20
12
  const {length} = components;
21
13
 
22
14
  for (let index = 0; index < length; index += 1) {
23
- removeRow(this.managers.render.pool, components[index]);
15
+ removeRow(this.state.managers.render.pool, components[index]);
24
16
  }
25
17
 
26
18
  this.components.clear();
19
+
20
+ this.components = undefined as never;
21
+ this.state = undefined as never;
27
22
  }
28
23
 
29
24
  get(key: Key): RowComponent | undefined {
@@ -46,7 +41,7 @@ export class RowManager {
46
41
  const row = this.components.get(key);
47
42
 
48
43
  if (row != null) {
49
- removeRow(this.managers.render.pool, row);
44
+ removeRow(this.state.managers.render.pool, row);
50
45
 
51
46
  this.components.delete(key);
52
47
  }
@@ -56,7 +51,7 @@ export class RowManager {
56
51
  const row = this.components.get(key);
57
52
 
58
53
  if (row != null) {
59
- renderRow(this.managers, row);
54
+ renderRow(this.state, row);
60
55
  }
61
56
  }
62
57
  }
@@ -6,7 +6,7 @@ import {getPosition, on} from '@oscarpalmer/toretto/event';
6
6
  import {createElement} from '../helpers/dom.helpers';
7
7
  import {getKey} from '../helpers/misc.helpers';
8
8
  import {dragStyling} from '../helpers/style.helper';
9
- import type {TabelaManagers, TabelaSelection} from '../models/tabela.model';
9
+ import type {TabelaSelection, TabelaState} from '../models/tabela.model';
10
10
 
11
11
  export class SelectionManager {
12
12
  handlers = Object.freeze({
@@ -20,11 +20,8 @@ export class SelectionManager {
20
20
 
21
21
  last: Key | undefined;
22
22
 
23
- constructor(
24
- public element: HTMLElement,
25
- readonly managers: TabelaManagers,
26
- ) {
27
- mapped.set(element, this);
23
+ constructor(public state: TabelaState) {
24
+ mapped.set(state.element, this);
28
25
  }
29
26
 
30
27
  clear(): void {
@@ -58,11 +55,12 @@ export class SelectionManager {
58
55
  }
59
56
 
60
57
  destroy(): void {
61
- mapped.delete(this.element);
58
+ mapped.delete(this.state.element);
62
59
 
63
60
  this.handlers = undefined as never;
64
- this.element = undefined as never;
65
61
  this.items = undefined as never;
62
+ this.last = undefined;
63
+ this.state = undefined as never;
66
64
  }
67
65
 
68
66
  handle(event: MouseEvent, target: HTMLElement): void {
@@ -76,20 +74,18 @@ export class SelectionManager {
76
74
 
77
75
  if (event.shiftKey) {
78
76
  if (this.last == null) {
79
- this.last = key;
80
-
81
- return;
77
+ this.state.managers.navigation.setActive(key, false);
78
+ } else {
79
+ this.range(this.last, key);
82
80
  }
83
81
 
84
- this.range(this.last, key);
85
-
86
- this.last = key;
87
-
88
82
  return;
89
83
  }
90
84
 
91
85
  this.last = key;
92
86
 
87
+ this.state.managers.navigation.setActive(key, false);
88
+
93
89
  if (event.ctrlKey || event.metaKey) {
94
90
  if (items.has(key)) {
95
91
  this.deselect([key]);
@@ -100,18 +96,12 @@ export class SelectionManager {
100
96
  return;
101
97
  }
102
98
 
103
- if (items.has(key)) {
104
- if (items.size === 1) {
105
- this.clear();
106
- } else {
107
- this.set([key]);
108
- }
109
- } else {
110
- this.set([key]);
111
- }
99
+ this.set([key]);
112
100
  }
113
101
 
114
102
  range(from: Key | HTMLElement, to: Key | HTMLElement): void {
103
+ const {state} = this;
104
+
115
105
  const keyed = isKey(from) && isKey(to);
116
106
 
117
107
  const fromKey = keyed ? (from as Key) : getKey((from as HTMLElement).getAttribute('data-key'))!;
@@ -121,10 +111,10 @@ export class SelectionManager {
121
111
  return;
122
112
  }
123
113
 
124
- const keys = this.managers.data.values.keys.active ?? this.managers.data.values.keys.original;
114
+ const keys = state.managers.data.values.keys.active ?? state.managers.data.values.keys.original;
125
115
 
126
- const fromIndex = keys.indexOf(fromKey);
127
- const toIndex = keys.indexOf(toKey);
116
+ const fromIndex = state.managers.data.getIndex(fromKey);
117
+ const toIndex = state.managers.data.getIndex(toKey);
128
118
 
129
119
  if (fromIndex === -1 || toIndex === -1) {
130
120
  return;
@@ -143,6 +133,10 @@ export class SelectionManager {
143
133
  } else {
144
134
  this.set(selected);
145
135
  }
136
+
137
+ this.last = toKey;
138
+
139
+ this.state.managers.navigation.setActive(toKey, false);
146
140
  }
147
141
 
148
142
  select(keys: Key[]): void {
@@ -181,9 +175,9 @@ export class SelectionManager {
181
175
  }
182
176
 
183
177
  toggle(): void {
184
- const {items, managers} = this;
178
+ const {items, state} = this;
185
179
 
186
- const all = managers.data.values.keys.active ?? managers.data.values.keys.original;
180
+ const all = state.managers.data.values.keys.active ?? state.managers.data.values.keys.original;
187
181
 
188
182
  if (items.size === all.length) {
189
183
  this.clear();
@@ -203,7 +197,7 @@ export class SelectionManager {
203
197
  for (let index = 0; index < length; index += 1) {
204
198
  const {key, removed} = items[index];
205
199
 
206
- const row = this.managers.row.get(key);
200
+ const row = this.state.managers.row.get(key);
207
201
 
208
202
  if (row == null || row.element == null) {
209
203
  continue;
@@ -2,7 +2,7 @@ import {sort, type ArrayKeySorter} from '@oscarpalmer/atoms/array';
2
2
  import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
3
3
  import {setAttribute, setAttributes} from '@oscarpalmer/toretto/attribute';
4
4
  import type {SortDirection, SortItem} from '../models/sort.model';
5
- import type {TabelaManagers, TabelaSort} from '../models/tabela.model';
5
+ import type {TabelaSort, TabelaState} from '../models/tabela.model';
6
6
 
7
7
  export class SortManager {
8
8
  handlers = Object.freeze({
@@ -13,9 +13,9 @@ export class SortManager {
13
13
  set: items => this.set(items),
14
14
  } satisfies TabelaSort);
15
15
 
16
- readonly items: ArrayKeySorter<PlainObject>[] = [];
16
+ items: ArrayKeySorter<PlainObject>[] = [];
17
17
 
18
- constructor(readonly managers: TabelaManagers) {}
18
+ constructor(public state: TabelaState) {}
19
19
 
20
20
  add(field: string, direction?: SortDirection): void {
21
21
  const index = this.items.findIndex(item => item.key === field);
@@ -50,7 +50,8 @@ export class SortManager {
50
50
 
51
51
  destroy(): void {
52
52
  this.handlers = undefined as never;
53
- this.items.length = 0;
53
+ this.items = undefined as never;
54
+ this.state = undefined as never;
54
55
  }
55
56
 
56
57
  flip(field: string): void {
@@ -94,12 +95,12 @@ export class SortManager {
94
95
  }
95
96
 
96
97
  sort(): void {
97
- const {items, managers} = this;
98
+ const {items, state} = this;
98
99
 
99
- const {length} = managers.column.items;
100
+ const {length} = state.managers.column.items;
100
101
 
101
102
  for (let index = 0; index < length; index += 1) {
102
- const column = managers.column.items[index];
103
+ const column = state.managers.column.items[index];
103
104
 
104
105
  const sorterIndex = items.findIndex(item => item.key === column.options.field);
105
106
  const sorterItem = items[sorterIndex];
@@ -117,18 +118,17 @@ export class SortManager {
117
118
  );
118
119
  }
119
120
 
120
- managers.data.values.keys.active =
121
+ state.managers.data.values.keys.active =
121
122
  items.length === 0
122
123
  ? undefined
123
124
  : (sort(
124
- managers.data.values.keys.active?.map(
125
- key => managers.data.values.objects.mapped.get(key)!,
126
- ) ??
127
- managers.data.values.objects.array,
125
+ state.managers.data.values.keys.active?.map(
126
+ key => state.managers.data.values.objects.mapped.get(key)!,
127
+ ) ?? state.managers.data.values.objects.array,
128
128
  items,
129
- ).map(row => row[managers.data.field]) as Key[]);
129
+ ).map(row => row[state.key]) as Key[]);
130
130
 
131
- managers.render.update(true, true);
131
+ state.managers.render.update(true, true);
132
132
  }
133
133
 
134
134
  toggle(event: MouseEvent, field: string, direction?: string | null): void {
@@ -1,3 +1,5 @@
1
+ import type {TabelaState} from './tabela.model';
2
+
1
3
  export type RenderElementPool = {
2
4
  cells: Record<string, HTMLDivElement[]>;
3
5
  rows: HTMLDivElement[];
@@ -11,4 +13,4 @@ export type RenderRange = {
11
13
  export type RenderState = {
12
14
  active: boolean;
13
15
  top: number;
14
- };
16
+ } & TabelaState;
@@ -6,12 +6,14 @@ import type {ColumnManager} from '../managers/column.manager';
6
6
  import type {DataManager} from '../managers/data.manager';
7
7
  import type {EventManager} from '../managers/event.manager';
8
8
  import type {FilterManager} from '../managers/filter.manager';
9
+ import type {NavigationManager} from '../managers/navigation.manager';
9
10
  import type {RenderManager} from '../managers/render.manager';
10
11
  import type {RowManager} from '../managers/row.manager';
11
12
  import type {SelectionManager} from '../managers/selection.manager';
12
13
  import type {SortManager} from '../managers/sort.manager';
13
14
  import type {FilterItem} from './filter.model';
14
15
  import type {SortDirection, SortItem} from './sort.model';
16
+ import type {TabelaOptions} from './tabela.options';
15
17
 
16
18
  export type TabelaComponents = {
17
19
  body: BodyComponent;
@@ -42,6 +44,7 @@ export type TabelaManagers = {
42
44
  data: DataManager;
43
45
  event: EventManager;
44
46
  filter: FilterManager;
47
+ navigation: NavigationManager;
45
48
  row: RowManager;
46
49
  selection: SelectionManager;
47
50
  sort: SortManager;
@@ -62,3 +65,12 @@ export type TabelaSort = {
62
65
  remove(field: string): void;
63
66
  set(items: SortItem[]): void;
64
67
  };
68
+
69
+ export type TabelaState = {
70
+ readonly components: TabelaComponents;
71
+ readonly element: HTMLElement;
72
+ readonly id: number;
73
+ readonly key: string;
74
+ readonly managers: TabelaManagers;
75
+ readonly options: TabelaOptions;
76
+ };
package/src/tabela.ts CHANGED
@@ -5,10 +5,11 @@ import {ColumnManager} from './managers/column.manager';
5
5
  import {DataManager} from './managers/data.manager';
6
6
  import {EventManager} from './managers/event.manager';
7
7
  import {FilterManager} from './managers/filter.manager';
8
+ import {NavigationManager} from './managers/navigation.manager';
9
+ import {RenderManager} from './managers/render.manager';
8
10
  import {RowManager} from './managers/row.manager';
9
11
  import {SelectionManager} from './managers/selection.manager';
10
12
  import {SortManager} from './managers/sort.manager';
11
- import {RenderManager} from './managers/render.manager';
12
13
  import type {
13
14
  TabelaComponents,
14
15
  TabelaData,
@@ -16,6 +17,7 @@ import type {
16
17
  TabelaManagers,
17
18
  TabelaSelection,
18
19
  TabelaSort,
20
+ TabelaState,
19
21
  } from './models/tabela.model';
20
22
  import type {TabelaOptions} from './models/tabela.options';
21
23
 
@@ -28,6 +30,8 @@ export class Tabela {
28
30
 
29
31
  #element: HTMLElement;
30
32
 
33
+ #id = getId();
34
+
31
35
  readonly #key: string;
32
36
 
33
37
  readonly #managers: TabelaManagers = {
@@ -35,6 +39,7 @@ export class Tabela {
35
39
  data: undefined as never,
36
40
  event: undefined as never,
37
41
  filter: undefined as never,
42
+ navigation: undefined as never,
38
43
  render: undefined as never,
39
44
  row: undefined as never,
40
45
  selection: undefined as never,
@@ -69,14 +74,24 @@ export class Tabela {
69
74
  this.#components.body = new BodyComponent();
70
75
  this.#components.footer = new FooterComponent();
71
76
 
72
- this.#managers.column = new ColumnManager(this.#managers, this.#components, options.columns);
73
- this.#managers.data = new DataManager(this.#managers, this.#components, options.key);
74
- this.#managers.event = new EventManager(this.#element, this.#managers);
75
- this.#managers.filter = new FilterManager(this.#managers);
76
- this.#managers.render = new RenderManager(this.#managers, this.#components);
77
- this.#managers.row = new RowManager(this.#managers, options.rowHeight);
78
- this.#managers.selection = new SelectionManager(this.#element, this.#managers);
79
- this.#managers.sort = new SortManager(this.#managers);
77
+ const state: TabelaState = {
78
+ element,
79
+ options,
80
+ components: this.#components,
81
+ id: this.#id,
82
+ key: this.#key,
83
+ managers: this.#managers,
84
+ };
85
+
86
+ this.#managers.column = new ColumnManager(state);
87
+ this.#managers.data = new DataManager(state);
88
+ this.#managers.event = new EventManager(state);
89
+ this.#managers.filter = new FilterManager(state);
90
+ this.#managers.navigation = new NavigationManager(state);
91
+ this.#managers.render = new RenderManager(state);
92
+ this.#managers.row = new RowManager(state);
93
+ this.#managers.selection = new SelectionManager(state);
94
+ this.#managers.sort = new SortManager(state);
80
95
 
81
96
  element.append(
82
97
  this.#components.header.elements.group,
@@ -105,8 +120,10 @@ export class Tabela {
105
120
  managers.data.destroy();
106
121
  managers.event.destroy();
107
122
  managers.filter.destroy();
123
+ // managers.navigation.destroy();
108
124
  managers.render.destroy();
109
125
  managers.row.destroy();
126
+ managers.selection.destroy();
110
127
  managers.sort.destroy();
111
128
 
112
129
  element.innerHTML = '';
@@ -119,3 +136,11 @@ export class Tabela {
119
136
  this.#element = undefined as never;
120
137
  }
121
138
  }
139
+
140
+ function getId(): number {
141
+ id += 1;
142
+
143
+ return id;
144
+ }
145
+
146
+ let id = 0;
@@ -1,8 +1,8 @@
1
1
  import type { Key } from '@oscarpalmer/atoms/models';
2
2
  import type { RenderElementPool } from '../models/render.model';
3
- import type { TabelaManagers } from '../models/tabela.model';
3
+ import type { TabelaState } from '../models/tabela.model';
4
4
  export declare function removeRow(pool: RenderElementPool, row: RowComponent): void;
5
- export declare function renderRow(managers: TabelaManagers, row: RowComponent): void;
5
+ export declare function renderRow(state: TabelaState, row: RowComponent): void;
6
6
  export declare class RowComponent {
7
7
  readonly key: Key;
8
8
  cells: Record<string, HTMLDivElement>;