x4js 2.0.13 → 2.0.14

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 (258) hide show
  1. package/.vscode/launch.json +14 -0
  2. package/README.md +5 -0
  3. package/{lib/src/demo → demo}/main.scss +3 -1
  4. package/{lib/src/demo/main.tsx → demo/main.ts} +37 -36
  5. package/demo/package.json +26 -0
  6. package/demo/scss.d.ts +4 -0
  7. package/demo/svg.d.ts +1 -0
  8. package/demo/tsconfig.json +14 -0
  9. package/lib/README.txt +5 -0
  10. package/lib/cjs/x4.css +1 -1
  11. package/lib/cjs/x4.js +2 -1
  12. package/lib/esm/x4.css +1 -1
  13. package/lib/esm/x4.mjs +2 -1
  14. package/lib/src/components/boxes/boxes.module.scss +17 -0
  15. package/lib/src/components/boxes/boxes.ts +162 -13
  16. package/lib/src/components/breadcrumb/breadcrumb.scss +56 -28
  17. package/lib/src/components/breadcrumb/breadcrumb.ts +93 -84
  18. package/lib/src/components/btngroup/btngroup.module.scss +12 -0
  19. package/lib/src/components/btngroup/btngroup.ts +41 -8
  20. package/lib/src/components/button/button.module.scss +23 -5
  21. package/lib/src/components/button/button.ts +72 -4
  22. package/lib/src/components/canvas/canvas.module.scss +25 -0
  23. package/lib/src/components/canvas/canvas.ts +189 -0
  24. package/lib/src/components/canvas/canvas_ex.ts +269 -0
  25. package/lib/src/components/checkbox/checkbox.ts +18 -4
  26. package/lib/src/components/combobox/combobox.module.scss +24 -15
  27. package/lib/src/components/combobox/combobox.ts +107 -24
  28. package/lib/src/components/components.ts +7 -0
  29. package/lib/src/components/dialog/dialog.module.scss +37 -3
  30. package/lib/src/components/dialog/dialog.ts +149 -31
  31. package/lib/src/components/filedrop/cloud-arrow-up.svg +1 -0
  32. package/lib/src/components/filedrop/filedrop.module.scss +70 -0
  33. package/lib/src/components/filedrop/filedrop.ts +131 -0
  34. package/lib/src/components/form/form.module.scss +4 -0
  35. package/lib/src/components/form/form.ts +137 -6
  36. package/lib/src/components/gridview/arrow-down-light.svg +1 -0
  37. package/lib/src/components/gridview/arrow-up-light.svg +1 -0
  38. package/lib/src/components/gridview/gridview.module.scss +324 -0
  39. package/lib/src/components/gridview/gridview.ts +1175 -0
  40. package/lib/src/components/icon/icon.module.scss +1 -1
  41. package/lib/src/components/icon/icon.ts +4 -1
  42. package/lib/src/components/image/image.module.scss +8 -1
  43. package/lib/src/components/image/image.ts +105 -6
  44. package/lib/src/components/input/input.module.scss +8 -3
  45. package/lib/src/components/input/input.ts +137 -14
  46. package/lib/src/components/keyboard/arrow-up.svg +1 -0
  47. package/lib/src/components/keyboard/delete-left.svg +1 -0
  48. package/lib/src/components/keyboard/eye-slash.svg +1 -0
  49. package/lib/src/components/keyboard/keyboard.module.scss +134 -0
  50. package/lib/src/components/keyboard/keyboard.ts +525 -0
  51. package/lib/src/components/label/label.module.scss +22 -4
  52. package/lib/src/components/label/label.ts +33 -0
  53. package/lib/src/components/link/link.ts +81 -78
  54. package/lib/src/components/listbox/listbox.module.scss +61 -3
  55. package/lib/src/components/listbox/listbox.ts +164 -56
  56. package/lib/src/components/menu/menu.module.scss +10 -1
  57. package/lib/src/components/menu/menu.ts +4 -1
  58. package/lib/src/components/messages/messages.module.scss +44 -0
  59. package/lib/src/components/messages/messages.ts +164 -18
  60. package/lib/src/components/messages/pen-field.svg +1 -0
  61. package/lib/src/components/normalize.scss +5 -0
  62. package/lib/src/components/notification/notification.module.scss +4 -2
  63. package/lib/src/components/notification/notification.ts +2 -4
  64. package/lib/src/components/panel/panel.module.scss +12 -0
  65. package/lib/src/components/popup/popup.module.scss +4 -2
  66. package/lib/src/components/popup/popup.ts +136 -92
  67. package/lib/src/components/propgrid/folder-closed.svg +1 -0
  68. package/lib/src/components/propgrid/folder-open.svg +1 -0
  69. package/lib/src/components/propgrid/progrid.module.scss +108 -0
  70. package/lib/src/components/propgrid/propgrid.ts +271 -0
  71. package/lib/src/components/propgrid/updown.svg +4 -0
  72. package/lib/src/components/radio/radio.module.scss +147 -0
  73. package/lib/src/components/radio/radio.svg +4 -0
  74. package/lib/src/components/radio/radio.ts +142 -0
  75. package/lib/src/components/select/select.module.scss +9 -0
  76. package/lib/src/components/select/select.ts +134 -0
  77. package/lib/src/components/shared.scss +47 -0
  78. package/lib/src/components/sizers/sizer.ts +9 -2
  79. package/lib/src/components/slider/slider.module.scss +77 -30
  80. package/lib/src/components/slider/slider.ts +72 -22
  81. package/lib/src/components/tabs/tabs.module.scss +1 -2
  82. package/lib/src/components/tabs/tabs.ts +43 -12
  83. package/lib/src/components/textarea/textarea.module.scss +6 -2
  84. package/lib/src/components/textarea/textarea.ts +73 -8
  85. package/lib/src/components/textedit/textedit.module.scss +3 -1
  86. package/lib/src/components/textedit/textedit.ts +31 -4
  87. package/lib/src/components/themes.scss +7 -0
  88. package/lib/src/components/tickline/tickline.module.scss +26 -0
  89. package/lib/src/components/tickline/tickline.ts +82 -0
  90. package/lib/src/components/tooltips/comments-question.svg +1 -0
  91. package/lib/src/components/tooltips/tooltips.scss +30 -9
  92. package/lib/src/components/tooltips/tooltips.ts +10 -5
  93. package/lib/src/components/treeview/treeview.module.scss +129 -60
  94. package/lib/src/components/treeview/treeview.ts +47 -12
  95. package/lib/src/components/viewport/viewport.module.scss +7 -0
  96. package/lib/src/core/component.ts +102 -32
  97. package/lib/src/core/core_application.ts +222 -2
  98. package/lib/src/core/core_colors.ts +2 -2
  99. package/lib/src/{components/grid/datastore.ts → core/core_data.ts} +261 -250
  100. package/lib/src/core/core_dragdrop.ts +3 -3
  101. package/lib/src/core/core_element.ts +13 -1
  102. package/lib/src/core/core_events.ts +28 -0
  103. package/lib/src/core/core_i18n.ts +18 -2
  104. package/lib/src/core/core_react.ts +79 -0
  105. package/lib/src/core/core_router.ts +23 -7
  106. package/lib/src/core/core_styles.ts +5 -5
  107. package/lib/src/core/core_svg.ts +173 -12
  108. package/lib/src/core/core_tools.ts +305 -87
  109. package/lib/src/x4tsx.d.ts +25 -0
  110. package/lib/styles/x4.css +1 -1
  111. package/lib/types/x4js.d.ts +767 -92
  112. package/package.json +4 -4
  113. package/scripts/build.mjs +378 -0
  114. package/scripts/prepack.mjs +346 -0
  115. package/src/components/base.scss +25 -0
  116. package/src/components/boxes/boxes.module.scss +54 -0
  117. package/src/components/boxes/boxes.ts +278 -0
  118. package/src/components/breadcrumb/breadcrumb.scss +56 -0
  119. package/src/components/breadcrumb/breadcrumb.ts +93 -0
  120. package/src/components/breadcrumb/chevron-right.svg +1 -0
  121. package/src/components/btngroup/btngroup.module.scss +41 -0
  122. package/src/components/btngroup/btngroup.ts +153 -0
  123. package/src/components/button/button.module.scss +173 -0
  124. package/src/components/button/button.ts +185 -0
  125. package/src/components/calendar/calendar-check-sharp-light.svg +1 -0
  126. package/src/components/calendar/calendar.module.scss +163 -0
  127. package/src/components/calendar/calendar.ts +327 -0
  128. package/src/components/calendar/chevron-left-sharp-light.svg +1 -0
  129. package/src/components/calendar/chevron-right-sharp-light.svg +1 -0
  130. package/src/components/canvas/canvas.module.scss +25 -0
  131. package/src/components/canvas/canvas.ts +189 -0
  132. package/src/components/canvas/canvas_ex.ts +269 -0
  133. package/src/components/checkbox/check.svg +4 -0
  134. package/src/components/checkbox/checkbox.module.scss +142 -0
  135. package/src/components/checkbox/checkbox.ts +140 -0
  136. package/src/components/colorinput/colorinput.module.scss +65 -0
  137. package/src/components/colorinput/colorinput.ts +91 -0
  138. package/src/components/colorinput/crosshairs-simple-sharp-light.svg +1 -0
  139. package/src/components/colorpicker/colorpicker.module.scss +133 -0
  140. package/src/components/colorpicker/colorpicker.ts +482 -0
  141. package/src/components/combobox/combobox.module.scss +133 -0
  142. package/src/components/combobox/combobox.ts +275 -0
  143. package/src/components/combobox/updown.svg +4 -0
  144. package/src/components/components.ts +41 -0
  145. package/src/components/dialog/dialog.module.scss +105 -0
  146. package/src/components/dialog/dialog.ts +212 -0
  147. package/src/components/dialog/xmark-sharp-light.svg +1 -0
  148. package/src/components/filedrop/cloud-arrow-up.svg +1 -0
  149. package/src/components/filedrop/filedrop.module.scss +70 -0
  150. package/src/components/filedrop/filedrop.ts +131 -0
  151. package/src/components/form/form.module.scss +38 -0
  152. package/src/components/form/form.ts +172 -0
  153. package/src/components/gridview/arrow-down-light.svg +1 -0
  154. package/src/components/gridview/arrow-up-light.svg +1 -0
  155. package/src/components/gridview/gridview.module.scss +324 -0
  156. package/src/components/gridview/gridview.ts +1175 -0
  157. package/src/components/header/header.module.scss +40 -0
  158. package/src/components/header/header.ts +130 -0
  159. package/src/components/icon/icon.module.scss +30 -0
  160. package/src/components/icon/icon.ts +139 -0
  161. package/src/components/image/image.module.scss +28 -0
  162. package/src/components/image/image.ts +168 -0
  163. package/src/components/input/input.module.scss +74 -0
  164. package/src/components/input/input.ts +398 -0
  165. package/src/components/keyboard/arrow-up.svg +1 -0
  166. package/src/components/keyboard/delete-left.svg +1 -0
  167. package/src/components/keyboard/eye-slash.svg +1 -0
  168. package/src/components/keyboard/keyboard.module.scss +134 -0
  169. package/src/components/keyboard/keyboard.ts +525 -0
  170. package/src/components/label/label.module.scss +76 -0
  171. package/src/components/label/label.ts +97 -0
  172. package/src/components/link/link.ts +81 -0
  173. package/src/components/listbox/listbox.module.scss +161 -0
  174. package/src/components/listbox/listbox.ts +539 -0
  175. package/src/components/menu/caret-right-solid.svg +1 -0
  176. package/src/components/menu/menu.module.scss +117 -0
  177. package/src/components/menu/menu.ts +174 -0
  178. package/src/components/messages/circle-exclamation.svg +1 -0
  179. package/src/components/messages/messages.module.scss +92 -0
  180. package/src/components/messages/messages.ts +215 -0
  181. package/src/components/messages/pen-field.svg +1 -0
  182. package/src/components/normalize.scss +391 -0
  183. package/src/components/notification/circle-check-solid.svg +1 -0
  184. package/src/components/notification/circle-exclamation-solid.svg +1 -0
  185. package/src/components/notification/circle-notch-light.svg +1 -0
  186. package/src/components/notification/notification.module.scss +84 -0
  187. package/src/components/notification/notification.ts +107 -0
  188. package/src/components/notification/xmark-sharp-light.svg +1 -0
  189. package/src/components/panel/panel.module.scss +60 -0
  190. package/src/components/panel/panel.ts +58 -0
  191. package/src/components/popup/popup.module.scss +45 -0
  192. package/src/components/popup/popup.ts +440 -0
  193. package/src/components/progress/progress.module.scss +57 -0
  194. package/src/components/progress/progress.ts +44 -0
  195. package/src/components/propgrid/folder-closed.svg +1 -0
  196. package/src/components/propgrid/folder-open.svg +1 -0
  197. package/src/components/propgrid/progrid.module.scss +108 -0
  198. package/src/components/propgrid/propgrid.ts +271 -0
  199. package/src/components/propgrid/updown.svg +4 -0
  200. package/src/components/radio/radio.module.scss +147 -0
  201. package/src/components/radio/radio.svg +4 -0
  202. package/src/components/radio/radio.ts +142 -0
  203. package/src/components/rating/rating.module.scss +23 -0
  204. package/src/components/rating/rating.ts +131 -0
  205. package/src/components/rating/star-sharp-light.svg +1 -0
  206. package/src/components/rating/star-sharp-solid.svg +1 -0
  207. package/src/components/select/select.module.scss +9 -0
  208. package/src/components/select/select.ts +134 -0
  209. package/src/components/shared.scss +137 -0
  210. package/src/components/sizers/sizer.module.scss +90 -0
  211. package/src/components/sizers/sizer.ts +131 -0
  212. package/src/components/slider/slider.module.scss +118 -0
  213. package/src/components/slider/slider.ts +198 -0
  214. package/src/components/switch/switch.module.scss +127 -0
  215. package/src/components/switch/switch.ts +62 -0
  216. package/src/components/tabs/tabs.module.scss +45 -0
  217. package/src/components/tabs/tabs.ts +199 -0
  218. package/src/components/textarea/textarea.module.scss +63 -0
  219. package/src/components/textarea/textarea.ts +125 -0
  220. package/src/components/textedit/textedit.module.scss +116 -0
  221. package/src/components/textedit/textedit.ts +110 -0
  222. package/src/components/themes.scss +88 -0
  223. package/src/components/tickline/tickline.module.scss +26 -0
  224. package/src/components/tickline/tickline.ts +82 -0
  225. package/src/components/tooltips/circle-info-sharp-light.svg +1 -0
  226. package/src/components/tooltips/comments-question.svg +1 -0
  227. package/src/components/tooltips/tooltips.scss +72 -0
  228. package/src/components/tooltips/tooltips.ts +109 -0
  229. package/src/components/treeview/chevron-down-light.svg +1 -0
  230. package/src/components/treeview/treeview.module.scss +185 -0
  231. package/src/components/treeview/treeview.ts +445 -0
  232. package/src/components/viewport/viewport.module.scss +32 -0
  233. package/src/components/viewport/viewport.ts +41 -0
  234. package/src/core/component.ts +1072 -0
  235. package/src/core/core_application.ts +264 -0
  236. package/src/core/core_colors.ts +250 -0
  237. package/src/core/core_data.ts +1309 -0
  238. package/src/core/core_dom.ts +471 -0
  239. package/src/core/core_dragdrop.ts +201 -0
  240. package/src/core/core_element.ts +110 -0
  241. package/src/core/core_events.ts +177 -0
  242. package/src/core/core_i18n.ts +393 -0
  243. package/src/core/core_react.ts +79 -0
  244. package/src/core/core_router.ts +237 -0
  245. package/src/core/core_styles.ts +214 -0
  246. package/src/core/core_svg.ts +711 -0
  247. package/src/core/core_tools.ts +906 -0
  248. package/src/types/scss.d.ts +4 -0
  249. package/src/types/svg.d.ts +1 -0
  250. package/src/types/x4react.d.ts +9 -0
  251. package/src/x4.scss +19 -0
  252. package/src/x4tsx.d.ts +25 -0
  253. package/tsconfig.json +14 -0
  254. package/lib/src/components/grid/gridview.ts +0 -1108
  255. package/lib/src/components/grid/memdb.ts +0 -325
  256. /package/{lib/src/demo → demo}/assets/house-light.svg +0 -0
  257. /package/{lib/src/demo → demo}/assets/radio.svg +0 -0
  258. /package/{lib/src/demo → demo}/index.html +0 -0
@@ -27,4 +27,4 @@
27
27
  width: 100%;
28
28
  height: 100%;
29
29
  }
30
- }
30
+ }
@@ -103,6 +103,8 @@ export class Icon extends Component<IconProps> {
103
103
  */
104
104
 
105
105
  setIcon( iconId: string ) {
106
+ this.clearContent( );
107
+
106
108
  if( iconId ) {
107
109
  if( iconId.startsWith('var:') ) {
108
110
  do {
@@ -123,9 +125,10 @@ export class Icon extends Component<IconProps> {
123
125
  else {
124
126
  this.setContent( new Component( { tag: "img", attrs: { src: iconId } } ) );
125
127
  }
128
+
129
+ this.removeClass( "empty" );
126
130
  }
127
131
  else {
128
- this.clearContent( );
129
132
  this.addClass( "empty" );
130
133
  }
131
134
  }
@@ -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
- .x-image {
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 '@core/core_tools.js';
18
- import { Component, ComponentProps } from '../../core/component.js';
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<ImageProps> {
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: ImageProps ) {
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
- this._img.setAttribute( "src", src );
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: 8px 4px;
42
+ padding: 4px 4px;
39
43
  }
40
44
 
41
45
  &[type="checkbox"]:checked,
42
46
  &[type="radio"]:checked {
43
- accent-color: var( --color-80 );
47
+ accent-color: var( --input-checkbox-color );
48
+ padding: 2px;
44
49
  }
45
50
 
46
51
  &[type="range"] {
47
- accent-color: var( --color-60 );
52
+ accent-color: var( --input-checkbox-color );
48
53
  }
49
54
 
50
55
  &::placeholder {
@@ -14,13 +14,18 @@
14
14
  * that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
15
15
  **/
16
16
 
17
- import { Component, ComponentProps } from '../../core/component';
18
- import { class_ns, IComponentInterface, IFormElement } from '../../core/core_tools.js';
17
+ import { EventCallback } from '@core/core_events.js';
18
+ import { Component, ComponentEvent, ComponentProps, EvChange, EvFocus } from '../../core/component';
19
+ import { class_ns, 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
+
27
+ focus?: EventCallback<EvFocus>;
28
+ change?: EventCallback<EvChange>;
24
29
  }
25
30
 
26
31
  interface CheckboxProps extends BaseProps {
@@ -66,38 +71,51 @@ interface FileProps extends BaseProps {
66
71
  }
67
72
 
68
73
  export interface TextInputProps extends BaseProps {
69
- type: "text" | "email" | "password";
74
+ type: "text" | "email" | "password" | "date" | "number";
70
75
  readonly?: boolean;
71
76
  required?: boolean;
72
77
  pattern?: string;
73
- value: string | number;
78
+ value?: string | number;
74
79
  placeholder?: string;
75
80
  spellcheck?: boolean;
81
+ minlength?: number;
82
+ maxlength?: number;
76
83
  }
77
84
 
78
85
 
79
86
  export type InputProps = CheckboxProps | RadioProps | TextInputProps | RangeProps | DateProps | NumberProps | FileProps;
80
87
 
81
88
 
89
+ interface InputEvents extends ComponentEvent {
90
+ focus: EvFocus;
91
+ change: EvChange;
92
+ }
93
+
82
94
 
83
95
  /**
84
96
  *
85
97
  */
86
98
 
87
99
  @class_ns( "x4" )
88
- export class Input extends Component<InputProps> {
100
+ export class Input extends Component<InputProps,InputEvents> {
89
101
  constructor( props: InputProps ) {
90
102
  super( { tag: "input", ...props } );
91
103
 
104
+ this.mapPropEvents( props, "focus", "change" );
105
+
92
106
  this.setAttribute( "type", props.type ?? "text" );
93
107
  this.setAttribute( "name", props.name );
108
+
109
+ if( props.autofocus===true ) {
110
+ this.setAttribute( "autofocus", true );
111
+ }
94
112
 
95
113
  switch( props.type ) {
96
114
  case "checkbox":
97
115
  case "radio": {
98
116
  const ck = this.dom as HTMLInputElement;
99
117
  ck.checked = props.checked;
100
- ck.value = props.value+"";
118
+ ck.value = props.value === undefined ? "" : props.value+"";
101
119
  //this.setAttribute( "checked", props.checked );
102
120
  //this.setAttribute( "value", props.value );
103
121
  break;
@@ -112,12 +130,27 @@ export class Input extends Component<InputProps> {
112
130
  }
113
131
 
114
132
  case "number": {
115
- this.setAttribute( "required", props.required );
116
- this.setAttribute( "readonly", props.readonly );
117
- this.setAttribute( "min", props.min );
118
- this.setAttribute( "max", props.max );
119
- this.setAttribute( "step", props.step );
120
- this.setAttribute( "value", props.value+'' );
133
+ const p = this.props as NumberProps;
134
+
135
+ this.setAttribute( "required", p.required );
136
+ this.setAttribute( "readonly", p.readonly );
137
+ this.setAttribute( "min", p.min );
138
+ this.setAttribute( "max", p.max );
139
+ this.setAttribute( "step", p.step );
140
+ //this.setAttribute( "value", p.value+'' );
141
+ this.setNumValue( isString(p.value) ? parseFloat(p.value) : p.value, -2 );
142
+
143
+ this.addDOMEvent( "wheel", ( e: WheelEvent ) => {
144
+ if( this.hasFocus() ) { // only if has focus
145
+ e.preventDefault( );
146
+ let v = this.getNumValue();
147
+ const delta = e.deltaY < 0 ? 1 : -1;
148
+ v += (p.step ? p.step : 1) * delta;
149
+ this.setNumValue( v, -2 );
150
+
151
+ this.dom.dispatchEvent(new Event('input'));
152
+ }
153
+ }, );
121
154
  break;
122
155
  }
123
156
 
@@ -168,9 +201,48 @@ export class Input extends Component<InputProps> {
168
201
  this.setAttribute( "spellcheck", false );
169
202
  }
170
203
 
204
+ if( props.minlength!==undefined ) {
205
+ this.setAttribute( "minlength", props.minlength );
206
+ }
207
+
208
+ if( props.maxlength!==undefined ) {
209
+ this.setAttribute( "maxlength", props.maxlength );
210
+ }
211
+
171
212
  break;
172
213
  }
173
214
  }
215
+
216
+ this.addDOMEvent( "blur", ( e ) => { this.on_focus(e,true);} );
217
+ this.addDOMEvent( "focus", ( e ) => { this.on_focus(e,false);} );
218
+ this.addDOMEvent( "input", ( e ) => { this.on_change(e as InputEvent); });
219
+ }
220
+
221
+ /**
222
+ *
223
+ */
224
+
225
+ private on_focus( ev: FocusEvent, focus_out: boolean ) {
226
+ const event: EvFocus = { focus_out }
227
+ this.fire( "focus", event );
228
+
229
+ if( event.defaultPrevented ) {
230
+ ev.preventDefault( );
231
+ }
232
+ }
233
+
234
+ /**
235
+ *
236
+ */
237
+
238
+ private on_change( ev: InputEvent ) {
239
+
240
+ const event: EvChange = { value: this.getValue() };
241
+ this.fire( "change", event );
242
+
243
+ if( event.defaultPrevented ) {
244
+ ev.preventDefault( );
245
+ }
174
246
  }
175
247
 
176
248
  /**
@@ -202,12 +274,46 @@ export class Input extends Component<InputProps> {
202
274
  /**
203
275
  *
204
276
  * @param value
277
+ * @param ndec number of decimals or -1 for auto, -2 as prop.step
278
+ *
205
279
  */
206
280
 
207
- public setNumValue( value: number ) {
281
+ public setNumValue( value: number, ndec = -1 ) {
282
+
283
+ if( ndec==-2 && this.props.type=='number' ) {
284
+ const p = this.props as NumberProps;
285
+
286
+ if( p.step ) {
287
+ let ndec = -Math.floor(Math.log10(p.step ?? 1) );
288
+ return this.setValue( value.toFixed(ndec) );
289
+ }
290
+ }
291
+ else if( ndec>=0 ) {
292
+ return this.setValue( value.toFixed(ndec) );
293
+ }
294
+
208
295
  this.setValue( value+"" );
209
296
  }
210
297
 
298
+ /**
299
+ * @return the checked value
300
+ */
301
+
302
+ public getCheck() {
303
+ const d = this.dom as HTMLInputElement;
304
+ return d.checked;
305
+ }
306
+
307
+ /**
308
+ * change the checked value
309
+ * @param {boolean} ck new checked value
310
+ */
311
+
312
+ public setCheck(ck: boolean) {
313
+ const d = this.dom as HTMLInputElement;
314
+ d.checked = ck;
315
+ }
316
+
211
317
  /**
212
318
  *
213
319
  */
@@ -250,6 +356,22 @@ export class Input extends Component<InputProps> {
250
356
  };
251
357
  }
252
358
 
359
+ /**
360
+ *
361
+ */
362
+
363
+ public isValid( ) {
364
+
365
+ if( (this.props as any).required ) {
366
+ const v = this.getValue( );
367
+ if( v==="" ) {
368
+ return false;
369
+ }
370
+ }
371
+
372
+ return true;
373
+ }
374
+
253
375
  /**
254
376
  *
255
377
  */
@@ -258,7 +380,8 @@ export class Input extends Component<InputProps> {
258
380
  if( name=="form-element" ) {
259
381
  const i: IFormElement = {
260
382
  getRawValue: ( ): any => { return this.getValue(); },
261
- setRawValue: ( v: any ) => { this.setValue(v); }
383
+ setRawValue: ( v: any ) => { this.setValue(v); },
384
+ isValid: ( ) => { return this.isValid(); }
262
385
  };
263
386
 
264
387
  //@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>
@@ -0,0 +1,134 @@
1
+ /**
2
+ * ___ ___ __
3
+ * \ \/ / / _
4
+ * \ / /_| |_
5
+ * / \____ _|
6
+ * /__/\__\ |_|.2
7
+ *
8
+ * @file keyboard.module.scss
9
+ * @author Etienne Cochard
10
+ *
11
+ * @copyright (c) 2024 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
+ :root {
18
+ --keyboard-key-background: #33302d;
19
+ --keyboard-hilite-color: #5ba921;
20
+ }
21
+
22
+ .x4keyboard {
23
+ z-index: 2000;
24
+ position: absolute !important;
25
+ width: 100vw;
26
+ height: 14rem;
27
+ bottom: 0;
28
+
29
+ background-color: rgba(0,0,0,0.9);
30
+
31
+ box-sizing: border-box;
32
+ padding: 4px;
33
+
34
+ #kb {
35
+ width: 100vw;
36
+ max-width: 800px;
37
+ }
38
+
39
+ .line {
40
+ flex-grow: 10;
41
+ position: relative;
42
+ }
43
+
44
+ .mi {
45
+ font-family: 'Material Icons';
46
+ font-size: 22px;
47
+ text-align: center;
48
+ }
49
+
50
+ .tch {
51
+ cursor: pointer;
52
+
53
+ flex-grow: 10;
54
+ flex-basis: 44px;
55
+
56
+ display: flex;
57
+ align-items: center;
58
+
59
+ div {
60
+ width: 100%;
61
+ }
62
+
63
+ color: white;
64
+ text-align: center;
65
+
66
+ background-color: var( --keyboard-key-background);
67
+ border: 1px solid var( --keyboard-key-background);
68
+
69
+ border-radius: 4px;
70
+ margin: 2px 4px;
71
+ box-sizing: border-box;
72
+
73
+ &:hover {
74
+ border: 1px solid var( --keyboard-hilite-color);
75
+ }
76
+
77
+ &:active {
78
+ background-color: var( --keyboard-hilite-color);
79
+ color: var( --keyboard-key-background);
80
+ }
81
+ }
82
+
83
+
84
+ .cplace {
85
+ visibility: hidden;
86
+ }
87
+
88
+ .kbicon {
89
+ div {
90
+ width: 0;
91
+ }
92
+ }
93
+
94
+ .cret {
95
+ color: var( --keyboard-hilite-color);
96
+ font-weight: bold;
97
+ }
98
+
99
+ .cdel,
100
+ .cshift,
101
+ .chide {
102
+ .x4icon {
103
+ margin: auto;
104
+ color: var( --keyboard-hilite-color);
105
+ }
106
+ }
107
+
108
+ // color: rgba(255,255,255,0.3);
109
+
110
+ .lower,
111
+ .upper {
112
+
113
+ .cspace {
114
+ flex-basis: 689px;
115
+ }
116
+
117
+ .cret {
118
+ flex-basis: 84px;
119
+ }
120
+
121
+ .cshift {
122
+ flex-basis: 60px;
123
+ }
124
+
125
+ .chide {
126
+ flex-basis: 88px;
127
+ }
128
+
129
+ .cnum {
130
+ flex-basis: 88px;
131
+ }
132
+ }
133
+ }
134
+