@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
@@ -1,59 +1,70 @@
1
1
  import {isKey} from '@oscarpalmer/atoms/is';
2
2
  import type {Key} from '@oscarpalmer/atoms/models';
3
- import {findAncestor, type EventPosition} from '@oscarpalmer/toretto';
4
3
  import {setAttribute} from '@oscarpalmer/toretto/attribute';
5
4
  import {getPosition, on} from '@oscarpalmer/toretto/event';
5
+ import {findAncestor} from '@oscarpalmer/toretto/find';
6
+ import type {EventPosition} from '@oscarpalmer/toretto/models';
7
+ import {GroupComponent} from '../components/group.component';
6
8
  import {createElement} from '../helpers/dom.helpers';
7
9
  import {getKey} from '../helpers/misc.helpers';
8
- import {dragStyling} from '../helpers/style.helper';
9
- import type {TabelaSelection, TabelaState} from '../models/tabela.model';
10
+ import {preventSelection} from '../helpers/style.helper';
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';
17
+ import type {State} from '../models/tabela.model';
10
18
 
11
19
  export class SelectionManager {
12
20
  handlers = Object.freeze({
21
+ add: keys => this.add(keys),
13
22
  clear: () => this.clear(),
14
- deselect: keys => this.deselect(keys),
15
- select: keys => this.select(keys),
23
+ remove: keys => this.remove(keys),
24
+ set: keys => this.set(keys),
16
25
  toggle: () => this.toggle(),
17
- } as TabelaSelection);
26
+ } satisfies TabelaSelection);
18
27
 
19
28
  items = new Set<Key>();
20
29
 
21
30
  last: Key | undefined;
22
31
 
23
- constructor(public state: TabelaState) {
32
+ constructor(public state: State) {
24
33
  mapped.set(state.element, this);
25
34
  }
26
35
 
27
- clear(): void {
28
- if (this.items.size === 0) {
29
- return;
30
- }
31
-
32
- const removed = [...this.items];
33
-
34
- this.items.clear();
35
-
36
- this.update(removed);
37
- }
38
-
39
- deselect(keys: Key[]): void {
36
+ add(keys: Key[]): void {
40
37
  const {length} = keys;
41
38
 
42
- const removed: Key[] = [];
39
+ let update = false;
43
40
 
44
41
  for (let index = 0; index < length; index += 1) {
45
42
  const key = keys[index];
46
43
 
47
- if (this.items.delete(key)) {
48
- removed.push(key);
44
+ if (!this.items.has(key)) {
45
+ this.items.add(key);
46
+
47
+ update = true;
49
48
  }
50
49
  }
51
50
 
52
- if (removed.length > 0) {
53
- this.update(removed);
51
+ if (update) {
52
+ this.update([]);
54
53
  }
55
54
  }
56
55
 
56
+ clear(): void {
57
+ if (this.items.size === 0) {
58
+ return;
59
+ }
60
+
61
+ const removed = [...this.items];
62
+
63
+ this.items.clear();
64
+
65
+ this.update(removed);
66
+ }
67
+
57
68
  destroy(): void {
58
69
  mapped.delete(this.state.element);
59
70
 
@@ -88,9 +99,9 @@ export class SelectionManager {
88
99
 
89
100
  if (event.ctrlKey || event.metaKey) {
90
101
  if (items.has(key)) {
91
- this.deselect([key]);
102
+ this.remove([key]);
92
103
  } else {
93
- this.select([key]);
104
+ this.add([key]);
94
105
  }
95
106
 
96
107
  return;
@@ -111,7 +122,7 @@ export class SelectionManager {
111
122
  return;
112
123
  }
113
124
 
114
- const keys = state.managers.data.values.keys.active ?? state.managers.data.values.keys.original;
125
+ const {items} = state.managers.data;
115
126
 
116
127
  const fromIndex = state.managers.data.getIndex(fromKey);
117
128
  const toIndex = state.managers.data.getIndex(toKey);
@@ -125,11 +136,15 @@ export class SelectionManager {
125
136
  const selected: Key[] = [];
126
137
 
127
138
  for (let index = start; index <= end; index += 1) {
128
- selected.push(keys[index]);
139
+ const item = items[index];
140
+
141
+ if (!(item instanceof GroupComponent)) {
142
+ selected.push(item as Key);
143
+ }
129
144
  }
130
145
 
131
146
  if (keyed) {
132
- this.select(selected);
147
+ this.add(selected);
133
148
  } else {
134
149
  this.set(selected);
135
150
  }
@@ -139,23 +154,21 @@ export class SelectionManager {
139
154
  this.state.managers.navigation.setActive(toKey, false);
140
155
  }
141
156
 
142
- select(keys: Key[]): void {
157
+ remove(keys: Key[]): void {
143
158
  const {length} = keys;
144
159
 
145
- let update = false;
160
+ const removed: Key[] = [];
146
161
 
147
162
  for (let index = 0; index < length; index += 1) {
148
163
  const key = keys[index];
149
164
 
150
- if (!this.items.has(key)) {
151
- this.items.add(key);
152
-
153
- update = true;
165
+ if (this.items.delete(key)) {
166
+ removed.push(key);
154
167
  }
155
168
  }
156
169
 
157
- if (update) {
158
- this.update([]);
170
+ if (removed.length > 0) {
171
+ this.update(removed);
159
172
  }
160
173
  }
161
174
 
@@ -176,39 +189,40 @@ export class SelectionManager {
176
189
 
177
190
  toggle(): void {
178
191
  const {items, state} = this;
192
+ const data = state.managers.data.items;
179
193
 
180
- const all = state.managers.data.values.keys.active ?? state.managers.data.values.keys.original;
181
-
182
- if (items.size === all.length) {
194
+ if (items.size === data.length - state.managers.group.items.length) {
183
195
  this.clear();
184
196
  } else {
185
- this.select(all);
197
+ this.set(data.filter(key => !(key instanceof GroupComponent)) as Key[]);
186
198
  }
187
199
  }
188
200
 
189
201
  update(removed: Key[]): void {
202
+ const {state} = this;
203
+
190
204
  const items = [
191
205
  ...removed.map(key => ({key, removed: true})),
192
206
  ...[...this.items].map(key => ({key, removed: false})),
193
207
  ];
194
208
 
195
- const {length} = items;
209
+ let {length} = items;
196
210
 
197
211
  for (let index = 0; index < length; index += 1) {
198
212
  const {key, removed} = items[index];
199
213
 
200
- const row = this.state.managers.row.get(key);
214
+ const element = state.managers.row.get(key, false)?.element;
201
215
 
202
- if (row == null || row.element == null) {
216
+ if (element == null) {
203
217
  continue;
204
218
  }
205
219
 
206
- setAttribute(row.element, 'aria-selected', String(!removed));
220
+ setAttribute(element, 'aria-selected', String(!removed));
207
221
 
208
222
  if (removed) {
209
- row.element.classList.remove('tabela__row--selected');
223
+ element.classList.remove(CSS_TABELA_ROW_SELECTED);
210
224
  } else {
211
- row.element.classList.add('tabela__row--selected');
225
+ element.classList.add(CSS_TABELA_ROW_SELECTED);
212
226
  }
213
227
  }
214
228
  }
@@ -218,7 +232,7 @@ function getPlaceholder(): HTMLElement {
218
232
  placeholder ??= createElement(
219
233
  'div',
220
234
  {
221
- className: 'tabela__selection--placeholder',
235
+ className: CSS_TABELA_SELECTION,
222
236
  },
223
237
  {},
224
238
  {},
@@ -229,7 +243,7 @@ function getPlaceholder(): HTMLElement {
229
243
 
230
244
  function onMouseDown(event: MouseEvent): void {
231
245
  if (shifted) {
232
- const row = findAncestor(event.target as HTMLElement, '.tabela__row--body');
246
+ const row = findAncestor(event.target as HTMLElement, `.${CSS_TABELA_ROW_BODY}`);
233
247
 
234
248
  if (!(row instanceof HTMLElement)) {
235
249
  return;
@@ -238,7 +252,7 @@ function onMouseDown(event: MouseEvent): void {
238
252
  startElement = row;
239
253
  startPosition = getPosition(event)!;
240
254
 
241
- dragStyling.set();
255
+ preventSelection.set();
242
256
  }
243
257
  }
244
258
 
@@ -279,7 +293,7 @@ function onMouseUp(event: MouseEvent): void {
279
293
  if (!event.shiftKey) {
280
294
  shifted = false;
281
295
 
282
- dragStyling.remove();
296
+ preventSelection.remove();
283
297
  }
284
298
 
285
299
  getPlaceholder().remove();
@@ -289,8 +303,8 @@ function onMouseUp(event: MouseEvent): void {
289
303
  if (row instanceof HTMLElement) {
290
304
  endElement = row;
291
305
 
292
- const endTable = findAncestor(endElement, '.tabela');
293
- const startTable = findAncestor(startElement, '.tabela');
306
+ const endTable = findAncestor(endElement, '.tabela__table');
307
+ const startTable = findAncestor(startElement, '.tabela__table');
294
308
 
295
309
  if (startTable != null && startTable === endTable) {
296
310
  mapped.get(startTable)?.range(startElement, endElement);
@@ -1,8 +1,12 @@
1
- import {sort, type ArrayKeySorter} from '@oscarpalmer/atoms/array';
1
+ import {sort} from '@oscarpalmer/atoms/array';
2
2
  import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
3
+ import {compare} from '@oscarpalmer/atoms/value/compare';
4
+ import {getValue} from '@oscarpalmer/atoms/value/handle';
3
5
  import {setAttribute, setAttributes} from '@oscarpalmer/toretto/attribute';
4
- import type {SortDirection, SortItem} from '../models/sort.model';
5
- import type {TabelaSort, TabelaState} from '../models/tabela.model';
6
+ import {GroupComponent} from '../components/group.component';
7
+ import type {DataItem} from '../models/data.model';
8
+ import type {TabelaSort, TabelaSortDirection, TabelaSortItem} from '../models/sort.model';
9
+ import type {State} from '../models/tabela.model';
6
10
 
7
11
  export class SortManager {
8
12
  handlers = Object.freeze({
@@ -13,11 +17,11 @@ export class SortManager {
13
17
  set: items => this.set(items),
14
18
  } satisfies TabelaSort);
15
19
 
16
- items: ArrayKeySorter<PlainObject>[] = [];
20
+ items: PlainObject[] = [];
17
21
 
18
- constructor(public state: TabelaState) {}
22
+ constructor(public state: State) {}
19
23
 
20
- add(field: string, direction?: SortDirection): void {
24
+ add(field: string, direction?: TabelaSortDirection): void {
21
25
  const index = this.items.findIndex(item => item.key === field);
22
26
 
23
27
  if (index > -1) {
@@ -84,7 +88,7 @@ export class SortManager {
84
88
  }
85
89
  }
86
90
 
87
- set(items: SortItem[]): void {
91
+ set(items: TabelaSortItem[]): void {
88
92
  this.items.splice(
89
93
  0,
90
94
  this.items.length,
@@ -118,15 +122,8 @@ export class SortManager {
118
122
  );
119
123
  }
120
124
 
121
- state.managers.data.values.keys.active =
122
- items.length === 0
123
- ? undefined
124
- : (sort(
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
- items,
129
- ).map(row => row[state.key]) as Key[]);
125
+ state.managers.data.state.items.active =
126
+ items.length === 0 ? undefined : getSortedItems(state, items);
130
127
 
131
128
  state.managers.render.update(true, true);
132
129
  }
@@ -147,3 +144,71 @@ export class SortManager {
147
144
  }
148
145
  }
149
146
  }
147
+
148
+ function getSortedItems(state: State, sorters: PlainObject[]): DataItem[] {
149
+ const data =
150
+ state.managers.data.state.items.active?.map(key =>
151
+ key instanceof GroupComponent ? key : state.managers.data.state.values.mapped.get(key)!,
152
+ ) ?? state.managers.data.state.values.array.slice();
153
+
154
+ if (!state.managers.group.enabled) {
155
+ return sort(data as PlainObject[], sorters as never).map(
156
+ item => getValue(item, state.key) as Key,
157
+ );
158
+ }
159
+
160
+ return sortWithGroups(state, data, sorters).map(item =>
161
+ item instanceof GroupComponent ? item : (getValue(item, state.key) as Key),
162
+ );
163
+ }
164
+
165
+ export function sortWithGroups(
166
+ state: State,
167
+ data: Array<GroupComponent | PlainObject>,
168
+ sorters: PlainObject[],
169
+ ): Array<GroupComponent | PlainObject> {
170
+ const {length} = sorters;
171
+
172
+ return data.sort((first, second) => {
173
+ const firstValue =
174
+ first instanceof GroupComponent
175
+ ? first.value.stringified
176
+ : getValue(first, state.managers.group.field);
177
+
178
+ const secondValue =
179
+ second instanceof GroupComponent
180
+ ? second.value.stringified
181
+ : getValue(second, state.managers.group.field);
182
+
183
+ const firstOrder = state.managers.group.order[firstValue as never];
184
+ const secondOrder = state.managers.group.order[secondValue as never];
185
+
186
+ const groupComparison = compare(firstOrder, secondOrder);
187
+
188
+ if (groupComparison !== 0) {
189
+ return groupComparison;
190
+ }
191
+
192
+ const firstIsGroup = first instanceof GroupComponent;
193
+ const secondIsGroup = second instanceof GroupComponent;
194
+
195
+ if (firstIsGroup || secondIsGroup) {
196
+ return firstIsGroup && secondIsGroup ? 0 : firstIsGroup ? -1 : 1;
197
+ }
198
+
199
+ for (let index = 0; index < length; index += 1) {
200
+ const sorter = sorters[index];
201
+
202
+ const comparison = compare(
203
+ getValue(first, (sorter as any).key),
204
+ getValue(second, (sorter as any).key),
205
+ );
206
+
207
+ if (comparison !== 0) {
208
+ return comparison * (sorter.direction === 'ascending' ? 1 : -1);
209
+ }
210
+ }
211
+
212
+ return 0;
213
+ });
214
+ }
@@ -0,0 +1,156 @@
1
+ import type {State} from '../models/tabela.model';
2
+
3
+ export class StyleManager {
4
+ constructor(readonly state: State) {
5
+ if (appended) {
6
+ return;
7
+ }
8
+
9
+ appended = true;
10
+
11
+ const style = document.createElement('style');
12
+
13
+ style.textContent = styling;
14
+
15
+ document.head.appendChild(style);
16
+ }
17
+ }
18
+
19
+ const styling = //css
20
+ `/** Table */
21
+
22
+ :where(.tabela) {
23
+ flex: 1;
24
+ position: relative;
25
+ background-color: var(--oui-absolute);
26
+ border: 1px solid grey;
27
+ }
28
+
29
+ :where(.tabela__table) {
30
+ min-height: 24em;
31
+ display: flex;
32
+ flex-flow: column nowrap;
33
+ flex: 1;
34
+ overflow: auto;
35
+ position: absolute;
36
+ inset: 0;
37
+ }
38
+
39
+ /** Row group */
40
+
41
+ :where(.tabela__rowgroup--header),
42
+ :where(.tabela__rowgroup--footer) {
43
+ background-color: white;
44
+ position: sticky;
45
+ left: 0;
46
+ z-index: 10;
47
+ }
48
+
49
+ :where(.tabela__rowgroup--header) {
50
+ top: 0;
51
+ }
52
+
53
+ :where(.tabela__rowgroup--footer) {
54
+ bottom: 0;
55
+ }
56
+
57
+ :where(.tabela__rowgroup--body) {
58
+ display: flex;
59
+ flex-flow: column nowrap;
60
+ flex: 1;
61
+ }
62
+
63
+ :where(.tabela__rowgroup--body:focus) {
64
+ outline: none;
65
+ }
66
+
67
+ :where(.tabela:has(.tabela__rowgroup--body:focus-visible)) {
68
+ outline: 2px solid var(--oui-blue-6);
69
+ outline-offset: 2px;
70
+ }
71
+
72
+ /** Row */
73
+
74
+ :where(.tabela__row) {
75
+ width: 100%;
76
+ display: flex;
77
+ flex-flow: row nowrap;
78
+ }
79
+
80
+ :where(.tabela__row:last-child .tabela__cell) {
81
+ border-bottom-width: 0;
82
+ }
83
+
84
+ :where(.tabela__row--body),
85
+ :where(.tabela__row--group) {
86
+ flex: 1;
87
+ position: absolute;
88
+ }
89
+
90
+ :where(.tabela__row--selected) {
91
+ background-color: var(--oui-blue-1);
92
+ color: var(--oui-blue-9);
93
+ }
94
+
95
+ :where(.tabela:has(.tabela__rowgroup--body:focus-visible) .tabela__row[data-active="true"]) {
96
+ outline: 2px solid var(--oui-blue-6);
97
+ outline-offset: 2px;
98
+ }
99
+
100
+ /** Cells */
101
+
102
+ :where(.tabela__cell),
103
+ :where(.tabela__heading) {
104
+ padding: 0.5em;
105
+ border-color: gray;
106
+ border-style: solid;
107
+ border-width: 0 1px 1px 0;
108
+ line-height: 1;
109
+ }
110
+
111
+ :where(.tabela__row .tabela__cell:last-child),
112
+ :where(.tabela__row .tabela__heading:last-child) {
113
+ flex: 1;
114
+ border-right-width: 0;
115
+ }
116
+
117
+ :where(.tabela__cell) {
118
+ overflow: hidden;
119
+ text-overflow: ellipsis;
120
+ white-space: nowrap;
121
+ }
122
+
123
+ :where(.tabela__cell--footer) {
124
+ border-top-width: 1px;
125
+ border-bottom-width: 0;
126
+ }
127
+
128
+ :where(.tabela__cell--group) {
129
+ padding: 0;
130
+ display: flex;
131
+ flex-flow: row nowrap;
132
+ align-items: center;
133
+ gap: 0.5em;
134
+ }
135
+
136
+ :where(.tabela__cell--group .tabela__button) {
137
+ margin: 0 0 0 .25rem;
138
+ }
139
+
140
+ /** Misc. */
141
+
142
+ :where(.tabela__button) {
143
+ font-size: .75rem;
144
+ font-weight: bold;
145
+ }
146
+
147
+ :where(.tabela__selection) {
148
+ background-color: color-mix(in oklch, var(--oui-blue-6), transparent);
149
+ border: 1px solid var(--oui-blue-6);
150
+ border-radius: .25rem;
151
+ position: fixed;
152
+ z-index: 1000;
153
+ }
154
+ `.replace(/^\s+|\s+|\s+$/g, ' ');
155
+
156
+ let appended = false;
@@ -1,11 +1,11 @@
1
- export type TabelaColumn = {
1
+ export type Column = {
2
2
  field: string;
3
3
  title: string;
4
4
  type: TabelaColumnType;
5
5
  width: number;
6
6
  };
7
7
 
8
- export type TabelaColumnOptions = {
8
+ export type TabelaColumn = {
9
9
  field: string;
10
10
  title: string;
11
11
  type: TabelaColumnType;
@@ -1,16 +1,30 @@
1
1
  import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
2
+ import type {GroupComponent} from '../components/group.component';
3
+ import type {State} from './tabela.model';
2
4
 
3
- export type DataValues = {
4
- keys: DataValuesKeys;
5
- objects: DataValuesObjects;
6
- };
5
+ export type DataItem = GroupComponent | Key;
7
6
 
8
- type DataValuesKeys = {
9
- active?: Key[];
10
- original: Key[];
7
+ type DataItems = {
8
+ active?: Array<DataItem>;
9
+ original: Array<DataItem>;
11
10
  };
12
11
 
13
- type DataValuesObjects = {
14
- array: PlainObject[];
12
+ export type DataState = {
13
+ items: DataItems;
14
+ values: DataValues;
15
+ } & State;
16
+
17
+ type DataValues = {
18
+ array: Array<GroupComponent | PlainObject>;
15
19
  mapped: Map<Key, PlainObject>;
16
20
  };
21
+
22
+ export type TabelaData = {
23
+ add(data: PlainObject[]): void;
24
+ clear(): void;
25
+ get(active?: boolean): PlainObject[];
26
+ remove(keys: Key[]): void;
27
+ remove(data: PlainObject[]): void;
28
+ synchronize(data: PlainObject[], remove?: boolean): void;
29
+ update(data: PlainObject[]): void;
30
+ };
@@ -1,4 +1,12 @@
1
- export type FilterComparison =
1
+ export type TabelaFilter = {
2
+ add(item: TabelaFilterItem): void;
3
+ clear(): void;
4
+ remove(field: string): void;
5
+ remove(item: TabelaFilterItem): void;
6
+ set(items: TabelaFilterItem[]): void;
7
+ };
8
+
9
+ export type TabelaFilterComparison =
2
10
  | 'contains'
3
11
  | 'ends-with'
4
12
  | 'equals'
@@ -10,8 +18,8 @@ export type FilterComparison =
10
18
  | 'not-equals'
11
19
  | 'starts-with';
12
20
 
13
- export type FilterItem = {
14
- comparison: FilterComparison;
21
+ export type TabelaFilterItem = {
22
+ comparison: TabelaFilterComparison;
15
23
  field: string;
16
24
  value: unknown;
17
25
  };
@@ -0,0 +1,8 @@
1
+ export type GroupValue = {
2
+ original: unknown;
3
+ stringified: string;
4
+ };
5
+
6
+ export type TabelaGroup = {
7
+ set(group?: string): void;
8
+ };
@@ -1,4 +1,4 @@
1
- import type {TabelaState} from './tabela.model';
1
+ import type {State} from './tabela.model';
2
2
 
3
3
  export type RenderElementPool = {
4
4
  cells: Record<string, HTMLDivElement[]>;
@@ -13,4 +13,4 @@ export type RenderRange = {
13
13
  export type RenderState = {
14
14
  active: boolean;
15
15
  top: number;
16
- } & TabelaState;
16
+ } & State;
@@ -0,0 +1,9 @@
1
+ import type {Key} from '@oscarpalmer/atoms/models';
2
+
3
+ export type TabelaSelection = {
4
+ add(keys: Key[]): void;
5
+ clear(): void;
6
+ remove(keys: Key[]): void;
7
+ set(keys: Key[]): void;
8
+ toggle(): void;
9
+ };
@@ -1,6 +1,14 @@
1
- export type SortDirection = 'ascending' | 'descending';
1
+ export type TabelaSort = {
2
+ add(field: string, direction?: TabelaSortDirection): void;
3
+ clear(): void;
4
+ flip(field: string): void;
5
+ remove(field: string): void;
6
+ set(items: TabelaSortItem[]): void;
7
+ };
8
+
9
+ export type TabelaSortDirection = 'ascending' | 'descending';
2
10
 
3
- export type SortItem = {
4
- direction: SortDirection;
11
+ export type TabelaSortItem = {
12
+ direction: TabelaSortDirection;
5
13
  field: string;
6
14
  };