@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.
- package/dist/components/body.component.d.mts +10 -1
- package/dist/components/body.component.mjs +8 -6
- package/dist/components/column.component.d.mts +15 -1
- package/dist/components/column.component.mjs +12 -10
- package/dist/components/footer.component.d.mts +12 -1
- package/dist/components/footer.component.mjs +6 -6
- package/dist/components/group.component.d.mts +19 -1
- package/dist/components/group.component.mjs +17 -11
- package/dist/components/header.component.d.mts +12 -1
- package/dist/components/header.component.mjs +5 -5
- package/dist/components/row.component.d.mts +14 -1
- package/dist/components/row.component.mjs +21 -17
- package/dist/helpers/dom.helpers.d.mts +3 -3
- package/dist/helpers/dom.helpers.mjs +12 -11
- package/dist/helpers/misc.helpers.d.mts +7 -1
- package/dist/helpers/misc.helpers.mjs +12 -1
- package/dist/index.d.mts +1 -1
- package/dist/managers/column.manager.d.mts +16 -1
- package/dist/managers/column.manager.mjs +7 -7
- package/dist/managers/data.manager.d.mts +26 -1
- package/dist/managers/data.manager.mjs +122 -88
- package/dist/managers/event.manager.d.mts +17 -1
- package/dist/managers/event.manager.mjs +35 -10
- package/dist/managers/filter.manager.d.mts +17 -1
- package/dist/managers/filter.manager.mjs +43 -35
- package/dist/managers/group.manager.d.mts +26 -1
- package/dist/managers/group.manager.mjs +36 -16
- package/dist/managers/navigation.manager.d.mts +15 -2
- package/dist/managers/navigation.manager.mjs +38 -34
- package/dist/managers/render.manager.d.mts +18 -1
- package/dist/managers/render.manager.mjs +44 -31
- package/dist/managers/row.manager.d.mts +18 -1
- package/dist/managers/row.manager.mjs +1 -1
- package/dist/managers/selection.manager.d.mts +22 -1
- package/dist/managers/selection.manager.mjs +26 -23
- package/dist/managers/sort.manager.d.mts +22 -1
- package/dist/managers/sort.manager.mjs +71 -49
- package/dist/managers/style.manager.d.mts +8 -1
- package/dist/managers/style.manager.mjs +57 -25
- package/dist/models/body.model.d.mts +6 -1
- package/dist/models/column.model.d.mts +13 -2
- package/dist/models/data.model.d.mts +28 -2
- package/dist/models/dom.model.d.mts +19 -0
- package/dist/models/dom.model.mjs +19 -0
- package/dist/models/event.model.d.mts +99 -0
- package/dist/models/event.model.mjs +53 -0
- package/dist/models/filter.model.d.mts +26 -2
- package/dist/models/filter.model.mjs +13 -1
- package/dist/models/footer.model.d.mts +7 -1
- package/dist/models/group.model.d.mts +19 -2
- package/dist/models/group.model.mjs +5 -1
- package/dist/models/header.model.d.mts +6 -1
- package/dist/models/render.model.d.mts +22 -2
- package/dist/models/selection.model.d.mts +11 -1
- package/dist/models/sort.model.d.mts +19 -2
- package/dist/models/sort.model.mjs +5 -1
- package/dist/models/style.model.d.mts +27 -21
- package/dist/models/style.model.mjs +27 -21
- package/dist/models/tabela.model.d.mts +45 -1
- package/dist/models/tabela.options.d.mts +13 -1
- package/dist/tabela.d.mts +9 -8
- package/dist/tabela.full.mjs +1083 -574
- package/dist/tabela.mjs +19 -19
- package/package.json +2 -4
- package/src/components/body.component.ts +10 -7
- package/src/components/column.component.ts +20 -16
- package/src/components/footer.component.ts +7 -10
- package/src/components/group.component.ts +39 -13
- package/src/components/header.component.ts +6 -5
- package/src/components/row.component.ts +27 -19
- package/src/helpers/dom.helpers.ts +18 -22
- package/src/helpers/misc.helpers.ts +17 -0
- package/src/managers/column.manager.ts +9 -9
- package/src/managers/data.manager.ts +196 -107
- package/src/managers/event.manager.ts +69 -12
- package/src/managers/filter.manager.ts +70 -41
- package/src/managers/group.manager.ts +60 -18
- package/src/managers/navigation.manager.ts +46 -49
- package/src/managers/render.manager.ts +60 -34
- package/src/managers/row.manager.ts +1 -1
- package/src/managers/selection.manager.ts +37 -35
- package/src/managers/sort.manager.ts +114 -72
- package/src/managers/style.manager.ts +73 -25
- package/src/models/column.model.ts +4 -8
- package/src/models/data.model.ts +13 -14
- package/src/models/dom.model.ts +31 -0
- package/src/models/event.model.ts +175 -0
- package/src/models/filter.model.ts +22 -2
- package/src/models/group.model.ts +13 -0
- package/src/models/render.model.ts +6 -0
- package/src/models/sort.model.ts +11 -5
- package/src/models/style.model.ts +32 -20
- package/src/models/tabela.model.ts +1 -0
- package/src/tabela.ts +26 -24
- package/dist/body.component-_VDOpJhV.d.mts +0 -10
- package/dist/body.model-2iwsovAV.d.mts +0 -7
- package/dist/column.component-Bx46r3JI.d.mts +0 -16
- package/dist/column.model-D-aw4EU4.d.mts +0 -16
- package/dist/filter.model-7ukJrtil.d.mts +0 -16
- package/dist/footer.component-Curiab8j.d.mts +0 -12
- package/dist/footer.model-DhqoS6ds.d.mts +0 -8
- package/dist/group.component-Cq1YYbfJ.d.mts +0 -285
- package/dist/group.model-BsKFwHbt.d.mts +0 -10
- package/dist/header.component-BjjlpZIg.d.mts +0 -12
- package/dist/header.model-DN_KzUCV.d.mts +0 -7
- package/dist/selection.model-rwQe9fco.d.mts +0 -12
- package/dist/sort.model-CauImaLu.d.mts +0 -15
- package/dist/tabela.options-RkZvfptB.d.mts +0 -14
package/dist/tabela.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ARIA_LABEL, ATTRIBUTE_ROLE, ROLE_TABLE } from "./models/dom.model.mjs";
|
|
2
|
+
import { CSS_TABLE, CSS_WRAPPER } from "./models/style.model.mjs";
|
|
2
3
|
import { createElement } from "./helpers/dom.helpers.mjs";
|
|
3
4
|
import { BodyComponent } from "./components/body.component.mjs";
|
|
4
5
|
import { FooterComponent } from "./components/footer.component.mjs";
|
|
@@ -19,7 +20,6 @@ var Tabela = class {
|
|
|
19
20
|
#components;
|
|
20
21
|
#element;
|
|
21
22
|
#id = getId();
|
|
22
|
-
#table;
|
|
23
23
|
#key;
|
|
24
24
|
#managers = {
|
|
25
25
|
column: void 0,
|
|
@@ -34,37 +34,37 @@ var Tabela = class {
|
|
|
34
34
|
sort: void 0,
|
|
35
35
|
style: void 0
|
|
36
36
|
};
|
|
37
|
+
#prefix = `tabela_${this.#id}_`;
|
|
37
38
|
#state;
|
|
39
|
+
#table;
|
|
38
40
|
data;
|
|
41
|
+
events;
|
|
39
42
|
filter;
|
|
40
43
|
group;
|
|
41
44
|
selection;
|
|
42
45
|
sort;
|
|
43
|
-
get key() {
|
|
44
|
-
return this.#key;
|
|
45
|
-
}
|
|
46
46
|
constructor(element, options) {
|
|
47
47
|
this.#element = element;
|
|
48
48
|
element.innerHTML = "";
|
|
49
|
-
element.classList.add(
|
|
49
|
+
element.classList.add(CSS_WRAPPER);
|
|
50
50
|
this.#table = createElement("div", {
|
|
51
|
-
className:
|
|
52
|
-
role:
|
|
53
|
-
}, {
|
|
51
|
+
className: CSS_TABLE,
|
|
52
|
+
role: ROLE_TABLE
|
|
53
|
+
}, { [ARIA_LABEL]: options.label });
|
|
54
54
|
this.#key = options.key;
|
|
55
|
-
this.#components = {
|
|
56
|
-
body: new BodyComponent(),
|
|
57
|
-
footer: new FooterComponent(),
|
|
58
|
-
header: new HeaderComponent()
|
|
59
|
-
};
|
|
55
|
+
this.#components = {};
|
|
60
56
|
this.#state = {
|
|
61
57
|
options,
|
|
62
58
|
components: this.#components,
|
|
63
59
|
element: this.#table,
|
|
64
60
|
id: this.#id,
|
|
65
61
|
key: this.#key,
|
|
66
|
-
managers: this.#managers
|
|
62
|
+
managers: this.#managers,
|
|
63
|
+
prefix: this.#prefix
|
|
67
64
|
};
|
|
65
|
+
this.#components.body = new BodyComponent(this.#state);
|
|
66
|
+
this.#components.footer = new FooterComponent(this.#state);
|
|
67
|
+
this.#components.header = new HeaderComponent(this.#state);
|
|
68
68
|
this.#managers.column = new ColumnManager(this.#state);
|
|
69
69
|
this.#managers.data = new DataManager(this.#state);
|
|
70
70
|
this.#managers.event = new EventManager(this.#state);
|
|
@@ -80,6 +80,7 @@ var Tabela = class {
|
|
|
80
80
|
element.append(this.#table);
|
|
81
81
|
this.#managers.data.set(options.data);
|
|
82
82
|
this.data = this.#managers.data.handlers;
|
|
83
|
+
this.events = this.#managers.event.handlers;
|
|
83
84
|
this.filter = this.#managers.filter.handlers;
|
|
84
85
|
this.group = this.#managers.group.handlers;
|
|
85
86
|
this.selection = this.#managers.selection.handlers;
|
|
@@ -105,10 +106,9 @@ var Tabela = class {
|
|
|
105
106
|
managers.sort.destroy();
|
|
106
107
|
element.innerHTML = "";
|
|
107
108
|
table.innerHTML = "";
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
table.removeAttribute(
|
|
111
|
-
table.removeAttribute("role");
|
|
109
|
+
element.classList.remove(CSS_WRAPPER);
|
|
110
|
+
table.removeAttribute(ARIA_LABEL);
|
|
111
|
+
table.removeAttribute(ATTRIBUTE_ROLE);
|
|
112
112
|
this.#state.components = void 0;
|
|
113
113
|
this.#state.managers = void 0;
|
|
114
114
|
this.#state.element = void 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oscarpalmer/tabela",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "A modern table.",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,12 +37,10 @@
|
|
|
37
37
|
"www:js": "vpx tsdown -c ./www/.app/js/tsdown.config.ts --watch"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@oscarpalmer/atoms": "^0.
|
|
40
|
+
"@oscarpalmer/atoms": "^0.166",
|
|
41
41
|
"@oscarpalmer/toretto": "^0.41"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@oscarpalmer/abydon": "^0.19",
|
|
45
|
-
"@oscarpalmer/oui": "^0.19",
|
|
46
44
|
"@types/node": "^25.5",
|
|
47
45
|
"@vitest/coverage-istanbul": "^4.1",
|
|
48
46
|
"concurrently": "^9.2",
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {createElement, createRowGroup} from '../helpers/dom.helpers';
|
|
2
2
|
import type {BodyElements} from '../models/body.model';
|
|
3
|
-
import {
|
|
3
|
+
import {ATTRIBUTE_DATA_EVENT, ELEMENT_DIV} from '../models/dom.model';
|
|
4
|
+
import {EVENT_BODY} from '../models/event.model';
|
|
5
|
+
import {CSS_FAKER, CSS_ROWGROUP_BODY} from '../models/style.model';
|
|
6
|
+
import type {State} from '../models/tabela.model';
|
|
4
7
|
|
|
5
8
|
function createFaker(): HTMLDivElement {
|
|
6
|
-
return createElement(
|
|
7
|
-
className:
|
|
9
|
+
return createElement(ELEMENT_DIV, {
|
|
10
|
+
className: CSS_FAKER,
|
|
8
11
|
});
|
|
9
12
|
}
|
|
10
13
|
|
|
@@ -14,16 +17,16 @@ export class BodyComponent {
|
|
|
14
17
|
group: undefined as never,
|
|
15
18
|
};
|
|
16
19
|
|
|
17
|
-
constructor() {
|
|
18
|
-
const group = createRowGroup(false);
|
|
20
|
+
constructor(state: State) {
|
|
21
|
+
const group = createRowGroup(state.options.rowHeight, false);
|
|
19
22
|
|
|
20
23
|
this.elements.group = group;
|
|
21
24
|
|
|
22
|
-
group.className += ` ${
|
|
25
|
+
group.className += ` ${CSS_ROWGROUP_BODY}`;
|
|
23
26
|
|
|
24
27
|
group.tabIndex = 0;
|
|
25
28
|
|
|
26
|
-
group.setAttribute(
|
|
29
|
+
group.setAttribute(ATTRIBUTE_DATA_EVENT, EVENT_BODY);
|
|
27
30
|
|
|
28
31
|
group.append(this.elements.faker);
|
|
29
32
|
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {createElement} from '../helpers/dom.helpers';
|
|
2
2
|
import type {Column, TabelaColumn} from '../models/column.model';
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
ATTRIBUTE_DATA_EVENT,
|
|
5
|
+
ATTRIBUTE_DATA_KEY,
|
|
6
|
+
ATTRIBUTE_ROLE,
|
|
7
|
+
ELEMENT_DIV,
|
|
8
|
+
ROLE_COLUMNHEADER,
|
|
9
|
+
} from '../models/dom.model';
|
|
10
|
+
import {EVENT_HEADING} from '../models/event.model';
|
|
11
|
+
import {CSS_HEADING, CSS_HEADING_CONTENT, CSS_HEADING_SORTER} from '../models/style.model';
|
|
8
12
|
|
|
9
13
|
export class ColumnComponent {
|
|
10
14
|
elements: ColumnElements;
|
|
@@ -13,14 +17,14 @@ export class ColumnComponent {
|
|
|
13
17
|
constructor(column: TabelaColumn) {
|
|
14
18
|
const width =
|
|
15
19
|
Number.parseInt(getComputedStyle(document.body).fontSize, 10) *
|
|
16
|
-
(column.width ?? column.
|
|
20
|
+
(column.width ?? column.label.length * 1.5);
|
|
17
21
|
|
|
18
22
|
this.options = {
|
|
19
23
|
...column,
|
|
20
24
|
width,
|
|
21
25
|
};
|
|
22
26
|
|
|
23
|
-
this.elements = createHeading(this.options.
|
|
27
|
+
this.elements = createHeading(this.options.key, this.options.label, width);
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
destroy(): void {
|
|
@@ -39,29 +43,29 @@ type ColumnElements = {
|
|
|
39
43
|
wrapper: HTMLDivElement;
|
|
40
44
|
};
|
|
41
45
|
|
|
42
|
-
function createHeading(
|
|
46
|
+
function createHeading(key: string, title: string, width: number): ColumnElements {
|
|
43
47
|
const wrapper = createElement(
|
|
44
|
-
|
|
48
|
+
ELEMENT_DIV,
|
|
45
49
|
{
|
|
46
|
-
className:
|
|
47
|
-
|
|
50
|
+
className: CSS_HEADING,
|
|
51
|
+
[ATTRIBUTE_ROLE]: ROLE_COLUMNHEADER,
|
|
48
52
|
},
|
|
49
53
|
{
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
[ATTRIBUTE_DATA_EVENT]: EVENT_HEADING,
|
|
55
|
+
[ATTRIBUTE_DATA_KEY]: key,
|
|
52
56
|
},
|
|
53
57
|
{
|
|
54
58
|
width: `${width}px`,
|
|
55
59
|
},
|
|
56
60
|
);
|
|
57
61
|
|
|
58
|
-
const content = createElement(
|
|
59
|
-
className:
|
|
62
|
+
const content = createElement(ELEMENT_DIV, {
|
|
63
|
+
className: CSS_HEADING_CONTENT,
|
|
60
64
|
textContent: title,
|
|
61
65
|
});
|
|
62
66
|
|
|
63
|
-
const sorter = createElement(
|
|
64
|
-
className:
|
|
67
|
+
const sorter = createElement(ELEMENT_DIV, {
|
|
68
|
+
className: CSS_HEADING_SORTER,
|
|
65
69
|
});
|
|
66
70
|
|
|
67
71
|
wrapper.append(content, sorter);
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import {createCell, createRowGroup} from '../helpers/dom.helpers';
|
|
2
2
|
import type {FooterElements} from '../models/footer.model';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
CSS_TABELA_ROW_FOOTER,
|
|
6
|
-
CSS_TABELA_ROWGROUP_FOOTER,
|
|
7
|
-
} from '../models/style.model';
|
|
3
|
+
import {CSS_CELL_FOOTER, CSS_ROW_FOOTER, CSS_ROWGROUP_FOOTER} from '../models/style.model';
|
|
4
|
+
import type {State} from '../models/tabela.model';
|
|
8
5
|
import type {ColumnComponent} from './column.component';
|
|
9
6
|
|
|
10
7
|
export class FooterComponent {
|
|
11
8
|
readonly elements: FooterElements;
|
|
12
9
|
|
|
13
|
-
constructor() {
|
|
14
|
-
const {group, row} = createRowGroup();
|
|
10
|
+
constructor(state: State) {
|
|
11
|
+
const {group, row} = createRowGroup(state.options.rowHeight);
|
|
15
12
|
|
|
16
13
|
this.elements = {
|
|
17
14
|
group,
|
|
@@ -19,8 +16,8 @@ export class FooterComponent {
|
|
|
19
16
|
cells: [],
|
|
20
17
|
};
|
|
21
18
|
|
|
22
|
-
group.className += ` ${
|
|
23
|
-
row.className += ` ${
|
|
19
|
+
group.className += ` ${CSS_ROWGROUP_FOOTER}`;
|
|
20
|
+
row.className += ` ${CSS_ROW_FOOTER}`;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
destroy(): void {
|
|
@@ -40,7 +37,7 @@ export class FooterComponent {
|
|
|
40
37
|
for (let index = 0; index < length; index += 1) {
|
|
41
38
|
const cell = createCell(columns[index].options.width ?? 4, false);
|
|
42
39
|
|
|
43
|
-
cell.className += ` ${
|
|
40
|
+
cell.className += ` ${CSS_CELL_FOOTER}`;
|
|
44
41
|
cell.innerHTML = ' ';
|
|
45
42
|
|
|
46
43
|
elements.cells.push(cell);
|
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
import {getString} from '@oscarpalmer/atoms/string';
|
|
2
2
|
import {createElement} from '../helpers/dom.helpers';
|
|
3
|
-
import type
|
|
4
|
-
import {
|
|
3
|
+
import {GROUP_KEY_PREFIX, type GroupValue} from '../models/group.model';
|
|
4
|
+
import {
|
|
5
|
+
CSS_BUTTON,
|
|
6
|
+
CSS_BUTTON_GROUP,
|
|
7
|
+
CSS_CELL,
|
|
8
|
+
CSS_CELL_GROUP,
|
|
9
|
+
CSS_GROUP_SELECTED,
|
|
10
|
+
CSS_GROUP_TOTAL,
|
|
11
|
+
CSS_ROW,
|
|
12
|
+
CSS_ROW_GROUP,
|
|
13
|
+
} from '../models/style.model';
|
|
5
14
|
import type {State} from '../models/tabela.model';
|
|
15
|
+
import {
|
|
16
|
+
ATTRIBUTE_DATA_EVENT,
|
|
17
|
+
ATTRIBUTE_DATA_KEY,
|
|
18
|
+
ATTRIBUTE_ROLE,
|
|
19
|
+
ELEMENT_DIV,
|
|
20
|
+
ROLE_CELL,
|
|
21
|
+
ROLE_ROW,
|
|
22
|
+
} from '../models/dom.model';
|
|
23
|
+
import {EVENT_GROUP, EVENT_GROUP_UPDATE} from '../models/event.model';
|
|
6
24
|
|
|
7
25
|
export class GroupComponent {
|
|
8
26
|
element: HTMLElement | undefined;
|
|
@@ -25,7 +43,7 @@ export class GroupComponent {
|
|
|
25
43
|
) {
|
|
26
44
|
const stringified = getString(value);
|
|
27
45
|
|
|
28
|
-
this.key =
|
|
46
|
+
this.key = `${GROUP_KEY_PREFIX}${stringified}`;
|
|
29
47
|
|
|
30
48
|
this.value = {
|
|
31
49
|
stringified,
|
|
@@ -46,19 +64,19 @@ export function removeGroup(group: GroupComponent): void {
|
|
|
46
64
|
|
|
47
65
|
export function renderGroup(state: State, component: GroupComponent): void {
|
|
48
66
|
component.element ??= createElement(
|
|
49
|
-
|
|
67
|
+
ELEMENT_DIV,
|
|
50
68
|
{
|
|
51
|
-
className: `${
|
|
52
|
-
innerHTML: `<div class="
|
|
53
|
-
<button class="
|
|
69
|
+
className: `${CSS_ROW} ${CSS_ROW_GROUP}`,
|
|
70
|
+
innerHTML: `<div class="${CSS_CELL} ${CSS_CELL_GROUP}" role="${ROLE_CELL}">
|
|
71
|
+
<button class="${CSS_BUTTON} ${CSS_BUTTON_GROUP}" ${ATTRIBUTE_DATA_EVENT}="${EVENT_GROUP}" ${ATTRIBUTE_DATA_KEY}="${state.prefix}_${component.key}" type="button">
|
|
54
72
|
<span aria-hidden="true"></span>
|
|
55
73
|
<span>Open/close</span>
|
|
56
74
|
</button>
|
|
57
75
|
<p>${component.label}</p>
|
|
58
|
-
<span class="
|
|
59
|
-
<span class="
|
|
76
|
+
<span class="${CSS_GROUP_TOTAL}">${component.total}</span>
|
|
77
|
+
<span class="${CSS_GROUP_SELECTED}">${component.selected === 0 ? '' : component.selected}</span>
|
|
60
78
|
</div>`,
|
|
61
|
-
|
|
79
|
+
[ATTRIBUTE_ROLE]: ROLE_ROW,
|
|
62
80
|
},
|
|
63
81
|
{},
|
|
64
82
|
{
|
|
@@ -67,13 +85,13 @@ export function renderGroup(state: State, component: GroupComponent): void {
|
|
|
67
85
|
);
|
|
68
86
|
}
|
|
69
87
|
|
|
70
|
-
export function updateGroup(state: State, component: GroupComponent): void {
|
|
88
|
+
export function updateGroup(state: State, component: GroupComponent, emit: boolean): void {
|
|
71
89
|
if (component.element == null) {
|
|
72
90
|
return;
|
|
73
91
|
}
|
|
74
92
|
|
|
75
|
-
const selected = component.element.querySelector<HTMLSpanElement>(
|
|
76
|
-
const total = component.element.querySelector<HTMLSpanElement>(
|
|
93
|
+
const selected = component.element.querySelector<HTMLSpanElement>(selectedSelector);
|
|
94
|
+
const total = component.element.querySelector<HTMLSpanElement>(totalSelector);
|
|
77
95
|
|
|
78
96
|
if (selected != null) {
|
|
79
97
|
selected.textContent = component.selected === 0 ? '' : String(component.selected);
|
|
@@ -82,4 +100,12 @@ export function updateGroup(state: State, component: GroupComponent): void {
|
|
|
82
100
|
if (total != null) {
|
|
83
101
|
total.textContent = String(component.total);
|
|
84
102
|
}
|
|
103
|
+
|
|
104
|
+
if (emit) {
|
|
105
|
+
state.managers.event.emit(EVENT_GROUP_UPDATE, [component]);
|
|
106
|
+
}
|
|
85
107
|
}
|
|
108
|
+
|
|
109
|
+
const selectedSelector = `.${CSS_GROUP_SELECTED}`;
|
|
110
|
+
|
|
111
|
+
const totalSelector = `.${CSS_GROUP_TOTAL}`;
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import {createRowGroup} from '../helpers/dom.helpers';
|
|
2
2
|
import type {HeaderElements} from '../models/header.model';
|
|
3
|
-
import {
|
|
3
|
+
import {CSS_ROW_HEADER, CSS_ROWGROUP_HEADER} from '../models/style.model';
|
|
4
|
+
import type {State} from '../models/tabela.model';
|
|
4
5
|
import type {ColumnComponent} from './column.component';
|
|
5
6
|
|
|
6
7
|
export class HeaderComponent {
|
|
7
8
|
readonly elements: HeaderElements;
|
|
8
9
|
|
|
9
|
-
constructor() {
|
|
10
|
-
const {group, row} = createRowGroup();
|
|
10
|
+
constructor(state: State) {
|
|
11
|
+
const {group, row} = createRowGroup(state.options.rowHeight);
|
|
11
12
|
|
|
12
13
|
this.elements = {group, row};
|
|
13
14
|
|
|
14
|
-
group.className += ` ${
|
|
15
|
-
row.className += ` ${
|
|
15
|
+
group.className += ` ${CSS_ROWGROUP_HEADER}`;
|
|
16
|
+
row.className += ` ${CSS_ROW_HEADER}`;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
destroy(): void {
|
|
@@ -3,8 +3,15 @@ import {getValue} from '@oscarpalmer/atoms/value/handle';
|
|
|
3
3
|
import {setAttributes} from '@oscarpalmer/toretto/attribute';
|
|
4
4
|
import {createCell, createRow} from '../helpers/dom.helpers';
|
|
5
5
|
import type {RenderElementPool} from '../models/render.model';
|
|
6
|
-
import {
|
|
6
|
+
import {CSS_ROW_BODY, CSS_ROW_SELECTED} from '../models/style.model';
|
|
7
7
|
import type {State} from '../models/tabela.model';
|
|
8
|
+
import {
|
|
9
|
+
ARIA_SELECTED,
|
|
10
|
+
ATTRIBUTE_DATA_ACTIVE,
|
|
11
|
+
ATTRIBUTE_DATA_EVENT,
|
|
12
|
+
ATTRIBUTE_DATA_KEY,
|
|
13
|
+
} from '../models/dom.model';
|
|
14
|
+
import {EVENT_ROW} from '../models/event.model';
|
|
8
15
|
|
|
9
16
|
export function removeRow(pool: RenderElementPool, row: RowComponent): void {
|
|
10
17
|
if (row.element != null) {
|
|
@@ -20,36 +27,38 @@ export function removeRow(pool: RenderElementPool, row: RowComponent): void {
|
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
export function renderRow(state: State, row: RowComponent): void {
|
|
23
|
-
const
|
|
30
|
+
const {managers, options, prefix} = state;
|
|
31
|
+
|
|
32
|
+
const element = row.element ?? managers.render.pool.rows.shift() ?? createRow(options.rowHeight);
|
|
24
33
|
|
|
25
34
|
row.element = element;
|
|
26
35
|
|
|
27
36
|
element.innerHTML = '';
|
|
28
37
|
|
|
29
|
-
const selected =
|
|
38
|
+
const selected = managers.selection.items.has(row.key);
|
|
30
39
|
|
|
31
40
|
const key = String(row.key);
|
|
32
41
|
|
|
33
42
|
setAttributes(element, {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
id:
|
|
43
|
+
[ARIA_SELECTED]: String(selected),
|
|
44
|
+
[ATTRIBUTE_DATA_ACTIVE]: String(managers.navigation.active === row.key),
|
|
45
|
+
[ATTRIBUTE_DATA_EVENT]: EVENT_ROW,
|
|
46
|
+
[ATTRIBUTE_DATA_KEY]: key,
|
|
47
|
+
id: `${prefix}${key}`,
|
|
39
48
|
});
|
|
40
49
|
|
|
41
|
-
element.classList.add(
|
|
50
|
+
element.classList.add(CSS_ROW_BODY);
|
|
42
51
|
|
|
43
52
|
if (selected) {
|
|
44
|
-
element.classList.add(
|
|
53
|
+
element.classList.add(CSS_ROW_SELECTED);
|
|
45
54
|
} else {
|
|
46
|
-
element.classList.remove(
|
|
55
|
+
element.classList.remove(CSS_ROW_SELECTED);
|
|
47
56
|
}
|
|
48
57
|
|
|
49
|
-
const columns =
|
|
58
|
+
const columns = managers.column.items;
|
|
50
59
|
const {length} = columns;
|
|
51
60
|
|
|
52
|
-
const data =
|
|
61
|
+
const data = managers.data.state.values.mapped.get(row.key);
|
|
53
62
|
|
|
54
63
|
if (data == null) {
|
|
55
64
|
return;
|
|
@@ -57,16 +66,15 @@ export function renderRow(state: State, row: RowComponent): void {
|
|
|
57
66
|
|
|
58
67
|
for (let index = 0; index < length; index += 1) {
|
|
59
68
|
const {options} = columns[index];
|
|
69
|
+
const {key, width} = options;
|
|
60
70
|
|
|
61
|
-
|
|
71
|
+
managers.render.pool.cells[key] ??= [];
|
|
62
72
|
|
|
63
|
-
const cell =
|
|
64
|
-
state.managers.render.pool.cells[columns[index].options.field].shift() ??
|
|
65
|
-
createCell(options.width);
|
|
73
|
+
const cell = managers.render.pool.cells[key].shift() ?? createCell(width);
|
|
66
74
|
|
|
67
|
-
cell.textContent = String(getValue(data,
|
|
75
|
+
cell.textContent = String(getValue(data, key));
|
|
68
76
|
|
|
69
|
-
row.cells[
|
|
77
|
+
row.cells[key] = cell;
|
|
70
78
|
|
|
71
79
|
element.append(cell);
|
|
72
80
|
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import {setAttributes} from '@oscarpalmer/toretto/attribute';
|
|
2
2
|
import {setStyles} from '@oscarpalmer/toretto/style';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
CSS_TABELA_CELL_BODY,
|
|
6
|
-
CSS_TABELA_ROW,
|
|
7
|
-
CSS_TABELA_ROWGROUP,
|
|
8
|
-
} from '../models/style.model';
|
|
3
|
+
import {ELEMENT_DIV, ROLE_CELL, ROLE_ROW, ROLE_ROWGROUP} from '../models/dom.model';
|
|
4
|
+
import {CSS_CELL, CSS_CELL_BODY, CSS_ROW, CSS_ROWGROUP} from '../models/style.model';
|
|
9
5
|
|
|
10
6
|
type RowGroupWithRow = {
|
|
11
7
|
group: HTMLDivElement;
|
|
@@ -14,10 +10,10 @@ type RowGroupWithRow = {
|
|
|
14
10
|
|
|
15
11
|
export function createCell(width: number, body?: boolean): HTMLDivElement {
|
|
16
12
|
const cell = createElement(
|
|
17
|
-
|
|
13
|
+
ELEMENT_DIV,
|
|
18
14
|
{
|
|
19
|
-
className:
|
|
20
|
-
role:
|
|
15
|
+
className: CSS_CELL,
|
|
16
|
+
role: ROLE_CELL,
|
|
21
17
|
},
|
|
22
18
|
{},
|
|
23
19
|
{
|
|
@@ -26,7 +22,7 @@ export function createCell(width: number, body?: boolean): HTMLDivElement {
|
|
|
26
22
|
);
|
|
27
23
|
|
|
28
24
|
if (body ?? true) {
|
|
29
|
-
cell.classList.add(
|
|
25
|
+
cell.classList.add(CSS_CELL_BODY);
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
return cell;
|
|
@@ -53,37 +49,37 @@ export function createElement<TagName extends keyof HTMLElementTagNameMap>(
|
|
|
53
49
|
return element;
|
|
54
50
|
}
|
|
55
51
|
|
|
56
|
-
export function createRowGroup(): RowGroupWithRow;
|
|
52
|
+
export function createRowGroup(height: number): RowGroupWithRow;
|
|
57
53
|
|
|
58
|
-
export function createRowGroup(withRow: boolean): HTMLDivElement;
|
|
54
|
+
export function createRowGroup(height: number, withRow: boolean): HTMLDivElement;
|
|
59
55
|
|
|
60
|
-
export function createRowGroup(withRow?: boolean) {
|
|
61
|
-
const group = createElement(
|
|
62
|
-
className:
|
|
63
|
-
role:
|
|
56
|
+
export function createRowGroup(height: number, withRow?: boolean) {
|
|
57
|
+
const group = createElement(ELEMENT_DIV, {
|
|
58
|
+
className: CSS_ROWGROUP,
|
|
59
|
+
role: ROLE_ROWGROUP,
|
|
64
60
|
});
|
|
65
61
|
|
|
66
62
|
if (!(withRow ?? true)) {
|
|
67
63
|
return group;
|
|
68
64
|
}
|
|
69
65
|
|
|
70
|
-
const row = createRow();
|
|
66
|
+
const row = createRow(height);
|
|
71
67
|
|
|
72
68
|
group.append(row);
|
|
73
69
|
|
|
74
70
|
return {group, row};
|
|
75
71
|
}
|
|
76
72
|
|
|
77
|
-
export function createRow(): HTMLDivElement {
|
|
73
|
+
export function createRow(height: number): HTMLDivElement {
|
|
78
74
|
const row = createElement(
|
|
79
|
-
|
|
75
|
+
ELEMENT_DIV,
|
|
80
76
|
{
|
|
81
|
-
className:
|
|
82
|
-
role:
|
|
77
|
+
className: CSS_ROW,
|
|
78
|
+
role: ROLE_ROW,
|
|
83
79
|
},
|
|
84
80
|
{},
|
|
85
81
|
{
|
|
86
|
-
height:
|
|
82
|
+
height: `${height}px`,
|
|
87
83
|
},
|
|
88
84
|
);
|
|
89
85
|
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type {Key} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import type {GroupComponent} from '../components/group.component';
|
|
3
|
+
import {EVENTS_NAMES, type EventName} from '../models/event.model';
|
|
4
|
+
import {GROUP_KEY_EXPRESSION, type TabelaGroup} from '../models/group.model';
|
|
5
|
+
|
|
6
|
+
export function getGroup(group: GroupComponent): TabelaGroup {
|
|
7
|
+
return {
|
|
8
|
+
value: group.value.original,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
2
11
|
|
|
3
12
|
export function getKey(value: unknown): Key | undefined {
|
|
4
13
|
if (typeof value === 'number') {
|
|
@@ -12,4 +21,12 @@ export function getKey(value: unknown): Key | undefined {
|
|
|
12
21
|
return integerExpression.test(value) ? Number.parseInt(value, 10) : value;
|
|
13
22
|
}
|
|
14
23
|
|
|
24
|
+
export function isEvent(value: unknown): value is EventName {
|
|
25
|
+
return EVENTS_NAMES.has(value as EventName);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function isGroupKey(key: unknown): boolean {
|
|
29
|
+
return typeof key === 'string' && GROUP_KEY_EXPRESSION.test(key);
|
|
30
|
+
}
|
|
31
|
+
|
|
15
32
|
const integerExpression = /^\d+$/;
|
|
@@ -20,31 +20,31 @@ export class ColumnManager {
|
|
|
20
20
|
this.state = undefined as never;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
get(
|
|
24
|
-
return this.items.find(item => item.options.
|
|
23
|
+
get(key: string): ColumnComponent | undefined {
|
|
24
|
+
return this.items.find(item => item.options.key === key);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
remove(
|
|
27
|
+
remove(key: string): void;
|
|
28
28
|
|
|
29
|
-
remove(
|
|
29
|
+
remove(keys: string[]): void;
|
|
30
30
|
|
|
31
31
|
remove(value: unknown): void {
|
|
32
32
|
const {items, state} = this;
|
|
33
33
|
const {components, managers} = state;
|
|
34
34
|
|
|
35
|
-
const
|
|
35
|
+
const keys = (Array.isArray(value) ? value : [value]).filter(
|
|
36
36
|
item => typeof item === 'string',
|
|
37
37
|
);
|
|
38
38
|
|
|
39
|
-
const {length} =
|
|
39
|
+
const {length} = keys;
|
|
40
40
|
|
|
41
41
|
if (length === 0) {
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
for (let
|
|
45
|
+
for (let keyIndex = 0; keyIndex < length; keyIndex += 1) {
|
|
46
46
|
const itemIndex = items.findIndex(
|
|
47
|
-
component => component.options.
|
|
47
|
+
component => component.options.key === keys[keyIndex],
|
|
48
48
|
);
|
|
49
49
|
|
|
50
50
|
if (itemIndex > -1) {
|
|
@@ -57,7 +57,7 @@ export class ColumnManager {
|
|
|
57
57
|
components.header.update(items);
|
|
58
58
|
components.footer.update(items);
|
|
59
59
|
|
|
60
|
-
managers.render.removeCells(
|
|
60
|
+
managers.render.removeCells(keys);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
set(columns: TabelaColumn[]): void {
|