@oscarpalmer/tabela 0.12.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} +8 -5
- 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} +13 -9
- 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} +9 -8
- package/dist/managers/filter.manager.d.mts +2 -0
- package/dist/managers/{filter.manager.js → filter.manager.mjs} +23 -14
- 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.js → render.manager.mjs} +35 -26
- 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} +32 -28
- package/dist/managers/sort.manager.d.mts +2 -0
- package/dist/managers/{sort.manager.js → sort.manager.mjs} +12 -9
- 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} +1073 -756
- 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 +13 -18
- package/src/components/footer.component.ts +8 -3
- package/src/components/group.component.ts +48 -6
- package/src/components/header.component.ts +3 -2
- package/src/components/row.component.ts +8 -6
- package/src/helpers/dom.helpers.ts +21 -19
- package/src/helpers/style.helper.ts +1 -1
- package/src/managers/column.manager.ts +4 -0
- package/src/managers/data.manager.ts +170 -100
- package/src/managers/event.manager.ts +9 -10
- package/src/managers/filter.manager.ts +23 -12
- package/src/managers/group.manager.ts +63 -11
- package/src/managers/navigation.manager.ts +23 -22
- package/src/managers/render.manager.ts +43 -29
- package/src/managers/row.manager.ts +21 -9
- package/src/managers/selection.manager.ts +28 -21
- package/src/managers/sort.manager.ts +22 -20
- package/src/managers/style.manager.ts +156 -0
- package/src/models/data.model.ts +11 -8
- package/src/models/group.model.ts +6 -2
- package/src/models/style.model.ts +39 -0
- package/src/models/tabela.model.ts +10 -8
- package/src/tabela.ts +65 -33
- package/dist/components/group.component.js +0 -28
- package/dist/helpers/style.helper.js +0 -6
- package/dist/managers/data.manager.js +0 -181
- package/dist/managers/group.manager.js +0 -46
- 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/group.model.js +0 -0
- package/dist/models/header.model.js +0 -0
- package/dist/models/render.model.js +0 -0
- package/dist/models/selection.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 -105
- 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/group.component.d.ts +0 -14
- 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 -29
- package/types/managers/event.manager.d.ts +0 -7
- package/types/managers/filter.manager.d.ts +0 -19
- package/types/managers/group.manager.d.ts +0 -17
- package/types/managers/navigation.manager.d.ts +0 -10
- package/types/managers/render.manager.d.ts +0 -17
- package/types/managers/row.manager.d.ts +0 -13
- package/types/managers/selection.manager.d.ts +0 -24
- package/types/managers/sort.manager.d.ts +0 -28
- 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 -24
- package/types/models/filter.model.d.ts +0 -13
- package/types/models/footer.model.d.ts +0 -5
- package/types/models/group.model.d.ts +0 -4
- package/types/models/header.model.d.ts +0 -4
- package/types/models/render.model.d.ts +0 -13
- package/types/models/selection.model.d.ts +0 -8
- package/types/models/sort.model.d.ts +0 -12
- package/types/models/tabela.model.d.ts +0 -39
- package/types/models/tabela.options.d.ts +0 -10
- package/types/tabela.d.ts +0 -15
|
@@ -2,7 +2,9 @@ import {sort} from '@oscarpalmer/atoms/array';
|
|
|
2
2
|
import {toRecord} from '@oscarpalmer/atoms/array/to-record';
|
|
3
3
|
import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
|
|
4
4
|
import type {Key, Simplify} from '@oscarpalmer/atoms/models';
|
|
5
|
-
import
|
|
5
|
+
import {getString} from '@oscarpalmer/atoms/string';
|
|
6
|
+
import {removeGroup, type GroupComponent} from '../components/group.component';
|
|
7
|
+
import type {TabelaGroup} from '../models/group.model';
|
|
6
8
|
import type {State} from '../models/tabela.model';
|
|
7
9
|
|
|
8
10
|
export class GroupManager {
|
|
@@ -12,11 +14,24 @@ export class GroupManager {
|
|
|
12
14
|
|
|
13
15
|
field!: string;
|
|
14
16
|
|
|
17
|
+
handlers = Object.freeze({
|
|
18
|
+
set: (group?: string) => {
|
|
19
|
+
if (group === this.field) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
this.enabled = !isNullableOrWhitespace(group);
|
|
24
|
+
this.field = group ?? '';
|
|
25
|
+
|
|
26
|
+
this.state.managers.data.set(this.state.managers.data.get());
|
|
27
|
+
},
|
|
28
|
+
} satisfies TabelaGroup);
|
|
29
|
+
|
|
15
30
|
items: GroupComponent[] = [];
|
|
16
31
|
|
|
17
32
|
order: Record<never, number> = {};
|
|
18
33
|
|
|
19
|
-
constructor(
|
|
34
|
+
constructor(public state: State) {
|
|
20
35
|
if (isNullableOrWhitespace(state.options.grouping)) {
|
|
21
36
|
return;
|
|
22
37
|
}
|
|
@@ -29,13 +44,38 @@ export class GroupManager {
|
|
|
29
44
|
this.set([...this.items, group]);
|
|
30
45
|
}
|
|
31
46
|
|
|
47
|
+
clear(): void {
|
|
48
|
+
const groups = this.items.splice(0);
|
|
49
|
+
const {length} = groups;
|
|
50
|
+
|
|
51
|
+
for (let index = 0; index < length; index += 1) {
|
|
52
|
+
this.remove(groups[index]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
destroy(): void {
|
|
57
|
+
const groups = this.items.splice(0);
|
|
58
|
+
const {length} = groups;
|
|
59
|
+
|
|
60
|
+
for (let index = 0; index < length; index += 1) {
|
|
61
|
+
removeGroup(groups[index]);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.collapsed.clear();
|
|
65
|
+
|
|
66
|
+
this.handlers = undefined as never;
|
|
67
|
+
this.state = undefined as never;
|
|
68
|
+
}
|
|
69
|
+
|
|
32
70
|
get(value: unknown) {
|
|
33
|
-
|
|
71
|
+
const asString = getString(value);
|
|
72
|
+
|
|
73
|
+
return this.items.find(item => item.value.stringified === asString);
|
|
34
74
|
}
|
|
35
75
|
|
|
36
76
|
handle(button: HTMLElement): void {
|
|
37
|
-
const
|
|
38
|
-
const group = this.get(
|
|
77
|
+
const value = button.dataset.key?.replace(`tabela_${this.state.id}_group:`, '');
|
|
78
|
+
const group = this.get(value);
|
|
39
79
|
|
|
40
80
|
if (group == null) {
|
|
41
81
|
return;
|
|
@@ -47,15 +87,15 @@ export class GroupManager {
|
|
|
47
87
|
|
|
48
88
|
const index = items.indexOf(group);
|
|
49
89
|
|
|
50
|
-
let first = state.managers.data.
|
|
90
|
+
let first = state.managers.data.state.items.original.indexOf(items[index]) + 1;
|
|
51
91
|
|
|
52
92
|
const last =
|
|
53
93
|
items[index + 1] == null
|
|
54
|
-
? state.managers.data.
|
|
55
|
-
: state.managers.data.
|
|
94
|
+
? state.managers.data.state.items.original.length - 1
|
|
95
|
+
: state.managers.data.state.items.original.indexOf(items[index + 1]) - 1;
|
|
56
96
|
|
|
57
97
|
for (; first <= last; first += 1) {
|
|
58
|
-
const key = state.managers.data.
|
|
98
|
+
const key = state.managers.data.state.items.original[first] as Key;
|
|
59
99
|
|
|
60
100
|
if (group.expanded) {
|
|
61
101
|
collapsed.delete(key);
|
|
@@ -64,16 +104,28 @@ export class GroupManager {
|
|
|
64
104
|
}
|
|
65
105
|
}
|
|
66
106
|
|
|
67
|
-
state.managers.
|
|
107
|
+
if (Object.keys(state.managers.filter.items).length > 0) {
|
|
108
|
+
state.managers.filter.filter();
|
|
109
|
+
} else if (state.managers.sort.items.length > 0) {
|
|
110
|
+
state.managers.sort.sort();
|
|
111
|
+
} else {
|
|
112
|
+
state.managers.render.update(true, true);
|
|
113
|
+
}
|
|
68
114
|
}
|
|
69
115
|
|
|
70
116
|
remove(group: GroupComponent): void {
|
|
117
|
+
removeGroup(group);
|
|
118
|
+
|
|
71
119
|
this.set(this.items.filter(item => item !== group));
|
|
72
120
|
}
|
|
73
121
|
|
|
74
122
|
set(items: GroupComponent[]) {
|
|
75
123
|
this.items = sort(items, item => item.label);
|
|
76
124
|
|
|
77
|
-
this.order = toRecord(
|
|
125
|
+
this.order = toRecord(
|
|
126
|
+
items as Simplify<GroupComponent>[],
|
|
127
|
+
group => group.value.stringified,
|
|
128
|
+
(_, index) => index,
|
|
129
|
+
);
|
|
78
130
|
}
|
|
79
131
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
|
|
2
|
-
import type {Key} from '@oscarpalmer/atoms/models';
|
|
3
2
|
import {clamp} from '@oscarpalmer/atoms/number';
|
|
4
|
-
import type {GroupComponent} from '../components/group.component';
|
|
5
3
|
import {getKey} from '../helpers/misc.helpers';
|
|
4
|
+
import type {DataItem} from '../models/data.model';
|
|
6
5
|
import type {State} from '../models/tabela.model';
|
|
6
|
+
import {GroupComponent} from '../components/group.component';
|
|
7
7
|
|
|
8
8
|
export class NavigationManager {
|
|
9
|
-
active:
|
|
9
|
+
active: DataItem | undefined;
|
|
10
10
|
|
|
11
11
|
constructor(public state: State) {}
|
|
12
12
|
|
|
@@ -25,26 +25,26 @@ export class NavigationManager {
|
|
|
25
25
|
|
|
26
26
|
const activeDescendant = components.body.elements.group.getAttribute('aria-activedescendant');
|
|
27
27
|
|
|
28
|
-
const {
|
|
29
|
-
const {length} =
|
|
28
|
+
const {items} = managers.data;
|
|
29
|
+
const {length} = items;
|
|
30
30
|
|
|
31
31
|
let next: number;
|
|
32
32
|
|
|
33
33
|
if (isNullableOrWhitespace(activeDescendant)) {
|
|
34
34
|
next = getDefaultIndex(event.key, length);
|
|
35
35
|
} else {
|
|
36
|
-
next = getIndex(event, activeDescendant, id
|
|
36
|
+
next = getIndex(this.state, event, activeDescendant, id)!;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
if (next != null) {
|
|
40
|
-
this.setActive(
|
|
40
|
+
this.setActive(items.at(next));
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
setActive(
|
|
45
|
-
const {components, managers, options} = this.state;
|
|
44
|
+
setActive(item: DataItem | undefined, scroll?: boolean): void {
|
|
45
|
+
const {components, id, managers, options} = this.state;
|
|
46
46
|
|
|
47
|
-
this.active =
|
|
47
|
+
this.active = item;
|
|
48
48
|
|
|
49
49
|
const active = components.body.elements.group.querySelectorAll('[data-active="true"]');
|
|
50
50
|
|
|
@@ -52,19 +52,19 @@ export class NavigationManager {
|
|
|
52
52
|
item.setAttribute('data-active', 'false');
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const
|
|
55
|
+
const component = item instanceof GroupComponent ? item : managers.row.get(item!, false);
|
|
56
56
|
|
|
57
|
-
if (
|
|
58
|
-
|
|
57
|
+
if (component != null) {
|
|
58
|
+
component.element?.setAttribute('data-active', 'true');
|
|
59
59
|
|
|
60
60
|
if (scroll ?? true) {
|
|
61
|
-
if (
|
|
61
|
+
if (component.element == null) {
|
|
62
62
|
components.body.elements.group.scrollTo({
|
|
63
|
-
top: managers.data.getIndex(
|
|
63
|
+
top: managers.data.getIndex(item!) * options.rowHeight,
|
|
64
64
|
behavior: 'smooth',
|
|
65
65
|
});
|
|
66
66
|
} else {
|
|
67
|
-
|
|
67
|
+
component.element.scrollIntoView({
|
|
68
68
|
block: 'nearest',
|
|
69
69
|
});
|
|
70
70
|
}
|
|
@@ -73,7 +73,7 @@ export class NavigationManager {
|
|
|
73
73
|
|
|
74
74
|
components.body.elements.group.setAttribute(
|
|
75
75
|
'aria-activedescendant',
|
|
76
|
-
|
|
76
|
+
component == null ? '' : `tabela_${id}_${component.key}`,
|
|
77
77
|
);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -95,25 +95,26 @@ function getDefaultIndex(key: string, max: number): number {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
function getIndex(
|
|
98
|
+
state: State,
|
|
98
99
|
event: KeyboardEvent,
|
|
99
100
|
active: string,
|
|
100
101
|
id: number,
|
|
101
|
-
keys: Array<GroupComponent | Key>,
|
|
102
102
|
): number | undefined {
|
|
103
|
-
const key = getKey(active.replace(`tabela_${id}
|
|
103
|
+
const key = getKey(active.replace(`tabela_${id}_`, ''));
|
|
104
104
|
|
|
105
105
|
if (key == null) {
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
if (absoluteKeys.has(event.key)) {
|
|
110
|
-
return event.key === 'Home' ? 0 :
|
|
110
|
+
return event.key === 'Home' ? 0 : state.managers.data.size - 1;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
const index =
|
|
113
|
+
const index = state.managers.data.getIndex(key);
|
|
114
|
+
|
|
114
115
|
const offset = getOffset(event.key);
|
|
115
116
|
|
|
116
|
-
return clamp(index + offset, 0,
|
|
117
|
+
return clamp(index + offset, 0, state.managers.data.size - 1, true);
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
function getOffset(key: string): number {
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import type {Key} from '@oscarpalmer/atoms/models';
|
|
2
1
|
import {on} from '@oscarpalmer/toretto/event';
|
|
3
2
|
import type {RemovableEventListener} from '@oscarpalmer/toretto/models';
|
|
4
3
|
import {GroupComponent, renderGroup} from '../components/group.component';
|
|
5
4
|
import {removeRow, renderRow} from '../components/row.component';
|
|
5
|
+
import type {DataItem} from '../models/data.model';
|
|
6
6
|
import type {RenderElementPool, RenderRange, RenderState} from '../models/render.model';
|
|
7
7
|
import type {State} from '../models/tabela.model';
|
|
8
8
|
|
|
9
9
|
function getRange(state: State, down: boolean): RenderRange {
|
|
10
|
-
const {
|
|
11
|
-
const {clientHeight, scrollTop} =
|
|
10
|
+
const {element, managers, options} = state;
|
|
11
|
+
const {clientHeight, scrollTop} = element;
|
|
12
12
|
|
|
13
|
-
const {
|
|
13
|
+
const {items} = managers.data;
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const firstIndex = Math.floor(scrollTop / options.rowHeight);
|
|
16
|
+
const lastIndex = items.length - managers.group.collapsed.size - 1;
|
|
16
17
|
|
|
17
|
-
const last = Math.min(
|
|
18
|
-
keys.length - managers.group.collapsed.size - 1,
|
|
19
|
-
Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1,
|
|
20
|
-
);
|
|
18
|
+
const last = Math.min(lastIndex, Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1);
|
|
21
19
|
|
|
22
|
-
const
|
|
23
|
-
const after = Math.ceil(clientHeight / options.rowHeight) * (down ? 2 : 1);
|
|
20
|
+
const visible = clientHeight / options.rowHeight;
|
|
24
21
|
|
|
25
|
-
const
|
|
26
|
-
const
|
|
22
|
+
const before = Math.ceil(visible) * (down ? 1 : 2);
|
|
23
|
+
const after = Math.ceil(visible) * (down ? 2 : 1);
|
|
24
|
+
|
|
25
|
+
const start = Math.max(0, firstIndex - before);
|
|
26
|
+
const end = Math.min(lastIndex, last + after);
|
|
27
27
|
|
|
28
28
|
return {end, start};
|
|
29
29
|
}
|
|
@@ -33,7 +33,7 @@ function onScroll(this: RenderManager): void {
|
|
|
33
33
|
|
|
34
34
|
if (!state.active) {
|
|
35
35
|
requestAnimationFrame(() => {
|
|
36
|
-
const top = state.
|
|
36
|
+
const top = state.element.scrollTop;
|
|
37
37
|
|
|
38
38
|
this.update(top > state.top);
|
|
39
39
|
|
|
@@ -57,10 +57,10 @@ export class RenderManager {
|
|
|
57
57
|
|
|
58
58
|
state: RenderState;
|
|
59
59
|
|
|
60
|
-
visible = new Map<number,
|
|
60
|
+
visible = new Map<number, DataItem>();
|
|
61
61
|
|
|
62
62
|
constructor(state: State) {
|
|
63
|
-
this.listener = on(state.
|
|
63
|
+
this.listener = on(state.element, 'scroll', onScroll.bind(this));
|
|
64
64
|
|
|
65
65
|
this.state = {
|
|
66
66
|
...state,
|
|
@@ -75,6 +75,20 @@ export class RenderManager {
|
|
|
75
75
|
listener();
|
|
76
76
|
visible.clear();
|
|
77
77
|
|
|
78
|
+
const cells = Object.values(pool.cells).flat();
|
|
79
|
+
|
|
80
|
+
let {length} = cells;
|
|
81
|
+
|
|
82
|
+
for (let index = 0; index < length; index += 1) {
|
|
83
|
+
cells[index].remove();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
length = pool.rows.length;
|
|
87
|
+
|
|
88
|
+
for (let index = 0; index < length; index += 1) {
|
|
89
|
+
pool.rows[index].remove();
|
|
90
|
+
}
|
|
91
|
+
|
|
78
92
|
pool.cells = {};
|
|
79
93
|
pool.rows = [];
|
|
80
94
|
|
|
@@ -98,7 +112,7 @@ export class RenderManager {
|
|
|
98
112
|
continue;
|
|
99
113
|
}
|
|
100
114
|
|
|
101
|
-
const row = state.managers.row.get(key);
|
|
115
|
+
const row = state.managers.row.get(key, false);
|
|
102
116
|
|
|
103
117
|
if (row == null || row.element == null) {
|
|
104
118
|
continue;
|
|
@@ -149,7 +163,7 @@ export class RenderManager {
|
|
|
149
163
|
continue;
|
|
150
164
|
}
|
|
151
165
|
|
|
152
|
-
const row = managers.row.get(key);
|
|
166
|
+
const row = managers.row.get(key, false);
|
|
153
167
|
|
|
154
168
|
if (remove || row == null || !indices.has(index) || managers.group.collapsed.has(key)) {
|
|
155
169
|
visible.delete(index);
|
|
@@ -162,7 +176,7 @@ export class RenderManager {
|
|
|
162
176
|
|
|
163
177
|
const fragment = this.getFragment();
|
|
164
178
|
|
|
165
|
-
const {
|
|
179
|
+
const {items} = managers.data;
|
|
166
180
|
|
|
167
181
|
let count = 0;
|
|
168
182
|
let offset = 0;
|
|
@@ -172,31 +186,31 @@ export class RenderManager {
|
|
|
172
186
|
continue;
|
|
173
187
|
}
|
|
174
188
|
|
|
175
|
-
const
|
|
189
|
+
const item = items[index];
|
|
176
190
|
|
|
177
|
-
if (
|
|
191
|
+
if (item instanceof GroupComponent) {
|
|
178
192
|
count += 1;
|
|
179
193
|
|
|
180
|
-
renderGroup(state,
|
|
194
|
+
renderGroup(state, item);
|
|
181
195
|
|
|
182
|
-
visible.set(index,
|
|
196
|
+
visible.set(index, item);
|
|
183
197
|
|
|
184
|
-
if (
|
|
185
|
-
|
|
198
|
+
if (item.element != null) {
|
|
199
|
+
item.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
|
|
186
200
|
|
|
187
|
-
fragment.append(
|
|
201
|
+
fragment.append(item.element);
|
|
188
202
|
}
|
|
189
203
|
|
|
190
204
|
continue;
|
|
191
205
|
}
|
|
192
206
|
|
|
193
|
-
const row = managers.row.get(
|
|
207
|
+
const row = managers.row.get(item, true);
|
|
194
208
|
|
|
195
209
|
if (row == null) {
|
|
196
210
|
continue;
|
|
197
211
|
}
|
|
198
212
|
|
|
199
|
-
if (managers.group.collapsed.has(
|
|
213
|
+
if (managers.group.collapsed.has(item)) {
|
|
200
214
|
offset += 1;
|
|
201
215
|
|
|
202
216
|
continue;
|
|
@@ -206,7 +220,7 @@ export class RenderManager {
|
|
|
206
220
|
|
|
207
221
|
renderRow(state, row);
|
|
208
222
|
|
|
209
|
-
visible.set(index,
|
|
223
|
+
visible.set(index, item);
|
|
210
224
|
|
|
211
225
|
if (row.element != null) {
|
|
212
226
|
row.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
|
|
@@ -7,24 +7,30 @@ export class RowManager {
|
|
|
7
7
|
|
|
8
8
|
constructor(public state: State) {}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
const components =
|
|
12
|
-
|
|
10
|
+
clear(): void {
|
|
11
|
+
const {components} = this;
|
|
12
|
+
|
|
13
|
+
const rows = [...components.values()];
|
|
14
|
+
const {length} = rows;
|
|
13
15
|
|
|
14
16
|
for (let index = 0; index < length; index += 1) {
|
|
15
|
-
removeRow(
|
|
17
|
+
this.removeRow(rows[index]);
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
components.clear();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
destroy(): void {
|
|
24
|
+
this.clear();
|
|
19
25
|
|
|
20
26
|
this.components = undefined as never;
|
|
21
27
|
this.state = undefined as never;
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
get(key: Key): RowComponent | undefined {
|
|
30
|
+
get(key: Key, create: boolean): RowComponent | undefined {
|
|
25
31
|
let row = this.components.get(key);
|
|
26
32
|
|
|
27
|
-
if (row == null) {
|
|
33
|
+
if (row == null && create) {
|
|
28
34
|
row = new RowComponent(key);
|
|
29
35
|
|
|
30
36
|
this.components.set(key, row);
|
|
@@ -41,10 +47,16 @@ export class RowManager {
|
|
|
41
47
|
const row = this.components.get(key);
|
|
42
48
|
|
|
43
49
|
if (row != null) {
|
|
44
|
-
removeRow(
|
|
50
|
+
this.removeRow(row);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
45
53
|
|
|
46
|
-
|
|
54
|
+
removeRow(row: RowComponent): void {
|
|
55
|
+
if (row.element != null) {
|
|
56
|
+
removeRow(this.state.managers.render.pool, row);
|
|
47
57
|
}
|
|
58
|
+
|
|
59
|
+
this.components.delete(row.key);
|
|
48
60
|
}
|
|
49
61
|
|
|
50
62
|
update(key: Key): void {
|
|
@@ -4,12 +4,17 @@ 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';
|
|
7
8
|
import {createElement} from '../helpers/dom.helpers';
|
|
8
9
|
import {getKey} from '../helpers/misc.helpers';
|
|
9
|
-
import {
|
|
10
|
+
import {preventSelection} from '../helpers/style.helper';
|
|
10
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';
|
|
11
17
|
import type {State} from '../models/tabela.model';
|
|
12
|
-
import {GroupComponent} from '../components/group.component';
|
|
13
18
|
|
|
14
19
|
export class SelectionManager {
|
|
15
20
|
handlers = Object.freeze({
|
|
@@ -117,7 +122,7 @@ export class SelectionManager {
|
|
|
117
122
|
return;
|
|
118
123
|
}
|
|
119
124
|
|
|
120
|
-
const {
|
|
125
|
+
const {items} = state.managers.data;
|
|
121
126
|
|
|
122
127
|
const fromIndex = state.managers.data.getIndex(fromKey);
|
|
123
128
|
const toIndex = state.managers.data.getIndex(toKey);
|
|
@@ -131,10 +136,10 @@ export class SelectionManager {
|
|
|
131
136
|
const selected: Key[] = [];
|
|
132
137
|
|
|
133
138
|
for (let index = start; index <= end; index += 1) {
|
|
134
|
-
const
|
|
139
|
+
const item = items[index];
|
|
135
140
|
|
|
136
|
-
if (!(
|
|
137
|
-
selected.push(
|
|
141
|
+
if (!(item instanceof GroupComponent)) {
|
|
142
|
+
selected.push(item as Key);
|
|
138
143
|
}
|
|
139
144
|
}
|
|
140
145
|
|
|
@@ -184,38 +189,40 @@ export class SelectionManager {
|
|
|
184
189
|
|
|
185
190
|
toggle(): void {
|
|
186
191
|
const {items, state} = this;
|
|
187
|
-
const
|
|
192
|
+
const data = state.managers.data.items;
|
|
188
193
|
|
|
189
|
-
if (items.size ===
|
|
194
|
+
if (items.size === data.length - state.managers.group.items.length) {
|
|
190
195
|
this.clear();
|
|
191
196
|
} else {
|
|
192
|
-
this.set(
|
|
197
|
+
this.set(data.filter(key => !(key instanceof GroupComponent)) as Key[]);
|
|
193
198
|
}
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
update(removed: Key[]): void {
|
|
202
|
+
const {state} = this;
|
|
203
|
+
|
|
197
204
|
const items = [
|
|
198
205
|
...removed.map(key => ({key, removed: true})),
|
|
199
206
|
...[...this.items].map(key => ({key, removed: false})),
|
|
200
207
|
];
|
|
201
208
|
|
|
202
|
-
|
|
209
|
+
let {length} = items;
|
|
203
210
|
|
|
204
211
|
for (let index = 0; index < length; index += 1) {
|
|
205
212
|
const {key, removed} = items[index];
|
|
206
213
|
|
|
207
|
-
const
|
|
214
|
+
const element = state.managers.row.get(key, false)?.element;
|
|
208
215
|
|
|
209
|
-
if (
|
|
216
|
+
if (element == null) {
|
|
210
217
|
continue;
|
|
211
218
|
}
|
|
212
219
|
|
|
213
|
-
setAttribute(
|
|
220
|
+
setAttribute(element, 'aria-selected', String(!removed));
|
|
214
221
|
|
|
215
222
|
if (removed) {
|
|
216
|
-
|
|
223
|
+
element.classList.remove(CSS_TABELA_ROW_SELECTED);
|
|
217
224
|
} else {
|
|
218
|
-
|
|
225
|
+
element.classList.add(CSS_TABELA_ROW_SELECTED);
|
|
219
226
|
}
|
|
220
227
|
}
|
|
221
228
|
}
|
|
@@ -225,7 +232,7 @@ function getPlaceholder(): HTMLElement {
|
|
|
225
232
|
placeholder ??= createElement(
|
|
226
233
|
'div',
|
|
227
234
|
{
|
|
228
|
-
className:
|
|
235
|
+
className: CSS_TABELA_SELECTION,
|
|
229
236
|
},
|
|
230
237
|
{},
|
|
231
238
|
{},
|
|
@@ -236,7 +243,7 @@ function getPlaceholder(): HTMLElement {
|
|
|
236
243
|
|
|
237
244
|
function onMouseDown(event: MouseEvent): void {
|
|
238
245
|
if (shifted) {
|
|
239
|
-
const row = findAncestor(event.target as HTMLElement,
|
|
246
|
+
const row = findAncestor(event.target as HTMLElement, `.${CSS_TABELA_ROW_BODY}`);
|
|
240
247
|
|
|
241
248
|
if (!(row instanceof HTMLElement)) {
|
|
242
249
|
return;
|
|
@@ -245,7 +252,7 @@ function onMouseDown(event: MouseEvent): void {
|
|
|
245
252
|
startElement = row;
|
|
246
253
|
startPosition = getPosition(event)!;
|
|
247
254
|
|
|
248
|
-
|
|
255
|
+
preventSelection.set();
|
|
249
256
|
}
|
|
250
257
|
}
|
|
251
258
|
|
|
@@ -286,7 +293,7 @@ function onMouseUp(event: MouseEvent): void {
|
|
|
286
293
|
if (!event.shiftKey) {
|
|
287
294
|
shifted = false;
|
|
288
295
|
|
|
289
|
-
|
|
296
|
+
preventSelection.remove();
|
|
290
297
|
}
|
|
291
298
|
|
|
292
299
|
getPlaceholder().remove();
|
|
@@ -296,8 +303,8 @@ function onMouseUp(event: MouseEvent): void {
|
|
|
296
303
|
if (row instanceof HTMLElement) {
|
|
297
304
|
endElement = row;
|
|
298
305
|
|
|
299
|
-
const endTable = findAncestor(endElement, '.
|
|
300
|
-
const startTable = findAncestor(startElement, '.
|
|
306
|
+
const endTable = findAncestor(endElement, '.tabela__table');
|
|
307
|
+
const startTable = findAncestor(startElement, '.tabela__table');
|
|
301
308
|
|
|
302
309
|
if (startTable != null && startTable === endTable) {
|
|
303
310
|
mapped.get(startTable)?.range(startElement, endElement);
|