@oscarpalmer/tabela 0.13.0 → 0.15.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 (108) hide show
  1. package/dist/components/body.component.d.mts +10 -1
  2. package/dist/components/body.component.mjs +8 -6
  3. package/dist/components/column.component.d.mts +15 -1
  4. package/dist/components/column.component.mjs +12 -10
  5. package/dist/components/footer.component.d.mts +12 -1
  6. package/dist/components/footer.component.mjs +6 -6
  7. package/dist/components/group.component.d.mts +19 -1
  8. package/dist/components/group.component.mjs +17 -11
  9. package/dist/components/header.component.d.mts +12 -1
  10. package/dist/components/header.component.mjs +5 -5
  11. package/dist/components/row.component.d.mts +14 -1
  12. package/dist/components/row.component.mjs +21 -17
  13. package/dist/helpers/dom.helpers.d.mts +3 -3
  14. package/dist/helpers/dom.helpers.mjs +12 -11
  15. package/dist/helpers/misc.helpers.d.mts +7 -1
  16. package/dist/helpers/misc.helpers.mjs +12 -1
  17. package/dist/index.d.mts +1 -1
  18. package/dist/managers/column.manager.d.mts +16 -1
  19. package/dist/managers/column.manager.mjs +7 -7
  20. package/dist/managers/data.manager.d.mts +26 -1
  21. package/dist/managers/data.manager.mjs +122 -88
  22. package/dist/managers/event.manager.d.mts +17 -1
  23. package/dist/managers/event.manager.mjs +35 -10
  24. package/dist/managers/filter.manager.d.mts +17 -1
  25. package/dist/managers/filter.manager.mjs +43 -35
  26. package/dist/managers/group.manager.d.mts +26 -1
  27. package/dist/managers/group.manager.mjs +36 -16
  28. package/dist/managers/navigation.manager.d.mts +15 -2
  29. package/dist/managers/navigation.manager.mjs +38 -34
  30. package/dist/managers/render.manager.d.mts +18 -1
  31. package/dist/managers/render.manager.mjs +44 -31
  32. package/dist/managers/row.manager.d.mts +18 -1
  33. package/dist/managers/row.manager.mjs +1 -1
  34. package/dist/managers/selection.manager.d.mts +22 -1
  35. package/dist/managers/selection.manager.mjs +26 -23
  36. package/dist/managers/sort.manager.d.mts +22 -1
  37. package/dist/managers/sort.manager.mjs +71 -49
  38. package/dist/managers/style.manager.d.mts +8 -1
  39. package/dist/managers/style.manager.mjs +57 -25
  40. package/dist/models/body.model.d.mts +6 -1
  41. package/dist/models/column.model.d.mts +13 -2
  42. package/dist/models/data.model.d.mts +28 -2
  43. package/dist/models/dom.model.d.mts +19 -0
  44. package/dist/models/dom.model.mjs +19 -0
  45. package/dist/models/event.model.d.mts +99 -0
  46. package/dist/models/event.model.mjs +53 -0
  47. package/dist/models/filter.model.d.mts +26 -2
  48. package/dist/models/filter.model.mjs +13 -1
  49. package/dist/models/footer.model.d.mts +7 -1
  50. package/dist/models/group.model.d.mts +19 -2
  51. package/dist/models/group.model.mjs +5 -1
  52. package/dist/models/header.model.d.mts +6 -1
  53. package/dist/models/render.model.d.mts +22 -2
  54. package/dist/models/selection.model.d.mts +11 -1
  55. package/dist/models/sort.model.d.mts +19 -2
  56. package/dist/models/sort.model.mjs +5 -1
  57. package/dist/models/style.model.d.mts +27 -21
  58. package/dist/models/style.model.mjs +27 -21
  59. package/dist/models/tabela.model.d.mts +45 -1
  60. package/dist/models/tabela.options.d.mts +13 -1
  61. package/dist/tabela.d.mts +9 -8
  62. package/dist/tabela.full.mjs +1083 -574
  63. package/dist/tabela.mjs +19 -19
  64. package/package.json +2 -4
  65. package/src/components/body.component.ts +10 -7
  66. package/src/components/column.component.ts +20 -16
  67. package/src/components/footer.component.ts +7 -10
  68. package/src/components/group.component.ts +39 -13
  69. package/src/components/header.component.ts +6 -5
  70. package/src/components/row.component.ts +27 -19
  71. package/src/helpers/dom.helpers.ts +18 -22
  72. package/src/helpers/misc.helpers.ts +17 -0
  73. package/src/managers/column.manager.ts +9 -9
  74. package/src/managers/data.manager.ts +196 -107
  75. package/src/managers/event.manager.ts +69 -12
  76. package/src/managers/filter.manager.ts +70 -41
  77. package/src/managers/group.manager.ts +60 -18
  78. package/src/managers/navigation.manager.ts +46 -49
  79. package/src/managers/render.manager.ts +60 -34
  80. package/src/managers/row.manager.ts +1 -1
  81. package/src/managers/selection.manager.ts +37 -35
  82. package/src/managers/sort.manager.ts +114 -72
  83. package/src/managers/style.manager.ts +73 -25
  84. package/src/models/column.model.ts +4 -8
  85. package/src/models/data.model.ts +13 -14
  86. package/src/models/dom.model.ts +31 -0
  87. package/src/models/event.model.ts +175 -0
  88. package/src/models/filter.model.ts +22 -2
  89. package/src/models/group.model.ts +13 -0
  90. package/src/models/render.model.ts +6 -0
  91. package/src/models/sort.model.ts +11 -5
  92. package/src/models/style.model.ts +32 -20
  93. package/src/models/tabela.model.ts +1 -0
  94. package/src/tabela.ts +26 -24
  95. package/dist/body.component-_VDOpJhV.d.mts +0 -10
  96. package/dist/body.model-2iwsovAV.d.mts +0 -7
  97. package/dist/column.component-Bx46r3JI.d.mts +0 -16
  98. package/dist/column.model-D-aw4EU4.d.mts +0 -16
  99. package/dist/filter.model-7ukJrtil.d.mts +0 -16
  100. package/dist/footer.component-Curiab8j.d.mts +0 -12
  101. package/dist/footer.model-DhqoS6ds.d.mts +0 -8
  102. package/dist/group.component-Cq1YYbfJ.d.mts +0 -285
  103. package/dist/group.model-BsKFwHbt.d.mts +0 -10
  104. package/dist/header.component-BjjlpZIg.d.mts +0 -12
  105. package/dist/header.model-DN_KzUCV.d.mts +0 -7
  106. package/dist/selection.model-rwQe9fco.d.mts +0 -12
  107. package/dist/sort.model-CauImaLu.d.mts +0 -15
  108. package/dist/tabela.options-RkZvfptB.d.mts +0 -14
@@ -1,19 +1,24 @@
1
1
  import {on} from '@oscarpalmer/toretto/event';
2
2
  import type {RemovableEventListener} from '@oscarpalmer/toretto/models';
3
- import {GroupComponent, renderGroup} from '../components/group.component';
3
+ import {renderGroup} from '../components/group.component';
4
4
  import {removeRow, renderRow} from '../components/row.component';
5
- import type {DataItem} from '../models/data.model';
6
- import type {RenderElementPool, RenderRange, RenderState} from '../models/render.model';
5
+ import {isGroupKey} from '../helpers/misc.helpers';
6
+ import type {
7
+ RenderElementPool,
8
+ RenderRange,
9
+ RenderState,
10
+ RenderVisible,
11
+ } from '../models/render.model';
7
12
  import type {State} from '../models/tabela.model';
8
13
 
9
14
  function getRange(state: State, down: boolean): RenderRange {
10
15
  const {element, managers, options} = state;
11
16
  const {clientHeight, scrollTop} = element;
12
17
 
13
- const {items} = managers.data;
18
+ const {keys} = managers.data;
14
19
 
15
20
  const firstIndex = Math.floor(scrollTop / options.rowHeight);
16
- const lastIndex = items.length - managers.group.collapsed.size - 1;
21
+ const lastIndex = keys.length - managers.group.collapsed.size - 1;
17
22
 
18
23
  const last = Math.min(lastIndex, Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1);
19
24
 
@@ -57,7 +62,10 @@ export class RenderManager {
57
62
 
58
63
  state: RenderState;
59
64
 
60
- visible = new Map<number, DataItem>();
65
+ visible: RenderVisible = {
66
+ indiced: new Map(),
67
+ keys: new Set(),
68
+ };
61
69
 
62
70
  constructor(state: State) {
63
71
  this.listener = on(state.element, 'scroll', onScroll.bind(this));
@@ -73,7 +81,9 @@ export class RenderManager {
73
81
  const {listener, pool, visible} = this;
74
82
 
75
83
  listener();
76
- visible.clear();
84
+
85
+ visible.indiced.clear();
86
+ visible.keys.clear();
77
87
 
78
88
  const cells = Object.values(pool.cells).flat();
79
89
 
@@ -99,16 +109,16 @@ export class RenderManager {
99
109
  this.visible = undefined as never;
100
110
  }
101
111
 
102
- removeCells(fields: string[]): void {
112
+ removeCells(keys: string[]): void {
103
113
  const {pool, state, visible} = this;
104
- const {length} = fields;
114
+ const {length} = keys;
105
115
 
106
116
  for (let index = 0; index < length; index += 1) {
107
- delete pool.cells[fields[index]];
117
+ delete pool.cells[keys[index]];
108
118
  }
109
119
 
110
- for (const [, key] of visible) {
111
- if (key instanceof GroupComponent) {
120
+ for (const [, key] of visible.indiced) {
121
+ if (isGroupKey(key)) {
112
122
  continue;
113
123
  }
114
124
 
@@ -119,11 +129,11 @@ export class RenderManager {
119
129
  }
120
130
 
121
131
  for (let index = 0; index < length; index += 1) {
122
- row.cells[fields[index]].innerHTML = '';
132
+ row.cells[keys[index]].innerHTML = '';
123
133
 
124
- row.cells[fields[index]].remove();
134
+ row.cells[keys[index]].remove();
125
135
 
126
- delete row.cells[fields[index]];
136
+ delete row.cells[keys[index]];
127
137
  }
128
138
  }
129
139
  }
@@ -152,12 +162,13 @@ export class RenderManager {
152
162
 
153
163
  let remove = rerender ?? false;
154
164
 
155
- for (const [index, key] of visible) {
156
- if (key instanceof GroupComponent) {
165
+ for (const [index, key] of visible.indiced) {
166
+ if (isGroupKey(key)) {
157
167
  if (remove || !indices.has(index)) {
158
- visible.delete(index);
168
+ visible.indiced.delete(index);
169
+ visible.keys.delete(key);
159
170
 
160
- key.element?.remove();
171
+ state.managers.group.getForKey(key as string)?.element?.remove();
161
172
  }
162
173
 
163
174
  continue;
@@ -166,7 +177,8 @@ export class RenderManager {
166
177
  const row = managers.row.get(key, false);
167
178
 
168
179
  if (remove || row == null || !indices.has(index) || managers.group.collapsed.has(key)) {
169
- visible.delete(index);
180
+ visible.indiced.delete(index);
181
+ visible.keys.delete(key);
170
182
 
171
183
  if (row != null) {
172
184
  removeRow(pool, row);
@@ -176,41 +188,48 @@ export class RenderManager {
176
188
 
177
189
  const fragment = this.getFragment();
178
190
 
179
- const {items} = managers.data;
191
+ const {keys} = managers.data;
180
192
 
181
193
  let count = 0;
182
194
  let offset = 0;
183
195
 
184
196
  for (let index = range.start; index <= range.end + offset; index += 1) {
185
- if (visible.has(index)) {
197
+ if (visible.indiced.has(index)) {
186
198
  continue;
187
199
  }
188
200
 
189
- const item = items[index];
201
+ const key = keys[index];
202
+
203
+ if (isGroupKey(key)) {
204
+ const group = managers.group.getForKey(key as string);
205
+
206
+ if (group == null) {
207
+ continue;
208
+ }
190
209
 
191
- if (item instanceof GroupComponent) {
192
210
  count += 1;
193
211
 
194
- renderGroup(state, item);
212
+ renderGroup(state, group);
195
213
 
196
- visible.set(index, item);
214
+ visible.indiced.set(index, group.key);
215
+ visible.keys.add(group.key);
197
216
 
198
- if (item.element != null) {
199
- item.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
217
+ if (group.element != null) {
218
+ group.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
200
219
 
201
- fragment.append(item.element);
220
+ fragment.append(group.element);
202
221
  }
203
222
 
204
223
  continue;
205
224
  }
206
225
 
207
- const row = managers.row.get(item, true);
226
+ const row = managers.row.get(key, true);
208
227
 
209
228
  if (row == null) {
210
229
  continue;
211
230
  }
212
231
 
213
- if (managers.group.collapsed.has(item)) {
232
+ if (managers.group.collapsed.has(key)) {
214
233
  offset += 1;
215
234
 
216
235
  continue;
@@ -220,7 +239,8 @@ export class RenderManager {
220
239
 
221
240
  renderRow(state, row);
222
241
 
223
- visible.set(index, item);
242
+ visible.indiced.set(index, key);
243
+ visible.keys.add(key);
224
244
 
225
245
  if (row.element != null) {
226
246
  row.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
@@ -229,8 +249,14 @@ export class RenderManager {
229
249
  }
230
250
  }
231
251
 
232
- if (count > 0) {
233
- components.body.elements.group[down ? 'append' : 'prepend'](fragment);
252
+ if (count === 0) {
253
+ return;
254
+ }
255
+
256
+ if (down) {
257
+ components.body.elements.group.append(fragment);
258
+ } else {
259
+ components.body.elements.group.prepend(fragment);
234
260
  }
235
261
  }
236
262
  }
@@ -62,7 +62,7 @@ export class RowManager {
62
62
  update(key: Key): void {
63
63
  const row = this.components.get(key);
64
64
 
65
- if (row != null) {
65
+ if (row?.element != null) {
66
66
  renderRow(this.state, row);
67
67
  }
68
68
  }
@@ -4,26 +4,22 @@ import {setAttribute} from '@oscarpalmer/toretto/attribute';
4
4
  import {getPosition, on} from '@oscarpalmer/toretto/event';
5
5
  import {findAncestor} from '@oscarpalmer/toretto/find';
6
6
  import type {EventPosition} from '@oscarpalmer/toretto/models';
7
- import {GroupComponent} from '../components/group.component';
8
7
  import {createElement} from '../helpers/dom.helpers';
9
- import {getKey} from '../helpers/misc.helpers';
8
+ import {getKey, isGroupKey} from '../helpers/misc.helpers';
10
9
  import {preventSelection} from '../helpers/style.helper';
10
+ import {ARIA_SELECTED, ATTRIBUTE_DATA_KEY, ELEMENT_DIV} from '../models/dom.model';
11
11
  import type {TabelaSelection} from '../models/selection.model';
12
- import {
13
- CSS_TABELA_ROW_BODY,
14
- CSS_TABELA_ROW_SELECTED,
15
- CSS_TABELA_SELECTION,
16
- } from '../models/style.model';
12
+ import {CSS_ROW_BODY, CSS_ROW_SELECTED, CSS_SELECTION, CSS_TABLE} from '../models/style.model';
17
13
  import type {State} from '../models/tabela.model';
18
14
 
19
15
  export class SelectionManager {
20
- handlers = Object.freeze({
16
+ handlers: TabelaSelection = {
21
17
  add: keys => this.add(keys),
22
18
  clear: () => this.clear(),
23
19
  remove: keys => this.remove(keys),
24
20
  set: keys => this.set(keys),
25
21
  toggle: () => this.toggle(),
26
- } satisfies TabelaSelection);
22
+ };
27
23
 
28
24
  items = new Set<Key>();
29
25
 
@@ -75,7 +71,7 @@ export class SelectionManager {
75
71
  }
76
72
 
77
73
  handle(event: MouseEvent, target: HTMLElement): void {
78
- const key = getKey(target.getAttribute('data-key'));
74
+ const key = getKey(target.getAttribute(ATTRIBUTE_DATA_KEY));
79
75
 
80
76
  if (key == null) {
81
77
  return;
@@ -115,14 +111,19 @@ export class SelectionManager {
115
111
 
116
112
  const keyed = isKey(from) && isKey(to);
117
113
 
118
- const fromKey = keyed ? (from as Key) : getKey((from as HTMLElement).getAttribute('data-key'))!;
119
- const toKey = keyed ? (to as Key) : getKey((to as HTMLElement).getAttribute('data-key'))!;
114
+ const fromKey = keyed
115
+ ? (from as Key)
116
+ : getKey((from as HTMLElement).getAttribute(ATTRIBUTE_DATA_KEY))!;
117
+
118
+ const toKey = keyed
119
+ ? (to as Key)
120
+ : getKey((to as HTMLElement).getAttribute(ATTRIBUTE_DATA_KEY))!;
120
121
 
121
122
  if (fromKey === toKey) {
122
123
  return;
123
124
  }
124
125
 
125
- const {items} = state.managers.data;
126
+ const {keys} = state.managers.data;
126
127
 
127
128
  const fromIndex = state.managers.data.getIndex(fromKey);
128
129
  const toIndex = state.managers.data.getIndex(toKey);
@@ -136,10 +137,10 @@ export class SelectionManager {
136
137
  const selected: Key[] = [];
137
138
 
138
139
  for (let index = start; index <= end; index += 1) {
139
- const item = items[index];
140
+ const key = keys[index];
140
141
 
141
- if (!(item instanceof GroupComponent)) {
142
- selected.push(item as Key);
142
+ if (!isGroupKey(key)) {
143
+ selected.push(key);
143
144
  }
144
145
  }
145
146
 
@@ -189,12 +190,12 @@ export class SelectionManager {
189
190
 
190
191
  toggle(): void {
191
192
  const {items, state} = this;
192
- const data = state.managers.data.items;
193
+ const {keys} = state.managers.data;
193
194
 
194
- if (items.size === data.length - state.managers.group.items.length) {
195
+ if (items.size === keys.length - state.managers.group.items.length) {
195
196
  this.clear();
196
197
  } else {
197
- this.set(data.filter(key => !(key instanceof GroupComponent)) as Key[]);
198
+ this.set(keys.filter(key => !isGroupKey(key)));
198
199
  }
199
200
  }
200
201
 
@@ -217,33 +218,28 @@ export class SelectionManager {
217
218
  continue;
218
219
  }
219
220
 
220
- setAttribute(element, 'aria-selected', String(!removed));
221
+ setAttribute(element, ARIA_SELECTED, String(!removed));
221
222
 
222
223
  if (removed) {
223
- element.classList.remove(CSS_TABELA_ROW_SELECTED);
224
+ element.classList.remove(CSS_ROW_SELECTED);
224
225
  } else {
225
- element.classList.add(CSS_TABELA_ROW_SELECTED);
226
+ element.classList.add(CSS_ROW_SELECTED);
226
227
  }
227
228
  }
228
229
  }
229
230
  }
230
231
 
231
232
  function getPlaceholder(): HTMLElement {
232
- placeholder ??= createElement(
233
- 'div',
234
- {
235
- className: CSS_TABELA_SELECTION,
236
- },
237
- {},
238
- {},
239
- );
233
+ placeholder ??= createElement(ELEMENT_DIV, {
234
+ className: CSS_SELECTION,
235
+ });
240
236
 
241
237
  return placeholder;
242
238
  }
243
239
 
244
240
  function onMouseDown(event: MouseEvent): void {
245
241
  if (shifted) {
246
- const row = findAncestor(event.target as HTMLElement, `.${CSS_TABELA_ROW_BODY}`);
242
+ const row = findAncestor(event.target as HTMLElement, `.${CSS_ROW_BODY}`);
247
243
 
248
244
  if (!(row instanceof HTMLElement)) {
249
245
  return;
@@ -298,13 +294,13 @@ function onMouseUp(event: MouseEvent): void {
298
294
 
299
295
  getPlaceholder().remove();
300
296
 
301
- const row = findAncestor(event.target as HTMLElement, '.tabela__row--body');
297
+ const row = findAncestor(event.target as HTMLElement, bodyRowSelector);
302
298
 
303
299
  if (row instanceof HTMLElement) {
304
300
  endElement = row;
305
301
 
306
- const endTable = findAncestor(endElement, '.tabela__table');
307
- const startTable = findAncestor(startElement, '.tabela__table');
302
+ const endTable = findAncestor(endElement, tableSelector);
303
+ const startTable = findAncestor(startElement, tableSelector);
308
304
 
309
305
  if (startTable != null && startTable === endTable) {
310
306
  mapped.get(startTable)?.range(startElement, endElement);
@@ -317,7 +313,7 @@ function onMouseUp(event: MouseEvent): void {
317
313
  }
318
314
 
319
315
  function onShift(event: KeyboardEvent, value: boolean): void {
320
- if (event.key === 'Shift') {
316
+ if (event.key === KEY_SHIFT) {
321
317
  shifted = value;
322
318
  }
323
319
  }
@@ -330,8 +326,14 @@ function onShiftUp(event: KeyboardEvent): void {
330
326
  onShift(event, false);
331
327
  }
332
328
 
329
+ const KEY_SHIFT = 'Shift';
330
+
333
331
  const mapped = new WeakMap<Element, SelectionManager>();
334
332
 
333
+ const bodyRowSelector = `.${CSS_ROW_BODY}`;
334
+
335
+ const tableSelector = `.${CSS_TABLE}`;
336
+
335
337
  let shifted = false;
336
338
 
337
339
  let endElement: HTMLElement | undefined;