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
@@ -14,16 +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, ComponentEvent, ComponentEvents, ComponentProps, componentFromDOM } from '../../core/component';
17
+ import { class_ns } from '@core/core_tools';
18
+ import { Component, ComponentEvent, ComponentEvents, ComponentProps, EvSelectionChange, componentFromDOM } from '../../core/component';
18
19
 
20
+ import { ScrollView, Viewport } from '../viewport/viewport';
19
21
  import { Label } from '../label/label';
20
22
  import { ListboxID, ListItem, kbNav } from '../listbox/listbox';
21
23
  import { Box, BoxProps, HBox, VBox } from '../boxes/boxes';
22
- import { Icon } from '../icon/icon.js';
24
+ import { Icon } from '../icon/icon';
23
25
 
24
26
  import "./treeview.module.scss";
25
27
  import folder_icon from "./chevron-down-light.svg"
26
- import { class_ns } from '@core/core_tools.js';
28
+
27
29
 
28
30
  //import folder_closed from "./folder-minus-light.svg"
29
31
 
@@ -49,6 +51,7 @@ export interface TreeItem extends ListItem {
49
51
 
50
52
  interface TreeviewProps extends Omit<ComponentProps,"content"> {
51
53
  items: TreeItem[];
54
+ footer?: Component;
52
55
  }
53
56
 
54
57
  interface ChangeEvent extends ComponentEvent {
@@ -56,7 +59,7 @@ interface ChangeEvent extends ComponentEvent {
56
59
  }
57
60
 
58
61
  interface TreeviewEvents extends ComponentEvents {
59
- change: ChangeEvent;
62
+ selectionChange?: EvSelectionChange;
60
63
  }
61
64
 
62
65
  /**
@@ -78,8 +81,8 @@ class CTreeViewItem extends Box {
78
81
 
79
82
  if( item ) {
80
83
  this._label = new HBox( {cls:"label item", content: [
81
- this._icon = new Icon( { iconId: item.children? folder_icon : item.iconId } ),
82
- new Label( { tag: "span", cls: "", text: item.text } ),
84
+ this._icon = new Icon( { iconId: item.children ? folder_icon : undefined } ),
85
+ new Label( { tag: "span", cls: "", text: item.text, icon: item.iconId } ),
83
86
  ]});
84
87
 
85
88
  this._label.setData( "id", item.id+"" );
@@ -136,12 +139,19 @@ class CTreeViewItem extends Box {
136
139
  }
137
140
  }
138
141
 
142
+
143
+ // ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
144
+
145
+
146
+
139
147
  /**
140
148
  *
141
149
  */
142
150
 
143
151
  @class_ns( "x4" )
144
152
  export class Treeview extends Component<TreeviewProps,TreeviewEvents> {
153
+
154
+ private _view: Viewport;
145
155
  private _selection: ListboxID;
146
156
  private _selitem: Component;
147
157
  private _items: TreeItem[];
@@ -149,8 +159,16 @@ export class Treeview extends Component<TreeviewProps,TreeviewEvents> {
149
159
  constructor( props: TreeviewProps ) {
150
160
  super( props );
151
161
 
152
- if( props.items ) {
153
- this.setItems( props.items );
162
+ const scroller = new ScrollView( { cls: "body" } );
163
+ this._view = scroller.getViewport( );
164
+
165
+ this.setContent( [
166
+ scroller,
167
+ props.footer,
168
+ ] );
169
+
170
+ if( props.footer ) {
171
+ props.footer.setAttribute( "id", "footer" );
154
172
  }
155
173
 
156
174
  this.setAttribute( "tabindex", 0 );
@@ -158,6 +176,10 @@ export class Treeview extends Component<TreeviewProps,TreeviewEvents> {
158
176
  click: ( ev ) => this._onclick( ev ),
159
177
  keydown: ( ev ) => this._onkey( ev ),
160
178
  });
179
+
180
+ if( props.items ) {
181
+ this.setItems( props.items );
182
+ }
161
183
  }
162
184
 
163
185
  /**
@@ -165,11 +187,16 @@ export class Treeview extends Component<TreeviewProps,TreeviewEvents> {
165
187
  */
166
188
 
167
189
  setItems( items: TreeItem[ ] ) {
190
+ this.clearSelection( );
191
+ this._view.clearContent( );
168
192
  this._items = items;
169
193
 
170
194
  const root = new CTreeViewItem( { cls: "root"}, null );
171
- root.setItems( items );
172
- this.setContent( root );
195
+
196
+ if( items ) {
197
+ root.setItems( items );
198
+ this._view.setContent( root );
199
+ }
173
200
  }
174
201
 
175
202
  private _onclick( ev: UIEvent ) {
@@ -386,7 +413,7 @@ export class Treeview extends Component<TreeviewProps,TreeviewEvents> {
386
413
  }
387
414
 
388
415
  const itm = this._findItem( id );
389
- this.fire( "change", { selection: itm } );
416
+ this.fire( "selectionChange", { selection: itm, empty: false } );
390
417
  }
391
418
 
392
419
  private _findItem( id: ListboxID ) {
@@ -405,6 +432,14 @@ export class Treeview extends Component<TreeviewProps,TreeviewEvents> {
405
432
  }
406
433
 
407
434
  this._selection = undefined;
408
- this.fire( "change", { selection: undefined } );
435
+ this.fire( "selectionChange", { selection: undefined, empty: true } );
436
+ }
437
+
438
+ /**
439
+ *
440
+ */
441
+
442
+ getSelection( ) {
443
+ return this._selection;
409
444
  }
410
445
  }
@@ -18,6 +18,13 @@
18
18
 
19
19
  .x4scrollview {
20
20
  @extend .flex;
21
+
22
+ position: absolute;
23
+ height: 100%;
24
+ width: 100%;
25
+ left: 0;
26
+ top: 0;
27
+ overflow: auto;
21
28
  }
22
29
 
23
30
  .x4viewport {
@@ -14,7 +14,7 @@
14
14
  * that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
15
15
  **/
16
16
 
17
- import { isArray, UnsafeHtml, isNumber, Rect, Constructor, class_ns, x4_class_ns_sym } from './core_tools';
17
+ import { isArray, UnsafeHtml, isNumber, Rect, Constructor, class_ns, x4_class_ns_sym, IRect } from './core_tools';
18
18
  import { CoreElement } from './core_element';
19
19
  import { ariaValues, unitless } from './core_styles';
20
20
  import { CoreEvent, EventMap } from './core_events';
@@ -41,11 +41,15 @@ const RE_NUMBER = /^-?\d+(\.\d*)?$/;
41
41
  * to your class to avoid autogenerated css class names conflicts
42
42
  */
43
43
 
44
- function genClassNames( x: any ) {
44
+ function genClassNames( x: any ): string[] {
45
45
 
46
46
  let classes = [];
47
47
  let self = Object.getPrototypeOf(x);
48
48
 
49
+ if( self.constructor==Component ) {
50
+ return ["x4-comp"];
51
+ }
52
+
49
53
  while (self && self.constructor !== Component ) {
50
54
  const clsname:string = self.constructor.name;
51
55
  const clsns: string = self.constructor.hasOwnProperty(x4_class_ns_sym) ? self.constructor[x4_class_ns_sym] : "";
@@ -60,7 +64,7 @@ function genClassNames( x: any ) {
60
64
  *
61
65
  */
62
66
 
63
- export type ComponentContent = Component | string | UnsafeHtml | number | boolean | Component[];
67
+ export type ComponentContent = Component | Component[] | string | string[] | UnsafeHtml| UnsafeHtml[] | number | boolean;
64
68
 
65
69
  let gen_id = 1000;
66
70
 
@@ -89,6 +93,7 @@ export interface ComponentProps {
89
93
  height?: string | number;
90
94
  disabled?: true,
91
95
  hidden?: true,
96
+ flex?: boolean | number;
92
97
 
93
98
  tooltip?: string;
94
99
 
@@ -129,7 +134,7 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
129
134
  readonly props: P;
130
135
  protected readonly clsprefix: string; // internal class name prefix (x4 internal)
131
136
 
132
- private store: Map<string|Symbol,any>;
137
+ #store: Map<string|Symbol,any>;
133
138
 
134
139
  constructor( props: P ) {
135
140
  super( );
@@ -159,6 +164,15 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
159
164
  this.show( false );
160
165
  }
161
166
 
167
+ if( props.flex===true ) {
168
+ this.addClass( "x4flex" );
169
+ }
170
+ else if( props.flex!==undefined ) {
171
+ this.setStyle( {
172
+ "flexGrow": props.flex+""
173
+ });
174
+ }
175
+
162
176
  if( props.id!==undefined ) {
163
177
  this.setAttribute( "id", props.id );
164
178
  }
@@ -220,8 +234,9 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
220
234
 
221
235
  addClass( cls: string ) {
222
236
  if( !cls ) return;
223
-
237
+
224
238
  if( cls.indexOf(' ')>=0 ) {
239
+ cls = cls.trim( );
225
240
  const ccs = cls.split( " " );
226
241
  this.dom.classList.add(...ccs);
227
242
  }
@@ -231,11 +246,16 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
231
246
  }
232
247
 
233
248
  /**
234
- *
249
+ * special case: '*' mean clear class list
235
250
  */
236
251
 
237
252
  removeClass( cls: string ) {
238
253
  if( !cls ) return;
254
+
255
+ if( cls=='*' ) {
256
+ this.dom.classList.value = "";
257
+ return;
258
+ }
239
259
 
240
260
  if( cls.indexOf(' ')>=0 ) {
241
261
  const ccs = cls.split( " " );
@@ -295,10 +315,8 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
295
315
  */
296
316
 
297
317
  setAttributes( attrs: ComponentAttributes ) {
298
-
299
318
  for( const name in attrs ) {
300
- const value = attrs[name];
301
- this.setAttribute( name, value );
319
+ this.setAttribute( name, attrs[name] );
302
320
  }
303
321
  }
304
322
 
@@ -331,6 +349,18 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
331
349
  return this.getAttribute( "data-"+name );
332
350
  }
333
351
 
352
+ /**
353
+ * @returns undefined if not a number
354
+ */
355
+ getIntData( name: string ) : number {
356
+ const v = parseInt( this.getAttribute( "data-"+name ) );
357
+ if( Number.isFinite(v) ) {
358
+ return v;
359
+ }
360
+
361
+ return undefined;
362
+ }
363
+
334
364
  /**
335
365
  *
336
366
  */
@@ -344,16 +374,16 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
344
374
  */
345
375
 
346
376
  setInternalData( name: string|Symbol, value: any ): this {
347
- if( !this.store ) {
348
- this.store = new Map( );
377
+ if( !this.#store ) {
378
+ this.#store = new Map( );
349
379
  }
350
380
 
351
- this.store.set( name, value );
381
+ this.#store.set( name, value );
352
382
  return this;
353
383
  }
354
384
 
355
385
  getInternalData( name: string|Symbol ): any {
356
- return this.store?.get(name);
386
+ return this.#store?.get(name);
357
387
  }
358
388
 
359
389
 
@@ -387,7 +417,7 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
387
417
  protected mapPropEvents<N extends keyof E>(props: P, ...elements: N[] ) {
388
418
  const p = props as any;
389
419
  elements.forEach( n => {
390
- if (p.hasOwnProperty(n) ) {
420
+ if (p.hasOwnProperty(n) && p[n]) {
391
421
  this.on( n, p[n] );
392
422
  }
393
423
  });
@@ -465,17 +495,15 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
465
495
 
466
496
  prependContent( content: ComponentContent ) {
467
497
  const d = this.dom;
468
-
469
498
  const set = ( c: Component | string | UnsafeHtml | number | boolean ) => {
470
499
  if (c instanceof Component ) {
471
- d.insertBefore( d.firstChild, c.dom );
500
+ d.insertAdjacentElement( 'afterbegin', c.dom );
472
501
  }
473
502
  else if( c instanceof UnsafeHtml) {
474
- d.insertAdjacentHTML( 'beforebegin', c.toString() );
503
+ d.insertAdjacentHTML( 'afterbegin', c.toString() );
475
504
  }
476
505
  else if (typeof c === "string" || typeof c === "number") {
477
- const tnode = document.createTextNode(c.toString());
478
- d.insertBefore( d.firstChild, tnode );
506
+ d.insertAdjacentText( 'afterbegin', c.toString() );
479
507
  }
480
508
  else {
481
509
  console.warn("Unknown type to append: ", c);
@@ -512,7 +540,7 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
512
540
  queryAll( selector: string ): Component[] {
513
541
  const all = this.dom.querySelectorAll( selector );
514
542
  const rc = new Array( all.length );
515
- all.forEach( (x,i) => rc[i]=componentFromDOM(x) );
543
+ all.forEach( (x,i) => rc[i]=wrapDOM(x as HTMLElement) );
516
544
  return rc;
517
545
  }
518
546
 
@@ -525,6 +553,7 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
525
553
  return componentFromDOM<T>(r);
526
554
  }
527
555
 
556
+
528
557
  // :: STYLES ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
529
558
 
530
559
 
@@ -646,7 +675,7 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
646
675
  *
647
676
  */
648
677
 
649
- getBoundingRect( ): Rect {
678
+ getBoundingRect( ): IRect {
650
679
  const rc = this.dom.getBoundingClientRect( );
651
680
  return new Rect( rc.x, rc.y, rc.width, rc.height );
652
681
  }
@@ -657,8 +686,13 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
657
686
  *
658
687
  */
659
688
 
660
- focus( ) {
689
+ focus( ): this {
661
690
  (this.dom as HTMLElement).focus( );
691
+ return this;
692
+ }
693
+
694
+ hasFocus( ) {
695
+ return document.activeElement==this.dom;
662
696
  }
663
697
 
664
698
  /**
@@ -681,40 +715,49 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
681
715
  *
682
716
  */
683
717
 
684
- show( vis = true ) {
718
+ show( vis = true ): this {
685
719
  this.setClass( 'x4hidden', !vis );
720
+ return this;
686
721
  }
687
722
 
688
723
  /**
689
724
  *
690
725
  */
691
726
 
692
- hide( ) {
727
+ hide( ): this {
693
728
  this.show( false );
729
+ return this;
694
730
  }
695
731
 
696
732
  /**
697
733
  * enable or disable a component (all sub HTMLElement will be also disabled)
698
734
  */
699
735
 
700
- enable( ena = true ) {
701
- this.setAttribute( "disabled", !ena );
736
+ enable( ena = true ): this {
737
+ this.setAttribute( "disabled", !ena ? 'true' : null );
738
+
739
+ if( this.dom instanceof HTMLInputElement || this.dom instanceof HTMLButtonElement ) {
740
+ this.dom.disabled = !ena;
741
+ }
702
742
 
703
743
  // propagate diable state to all input children
704
744
  const nodes = this.enumChildNodes( true );
705
745
  nodes.forEach( x => {
706
- if( x instanceof HTMLInputElement ) {
746
+ if( x instanceof HTMLInputElement || x instanceof HTMLButtonElement ) {
707
747
  x.disabled = !ena;
708
748
  }
709
749
  });
750
+
751
+ return this;
710
752
  }
711
753
 
712
754
  /**
713
755
  *
714
756
  */
715
757
 
716
- disable( ) {
758
+ disable( ): this {
717
759
  this.enable( false );
760
+ return this;
718
761
  }
719
762
 
720
763
  /**
@@ -749,10 +792,17 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
749
792
  */
750
793
 
751
794
  parentElement<T extends Component>( cls?: Constructor<T> ): T {
752
- let p = this.dom;
795
+ return Component.parentElement<T>( this.dom, cls );
796
+ }
753
797
 
754
- while( p.parentElement ) {
755
- const cp = componentFromDOM( p.parentElement );
798
+ /**
799
+ * search for parent that match the given contructor
800
+ */
801
+
802
+ static parentElement<T extends Component>( dom: Node, cls?: Constructor<T> ): T {
803
+
804
+ while( dom.parentElement ) {
805
+ const cp = componentFromDOM( dom.parentElement );
756
806
  if( !cls ) {
757
807
  return cp as T;
758
808
  }
@@ -761,7 +811,7 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
761
811
  return cp;
762
812
  }
763
813
 
764
- p = p.parentElement;
814
+ dom = dom.parentElement;
765
815
  }
766
816
 
767
817
  return null;
@@ -875,7 +925,11 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
875
925
  // :: SPECIALS ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
876
926
 
877
927
  /**
928
+ * system interfaces:
929
+ * "form-element"
930
+ * "tab-handler"
878
931
  *
932
+ * each app can create it's own interface
879
933
  */
880
934
 
881
935
  queryInterface<T>( name: string ): T {
@@ -923,6 +977,13 @@ export class Flex extends Component {
923
977
  }
924
978
  }
925
979
 
980
+ // just a spacer element that push other
981
+ export class Space extends Component {
982
+ constructor( width?: number|string, cls?: string ) {
983
+ super( { width, cls } )
984
+ }
985
+ }
986
+
926
987
 
927
988
  // :: HIGH LEVEL BASIC EVENTS ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
928
989
 
@@ -945,6 +1006,14 @@ export interface EvChange extends ComponentEvent {
945
1006
  readonly value: any;
946
1007
  }
947
1008
 
1009
+ /**
1010
+ * Focus event
1011
+ */
1012
+
1013
+ export interface EvFocus extends ComponentEvent {
1014
+ readonly focus_out: boolean;
1015
+ }
1016
+
948
1017
  /**
949
1018
  * Selection Event
950
1019
  * value is the new selection or null
@@ -955,6 +1024,7 @@ interface ISelection {
955
1024
 
956
1025
  export interface EvSelectionChange extends ComponentEvent {
957
1026
  readonly selection: ISelection;
1027
+ readonly empty: boolean;
958
1028
  }
959
1029
 
960
1030