@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
@@ -3,53 +3,78 @@ import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
3
3
  import {compare} from '@oscarpalmer/atoms/value/compare';
4
4
  import {getValue} from '@oscarpalmer/atoms/value/handle';
5
5
  import {setAttribute, setAttributes} from '@oscarpalmer/toretto/attribute';
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';
6
+ import {isGroupKey} from '../helpers/misc.helpers';
7
+ import type {DataValue} from '../models/data.model';
8
+ import {
9
+ ARIA_SORT,
10
+ ATTRIBUTE_DATA_SORT_DIRECTION,
11
+ ATTRIBUTE_DATA_SORT_POSITION,
12
+ } from '../models/dom.model';
13
+ import {
14
+ EVENT_DATA_SORTED,
15
+ EVENT_SORT_ADD,
16
+ EVENT_SORT_CLEAR,
17
+ EVENT_SORT_FLIP,
18
+ EVENT_SORT_REMOVE,
19
+ EVENT_SORT_SET,
20
+ } from '../models/event.model';
21
+ import {
22
+ SORT_ASCENDING,
23
+ SORT_DESCENDING,
24
+ type TabelaSort,
25
+ type TabelaSortDirection,
26
+ type TabelaSortItem,
27
+ } from '../models/sort.model';
9
28
  import type {State} from '../models/tabela.model';
10
29
 
11
30
  export class SortManager {
12
- handlers = Object.freeze({
31
+ handlers: TabelaSort = {
13
32
  add: (field, direction) => this.add(field, direction),
14
33
  flip: field => this.flip(field),
15
34
  clear: () => this.clear(),
16
35
  remove: field => this.remove(field),
17
- set: items => this.set(items),
18
- } satisfies TabelaSort);
36
+ set: items => this.set(items, true),
37
+ };
19
38
 
20
- items: PlainObject[] = [];
39
+ items: TabelaSortItem[] = [];
21
40
 
22
41
  constructor(public state: State) {}
23
42
 
24
- add(field: string, direction?: TabelaSortDirection): void {
25
- const index = this.items.findIndex(item => item.key === field);
43
+ add(key: string, direction?: TabelaSortDirection): void {
44
+ const index = this.items.findIndex(item => item.key === key);
26
45
 
27
46
  if (index > -1) {
28
47
  return;
29
48
  }
30
49
 
31
50
  this.items.push({
32
- key: field,
33
- direction: direction ?? 'ascending',
51
+ key,
52
+ direction: direction ?? SORT_ASCENDING,
34
53
  });
35
54
 
55
+ this.state.managers.event.emit(EVENT_SORT_ADD, [{key, direction: direction ?? SORT_ASCENDING}]);
56
+
36
57
  this.sort();
37
58
  }
38
59
 
39
- addOrSet(event: MouseEvent, field: string): void {
60
+ addOrSet(event: MouseEvent, key: string): void {
40
61
  if (event.ctrlKey || event.metaKey) {
41
- this.add(field);
62
+ this.add(key);
42
63
  } else {
43
- this.set([{field, direction: 'ascending'}]);
64
+ this.set([{key, direction: SORT_ASCENDING}], false);
44
65
  }
45
66
  }
46
67
 
47
68
  clear(): void {
48
- if (this.items.length > 0) {
49
- this.items.length = 0;
50
-
51
- this.sort();
69
+ if (this.items.length === 0) {
70
+ return;
52
71
  }
72
+
73
+ this.items.length = 0;
74
+
75
+ this.state.managers.event.emit(EVENT_SORT_CLEAR);
76
+
77
+ this.sort();
53
78
  }
54
79
 
55
80
  destroy(): void {
@@ -58,43 +83,57 @@ export class SortManager {
58
83
  this.state = undefined as never;
59
84
  }
60
85
 
61
- flip(field: string): void {
62
- const item = this.items.find(item => item.key === field);
86
+ flip(key: string): void {
87
+ const item = this.items.find(item => item.key === key);
63
88
 
64
89
  if (item == null) {
65
90
  return;
66
91
  }
67
92
 
68
- item.direction = item.direction === 'ascending' ? 'descending' : 'ascending';
93
+ item.direction = item.direction === SORT_ASCENDING ? SORT_DESCENDING : SORT_ASCENDING;
94
+
95
+ this.state.managers.event.emit(EVENT_SORT_FLIP, [{key, direction: item.direction}]);
69
96
 
70
97
  this.sort();
71
98
  }
72
99
 
73
- remove(field: string): void {
74
- const index = this.items.findIndex(item => item.key === field);
75
-
76
- if (index > -1) {
77
- this.items.splice(index, 1);
100
+ remove(key: string): void {
101
+ const index = this.items.findIndex(item => item.key === key);
78
102
 
79
- this.sort();
103
+ if (index === -1) {
104
+ return;
80
105
  }
81
- }
82
106
 
83
- removeOrClear(event: MouseEvent, field: string): void {
84
- if (event.ctrlKey || event.metaKey) {
85
- this.remove(field);
86
- } else {
87
- this.clear();
107
+ const spliced = this.items.splice(index, 1);
108
+
109
+ this.state.managers.event.emit(EVENT_SORT_REMOVE, spliced);
110
+
111
+ if (this.items.length === 0) {
112
+ this.state.managers.event.emit(EVENT_SORT_CLEAR);
88
113
  }
114
+
115
+ this.sort();
89
116
  }
90
117
 
91
- set(items: TabelaSortItem[]): void {
92
- this.items.splice(
118
+ set(items: TabelaSortItem[], set: boolean): void {
119
+ const removed = this.items.splice(
93
120
  0,
94
121
  this.items.length,
95
- ...items.map(item => ({key: item.field, direction: item.direction})),
122
+ ...items.map(item => ({key: item.key, direction: item.direction})),
96
123
  );
97
124
 
125
+ if (set) {
126
+ this.state.managers.event.emit(EVENT_SORT_SET, {
127
+ removed,
128
+ added: items.map(item => ({key: item.key, direction: item.direction})),
129
+ });
130
+ } else {
131
+ this.state.managers.event.emit(
132
+ EVENT_SORT_ADD,
133
+ items.map(item => ({key: item.key, direction: item.direction})),
134
+ );
135
+ }
136
+
98
137
  this.sort();
99
138
  }
100
139
 
@@ -106,50 +145,51 @@ export class SortManager {
106
145
  for (let index = 0; index < length; index += 1) {
107
146
  const column = state.managers.column.items[index];
108
147
 
109
- const sorterIndex = items.findIndex(item => item.key === column.options.field);
148
+ const sorterIndex = items.findIndex(item => item.key === column.options.key);
110
149
  const sorterItem = items[sorterIndex];
111
150
 
112
151
  setAttributes(column.elements.wrapper, {
113
- 'aria-sort':
114
- sorterItem == null ? 'none' : items.length > 1 ? 'other' : sorterItem.direction,
115
- 'data-sort-direction': sorterItem == null ? undefined : sorterItem.direction,
152
+ [ARIA_SORT]:
153
+ sorterItem == null ? SORT_NONE : items.length > 1 ? SORT_OTHER : sorterItem.direction,
154
+ [ATTRIBUTE_DATA_SORT_DIRECTION]: sorterItem == null ? undefined : sorterItem.direction,
116
155
  });
117
156
 
118
157
  setAttribute(
119
158
  column.elements.sorter,
120
- 'data-sort-position',
159
+ ATTRIBUTE_DATA_SORT_POSITION,
121
160
  sorterIndex > -1 && items.length > 1 ? sorterIndex + 1 : undefined,
122
161
  );
123
162
  }
124
163
 
125
- state.managers.data.state.items.active =
164
+ state.managers.data.state.keys.active =
126
165
  items.length === 0 ? undefined : getSortedItems(state, items);
127
166
 
167
+ state.managers.event.emit(EVENT_DATA_SORTED, state.managers.data.get(true));
168
+
128
169
  state.managers.render.update(true, true);
129
170
  }
130
171
 
131
- toggle(event: MouseEvent, field: string, direction?: string | null): void {
172
+ toggle(event: MouseEvent, key: string, direction?: string | null): void {
132
173
  switch (direction) {
133
- case 'ascending':
134
- this.flip(field);
174
+ case SORT_ASCENDING:
175
+ this.flip(key);
135
176
  return;
136
177
 
137
- case 'descending':
138
- this.removeOrClear(event, field);
178
+ case SORT_DESCENDING:
179
+ this.remove(key);
139
180
  return;
140
181
 
141
182
  default:
142
- this.addOrSet(event, field);
183
+ this.addOrSet(event, key);
143
184
  return;
144
185
  }
145
186
  }
146
187
  }
147
188
 
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();
189
+ function getSortedItems(state: State, sorters: TabelaSortItem[]): Key[] {
190
+ const data = (state.managers.data.state.keys.active?.map(key =>
191
+ isGroupKey(key) ? key : state.managers.data.state.values.mapped.get(key)!,
192
+ ) ?? state.managers.data.state.values.array) as DataValue[];
153
193
 
154
194
  if (!state.managers.group.enabled) {
155
195
  return sort(data as PlainObject[], sorters as never).map(
@@ -158,27 +198,28 @@ function getSortedItems(state: State, sorters: PlainObject[]): DataItem[] {
158
198
  }
159
199
 
160
200
  return sortWithGroups(state, data, sorters).map(item =>
161
- item instanceof GroupComponent ? item : (getValue(item, state.key) as Key),
162
- );
201
+ isGroupKey(item) ? item : (getValue(item as PlainObject, state.key) as Key),
202
+ ) as Key[];
163
203
  }
164
204
 
165
205
  export function sortWithGroups(
166
206
  state: State,
167
- data: Array<GroupComponent | PlainObject>,
168
- sorters: PlainObject[],
169
- ): Array<GroupComponent | PlainObject> {
207
+ data: DataValue[],
208
+ sorters: TabelaSortItem[],
209
+ ): DataValue[] {
170
210
  const {length} = sorters;
171
211
 
172
212
  return data.sort((first, second) => {
173
- const firstValue =
174
- first instanceof GroupComponent
175
- ? first.value.stringified
176
- : getValue(first, state.managers.group.field);
213
+ const firstIsGroup = isGroupKey(first);
214
+ const secondIsGroup = isGroupKey(second);
215
+
216
+ const firstValue = firstIsGroup
217
+ ? state.managers.group.getForKey(first as string)!.value.stringified
218
+ : getValue(first as PlainObject, state.managers.group.key);
177
219
 
178
- const secondValue =
179
- second instanceof GroupComponent
180
- ? second.value.stringified
181
- : getValue(second, state.managers.group.field);
220
+ const secondValue = secondIsGroup
221
+ ? state.managers.group.getForKey(second as string)!.value.stringified
222
+ : getValue(second as PlainObject, state.managers.group.key);
182
223
 
183
224
  const firstOrder = state.managers.group.order[firstValue as never];
184
225
  const secondOrder = state.managers.group.order[secondValue as never];
@@ -189,9 +230,6 @@ export function sortWithGroups(
189
230
  return groupComparison;
190
231
  }
191
232
 
192
- const firstIsGroup = first instanceof GroupComponent;
193
- const secondIsGroup = second instanceof GroupComponent;
194
-
195
233
  if (firstIsGroup || secondIsGroup) {
196
234
  return firstIsGroup && secondIsGroup ? 0 : firstIsGroup ? -1 : 1;
197
235
  }
@@ -200,15 +238,19 @@ export function sortWithGroups(
200
238
  const sorter = sorters[index];
201
239
 
202
240
  const comparison = compare(
203
- getValue(first, (sorter as any).key),
204
- getValue(second, (sorter as any).key),
241
+ getValue(first as PlainObject, sorter.key),
242
+ getValue(second as PlainObject, sorter.key),
205
243
  );
206
244
 
207
245
  if (comparison !== 0) {
208
- return comparison * (sorter.direction === 'ascending' ? 1 : -1);
246
+ return comparison * (sorter.direction === SORT_ASCENDING ? 1 : -1);
209
247
  }
210
248
  }
211
249
 
212
250
  return 0;
213
251
  });
214
252
  }
253
+
254
+ const SORT_NONE = 'none';
255
+
256
+ const SORT_OTHER = 'other';
@@ -1,3 +1,20 @@
1
+ import {
2
+ CSS_BUTTON,
3
+ CSS_CELL,
4
+ CSS_CELL_FOOTER,
5
+ CSS_CELL_GROUP,
6
+ CSS_HEADING,
7
+ CSS_HEADING_CONTENT,
8
+ CSS_HEADING_SORTER,
9
+ CSS_ROW,
10
+ CSS_ROW_SELECTED,
11
+ CSS_ROWGROUP_BODY,
12
+ CSS_ROWGROUP_FOOTER,
13
+ CSS_ROWGROUP_HEADER,
14
+ CSS_SELECTION,
15
+ CSS_TABLE,
16
+ CSS_WRAPPER,
17
+ } from '../models/style.model';
1
18
  import type {State} from '../models/tabela.model';
2
19
 
3
20
  export class StyleManager {
@@ -19,14 +36,14 @@ export class StyleManager {
19
36
  const styling = //css
20
37
  `/** Table */
21
38
 
22
- :where(.tabela) {
39
+ :where(.${CSS_WRAPPER}) {
23
40
  flex: 1;
24
41
  position: relative;
25
42
  background-color: var(--oui-absolute);
26
43
  border: 1px solid grey;
27
44
  }
28
45
 
29
- :where(.tabela__table) {
46
+ :where(.${CSS_TABLE}) {
30
47
  min-height: 24em;
31
48
  display: flex;
32
49
  flex-flow: column nowrap;
@@ -38,69 +55,69 @@ const styling = //css
38
55
 
39
56
  /** Row group */
40
57
 
41
- :where(.tabela__rowgroup--header),
42
- :where(.tabela__rowgroup--footer) {
58
+ :where(.${CSS_ROWGROUP_HEADER}),
59
+ :where(.${CSS_ROWGROUP_FOOTER}) {
43
60
  background-color: white;
44
61
  position: sticky;
45
62
  left: 0;
46
63
  z-index: 10;
47
64
  }
48
65
 
49
- :where(.tabela__rowgroup--header) {
66
+ :where(.${CSS_ROWGROUP_HEADER}) {
50
67
  top: 0;
51
68
  }
52
69
 
53
- :where(.tabela__rowgroup--footer) {
70
+ :where(.${CSS_ROWGROUP_FOOTER}) {
54
71
  bottom: 0;
55
72
  }
56
73
 
57
- :where(.tabela__rowgroup--body) {
74
+ :where(.${CSS_ROWGROUP_BODY}) {
58
75
  display: flex;
59
76
  flex-flow: column nowrap;
60
77
  flex: 1;
61
78
  }
62
79
 
63
- :where(.tabela__rowgroup--body:focus) {
80
+ :where(.${CSS_ROWGROUP_BODY}:focus) {
64
81
  outline: none;
65
82
  }
66
83
 
67
- :where(.tabela:has(.tabela__rowgroup--body:focus-visible)) {
84
+ :where(.${CSS_WRAPPER}:has(.${CSS_ROWGROUP_BODY}:focus-visible)) {
68
85
  outline: 2px solid var(--oui-blue-6);
69
86
  outline-offset: 2px;
70
87
  }
71
88
 
72
89
  /** Row */
73
90
 
74
- :where(.tabela__row) {
91
+ :where(.${CSS_ROW}) {
75
92
  width: 100%;
76
93
  display: flex;
77
94
  flex-flow: row nowrap;
78
95
  }
79
96
 
80
- :where(.tabela__row:last-child .tabela__cell) {
97
+ :where(.${CSS_ROW}:last-child .${CSS_CELL}) {
81
98
  border-bottom-width: 0;
82
99
  }
83
100
 
84
- :where(.tabela__row--body),
85
- :where(.tabela__row--group) {
101
+ :where(.${CSS_ROW}--body),
102
+ :where(.${CSS_ROW}--group) {
86
103
  flex: 1;
87
104
  position: absolute;
88
105
  }
89
106
 
90
- :where(.tabela__row--selected) {
107
+ :where(.${CSS_ROW_SELECTED}) {
91
108
  background-color: var(--oui-blue-1);
92
109
  color: var(--oui-blue-9);
93
110
  }
94
111
 
95
- :where(.tabela:has(.tabela__rowgroup--body:focus-visible) .tabela__row[data-active="true"]) {
112
+ :where(.${CSS_WRAPPER}:has(.${CSS_ROWGROUP_BODY}:focus-visible) .${CSS_ROW}[data-active="true"]) {
96
113
  outline: 2px solid var(--oui-blue-6);
97
114
  outline-offset: 2px;
98
115
  }
99
116
 
100
117
  /** Cells */
101
118
 
102
- :where(.tabela__cell),
103
- :where(.tabela__heading) {
119
+ :where(.${CSS_CELL}),
120
+ :where(.${CSS_HEADING}) {
104
121
  padding: 0.5em;
105
122
  border-color: gray;
106
123
  border-style: solid;
@@ -108,24 +125,55 @@ const styling = //css
108
125
  line-height: 1;
109
126
  }
110
127
 
111
- :where(.tabela__row .tabela__cell:last-child),
112
- :where(.tabela__row .tabela__heading:last-child) {
128
+ :where(.${CSS_WRAPPER} .${CSS_CELL}:last-child),
129
+ :where(.${CSS_ROW} .${CSS_HEADING}:last-child) {
113
130
  flex: 1;
114
131
  border-right-width: 0;
115
132
  }
116
133
 
117
- :where(.tabela__cell) {
134
+ :where(.${CSS_CELL}) {
118
135
  overflow: hidden;
119
136
  text-overflow: ellipsis;
120
137
  white-space: nowrap;
121
138
  }
122
139
 
123
- :where(.tabela__cell--footer) {
140
+ :where(.${CSS_HEADING}) {
141
+ display: flex;
142
+ flex-flow: row nowrap;
143
+ align-items: center;
144
+ justify-content: space-between;
145
+ gap: 0.5em;
146
+ cursor: pointer;
147
+ }
148
+
149
+ :where(.${CSS_HEADING_CONTENT}) {
150
+ overflow: hidden;
151
+ white-space: nowrap;
152
+ text-overflow: ellipsis;
153
+ }
154
+
155
+ :where(.${CSS_HEADING}[data-sort-direction] .${CSS_HEADING_SORTER})::after {
156
+ width: 1em;
157
+ height: 1em;
158
+ display: inline-flex;
159
+ font-size: .75em;
160
+ font-weight: bold;
161
+ }
162
+
163
+ :where(.${CSS_HEADING}[data-sort-direction="ascending"] .${CSS_HEADING_SORTER})::after {
164
+ content: '\\21C8';
165
+ }
166
+
167
+ :where(.${CSS_HEADING}[data-sort-direction="descending"] .${CSS_HEADING_SORTER})::after {
168
+ content: '\\21CA';
169
+ }
170
+
171
+ :where(.${CSS_CELL_FOOTER}) {
124
172
  border-top-width: 1px;
125
173
  border-bottom-width: 0;
126
174
  }
127
175
 
128
- :where(.tabela__cell--group) {
176
+ :where(.${CSS_CELL_GROUP}) {
129
177
  padding: 0;
130
178
  display: flex;
131
179
  flex-flow: row nowrap;
@@ -133,18 +181,18 @@ const styling = //css
133
181
  gap: 0.5em;
134
182
  }
135
183
 
136
- :where(.tabela__cell--group .tabela__button) {
184
+ :where(.${CSS_CELL_GROUP} .${CSS_BUTTON}) {
137
185
  margin: 0 0 0 .25rem;
138
186
  }
139
187
 
140
188
  /** Misc. */
141
189
 
142
- :where(.tabela__button) {
190
+ :where(.${CSS_BUTTON}) {
143
191
  font-size: .75rem;
144
192
  font-weight: bold;
145
193
  }
146
194
 
147
- :where(.tabela__selection) {
195
+ :where(.${CSS_SELECTION}) {
148
196
  background-color: color-mix(in oklch, var(--oui-blue-6), transparent);
149
197
  border: 1px solid var(--oui-blue-6);
150
198
  border-radius: .25rem;
@@ -1,15 +1,11 @@
1
1
  export type Column = {
2
- field: string;
3
- title: string;
4
- type: TabelaColumnType;
2
+ key: string;
3
+ label: string;
5
4
  width: number;
6
5
  };
7
6
 
8
7
  export type TabelaColumn = {
9
- field: string;
10
- title: string;
11
- type: TabelaColumnType;
8
+ key: string;
9
+ label: string;
12
10
  width?: number;
13
11
  };
14
-
15
- export type TabelaColumnType = 'boolean' | 'date' | 'date-time' | 'number' | 'string' | 'time';
@@ -1,30 +1,29 @@
1
1
  import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
2
- import type {GroupComponent} from '../components/group.component';
3
2
  import type {State} from './tabela.model';
4
3
 
5
- export type DataItem = GroupComponent | Key;
6
-
7
- type DataItems = {
8
- active?: Array<DataItem>;
9
- original: Array<DataItem>;
4
+ type DataKeys = {
5
+ active?: Key[];
6
+ original: Key[];
10
7
  };
11
8
 
12
9
  export type DataState = {
13
- items: DataItems;
10
+ keys: DataKeys;
14
11
  values: DataValues;
15
12
  } & State;
16
13
 
14
+ export type DataValue = string | PlainObject;
15
+
17
16
  type DataValues = {
18
- array: Array<GroupComponent | PlainObject>;
17
+ array: DataValue[];
19
18
  mapped: Map<Key, PlainObject>;
20
19
  };
21
20
 
22
21
  export type TabelaData = {
23
- add(data: PlainObject[]): void;
24
- clear(): void;
22
+ add(data: PlainObject[]): Promise<void>;
23
+ clear(): Promise<void>;
25
24
  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;
25
+ remove(keys: Key[]): Promise<void>;
26
+ remove(data: PlainObject[]): Promise<void>;
27
+ synchronize(data: PlainObject[], remove?: boolean): Promise<void>;
28
+ update(data: PlainObject[]): Promise<void>;
30
29
  };
@@ -0,0 +1,31 @@
1
+ export const ARIA_ACTIVEDESCENDANT = 'aria-activedescendant';
2
+
3
+ export const ARIA_LABEL = 'aria-label';
4
+
5
+ export const ARIA_SELECTED = 'aria-selected';
6
+
7
+ export const ARIA_SORT = 'aria-sort';
8
+
9
+ export const ATTRIBUTE_DATA_ACTIVE = 'data-active';
10
+
11
+ export const ATTRIBUTE_DATA_EVENT = 'data-event';
12
+
13
+ export const ATTRIBUTE_DATA_KEY = 'data-key';
14
+
15
+ export const ATTRIBUTE_DATA_SORT_DIRECTION = 'data-sort-direction';
16
+
17
+ export const ATTRIBUTE_DATA_SORT_POSITION = 'data-sort-position';
18
+
19
+ export const ATTRIBUTE_ROLE = 'role';
20
+
21
+ export const ELEMENT_DIV = 'div';
22
+
23
+ export const ROLE_CELL = 'cell';
24
+
25
+ export const ROLE_COLUMNHEADER = 'columnheader';
26
+
27
+ export const ROLE_ROW = 'row';
28
+
29
+ export const ROLE_ROWGROUP = 'rowgroup';
30
+
31
+ export const ROLE_TABLE = 'table';