@oscarpalmer/tabela 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/dist/body.component-_VDOpJhV.d.mts +10 -0
  2. package/dist/body.model-2iwsovAV.d.mts +7 -0
  3. package/dist/column.component-Bx46r3JI.d.mts +16 -0
  4. package/dist/column.model-D-aw4EU4.d.mts +16 -0
  5. package/dist/components/body.component.d.mts +2 -0
  6. package/dist/components/{body.component.js → body.component.mjs} +6 -3
  7. package/dist/components/column.component.d.mts +2 -0
  8. package/dist/components/{column.component.js → column.component.mjs} +12 -9
  9. package/dist/components/footer.component.d.mts +2 -0
  10. package/dist/components/{footer.component.js → footer.component.mjs} +7 -4
  11. package/dist/components/group.component.d.mts +2 -0
  12. package/dist/components/group.component.mjs +51 -0
  13. package/dist/components/header.component.d.mts +2 -0
  14. package/dist/components/{header.component.js → header.component.mjs} +6 -3
  15. package/dist/components/row.component.d.mts +2 -0
  16. package/dist/components/{row.component.js → row.component.mjs} +11 -7
  17. package/dist/filter.model-7ukJrtil.d.mts +16 -0
  18. package/dist/footer.component-Curiab8j.d.mts +12 -0
  19. package/dist/footer.model-DhqoS6ds.d.mts +8 -0
  20. package/dist/group.component-Cq1YYbfJ.d.mts +285 -0
  21. package/dist/group.model-BsKFwHbt.d.mts +10 -0
  22. package/dist/header.component-BjjlpZIg.d.mts +12 -0
  23. package/dist/header.model-DN_KzUCV.d.mts +7 -0
  24. package/dist/helpers/dom.helpers.d.mts +12 -0
  25. package/dist/helpers/{dom.helpers.js → dom.helpers.mjs} +14 -10
  26. package/dist/helpers/misc.helpers.d.mts +6 -0
  27. package/dist/helpers/{misc.helpers.js → misc.helpers.mjs} +3 -1
  28. package/dist/helpers/style.helper.d.mts +6 -0
  29. package/dist/helpers/style.helper.mjs +8 -0
  30. package/dist/index.d.mts +7 -0
  31. package/dist/{index.js → index.mjs} +3 -1
  32. package/dist/managers/column.manager.d.mts +2 -0
  33. package/dist/managers/{column.manager.js → column.manager.mjs} +6 -1
  34. package/dist/managers/data.manager.d.mts +2 -0
  35. package/dist/managers/data.manager.mjs +222 -0
  36. package/dist/managers/event.manager.d.mts +2 -0
  37. package/dist/managers/{event.manager.js → event.manager.mjs} +12 -8
  38. package/dist/managers/filter.manager.d.mts +2 -0
  39. package/dist/managers/{filter.manager.js → filter.manager.mjs} +25 -11
  40. package/dist/managers/group.manager.d.mts +2 -0
  41. package/dist/managers/group.manager.mjs +73 -0
  42. package/dist/managers/navigation.manager.d.mts +2 -0
  43. package/dist/managers/{navigation.manager.js → navigation.manager.mjs} +27 -24
  44. package/dist/managers/render.manager.d.mts +2 -0
  45. package/dist/managers/render.manager.mjs +144 -0
  46. package/dist/managers/row.manager.d.mts +2 -0
  47. package/dist/managers/{row.manager.js → row.manager.mjs} +18 -11
  48. package/dist/managers/selection.manager.d.mts +2 -0
  49. package/dist/managers/{selection.manager.js → selection.manager.mjs} +57 -48
  50. package/dist/managers/sort.manager.d.mts +2 -0
  51. package/dist/managers/{sort.manager.js → sort.manager.mjs} +32 -2
  52. package/dist/managers/style.manager.d.mts +2 -0
  53. package/dist/managers/style.manager.mjs +149 -0
  54. package/dist/models/body.model.d.mts +2 -0
  55. package/dist/models/body.model.mjs +1 -0
  56. package/dist/models/column.model.d.mts +2 -0
  57. package/dist/models/column.model.mjs +1 -0
  58. package/dist/models/data.model.d.mts +2 -0
  59. package/dist/models/data.model.mjs +1 -0
  60. package/dist/models/filter.model.d.mts +2 -0
  61. package/dist/models/filter.model.mjs +1 -0
  62. package/dist/models/footer.model.d.mts +2 -0
  63. package/dist/models/footer.model.mjs +1 -0
  64. package/dist/models/group.model.d.mts +2 -0
  65. package/dist/models/group.model.mjs +1 -0
  66. package/dist/models/header.model.d.mts +2 -0
  67. package/dist/models/header.model.mjs +1 -0
  68. package/dist/models/render.model.d.mts +2 -0
  69. package/dist/models/render.model.mjs +1 -0
  70. package/dist/models/selection.model.d.mts +2 -0
  71. package/dist/models/selection.model.mjs +1 -0
  72. package/dist/models/sort.model.d.mts +2 -0
  73. package/dist/models/sort.model.mjs +1 -0
  74. package/dist/models/style.model.d.mts +23 -0
  75. package/dist/models/style.model.mjs +23 -0
  76. package/dist/models/tabela.model.d.mts +2 -0
  77. package/dist/models/tabela.model.mjs +1 -0
  78. package/dist/models/tabela.options.d.mts +2 -0
  79. package/dist/models/tabela.options.mjs +1 -0
  80. package/dist/selection.model-rwQe9fco.d.mts +12 -0
  81. package/dist/sort.model-CauImaLu.d.mts +15 -0
  82. package/dist/tabela.d.mts +21 -0
  83. package/dist/{tabela.full.js → tabela.full.mjs} +1407 -1124
  84. package/dist/tabela.mjs +126 -0
  85. package/dist/tabela.options-RkZvfptB.d.mts +14 -0
  86. package/package.json +45 -37
  87. package/src/components/body.component.ts +4 -3
  88. package/src/components/column.component.ts +19 -24
  89. package/src/components/footer.component.ts +8 -3
  90. package/src/components/group.component.ts +85 -0
  91. package/src/components/header.component.ts +3 -2
  92. package/src/components/row.component.ts +10 -8
  93. package/src/helpers/dom.helpers.ts +24 -20
  94. package/src/helpers/style.helper.ts +1 -1
  95. package/src/managers/column.manager.ts +8 -4
  96. package/src/managers/data.manager.ts +265 -61
  97. package/src/managers/event.manager.ts +14 -11
  98. package/src/managers/filter.manager.ts +38 -19
  99. package/src/managers/group.manager.ts +131 -0
  100. package/src/managers/navigation.manager.ts +25 -23
  101. package/src/managers/render.manager.ts +84 -32
  102. package/src/managers/row.manager.ts +23 -11
  103. package/src/managers/selection.manager.ts +68 -54
  104. package/src/managers/sort.manager.ts +81 -16
  105. package/src/managers/style.manager.ts +156 -0
  106. package/src/models/column.model.ts +2 -2
  107. package/src/models/data.model.ts +23 -9
  108. package/src/models/filter.model.ts +11 -3
  109. package/src/models/group.model.ts +8 -0
  110. package/src/models/render.model.ts +2 -2
  111. package/src/models/selection.model.ts +9 -0
  112. package/src/models/sort.model.ts +11 -3
  113. package/src/models/style.model.ts +39 -0
  114. package/src/models/tabela.model.ts +14 -46
  115. package/src/models/tabela.options.ts +3 -2
  116. package/src/tabela.ts +72 -41
  117. package/dist/helpers/style.helper.js +0 -6
  118. package/dist/managers/data.manager.js +0 -120
  119. package/dist/managers/render.manager.js +0 -110
  120. package/dist/models/body.model.js +0 -0
  121. package/dist/models/column.model.js +0 -0
  122. package/dist/models/data.model.js +0 -0
  123. package/dist/models/filter.model.js +0 -0
  124. package/dist/models/footer.model.js +0 -0
  125. package/dist/models/header.model.js +0 -0
  126. package/dist/models/render.model.js +0 -0
  127. package/dist/models/sort.model.js +0 -0
  128. package/dist/models/tabela.model.js +0 -0
  129. package/dist/models/tabela.options.js +0 -0
  130. package/dist/tabela.js +0 -102
  131. package/types/components/body.component.d.ts +0 -6
  132. package/types/components/column.component.d.ts +0 -13
  133. package/types/components/footer.component.d.ts +0 -8
  134. package/types/components/header.component.d.ts +0 -8
  135. package/types/components/row.component.d.ts +0 -11
  136. package/types/helpers/dom.helpers.d.ts +0 -10
  137. package/types/helpers/misc.helpers.d.ts +0 -2
  138. package/types/helpers/style.helper.d.ts +0 -1
  139. package/types/index.d.ts +0 -4
  140. package/types/managers/column.manager.d.ts +0 -12
  141. package/types/managers/data.manager.d.ts +0 -27
  142. package/types/managers/event.manager.d.ts +0 -7
  143. package/types/managers/filter.manager.d.ts +0 -19
  144. package/types/managers/navigation.manager.d.ts +0 -10
  145. package/types/managers/render.manager.d.ts +0 -16
  146. package/types/managers/row.manager.d.ts +0 -13
  147. package/types/managers/selection.manager.d.ts +0 -18
  148. package/types/managers/sort.manager.d.ts +0 -26
  149. package/types/models/body.model.d.ts +0 -4
  150. package/types/models/column.model.d.ts +0 -13
  151. package/types/models/data.model.d.ts +0 -14
  152. package/types/models/filter.model.d.ts +0 -6
  153. package/types/models/footer.model.d.ts +0 -5
  154. package/types/models/header.model.d.ts +0 -4
  155. package/types/models/render.model.d.ts +0 -13
  156. package/types/models/sort.model.d.ts +0 -5
  157. package/types/models/tabela.model.d.ts +0 -69
  158. package/types/models/tabela.options.d.ts +0 -9
  159. package/types/tabela.d.ts +0 -12
@@ -0,0 +1,126 @@
1
+ import { CSS_TABELA, CSS_TABELA_TABLE } from "./models/style.model.mjs";
2
+ import { createElement } from "./helpers/dom.helpers.mjs";
3
+ import { BodyComponent } from "./components/body.component.mjs";
4
+ import { FooterComponent } from "./components/footer.component.mjs";
5
+ import { HeaderComponent } from "./components/header.component.mjs";
6
+ import { ColumnManager } from "./managers/column.manager.mjs";
7
+ import { SortManager } from "./managers/sort.manager.mjs";
8
+ import { DataManager } from "./managers/data.manager.mjs";
9
+ import { EventManager } from "./managers/event.manager.mjs";
10
+ import { FilterManager } from "./managers/filter.manager.mjs";
11
+ import { GroupManager } from "./managers/group.manager.mjs";
12
+ import { NavigationManager } from "./managers/navigation.manager.mjs";
13
+ import { RenderManager } from "./managers/render.manager.mjs";
14
+ import { RowManager } from "./managers/row.manager.mjs";
15
+ import { SelectionManager } from "./managers/selection.manager.mjs";
16
+ import { StyleManager } from "./managers/style.manager.mjs";
17
+ //#region src/tabela.ts
18
+ var Tabela = class {
19
+ #components;
20
+ #element;
21
+ #id = getId();
22
+ #table;
23
+ #key;
24
+ #managers = {
25
+ column: void 0,
26
+ data: void 0,
27
+ event: void 0,
28
+ filter: void 0,
29
+ group: void 0,
30
+ navigation: void 0,
31
+ render: void 0,
32
+ row: void 0,
33
+ selection: void 0,
34
+ sort: void 0,
35
+ style: void 0
36
+ };
37
+ #state;
38
+ data;
39
+ filter;
40
+ group;
41
+ selection;
42
+ sort;
43
+ get key() {
44
+ return this.#key;
45
+ }
46
+ constructor(element, options) {
47
+ this.#element = element;
48
+ element.innerHTML = "";
49
+ element.classList.add(CSS_TABELA);
50
+ this.#table = createElement("div", {
51
+ className: CSS_TABELA_TABLE,
52
+ role: "table"
53
+ }, { "aria-label": options.label });
54
+ this.#key = options.key;
55
+ this.#components = {
56
+ body: new BodyComponent(),
57
+ footer: new FooterComponent(),
58
+ header: new HeaderComponent()
59
+ };
60
+ this.#state = {
61
+ options,
62
+ components: this.#components,
63
+ element: this.#table,
64
+ id: this.#id,
65
+ key: this.#key,
66
+ managers: this.#managers
67
+ };
68
+ this.#managers.column = new ColumnManager(this.#state);
69
+ this.#managers.data = new DataManager(this.#state);
70
+ this.#managers.event = new EventManager(this.#state);
71
+ this.#managers.filter = new FilterManager(this.#state);
72
+ this.#managers.group = new GroupManager(this.#state);
73
+ this.#managers.navigation = new NavigationManager(this.#state);
74
+ this.#managers.render = new RenderManager(this.#state);
75
+ this.#managers.row = new RowManager(this.#state);
76
+ this.#managers.selection = new SelectionManager(this.#state);
77
+ this.#managers.sort = new SortManager(this.#state);
78
+ this.#managers.style = new StyleManager(this.#state);
79
+ this.#table.append(this.#components.header.elements.group, this.#components.body.elements.group, this.#components.footer.elements.group);
80
+ element.append(this.#table);
81
+ this.#managers.data.set(options.data);
82
+ this.data = this.#managers.data.handlers;
83
+ this.filter = this.#managers.filter.handlers;
84
+ this.group = this.#managers.group.handlers;
85
+ this.selection = this.#managers.selection.handlers;
86
+ this.sort = this.#managers.sort.handlers;
87
+ }
88
+ destroy() {
89
+ const components = this.#components;
90
+ const managers = this.#managers;
91
+ const element = this.#element;
92
+ const table = this.#table;
93
+ components.body.destroy();
94
+ components.footer.destroy();
95
+ components.header.destroy();
96
+ managers.column.destroy();
97
+ managers.data.destroy();
98
+ managers.event.destroy();
99
+ managers.filter.destroy();
100
+ managers.group.destroy();
101
+ managers.navigation.destroy();
102
+ managers.render.destroy();
103
+ managers.row.destroy();
104
+ managers.selection.destroy();
105
+ managers.sort.destroy();
106
+ element.innerHTML = "";
107
+ table.innerHTML = "";
108
+ table.role = "";
109
+ element.classList.remove(CSS_TABELA);
110
+ table.removeAttribute("aria-label");
111
+ table.removeAttribute("role");
112
+ this.#state.components = void 0;
113
+ this.#state.managers = void 0;
114
+ this.#state.element = void 0;
115
+ this.#state.options = void 0;
116
+ this.#element = void 0;
117
+ this.#table = void 0;
118
+ }
119
+ };
120
+ function getId() {
121
+ id += 1;
122
+ return id;
123
+ }
124
+ let id = 0;
125
+ //#endregion
126
+ export { Tabela };
@@ -0,0 +1,14 @@
1
+ import { n as TabelaColumn } from "./column.model-D-aw4EU4.mjs";
2
+ import { PlainObject } from "@oscarpalmer/atoms/models";
3
+
4
+ //#region src/models/tabela.options.d.ts
5
+ type TabelaOptions = {
6
+ columns: TabelaColumn[];
7
+ data: PlainObject[];
8
+ grouping?: string;
9
+ key: string;
10
+ label: string;
11
+ rowHeight: number;
12
+ };
13
+ //#endregion
14
+ export { TabelaOptions as t };
package/package.json CHANGED
@@ -1,50 +1,58 @@
1
1
  {
2
+ "name": "@oscarpalmer/tabela",
3
+ "version": "0.13.0",
4
+ "description": "A modern table.",
5
+ "keywords": [],
6
+ "license": "MIT",
2
7
  "author": {
3
8
  "name": "Oscar Palmér",
4
9
  "url": "https://oscarpalmer.se"
5
10
  },
6
- "dependencies": {
7
- "@oscarpalmer/atoms": "^0.159",
8
- "@oscarpalmer/toretto": "^0.38"
9
- },
10
- "description": "A modern table.",
11
- "devDependencies": {
12
- "@oscarpalmer/oui": "^0.19",
13
- "@types/node": "^25.3",
14
- "@vitest/coverage-istanbul": "^4",
15
- "jsdom": "^28.1",
16
- "oxfmt": "^0.36",
17
- "oxlint": "^1.51",
18
- "rolldown": "1.0.0-rc.7",
19
- "tslib": "^2.8",
20
- "typescript": "^5.9",
21
- "vite": "8.0.0-beta.16",
22
- "vitest": "^4"
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/oscarpalmer/tabela.git"
23
14
  },
15
+ "files": [
16
+ "dist",
17
+ "src"
18
+ ],
19
+ "type": "module",
20
+ "module": "./dist/index.mjs",
21
+ "types": "./dist/index.d.mts",
24
22
  "exports": {
25
23
  ".": {
26
- "types": "./types/index.d.ts",
27
- "default": "./dist/index.js"
24
+ "types": "./dist/index.d.mts",
25
+ "default": "./dist/index.mjs"
28
26
  }
29
27
  },
30
- "files": ["dist", "src", "types"],
31
- "keywords": [],
32
- "license": "MIT",
33
- "module": "./dist/index.js",
34
- "name": "@oscarpalmer/tabela",
35
- "repository": {
36
- "type": "git",
37
- "url": "git+https://github.com/oscarpalmer/tabela.git"
38
- },
39
28
  "scripts": {
40
- "build": "npm run clean && npx vite build && npm run rolldown:build && npx tsc",
41
- "clean": "rm -rf ./dist && rm -rf ./types && rm -f ./tsconfig.tsbuildinfo",
42
- "rolldown:build": "npx rolldown -c",
43
- "rolldown:watch": "npx rolldown -c ./rolldown.config.js --watch",
44
- "test": "npx vitest --coverage",
45
- "watch": "npx vite build --watch"
29
+ "build": "vpx vp run tsdown:build && vpx vp pack",
30
+ "tsdown:build": "vpx tsdown -c ./tsdown.config.ts",
31
+ "tsdown:watch": "vpx tsdown -c ./tsdown.config.ts --watch",
32
+ "test": "vpx vp test run --coverage",
33
+ "test:leak": "vpx vp test run --detect-async-leaks --coverage",
34
+ "watch": "vpx vite build --watch",
35
+ "www": "concurrently \"vpx vp run www:css\" \"vpx vp run www:js\"",
36
+ "www:css": "sass --watch www/.app/css:./www/css",
37
+ "www:js": "vpx tsdown -c ./www/.app/js/tsdown.config.ts --watch"
46
38
  },
47
- "type": "module",
48
- "types": "./types/index.d.ts",
49
- "version": "0.11.0"
39
+ "dependencies": {
40
+ "@oscarpalmer/atoms": "^0.165",
41
+ "@oscarpalmer/toretto": "^0.41"
42
+ },
43
+ "devDependencies": {
44
+ "@oscarpalmer/abydon": "^0.19",
45
+ "@oscarpalmer/oui": "^0.19",
46
+ "@types/node": "^25.5",
47
+ "@vitest/coverage-istanbul": "^4.1",
48
+ "concurrently": "^9.2",
49
+ "jsdom": "^28.1",
50
+ "sass": "^1.98",
51
+ "tsdown": "^0.21",
52
+ "typescript": "^5.9",
53
+ "vite": "npm:@voidzero-dev/vite-plus-core@latest",
54
+ "vite-plus": "latest",
55
+ "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
56
+ },
57
+ "packageManager": "npm@11.11.1"
50
58
  }
@@ -1,10 +1,11 @@
1
1
  import {createElement, createRowGroup} from '../helpers/dom.helpers';
2
2
  import type {BodyElements} from '../models/body.model';
3
+ import {CSS_TABELA_FAKER, CSS_TABELA_ROWGROUP_BODY} from '../models/style.model';
3
4
 
4
5
  function createFaker(): HTMLDivElement {
5
6
  return createElement('div', {
6
- className: 'tabela__faker',
7
- }, {}, {});
7
+ className: CSS_TABELA_FAKER,
8
+ });
8
9
  }
9
10
 
10
11
  export class BodyComponent {
@@ -18,7 +19,7 @@ export class BodyComponent {
18
19
 
19
20
  this.elements.group = group;
20
21
 
21
- group.className += ' tabela__rowgroup--body';
22
+ group.className += ` ${CSS_TABELA_ROWGROUP_BODY}`;
22
23
 
23
24
  group.tabIndex = 0;
24
25
 
@@ -1,21 +1,26 @@
1
1
  import {createElement} from '../helpers/dom.helpers';
2
- import type {TabelaColumn, TabelaColumnOptions} from '../models/column.model';
2
+ import type {Column, TabelaColumn} from '../models/column.model';
3
+ import {
4
+ CSS_TABELA_HEADING,
5
+ CSS_TABELA_HEADING_CONTENT,
6
+ CSS_TABELA_HEADING_SORTER,
7
+ } from '../models/style.model';
3
8
 
4
9
  export class ColumnComponent {
5
10
  elements: ColumnElements;
6
- options: TabelaColumn;
11
+ options: Column;
7
12
 
8
- constructor(options: TabelaColumnOptions) {
13
+ constructor(column: TabelaColumn) {
9
14
  const width =
10
15
  Number.parseInt(getComputedStyle(document.body).fontSize, 10) *
11
- (options.width ?? options.title.length * 1.5);
16
+ (column.width ?? column.title.length * 1.5);
12
17
 
13
18
  this.options = {
14
- ...options,
19
+ ...column,
15
20
  width,
16
21
  };
17
22
 
18
- this.elements = createHeading(options.field, options.title, width);
23
+ this.elements = createHeading(this.options.field, this.options.title, width);
19
24
  }
20
25
 
21
26
  destroy(): void {
@@ -38,7 +43,7 @@ function createHeading(field: string, title: string, width: number): ColumnEleme
38
43
  const wrapper = createElement(
39
44
  'div',
40
45
  {
41
- className: 'tabela__heading',
46
+ className: CSS_TABELA_HEADING,
42
47
  role: 'columnheader',
43
48
  },
44
49
  {
@@ -50,24 +55,14 @@ function createHeading(field: string, title: string, width: number): ColumnEleme
50
55
  },
51
56
  );
52
57
 
53
- const content = createElement(
54
- 'div',
55
- {
56
- className: 'tabela__heading__content',
57
- textContent: title,
58
- },
59
- {},
60
- {},
61
- );
58
+ const content = createElement('div', {
59
+ className: CSS_TABELA_HEADING_CONTENT,
60
+ textContent: title,
61
+ });
62
62
 
63
- const sorter = createElement(
64
- 'div',
65
- {
66
- className: 'tabela__heading__sorter',
67
- },
68
- {},
69
- {},
70
- );
63
+ const sorter = createElement('div', {
64
+ className: CSS_TABELA_HEADING_SORTER,
65
+ });
71
66
 
72
67
  wrapper.append(content, sorter);
73
68
 
@@ -1,5 +1,10 @@
1
1
  import {createCell, createRowGroup} from '../helpers/dom.helpers';
2
2
  import type {FooterElements} from '../models/footer.model';
3
+ import {
4
+ CSS_TABELA_CELL_FOOTER,
5
+ CSS_TABELA_ROW_FOOTER,
6
+ CSS_TABELA_ROWGROUP_FOOTER,
7
+ } from '../models/style.model';
3
8
  import type {ColumnComponent} from './column.component';
4
9
 
5
10
  export class FooterComponent {
@@ -14,8 +19,8 @@ export class FooterComponent {
14
19
  cells: [],
15
20
  };
16
21
 
17
- group.className += ' tabela__rowgroup--footer';
18
- row.className += ' tabela__row--footer';
22
+ group.className += ` ${CSS_TABELA_ROWGROUP_FOOTER}`;
23
+ row.className += ` ${CSS_TABELA_ROW_FOOTER}`;
19
24
  }
20
25
 
21
26
  destroy(): void {
@@ -35,7 +40,7 @@ export class FooterComponent {
35
40
  for (let index = 0; index < length; index += 1) {
36
41
  const cell = createCell(columns[index].options.width ?? 4, false);
37
42
 
38
- cell.className += ' tabela__cell--footer';
43
+ cell.className += ` ${CSS_TABELA_CELL_FOOTER}`;
39
44
  cell.innerHTML = '&nbsp;';
40
45
 
41
46
  elements.cells.push(cell);
@@ -0,0 +1,85 @@
1
+ import {getString} from '@oscarpalmer/atoms/string';
2
+ import {createElement} from '../helpers/dom.helpers';
3
+ import type {GroupValue} from '../models/group.model';
4
+ import {CSS_TABELA_ROW, CSS_TABELA_ROW_GROUP} from '../models/style.model';
5
+ import type {State} from '../models/tabela.model';
6
+
7
+ export class GroupComponent {
8
+ element: HTMLElement | undefined;
9
+
10
+ expanded = true;
11
+
12
+ filtered = 0;
13
+
14
+ readonly key: string;
15
+
16
+ selected = 0;
17
+
18
+ total = 0;
19
+
20
+ readonly value: GroupValue;
21
+
22
+ constructor(
23
+ readonly label: string,
24
+ value: unknown,
25
+ ) {
26
+ const stringified = getString(value);
27
+
28
+ this.key = `group:${stringified}`;
29
+
30
+ this.value = {
31
+ stringified,
32
+ original: value,
33
+ };
34
+ }
35
+ }
36
+
37
+ export function removeGroup(group: GroupComponent): void {
38
+ if (group.element == null) {
39
+ return;
40
+ }
41
+
42
+ group.element.innerHTML = '';
43
+
44
+ group.element.remove();
45
+ }
46
+
47
+ export function renderGroup(state: State, component: GroupComponent): void {
48
+ component.element ??= createElement(
49
+ 'div',
50
+ {
51
+ className: `${CSS_TABELA_ROW} ${CSS_TABELA_ROW_GROUP}`,
52
+ innerHTML: `<div class="tabela__cell tabela__cell--group" role="cell">
53
+ <button class="tabela__button tabela__button--group" data-event="group" data-key="tabela_${state.id}_${component.key}" type="button">
54
+ <span aria-hidden="true"></span>
55
+ <span>Open/close</span>
56
+ </button>
57
+ <p>${component.label}</p>
58
+ <span class="tabela__group__total">${component.total}</span>
59
+ <span class="tabela__group__selected">${component.selected === 0 ? '' : component.selected}</span>
60
+ </div>`,
61
+ role: 'row',
62
+ },
63
+ {},
64
+ {
65
+ height: `${state.options.rowHeight}px`,
66
+ },
67
+ );
68
+ }
69
+
70
+ export function updateGroup(state: State, component: GroupComponent): void {
71
+ if (component.element == null) {
72
+ return;
73
+ }
74
+
75
+ const selected = component.element.querySelector<HTMLSpanElement>('.tabela__group__selected');
76
+ const total = component.element.querySelector<HTMLSpanElement>('.tabela__group__total');
77
+
78
+ if (selected != null) {
79
+ selected.textContent = component.selected === 0 ? '' : String(component.selected);
80
+ }
81
+
82
+ if (total != null) {
83
+ total.textContent = String(component.total);
84
+ }
85
+ }
@@ -1,5 +1,6 @@
1
1
  import {createRowGroup} from '../helpers/dom.helpers';
2
2
  import type {HeaderElements} from '../models/header.model';
3
+ import {CSS_TABELA_ROW_HEADER, CSS_TABELA_ROWGROUP_HEADER} from '../models/style.model';
3
4
  import type {ColumnComponent} from './column.component';
4
5
 
5
6
  export class HeaderComponent {
@@ -10,8 +11,8 @@ export class HeaderComponent {
10
11
 
11
12
  this.elements = {group, row};
12
13
 
13
- group.className += ' tabela__rowgroup--header';
14
- row.className += ' tabela__row--header';
14
+ group.className += ` ${CSS_TABELA_ROWGROUP_HEADER}`;
15
+ row.className += ` ${CSS_TABELA_ROW_HEADER}`;
15
16
  }
16
17
 
17
18
  destroy(): void {
@@ -1,8 +1,10 @@
1
1
  import type {Key} from '@oscarpalmer/atoms/models';
2
+ import {getValue} from '@oscarpalmer/atoms/value/handle';
2
3
  import {setAttributes} from '@oscarpalmer/toretto/attribute';
3
4
  import {createCell, createRow} from '../helpers/dom.helpers';
4
5
  import type {RenderElementPool} from '../models/render.model';
5
- import type {TabelaState} from '../models/tabela.model';
6
+ import {CSS_TABELA_ROW_BODY, CSS_TABELA_ROW_SELECTED} from '../models/style.model';
7
+ import type {State} from '../models/tabela.model';
6
8
 
7
9
  export function removeRow(pool: RenderElementPool, row: RowComponent): void {
8
10
  if (row.element != null) {
@@ -17,7 +19,7 @@ export function removeRow(pool: RenderElementPool, row: RowComponent): void {
17
19
  row.cells = {};
18
20
  }
19
21
 
20
- export function renderRow(state: TabelaState, row: RowComponent): void {
22
+ export function renderRow(state: State, row: RowComponent): void {
21
23
  const element = row.element ?? state.managers.render.pool.rows.shift() ?? createRow();
22
24
 
23
25
  row.element = element;
@@ -33,21 +35,21 @@ export function renderRow(state: TabelaState, row: RowComponent): void {
33
35
  'data-active': String(state.managers.navigation.active === row.key),
34
36
  'data-event': 'row',
35
37
  'data-key': key,
36
- id: `tabela_${state.id}_row_${key}`,
38
+ id: `tabela_${state.id}_${key}`,
37
39
  });
38
40
 
39
- element.classList.add('tabela__row--body');
41
+ element.classList.add(CSS_TABELA_ROW_BODY);
40
42
 
41
43
  if (selected) {
42
- element.classList.add('tabela__row--selected');
44
+ element.classList.add(CSS_TABELA_ROW_SELECTED);
43
45
  } else {
44
- element.classList.remove('tabela__row--selected');
46
+ element.classList.remove(CSS_TABELA_ROW_SELECTED);
45
47
  }
46
48
 
47
49
  const columns = state.managers.column.items;
48
50
  const {length} = columns;
49
51
 
50
- const data = state.managers.data.values.objects.mapped.get(row.key);
52
+ const data = state.managers.data.state.values.mapped.get(row.key);
51
53
 
52
54
  if (data == null) {
53
55
  return;
@@ -62,7 +64,7 @@ export function renderRow(state: TabelaState, row: RowComponent): void {
62
64
  state.managers.render.pool.cells[columns[index].options.field].shift() ??
63
65
  createCell(options.width);
64
66
 
65
- cell.textContent = String(data[options.field]);
67
+ cell.textContent = String(getValue(data, options.field));
66
68
 
67
69
  row.cells[options.field] = cell;
68
70
 
@@ -1,5 +1,11 @@
1
1
  import {setAttributes} from '@oscarpalmer/toretto/attribute';
2
2
  import {setStyles} from '@oscarpalmer/toretto/style';
3
+ import {
4
+ CSS_TABELA_CELL,
5
+ CSS_TABELA_CELL_BODY,
6
+ CSS_TABELA_ROW,
7
+ CSS_TABELA_ROWGROUP,
8
+ } from '../models/style.model';
3
9
 
4
10
  type RowGroupWithRow = {
5
11
  group: HTMLDivElement;
@@ -10,7 +16,7 @@ export function createCell(width: number, body?: boolean): HTMLDivElement {
10
16
  const cell = createElement(
11
17
  'div',
12
18
  {
13
- className: 'tabela__cell',
19
+ className: CSS_TABELA_CELL,
14
20
  role: 'cell',
15
21
  },
16
22
  {},
@@ -20,7 +26,7 @@ export function createCell(width: number, body?: boolean): HTMLDivElement {
20
26
  );
21
27
 
22
28
  if (body ?? true) {
23
- cell.classList.add('tabela__cell--body');
29
+ cell.classList.add(CSS_TABELA_CELL_BODY);
24
30
  }
25
31
 
26
32
  return cell;
@@ -28,20 +34,21 @@ export function createCell(width: number, body?: boolean): HTMLDivElement {
28
34
 
29
35
  export function createElement<TagName extends keyof HTMLElementTagNameMap>(
30
36
  tagName: TagName,
31
- properties: Partial<HTMLElementTagNameMap[TagName]>,
32
- attributes: Record<string, string>,
33
- style: Partial<CSSStyleDeclaration>,
37
+ properties?: Partial<HTMLElementTagNameMap[TagName]>,
38
+ attributes?: Record<string, string>,
39
+ style?: Partial<CSSStyleDeclaration>,
34
40
  ): HTMLElementTagNameMap[TagName] {
35
41
  const element = document.createElement(tagName);
36
42
 
37
- const keys = Object.keys(properties);
43
+ const props = properties ?? {};
44
+ const keys = Object.keys(props);
38
45
 
39
46
  for (const key of keys) {
40
- (element as any)[key] = properties[key as keyof typeof properties];
47
+ (element as any)[key] = props[key as keyof typeof props];
41
48
  }
42
49
 
43
- setAttributes(element, attributes);
44
- setStyles(element, style);
50
+ setAttributes(element, attributes ?? {});
51
+ setStyles(element, style ?? {});
45
52
 
46
53
  return element;
47
54
  }
@@ -51,15 +58,10 @@ export function createRowGroup(): RowGroupWithRow;
51
58
  export function createRowGroup(withRow: boolean): HTMLDivElement;
52
59
 
53
60
  export function createRowGroup(withRow?: boolean) {
54
- const group = createElement(
55
- 'div',
56
- {
57
- className: 'tabela__rowgroup',
58
- role: 'rowgroup',
59
- },
60
- {},
61
- {},
62
- );
61
+ const group = createElement('div', {
62
+ className: CSS_TABELA_ROWGROUP,
63
+ role: 'rowgroup',
64
+ });
63
65
 
64
66
  if (!(withRow ?? true)) {
65
67
  return group;
@@ -76,11 +78,13 @@ export function createRow(): HTMLDivElement {
76
78
  const row = createElement(
77
79
  'div',
78
80
  {
79
- className: 'tabela__row',
81
+ className: CSS_TABELA_ROW,
80
82
  role: 'row',
81
83
  },
82
84
  {},
83
- {},
85
+ {
86
+ height: '32px',
87
+ },
84
88
  );
85
89
 
86
90
  return row;
@@ -1,6 +1,6 @@
1
1
  import {toggleStyles} from '@oscarpalmer/toretto/style';
2
2
 
3
- export const dragStyling = toggleStyles(document.body, {
3
+ export const preventSelection = toggleStyles(document.body, {
4
4
  userSelect: 'none',
5
5
  webkitUserSelect: 'none',
6
6
  });
@@ -1,11 +1,11 @@
1
1
  import {ColumnComponent} from '../components/column.component';
2
- import type {TabelaColumnOptions} from '../models/column.model';
3
- import type {TabelaState} from '../models/tabela.model';
2
+ import type {TabelaColumn} from '../models/column.model';
3
+ import type {State} from '../models/tabela.model';
4
4
 
5
5
  export class ColumnManager {
6
6
  items: ColumnComponent[] = [];
7
7
 
8
- constructor(public state: TabelaState) {
8
+ constructor(public state: State) {
9
9
  this.set(state.options.columns);
10
10
  }
11
11
 
@@ -20,6 +20,10 @@ export class ColumnManager {
20
20
  this.state = undefined as never;
21
21
  }
22
22
 
23
+ get(field: string): ColumnComponent | undefined {
24
+ return this.items.find(item => item.options.field === field);
25
+ }
26
+
23
27
  remove(field: string): void;
24
28
 
25
29
  remove(fields: string[]): void;
@@ -56,7 +60,7 @@ export class ColumnManager {
56
60
  managers.render.removeCells(fields);
57
61
  }
58
62
 
59
- set(columns: TabelaColumnOptions[]): void {
63
+ set(columns: TabelaColumn[]): void {
60
64
  const {items, state} = this;
61
65
  const {footer, header} = state.components;
62
66