cedro 0.1.3 → 0.1.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cedro",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "devDependencies": {
6
6
  "@types/node": "^20.4.4",
@@ -7,7 +7,11 @@ export type WUIEvent =
7
7
  | "mousedown"
8
8
  | "mouseup"
9
9
  | "mousemove"
10
- | "option-clicked";
10
+ | "mouseout"
11
+ | "mouseleave"
12
+ | "option-clicked"
13
+ | "wheel"
14
+ | "drag";
11
15
 
12
16
  export type WUICallback = {
13
17
  event: WUIEvent;
@@ -48,6 +52,7 @@ export interface IWidget {
48
52
 
49
53
  subscribe: (cb: WUICallback) => void;
50
54
  unsubscribe: (event: WUIEvent) => void;
55
+ run(eventId: WUIEvent): void;
51
56
 
52
57
  setPadding(p: number): void;
53
58
 
@@ -0,0 +1 @@
1
+ export type OrientationTypes = "horizontal" | "vertical";
@@ -0,0 +1,216 @@
1
+ import "./styles/datagrid.css";
2
+ import { Label } from "./label.ui";
3
+ import { Widget, WidgetAlignTypes, WidgetTypes } from "./widget.ui";
4
+ import { Scroll } from "./scroll.ui";
5
+
6
+ const DATA_GRID_HEADER_HEIGHT = 30;
7
+ const DATA_GRID_FOOTER_HEIGHT = 40;
8
+ const DATA_GRID_ROW_HEIGHT = 20;
9
+ const DATA_GRID_MIN_COLUMN_WIDTH = 24;
10
+
11
+ type DataGridColumn = {
12
+ header: string;
13
+ width: number | null;
14
+ handler: (args: any) => void;
15
+ };
16
+
17
+ export class DataGrid extends Widget {
18
+ headerContainer: Widget;
19
+ dataContainer: Widget;
20
+ footerContainer: Widget;
21
+ data: Array<any>;
22
+ verticalScrollbar: Scroll;
23
+ horizontalScrollbar: Scroll;
24
+
25
+ rowHeight: number;
26
+
27
+ columns: Array<DataGridColumn>;
28
+
29
+ constructor(id: string, parent: Widget | null = null) {
30
+ super(id, "div", parent);
31
+
32
+ this.rowHeight = DATA_GRID_ROW_HEIGHT;
33
+
34
+ this.headerContainer = new Widget(id + ".header", "div");
35
+ this.headerContainer.setType(WidgetTypes.FILL);
36
+ this.headerContainer.setFixedSize(DATA_GRID_HEADER_HEIGHT);
37
+ this.headerContainer.addClass("WUIDataGrid-Header");
38
+
39
+ this.dataContainer = new Widget(id + ".data", "div");
40
+ this.dataContainer.setType(WidgetTypes.FILL);
41
+
42
+ this.footerContainer = new Widget(id + ".footer", "div");
43
+ this.footerContainer.setType(WidgetTypes.FILL);
44
+ this.footerContainer.setFixedSize(DATA_GRID_FOOTER_HEIGHT);
45
+
46
+ this.setType(WidgetTypes.FILL);
47
+ this.setAlign(WidgetAlignTypes.VERTICAL);
48
+
49
+ this.addChild(this.headerContainer);
50
+ this.addChild(this.dataContainer);
51
+ this.addChild(this.footerContainer);
52
+
53
+ this.verticalScrollbar = new Scroll(id + ".VerticalScrollbar", this.dataContainer);
54
+ this.horizontalScrollbar = new Scroll(id + ".HorizontalScrollbar", this.dataContainer, "horizontal");
55
+
56
+ this.columns = new Array<DataGridColumn>();
57
+
58
+ this.data = new Array<any>();
59
+ }
60
+
61
+ private getFreeWidth(): number {
62
+ let freeW = 0;
63
+ for (let i = 0; i < this.columns.length; i++) {
64
+ let width = this.columns[i].width;
65
+ if (width) {
66
+ freeW += width;
67
+ }
68
+ }
69
+
70
+ freeW = this.dataContainer.getW() - freeW;
71
+
72
+ if (freeW < DATA_GRID_MIN_COLUMN_WIDTH) {
73
+ freeW = DATA_GRID_MIN_COLUMN_WIDTH;
74
+ }
75
+ return freeW;
76
+ }
77
+
78
+ private getAllColumnsWidth(): number {
79
+ let returnValue = 0;
80
+ for (let i = 0; i < this.columns.length; i++) {
81
+ let width = this.columns[i].width;
82
+ if (width) {
83
+ returnValue += width;
84
+ }
85
+ }
86
+ return returnValue;
87
+ }
88
+
89
+ public init(): void {
90
+ super.init();
91
+
92
+ this.createHeaders();
93
+ }
94
+
95
+ private createHeaders(): void {
96
+ if (!this.columns) {
97
+ return;
98
+ }
99
+
100
+ for (let i = 0; i < this.columns.length; i++) {
101
+ const btn = new Label(this.id + "header." + i, "span");
102
+ btn.addClass("WUIDataGrid-HeaderLabel");
103
+ this.headerContainer.addChild(btn);
104
+ }
105
+
106
+ this.buildRows();
107
+ this.renderHeaders();
108
+ }
109
+
110
+ private renderHeaders(): void {
111
+ if (!this.columns) {
112
+ return;
113
+ }
114
+
115
+ let startX = 0;
116
+ for (let i = 0; i < this.columns.length; i++) {
117
+ const column = this.columns[i];
118
+ const btn = window.w.get(this.id + "header." + i) as Label;
119
+ const width = column.width ? column.width : this.getFreeWidth();
120
+ btn.setType(WidgetTypes.CUSTOM);
121
+ btn.setX(startX);
122
+ btn.setY(0);
123
+ btn.setW(width);
124
+ btn.setH(DATA_GRID_HEADER_HEIGHT);
125
+ btn.getBody().style.lineHeight = DATA_GRID_HEADER_HEIGHT + "px";
126
+ btn.setText(column.header);
127
+ this.headerContainer.addChild(btn);
128
+ startX += width;
129
+ }
130
+ }
131
+
132
+ private buildRows(): void {
133
+ let rowY = 0;
134
+
135
+ for (let i = 0; i < this.data.length; i++) {
136
+ const row = new Widget(this.id + ".row." + i, "div");
137
+
138
+ row.setType(WidgetTypes.CUSTOM);
139
+ row.getBody().style.position = "absolute";
140
+ row.getBody().style.overflow = "hidden";
141
+
142
+ this.dataContainer.addChild(row);
143
+
144
+ for (let j = 0; j < this.columns.length; j++) {
145
+ const column = this.columns[j];
146
+ const fieldId = this.id + ".row." + i + ".column." + j;
147
+ column.handler({
148
+ data: this.data[i],
149
+ index: i,
150
+ fieldId: fieldId,
151
+ row: row,
152
+ });
153
+ const columnWidget = window.w.get(fieldId) as Widget;
154
+ columnWidget.getBody().style.position = "absolute";
155
+ }
156
+ rowY += this.rowHeight;
157
+ }
158
+ }
159
+
160
+ private renderRows(): void {
161
+ let rowY = 0;
162
+
163
+ for (let i = 0; i < this.data.length; i++) {
164
+ const row = window.w.get(this.id + ".row." + i) as Widget;
165
+
166
+ row.setX(0);
167
+ row.setY(rowY);
168
+ row.setW(this.getAllColumnsWidth());
169
+ row.setH(this.rowHeight);
170
+
171
+ let widgetX = 0;
172
+ for (let j = 0; j < this.columns.length; j++) {
173
+ const column = this.columns[j];
174
+ const fieldId = this.id + ".row." + i + ".column." + j;
175
+ const columnWidget = window.w.get(fieldId) as Widget;
176
+ columnWidget.setY(0);
177
+ columnWidget.setX(widgetX);
178
+ columnWidget.setH(this.rowHeight);
179
+ if (column.width) {
180
+ columnWidget.setW(column.width);
181
+ } else {
182
+ columnWidget.setW(this.getFreeWidth());
183
+ }
184
+ widgetX += column.width ? column.width : columnWidget.getW();
185
+ }
186
+ rowY += this.rowHeight;
187
+ }
188
+ }
189
+
190
+ public render(): void {
191
+ super.render();
192
+ this.renderHeaders();
193
+ this.renderRows();
194
+ this.verticalScrollbar.render();
195
+ this.horizontalScrollbar.render();
196
+ }
197
+
198
+ public setRowHeight(rowHeight: number): void {
199
+ this.rowHeight = rowHeight;
200
+ }
201
+
202
+ public addColumn(header: string, width: number | null, handler: (args: any) => void) {
203
+ this.columns.push({ header, width, handler });
204
+ }
205
+
206
+ public getHeader(index: number): Label {
207
+ return window.w.get(this.id + "header." + index) as Label;
208
+ }
209
+
210
+ public setData(data: Array<any>): void {
211
+ this.data = data;
212
+
213
+ this.buildRows();
214
+ this.renderRows();
215
+ }
216
+ }
@@ -0,0 +1,143 @@
1
+ import { OrientationTypes } from "src/types/orientation.type";
2
+ import "./styles/draggable.css";
3
+ import { Widget, WidgetTypes } from "./widget.ui";
4
+
5
+ export type DragOrientation = OrientationTypes | "both";
6
+
7
+ export class Draggable {
8
+ target: Widget;
9
+ background: Widget;
10
+
11
+ dragging: boolean = false;
12
+ dragDistX: number;
13
+ dragDistY: number;
14
+ dragOrientation: DragOrientation;
15
+
16
+ minX: number | null;
17
+ minY: number | null;
18
+ maxX: number | null;
19
+ maxY: number | null;
20
+
21
+ constructor(widget: Widget, orientation: DragOrientation = "both") {
22
+ this.target = widget;
23
+
24
+ this.background = new Widget(this.target.id + ".Draggable.Background", "div", null);
25
+ this.background.setType(WidgetTypes.CUSTOM);
26
+ this.background.addClass("WUIDraggableBackground");
27
+
28
+ this.dragDistX = 0;
29
+ this.dragDistY = 0;
30
+
31
+ this.maxX = null;
32
+ this.maxY = null;
33
+
34
+ this.minX = null;
35
+ this.minY = null;
36
+
37
+ this.dragOrientation = orientation;
38
+
39
+ this.target.subscribe({
40
+ event: "mousedown",
41
+ then: (e, _w) => {
42
+ this.startDrag(e as MouseEvent);
43
+ },
44
+ });
45
+
46
+ this.background.subscribe({
47
+ event: "mousemove",
48
+ then: (e, _w) => {
49
+ this.draggingTarget(e as MouseEvent);
50
+ },
51
+ });
52
+
53
+ this.background.subscribe({
54
+ event: "mouseup",
55
+ then: (_e, _w) => {
56
+ this.endDrag();
57
+ },
58
+ });
59
+
60
+ this.background.subscribe({
61
+ event: "mouseout",
62
+ then: (_e, _w) => {
63
+ this.endDrag();
64
+ },
65
+ });
66
+
67
+ this.background.subscribe({
68
+ event: "mouseleave",
69
+ then: (_e, _w) => {
70
+ this.endDrag();
71
+ },
72
+ });
73
+ }
74
+
75
+ private startDrag(e: MouseEvent): void {
76
+ e.preventDefault();
77
+ const mouseX = e.clientX;
78
+ const mouseY = e.clientY;
79
+ this.dragDistX = Math.abs(this.target.getX() - mouseX);
80
+ this.dragDistY = Math.abs(this.target.getY() - mouseY);
81
+ this.dragging = true;
82
+ this.background.setVisible(true);
83
+ this.background.raisteTop();
84
+ }
85
+
86
+ private draggingTarget(e: MouseEvent): void {
87
+ if (!this.dragging) {
88
+ return;
89
+ }
90
+
91
+ e.preventDefault();
92
+
93
+ const mouseX = e.clientX;
94
+ const mouseY = e.clientY;
95
+
96
+ if (this.dragOrientation === "both" || this.dragOrientation === "horizontal") {
97
+ let newX = mouseX - this.dragDistX;
98
+ if (this.maxX != null && newX > this.maxX) {
99
+ newX = this.maxX;
100
+ }
101
+
102
+ if (this.minX != null && newX < this.minX) {
103
+ newX = this.minX;
104
+ }
105
+ this.target.setX(newX);
106
+ }
107
+
108
+ if (this.dragOrientation === "both" || this.dragOrientation === "vertical") {
109
+ let newY = mouseY - this.dragDistY;
110
+ if (this.maxY != null && newY > this.maxY) {
111
+ newY = this.maxY;
112
+ }
113
+
114
+ if (this.minY != null && newY < this.minY) {
115
+ newY = this.minY;
116
+ }
117
+ this.target.setY(newY);
118
+ }
119
+
120
+ this.target.run("drag");
121
+ }
122
+
123
+ private endDrag(): void {
124
+ this.dragging = false;
125
+ this.background.setVisible(false);
126
+ }
127
+
128
+ public setMaxX(x: number | null): void {
129
+ this.maxX = x;
130
+ }
131
+
132
+ public setMaxY(y: number | null): void {
133
+ this.maxY = y;
134
+ }
135
+
136
+ public setMinX(x: number | null): void {
137
+ this.minX = x;
138
+ }
139
+
140
+ public setMinY(y: number | null): void {
141
+ this.minY = y;
142
+ }
143
+ }
package/src/ui/index.ts CHANGED
@@ -7,7 +7,23 @@ import { Label } from "./label.ui";
7
7
  import { Menu } from "./menu.ui";
8
8
  import { Select } from "./select.ui";
9
9
  import { Textbox } from "./textbox.ui";
10
+ import { Tabs } from "./tabs.ui";
10
11
  import { Toolbar } from "./toolbar.ui";
12
+ import { DataGrid } from "./datagrid.ui";
11
13
  import { createWidget } from "./widget.builder.ui";
12
14
 
13
- export { Button, Widget, Dialog, Icon, IconButton, Label, Menu, Select, Textbox, Toolbar, createWidget };
15
+ export {
16
+ Button,
17
+ Widget,
18
+ Dialog,
19
+ Icon,
20
+ IconButton,
21
+ Label,
22
+ Menu,
23
+ Select,
24
+ Tabs,
25
+ Textbox,
26
+ Toolbar,
27
+ DataGrid,
28
+ createWidget,
29
+ };
@@ -0,0 +1,185 @@
1
+ import { OrientationTypes } from "src/types/orientation.type";
2
+ import "./styles/scroll.css";
3
+ import { Widget, WidgetTypes } from "./widget.ui";
4
+ import { Draggable } from "./draggable.ui";
5
+
6
+ const SCROLL_SIZE = 10;
7
+
8
+ type ScrollData = {
9
+ scrollHeight: number;
10
+ areaHeight: number;
11
+ scrollBarHeight: number;
12
+ scrollWidth: number;
13
+ areaWidth: number;
14
+ scrollBarWidth: number;
15
+ scrollWidt: number;
16
+ availablePositionSize: number;
17
+ ratioScroll: number;
18
+ position: number;
19
+ scrollPositionY: number;
20
+ };
21
+
22
+ export class Scroll extends Widget {
23
+ contentArea: Widget;
24
+ orientation: OrientationTypes;
25
+
26
+ drag: Draggable;
27
+
28
+ constructor(id: string, contentArea: Widget, orientation: OrientationTypes = "vertical") {
29
+ super(id, "div", contentArea.getParent());
30
+
31
+ this.contentArea = contentArea;
32
+ this.orientation = orientation;
33
+
34
+ this.setType(WidgetTypes.CUSTOM);
35
+
36
+ this.getBody().style.overflow = "hidden";
37
+ this.getBody().style.position = "absolute";
38
+
39
+ this.addClass("WUIScrollbar");
40
+
41
+ this.drag = new Draggable(this, orientation);
42
+
43
+ this.contentArea.subscribe({
44
+ event: "wheel",
45
+ then: (e, _w) => {
46
+ const wheel = e as WheelEvent;
47
+ this.contentArea.getBody().scrollBy(0, wheel.deltaY);
48
+ this.render();
49
+ },
50
+ });
51
+
52
+ this.subscribe({
53
+ event: "drag",
54
+ then: (_e, _w) => {
55
+ this.updateScrollPositionByScrollbar();
56
+ },
57
+ });
58
+ }
59
+
60
+ private getScrollData(): ScrollData {
61
+ let returnData: ScrollData = {
62
+ scrollHeight: 0,
63
+ areaHeight: 0,
64
+ scrollBarHeight: 0,
65
+ scrollWidth: 0,
66
+ areaWidth: 0,
67
+ scrollBarWidth: 0,
68
+ scrollWidt: 0,
69
+ availablePositionSize: 0,
70
+ ratioScroll: 0,
71
+ position: 0,
72
+ scrollPositionY: 0,
73
+ };
74
+
75
+ if (this.orientation === "vertical") {
76
+ returnData.scrollHeight = this.contentArea.getBody().scrollHeight;
77
+ returnData.areaHeight = this.contentArea.getH();
78
+ returnData.scrollBarHeight =
79
+ returnData.areaHeight * (returnData.areaHeight / returnData.scrollHeight);
80
+ returnData.availablePositionSize =
81
+ returnData.areaHeight - returnData.scrollBarHeight - 1;
82
+ returnData.ratioScroll =
83
+ this.contentArea.getBody().scrollTop /
84
+ (returnData.areaHeight - returnData.scrollBarHeight);
85
+ returnData.position = returnData.availablePositionSize * returnData.ratioScroll;
86
+
87
+ if (returnData.scrollBarHeight >= returnData.areaHeight) {
88
+ returnData.scrollBarHeight = returnData.areaHeight;
89
+ }
90
+ } else if (this.orientation === "horizontal") {
91
+ returnData.scrollWidth = this.contentArea.getBody().scrollWidth;
92
+ returnData.areaWidth = this.contentArea.getW();
93
+ returnData.scrollBarWidth =
94
+ returnData.areaWidth * (returnData.areaWidth / returnData.scrollWidth);
95
+ returnData.availablePositionSize = returnData.areaWidth - returnData.scrollBarWidth - 1;
96
+ returnData.ratioScroll =
97
+ this.contentArea.getBody().scrollLeft /
98
+ (returnData.areaWidth - returnData.scrollBarWidth);
99
+ returnData.position = returnData.availablePositionSize * returnData.ratioScroll;
100
+ returnData.scrollPositionY = this.contentArea.getH() + this.contentArea.getY();
101
+ if (returnData.scrollBarWidth >= returnData.areaWidth) {
102
+ returnData.scrollBarWidth = returnData.areaWidth;
103
+ }
104
+ }
105
+ return returnData;
106
+ }
107
+
108
+ private updateScrollPositionByScrollbar(): void {
109
+ const scrollData = this.getScrollData();
110
+
111
+ if (this.orientation === "vertical") {
112
+ const recorrido = scrollData.scrollHeight - scrollData.areaHeight;
113
+ const maxY = this.drag.maxY ? this.drag.maxY : 1;
114
+ const ratio = (this.getY() - this.contentArea.getY()) / maxY;
115
+ this.contentArea.getBody().scrollTop = recorrido * ratio;
116
+ } else if (this.orientation === "horizontal") {
117
+ const recorrido = scrollData.scrollWidth - scrollData.areaWidth;
118
+ const maxX = this.drag.maxX ? this.drag.maxX : 1;
119
+ const ratio = (this.getX() - this.contentArea.getX()) / maxX;
120
+ this.contentArea.getBody().scrollLeft = recorrido * ratio;
121
+ }
122
+ }
123
+
124
+ public render(): void {
125
+ super.render();
126
+
127
+ const scrollData = this.getScrollData();
128
+
129
+ if (this.orientation === "vertical") {
130
+ if (scrollData.areaHeight < scrollData.scrollHeight) {
131
+ this.setVisible(true);
132
+ } else {
133
+ this.setVisible(false);
134
+ return;
135
+ }
136
+
137
+ this.setX(this.contentArea.getW() - SCROLL_SIZE - 1);
138
+ this.setY(1 + this.contentArea.getY() + scrollData.position);
139
+ this.setH(scrollData.scrollBarHeight);
140
+ this.setW(SCROLL_SIZE);
141
+ this.raisteTop();
142
+
143
+ const minY = 1 + this.contentArea.getY();
144
+ const maxY = this.contentArea.getY() + scrollData.availablePositionSize;
145
+
146
+ this.drag.setMinY(minY);
147
+ this.drag.setMaxY(maxY);
148
+
149
+ if (this.getY() > maxY) {
150
+ this.setY(maxY);
151
+ }
152
+
153
+ if (this.getY() < minY) {
154
+ this.setY(minY);
155
+ }
156
+ } else if (this.orientation === "horizontal") {
157
+ if (scrollData.areaWidth < scrollData.scrollWidth) {
158
+ this.setVisible(true);
159
+ } else {
160
+ this.setVisible(false);
161
+ return;
162
+ }
163
+
164
+ this.setX(1 + this.contentArea.getX() + scrollData.position);
165
+ this.setY(scrollData.scrollPositionY - SCROLL_SIZE - 1);
166
+ this.setW(scrollData.scrollBarWidth);
167
+ this.setH(SCROLL_SIZE);
168
+ this.raisteTop();
169
+
170
+ const minX = 1 + this.contentArea.getX();
171
+ const maxX = this.contentArea.getX() + scrollData.availablePositionSize;
172
+
173
+ this.drag.setMinX(minX);
174
+ this.drag.setMaxX(maxX);
175
+
176
+ if (this.getX() > maxX) {
177
+ this.setX(maxX);
178
+ }
179
+
180
+ if (this.getX() < minX) {
181
+ this.setX(minX);
182
+ }
183
+ }
184
+ }
185
+ }
@@ -0,0 +1,10 @@
1
+ .WUIDataGrid-Header {
2
+ border-bottom: solid 1px var(--palette-primary-text-light);
3
+ }
4
+
5
+ .WUIDataGrid-HeaderLabel {
6
+ border-right: solid 1px var(--palette-primary-text-light);
7
+ /*border-bottom: solid 1px var(--palette-primary-text-light);*/
8
+ padding-left: 5px;
9
+ font-weight: bold;
10
+ }
@@ -0,0 +1,9 @@
1
+ .WUIDraggableBackground {
2
+ background-color: rgba(0, 0, 0, 0.01);
3
+ opacity: 0.1;
4
+ position: absolute;
5
+ left: 0px;
6
+ top: 0px;
7
+ right: 0px;
8
+ bottom: 0px;
9
+ }
@@ -0,0 +1,4 @@
1
+ .WUIScrollbar {
2
+ background-color: var(--palette-action-hover);
3
+ border-radius: 5px;
4
+ }
@@ -0,0 +1,33 @@
1
+ .WUITabControl {
2
+ border-top: none !important;
3
+ border-left: none !important;
4
+ border-right: none !important;
5
+ border-bottom: none !important;
6
+ background-color: var(--palette-background-default);
7
+ box-sizing: border-box;
8
+ font-weight: normal;
9
+ text-align: center;
10
+ cursor: default;
11
+ padding-left: 15px;
12
+ padding-right: 15px;
13
+ border-radius: 0px !important;
14
+ }
15
+
16
+ .WUITabControlActive {
17
+ border-top: none !important;
18
+ border-left: none !important;
19
+ border-right: none !important;
20
+ border-bottom: solid 2px var(--palette-primary-dark) !important;
21
+ background-color: var(--palette-divider);
22
+ box-sizing: border-box;
23
+ font-weight: bold;
24
+ text-align: center;
25
+ cursor: default;
26
+ padding-left: 15px;
27
+ padding-right: 15px;
28
+ border-radius: 0px !important;
29
+ }
30
+
31
+ .WUITabContainer {
32
+ border-top: solid 1px var(--palette-divider);
33
+ }
@@ -0,0 +1,131 @@
1
+ import "./styles/tabs.css";
2
+
3
+ import { OrientationTypes } from "src/types/orientation.type";
4
+ import { Widget, WidgetAlignTypes, WidgetTypes } from "./widget.ui";
5
+ import { Toolbar } from "./toolbar.ui";
6
+ import { Label } from "./label.ui";
7
+ import { IconButton } from "./IconButton.ui";
8
+
9
+ const TAB_HEADER_HEIGHT = 40;
10
+
11
+ export type TabItem = {
12
+ title: string;
13
+ content: Widget;
14
+ };
15
+
16
+ class TabControl extends Label {
17
+ constructor(id: string, parent: Widget | null = null, text: string) {
18
+ super(id, "span", parent);
19
+ this.setText(text);
20
+ this.addClass("WUITabControl");
21
+ this.getBody().style.lineHeight = TAB_HEADER_HEIGHT + "px";
22
+ }
23
+ }
24
+ export class Tabs extends Widget {
25
+ orientation: OrientationTypes;
26
+
27
+ header: Widget;
28
+ content: Widget;
29
+
30
+ itemControls: Toolbar;
31
+
32
+ items: Map<string, TabItem>;
33
+
34
+ constructor(
35
+ id: string,
36
+ parent: Widget | null = null,
37
+ orientation: OrientationTypes = "horizontal"
38
+ ) {
39
+ super(id, "div", parent);
40
+ this.orientation = orientation;
41
+
42
+ this.header = new Widget(id + ".header", "div");
43
+ this.header.setType(WidgetTypes.FILL);
44
+ this.header.setFixedSize(TAB_HEADER_HEIGHT);
45
+
46
+ this.content = new Widget(id + ".content", "div");
47
+ this.content.setType(WidgetTypes.FILL);
48
+ this.content.addClass("WUITabContainer");
49
+
50
+ this.setType(WidgetTypes.FILL);
51
+
52
+ if (this.orientation === "horizontal") {
53
+ this.setAlign(WidgetAlignTypes.VERTICAL);
54
+ } else {
55
+ this.setAlign(WidgetAlignTypes.HORIZONTAL);
56
+ }
57
+
58
+ this.addChild(this.header);
59
+ this.addChild(this.content);
60
+
61
+ this.items = new Map<string, TabItem>();
62
+
63
+ this.itemControls = new Toolbar(id + ".itemControls", this.header);
64
+ }
65
+
66
+ public setOrientation(orientation: OrientationTypes) {
67
+ this.orientation = orientation;
68
+ }
69
+
70
+ public addTab(id: string, title: string, content: Widget) {
71
+ this.items.set(id, { title, content });
72
+
73
+ const itemControl = new TabControl(id + ".itemControl", null, title);
74
+ //itemControl.setW(100);
75
+ itemControl.setH(TAB_HEADER_HEIGHT);
76
+
77
+ itemControl.subscribe({
78
+ event: "click",
79
+ then: (_e, _w) => {
80
+ this.setTab(id);
81
+ },
82
+ });
83
+
84
+ this.itemControls.addItem(id, itemControl);
85
+ }
86
+
87
+ public addIconTab(id: string, icon: string, content: Widget) {
88
+ this.items.set(id, { title: icon, content });
89
+
90
+ const itemControl = new IconButton(id + ".itemControl", icon);
91
+ itemControl.setW(40);
92
+ itemControl.setH(TAB_HEADER_HEIGHT);
93
+
94
+ itemControl.subscribe({
95
+ event: "click",
96
+ then: (_e, _w) => {
97
+ this.setTab(id);
98
+ },
99
+ });
100
+
101
+ this.itemControls.addItem(id, itemControl);
102
+ }
103
+
104
+ public setTab(id: string) {
105
+ this.content.removeAllChilds();
106
+ const actualTab = this.items.get(id);
107
+
108
+ for (const itemId of this.items.keys()) {
109
+ if (itemId != id) {
110
+ this.items.get(itemId)?.content.setVisible(false);
111
+ const ctrlTab = window.w.get(itemId + ".itemControl");
112
+ if (ctrlTab) {
113
+ ctrlTab.deleteClass("WUITabControlActive");
114
+ ctrlTab.addClass("WUITabControl");
115
+ }
116
+ } else {
117
+ const ctrlTab = window.w.get(itemId + ".itemControl");
118
+ if (ctrlTab) {
119
+ ctrlTab.addClass("WUITabControlActive");
120
+ }
121
+ }
122
+ }
123
+
124
+ if (actualTab) {
125
+ this.items.get(id)?.content.setVisible(true);
126
+ this.content.addChild(actualTab.content);
127
+ }
128
+
129
+ this.render();
130
+ }
131
+ }
@@ -1,13 +1,13 @@
1
1
  import { IWidget } from "src/interfaces/widget.interface";
2
2
  import { Widget, WidgetTypes } from "./widget.ui";
3
3
  import { IconButton } from "./IconButton.ui";
4
+ import { OrientationTypes } from "src/types/orientation.type";
4
5
 
5
- export type ToolbarOrientationTypes = "horizontal" | "vertical";
6
6
  const TOOLBAR_SIZE = 40;
7
7
  const TOOLBAR_BUTTON_SIZE = 40;
8
8
 
9
9
  export class Toolbar extends Widget {
10
- orientation: ToolbarOrientationTypes;
10
+ orientation: OrientationTypes;
11
11
  items: Map<string, IWidget>;
12
12
  size: number; //Indica el alto o ancho de la toolbar.
13
13
 
@@ -15,7 +15,7 @@ export class Toolbar extends Widget {
15
15
  btnLeft: IconButton;
16
16
  btnRight: IconButton;
17
17
 
18
- constructor(id: string, parent: Widget | null = null, orientationType: ToolbarOrientationTypes = "horizontal") {
18
+ constructor(id: string, parent: Widget | null = null, orientationType: OrientationTypes = "horizontal") {
19
19
  super(id, "div", parent);
20
20
  this.orientation = orientationType;
21
21
  this.size = TOOLBAR_SIZE;
@@ -86,7 +86,7 @@ export class Toolbar extends Widget {
86
86
  * @param {ToolbarOrientationTypes} orientationType - the type of orientation to set
87
87
  * @return {void}
88
88
  */
89
- public setOrientation(orientationType: ToolbarOrientationTypes, size: number = TOOLBAR_SIZE): void {
89
+ public setOrientation(orientationType: OrientationTypes, size: number = TOOLBAR_SIZE): void {
90
90
  this.orientation = orientationType;
91
91
  this.size = size;
92
92
  }
@@ -113,6 +113,30 @@ export class Widget implements IWidget {
113
113
  });
114
114
  });
115
115
 
116
+ this.body.addEventListener("wheel", (e) => {
117
+ this.subscribers.forEach((callback) => {
118
+ if (callback.event == "wheel") {
119
+ callback.then(e, this);
120
+ }
121
+ });
122
+ });
123
+
124
+ this.body.addEventListener("mouseout", (e) => {
125
+ this.subscribers.forEach((callback) => {
126
+ if (callback.event == "mouseout") {
127
+ callback.then(e, this);
128
+ }
129
+ });
130
+ });
131
+
132
+ this.body.addEventListener("mouseleave", (e) => {
133
+ this.subscribers.forEach((callback) => {
134
+ if (callback.event == "mouseleave") {
135
+ callback.then(e, this);
136
+ }
137
+ });
138
+ });
139
+
116
140
  this.init();
117
141
 
118
142
  this.getMaxZIndex();
@@ -120,8 +144,18 @@ export class Widget implements IWidget {
120
144
  window.w.set(this.id, this);
121
145
  }
122
146
 
147
+ public run(eventId: WUIEvent): void {
148
+ this.subscribers.forEach((callback) => {
149
+ if (callback.event == eventId) {
150
+ callback.then(new Event(eventId), this);
151
+ }
152
+ });
153
+ }
154
+
123
155
  public subscribe(cb: WUICallback) {
124
- const randomId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
156
+ const randomId =
157
+ Math.random().toString(36).substring(2, 15) +
158
+ Math.random().toString(36).substring(2, 15);
125
159
 
126
160
  this.subscribers.set(`${randomId}.${cb.event}`, cb);
127
161
  }