x4js 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/lib/application.d.ts +95 -0
  2. package/lib/application.js +137 -0
  3. package/lib/base64.d.ts +31 -0
  4. package/lib/base64.js +135 -0
  5. package/lib/base_component.d.ts +64 -0
  6. package/lib/base_component.js +77 -0
  7. package/lib/button.d.ts +145 -0
  8. package/lib/button.js +235 -0
  9. package/lib/calendar.d.ts +77 -0
  10. package/lib/calendar.js +236 -0
  11. package/lib/canvas.d.ts +88 -0
  12. package/lib/canvas.js +354 -0
  13. package/lib/cardview.d.ts +83 -0
  14. package/lib/cardview.js +152 -0
  15. package/lib/checkbox.d.ts +72 -0
  16. package/lib/checkbox.js +126 -0
  17. package/lib/color.d.ts +144 -0
  18. package/lib/color.js +584 -0
  19. package/lib/colorpicker.d.ts +98 -0
  20. package/lib/colorpicker.js +1457 -0
  21. package/lib/combobox.d.ts +97 -0
  22. package/lib/combobox.js +246 -0
  23. package/lib/component.d.ts +572 -0
  24. package/lib/component.js +1712 -0
  25. package/lib/datastore.d.ts +392 -0
  26. package/lib/datastore.js +986 -0
  27. package/lib/dialog.d.ts +171 -0
  28. package/lib/dialog.js +468 -0
  29. package/lib/dom_events.d.ts +284 -0
  30. package/lib/dom_events.js +13 -0
  31. package/lib/drag_manager.d.ts +26 -0
  32. package/lib/drag_manager.js +118 -0
  33. package/lib/drawtext.d.ts +43 -0
  34. package/lib/drawtext.js +261 -0
  35. package/lib/fileupload.d.ts +60 -0
  36. package/lib/fileupload.js +158 -0
  37. package/lib/form.d.ts +122 -0
  38. package/lib/form.js +293 -0
  39. package/lib/formatters.d.ts +31 -0
  40. package/lib/formatters.js +75 -0
  41. package/lib/gridview.d.ts +171 -0
  42. package/lib/gridview.js +786 -0
  43. package/lib/hosts/host.d.ts +44 -0
  44. package/lib/hosts/host.js +69 -0
  45. package/lib/i18n.d.ts +67 -0
  46. package/lib/i18n.js +169 -0
  47. package/lib/icon.d.ts +56 -0
  48. package/lib/icon.js +173 -0
  49. package/lib/image.d.ts +51 -0
  50. package/lib/image.js +149 -0
  51. package/lib/index.js +1 -0
  52. package/lib/input.d.ts +86 -0
  53. package/lib/input.js +172 -0
  54. package/lib/label.d.ts +54 -0
  55. package/lib/label.js +86 -0
  56. package/lib/layout.d.ts +77 -0
  57. package/lib/layout.js +261 -0
  58. package/lib/link.d.ts +46 -0
  59. package/lib/link.js +55 -0
  60. package/lib/listview.d.ts +173 -0
  61. package/lib/listview.js +532 -0
  62. package/lib/md5.d.ts +56 -0
  63. package/lib/md5.js +397 -0
  64. package/lib/menu.d.ts +122 -0
  65. package/lib/menu.js +276 -0
  66. package/lib/messagebox.d.ts +64 -0
  67. package/lib/messagebox.js +141 -0
  68. package/lib/panel.d.ts +42 -0
  69. package/lib/panel.js +61 -0
  70. package/lib/popup.d.ts +71 -0
  71. package/lib/popup.js +373 -0
  72. package/lib/property_editor.d.ts +67 -0
  73. package/lib/property_editor.js +247 -0
  74. package/lib/radiobtn.d.ts +68 -0
  75. package/lib/radiobtn.js +131 -0
  76. package/lib/rating.d.ts +49 -0
  77. package/lib/rating.js +93 -0
  78. package/lib/request.d.ts +48 -0
  79. package/lib/request.js +220 -0
  80. package/lib/router.d.ts +13 -0
  81. package/lib/router.js +27 -0
  82. package/lib/settings.d.ts +33 -0
  83. package/lib/settings.js +63 -0
  84. package/lib/sidebarview.d.ts +44 -0
  85. package/lib/sidebarview.js +73 -0
  86. package/lib/smartedit.d.ts +103 -0
  87. package/lib/smartedit.js +381 -0
  88. package/lib/spreadsheet.d.ts +214 -0
  89. package/lib/spreadsheet.js +1073 -0
  90. package/lib/styles.d.ts +81 -0
  91. package/lib/styles.js +262 -0
  92. package/lib/svgcomponent.d.ts +165 -0
  93. package/lib/svgcomponent.js +350 -0
  94. package/lib/tabbar.d.ts +41 -0
  95. package/lib/tabbar.js +66 -0
  96. package/lib/tabview.d.ts +45 -0
  97. package/lib/tabview.js +79 -0
  98. package/lib/textarea.d.ts +59 -0
  99. package/lib/textarea.js +119 -0
  100. package/lib/textedit.d.ts +118 -0
  101. package/lib/textedit.js +406 -0
  102. package/lib/texthiliter.d.ts +56 -0
  103. package/lib/texthiliter.js +219 -0
  104. package/lib/toaster.d.ts +38 -0
  105. package/lib/toaster.js +58 -0
  106. package/lib/tools.d.ts +382 -0
  107. package/lib/tools.js +1096 -0
  108. package/lib/tooltips.d.ts +42 -0
  109. package/lib/tooltips.js +148 -0
  110. package/lib/treeview.d.ts +128 -0
  111. package/lib/treeview.js +490 -0
  112. package/lib/x4_events.d.ts +253 -0
  113. package/lib/x4_events.js +363 -0
  114. package/package.json +21 -0
  115. package/src/README.md +2 -0
  116. package/src/application.ts +191 -0
  117. package/src/base64.ts +162 -0
  118. package/src/base_component.ts +118 -0
  119. package/src/button.ts +327 -0
  120. package/src/calendar.ts +312 -0
  121. package/src/canvas.ts +501 -0
  122. package/src/cardview.ts +220 -0
  123. package/src/checkbox.ts +178 -0
  124. package/src/color.ts +748 -0
  125. package/src/colorpicker.ts +1618 -0
  126. package/src/combobox.ts +348 -0
  127. package/src/component.ts +2330 -0
  128. package/src/datastore.ts +1318 -0
  129. package/src/dialog.ts +631 -0
  130. package/src/dom_events.ts +297 -0
  131. package/src/drag_manager.ts +168 -0
  132. package/src/drawtext.ts +342 -0
  133. package/src/fileupload.ts +208 -0
  134. package/src/form.ts +362 -0
  135. package/src/formatters.ts +96 -0
  136. package/src/gridview.ts +1051 -0
  137. package/src/hosts/electron.ts +161 -0
  138. package/src/hosts/host.ts +100 -0
  139. package/src/hosts/nwjs.ts +141 -0
  140. package/src/hosts/nwjs_types.ts +339 -0
  141. package/src/i18n.ts +205 -0
  142. package/src/icon.ts +237 -0
  143. package/src/image.ts +198 -0
  144. package/src/input.ts +236 -0
  145. package/src/label.ts +124 -0
  146. package/src/layout.ts +366 -0
  147. package/src/link.ts +82 -0
  148. package/src/listview.ts +749 -0
  149. package/src/md5.ts +432 -0
  150. package/src/menu.ts +394 -0
  151. package/src/messagebox.ts +199 -0
  152. package/src/panel.ts +81 -0
  153. package/src/popup.ts +488 -0
  154. package/src/property_editor.ts +333 -0
  155. package/src/radiobtn.ts +190 -0
  156. package/src/rating.ts +131 -0
  157. package/src/request.ts +296 -0
  158. package/src/router.ts +43 -0
  159. package/src/settings.ts +75 -0
  160. package/src/sidebarview.ts +97 -0
  161. package/src/smartedit.ts +532 -0
  162. package/src/spreadsheet.ts +1423 -0
  163. package/src/styles.ts +332 -0
  164. package/src/svgcomponent.ts +440 -0
  165. package/src/tabbar.ts +105 -0
  166. package/src/tabview.ts +106 -0
  167. package/src/textarea.ts +183 -0
  168. package/src/textedit.ts +535 -0
  169. package/src/texthiliter.ts +284 -0
  170. package/src/toaster.ts +76 -0
  171. package/src/tools.ts +1391 -0
  172. package/src/tooltips.ts +185 -0
  173. package/src/treeview.ts +670 -0
  174. package/src/x4.less +1940 -0
  175. package/src/x4_events.ts +558 -0
  176. package/tsconfig.json +14 -0
package/src/icon.ts ADDED
@@ -0,0 +1,237 @@
1
+ /**
2
+ * ___ ___ __
3
+ * \ \/ / / _
4
+ * \ / /_| |_
5
+ * / \____ _|
6
+ * /__/\__\ |_|
7
+ *
8
+ * @file icon.ts
9
+ * @author Etienne Cochard
10
+ * @license
11
+ * Copyright (c) 2019-2021 R-libre ingenierie
12
+ *
13
+ * This program is free software; you can redistribute it and/or modify
14
+ * it under the terms of the GNU General Public License as published by
15
+ * the Free Software Foundation; either version 3 of the License, or
16
+ * (at your option) any later version.
17
+ *
18
+ * This program is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
24
+ **/
25
+
26
+ import { Component, CProps } from './component'
27
+ import { Stylesheet } from './styles'
28
+ import { HtmlString } from './tools';
29
+ import { BasicEvent, EvChange, EventMap, EventSource } from './x4_events';
30
+
31
+ // ============================================================================
32
+ // [ICON]
33
+ // ============================================================================
34
+
35
+ export type IconID = string | number;
36
+
37
+ export interface IconProps extends CProps {
38
+ icon: IconID;
39
+ size?: number;
40
+ }
41
+
42
+
43
+ export interface EvLoaded extends BasicEvent {
44
+ url: string;
45
+ svg: string;
46
+ }
47
+
48
+ export function EvLoaded( url: string, svg: string, context = null ) {
49
+ return BasicEvent<EvLoaded>({ url, svg, context });
50
+ }
51
+
52
+ interface LoadingEventMap extends EventMap {
53
+ loaded: EvLoaded;
54
+ }
55
+
56
+ class Loader extends EventSource<LoadingEventMap> {
57
+ svgs: Map<string,string>;
58
+
59
+ constructor( ) {
60
+ super( );
61
+ this.svgs = new Map( );
62
+ }
63
+
64
+ load( url: string ) {
65
+ if( this.svgs.has(url) ) {
66
+ const svg = this.svgs.get( url );
67
+ if( svg ) {
68
+ //console.log( 'cached=', url );
69
+ this.signal( 'loaded', EvLoaded(url,svg) );
70
+ }
71
+ }
72
+ else {
73
+ // mark it as loading
74
+ this.svgs.set( url, null );
75
+
76
+ // then start loading
77
+ const _load = async ( url ) => {
78
+ const r = await fetch( url );
79
+ if( r.ok ) {
80
+ const svg = await r.text();
81
+ this.svgs.set( url, svg );
82
+
83
+ //console.log( 'signal=', url );
84
+ this.signal( 'loaded', EvLoaded(url,svg) );
85
+ }
86
+ }
87
+
88
+ _load( url );
89
+ }
90
+ }
91
+ }
92
+
93
+ const svgLoader = new Loader( );
94
+
95
+
96
+ /**
97
+ * standard icon
98
+ */
99
+ export class Icon extends Component<IconProps>
100
+ {
101
+ private m_icon: string;
102
+ private m_iconName: IconID;
103
+
104
+ constructor( props: IconProps ) {
105
+ super( props );
106
+
107
+ this._setIcon( props.icon, false );
108
+
109
+ if( props.size ) {
110
+ this.setStyleValue( 'fontSize', props.size );
111
+ }
112
+ }
113
+
114
+ private _setIcon(icon: IconID, remove_old: boolean) {
115
+
116
+ const reUrl = /\s*url\s*\(\s*(.+)\s*\)\s*/gi;
117
+ const reSvg = /\s*svg\s*\(\s*(.+)\s*\)\s*/gi;
118
+ const reSvg2 = /(.*\.svg)$/gi;
119
+ const reCls = /\s*cls\s*\(\s*(.+)\s*\)\s*/gi;
120
+
121
+ if( !icon ) {
122
+ this.m_iconName = '';
123
+ return;
124
+ }
125
+
126
+ this.removeClass( '@svg' );
127
+
128
+ let name, url;
129
+ if (typeof (icon) === 'number') {
130
+ icon = icon.toString(16);
131
+ name = icon;
132
+ }
133
+ else {
134
+ let match_svg = reSvg.exec( icon ) || reSvg2.exec(icon);
135
+ if( match_svg ) {
136
+ const url = match_svg[1].trim( );
137
+ this._setSVG( url );
138
+ return;
139
+ }
140
+
141
+ let match_cls = reCls.exec( icon );
142
+ if( match_cls ) {
143
+ const classes = match_cls[1].trim( );
144
+ this.addClass( classes );
145
+ return;
146
+ }
147
+
148
+ let match_url = reUrl.exec( icon );
149
+ if( match_url ) {
150
+ url = match_url[1].trim( );
151
+ name = url.replace( /[/\\\.\* ]/g, '_' );
152
+ }
153
+ else {
154
+ name = icon;
155
+ icon = Stylesheet.getVar( 'icon-'+icon ) as string;
156
+
157
+ if( icon=='' || icon===undefined ) {
158
+ // name your icon 'icon-xxx'
159
+ // ex:
160
+ // :root { --icon-zoom-p: f00e; }
161
+ console.assert( false );
162
+ icon = '0';
163
+ }
164
+ }
165
+ }
166
+
167
+ this.m_iconName = name;
168
+ if( this.m_icon===icon ) {
169
+ return;
170
+ }
171
+
172
+ let css = Component.getCss(),
173
+ rulename: string;
174
+
175
+ if (remove_old && this.m_icon) {
176
+ rulename = 'icon-' + name;
177
+ this.removeClass(rulename);
178
+ }
179
+
180
+ // generate dynamic css icon rule
181
+ rulename = 'icon-' + name;
182
+
183
+ if( Icon.icon_cache[rulename]===undefined ) {
184
+ Icon.icon_cache[rulename] = true;
185
+
186
+ let rule: string;
187
+
188
+ if( url ) {
189
+ rule = `display: block; content: ' '; background-image: url(${url}); background-size: contain; width: 100%; height: 100%; background-repeat: no-repeat; color: white;`;
190
+ }
191
+ else {
192
+ rule = `content: "\\${icon}";`;
193
+ }
194
+
195
+ css.setRule(rulename, `.${rulename}::before {${rule}}`);
196
+ }
197
+
198
+ this.addClass(rulename);
199
+ this.m_icon = icon;
200
+ }
201
+
202
+ /**
203
+ * change the icon
204
+ * @param icon - new icon
205
+ */
206
+ public set icon( icon: IconID ) {
207
+ this._setIcon( icon, true );
208
+ }
209
+
210
+ public get icon( ) : IconID {
211
+ return this.m_iconName;
212
+ }
213
+
214
+ private _setSVG( url: string ) {
215
+
216
+ const set = ( ev: EvLoaded ) => {
217
+ //console.log( 'set=', ev.url, 'url=', url );
218
+
219
+ if( ev.url==url ) {
220
+ this.addClass( '@svg-icon' );
221
+ this.setContent( HtmlString.from(ev.svg), false );
222
+ svgLoader.off( 'loaded', set );
223
+ }
224
+ }
225
+
226
+ svgLoader.on( 'loaded', set );
227
+ svgLoader.load( url );
228
+ }
229
+
230
+
231
+ /**
232
+ *
233
+ */
234
+
235
+ private static icon_cache = [];
236
+ }
237
+
package/src/image.ts ADDED
@@ -0,0 +1,198 @@
1
+ /**
2
+ * ___ ___ __
3
+ * \ \/ / / _
4
+ * \ / /_| |_
5
+ * / \____ _|
6
+ * /__/\__\ |_|
7
+ *
8
+ * @file image.ts
9
+ * @author Etienne Cochard
10
+ * @license
11
+ * Copyright (c) 2019-2021 R-libre ingenierie
12
+ *
13
+ * This program is free software; you can redistribute it and/or modify
14
+ * it under the terms of the GNU General Public License as published by
15
+ * the Free Software Foundation; either version 3 of the License, or
16
+ * (at your option) any later version.
17
+ *
18
+ * This program is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
24
+ **/
25
+
26
+ import { Component, CProps, html } from './component'
27
+
28
+ // ============================================================================
29
+ // [IMAGE]
30
+ // ============================================================================
31
+
32
+ interface ImageProps extends CProps
33
+ {
34
+ src: string;
35
+ alt?: string;
36
+ lazy?: boolean; // mark image as lazy loading
37
+ alignment?: 'fill' | 'contain' | 'cover' | 'scale-down' | 'none';
38
+ }
39
+
40
+ const emptyImageSrc = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
41
+
42
+ function _isStaticImage( src: string ) {
43
+ return src.substr(0,5)=='data:';
44
+ }
45
+
46
+
47
+
48
+ /**
49
+ * Standard image class
50
+ */
51
+ export class Image extends Component<ImageProps>
52
+ {
53
+ protected m_created: boolean;
54
+ protected m_lazysrc: string; // expected
55
+
56
+ constructor(props: ImageProps) {
57
+ super(props);
58
+
59
+ this.m_created = false;
60
+
61
+ this.m_props.lazy = props.lazy===false ? false : true;
62
+ this.m_props.alt = props.alt;
63
+
64
+ if( props.lazy!==false ) {
65
+ this.m_lazysrc = props.src;
66
+ props.src = emptyImageSrc;
67
+ }
68
+
69
+ this.setDomEvent( 'create', ( ) => {
70
+ if( props.lazy ) {
71
+ this.setImage( this.m_lazysrc, true );
72
+ }
73
+ });
74
+ }
75
+
76
+ /** @ignore */
77
+ render( ) {
78
+ let mp = this.m_props;
79
+
80
+ const img = new Component( {
81
+ tag: 'img',
82
+ attrs: {
83
+ draggable: false,
84
+ alt: mp.alt ?? '',
85
+ decoding: mp.lazy ? 'async' : undefined,
86
+ },
87
+ style: {
88
+ objectFit: mp.alignment ? mp.alignment : undefined
89
+ }
90
+ });
91
+
92
+ this.setContent( img );
93
+ }
94
+
95
+ /**
96
+ * change the image
97
+ * @param src - image path
98
+ */
99
+
100
+ public setImage( src: string, force?: boolean ) {
101
+
102
+ if( !src ) {
103
+ src = emptyImageSrc;
104
+ }
105
+
106
+ if( !this.m_props.lazy ) {
107
+ this.m_props.src = src;
108
+ this.m_lazysrc = src;
109
+
110
+ if( this.dom ) {
111
+ (<HTMLElement>this.dom.firstChild).setAttribute( 'src', src );
112
+ }
113
+ }
114
+ else if( force || this.m_lazysrc!=src ) {
115
+ if( _isStaticImage(src) ) {
116
+ // not to download -> direct display
117
+ this.m_props.src = src;
118
+ this.m_lazysrc = src;
119
+
120
+ if( this.dom ) {
121
+ (<HTMLElement>this.dom.firstChild).setAttribute( 'src', this.m_props.src );
122
+ }
123
+ }
124
+ else {
125
+ // clear current image while waiting
126
+ this.m_props.src = emptyImageSrc;
127
+ if( this.dom ) {
128
+ (<HTMLElement>this.dom.firstChild).setAttribute( 'src', this.m_props.src );
129
+ }
130
+
131
+ this.m_lazysrc = src;
132
+ if( this.dom ) {
133
+ this._update_image( );
134
+ }
135
+ }
136
+ }
137
+ }
138
+
139
+ private _update_image( ) {
140
+
141
+ console.assert( !!this.dom );
142
+
143
+ if( this.m_lazysrc && !_isStaticImage(this.m_lazysrc) ) {
144
+ // we do not push Components in a static array...
145
+ Image.lazy_images_waiting.push( { dom: this.dom, src: this.m_lazysrc } );
146
+ if( Image.lazy_image_timer===undefined ) {
147
+ Image.lazy_image_timer = setInterval( Image.lazyWatch as TimerHandler, 10 );
148
+ }
149
+ }
150
+ }
151
+
152
+ private static lazy_images_waiting = [];
153
+ private static lazy_image_timer: number = undefined;
154
+
155
+ private static lazyWatch( ) {
156
+
157
+ let newList = [];
158
+ let done = 0;
159
+
160
+ Image.lazy_images_waiting.forEach( ( el ) => {
161
+
162
+ let dom = el.dom,
163
+ src = el.src;
164
+
165
+ // skip deleted elements
166
+ if( !dom || !document.contains(dom) ) {
167
+ // do not append to newList
168
+ return;
169
+ }
170
+
171
+ let rc = dom.getBoundingClientRect();
172
+
173
+ // if it is visible & inserted inside the document
174
+ if( !done && dom.offsetParent!==null &&
175
+ rc.bottom >= 0 && rc.right >= 0 &&
176
+ rc.top <= (window.innerHeight || document.documentElement.clientHeight) &&
177
+ rc.left <= (window.innerWidth || document.documentElement.clientWidth) ) {
178
+
179
+ // ok, we load the image
180
+ let img = <HTMLElement>dom.firstChild;
181
+ img.setAttribute( 'src', src );
182
+ done++;
183
+ }
184
+ else {
185
+ // still not visible: may be next time
186
+ newList.push( el );
187
+ }
188
+ } );
189
+
190
+ Image.lazy_images_waiting = newList;
191
+
192
+ // no more elements to watch...
193
+ if( newList.length==0 ) {
194
+ clearInterval( Image.lazy_image_timer );
195
+ Image.lazy_image_timer = undefined;
196
+ }
197
+ }
198
+ }
package/src/input.ts ADDED
@@ -0,0 +1,236 @@
1
+ /**
2
+ * ___ ___ __
3
+ * \ \/ / / _
4
+ * \ / /_| |_
5
+ * / \____ _|
6
+ * /__/\__\ |_|
7
+ *
8
+ * @file input.ts
9
+ * @author Etienne Cochard
10
+ * @license
11
+ * Copyright (c) 2019-2021 R-libre ingenierie
12
+ *
13
+ * This program is free software; you can redistribute it and/or modify
14
+ * it under the terms of the GNU General Public License as published by
15
+ * the Free Software Foundation; either version 3 of the License, or
16
+ * (at your option) any later version.
17
+ *
18
+ * This program is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
24
+ **/
25
+
26
+ import { Component, CProps, CEventMap, EvFocus } from './component'
27
+ //import { EvChange } from './x4_events';
28
+
29
+ export type EditType = 'text' | 'number' | 'email' | 'date' | 'password' | 'file' | 'checkbox' | 'radio';
30
+
31
+ export interface ValueHook {
32
+ get( ) : any;
33
+ set( v: any ) : void;
34
+ }
35
+
36
+ export interface InputEventMap extends CEventMap {
37
+ // change?: EvChange;
38
+ // focus?: EvFocus;
39
+ }
40
+
41
+ export interface InputProps<P extends InputEventMap = InputEventMap> extends CProps<P> {
42
+ value?: string;
43
+ name?: string;
44
+ type?: EditType
45
+ placeHolder?: string;
46
+ autoFocus?: boolean;
47
+ readOnly?: boolean;
48
+ tabIndex?: number | boolean;
49
+ pattern?: string;
50
+ uppercase?: boolean;
51
+ spellcheck?: boolean;
52
+ value_hook?: ValueHook;
53
+ min?: number;
54
+ max?: number;
55
+ }
56
+
57
+
58
+ /**
59
+ * base class for elements implementing an input
60
+ * CARE derived classes must set this.ui.input
61
+ */
62
+
63
+ export class Input extends Component<InputProps,InputEventMap>
64
+ {
65
+ constructor( props: InputProps ) {
66
+ super( props );
67
+ }
68
+
69
+ /** @ignore */
70
+ render( props: InputProps ) {
71
+
72
+ this.setProp( 'tag', 'input' );
73
+ this._setTabIndex( props.tabIndex );
74
+
75
+ this.setAttributes( {
76
+ value: props.value,
77
+ type: props.type || 'text',
78
+ name: props.name,
79
+ placeholder: props.placeHolder,
80
+ autofocus: props.autoFocus,
81
+ readonly: props.readOnly,
82
+ autocomplete: 'new-password', // chrome ignore 'off' but not something else than 'on'
83
+ tabindex: props.tabIndex,
84
+ spellcheck: props.spellcheck===false ? 'false' : undefined,
85
+ min: props.min,
86
+ max: props.max,
87
+ ...props.attrs
88
+ });
89
+
90
+ if( props.uppercase ) {
91
+ this.setStyleValue( 'textTransform', 'uppercase' );
92
+ }
93
+ }
94
+
95
+ public getType( ) {
96
+ return this.m_props.type;
97
+ }
98
+
99
+ /**
100
+ * return the current editor value
101
+ */
102
+
103
+ public get value( ) : string {
104
+
105
+ if( this.dom ) {
106
+ this.m_props.value = (<HTMLInputElement>this.dom).value;
107
+ }
108
+
109
+ if( this.m_props.uppercase ) {
110
+ let upper = this.m_props.value.toUpperCase( ); // todo: locale ?
111
+ if( this.dom && upper!=this.m_props.value ) {
112
+ (<HTMLInputElement>this.dom).value = upper; // update the input
113
+ }
114
+
115
+ this.m_props.value = upper;
116
+ }
117
+
118
+ return this.m_props.value;
119
+ }
120
+
121
+ /**
122
+ * Change the editor value
123
+ * @param value - new value to set
124
+ */
125
+
126
+ public set value( value: string ) {
127
+
128
+ this.m_props.value = value;
129
+
130
+ if( this.dom ) {
131
+ (<HTMLInputElement>this.dom).value = value;
132
+ }
133
+ }
134
+
135
+ public getStoreValue( ): any {
136
+
137
+ if( this.m_props.value_hook ) {
138
+ return this.m_props.value_hook.get( );
139
+ }
140
+ else {
141
+ let type = this.getAttribute('type');
142
+ if( type ) { type = type.toLowerCase( ); }
143
+
144
+ let value,
145
+ dom = (<HTMLInputElement>this.dom);
146
+
147
+ if( type === "file") {
148
+ value = [];
149
+
150
+ let files = dom.files;
151
+ for( let file = 0; file < files.length; file++ ) {
152
+ value.push( files[file].name );
153
+ }
154
+ }
155
+ else if ( type === 'checkbox' ) {
156
+ if( dom.checked ) {
157
+ value = 1;
158
+ }
159
+ else {
160
+ value = 0;
161
+ }
162
+ }
163
+ else if( type === 'radio' ) {
164
+ if( dom.checked ) {
165
+ value = this.value;
166
+ }
167
+ }
168
+ else if( type === 'date' ) {
169
+ debugger;
170
+ }
171
+ else {
172
+ value = this.value;
173
+ }
174
+
175
+ return value;
176
+ }
177
+ }
178
+
179
+ public setStoreValue( v: any ) {
180
+
181
+ if( this.m_props.value_hook ) {
182
+ return this.m_props.value_hook.set( v );
183
+ }
184
+ else {
185
+ let type = this.getAttribute('type'),
186
+ dom = (<HTMLInputElement>this.dom);
187
+
188
+ if( type ) { type = type.toLowerCase( ); }
189
+ if( type==='checkbox' ) {
190
+ let newval = v!==null && v!=='0' && v!==0 && v!==false;
191
+ if( newval!==dom.checked ) {
192
+ dom.setAttribute( 'checked', ''+newval );
193
+ dom.dispatchEvent( new Event( 'change' ) );
194
+ }
195
+ }
196
+ else {
197
+ this.value = v;
198
+ }
199
+ }
200
+ }
201
+
202
+ set readOnly( ro: boolean ) {
203
+ this.setAttribute('readonly', ro );
204
+ }
205
+
206
+ /**
207
+ * select all the text
208
+ */
209
+
210
+ public selectAll( ) {
211
+ (<HTMLInputElement>this.dom).select();
212
+ }
213
+
214
+ /**
215
+ * select a part of the text
216
+ * @param start
217
+ * @param length
218
+ */
219
+
220
+ public select( start: number, length: number = 9999 ) : void {
221
+ (<HTMLInputElement>this.dom).setSelectionRange( start, start+length );
222
+ }
223
+
224
+ /**
225
+ * get the selection as { start, length }
226
+ */
227
+
228
+ public getSelection( ) {
229
+ let idom = (<HTMLInputElement>this.dom);
230
+
231
+ return {
232
+ start: idom.selectionStart,
233
+ length: idom.selectionEnd - idom.selectionStart,
234
+ };
235
+ }
236
+ }