x4js 2.0.28 → 2.0.30
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/.vscode/launch.json +14 -0
- package/.vscode/settings.json +2 -0
- package/ai-comments.txt +97 -0
- package/demo/assets/house-light.svg +1 -0
- package/demo/assets/radio.svg +4 -0
- package/demo/index.html +12 -0
- package/demo/main.scss +23 -0
- package/demo/main.ts +324 -0
- package/demo/package.json +26 -0
- package/demo/scss.d.ts +4 -0
- package/demo/svg.d.ts +1 -0
- package/demo/tsconfig.json +14 -0
- package/lib/types/x4js.d.ts +0 -2374
- package/package.json +23 -47
- package/prepack.mjs +3 -0
- package/scripts/prepack.mjs +342 -0
- package/src/colors.scss +246 -0
- package/src/components/boxes/boxes.module.scss +1 -1
- package/src/components/boxes/boxes.ts +139 -28
- package/src/components/button/button.ts +80 -33
- package/src/components/combobox/combobox.ts +1 -1
- package/src/components/dialog/dialog.ts +4 -0
- package/src/components/gridview/gridview.ts +104 -6
- package/src/components/icon/icon.ts +42 -14
- package/src/components/input/input.ts +146 -74
- package/src/components/keyboard/keyboard.module.scss +1 -1
- package/src/components/keyboard/keyboard.ts +31 -9
- package/src/components/label/label.module.scss +9 -0
- package/src/components/label/label.ts +10 -6
- package/src/components/link/link.module.scss +44 -0
- package/src/components/link/link.ts +7 -1
- package/src/components/listbox/listbox.module.scss +18 -4
- package/src/components/listbox/listbox.ts +32 -12
- package/src/components/menu/menu.module.scss +14 -2
- package/src/components/menu/menu.ts +1 -1
- package/src/components/messages/messages.ts +13 -5
- package/src/components/panel/panel.module.scss +7 -0
- package/src/components/popup/popup.ts +14 -10
- package/src/components/propgrid/propgrid.ts +1 -1
- package/src/components/shared.scss +4 -0
- package/src/components/spreadsheet/spreadsheet.ts +81 -34
- package/src/components/tabs/tabs.module.scss +1 -0
- package/src/components/textarea/textarea.ts +8 -2
- package/src/components/textedit/textedit.ts +7 -0
- package/src/components/themes.scss +2 -0
- package/src/components/tooltips/tooltips.ts +15 -3
- package/src/core/component.ts +358 -162
- package/src/core/core_application.ts +129 -32
- package/src/core/core_colors.ts +382 -119
- package/src/core/core_data.ts +73 -86
- package/src/core/core_dom.ts +10 -0
- package/src/core/core_dragdrop.ts +32 -7
- package/src/core/core_element.ts +111 -4
- package/src/core/core_events.ts +48 -11
- package/src/core/core_i18n.ts +2 -0
- package/src/core/core_pdf.ts +454 -0
- package/src/core/core_router.ts +64 -5
- package/src/core/core_state.ts +1 -0
- package/src/core/core_styles.ts +11 -12
- package/src/core/core_svg.ts +346 -51
- package/src/core/core_tools.ts +105 -17
- package/src/x4.ts +1 -0
- package/src/x4tsx.d.ts +2 -1
- package/tsconfig.json +11 -0
- package/lib/README.txt +0 -20
- package/lib/cjs/x4.css +0 -1
- package/lib/cjs/x4.js +0 -2
- package/lib/esm/x4.css +0 -1
- package/lib/esm/x4.mjs +0 -2
- package/lib/styles/x4.css +0 -1
|
@@ -121,14 +121,14 @@ export class Keyboard extends HBox<KeyboardProps>
|
|
|
121
121
|
this.hide( );
|
|
122
122
|
|
|
123
123
|
this.addDOMEvent( "mousedown", (e) => {
|
|
124
|
-
this.
|
|
124
|
+
this.handleKeyEvent( e );
|
|
125
125
|
e.preventDefault( );
|
|
126
126
|
e.stopPropagation( );
|
|
127
127
|
});
|
|
128
128
|
|
|
129
129
|
// for rapid people
|
|
130
130
|
this.addDOMEvent( "dblclick", (e) => {
|
|
131
|
-
this.
|
|
131
|
+
this.handleKeyEvent( e );
|
|
132
132
|
e.preventDefault( );
|
|
133
133
|
e.stopPropagation( );
|
|
134
134
|
});
|
|
@@ -148,7 +148,7 @@ export class Keyboard extends HBox<KeyboardProps>
|
|
|
148
148
|
*
|
|
149
149
|
*/
|
|
150
150
|
|
|
151
|
-
private
|
|
151
|
+
private handleKeyEvent( e: UIEvent ) {
|
|
152
152
|
let target = e.target as HTMLElement;
|
|
153
153
|
let key;
|
|
154
154
|
|
|
@@ -165,6 +165,10 @@ export class Keyboard extends HBox<KeyboardProps>
|
|
|
165
165
|
return;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
this._handleKey( key );
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private _handleKey( key: number ) {
|
|
168
172
|
switch( key ) {
|
|
169
173
|
// bk space
|
|
170
174
|
case 2: {
|
|
@@ -326,11 +330,16 @@ export class Keyboard extends HBox<KeyboardProps>
|
|
|
326
330
|
private handleFocus( target: Element, enter: boolean ) {
|
|
327
331
|
|
|
328
332
|
if( enter ) {
|
|
329
|
-
if( target.tagName=='INPUT'
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
333
|
+
if( target.tagName=='INPUT' ) {
|
|
334
|
+
const input = target as HTMLInputElement;
|
|
335
|
+
if( !input.readOnly &&
|
|
336
|
+
input.type!='checkbox' && input.type!='radio' &&
|
|
337
|
+
input.type!='range' && input.type!='file' ) {
|
|
338
|
+
this.input = input;
|
|
339
|
+
this.visible = true;
|
|
340
|
+
this.setTimeout( "vis", 200, this._updateVis );
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
334
343
|
}
|
|
335
344
|
}
|
|
336
345
|
|
|
@@ -430,6 +439,7 @@ export class Keyboard extends HBox<KeyboardProps>
|
|
|
430
439
|
let content = line[i];
|
|
431
440
|
let key;
|
|
432
441
|
let icon = null;
|
|
442
|
+
let repeat = false;
|
|
433
443
|
|
|
434
444
|
if( content.length>2 && content[0]=='{' && content[content.length-1]=='}') {
|
|
435
445
|
|
|
@@ -452,6 +462,7 @@ export class Keyboard extends HBox<KeyboardProps>
|
|
|
452
462
|
|
|
453
463
|
case 2:
|
|
454
464
|
{
|
|
465
|
+
repeat = true;
|
|
455
466
|
content = undefined;
|
|
456
467
|
icon = icon_bksp;
|
|
457
468
|
cls += ' cdel';
|
|
@@ -516,7 +527,18 @@ export class Keyboard extends HBox<KeyboardProps>
|
|
|
516
527
|
key = line[i].charCodeAt(0);
|
|
517
528
|
}
|
|
518
529
|
|
|
519
|
-
let el = new Button( {
|
|
530
|
+
let el = new Button( {
|
|
531
|
+
cls,
|
|
532
|
+
label: content,
|
|
533
|
+
attrs: {'data-key': key},
|
|
534
|
+
icon,
|
|
535
|
+
autorepeat: repeat,
|
|
536
|
+
click: ( e ) => {
|
|
537
|
+
if( e.repeat ) {
|
|
538
|
+
this._handleKey( key )
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
} );
|
|
520
542
|
tl.push( el );
|
|
521
543
|
}
|
|
522
544
|
|
|
@@ -30,16 +30,25 @@
|
|
|
30
30
|
background-color: var( --label-background );
|
|
31
31
|
gap: 0.2em;
|
|
32
32
|
|
|
33
|
+
&.al-right
|
|
33
34
|
&.right {
|
|
34
35
|
text-align: right;
|
|
35
36
|
justify-content: end;
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
&.al-center,
|
|
38
40
|
&.center {
|
|
39
41
|
text-align: center;
|
|
40
42
|
justify-content: center;
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
&.al-right {
|
|
46
|
+
padding-left: 8px;
|
|
47
|
+
#icon {
|
|
48
|
+
order: 2;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
#text {
|
|
44
53
|
&:empty {
|
|
45
54
|
display: none;
|
|
@@ -24,6 +24,7 @@ export interface LabelProps extends ComponentProps {
|
|
|
24
24
|
text?: string | UnsafeHtml;
|
|
25
25
|
icon?: string;
|
|
26
26
|
labelFor?: string;
|
|
27
|
+
align?: "left" | "center" | "right";
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
/**
|
|
@@ -32,29 +33,32 @@ export interface LabelProps extends ComponentProps {
|
|
|
32
33
|
|
|
33
34
|
@class_ns( "x4" )
|
|
34
35
|
export class Label extends Component<LabelProps> {
|
|
35
|
-
#text: Component;
|
|
36
36
|
|
|
37
37
|
constructor( p: LabelProps ) {
|
|
38
38
|
super( { ...p, content: null } );
|
|
39
39
|
|
|
40
40
|
this.setContent( [
|
|
41
41
|
new Icon( { id:"icon", iconId: this.props.icon } ),
|
|
42
|
-
|
|
42
|
+
new Component( { tag: 'span', id: 'text' } )
|
|
43
43
|
] );
|
|
44
44
|
|
|
45
45
|
// small hack for react:
|
|
46
46
|
// p.content may be the text
|
|
47
|
-
|
|
48
|
-
this.setText( text );
|
|
47
|
+
this.setText( this.props.text );
|
|
49
48
|
|
|
50
49
|
if( p.labelFor ) {
|
|
51
50
|
this.setAttribute( "for", p.labelFor );
|
|
52
51
|
}
|
|
52
|
+
|
|
53
|
+
if( p.align ) {
|
|
54
|
+
this.addClass( "al-"+p.align );
|
|
55
|
+
}
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
setText( text: string | UnsafeHtml ) {
|
|
56
|
-
this
|
|
57
|
-
|
|
59
|
+
const lab = this.query<Icon>( "#text" );
|
|
60
|
+
lab.setContent( text );
|
|
61
|
+
lab.setClass( "empty", !text );
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
setIcon( icon: string ) {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ___ ___ __
|
|
3
|
+
* \ \/ / / _
|
|
4
|
+
* \ / /_| |_
|
|
5
|
+
* / \____ _|
|
|
6
|
+
* /__/\__\ |_|
|
|
7
|
+
*
|
|
8
|
+
* @file link.module.scss
|
|
9
|
+
* @author Etienne Cochard
|
|
10
|
+
*
|
|
11
|
+
* @copyright (c) 2026 R-libre ingenierie
|
|
12
|
+
*
|
|
13
|
+
* Use of this source code is governed by an MIT-style license
|
|
14
|
+
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
|
+
**/
|
|
16
|
+
|
|
17
|
+
.x4link {
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
|
|
20
|
+
#text {
|
|
21
|
+
text-decoration: underline;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&[disabled] {
|
|
25
|
+
cursor: not-allowed;
|
|
26
|
+
border-color: var( --border );
|
|
27
|
+
color: var( --listbox-item-color-disabled );
|
|
28
|
+
|
|
29
|
+
&>.body {
|
|
30
|
+
.x4viewport {
|
|
31
|
+
pointer-events: none;
|
|
32
|
+
.x4item {
|
|
33
|
+
&.selected {
|
|
34
|
+
background-color: var( --listbox-item-color-sel-disabled );
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&:focus-within {
|
|
42
|
+
border-color: var( --listbox-border-focus );
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -19,6 +19,7 @@ import { EventCallback } from '../../core/core_events';
|
|
|
19
19
|
import { class_ns, UnsafeHtml } from '../../core/core_tools';
|
|
20
20
|
import { Label } from '../label/label';
|
|
21
21
|
|
|
22
|
+
import "./link.module.scss"
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Link events
|
|
@@ -36,6 +37,7 @@ interface LinkProps extends ComponentProps {
|
|
|
36
37
|
href: string;
|
|
37
38
|
text?: string | UnsafeHtml; // you can also use content for complexe content
|
|
38
39
|
icon?: string;
|
|
40
|
+
align?: "left" | "center" | "right";
|
|
39
41
|
click?: EventCallback<EvClick>;
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -44,12 +46,16 @@ export class Link extends Component<LinkProps,LinkEvents> {
|
|
|
44
46
|
constructor( props: LinkProps ) {
|
|
45
47
|
super( { tag: "a", ...props} );
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
if( props.href ) {
|
|
50
|
+
this.setAttribute( "href", props.href );
|
|
51
|
+
}
|
|
52
|
+
|
|
48
53
|
this.mapPropEvents( props, "click" );
|
|
49
54
|
|
|
50
55
|
this.setContent( new Label( {
|
|
51
56
|
text: props.text,
|
|
52
57
|
icon: props.icon,
|
|
58
|
+
align: props.align,
|
|
53
59
|
} ) );
|
|
54
60
|
|
|
55
61
|
this.addDOMEvent('click', (e) => this._on_click(e));
|
|
@@ -39,16 +39,20 @@
|
|
|
39
39
|
border: 1px solid var( --listbox-border );
|
|
40
40
|
background-color: var( --listbox-background );
|
|
41
41
|
|
|
42
|
-
&:focus-within {
|
|
43
|
-
border-color: var( --listbox-border-focus );
|
|
44
|
-
}
|
|
45
|
-
|
|
46
42
|
outline: none;
|
|
47
43
|
|
|
48
44
|
&>.x4header {
|
|
49
45
|
border-bottom: 1px solid var( --border );
|
|
50
46
|
}
|
|
51
47
|
|
|
48
|
+
&>.title {
|
|
49
|
+
background: white;
|
|
50
|
+
padding: 4px;
|
|
51
|
+
font-weight: bold;
|
|
52
|
+
color: black;
|
|
53
|
+
border-bottom: 1px solid var(--border);
|
|
54
|
+
}
|
|
55
|
+
|
|
52
56
|
&>.body {
|
|
53
57
|
width: 100%;
|
|
54
58
|
flex-basis: 0;
|
|
@@ -94,6 +98,12 @@
|
|
|
94
98
|
}
|
|
95
99
|
}
|
|
96
100
|
|
|
101
|
+
.ref-c1 { width: var( --ref-c1-width); }
|
|
102
|
+
.ref-c2 { width: var( --ref-c2-width); }
|
|
103
|
+
.ref-c3 { width: var( --ref-c3-width); }
|
|
104
|
+
.ref-c4 { width: var( --ref-c4-width); }
|
|
105
|
+
.ref-c5 { width: var( --ref-c5-width); }
|
|
106
|
+
|
|
97
107
|
//&:active{
|
|
98
108
|
//background-color: var( --color-80 );
|
|
99
109
|
//color: var(--color-0);
|
|
@@ -162,4 +172,8 @@
|
|
|
162
172
|
}
|
|
163
173
|
}
|
|
164
174
|
}
|
|
175
|
+
|
|
176
|
+
&:focus-within {
|
|
177
|
+
border-color: var( --listbox-border-focus );
|
|
178
|
+
}
|
|
165
179
|
}
|
|
@@ -56,6 +56,8 @@ export interface ListboxEvents extends ComponentEvents {
|
|
|
56
56
|
export interface ListboxProps extends Omit<ComponentProps,'content'> {
|
|
57
57
|
items?: ListItem[];
|
|
58
58
|
renderer?: ( item: ListItem ) => Component;
|
|
59
|
+
title?: string;
|
|
60
|
+
icon?: string;
|
|
59
61
|
header?: Header;
|
|
60
62
|
footer?: Component,
|
|
61
63
|
checkable?: true,
|
|
@@ -104,6 +106,7 @@ export class Listbox extends Component<ListboxProps,ListboxEvents> {
|
|
|
104
106
|
}
|
|
105
107
|
|
|
106
108
|
this.setContent( [
|
|
109
|
+
(props.title || props.icon) ? new Label( { cls: 'title', text: props.title, icon: props.icon }) : null,
|
|
107
110
|
props.header ? props.header : null,
|
|
108
111
|
scroller,
|
|
109
112
|
props.footer,
|
|
@@ -117,7 +120,7 @@ export class Listbox extends Component<ListboxProps,ListboxEvents> {
|
|
|
117
120
|
} );
|
|
118
121
|
|
|
119
122
|
if( props.items ) {
|
|
120
|
-
this.setItems( props.items );
|
|
123
|
+
this.setItems( props.items, false );
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
126
|
|
|
@@ -191,8 +194,15 @@ export class Listbox extends Component<ListboxProps,ListboxEvents> {
|
|
|
191
194
|
}
|
|
192
195
|
else {
|
|
193
196
|
const selitem = this._itemWithID( this._lastsel );
|
|
194
|
-
|
|
195
|
-
|
|
197
|
+
|
|
198
|
+
let nel;
|
|
199
|
+
if( selitem ) {
|
|
200
|
+
nel = sens==kbNav.next ? selitem.nextElement() : selitem.prevElement();
|
|
201
|
+
nel = next_visible( nel, sens==kbNav.next );
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
nel = sens==kbNav.next ? this._view.firstChild() : this._view.lastChild( );
|
|
205
|
+
}
|
|
196
206
|
|
|
197
207
|
if( nel ) {
|
|
198
208
|
const id = nel.getInternalData( "id" );
|
|
@@ -406,10 +416,12 @@ export class Listbox extends Component<ListboxProps,ListboxEvents> {
|
|
|
406
416
|
this._multisel.clear( );
|
|
407
417
|
}
|
|
408
418
|
|
|
409
|
-
clearSelection( ) {
|
|
419
|
+
clearSelection( fireEvent = true ) {
|
|
410
420
|
if( this._multisel.size ) {
|
|
411
421
|
this._clearSelection( );
|
|
412
|
-
|
|
422
|
+
if( fireEvent ) {
|
|
423
|
+
this.fire( "selectionChange", { selection: [], empty: true } );
|
|
424
|
+
}
|
|
413
425
|
}
|
|
414
426
|
}
|
|
415
427
|
|
|
@@ -425,24 +437,21 @@ export class Listbox extends Component<ListboxProps,ListboxEvents> {
|
|
|
425
437
|
this._view.clearContent( );
|
|
426
438
|
this._items = items ?? [];
|
|
427
439
|
|
|
428
|
-
let
|
|
440
|
+
let update_sel = false;
|
|
429
441
|
|
|
430
442
|
if( this._items.length ) {
|
|
431
443
|
const content = items.map( x => this.renderItem(x) );
|
|
432
444
|
this._view.setContent( content );
|
|
433
445
|
|
|
434
|
-
if( keepSel ) {
|
|
446
|
+
if( keepSel && oldSel.length>0 ) {
|
|
435
447
|
this.select( oldSel );
|
|
436
448
|
}
|
|
437
|
-
else {
|
|
438
|
-
upsel = true;
|
|
439
|
-
}
|
|
440
449
|
}
|
|
441
450
|
else {
|
|
442
|
-
|
|
451
|
+
update_sel = oldSel.length>0;
|
|
443
452
|
}
|
|
444
453
|
|
|
445
|
-
if(
|
|
454
|
+
if( update_sel ) {
|
|
446
455
|
this.setTimeout( "sel", 100, ( ) => {
|
|
447
456
|
this.fire( "selectionChange", { selection: [], empty: true } );
|
|
448
457
|
} );
|
|
@@ -573,4 +582,15 @@ export class Listbox extends Component<ListboxProps,ListboxEvents> {
|
|
|
573
582
|
getSelection( ) {
|
|
574
583
|
return Array.from( this._multisel );
|
|
575
584
|
}
|
|
585
|
+
|
|
586
|
+
ensureSelectionVisible( ) {
|
|
587
|
+
const sels = Array.from( this._multisel.values() );
|
|
588
|
+
if( sels.length) {
|
|
589
|
+
const item = this._itemWithID( sels[0] );
|
|
590
|
+
item?.scrollIntoView( {
|
|
591
|
+
behavior: "instant",
|
|
592
|
+
block: "nearest"
|
|
593
|
+
} )
|
|
594
|
+
}
|
|
595
|
+
}
|
|
576
596
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
@use "../shared.scss";
|
|
18
18
|
|
|
19
19
|
:root {
|
|
20
|
-
--menu-background: var( --background-
|
|
20
|
+
--menu-background: var( --background-ternary );
|
|
21
21
|
--menu-border: var( --border-hover );
|
|
22
22
|
|
|
23
23
|
--menuitem-color: var( --text-ternary );;
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
.x4menu {
|
|
31
|
-
@extend .shadow-
|
|
31
|
+
@extend .shadow-xxl;
|
|
32
32
|
|
|
33
33
|
position: absolute;
|
|
34
34
|
overflow-y: auto;
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
|
|
40
40
|
background-color: var(--menu-background);
|
|
41
41
|
border: 1px solid var(--menu-border);
|
|
42
|
+
border-left: 4px solid var( --accent-background );
|
|
42
43
|
|
|
43
44
|
max-height: calc( 100vh - 32px );
|
|
44
45
|
|
|
@@ -69,6 +70,17 @@
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
&.danger #icon {
|
|
74
|
+
.fa-primary {
|
|
75
|
+
fill: var( --color-danger-a50 );
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.fa-secondary {
|
|
79
|
+
fill: var( --color-danger-a30 );
|
|
80
|
+
opacity: 1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
72
84
|
#text {
|
|
73
85
|
@extend .flex;
|
|
74
86
|
}
|
|
@@ -98,6 +98,11 @@ export class MessageBox extends Dialog<DialogProps>
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
|
|
101
|
+
interface InputOptions {
|
|
102
|
+
password?: boolean;
|
|
103
|
+
trim?: boolean;
|
|
104
|
+
}
|
|
105
|
+
|
|
101
106
|
@class_ns( "x4" )
|
|
102
107
|
export class InputBox extends Dialog<DialogProps>
|
|
103
108
|
{
|
|
@@ -110,7 +115,10 @@ export class InputBox extends Dialog<DialogProps>
|
|
|
110
115
|
return input.getValue( );
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
private static _create( msg: string | UnsafeHtml, value: string, title: string ) {
|
|
118
|
+
private static _create( msg: string | UnsafeHtml, value: string, title: string, options?: InputOptions ) {
|
|
119
|
+
|
|
120
|
+
options = {trim: true, password: false, ...options };
|
|
121
|
+
|
|
114
122
|
const box = new InputBox({
|
|
115
123
|
modal: true,
|
|
116
124
|
title,
|
|
@@ -122,7 +130,7 @@ export class InputBox extends Dialog<DialogProps>
|
|
|
122
130
|
new Icon( { iconId: pen_icon }),
|
|
123
131
|
new VBox( { flex: 1, content: [
|
|
124
132
|
new Label( { text: msg } ),
|
|
125
|
-
new Input( { value, type: "text" } )
|
|
133
|
+
new Input( { value, type: options.password ? "password" : "text", trim: options.trim } )
|
|
126
134
|
]})
|
|
127
135
|
]
|
|
128
136
|
}),
|
|
@@ -138,11 +146,11 @@ export class InputBox extends Dialog<DialogProps>
|
|
|
138
146
|
* idem with promise
|
|
139
147
|
*/
|
|
140
148
|
|
|
141
|
-
static async showAsync( msg: string | UnsafeHtml, value: string, title?: string ) : Promise<string> {
|
|
149
|
+
static async showAsync( msg: string | UnsafeHtml, value: string, title?: string, options?: InputOptions ) : Promise<string> {
|
|
142
150
|
|
|
143
|
-
return new Promise( (resolve,
|
|
151
|
+
return new Promise( (resolve, _reject ) => {
|
|
144
152
|
|
|
145
|
-
const box = this._create( msg, value, title );
|
|
153
|
+
const box = this._create( msg, value, title, options );
|
|
146
154
|
|
|
147
155
|
box.on( "btnclick", ( ev ) => {
|
|
148
156
|
asap( ( ) => {
|
|
@@ -21,6 +21,7 @@ import { Rect, Point, class_ns, asap } from '../../core/core_tools';
|
|
|
21
21
|
import { Box } from '../boxes/boxes'
|
|
22
22
|
|
|
23
23
|
import "./popup.module.scss"
|
|
24
|
+
import { getGlobalZoom, getScrollbarSize } from '../../core/core_tools.js';
|
|
24
25
|
|
|
25
26
|
export interface PopupEvents extends ComponentEvents {
|
|
26
27
|
closed: ComponentEvent;
|
|
@@ -143,24 +144,27 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
|
|
|
143
144
|
*/
|
|
144
145
|
|
|
145
146
|
displayAt( x: number, y: number ) {
|
|
147
|
+
const zm = getGlobalZoom( );
|
|
148
|
+
|
|
146
149
|
//TODO: check is already visible
|
|
147
150
|
this.setStyle( {
|
|
148
|
-
left: x+"px",
|
|
149
|
-
top: y+"px",
|
|
151
|
+
left: (x/zm)+"px",
|
|
152
|
+
top: (y/zm)+"px",
|
|
150
153
|
})
|
|
151
154
|
|
|
152
155
|
this._do_show( ); // to compute size
|
|
153
156
|
|
|
154
|
-
const rc = this.getBoundingRect( );
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if( rc.right>
|
|
159
|
-
this.setStyleValue( "left",
|
|
157
|
+
const rc = this.getBoundingRect( ).scale( 1/zm );
|
|
158
|
+
const sbw = getScrollbarSize( );
|
|
159
|
+
|
|
160
|
+
const screen_width = window.innerWidth - sbw;
|
|
161
|
+
if( rc.right>screen_width ) {
|
|
162
|
+
this.setStyleValue( "left", screen_width-rc.width );
|
|
160
163
|
}
|
|
161
164
|
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
const screen_height = window.innerHeight - sbw;
|
|
166
|
+
if( rc.bottom>screen_height ) {
|
|
167
|
+
this.setStyleValue( "top", screen_height-rc.height );
|
|
164
168
|
}
|
|
165
169
|
}
|
|
166
170
|
|