@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.
- package/dist/body.component-_VDOpJhV.d.mts +10 -0
- package/dist/body.model-2iwsovAV.d.mts +7 -0
- package/dist/column.component-Bx46r3JI.d.mts +16 -0
- package/dist/column.model-D-aw4EU4.d.mts +16 -0
- package/dist/components/body.component.d.mts +2 -0
- package/dist/components/{body.component.js → body.component.mjs} +6 -3
- package/dist/components/column.component.d.mts +2 -0
- package/dist/components/{column.component.js → column.component.mjs} +12 -9
- package/dist/components/footer.component.d.mts +2 -0
- package/dist/components/{footer.component.js → footer.component.mjs} +7 -4
- package/dist/components/group.component.d.mts +2 -0
- package/dist/components/group.component.mjs +51 -0
- package/dist/components/header.component.d.mts +2 -0
- package/dist/components/{header.component.js → header.component.mjs} +6 -3
- package/dist/components/row.component.d.mts +2 -0
- package/dist/components/{row.component.js → row.component.mjs} +11 -7
- package/dist/filter.model-7ukJrtil.d.mts +16 -0
- package/dist/footer.component-Curiab8j.d.mts +12 -0
- package/dist/footer.model-DhqoS6ds.d.mts +8 -0
- package/dist/group.component-Cq1YYbfJ.d.mts +285 -0
- package/dist/group.model-BsKFwHbt.d.mts +10 -0
- package/dist/header.component-BjjlpZIg.d.mts +12 -0
- package/dist/header.model-DN_KzUCV.d.mts +7 -0
- package/dist/helpers/dom.helpers.d.mts +12 -0
- package/dist/helpers/{dom.helpers.js → dom.helpers.mjs} +14 -10
- package/dist/helpers/misc.helpers.d.mts +6 -0
- package/dist/helpers/{misc.helpers.js → misc.helpers.mjs} +3 -1
- package/dist/helpers/style.helper.d.mts +6 -0
- package/dist/helpers/style.helper.mjs +8 -0
- package/dist/index.d.mts +7 -0
- package/dist/{index.js → index.mjs} +3 -1
- package/dist/managers/column.manager.d.mts +2 -0
- package/dist/managers/{column.manager.js → column.manager.mjs} +6 -1
- package/dist/managers/data.manager.d.mts +2 -0
- package/dist/managers/data.manager.mjs +222 -0
- package/dist/managers/event.manager.d.mts +2 -0
- package/dist/managers/{event.manager.js → event.manager.mjs} +12 -8
- package/dist/managers/filter.manager.d.mts +2 -0
- package/dist/managers/{filter.manager.js → filter.manager.mjs} +25 -11
- package/dist/managers/group.manager.d.mts +2 -0
- package/dist/managers/group.manager.mjs +73 -0
- package/dist/managers/navigation.manager.d.mts +2 -0
- package/dist/managers/{navigation.manager.js → navigation.manager.mjs} +27 -24
- package/dist/managers/render.manager.d.mts +2 -0
- package/dist/managers/render.manager.mjs +144 -0
- package/dist/managers/row.manager.d.mts +2 -0
- package/dist/managers/{row.manager.js → row.manager.mjs} +18 -11
- package/dist/managers/selection.manager.d.mts +2 -0
- package/dist/managers/{selection.manager.js → selection.manager.mjs} +57 -48
- package/dist/managers/sort.manager.d.mts +2 -0
- package/dist/managers/{sort.manager.js → sort.manager.mjs} +32 -2
- package/dist/managers/style.manager.d.mts +2 -0
- package/dist/managers/style.manager.mjs +149 -0
- package/dist/models/body.model.d.mts +2 -0
- package/dist/models/body.model.mjs +1 -0
- package/dist/models/column.model.d.mts +2 -0
- package/dist/models/column.model.mjs +1 -0
- package/dist/models/data.model.d.mts +2 -0
- package/dist/models/data.model.mjs +1 -0
- package/dist/models/filter.model.d.mts +2 -0
- package/dist/models/filter.model.mjs +1 -0
- package/dist/models/footer.model.d.mts +2 -0
- package/dist/models/footer.model.mjs +1 -0
- package/dist/models/group.model.d.mts +2 -0
- package/dist/models/group.model.mjs +1 -0
- package/dist/models/header.model.d.mts +2 -0
- package/dist/models/header.model.mjs +1 -0
- package/dist/models/render.model.d.mts +2 -0
- package/dist/models/render.model.mjs +1 -0
- package/dist/models/selection.model.d.mts +2 -0
- package/dist/models/selection.model.mjs +1 -0
- package/dist/models/sort.model.d.mts +2 -0
- package/dist/models/sort.model.mjs +1 -0
- package/dist/models/style.model.d.mts +23 -0
- package/dist/models/style.model.mjs +23 -0
- package/dist/models/tabela.model.d.mts +2 -0
- package/dist/models/tabela.model.mjs +1 -0
- package/dist/models/tabela.options.d.mts +2 -0
- package/dist/models/tabela.options.mjs +1 -0
- package/dist/selection.model-rwQe9fco.d.mts +12 -0
- package/dist/sort.model-CauImaLu.d.mts +15 -0
- package/dist/tabela.d.mts +21 -0
- package/dist/{tabela.full.js → tabela.full.mjs} +1407 -1124
- package/dist/tabela.mjs +126 -0
- package/dist/tabela.options-RkZvfptB.d.mts +14 -0
- package/package.json +45 -37
- package/src/components/body.component.ts +4 -3
- package/src/components/column.component.ts +19 -24
- package/src/components/footer.component.ts +8 -3
- package/src/components/group.component.ts +85 -0
- package/src/components/header.component.ts +3 -2
- package/src/components/row.component.ts +10 -8
- package/src/helpers/dom.helpers.ts +24 -20
- package/src/helpers/style.helper.ts +1 -1
- package/src/managers/column.manager.ts +8 -4
- package/src/managers/data.manager.ts +265 -61
- package/src/managers/event.manager.ts +14 -11
- package/src/managers/filter.manager.ts +38 -19
- package/src/managers/group.manager.ts +131 -0
- package/src/managers/navigation.manager.ts +25 -23
- package/src/managers/render.manager.ts +84 -32
- package/src/managers/row.manager.ts +23 -11
- package/src/managers/selection.manager.ts +68 -54
- package/src/managers/sort.manager.ts +81 -16
- package/src/managers/style.manager.ts +156 -0
- package/src/models/column.model.ts +2 -2
- package/src/models/data.model.ts +23 -9
- package/src/models/filter.model.ts +11 -3
- package/src/models/group.model.ts +8 -0
- package/src/models/render.model.ts +2 -2
- package/src/models/selection.model.ts +9 -0
- package/src/models/sort.model.ts +11 -3
- package/src/models/style.model.ts +39 -0
- package/src/models/tabela.model.ts +14 -46
- package/src/models/tabela.options.ts +3 -2
- package/src/tabela.ts +72 -41
- package/dist/helpers/style.helper.js +0 -6
- package/dist/managers/data.manager.js +0 -120
- package/dist/managers/render.manager.js +0 -110
- package/dist/models/body.model.js +0 -0
- package/dist/models/column.model.js +0 -0
- package/dist/models/data.model.js +0 -0
- package/dist/models/filter.model.js +0 -0
- package/dist/models/footer.model.js +0 -0
- package/dist/models/header.model.js +0 -0
- package/dist/models/render.model.js +0 -0
- package/dist/models/sort.model.js +0 -0
- package/dist/models/tabela.model.js +0 -0
- package/dist/models/tabela.options.js +0 -0
- package/dist/tabela.js +0 -102
- package/types/components/body.component.d.ts +0 -6
- package/types/components/column.component.d.ts +0 -13
- package/types/components/footer.component.d.ts +0 -8
- package/types/components/header.component.d.ts +0 -8
- package/types/components/row.component.d.ts +0 -11
- package/types/helpers/dom.helpers.d.ts +0 -10
- package/types/helpers/misc.helpers.d.ts +0 -2
- package/types/helpers/style.helper.d.ts +0 -1
- package/types/index.d.ts +0 -4
- package/types/managers/column.manager.d.ts +0 -12
- package/types/managers/data.manager.d.ts +0 -27
- package/types/managers/event.manager.d.ts +0 -7
- package/types/managers/filter.manager.d.ts +0 -19
- package/types/managers/navigation.manager.d.ts +0 -10
- package/types/managers/render.manager.d.ts +0 -16
- package/types/managers/row.manager.d.ts +0 -13
- package/types/managers/selection.manager.d.ts +0 -18
- package/types/managers/sort.manager.d.ts +0 -26
- package/types/models/body.model.d.ts +0 -4
- package/types/models/column.model.d.ts +0 -13
- package/types/models/data.model.d.ts +0 -14
- package/types/models/filter.model.d.ts +0 -6
- package/types/models/footer.model.d.ts +0 -5
- package/types/models/header.model.d.ts +0 -4
- package/types/models/render.model.d.ts +0 -13
- package/types/models/sort.model.d.ts +0 -5
- package/types/models/tabela.model.d.ts +0 -69
- package/types/models/tabela.options.d.ts +0 -9
- 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 {
|
|
9
|
-
import type {TabelaSelection
|
|
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
|
-
|
|
15
|
-
|
|
23
|
+
remove: keys => this.remove(keys),
|
|
24
|
+
set: keys => this.set(keys),
|
|
16
25
|
toggle: () => this.toggle(),
|
|
17
|
-
}
|
|
26
|
+
} satisfies TabelaSelection);
|
|
18
27
|
|
|
19
28
|
items = new Set<Key>();
|
|
20
29
|
|
|
21
30
|
last: Key | undefined;
|
|
22
31
|
|
|
23
|
-
constructor(public state:
|
|
32
|
+
constructor(public state: State) {
|
|
24
33
|
mapped.set(state.element, this);
|
|
25
34
|
}
|
|
26
35
|
|
|
27
|
-
|
|
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
|
-
|
|
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.
|
|
48
|
-
|
|
44
|
+
if (!this.items.has(key)) {
|
|
45
|
+
this.items.add(key);
|
|
46
|
+
|
|
47
|
+
update = true;
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
if (
|
|
53
|
-
this.update(
|
|
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.
|
|
102
|
+
this.remove([key]);
|
|
92
103
|
} else {
|
|
93
|
-
this.
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
157
|
+
remove(keys: Key[]): void {
|
|
143
158
|
const {length} = keys;
|
|
144
159
|
|
|
145
|
-
|
|
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 (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
update = true;
|
|
165
|
+
if (this.items.delete(key)) {
|
|
166
|
+
removed.push(key);
|
|
154
167
|
}
|
|
155
168
|
}
|
|
156
169
|
|
|
157
|
-
if (
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
|
214
|
+
const element = state.managers.row.get(key, false)?.element;
|
|
201
215
|
|
|
202
|
-
if (
|
|
216
|
+
if (element == null) {
|
|
203
217
|
continue;
|
|
204
218
|
}
|
|
205
219
|
|
|
206
|
-
setAttribute(
|
|
220
|
+
setAttribute(element, 'aria-selected', String(!removed));
|
|
207
221
|
|
|
208
222
|
if (removed) {
|
|
209
|
-
|
|
223
|
+
element.classList.remove(CSS_TABELA_ROW_SELECTED);
|
|
210
224
|
} else {
|
|
211
|
-
|
|
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:
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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, '.
|
|
293
|
-
const startTable = findAncestor(startElement, '.
|
|
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
|
|
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
|
|
5
|
-
import type {
|
|
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:
|
|
20
|
+
items: PlainObject[] = [];
|
|
17
21
|
|
|
18
|
-
constructor(public state:
|
|
22
|
+
constructor(public state: State) {}
|
|
19
23
|
|
|
20
|
-
add(field: string, direction?:
|
|
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:
|
|
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.
|
|
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
|
|
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
|
|
8
|
+
export type TabelaColumn = {
|
|
9
9
|
field: string;
|
|
10
10
|
title: string;
|
|
11
11
|
type: TabelaColumnType;
|
package/src/models/data.model.ts
CHANGED
|
@@ -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
|
|
4
|
-
keys: DataValuesKeys;
|
|
5
|
-
objects: DataValuesObjects;
|
|
6
|
-
};
|
|
5
|
+
export type DataItem = GroupComponent | Key;
|
|
7
6
|
|
|
8
|
-
type
|
|
9
|
-
active?:
|
|
10
|
-
original:
|
|
7
|
+
type DataItems = {
|
|
8
|
+
active?: Array<DataItem>;
|
|
9
|
+
original: Array<DataItem>;
|
|
11
10
|
};
|
|
12
11
|
|
|
13
|
-
type
|
|
14
|
-
|
|
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
|
|
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
|
|
14
|
-
comparison:
|
|
21
|
+
export type TabelaFilterItem = {
|
|
22
|
+
comparison: TabelaFilterComparison;
|
|
15
23
|
field: string;
|
|
16
24
|
value: unknown;
|
|
17
25
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
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
|
-
} &
|
|
16
|
+
} & State;
|
package/src/models/sort.model.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
export type
|
|
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
|
|
4
|
-
direction:
|
|
11
|
+
export type TabelaSortItem = {
|
|
12
|
+
direction: TabelaSortDirection;
|
|
5
13
|
field: string;
|
|
6
14
|
};
|