x4js 2.0.13 → 2.0.15
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/README.md +5 -0
- package/{lib/src/demo → demo}/main.scss +3 -1
- package/{lib/src/demo/main.tsx → demo/main.ts} +37 -36
- 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/README.txt +5 -0
- package/lib/cjs/x4.css +1 -1
- package/lib/cjs/x4.js +2 -1
- package/lib/esm/x4.css +1 -1
- package/lib/esm/x4.mjs +2 -1
- package/lib/src/components/boxes/boxes.module.scss +17 -0
- package/lib/src/components/boxes/boxes.ts +258 -17
- package/lib/src/components/breadcrumb/breadcrumb.scss +56 -28
- package/lib/src/components/breadcrumb/breadcrumb.ts +93 -84
- package/lib/src/components/btngroup/btngroup.module.scss +12 -0
- package/lib/src/components/btngroup/btngroup.ts +41 -8
- package/lib/src/components/button/button.module.scss +23 -5
- package/lib/src/components/button/button.ts +72 -4
- package/lib/src/components/canvas/canvas.module.scss +25 -0
- package/lib/src/components/canvas/canvas.ts +189 -0
- package/lib/src/components/canvas/canvas_ex.ts +276 -0
- package/lib/src/components/checkbox/checkbox.ts +18 -4
- package/lib/src/components/combobox/combobox.module.scss +24 -15
- package/lib/src/components/combobox/combobox.ts +107 -24
- package/lib/src/components/components.ts +7 -0
- package/lib/src/components/dialog/dialog.module.scss +40 -7
- package/lib/src/components/dialog/dialog.ts +166 -31
- package/lib/src/components/filedrop/cloud-arrow-up.svg +1 -0
- package/lib/src/components/filedrop/filedrop.module.scss +70 -0
- package/lib/src/components/filedrop/filedrop.ts +131 -0
- package/lib/src/components/form/form.module.scss +4 -0
- package/lib/src/components/form/form.ts +137 -6
- package/lib/src/components/gridview/arrow-down-light.svg +1 -0
- package/lib/src/components/gridview/arrow-up-light.svg +1 -0
- package/lib/src/components/gridview/gridview.module.scss +324 -0
- package/lib/src/components/gridview/gridview.ts +1175 -0
- package/lib/src/components/icon/icon.module.scss +2 -1
- package/lib/src/components/icon/icon.ts +4 -3
- package/lib/src/components/image/image.module.scss +8 -1
- package/lib/src/components/image/image.ts +105 -6
- package/lib/src/components/input/input.module.scss +8 -3
- package/lib/src/components/input/input.ts +178 -31
- package/lib/src/components/keyboard/arrow-up.svg +1 -0
- package/lib/src/components/keyboard/delete-left.svg +1 -0
- package/lib/src/components/keyboard/eye-slash.svg +1 -0
- package/lib/src/components/keyboard/keyboard.module.scss +134 -0
- package/lib/src/components/keyboard/keyboard.ts +526 -0
- package/lib/src/components/label/label.module.scss +22 -4
- package/lib/src/components/label/label.ts +33 -0
- package/lib/src/components/link/link.ts +81 -78
- package/lib/src/components/listbox/listbox.module.scss +61 -3
- package/lib/src/components/listbox/listbox.ts +164 -56
- package/lib/src/components/menu/menu.module.scss +10 -1
- package/lib/src/components/menu/menu.ts +6 -3
- package/lib/src/components/messages/messages.module.scss +44 -0
- package/lib/src/components/messages/messages.ts +164 -18
- package/lib/src/components/messages/pen-field.svg +1 -0
- package/lib/src/components/normalize.scss +5 -0
- package/lib/src/components/notification/notification.module.scss +4 -2
- package/lib/src/components/notification/notification.ts +2 -4
- package/lib/src/components/panel/panel.module.scss +12 -0
- package/lib/src/components/popup/popup.module.scss +10 -2
- package/lib/src/components/popup/popup.ts +141 -95
- package/lib/src/components/propgrid/folder-closed.svg +1 -0
- package/lib/src/components/propgrid/folder-open.svg +1 -0
- package/lib/src/components/propgrid/progrid.module.scss +112 -0
- package/lib/src/components/propgrid/propgrid.ts +288 -0
- package/lib/src/components/propgrid/updown.svg +4 -0
- package/lib/src/components/radio/radio.module.scss +147 -0
- package/lib/src/components/radio/radio.svg +4 -0
- package/lib/src/components/radio/radio.ts +142 -0
- package/lib/src/components/select/select.module.scss +9 -0
- package/lib/src/components/select/select.ts +134 -0
- package/lib/src/components/shared.scss +47 -0
- package/lib/src/components/sizers/sizer.ts +10 -2
- package/lib/src/components/slider/slider.module.scss +77 -30
- package/lib/src/components/slider/slider.ts +72 -22
- package/lib/src/components/tabs/tabs.module.scss +1 -2
- package/lib/src/components/tabs/tabs.ts +49 -12
- package/lib/src/components/textarea/textarea.module.scss +6 -2
- package/lib/src/components/textarea/textarea.ts +73 -8
- package/lib/src/components/textedit/textedit.module.scss +3 -1
- package/lib/src/components/textedit/textedit.ts +47 -15
- package/lib/src/components/themes.scss +7 -0
- package/lib/src/components/tickline/tickline.module.scss +26 -0
- package/lib/src/components/tickline/tickline.ts +82 -0
- package/lib/src/components/tooltips/comments-question.svg +1 -0
- package/lib/src/components/tooltips/tooltips.scss +30 -9
- package/lib/src/components/tooltips/tooltips.ts +10 -5
- package/lib/src/components/treeview/treeview.module.scss +129 -60
- package/lib/src/components/treeview/treeview.ts +47 -12
- package/lib/src/components/viewport/viewport.module.scss +7 -0
- package/lib/src/core/component.ts +113 -40
- package/lib/src/core/core_application.ts +223 -2
- package/lib/src/core/core_colors.ts +2 -2
- package/lib/src/{components/grid/datastore.ts → core/core_data.ts} +264 -252
- package/lib/src/core/core_dragdrop.ts +3 -3
- package/lib/src/core/core_element.ts +18 -1
- package/lib/src/core/core_events.ts +28 -0
- package/lib/src/core/core_i18n.ts +19 -3
- package/lib/src/core/core_react.ts +79 -0
- package/lib/src/core/core_router.ts +25 -9
- package/lib/src/core/core_state.ts +62 -0
- package/lib/src/core/core_styles.ts +5 -5
- package/lib/src/core/core_svg.ts +174 -12
- package/lib/src/core/core_tools.ts +305 -87
- package/lib/src/x4tsx.d.ts +25 -0
- package/lib/styles/x4.css +1 -1
- package/lib/types/x4js.d.ts +828 -119
- package/package.json +4 -4
- package/scripts/build.mjs +378 -0
- package/scripts/prepack.mjs +346 -0
- package/src/components/base.scss +25 -0
- package/src/components/boxes/boxes.module.scss +54 -0
- package/src/components/boxes/boxes.ts +370 -0
- package/src/components/breadcrumb/breadcrumb.scss +56 -0
- package/src/components/breadcrumb/breadcrumb.ts +93 -0
- package/src/components/breadcrumb/chevron-right.svg +1 -0
- package/src/components/btngroup/btngroup.module.scss +41 -0
- package/src/components/btngroup/btngroup.ts +153 -0
- package/src/components/button/button.module.scss +173 -0
- package/src/components/button/button.ts +185 -0
- package/src/components/calendar/calendar-check-sharp-light.svg +1 -0
- package/src/components/calendar/calendar.module.scss +163 -0
- package/src/components/calendar/calendar.ts +327 -0
- package/src/components/calendar/chevron-left-sharp-light.svg +1 -0
- package/src/components/calendar/chevron-right-sharp-light.svg +1 -0
- package/src/components/canvas/canvas.module.scss +25 -0
- package/src/components/canvas/canvas.ts +189 -0
- package/src/components/canvas/canvas_ex.ts +276 -0
- package/src/components/checkbox/check.svg +4 -0
- package/src/components/checkbox/checkbox.module.scss +142 -0
- package/src/components/checkbox/checkbox.ts +140 -0
- package/src/components/colorinput/colorinput.module.scss +65 -0
- package/src/components/colorinput/colorinput.ts +91 -0
- package/src/components/colorinput/crosshairs-simple-sharp-light.svg +1 -0
- package/src/components/colorpicker/colorpicker.module.scss +133 -0
- package/src/components/colorpicker/colorpicker.ts +482 -0
- package/src/components/combobox/combobox.module.scss +133 -0
- package/src/components/combobox/combobox.ts +275 -0
- package/src/components/combobox/updown.svg +4 -0
- package/src/components/components.ts +41 -0
- package/src/components/dialog/dialog.module.scss +104 -0
- package/src/components/dialog/dialog.ts +229 -0
- package/src/components/dialog/xmark-sharp-light.svg +1 -0
- package/src/components/filedrop/cloud-arrow-up.svg +1 -0
- package/src/components/filedrop/filedrop.module.scss +70 -0
- package/src/components/filedrop/filedrop.ts +131 -0
- package/src/components/form/form.module.scss +38 -0
- package/src/components/form/form.ts +172 -0
- package/src/components/gridview/arrow-down-light.svg +1 -0
- package/src/components/gridview/arrow-up-light.svg +1 -0
- package/src/components/gridview/gridview.module.scss +324 -0
- package/src/components/gridview/gridview.ts +1175 -0
- package/src/components/header/header.module.scss +40 -0
- package/src/components/header/header.ts +130 -0
- package/src/components/icon/icon.module.scss +31 -0
- package/src/components/icon/icon.ts +137 -0
- package/src/components/image/image.module.scss +28 -0
- package/src/components/image/image.ts +168 -0
- package/src/components/input/input.module.scss +74 -0
- package/src/components/input/input.ts +422 -0
- package/src/components/keyboard/arrow-up.svg +1 -0
- package/src/components/keyboard/delete-left.svg +1 -0
- package/src/components/keyboard/eye-slash.svg +1 -0
- package/src/components/keyboard/keyboard.module.scss +134 -0
- package/src/components/keyboard/keyboard.ts +526 -0
- package/src/components/label/label.module.scss +76 -0
- package/src/components/label/label.ts +97 -0
- package/src/components/link/link.ts +81 -0
- package/src/components/listbox/listbox.module.scss +161 -0
- package/src/components/listbox/listbox.ts +539 -0
- package/src/components/menu/caret-right-solid.svg +1 -0
- package/src/components/menu/menu.module.scss +117 -0
- package/src/components/menu/menu.ts +174 -0
- package/src/components/messages/circle-exclamation.svg +1 -0
- package/src/components/messages/messages.module.scss +92 -0
- package/src/components/messages/messages.ts +215 -0
- package/src/components/messages/pen-field.svg +1 -0
- package/src/components/normalize.scss +391 -0
- package/src/components/notification/circle-check-solid.svg +1 -0
- package/src/components/notification/circle-exclamation-solid.svg +1 -0
- package/src/components/notification/circle-notch-light.svg +1 -0
- package/src/components/notification/notification.module.scss +84 -0
- package/src/components/notification/notification.ts +107 -0
- package/src/components/notification/xmark-sharp-light.svg +1 -0
- package/src/components/panel/panel.module.scss +60 -0
- package/src/components/panel/panel.ts +58 -0
- package/src/components/popup/popup.module.scss +51 -0
- package/src/components/popup/popup.ts +442 -0
- package/src/components/progress/progress.module.scss +57 -0
- package/src/components/progress/progress.ts +44 -0
- package/src/components/propgrid/folder-closed.svg +1 -0
- package/src/components/propgrid/folder-open.svg +1 -0
- package/src/components/propgrid/progrid.module.scss +112 -0
- package/src/components/propgrid/propgrid.ts +288 -0
- package/src/components/propgrid/updown.svg +4 -0
- package/src/components/radio/radio.module.scss +147 -0
- package/src/components/radio/radio.svg +4 -0
- package/src/components/radio/radio.ts +142 -0
- package/src/components/rating/rating.module.scss +23 -0
- package/src/components/rating/rating.ts +131 -0
- package/src/components/rating/star-sharp-light.svg +1 -0
- package/src/components/rating/star-sharp-solid.svg +1 -0
- package/src/components/select/select.module.scss +9 -0
- package/src/components/select/select.ts +134 -0
- package/src/components/shared.scss +137 -0
- package/src/components/sizers/sizer.module.scss +90 -0
- package/src/components/sizers/sizer.ts +132 -0
- package/src/components/slider/slider.module.scss +118 -0
- package/src/components/slider/slider.ts +198 -0
- package/src/components/switch/switch.module.scss +127 -0
- package/src/components/switch/switch.ts +62 -0
- package/src/components/tabs/tabs.module.scss +45 -0
- package/src/components/tabs/tabs.ts +205 -0
- package/src/components/textarea/textarea.module.scss +63 -0
- package/src/components/textarea/textarea.ts +125 -0
- package/src/components/textedit/textedit.module.scss +116 -0
- package/src/components/textedit/textedit.ts +115 -0
- package/src/components/themes.scss +88 -0
- package/src/components/tickline/tickline.module.scss +26 -0
- package/src/components/tickline/tickline.ts +82 -0
- package/src/components/tooltips/circle-info-sharp-light.svg +1 -0
- package/src/components/tooltips/comments-question.svg +1 -0
- package/src/components/tooltips/tooltips.scss +72 -0
- package/src/components/tooltips/tooltips.ts +109 -0
- package/src/components/treeview/chevron-down-light.svg +1 -0
- package/src/components/treeview/treeview.module.scss +185 -0
- package/src/components/treeview/treeview.ts +445 -0
- package/src/components/viewport/viewport.module.scss +32 -0
- package/src/components/viewport/viewport.ts +41 -0
- package/src/core/component.ts +1075 -0
- package/src/core/core_application.ts +265 -0
- package/src/core/core_colors.ts +250 -0
- package/src/core/core_data.ts +1310 -0
- package/src/core/core_dom.ts +471 -0
- package/src/core/core_dragdrop.ts +201 -0
- package/src/core/core_element.ts +115 -0
- package/src/core/core_events.ts +177 -0
- package/src/core/core_i18n.ts +393 -0
- package/src/core/core_react.ts +79 -0
- package/src/core/core_router.ts +237 -0
- package/src/core/core_state.ts +62 -0
- package/src/core/core_styles.ts +214 -0
- package/src/core/core_svg.ts +712 -0
- package/src/core/core_tools.ts +906 -0
- package/src/types/scss.d.ts +4 -0
- package/src/types/svg.d.ts +1 -0
- package/src/types/x4react.d.ts +9 -0
- package/src/x4.scss +19 -0
- package/src/x4tsx.d.ts +25 -0
- package/tsconfig.json +14 -0
- package/lib/src/components/grid/gridview.ts +0 -1108
- package/lib/src/components/grid/memdb.ts +0 -325
- /package/{lib/src/demo → demo}/assets/house-light.svg +0 -0
- /package/{lib/src/demo → demo}/assets/radio.svg +0 -0
- /package/{lib/src/demo → demo}/index.html +0 -0
|
@@ -48,7 +48,6 @@ class SvgLoader {
|
|
|
48
48
|
this.waiters.set( file, [resolve] );
|
|
49
49
|
this._load( file )
|
|
50
50
|
.then( ( data: string ) => {
|
|
51
|
-
console.timeEnd( file );
|
|
52
51
|
this.cache.set( file, data );
|
|
53
52
|
const ww = this.waiters.get( file );
|
|
54
53
|
ww.forEach( cb => cb(data ) );
|
|
@@ -58,7 +57,6 @@ class SvgLoader {
|
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
private async _load( file: string ): Promise<string> {
|
|
61
|
-
console.time( file );
|
|
62
60
|
const res = await fetch( file );
|
|
63
61
|
if( res.ok ) {
|
|
64
62
|
return res.text( );
|
|
@@ -103,6 +101,8 @@ export class Icon extends Component<IconProps> {
|
|
|
103
101
|
*/
|
|
104
102
|
|
|
105
103
|
setIcon( iconId: string ) {
|
|
104
|
+
this.clearContent( );
|
|
105
|
+
|
|
106
106
|
if( iconId ) {
|
|
107
107
|
if( iconId.startsWith('var:') ) {
|
|
108
108
|
do {
|
|
@@ -123,9 +123,10 @@ export class Icon extends Component<IconProps> {
|
|
|
123
123
|
else {
|
|
124
124
|
this.setContent( new Component( { tag: "img", attrs: { src: iconId } } ) );
|
|
125
125
|
}
|
|
126
|
+
|
|
127
|
+
this.removeClass( "empty" );
|
|
126
128
|
}
|
|
127
129
|
else {
|
|
128
|
-
this.clearContent( );
|
|
129
130
|
this.addClass( "empty" );
|
|
130
131
|
}
|
|
131
132
|
}
|
|
@@ -14,8 +14,15 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
+
:root {
|
|
18
|
+
--image-border-drop-hover: var( --accent-background );
|
|
19
|
+
}
|
|
17
20
|
|
|
18
|
-
.
|
|
21
|
+
.x4image {
|
|
19
22
|
position: relative;
|
|
20
23
|
background: none;
|
|
24
|
+
|
|
25
|
+
&.hit {
|
|
26
|
+
border-color: var( --image-border-drop-hover ) !important;
|
|
27
|
+
}
|
|
21
28
|
}
|
|
@@ -14,11 +14,24 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
-
import { class_ns } from '
|
|
18
|
-
import { Component, ComponentProps } from '../../core/component
|
|
17
|
+
import { class_ns } from '../../core/core_tools';
|
|
18
|
+
import { Component, ComponentEvents, ComponentProps } from '../../core/component';
|
|
19
|
+
import { EventCallback, CoreEvent } from '../../core/core_events.js';
|
|
20
|
+
import { dragManager } from '../../core/core_dragdrop.js';
|
|
21
|
+
|
|
22
|
+
import { EvDropChange, FileDialog } from '../filedrop/filedrop';
|
|
23
|
+
import { Menu } from '../menu/menu';
|
|
24
|
+
|
|
25
|
+
|
|
19
26
|
|
|
20
27
|
import "./image.module.scss"
|
|
28
|
+
import { _tr } from '@core/core_i18n.js';
|
|
29
|
+
|
|
21
30
|
|
|
31
|
+
interface ImageEvents extends ComponentEvents {
|
|
32
|
+
change: EvDropChange;
|
|
33
|
+
clear: CoreEvent;
|
|
34
|
+
}
|
|
22
35
|
export interface ImageProps extends ComponentProps {
|
|
23
36
|
src: string;
|
|
24
37
|
fit?: "contain" | "cover" | "fill" | "scale-down";
|
|
@@ -26,6 +39,12 @@ export interface ImageProps extends ComponentProps {
|
|
|
26
39
|
lazy?: boolean;
|
|
27
40
|
alt?: string;
|
|
28
41
|
draggable?: boolean;
|
|
42
|
+
|
|
43
|
+
candrop?: boolean;
|
|
44
|
+
accept?: string; // ex: 'image/*'
|
|
45
|
+
|
|
46
|
+
change?: EventCallback<EvDropChange>;
|
|
47
|
+
clear?: EventCallback<CoreEvent>;
|
|
29
48
|
}
|
|
30
49
|
|
|
31
50
|
/**
|
|
@@ -33,11 +52,11 @@ export interface ImageProps extends ComponentProps {
|
|
|
33
52
|
*/
|
|
34
53
|
|
|
35
54
|
@class_ns( "x4" )
|
|
36
|
-
export class Image extends Component<
|
|
55
|
+
export class Image<P extends ImageProps = ImageProps, E extends ImageEvents = ImageEvents> extends Component<P,E> {
|
|
37
56
|
|
|
38
57
|
private _img: Component;
|
|
39
58
|
|
|
40
|
-
constructor( props:
|
|
59
|
+
constructor( props: P ) {
|
|
41
60
|
super( props );
|
|
42
61
|
|
|
43
62
|
this._img = new Component( {
|
|
@@ -57,6 +76,63 @@ export class Image extends Component<ImageProps> {
|
|
|
57
76
|
|
|
58
77
|
this.setContent( this._img );
|
|
59
78
|
this.setImage( props.src );
|
|
79
|
+
|
|
80
|
+
if( props.candrop ) {
|
|
81
|
+
this.mapPropEvents( props, "change", "clear" );
|
|
82
|
+
|
|
83
|
+
let fileDialog = new FileDialog( {
|
|
84
|
+
accept: props.accept,
|
|
85
|
+
multiple: false,
|
|
86
|
+
callback: ( files ) => {
|
|
87
|
+
this.fire( "change", { files } );
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
this.appendContent( fileDialog );
|
|
92
|
+
|
|
93
|
+
this.addDOMEvent( "click", ( ) => fileDialog.showDialog() );
|
|
94
|
+
|
|
95
|
+
const filterInput = ( _: Component, data: DataTransfer ) => {
|
|
96
|
+
// check that input is of type image
|
|
97
|
+
if( data.items?.length ) {
|
|
98
|
+
const type = data.items[0].type;
|
|
99
|
+
if( /image\/.*/.test(type) ) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
dragManager.registerDropTarget( this, async ( cmd, el, infos ) => {
|
|
108
|
+
if( cmd=="enter" ) {
|
|
109
|
+
this.addClass( "hit" );
|
|
110
|
+
}
|
|
111
|
+
else if( cmd=='leave' ) {
|
|
112
|
+
this.removeClass( "hit" );
|
|
113
|
+
}
|
|
114
|
+
else if( cmd=='drop' ) {
|
|
115
|
+
if( infos.data.files && infos.data.files.length>0 ) {
|
|
116
|
+
const files = infos.data.files;
|
|
117
|
+
this.fire( "change", { files } );
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}, filterInput );
|
|
121
|
+
|
|
122
|
+
this.addDOMEvent( "contextmenu", ( ev ) => {
|
|
123
|
+
const menu = new Menu( {
|
|
124
|
+
items: [
|
|
125
|
+
{ text: _tr.global.cut, click: ( ) => {
|
|
126
|
+
this.fire( "clear", {} );
|
|
127
|
+
} },
|
|
128
|
+
]
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
menu.displayAt( ev.pageX, ev.pageY );
|
|
132
|
+
ev.stopPropagation( );
|
|
133
|
+
ev.preventDefault( );
|
|
134
|
+
});
|
|
135
|
+
}
|
|
60
136
|
}
|
|
61
137
|
|
|
62
138
|
/**
|
|
@@ -64,6 +140,29 @@ export class Image extends Component<ImageProps> {
|
|
|
64
140
|
*/
|
|
65
141
|
|
|
66
142
|
setImage( src: string ) {
|
|
67
|
-
|
|
143
|
+
if( src ) {
|
|
144
|
+
this._img.setAttribute( "src", src );
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
this.clear( );
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
*
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
setBase64( mime: string, base64: string ) {
|
|
156
|
+
this.setImage( "data:"+mime+";base64,"+base64 );
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
*
|
|
161
|
+
*/
|
|
162
|
+
|
|
163
|
+
clear( ) {
|
|
164
|
+
this._img.setAttribute( "src", 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' );
|
|
68
165
|
}
|
|
69
|
-
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
--input-sel-color: var( --accent-color );
|
|
20
20
|
--input-placeholder: var( --disabled-background );
|
|
21
21
|
--input-error: var( --alert-background );
|
|
22
|
+
|
|
23
|
+
--input-checkbox-color: var( --accent-background );
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
input.x4input {
|
|
@@ -34,17 +36,20 @@ input.x4input {
|
|
|
34
36
|
|
|
35
37
|
&[type="text"],
|
|
36
38
|
&[type="password"],
|
|
39
|
+
&[type="date"],
|
|
40
|
+
&[type="number"],
|
|
37
41
|
&[type="email"] {
|
|
38
|
-
padding:
|
|
42
|
+
padding: 4px 4px;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
&[type="checkbox"]:checked,
|
|
42
46
|
&[type="radio"]:checked {
|
|
43
|
-
accent-color: var( --color
|
|
47
|
+
accent-color: var( --input-checkbox-color );
|
|
48
|
+
padding: 2px;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
&[type="range"] {
|
|
47
|
-
accent-color: var( --color
|
|
52
|
+
accent-color: var( --input-checkbox-color );
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
&::placeholder {
|
|
@@ -14,13 +14,21 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
17
|
+
import { EventCallback } from '@core/core_events.js';
|
|
18
|
+
import { Component, ComponentEvent, ComponentProps, EvChange, EvFocus } from '../../core/component';
|
|
19
|
+
import { class_ns, formatIntlDate, IComponentInterface, IFormElement, isString } from '../../core/core_tools.js';
|
|
19
20
|
|
|
20
21
|
import "./input.module.scss"
|
|
21
22
|
|
|
22
23
|
export interface BaseProps extends ComponentProps {
|
|
23
24
|
name?: string;
|
|
25
|
+
autofocus?: boolean;
|
|
26
|
+
required?: boolean;
|
|
27
|
+
readonly?: boolean;
|
|
28
|
+
placeholder?: string;
|
|
29
|
+
|
|
30
|
+
focus?: EventCallback<EvFocus>;
|
|
31
|
+
change?: EventCallback<EvChange>;
|
|
24
32
|
}
|
|
25
33
|
|
|
26
34
|
interface CheckboxProps extends BaseProps {
|
|
@@ -31,73 +39,92 @@ interface CheckboxProps extends BaseProps {
|
|
|
31
39
|
|
|
32
40
|
interface RadioProps extends BaseProps {
|
|
33
41
|
type: "radio";
|
|
34
|
-
value
|
|
42
|
+
value?: boolean | number | string;
|
|
35
43
|
checked?: boolean;
|
|
36
44
|
}
|
|
37
45
|
|
|
38
46
|
export interface RangeProps extends BaseProps {
|
|
39
47
|
type: "range";
|
|
40
|
-
value
|
|
48
|
+
value?: number;
|
|
41
49
|
min: number;
|
|
42
50
|
max: number;
|
|
43
51
|
step?: number;
|
|
44
52
|
}
|
|
45
53
|
|
|
46
|
-
interface
|
|
54
|
+
export interface FileProps extends BaseProps {
|
|
55
|
+
type: "file";
|
|
56
|
+
accept: string | string[];
|
|
57
|
+
value?: never;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
export interface DateProps extends BaseProps {
|
|
47
62
|
type: "date";
|
|
63
|
+
value?: Date | string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface TimeProps extends BaseProps {
|
|
67
|
+
type: "time";
|
|
48
68
|
readonly?: boolean;
|
|
49
69
|
required?: boolean;
|
|
50
|
-
value
|
|
70
|
+
value?: string;
|
|
51
71
|
}
|
|
52
72
|
|
|
53
|
-
interface NumberProps extends BaseProps {
|
|
73
|
+
export interface NumberProps extends BaseProps {
|
|
54
74
|
type: "number";
|
|
55
75
|
readonly?: boolean;
|
|
56
76
|
required?: boolean;
|
|
57
|
-
value
|
|
77
|
+
value?: number | string;
|
|
58
78
|
min?: number;
|
|
59
79
|
max?: number;
|
|
60
80
|
step?: number;
|
|
61
81
|
}
|
|
62
82
|
|
|
63
|
-
interface FileProps extends BaseProps {
|
|
64
|
-
type: "file";
|
|
65
|
-
accept: string | string[];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
83
|
export interface TextInputProps extends BaseProps {
|
|
69
|
-
type
|
|
84
|
+
type?: "text" | "email" | "password";
|
|
70
85
|
readonly?: boolean;
|
|
71
86
|
required?: boolean;
|
|
72
87
|
pattern?: string;
|
|
73
|
-
value
|
|
74
|
-
placeholder?: string;
|
|
88
|
+
value?: string | number;
|
|
75
89
|
spellcheck?: boolean;
|
|
90
|
+
minlength?: number;
|
|
91
|
+
maxlength?: number;
|
|
76
92
|
}
|
|
77
93
|
|
|
78
94
|
|
|
79
|
-
export type InputProps =
|
|
95
|
+
export type InputProps = TextInputProps | CheckboxProps | RadioProps | RangeProps | DateProps | NumberProps | FileProps | TimeProps;
|
|
80
96
|
|
|
81
97
|
|
|
98
|
+
interface InputEvents extends ComponentEvent {
|
|
99
|
+
focus: EvFocus;
|
|
100
|
+
change: EvChange;
|
|
101
|
+
}
|
|
102
|
+
|
|
82
103
|
|
|
83
104
|
/**
|
|
84
105
|
*
|
|
85
106
|
*/
|
|
86
107
|
|
|
87
108
|
@class_ns( "x4" )
|
|
88
|
-
export class Input extends Component<InputProps> {
|
|
109
|
+
export class Input extends Component<InputProps,InputEvents> {
|
|
89
110
|
constructor( props: InputProps ) {
|
|
90
111
|
super( { tag: "input", ...props } );
|
|
91
112
|
|
|
113
|
+
this.mapPropEvents( props, "focus", "change" );
|
|
114
|
+
|
|
92
115
|
this.setAttribute( "type", props.type ?? "text" );
|
|
93
116
|
this.setAttribute( "name", props.name );
|
|
117
|
+
|
|
118
|
+
if( props.autofocus===true ) {
|
|
119
|
+
this.setAttribute( "autofocus", true );
|
|
120
|
+
}
|
|
94
121
|
|
|
95
122
|
switch( props.type ) {
|
|
96
123
|
case "checkbox":
|
|
97
124
|
case "radio": {
|
|
98
125
|
const ck = this.dom as HTMLInputElement;
|
|
99
126
|
ck.checked = props.checked;
|
|
100
|
-
ck.value = props.value+"";
|
|
127
|
+
ck.value = props.value === undefined ? "" : props.value+"";
|
|
101
128
|
//this.setAttribute( "checked", props.checked );
|
|
102
129
|
//this.setAttribute( "value", props.value );
|
|
103
130
|
break;
|
|
@@ -112,12 +139,27 @@ export class Input extends Component<InputProps> {
|
|
|
112
139
|
}
|
|
113
140
|
|
|
114
141
|
case "number": {
|
|
115
|
-
this.
|
|
116
|
-
|
|
117
|
-
this.setAttribute( "
|
|
118
|
-
this.setAttribute( "
|
|
119
|
-
this.setAttribute( "
|
|
120
|
-
this.setAttribute( "
|
|
142
|
+
const p = this.props as NumberProps;
|
|
143
|
+
|
|
144
|
+
this.setAttribute( "required", p.required );
|
|
145
|
+
this.setAttribute( "readonly", p.readonly );
|
|
146
|
+
this.setAttribute( "min", p.min );
|
|
147
|
+
this.setAttribute( "max", p.max );
|
|
148
|
+
this.setAttribute( "step", p.step );
|
|
149
|
+
//this.setAttribute( "value", p.value+'' );
|
|
150
|
+
this.setNumValue( isString(p.value) ? parseFloat(p.value) : p.value, -2 );
|
|
151
|
+
|
|
152
|
+
this.addDOMEvent( "wheel", ( e: WheelEvent ) => {
|
|
153
|
+
if( this.hasFocus() ) { // only if has focus
|
|
154
|
+
e.preventDefault( );
|
|
155
|
+
let v = this.getNumValue();
|
|
156
|
+
const delta = e.deltaY < 0 ? 1 : -1;
|
|
157
|
+
v += (p.step ? p.step : 1) * delta;
|
|
158
|
+
this.setNumValue( v, -2 );
|
|
159
|
+
|
|
160
|
+
this.dom.dispatchEvent(new Event('input'));
|
|
161
|
+
}
|
|
162
|
+
}, );
|
|
121
163
|
break;
|
|
122
164
|
}
|
|
123
165
|
|
|
@@ -126,9 +168,9 @@ export class Input extends Component<InputProps> {
|
|
|
126
168
|
|
|
127
169
|
let v = props.value;
|
|
128
170
|
if( v instanceof Date ) {
|
|
129
|
-
|
|
171
|
+
this.setAttribute( "value", formatIntlDate( v, "Y-M-D" ) );
|
|
130
172
|
}
|
|
131
|
-
else {
|
|
173
|
+
else if( props.value!==null && props.value!==undefined ) {
|
|
132
174
|
this.setAttribute( "value", v );
|
|
133
175
|
}
|
|
134
176
|
|
|
@@ -148,6 +190,14 @@ export class Input extends Component<InputProps> {
|
|
|
148
190
|
break;
|
|
149
191
|
}
|
|
150
192
|
|
|
193
|
+
case "time": {
|
|
194
|
+
this.setAttribute( "required", props.required );
|
|
195
|
+
if( props.value!==null && props.value!==undefined ) {
|
|
196
|
+
this.setAttribute( "value", props.value );
|
|
197
|
+
}
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
|
|
151
201
|
default: {
|
|
152
202
|
this.setAttribute( "required", props.required );
|
|
153
203
|
this.setAttribute( "readonly", props.readonly );
|
|
@@ -168,9 +218,48 @@ export class Input extends Component<InputProps> {
|
|
|
168
218
|
this.setAttribute( "spellcheck", false );
|
|
169
219
|
}
|
|
170
220
|
|
|
221
|
+
if( props.minlength!==undefined ) {
|
|
222
|
+
this.setAttribute( "minlength", props.minlength );
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if( props.maxlength!==undefined ) {
|
|
226
|
+
this.setAttribute( "maxlength", props.maxlength );
|
|
227
|
+
}
|
|
228
|
+
|
|
171
229
|
break;
|
|
172
230
|
}
|
|
173
231
|
}
|
|
232
|
+
|
|
233
|
+
this.addDOMEvent( "blur", ( e ) => { this.on_focus(e,true);} );
|
|
234
|
+
this.addDOMEvent( "focus", ( e ) => { this.on_focus(e,false);} );
|
|
235
|
+
this.addDOMEvent( "input", ( e ) => { this.on_change(e as InputEvent); });
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
*
|
|
240
|
+
*/
|
|
241
|
+
|
|
242
|
+
private on_focus( ev: FocusEvent, focus_out: boolean ) {
|
|
243
|
+
const event: EvFocus = { focus_out }
|
|
244
|
+
this.fire( "focus", event );
|
|
245
|
+
|
|
246
|
+
if( event.defaultPrevented ) {
|
|
247
|
+
ev.preventDefault( );
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
*
|
|
253
|
+
*/
|
|
254
|
+
|
|
255
|
+
private on_change( ev: InputEvent ) {
|
|
256
|
+
|
|
257
|
+
const event: EvChange = { value: this.getValue() };
|
|
258
|
+
this.fire( "change", event );
|
|
259
|
+
|
|
260
|
+
if( event.defaultPrevented ) {
|
|
261
|
+
ev.preventDefault( );
|
|
262
|
+
}
|
|
174
263
|
}
|
|
175
264
|
|
|
176
265
|
/**
|
|
@@ -195,19 +284,60 @@ export class Input extends Component<InputProps> {
|
|
|
195
284
|
* @returns
|
|
196
285
|
*/
|
|
197
286
|
|
|
198
|
-
public getNumValue( ) {
|
|
199
|
-
|
|
287
|
+
public getNumValue( defNan?: number ) {
|
|
288
|
+
const v = parseFloat( this.getValue() );
|
|
289
|
+
if( isNaN(v) && defNan!==undefined ) {
|
|
290
|
+
return defNan;
|
|
291
|
+
}
|
|
292
|
+
return v;
|
|
200
293
|
}
|
|
201
294
|
|
|
202
295
|
/**
|
|
203
296
|
*
|
|
204
297
|
* @param value
|
|
298
|
+
* @param ndec number of decimals or -1 for auto, -2 as prop.step
|
|
299
|
+
*
|
|
205
300
|
*/
|
|
206
301
|
|
|
207
|
-
public setNumValue( value: number ) {
|
|
302
|
+
public setNumValue( value: number, ndec = -1 ) {
|
|
303
|
+
|
|
304
|
+
if( ndec==-2 && this.props.type=='number' ) {
|
|
305
|
+
const p = this.props as NumberProps;
|
|
306
|
+
|
|
307
|
+
if( p.step<1 ) {
|
|
308
|
+
let ndec = -Math.floor(Math.log10(p.step ?? 1) );
|
|
309
|
+
return this.setValue( value.toFixed(ndec) );
|
|
310
|
+
}
|
|
311
|
+
else if( p.step>1 ) {
|
|
312
|
+
return this.setValue( value.toFixed() );
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
else if( ndec>=0 ) {
|
|
316
|
+
return this.setValue( value.toFixed(ndec) );
|
|
317
|
+
}
|
|
318
|
+
|
|
208
319
|
this.setValue( value+"" );
|
|
209
320
|
}
|
|
210
321
|
|
|
322
|
+
/**
|
|
323
|
+
* @return the checked value
|
|
324
|
+
*/
|
|
325
|
+
|
|
326
|
+
public getCheck() {
|
|
327
|
+
const d = this.dom as HTMLInputElement;
|
|
328
|
+
return d.checked;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* change the checked value
|
|
333
|
+
* @param {boolean} ck new checked value
|
|
334
|
+
*/
|
|
335
|
+
|
|
336
|
+
public setCheck(ck: boolean) {
|
|
337
|
+
const d = this.dom as HTMLInputElement;
|
|
338
|
+
d.checked = ck;
|
|
339
|
+
}
|
|
340
|
+
|
|
211
341
|
/**
|
|
212
342
|
*
|
|
213
343
|
*/
|
|
@@ -250,6 +380,22 @@ export class Input extends Component<InputProps> {
|
|
|
250
380
|
};
|
|
251
381
|
}
|
|
252
382
|
|
|
383
|
+
/**
|
|
384
|
+
*
|
|
385
|
+
*/
|
|
386
|
+
|
|
387
|
+
public isValid( ) {
|
|
388
|
+
|
|
389
|
+
if( (this.props as any).required ) {
|
|
390
|
+
const v = this.getValue( );
|
|
391
|
+
if( v==="" ) {
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
|
|
253
399
|
/**
|
|
254
400
|
*
|
|
255
401
|
*/
|
|
@@ -258,7 +404,8 @@ export class Input extends Component<InputProps> {
|
|
|
258
404
|
if( name=="form-element" ) {
|
|
259
405
|
const i: IFormElement = {
|
|
260
406
|
getRawValue: ( ): any => { return this.getValue(); },
|
|
261
|
-
setRawValue: ( v: any ) => { this.setValue(v); }
|
|
407
|
+
setRawValue: ( v: any ) => { this.setValue(v); },
|
|
408
|
+
isValid: ( ) => { return this.isValid(); }
|
|
262
409
|
};
|
|
263
410
|
|
|
264
411
|
//@ts-ignore
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" fill="currentColor"><!--!Font Awesome Free 6.7.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M214.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 141.2 160 448c0 17.7 14.3 32 32 32s32-14.3 32-32l0-306.7L329.4 246.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor"><!--!Font Awesome Free 6.7.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M576 128c0-35.3-28.7-64-64-64L205.3 64c-17 0-33.3 6.7-45.3 18.7L9.4 233.4c-6 6-9.4 14.1-9.4 22.6s3.4 16.6 9.4 22.6L160 429.3c12 12 28.3 18.7 45.3 18.7L512 448c35.3 0 64-28.7 64-64l0-256zM271 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" fill="currentColor"><!--!Font Awesome Free 6.7.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zm151 118.3C226 97.7 269.5 80 320 80c65.2 0 118.8 29.6 159.9 67.7C518.4 183.5 545 226 558.6 256c-12.6 28-36.6 66.8-70.9 100.9l-53.8-42.2c9.1-17.6 14.2-37.5 14.2-58.7c0-70.7-57.3-128-128-128c-32.2 0-61.7 11.9-84.2 31.5l-46.1-36.1zM394.9 284.2l-81.5-63.9c4.2-8.5 6.6-18.2 6.6-28.3c0-5.5-.7-10.9-2-16c.7 0 1.3 0 2 0c44.2 0 80 35.8 80 80c0 9.9-1.8 19.4-5.1 28.2zm9.4 130.3C378.8 425.4 350.7 432 320 432c-65.2 0-118.8-29.6-159.9-67.7C121.6 328.5 95 286 81.4 256c8.3-18.4 21.5-41.5 39.4-64.8L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5l-41.9-33zM192 256c0 70.7 57.3 128 128 128c13.3 0 26.1-2 38.2-5.8L302 334c-23.5-5.4-43.1-21.2-53.7-42.3l-56.1-44.2c-.2 2.8-.3 5.6-.3 8.5z"/></svg>
|