x4js 2.1.1 → 2.2.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/package.json +9 -13
- package/src/components/base.scss +66 -2
- package/src/components/boxes/boxes.module.scss +3 -3
- package/src/components/button/button.module.scss +1 -1
- package/src/components/button/button.ts +4 -4
- package/src/components/calendar/calendar.module.scss +3 -3
- package/src/components/checkbox/checkbox.module.scss +1 -1
- package/src/components/combobox/combobox.module.scss +6 -6
- package/src/components/dialog/dialog.module.scss +4 -2
- package/src/components/form/form.module.scss +2 -2
- package/src/components/gridview/folder-open.svg +1 -0
- package/src/components/gridview/gridview.module.scss +14 -0
- package/src/components/gridview/gridview.ts +55 -15
- package/src/components/icon/icon.module.scss +1 -1
- package/src/components/label/label.module.scss +3 -2
- package/src/components/listbox/listbox.module.scss +2 -2
- package/src/components/menu/menu.module.scss +3 -3
- package/src/components/messages/messages.module.scss +54 -0
- package/src/components/messages/messages.ts +69 -3
- package/src/components/messages/spinner.svg +1 -0
- package/src/components/notification/notification.module.scss +1 -1
- package/src/components/panel/panel.module.scss +6 -1
- package/src/components/shared.scss +12 -82
- package/src/components/sizers/sizer.module.scss +23 -1
- package/src/components/sizers/sizer.ts +36 -12
- package/src/components/tabs/tabs.module.scss +21 -0
- package/src/components/tabs/tabs.ts +10 -5
- package/src/components/textarea/textarea.module.scss +1 -1
- package/src/components/textedit/textedit.module.scss +5 -5
- package/src/components/tooltips/tooltips.scss +1 -1
- package/src/components/treeview/treeview.module.scss +1 -1
- package/src/components/viewport/viewport.module.scss +1 -1
- package/src/core/core_application.ts +1 -1
- package/src/core/core_data.ts +20 -7
- package/src/x4.d.ts +10 -0
- package/src/x4.scss +3 -3
|
@@ -2,21 +2,23 @@
|
|
|
2
2
|
// :: MESSAGEBOX ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
3
3
|
|
|
4
4
|
import { _tr } from '../../core/core_i18n';
|
|
5
|
-
import { asap, class_ns, UnsafeHtml } from '../../core/core_tools';
|
|
5
|
+
import { asap, class_ns, unsafeHtml, UnsafeHtml } from '../../core/core_tools';
|
|
6
6
|
|
|
7
7
|
import { HBox, VBox } from '../boxes/boxes';
|
|
8
8
|
import { Icon } from '../icon/icon';
|
|
9
|
-
import { Label } from '../label/label';
|
|
9
|
+
import { Label, SimpleText } from '../label/label';
|
|
10
10
|
import { Dialog, DialogProps } from "../dialog/dialog"
|
|
11
11
|
import { Form } from '../form/form';
|
|
12
12
|
import { BtnGroupItem } from '../btngroup/btngroup';
|
|
13
13
|
import { Input } from '../input/input';
|
|
14
|
+
import { Component } from '../../core/component';
|
|
15
|
+
import { Progress } from '../components.js';
|
|
14
16
|
|
|
15
17
|
import "./messages.module.scss";
|
|
16
18
|
|
|
17
19
|
import error_icon from "./circle-exclamation.svg";
|
|
18
20
|
import pen_icon from "./pen-field.svg";
|
|
19
|
-
import
|
|
21
|
+
import spinner from "./spinner.svg"
|
|
20
22
|
|
|
21
23
|
export interface MessageBoxProps extends DialogProps {
|
|
22
24
|
message: string;
|
|
@@ -235,3 +237,67 @@ export class PromptBox extends Dialog<DialogProps>
|
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
239
|
|
|
240
|
+
@class_ns( "x4" )
|
|
241
|
+
export class ProgressionBox extends Dialog {
|
|
242
|
+
|
|
243
|
+
#has_errors = false;
|
|
244
|
+
|
|
245
|
+
constructor( title: string ) {
|
|
246
|
+
super( {
|
|
247
|
+
modal: true,
|
|
248
|
+
title: null,
|
|
249
|
+
sizable: true,
|
|
250
|
+
movable: true,
|
|
251
|
+
form: new Form( {
|
|
252
|
+
content: [
|
|
253
|
+
new HBox( {
|
|
254
|
+
content: [
|
|
255
|
+
new Icon( { iconId: spinner }),
|
|
256
|
+
new VBox( { flex: 1, cls: "right", content: [
|
|
257
|
+
new SimpleText( { id: "title", text: title } ),
|
|
258
|
+
new Progress( { id:"prog", min: 0, max: 100, value: 0 } ),
|
|
259
|
+
new VBox( { id: "sub-text" } ),
|
|
260
|
+
]})
|
|
261
|
+
]
|
|
262
|
+
}),
|
|
263
|
+
]
|
|
264
|
+
}),
|
|
265
|
+
buttons: [ "ok.outline.default" ]
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
this.query("#btnbar").show( false );
|
|
269
|
+
|
|
270
|
+
this.on("btnclick", ( ) => this.show( false ) );
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
addText( text: string | UnsafeHtml, perc: number ) {
|
|
274
|
+
this.query<Label>( "#sub-text").appendContent( new SimpleText( { text } ) );
|
|
275
|
+
this.query<Progress>( "#prog").setValue( perc );
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
addError( text: string | UnsafeHtml, perc: number ) {
|
|
279
|
+
this.query<Label>( "#sub-text").appendContent( new SimpleText( { cls:"error", text } ) );
|
|
280
|
+
this.query<Progress>( "#prog").setValue( perc );
|
|
281
|
+
|
|
282
|
+
this.#has_errors = true;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
setText( text: string | UnsafeHtml, perc: number ) {
|
|
286
|
+
this.query<Label>( "#sub-text").setContent( new SimpleText( { text } ) );
|
|
287
|
+
this.query<Progress>( "#prog").setValue( perc );
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
clear( ) {
|
|
291
|
+
this.#has_errors = true;
|
|
292
|
+
this.query<Label>( "#sub-text").clearContent( );
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
done( ) {
|
|
296
|
+
if( this.#has_errors ) {
|
|
297
|
+
this.query("#btnbar").show( true );
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
this.setTimeout( "close", 5000, ( ) => { this.show(false);} );
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Pro 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2026 Fonticons, Inc.--><path d="M352 96C352 78.3 337.7 64 320 64C302.3 64 288 78.3 288 96C288 113.7 302.3 128 320 128C337.7 128 352 113.7 352 96zM352 544C352 526.3 337.7 512 320 512C302.3 512 288 526.3 288 544C288 561.7 302.3 576 320 576C337.7 576 352 561.7 352 544zM512 320C512 337.7 526.3 352 544 352C561.7 352 576 337.7 576 320C576 302.3 561.7 288 544 288C526.3 288 512 302.3 512 320zM96 352C113.7 352 128 337.7 128 320C128 302.3 113.7 288 96 288C78.3 288 64 302.3 64 320C64 337.7 78.3 352 96 352zM139 501C146.9 509.8 159 513.4 170.5 510.6C181.9 507.7 190.9 498.7 193.8 487.3C196.6 475.8 193 463.7 184.2 455.8C176.3 447 164.2 443.4 152.7 446.2C141.3 449.1 132.3 458.1 129.4 469.5C126.6 481 130.2 493.1 139 501zM455.8 501C463.7 509.8 475.8 513.4 487.3 510.6C498.7 507.7 507.7 498.7 510.6 487.3C513.4 475.8 509.8 463.7 501 455.8C493.1 447 481 443.4 469.5 446.2C458.1 449.1 449.1 458.1 446.2 469.5C443.4 481 447 493.1 455.8 501zM139 139C130.2 146.9 126.6 159 129.4 170.5C132.3 181.9 141.3 190.9 152.7 193.8C164.2 196.6 176.3 193 184.2 184.2C193 176.3 196.6 164.2 193.8 152.7C190.9 141.3 181.9 132.3 170.5 129.4C159 126.6 146.9 130.2 139 139z"/></svg>
|
|
@@ -14,25 +14,25 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
%box {
|
|
18
18
|
position: relative;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
@extend
|
|
21
|
+
%hbox {
|
|
22
|
+
@extend %box;
|
|
23
23
|
display: flex;
|
|
24
24
|
flex-direction: row;
|
|
25
25
|
align-items: center;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
@extend
|
|
28
|
+
%vbox {
|
|
29
|
+
@extend %box;
|
|
30
30
|
display: flex;
|
|
31
31
|
flex-direction: column;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
%fit {
|
|
36
36
|
position: absolute;
|
|
37
37
|
left: 0;
|
|
38
38
|
top: 0;
|
|
@@ -40,16 +40,7 @@
|
|
|
40
40
|
bottom: 0;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
.rel-fit {
|
|
45
|
-
position: relative;
|
|
46
|
-
left: 0;
|
|
47
|
-
top: 0;
|
|
48
|
-
right: 0;
|
|
49
|
-
bottom: 0;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.flex {
|
|
43
|
+
%flex {
|
|
53
44
|
flex-grow: 1;
|
|
54
45
|
flex-shrink: 0;
|
|
55
46
|
flex-basis: 0;
|
|
@@ -59,83 +50,22 @@
|
|
|
59
50
|
|
|
60
51
|
// from tailwind
|
|
61
52
|
|
|
62
|
-
|
|
53
|
+
%shadow-sm {
|
|
63
54
|
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
64
55
|
}
|
|
65
56
|
|
|
66
|
-
|
|
57
|
+
%shadow-md {
|
|
67
58
|
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
68
59
|
}
|
|
69
60
|
|
|
70
|
-
|
|
61
|
+
%shadow-lg {
|
|
71
62
|
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
72
63
|
}
|
|
73
64
|
|
|
74
|
-
|
|
65
|
+
%shadow-xl {
|
|
75
66
|
box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
|
76
67
|
}
|
|
77
68
|
|
|
78
|
-
|
|
69
|
+
%shadow-xxl {
|
|
79
70
|
box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.3), 0 8px 10px -6px rgb(0 0 0 / 0.3);
|
|
80
71
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
@keyframes rotating {
|
|
84
|
-
from {
|
|
85
|
-
transform: rotate(0deg);
|
|
86
|
-
}
|
|
87
|
-
to {
|
|
88
|
-
transform: rotate(360deg);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
@keyframes shaking {
|
|
93
|
-
0% {
|
|
94
|
-
transform: rotate(-15deg)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
4% {
|
|
98
|
-
transform: rotate(15deg)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
8%,24% {
|
|
102
|
-
transform: rotate(-18deg)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
12%,28% {
|
|
106
|
-
transform: rotate(18deg)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
16% {
|
|
110
|
-
transform: rotate(-22deg)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
20% {
|
|
114
|
-
transform: rotate(22deg)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
32% {
|
|
118
|
-
transform: rotate(-12deg)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
36% {
|
|
122
|
-
transform: rotate(12deg)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
40% {
|
|
126
|
-
transform: rotate(0deg)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
.x4rotate {
|
|
132
|
-
animation: rotating 2s linear infinite;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
.x4shake {
|
|
136
|
-
animation-name: shaking;
|
|
137
|
-
animation-duration: 5s;
|
|
138
|
-
animation-iteration-count: infinite;
|
|
139
|
-
animation-timing-function: linear;
|
|
140
|
-
animation-direction: reverse;
|
|
141
|
-
}
|
|
@@ -26,6 +26,22 @@
|
|
|
26
26
|
cursor: ns-resize;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
&.vsize,
|
|
30
|
+
&.hsize {
|
|
31
|
+
position: relative;
|
|
32
|
+
align-self: stretch;
|
|
33
|
+
min-width: 4px;
|
|
34
|
+
min-height: 4px;
|
|
35
|
+
|
|
36
|
+
&:hover {
|
|
37
|
+
background-color: var( --border );
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.hsize {
|
|
42
|
+
cursor: ew-resize;
|
|
43
|
+
}
|
|
44
|
+
|
|
29
45
|
&.top {
|
|
30
46
|
@include horz;
|
|
31
47
|
top: 0;
|
|
@@ -87,4 +103,10 @@
|
|
|
87
103
|
bottom: 0;
|
|
88
104
|
cursor: nw-resize;
|
|
89
105
|
}
|
|
90
|
-
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.x4hbox {
|
|
109
|
+
&>.x4csizer {
|
|
110
|
+
cursor: ew-resize;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -33,7 +33,7 @@ interface CSizerEvent extends ComponentEvents {
|
|
|
33
33
|
stop: ComponentEvent;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
type SizerType = "left" | "top" | "right" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right" ;
|
|
36
|
+
type SizerType = "left" | "top" | "right" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "hsize" | "vsize";
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
*
|
|
@@ -52,22 +52,28 @@ export class CSizer extends Component<ComponentProps,CSizerEvent> {
|
|
|
52
52
|
|
|
53
53
|
this._type = type;
|
|
54
54
|
this.addClass( type );
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
this.addDOMEvent( "pointerdown", ( e: PointerEvent ) => {
|
|
57
57
|
this.setCapture( e.pointerId );
|
|
58
|
-
|
|
58
|
+
|
|
59
|
+
let targ = target;
|
|
60
|
+
if( !targ && (type=='hsize' || type=='vsize') ) {
|
|
61
|
+
targ = this.nextElement( );
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this._ref = targ ?? componentFromDOM( this.dom.parentElement );
|
|
59
65
|
|
|
60
66
|
this._delta = {x:0,y:0};
|
|
61
67
|
const rc = this._ref.getBoundingRect();
|
|
62
68
|
|
|
63
|
-
if( this._type.includes("left") ) {
|
|
69
|
+
if( this._type=="hsize" || this._type.includes("left") ) {
|
|
64
70
|
this._delta.x = e.pageX-rc.left;
|
|
65
71
|
}
|
|
66
72
|
else {
|
|
67
73
|
this._delta.x = e.pageX-(rc.left+rc.width);
|
|
68
74
|
}
|
|
69
75
|
|
|
70
|
-
if( this._type.includes("top") ) {
|
|
76
|
+
if( this._type=="vsize" || this._type.includes("top") ) {
|
|
71
77
|
this._delta.y = e.pageY-rc.top;
|
|
72
78
|
}
|
|
73
79
|
else {
|
|
@@ -104,21 +110,25 @@ export class CSizer extends Component<ComponentProps,CSizerEvent> {
|
|
|
104
110
|
nr.height = (rc.top+rc.height)-pt.y;
|
|
105
111
|
horz = false;
|
|
106
112
|
}
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
else if( this._type=="vsize" ) {
|
|
114
|
+
nr.height = (rc.top+rc.height)-pt.y;
|
|
115
|
+
horz = false;
|
|
116
|
+
}
|
|
117
|
+
else if( this._type.includes("bottom") ) {
|
|
109
118
|
//nr.top = rc.top;
|
|
110
119
|
nr.height = (pt.y-rc.top);
|
|
111
120
|
horz = false;
|
|
112
121
|
}
|
|
113
|
-
|
|
114
|
-
if( this._type.includes("left") ) {
|
|
122
|
+
else if( this._type.includes("left") ) {
|
|
115
123
|
nr.left = pt.x;
|
|
116
124
|
nr.width = ((rc.left+rc.width)-pt.x);
|
|
117
125
|
}
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
else if( this._type=="hsize" ) {
|
|
127
|
+
nr.width = ((rc.left+rc.width)-pt.x);
|
|
128
|
+
}
|
|
129
|
+
else if( this._type.includes("right") ) {
|
|
120
130
|
nr.width = (pt.x-rc.left);
|
|
121
|
-
|
|
131
|
+
}
|
|
122
132
|
|
|
123
133
|
this._ref.setStyle( nr );
|
|
124
134
|
//this._ref.setStyleValue( "flexGrow", 0 );
|
|
@@ -129,4 +139,18 @@ export class CSizer extends Component<ComponentProps,CSizerEvent> {
|
|
|
129
139
|
e.preventDefault( );
|
|
130
140
|
e.stopPropagation( );
|
|
131
141
|
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@class_ns( "x4" )
|
|
145
|
+
export class HSizer extends CSizer {
|
|
146
|
+
constructor( ) {
|
|
147
|
+
super( "hsize" );
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@class_ns( "x4" )
|
|
152
|
+
export class VSizer extends CSizer {
|
|
153
|
+
constructor( ) {
|
|
154
|
+
super( "vsize" );
|
|
155
|
+
}
|
|
132
156
|
}
|
|
@@ -6,7 +6,14 @@
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
.x4tabs {
|
|
9
|
+
display: grid;
|
|
10
|
+
grid-template-rows: auto 1fr;
|
|
11
|
+
|
|
12
|
+
|
|
9
13
|
.x4ctablist {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: row;
|
|
16
|
+
|
|
10
17
|
gap: 4px;
|
|
11
18
|
padding: 5px 5px 0 5px;
|
|
12
19
|
|
|
@@ -34,9 +41,23 @@
|
|
|
34
41
|
//color: var( --color-60 );
|
|
35
42
|
//}
|
|
36
43
|
}
|
|
44
|
+
}
|
|
37
45
|
|
|
46
|
+
&.vertical {
|
|
47
|
+
display: grid;
|
|
48
|
+
grid-template-rows: unset;
|
|
49
|
+
grid-template-columns: auto 1fr;
|
|
50
|
+
|
|
51
|
+
.x4ctablist {
|
|
52
|
+
align-items: start;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
border-top: 1px solid var(--border);
|
|
55
|
+
border-bottom: 1px solid var(--border);
|
|
56
|
+
border-left: 1px solid var(--border);
|
|
57
|
+
}
|
|
38
58
|
}
|
|
39
59
|
|
|
60
|
+
|
|
40
61
|
&> .body {
|
|
41
62
|
padding: 8px;
|
|
42
63
|
border: 1px solid var( --border );
|
|
@@ -17,7 +17,7 @@ import { Component, ComponentEvents, ComponentProps, EvClick } from '../../core/
|
|
|
17
17
|
import { CoreEvent } from '../../core/core_events';
|
|
18
18
|
|
|
19
19
|
import { Button, ButtonProps } from '../button/button';
|
|
20
|
-
import { HBox, VBox, StackBox } from '../boxes/boxes';
|
|
20
|
+
import { HBox, VBox, StackBox, Box } from '../boxes/boxes';
|
|
21
21
|
|
|
22
22
|
import "./tabs.module.scss"
|
|
23
23
|
import { class_ns } from '../../core/core_tools';
|
|
@@ -26,12 +26,13 @@ import { class_ns } from '../../core/core_tools';
|
|
|
26
26
|
*
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
+
type callback = ( ) => Component;
|
|
29
30
|
|
|
30
31
|
export interface TabItem {
|
|
31
32
|
name: string;
|
|
32
33
|
title: string;
|
|
33
34
|
icon?: string;
|
|
34
|
-
content: Component;
|
|
35
|
+
content: Component | callback;
|
|
35
36
|
cls?: string; // button class
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -64,6 +65,7 @@ interface TablistClickEvent extends CoreEvent {
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
interface TablistProps extends ComponentProps {
|
|
68
|
+
vertical?: boolean;
|
|
67
69
|
click: ( ev: TablistClickEvent ) => void;
|
|
68
70
|
}
|
|
69
71
|
|
|
@@ -133,7 +135,8 @@ class CTabList extends HBox<TablistProps,TablistEvents> {
|
|
|
133
135
|
|
|
134
136
|
interface TabsProps extends Omit<ComponentProps,"content"> {
|
|
135
137
|
default: string;
|
|
136
|
-
items: TabItem[]
|
|
138
|
+
items: TabItem[];
|
|
139
|
+
vertical?: boolean;
|
|
137
140
|
}
|
|
138
141
|
|
|
139
142
|
/**
|
|
@@ -141,7 +144,7 @@ interface TabsProps extends Omit<ComponentProps,"content"> {
|
|
|
141
144
|
*/
|
|
142
145
|
|
|
143
146
|
@class_ns( "x4" )
|
|
144
|
-
export class Tabs extends
|
|
147
|
+
export class Tabs extends Box<TabsProps> {
|
|
145
148
|
|
|
146
149
|
private _list: CTabList;
|
|
147
150
|
private _stack: StackBox;
|
|
@@ -150,6 +153,8 @@ export class Tabs extends VBox<TabsProps> {
|
|
|
150
153
|
constructor( props: TabsProps ) {
|
|
151
154
|
super( props );
|
|
152
155
|
|
|
156
|
+
this.setClass( "vertical", props.vertical );
|
|
157
|
+
|
|
153
158
|
const pages = props.items?.map( x => {
|
|
154
159
|
return {
|
|
155
160
|
name: x.name,
|
|
@@ -160,7 +165,7 @@ export class Tabs extends VBox<TabsProps> {
|
|
|
160
165
|
this.setContent( [
|
|
161
166
|
this._list = new CTabList( {
|
|
162
167
|
click: ( ev ) => this._onclick( ev ) },
|
|
163
|
-
props.items
|
|
168
|
+
props.items
|
|
164
169
|
),
|
|
165
170
|
this._stack = new StackBox( {
|
|
166
171
|
cls: "body x4flex",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
.x4textedit {
|
|
32
|
-
@extend
|
|
32
|
+
@extend %hbox;
|
|
33
33
|
margin: 5px;
|
|
34
34
|
gap: 6px;
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
justify-content: end;
|
|
39
39
|
|
|
40
40
|
&> .x4label {
|
|
41
|
-
@extend
|
|
41
|
+
@extend %hbox;
|
|
42
42
|
height: 100%;
|
|
43
43
|
padding: 0;
|
|
44
44
|
font-weight: 500;
|
|
@@ -51,12 +51,12 @@
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
&> #edit {
|
|
54
|
-
@extend
|
|
55
|
-
@extend
|
|
54
|
+
@extend %hbox;
|
|
55
|
+
@extend %flex;
|
|
56
56
|
border-bottom: 1px solid var( --textedit-border );
|
|
57
57
|
|
|
58
58
|
.x4input {
|
|
59
|
-
@extend
|
|
59
|
+
@extend %flex;
|
|
60
60
|
outline: none;
|
|
61
61
|
margin: 0;
|
|
62
62
|
}
|
package/src/core/core_data.ts
CHANGED
|
@@ -25,6 +25,7 @@ export type DataFieldValue = string | Date | number | boolean;
|
|
|
25
25
|
|
|
26
26
|
export type ChangeCallback = (type: string, id?: DataRecordID) => void;
|
|
27
27
|
export type CalcCallback = () => string;
|
|
28
|
+
export type SortCallback = ( v1: any, v2: any ) => number;
|
|
28
29
|
|
|
29
30
|
export type FieldType = 'string' | 'int' | 'float' | 'date' | 'bool' | 'array' | 'object' | 'any' | 'calc';
|
|
30
31
|
export type DataIndex = Uint32Array;
|
|
@@ -935,7 +936,8 @@ export class DataStore<T = any> extends EventSource<DataStoreEventMap> {
|
|
|
935
936
|
|
|
936
937
|
interface sort_info {
|
|
937
938
|
fidx: number,
|
|
938
|
-
asc: boolean
|
|
939
|
+
asc: boolean,
|
|
940
|
+
cb: SortCallback,
|
|
939
941
|
}
|
|
940
942
|
|
|
941
943
|
let bads = 0; // unknown fields
|
|
@@ -943,7 +945,7 @@ export class DataStore<T = any> extends EventSource<DataStoreEventMap> {
|
|
|
943
945
|
|
|
944
946
|
// if no fields are given, reset sort by id
|
|
945
947
|
if ( sort===null ) {
|
|
946
|
-
fidxs.push( { fidx: 0, asc: true } );
|
|
948
|
+
fidxs.push( { fidx: 0, asc: true, cb: null } );
|
|
947
949
|
}
|
|
948
950
|
else {
|
|
949
951
|
fidxs = sort.map( (si) => {
|
|
@@ -954,7 +956,7 @@ export class DataStore<T = any> extends EventSource<DataStoreEventMap> {
|
|
|
954
956
|
bads++;
|
|
955
957
|
}
|
|
956
958
|
|
|
957
|
-
return { fidx: fi, asc: si.ascending };
|
|
959
|
+
return { fidx: fi, asc: si.ascending, cb: si.callback };
|
|
958
960
|
});
|
|
959
961
|
}
|
|
960
962
|
|
|
@@ -969,11 +971,17 @@ export class DataStore<T = any> extends EventSource<DataStoreEventMap> {
|
|
|
969
971
|
if( fidxs.length==1 ) {
|
|
970
972
|
|
|
971
973
|
const field = fidxs[0].fidx;
|
|
974
|
+
const cb = fidxs[0].cb;
|
|
972
975
|
|
|
973
976
|
index.sort( ( ia, ib ) => {
|
|
974
977
|
|
|
975
978
|
let va = m.getRaw( field, this.getByIndex(ia) ) ?? '';
|
|
976
979
|
let vb = m.getRaw( field, this.getByIndex(ib) ) ?? '';
|
|
980
|
+
|
|
981
|
+
if( cb ) {
|
|
982
|
+
return cb( va, vb );
|
|
983
|
+
}
|
|
984
|
+
|
|
977
985
|
if (va > vb) { return 1; }
|
|
978
986
|
if (va < vb) { return -1; }
|
|
979
987
|
return 0;
|
|
@@ -987,13 +995,17 @@ export class DataStore<T = any> extends EventSource<DataStoreEventMap> {
|
|
|
987
995
|
else {
|
|
988
996
|
index.sort( ( ia, ib ) => {
|
|
989
997
|
|
|
990
|
-
for(
|
|
991
|
-
|
|
992
|
-
let
|
|
993
|
-
let mul = fidxs[fi].asc ? 1 : -1;
|
|
998
|
+
for( const fi of fidxs ) {
|
|
999
|
+
let fidx = fi.fidx;
|
|
1000
|
+
let mul = fi.asc ? 1 : -1;
|
|
994
1001
|
|
|
995
1002
|
let va = m.getRaw( fidx, this.getByIndex(ia) ) ?? '';
|
|
996
1003
|
let vb = m.getRaw( fidx, this.getByIndex(ib) ) ?? '';
|
|
1004
|
+
|
|
1005
|
+
if( fi.cb ) {
|
|
1006
|
+
return fi.cb( va, vb );
|
|
1007
|
+
}
|
|
1008
|
+
|
|
997
1009
|
if (va > vb) { return mul; }
|
|
998
1010
|
if (va < vb) { return -mul; }
|
|
999
1011
|
}
|
|
@@ -1096,6 +1108,7 @@ export interface SortProp {
|
|
|
1096
1108
|
field: string; //
|
|
1097
1109
|
ascending: boolean; //
|
|
1098
1110
|
numeric?: boolean; // numeric sort
|
|
1111
|
+
callback?: SortCallback;
|
|
1099
1112
|
}
|
|
1100
1113
|
|
|
1101
1114
|
|
package/src/x4.d.ts
ADDED
package/src/x4.scss
CHANGED
|
@@ -14,6 +14,6 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
-
@
|
|
18
|
-
@
|
|
19
|
-
@
|
|
17
|
+
@import "./components/normalize.scss";
|
|
18
|
+
@import "./components/themes.scss";
|
|
19
|
+
@import "./components/base.scss";
|