@oscarpalmer/tabela 0.11.0 → 0.13.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 (159) hide show
  1. package/dist/body.component-_VDOpJhV.d.mts +10 -0
  2. package/dist/body.model-2iwsovAV.d.mts +7 -0
  3. package/dist/column.component-Bx46r3JI.d.mts +16 -0
  4. package/dist/column.model-D-aw4EU4.d.mts +16 -0
  5. package/dist/components/body.component.d.mts +2 -0
  6. package/dist/components/{body.component.js → body.component.mjs} +6 -3
  7. package/dist/components/column.component.d.mts +2 -0
  8. package/dist/components/{column.component.js → column.component.mjs} +12 -9
  9. package/dist/components/footer.component.d.mts +2 -0
  10. package/dist/components/{footer.component.js → footer.component.mjs} +7 -4
  11. package/dist/components/group.component.d.mts +2 -0
  12. package/dist/components/group.component.mjs +51 -0
  13. package/dist/components/header.component.d.mts +2 -0
  14. package/dist/components/{header.component.js → header.component.mjs} +6 -3
  15. package/dist/components/row.component.d.mts +2 -0
  16. package/dist/components/{row.component.js → row.component.mjs} +11 -7
  17. package/dist/filter.model-7ukJrtil.d.mts +16 -0
  18. package/dist/footer.component-Curiab8j.d.mts +12 -0
  19. package/dist/footer.model-DhqoS6ds.d.mts +8 -0
  20. package/dist/group.component-Cq1YYbfJ.d.mts +285 -0
  21. package/dist/group.model-BsKFwHbt.d.mts +10 -0
  22. package/dist/header.component-BjjlpZIg.d.mts +12 -0
  23. package/dist/header.model-DN_KzUCV.d.mts +7 -0
  24. package/dist/helpers/dom.helpers.d.mts +12 -0
  25. package/dist/helpers/{dom.helpers.js → dom.helpers.mjs} +14 -10
  26. package/dist/helpers/misc.helpers.d.mts +6 -0
  27. package/dist/helpers/{misc.helpers.js → misc.helpers.mjs} +3 -1
  28. package/dist/helpers/style.helper.d.mts +6 -0
  29. package/dist/helpers/style.helper.mjs +8 -0
  30. package/dist/index.d.mts +7 -0
  31. package/dist/{index.js → index.mjs} +3 -1
  32. package/dist/managers/column.manager.d.mts +2 -0
  33. package/dist/managers/{column.manager.js → column.manager.mjs} +6 -1
  34. package/dist/managers/data.manager.d.mts +2 -0
  35. package/dist/managers/data.manager.mjs +222 -0
  36. package/dist/managers/event.manager.d.mts +2 -0
  37. package/dist/managers/{event.manager.js → event.manager.mjs} +12 -8
  38. package/dist/managers/filter.manager.d.mts +2 -0
  39. package/dist/managers/{filter.manager.js → filter.manager.mjs} +25 -11
  40. package/dist/managers/group.manager.d.mts +2 -0
  41. package/dist/managers/group.manager.mjs +73 -0
  42. package/dist/managers/navigation.manager.d.mts +2 -0
  43. package/dist/managers/{navigation.manager.js → navigation.manager.mjs} +27 -24
  44. package/dist/managers/render.manager.d.mts +2 -0
  45. package/dist/managers/render.manager.mjs +144 -0
  46. package/dist/managers/row.manager.d.mts +2 -0
  47. package/dist/managers/{row.manager.js → row.manager.mjs} +18 -11
  48. package/dist/managers/selection.manager.d.mts +2 -0
  49. package/dist/managers/{selection.manager.js → selection.manager.mjs} +57 -48
  50. package/dist/managers/sort.manager.d.mts +2 -0
  51. package/dist/managers/{sort.manager.js → sort.manager.mjs} +32 -2
  52. package/dist/managers/style.manager.d.mts +2 -0
  53. package/dist/managers/style.manager.mjs +149 -0
  54. package/dist/models/body.model.d.mts +2 -0
  55. package/dist/models/body.model.mjs +1 -0
  56. package/dist/models/column.model.d.mts +2 -0
  57. package/dist/models/column.model.mjs +1 -0
  58. package/dist/models/data.model.d.mts +2 -0
  59. package/dist/models/data.model.mjs +1 -0
  60. package/dist/models/filter.model.d.mts +2 -0
  61. package/dist/models/filter.model.mjs +1 -0
  62. package/dist/models/footer.model.d.mts +2 -0
  63. package/dist/models/footer.model.mjs +1 -0
  64. package/dist/models/group.model.d.mts +2 -0
  65. package/dist/models/group.model.mjs +1 -0
  66. package/dist/models/header.model.d.mts +2 -0
  67. package/dist/models/header.model.mjs +1 -0
  68. package/dist/models/render.model.d.mts +2 -0
  69. package/dist/models/render.model.mjs +1 -0
  70. package/dist/models/selection.model.d.mts +2 -0
  71. package/dist/models/selection.model.mjs +1 -0
  72. package/dist/models/sort.model.d.mts +2 -0
  73. package/dist/models/sort.model.mjs +1 -0
  74. package/dist/models/style.model.d.mts +23 -0
  75. package/dist/models/style.model.mjs +23 -0
  76. package/dist/models/tabela.model.d.mts +2 -0
  77. package/dist/models/tabela.model.mjs +1 -0
  78. package/dist/models/tabela.options.d.mts +2 -0
  79. package/dist/models/tabela.options.mjs +1 -0
  80. package/dist/selection.model-rwQe9fco.d.mts +12 -0
  81. package/dist/sort.model-CauImaLu.d.mts +15 -0
  82. package/dist/tabela.d.mts +21 -0
  83. package/dist/{tabela.full.js → tabela.full.mjs} +1407 -1124
  84. package/dist/tabela.mjs +126 -0
  85. package/dist/tabela.options-RkZvfptB.d.mts +14 -0
  86. package/package.json +45 -37
  87. package/src/components/body.component.ts +4 -3
  88. package/src/components/column.component.ts +19 -24
  89. package/src/components/footer.component.ts +8 -3
  90. package/src/components/group.component.ts +85 -0
  91. package/src/components/header.component.ts +3 -2
  92. package/src/components/row.component.ts +10 -8
  93. package/src/helpers/dom.helpers.ts +24 -20
  94. package/src/helpers/style.helper.ts +1 -1
  95. package/src/managers/column.manager.ts +8 -4
  96. package/src/managers/data.manager.ts +265 -61
  97. package/src/managers/event.manager.ts +14 -11
  98. package/src/managers/filter.manager.ts +38 -19
  99. package/src/managers/group.manager.ts +131 -0
  100. package/src/managers/navigation.manager.ts +25 -23
  101. package/src/managers/render.manager.ts +84 -32
  102. package/src/managers/row.manager.ts +23 -11
  103. package/src/managers/selection.manager.ts +68 -54
  104. package/src/managers/sort.manager.ts +81 -16
  105. package/src/managers/style.manager.ts +156 -0
  106. package/src/models/column.model.ts +2 -2
  107. package/src/models/data.model.ts +23 -9
  108. package/src/models/filter.model.ts +11 -3
  109. package/src/models/group.model.ts +8 -0
  110. package/src/models/render.model.ts +2 -2
  111. package/src/models/selection.model.ts +9 -0
  112. package/src/models/sort.model.ts +11 -3
  113. package/src/models/style.model.ts +39 -0
  114. package/src/models/tabela.model.ts +14 -46
  115. package/src/models/tabela.options.ts +3 -2
  116. package/src/tabela.ts +72 -41
  117. package/dist/helpers/style.helper.js +0 -6
  118. package/dist/managers/data.manager.js +0 -120
  119. package/dist/managers/render.manager.js +0 -110
  120. package/dist/models/body.model.js +0 -0
  121. package/dist/models/column.model.js +0 -0
  122. package/dist/models/data.model.js +0 -0
  123. package/dist/models/filter.model.js +0 -0
  124. package/dist/models/footer.model.js +0 -0
  125. package/dist/models/header.model.js +0 -0
  126. package/dist/models/render.model.js +0 -0
  127. package/dist/models/sort.model.js +0 -0
  128. package/dist/models/tabela.model.js +0 -0
  129. package/dist/models/tabela.options.js +0 -0
  130. package/dist/tabela.js +0 -102
  131. package/types/components/body.component.d.ts +0 -6
  132. package/types/components/column.component.d.ts +0 -13
  133. package/types/components/footer.component.d.ts +0 -8
  134. package/types/components/header.component.d.ts +0 -8
  135. package/types/components/row.component.d.ts +0 -11
  136. package/types/helpers/dom.helpers.d.ts +0 -10
  137. package/types/helpers/misc.helpers.d.ts +0 -2
  138. package/types/helpers/style.helper.d.ts +0 -1
  139. package/types/index.d.ts +0 -4
  140. package/types/managers/column.manager.d.ts +0 -12
  141. package/types/managers/data.manager.d.ts +0 -27
  142. package/types/managers/event.manager.d.ts +0 -7
  143. package/types/managers/filter.manager.d.ts +0 -19
  144. package/types/managers/navigation.manager.d.ts +0 -10
  145. package/types/managers/render.manager.d.ts +0 -16
  146. package/types/managers/row.manager.d.ts +0 -13
  147. package/types/managers/selection.manager.d.ts +0 -18
  148. package/types/managers/sort.manager.d.ts +0 -26
  149. package/types/models/body.model.d.ts +0 -4
  150. package/types/models/column.model.d.ts +0 -13
  151. package/types/models/data.model.d.ts +0 -14
  152. package/types/models/filter.model.d.ts +0 -6
  153. package/types/models/footer.model.d.ts +0 -5
  154. package/types/models/header.model.d.ts +0 -4
  155. package/types/models/render.model.d.ts +0 -13
  156. package/types/models/sort.model.d.ts +0 -5
  157. package/types/models/tabela.model.d.ts +0 -69
  158. package/types/models/tabela.options.d.ts +0 -9
  159. package/types/tabela.d.ts +0 -12
@@ -0,0 +1,131 @@
1
+ import {sort} from '@oscarpalmer/atoms/array';
2
+ import {toRecord} from '@oscarpalmer/atoms/array/to-record';
3
+ import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
4
+ import type {Key, Simplify} from '@oscarpalmer/atoms/models';
5
+ import {getString} from '@oscarpalmer/atoms/string';
6
+ import {removeGroup, type GroupComponent} from '../components/group.component';
7
+ import type {TabelaGroup} from '../models/group.model';
8
+ import type {State} from '../models/tabela.model';
9
+
10
+ export class GroupManager {
11
+ collapsed = new Set<Key>();
12
+
13
+ enabled = false;
14
+
15
+ field!: string;
16
+
17
+ handlers = Object.freeze({
18
+ set: (group?: string) => {
19
+ if (group === this.field) {
20
+ return;
21
+ }
22
+
23
+ this.enabled = !isNullableOrWhitespace(group);
24
+ this.field = group ?? '';
25
+
26
+ this.state.managers.data.set(this.state.managers.data.get());
27
+ },
28
+ } satisfies TabelaGroup);
29
+
30
+ items: GroupComponent[] = [];
31
+
32
+ order: Record<never, number> = {};
33
+
34
+ constructor(public state: State) {
35
+ if (isNullableOrWhitespace(state.options.grouping)) {
36
+ return;
37
+ }
38
+
39
+ this.enabled = true;
40
+ this.field = state.options.grouping;
41
+ }
42
+
43
+ add(group: GroupComponent): void {
44
+ this.set([...this.items, group]);
45
+ }
46
+
47
+ clear(): void {
48
+ const groups = this.items.splice(0);
49
+ const {length} = groups;
50
+
51
+ for (let index = 0; index < length; index += 1) {
52
+ this.remove(groups[index]);
53
+ }
54
+ }
55
+
56
+ destroy(): void {
57
+ const groups = this.items.splice(0);
58
+ const {length} = groups;
59
+
60
+ for (let index = 0; index < length; index += 1) {
61
+ removeGroup(groups[index]);
62
+ }
63
+
64
+ this.collapsed.clear();
65
+
66
+ this.handlers = undefined as never;
67
+ this.state = undefined as never;
68
+ }
69
+
70
+ get(value: unknown) {
71
+ const asString = getString(value);
72
+
73
+ return this.items.find(item => item.value.stringified === asString);
74
+ }
75
+
76
+ handle(button: HTMLElement): void {
77
+ const value = button.dataset.key?.replace(`tabela_${this.state.id}_group:`, '');
78
+ const group = this.get(value);
79
+
80
+ if (group == null) {
81
+ return;
82
+ }
83
+
84
+ const {collapsed, items, state} = this;
85
+
86
+ group.expanded = !group.expanded;
87
+
88
+ const index = items.indexOf(group);
89
+
90
+ let first = state.managers.data.state.items.original.indexOf(items[index]) + 1;
91
+
92
+ const last =
93
+ items[index + 1] == null
94
+ ? state.managers.data.state.items.original.length - 1
95
+ : state.managers.data.state.items.original.indexOf(items[index + 1]) - 1;
96
+
97
+ for (; first <= last; first += 1) {
98
+ const key = state.managers.data.state.items.original[first] as Key;
99
+
100
+ if (group.expanded) {
101
+ collapsed.delete(key);
102
+ } else {
103
+ collapsed.add(key);
104
+ }
105
+ }
106
+
107
+ if (Object.keys(state.managers.filter.items).length > 0) {
108
+ state.managers.filter.filter();
109
+ } else if (state.managers.sort.items.length > 0) {
110
+ state.managers.sort.sort();
111
+ } else {
112
+ state.managers.render.update(true, true);
113
+ }
114
+ }
115
+
116
+ remove(group: GroupComponent): void {
117
+ removeGroup(group);
118
+
119
+ this.set(this.items.filter(item => item !== group));
120
+ }
121
+
122
+ set(items: GroupComponent[]) {
123
+ this.items = sort(items, item => item.label);
124
+
125
+ this.order = toRecord(
126
+ items as Simplify<GroupComponent>[],
127
+ group => group.value.stringified,
128
+ (_, index) => index,
129
+ );
130
+ }
131
+ }
@@ -1,13 +1,14 @@
1
1
  import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
2
- import type {Key} from '@oscarpalmer/atoms/models';
3
2
  import {clamp} from '@oscarpalmer/atoms/number';
4
3
  import {getKey} from '../helpers/misc.helpers';
5
- import type {TabelaState} from '../models/tabela.model';
4
+ import type {DataItem} from '../models/data.model';
5
+ import type {State} from '../models/tabela.model';
6
+ import {GroupComponent} from '../components/group.component';
6
7
 
7
8
  export class NavigationManager {
8
- active: Key | undefined;
9
+ active: DataItem | undefined;
9
10
 
10
- constructor(public state: TabelaState) {}
11
+ constructor(public state: State) {}
11
12
 
12
13
  destroy(): void {
13
14
  this.state = undefined as never;
@@ -24,26 +25,26 @@ export class NavigationManager {
24
25
 
25
26
  const activeDescendant = components.body.elements.group.getAttribute('aria-activedescendant');
26
27
 
27
- const keys = managers.data.values.keys.active ?? managers.data.values.keys.original;
28
- const {length} = keys;
28
+ const {items} = managers.data;
29
+ const {length} = items;
29
30
 
30
31
  let next: number;
31
32
 
32
33
  if (isNullableOrWhitespace(activeDescendant)) {
33
34
  next = getDefaultIndex(event.key, length);
34
35
  } else {
35
- next = getIndex(event, activeDescendant, id, keys)!;
36
+ next = getIndex(this.state, event, activeDescendant, id)!;
36
37
  }
37
38
 
38
39
  if (next != null) {
39
- this.setActive(keys.at(next)!);
40
+ this.setActive(items.at(next));
40
41
  }
41
42
  }
42
43
 
43
- setActive(key: Key | undefined, scroll?: boolean): void {
44
- const {components, managers, options} = this.state;
44
+ setActive(item: DataItem | undefined, scroll?: boolean): void {
45
+ const {components, id, managers, options} = this.state;
45
46
 
46
- this.active = key;
47
+ this.active = item;
47
48
 
48
49
  const active = components.body.elements.group.querySelectorAll('[data-active="true"]');
49
50
 
@@ -51,19 +52,19 @@ export class NavigationManager {
51
52
  item.setAttribute('data-active', 'false');
52
53
  }
53
54
 
54
- const row = managers.row.get(key!);
55
+ const component = item instanceof GroupComponent ? item : managers.row.get(item!, false);
55
56
 
56
- if (row != null) {
57
- row.element?.setAttribute('data-active', 'true');
57
+ if (component != null) {
58
+ component.element?.setAttribute('data-active', 'true');
58
59
 
59
60
  if (scroll ?? true) {
60
- if (row.element == null) {
61
+ if (component.element == null) {
61
62
  components.body.elements.group.scrollTo({
62
- top: managers.data.getIndex(key!) * options.rowHeight,
63
+ top: managers.data.getIndex(item!) * options.rowHeight,
63
64
  behavior: 'smooth',
64
65
  });
65
66
  } else {
66
- row.element.scrollIntoView({
67
+ component.element.scrollIntoView({
67
68
  block: 'nearest',
68
69
  });
69
70
  }
@@ -72,7 +73,7 @@ export class NavigationManager {
72
73
 
73
74
  components.body.elements.group.setAttribute(
74
75
  'aria-activedescendant',
75
- row == null ? '' : `tabela_${this.state.id}_row_${key}`,
76
+ component == null ? '' : `tabela_${id}_${component.key}`,
76
77
  );
77
78
  }
78
79
  }
@@ -94,25 +95,26 @@ function getDefaultIndex(key: string, max: number): number {
94
95
  }
95
96
 
96
97
  function getIndex(
98
+ state: State,
97
99
  event: KeyboardEvent,
98
100
  active: string,
99
101
  id: number,
100
- keys: Key[],
101
102
  ): number | undefined {
102
- const key = getKey(active.replace(`tabela_${id}_row_`, ''));
103
+ const key = getKey(active.replace(`tabela_${id}_`, ''));
103
104
 
104
105
  if (key == null) {
105
106
  return;
106
107
  }
107
108
 
108
109
  if (absoluteKeys.has(event.key)) {
109
- return event.key === 'Home' ? 0 : keys.length - 1;
110
+ return event.key === 'Home' ? 0 : state.managers.data.size - 1;
110
111
  }
111
112
 
112
- const index = keys.indexOf(key);
113
+ const index = state.managers.data.getIndex(key);
114
+
113
115
  const offset = getOffset(event.key);
114
116
 
115
- return clamp(index + offset, 0, keys.length - 1, true);
117
+ return clamp(index + offset, 0, state.managers.data.size - 1, true);
116
118
  }
117
119
 
118
120
  function getOffset(key: string): number {
@@ -1,30 +1,29 @@
1
- import type {Key} from '@oscarpalmer/atoms/models';
2
1
  import {on} from '@oscarpalmer/toretto/event';
3
2
  import type {RemovableEventListener} from '@oscarpalmer/toretto/models';
3
+ import {GroupComponent, renderGroup} from '../components/group.component';
4
4
  import {removeRow, renderRow} from '../components/row.component';
5
+ import type {DataItem} from '../models/data.model';
5
6
  import type {RenderElementPool, RenderRange, RenderState} from '../models/render.model';
6
- import type {TabelaState} from '../models/tabela.model';
7
+ import type {State} from '../models/tabela.model';
7
8
 
8
- function getRange(this: RenderManager, down: boolean): RenderRange {
9
- const {components, managers, options} = this.state;
10
- const {clientHeight, scrollTop} = components.body.elements.group;
9
+ function getRange(state: State, down: boolean): RenderRange {
10
+ const {element, managers, options} = state;
11
+ const {clientHeight, scrollTop} = element;
11
12
 
12
- const first = Math.floor(scrollTop / options.rowHeight);
13
+ const {items} = managers.data;
13
14
 
14
- const last = Math.min(
15
- (managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length) - 1,
16
- Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1,
17
- );
15
+ const firstIndex = Math.floor(scrollTop / options.rowHeight);
16
+ const lastIndex = items.length - managers.group.collapsed.size - 1;
18
17
 
19
- const before = Math.ceil(clientHeight / options.rowHeight) * (down ? 1 : 2);
20
- const after = Math.ceil(clientHeight / options.rowHeight) * (down ? 2 : 1);
18
+ const last = Math.min(lastIndex, Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1);
21
19
 
22
- const start = Math.max(0, first - before);
20
+ const visible = clientHeight / options.rowHeight;
23
21
 
24
- const end = Math.min(
25
- (managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length) - 1,
26
- last + after,
27
- );
22
+ const before = Math.ceil(visible) * (down ? 1 : 2);
23
+ const after = Math.ceil(visible) * (down ? 2 : 1);
24
+
25
+ const start = Math.max(0, firstIndex - before);
26
+ const end = Math.min(lastIndex, last + after);
28
27
 
29
28
  return {end, start};
30
29
  }
@@ -34,7 +33,7 @@ function onScroll(this: RenderManager): void {
34
33
 
35
34
  if (!state.active) {
36
35
  requestAnimationFrame(() => {
37
- const top = state.components.body.elements.group.scrollTop;
36
+ const top = state.element.scrollTop;
38
37
 
39
38
  this.update(top > state.top);
40
39
 
@@ -58,10 +57,10 @@ export class RenderManager {
58
57
 
59
58
  state: RenderState;
60
59
 
61
- visible = new Map<number, Key>();
60
+ visible = new Map<number, DataItem>();
62
61
 
63
- constructor(state: TabelaState) {
64
- this.listener = on(state.components.body.elements.group, 'scroll', onScroll.bind(this));
62
+ constructor(state: State) {
63
+ this.listener = on(state.element, 'scroll', onScroll.bind(this));
65
64
 
66
65
  this.state = {
67
66
  ...state,
@@ -76,6 +75,20 @@ export class RenderManager {
76
75
  listener();
77
76
  visible.clear();
78
77
 
78
+ const cells = Object.values(pool.cells).flat();
79
+
80
+ let {length} = cells;
81
+
82
+ for (let index = 0; index < length; index += 1) {
83
+ cells[index].remove();
84
+ }
85
+
86
+ length = pool.rows.length;
87
+
88
+ for (let index = 0; index < length; index += 1) {
89
+ pool.rows[index].remove();
90
+ }
91
+
79
92
  pool.cells = {};
80
93
  pool.rows = [];
81
94
 
@@ -95,7 +108,11 @@ export class RenderManager {
95
108
  }
96
109
 
97
110
  for (const [, key] of visible) {
98
- const row = state.managers.row.get(key);
111
+ if (key instanceof GroupComponent) {
112
+ continue;
113
+ }
114
+
115
+ const row = state.managers.row.get(key, false);
99
116
 
100
117
  if (row == null || row.element == null) {
101
118
  continue;
@@ -123,10 +140,11 @@ export class RenderManager {
123
140
  const {state, pool, visible} = this;
124
141
  const {components, managers, options} = state;
125
142
 
126
- components.body.elements.faker.style.height = `${managers.data.size * options.rowHeight}px`;
143
+ components.body.elements.faker.style.height = `${(managers.data.size - managers.group.collapsed.size) * options.rowHeight}px`;
127
144
 
128
145
  const indices = new Set<number>();
129
- const range = getRange.call(this, down);
146
+
147
+ const range = getRange(state, down);
130
148
 
131
149
  for (let index = range.start; index <= range.end; index += 1) {
132
150
  indices.add(index);
@@ -135,9 +153,19 @@ export class RenderManager {
135
153
  let remove = rerender ?? false;
136
154
 
137
155
  for (const [index, key] of visible) {
138
- const row = managers.row.get(key);
156
+ if (key instanceof GroupComponent) {
157
+ if (remove || !indices.has(index)) {
158
+ visible.delete(index);
139
159
 
140
- if (remove || row == null || !indices.has(index)) {
160
+ key.element?.remove();
161
+ }
162
+
163
+ continue;
164
+ }
165
+
166
+ const row = managers.row.get(key, false);
167
+
168
+ if (remove || row == null || !indices.has(index) || managers.group.collapsed.has(key)) {
141
169
  visible.delete(index);
142
170
 
143
171
  if (row != null) {
@@ -148,30 +176,54 @@ export class RenderManager {
148
176
 
149
177
  const fragment = this.getFragment();
150
178
 
151
- const keys = managers.data.values.keys.active ?? managers.data.values.keys.original;
179
+ const {items} = managers.data;
152
180
 
153
181
  let count = 0;
182
+ let offset = 0;
154
183
 
155
- for (let index = range.start; index <= range.end; index += 1) {
184
+ for (let index = range.start; index <= range.end + offset; index += 1) {
156
185
  if (visible.has(index)) {
157
186
  continue;
158
187
  }
159
188
 
160
- const key = keys[index];
161
- const row = managers.row.get(key);
189
+ const item = items[index];
190
+
191
+ if (item instanceof GroupComponent) {
192
+ count += 1;
193
+
194
+ renderGroup(state, item);
195
+
196
+ visible.set(index, item);
197
+
198
+ if (item.element != null) {
199
+ item.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
200
+
201
+ fragment.append(item.element);
202
+ }
203
+
204
+ continue;
205
+ }
206
+
207
+ const row = managers.row.get(item, true);
162
208
 
163
209
  if (row == null) {
164
210
  continue;
165
211
  }
166
212
 
213
+ if (managers.group.collapsed.has(item)) {
214
+ offset += 1;
215
+
216
+ continue;
217
+ }
218
+
167
219
  count += 1;
168
220
 
169
221
  renderRow(state, row);
170
222
 
171
- visible.set(index, key);
223
+ visible.set(index, item);
172
224
 
173
225
  if (row.element != null) {
174
- row.element.style.transform = `translateY(${index * options.rowHeight}px)`;
226
+ row.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
175
227
 
176
228
  fragment.append(row.element);
177
229
  }
@@ -1,30 +1,36 @@
1
1
  import type {Key} from '@oscarpalmer/atoms/models';
2
2
  import {removeRow, renderRow, RowComponent} from '../components/row.component';
3
- import type {TabelaState} from '../models/tabela.model';
3
+ import type {State} from '../models/tabela.model';
4
4
 
5
5
  export class RowManager {
6
6
  components = new Map<Key, RowComponent>();
7
7
 
8
- constructor(public state: TabelaState) {}
8
+ constructor(public state: State) {}
9
9
 
10
- destroy(): void {
11
- const components = [...this.components.values()];
12
- const {length} = components;
10
+ clear(): void {
11
+ const {components} = this;
12
+
13
+ const rows = [...components.values()];
14
+ const {length} = rows;
13
15
 
14
16
  for (let index = 0; index < length; index += 1) {
15
- removeRow(this.state.managers.render.pool, components[index]);
17
+ this.removeRow(rows[index]);
16
18
  }
17
19
 
18
- this.components.clear();
20
+ components.clear();
21
+ }
22
+
23
+ destroy(): void {
24
+ this.clear();
19
25
 
20
26
  this.components = undefined as never;
21
27
  this.state = undefined as never;
22
28
  }
23
29
 
24
- get(key: Key): RowComponent | undefined {
30
+ get(key: Key, create: boolean): RowComponent | undefined {
25
31
  let row = this.components.get(key);
26
32
 
27
- if (row == null) {
33
+ if (row == null && create) {
28
34
  row = new RowComponent(key);
29
35
 
30
36
  this.components.set(key, row);
@@ -41,10 +47,16 @@ export class RowManager {
41
47
  const row = this.components.get(key);
42
48
 
43
49
  if (row != null) {
44
- removeRow(this.state.managers.render.pool, row);
50
+ this.removeRow(row);
51
+ }
52
+ }
45
53
 
46
- this.components.delete(key);
54
+ removeRow(row: RowComponent): void {
55
+ if (row.element != null) {
56
+ removeRow(this.state.managers.render.pool, row);
47
57
  }
58
+
59
+ this.components.delete(row.key);
48
60
  }
49
61
 
50
62
  update(key: Key): void {