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.
Files changed (260) 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 +258 -17
  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 +276 -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 +40 -7
  30. package/lib/src/components/dialog/dialog.ts +166 -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 +2 -1
  41. package/lib/src/components/icon/icon.ts +4 -3
  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 +178 -31
  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 +526 -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 +6 -3
  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 +10 -2
  66. package/lib/src/components/popup/popup.ts +141 -95
  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 +112 -0
  70. package/lib/src/components/propgrid/propgrid.ts +288 -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 +10 -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 +49 -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 +47 -15
  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 +113 -40
  97. package/lib/src/core/core_application.ts +223 -2
  98. package/lib/src/core/core_colors.ts +2 -2
  99. package/lib/src/{components/grid/datastore.ts → core/core_data.ts} +264 -252
  100. package/lib/src/core/core_dragdrop.ts +3 -3
  101. package/lib/src/core/core_element.ts +18 -1
  102. package/lib/src/core/core_events.ts +28 -0
  103. package/lib/src/core/core_i18n.ts +19 -3
  104. package/lib/src/core/core_react.ts +79 -0
  105. package/lib/src/core/core_router.ts +25 -9
  106. package/lib/src/core/core_state.ts +62 -0
  107. package/lib/src/core/core_styles.ts +5 -5
  108. package/lib/src/core/core_svg.ts +174 -12
  109. package/lib/src/core/core_tools.ts +305 -87
  110. package/lib/src/x4tsx.d.ts +25 -0
  111. package/lib/styles/x4.css +1 -1
  112. package/lib/types/x4js.d.ts +828 -119
  113. package/package.json +4 -4
  114. package/scripts/build.mjs +378 -0
  115. package/scripts/prepack.mjs +346 -0
  116. package/src/components/base.scss +25 -0
  117. package/src/components/boxes/boxes.module.scss +54 -0
  118. package/src/components/boxes/boxes.ts +370 -0
  119. package/src/components/breadcrumb/breadcrumb.scss +56 -0
  120. package/src/components/breadcrumb/breadcrumb.ts +93 -0
  121. package/src/components/breadcrumb/chevron-right.svg +1 -0
  122. package/src/components/btngroup/btngroup.module.scss +41 -0
  123. package/src/components/btngroup/btngroup.ts +153 -0
  124. package/src/components/button/button.module.scss +173 -0
  125. package/src/components/button/button.ts +185 -0
  126. package/src/components/calendar/calendar-check-sharp-light.svg +1 -0
  127. package/src/components/calendar/calendar.module.scss +163 -0
  128. package/src/components/calendar/calendar.ts +327 -0
  129. package/src/components/calendar/chevron-left-sharp-light.svg +1 -0
  130. package/src/components/calendar/chevron-right-sharp-light.svg +1 -0
  131. package/src/components/canvas/canvas.module.scss +25 -0
  132. package/src/components/canvas/canvas.ts +189 -0
  133. package/src/components/canvas/canvas_ex.ts +276 -0
  134. package/src/components/checkbox/check.svg +4 -0
  135. package/src/components/checkbox/checkbox.module.scss +142 -0
  136. package/src/components/checkbox/checkbox.ts +140 -0
  137. package/src/components/colorinput/colorinput.module.scss +65 -0
  138. package/src/components/colorinput/colorinput.ts +91 -0
  139. package/src/components/colorinput/crosshairs-simple-sharp-light.svg +1 -0
  140. package/src/components/colorpicker/colorpicker.module.scss +133 -0
  141. package/src/components/colorpicker/colorpicker.ts +482 -0
  142. package/src/components/combobox/combobox.module.scss +133 -0
  143. package/src/components/combobox/combobox.ts +275 -0
  144. package/src/components/combobox/updown.svg +4 -0
  145. package/src/components/components.ts +41 -0
  146. package/src/components/dialog/dialog.module.scss +104 -0
  147. package/src/components/dialog/dialog.ts +229 -0
  148. package/src/components/dialog/xmark-sharp-light.svg +1 -0
  149. package/src/components/filedrop/cloud-arrow-up.svg +1 -0
  150. package/src/components/filedrop/filedrop.module.scss +70 -0
  151. package/src/components/filedrop/filedrop.ts +131 -0
  152. package/src/components/form/form.module.scss +38 -0
  153. package/src/components/form/form.ts +172 -0
  154. package/src/components/gridview/arrow-down-light.svg +1 -0
  155. package/src/components/gridview/arrow-up-light.svg +1 -0
  156. package/src/components/gridview/gridview.module.scss +324 -0
  157. package/src/components/gridview/gridview.ts +1175 -0
  158. package/src/components/header/header.module.scss +40 -0
  159. package/src/components/header/header.ts +130 -0
  160. package/src/components/icon/icon.module.scss +31 -0
  161. package/src/components/icon/icon.ts +137 -0
  162. package/src/components/image/image.module.scss +28 -0
  163. package/src/components/image/image.ts +168 -0
  164. package/src/components/input/input.module.scss +74 -0
  165. package/src/components/input/input.ts +422 -0
  166. package/src/components/keyboard/arrow-up.svg +1 -0
  167. package/src/components/keyboard/delete-left.svg +1 -0
  168. package/src/components/keyboard/eye-slash.svg +1 -0
  169. package/src/components/keyboard/keyboard.module.scss +134 -0
  170. package/src/components/keyboard/keyboard.ts +526 -0
  171. package/src/components/label/label.module.scss +76 -0
  172. package/src/components/label/label.ts +97 -0
  173. package/src/components/link/link.ts +81 -0
  174. package/src/components/listbox/listbox.module.scss +161 -0
  175. package/src/components/listbox/listbox.ts +539 -0
  176. package/src/components/menu/caret-right-solid.svg +1 -0
  177. package/src/components/menu/menu.module.scss +117 -0
  178. package/src/components/menu/menu.ts +174 -0
  179. package/src/components/messages/circle-exclamation.svg +1 -0
  180. package/src/components/messages/messages.module.scss +92 -0
  181. package/src/components/messages/messages.ts +215 -0
  182. package/src/components/messages/pen-field.svg +1 -0
  183. package/src/components/normalize.scss +391 -0
  184. package/src/components/notification/circle-check-solid.svg +1 -0
  185. package/src/components/notification/circle-exclamation-solid.svg +1 -0
  186. package/src/components/notification/circle-notch-light.svg +1 -0
  187. package/src/components/notification/notification.module.scss +84 -0
  188. package/src/components/notification/notification.ts +107 -0
  189. package/src/components/notification/xmark-sharp-light.svg +1 -0
  190. package/src/components/panel/panel.module.scss +60 -0
  191. package/src/components/panel/panel.ts +58 -0
  192. package/src/components/popup/popup.module.scss +51 -0
  193. package/src/components/popup/popup.ts +442 -0
  194. package/src/components/progress/progress.module.scss +57 -0
  195. package/src/components/progress/progress.ts +44 -0
  196. package/src/components/propgrid/folder-closed.svg +1 -0
  197. package/src/components/propgrid/folder-open.svg +1 -0
  198. package/src/components/propgrid/progrid.module.scss +112 -0
  199. package/src/components/propgrid/propgrid.ts +288 -0
  200. package/src/components/propgrid/updown.svg +4 -0
  201. package/src/components/radio/radio.module.scss +147 -0
  202. package/src/components/radio/radio.svg +4 -0
  203. package/src/components/radio/radio.ts +142 -0
  204. package/src/components/rating/rating.module.scss +23 -0
  205. package/src/components/rating/rating.ts +131 -0
  206. package/src/components/rating/star-sharp-light.svg +1 -0
  207. package/src/components/rating/star-sharp-solid.svg +1 -0
  208. package/src/components/select/select.module.scss +9 -0
  209. package/src/components/select/select.ts +134 -0
  210. package/src/components/shared.scss +137 -0
  211. package/src/components/sizers/sizer.module.scss +90 -0
  212. package/src/components/sizers/sizer.ts +132 -0
  213. package/src/components/slider/slider.module.scss +118 -0
  214. package/src/components/slider/slider.ts +198 -0
  215. package/src/components/switch/switch.module.scss +127 -0
  216. package/src/components/switch/switch.ts +62 -0
  217. package/src/components/tabs/tabs.module.scss +45 -0
  218. package/src/components/tabs/tabs.ts +205 -0
  219. package/src/components/textarea/textarea.module.scss +63 -0
  220. package/src/components/textarea/textarea.ts +125 -0
  221. package/src/components/textedit/textedit.module.scss +116 -0
  222. package/src/components/textedit/textedit.ts +115 -0
  223. package/src/components/themes.scss +88 -0
  224. package/src/components/tickline/tickline.module.scss +26 -0
  225. package/src/components/tickline/tickline.ts +82 -0
  226. package/src/components/tooltips/circle-info-sharp-light.svg +1 -0
  227. package/src/components/tooltips/comments-question.svg +1 -0
  228. package/src/components/tooltips/tooltips.scss +72 -0
  229. package/src/components/tooltips/tooltips.ts +109 -0
  230. package/src/components/treeview/chevron-down-light.svg +1 -0
  231. package/src/components/treeview/treeview.module.scss +185 -0
  232. package/src/components/treeview/treeview.ts +445 -0
  233. package/src/components/viewport/viewport.module.scss +32 -0
  234. package/src/components/viewport/viewport.ts +41 -0
  235. package/src/core/component.ts +1075 -0
  236. package/src/core/core_application.ts +265 -0
  237. package/src/core/core_colors.ts +250 -0
  238. package/src/core/core_data.ts +1310 -0
  239. package/src/core/core_dom.ts +471 -0
  240. package/src/core/core_dragdrop.ts +201 -0
  241. package/src/core/core_element.ts +115 -0
  242. package/src/core/core_events.ts +177 -0
  243. package/src/core/core_i18n.ts +393 -0
  244. package/src/core/core_react.ts +79 -0
  245. package/src/core/core_router.ts +237 -0
  246. package/src/core/core_state.ts +62 -0
  247. package/src/core/core_styles.ts +214 -0
  248. package/src/core/core_svg.ts +712 -0
  249. package/src/core/core_tools.ts +906 -0
  250. package/src/types/scss.d.ts +4 -0
  251. package/src/types/svg.d.ts +1 -0
  252. package/src/types/x4react.d.ts +9 -0
  253. package/src/x4.scss +19 -0
  254. package/src/x4tsx.d.ts +25 -0
  255. package/tsconfig.json +14 -0
  256. package/lib/src/components/grid/gridview.ts +0 -1108
  257. package/lib/src/components/grid/memdb.ts +0 -325
  258. /package/{lib/src/demo → demo}/assets/house-light.svg +0 -0
  259. /package/{lib/src/demo → demo}/assets/radio.svg +0 -0
  260. /package/{lib/src/demo → demo}/index.html +0 -0
@@ -2,17 +2,21 @@
2
2
  // :: MESSAGEBOX ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
3
3
 
4
4
  import { _tr } from '../../core/core_i18n';
5
+ import { asap, class_ns, UnsafeHtml } from '../../core/core_tools';
5
6
 
6
- import { HBox } from '../boxes/boxes';
7
+ import { HBox, VBox } from '../boxes/boxes';
7
8
  import { Icon } from '../icon/icon';
8
9
  import { Label } from '../label/label';
9
10
  import { Dialog, DialogProps } from "../dialog/dialog"
11
+ import { Form } from '../form/form';
12
+ import { BtnGroupItem } from '../btngroup/btngroup';
13
+ import { Input } from '../input/input';
10
14
 
11
15
  import "./messages.module.scss";
12
16
 
13
17
  import error_icon from "./circle-exclamation.svg";
14
- import { asap, class_ns, UnsafeHtml } from '../../core/core_tools.js';
15
- import { Form } from '../form/form.js';
18
+ import pen_icon from "./pen-field.svg";
19
+ import { Component } from '@core/component.js';
16
20
 
17
21
  export interface MessageBoxProps extends DialogProps {
18
22
  message: string;
@@ -26,25 +30,18 @@ export interface MessageBoxProps extends DialogProps {
26
30
  @class_ns( "x4" )
27
31
  export class MessageBox extends Dialog<DialogProps>
28
32
  {
29
- m_label: Label;
30
-
31
33
  constructor(props: DialogProps) {
32
34
  super(props);
33
35
  }
34
36
 
35
- setText(txt: string | UnsafeHtml ) {
36
- this.m_label.setText( txt );
37
- }
38
-
39
37
  /**
40
- * display a messagebox
38
+ *
41
39
  */
42
40
 
43
- static show( msg: string | UnsafeHtml ): MessageBox {
44
-
41
+ private static _create( msg: string | UnsafeHtml, buttons?: BtnGroupItem[], title?: string ) {
45
42
  const box = new MessageBox({
46
43
  modal: true,
47
- title: _tr.global.error,
44
+ title: title ?? _tr.global.error,
48
45
  movable: true,
49
46
  form: new Form( {
50
47
  content: [
@@ -56,14 +53,163 @@ export class MessageBox extends Dialog<DialogProps>
56
53
  }),
57
54
  ]
58
55
  }),
59
- buttons: [ "ok.outline","cancel.outline" ]
56
+ buttons: buttons ?? [ "ok.outline","cancel.outline" ]
60
57
  });
61
-
58
+
59
+ return box;
60
+ }
61
+
62
+ /**
63
+ * display a messagebox
64
+ */
65
+
66
+ static show( msg: string | UnsafeHtml, buttons?: BtnGroupItem[], title?: string ): MessageBox {
67
+
68
+ const box = this._create( msg, buttons, title );
62
69
  box.on( "btnclick", ( ev ) => {
63
- asap( ( ) => box.close() );
70
+ asap( ( ) => {
71
+ box.close()
72
+ });
73
+ });
74
+
75
+ box.show();
76
+ return box;
77
+ }
78
+
79
+ /**
80
+ * idem with promise
81
+ */
82
+
83
+ static async showAsync( msg: string | UnsafeHtml, buttons?: BtnGroupItem[], title?: string ) : Promise<string> {
84
+
85
+ return new Promise( (resolve, reject ) => {
86
+ const box = this._create( msg, buttons, title );
87
+ box.on( "btnclick", ( ev ) => {
88
+ asap( ( ) => {
89
+ resolve( ev.button );
90
+ box.close()
91
+ });
92
+ });
93
+
94
+ box.show();
95
+ } );
96
+
97
+ }
98
+ }
99
+
100
+
101
+ @class_ns( "x4" )
102
+ export class InputBox extends Dialog<DialogProps>
103
+ {
104
+ constructor(props: DialogProps) {
105
+ super(props);
106
+ }
107
+
108
+ getValue( ) {
109
+ const input = this.query<Input>( "input" );
110
+ return input.getValue( );
111
+ }
112
+
113
+ private static _create( msg: string | UnsafeHtml, value: string, title: string ) {
114
+ const box = new InputBox({
115
+ modal: true,
116
+ title,
117
+ movable: true,
118
+ form: new Form( {
119
+ content: [
120
+ new HBox( {
121
+ content: [
122
+ new Icon( { iconId: pen_icon }),
123
+ new VBox( { flex: 1, content: [
124
+ new Label( { text: msg } ),
125
+ new Input( { value, type: "text" } )
126
+ ]})
127
+ ]
128
+ }),
129
+ ]
130
+ }),
131
+ buttons: [ "ok.outline.default","cancel.outline" ]
64
132
  });
133
+
134
+ return box;
135
+ }
136
+
137
+ /**
138
+ * idem with promise
139
+ */
140
+
141
+ static async showAsync( msg: string | UnsafeHtml, value: string, title?: string ) : Promise<string> {
142
+
143
+ return new Promise( (resolve, reject ) => {
144
+
145
+ const box = this._create( msg, value, title );
146
+
147
+ box.on( "btnclick", ( ev ) => {
148
+ asap( ( ) => {
149
+ resolve( ev.button=="ok" ? box.getValue( ) : null );
150
+ box.close()
151
+ });
152
+ });
153
+
154
+ box.show();
155
+ } );
156
+
157
+ }
158
+ }
159
+
160
+
161
+
162
+ @class_ns( "x4" )
163
+ export class PromptBox extends Dialog<DialogProps>
164
+ {
165
+ constructor(props: DialogProps) {
166
+ super(props);
167
+ }
65
168
 
66
- box.display();
169
+ private static _create( msg: string | UnsafeHtml, editor: Component, title: string ) {
170
+ const box = new PromptBox({
171
+ modal: true,
172
+ title,
173
+ movable: true,
174
+ form: new Form( {
175
+ content: [
176
+ new HBox( {
177
+ content: [
178
+ new Icon( { iconId: pen_icon }),
179
+ new VBox( { flex: 1, cls: "right", content: [
180
+ new Label( { text: msg } ),
181
+ editor
182
+ ]})
183
+ ]
184
+ }),
185
+ ]
186
+ }),
187
+ buttons: [ "ok.outline.default","cancel.outline" ]
188
+ });
189
+
67
190
  return box;
68
191
  }
69
- }
192
+
193
+ /**
194
+ * idem with promise
195
+ */
196
+
197
+ static async showAsync( msg: string | UnsafeHtml, editor: Component, title?: string ) : Promise<string> {
198
+
199
+ return new Promise( (resolve ) => {
200
+
201
+ const box = this._create( msg, editor, title );
202
+
203
+ box.on( "btnclick", ( ev ) => {
204
+ asap( ( ) => {
205
+ resolve( ev.button );
206
+ box.close()
207
+ });
208
+ });
209
+
210
+ box.show();
211
+ } );
212
+
213
+ }
214
+ }
215
+
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--!Font Awesome Pro 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc.--><path class="fa-secondary" opacity=".4" d="M0 128l32 0 224 0 32 0 0 64-32 0L64 192l0 256 448 0 0-128 0-32 64 0 0 32 0 160 0 32-32 0L32 512 0 512l0-32L0 160l0-32z"/><path class="fa-primary" d="M288 352l16-112L468.7 75.3l96 96L400 336 288 352zM587.3 148.7l-96-96L544 0l96 96-52.7 52.7zM96 288l64 0 0 64-64 0 0-64zm160 0l0 64-64 0 0-64 64 0z"/></svg>
@@ -380,6 +380,11 @@ body {
380
380
  font-size: var( --font-size );
381
381
  }
382
382
 
383
+ dialog {
384
+ margin: 0;
385
+ padding: 0;
386
+ }
387
+
383
388
  .x4hidden {
384
389
  display: none !important;
385
390
  }
@@ -18,6 +18,7 @@
18
18
 
19
19
  :root {
20
20
  --notification-border: var( --border );
21
+ --notification-background: white;
21
22
 
22
23
  --notification-icon-default: var( --accent-background );
23
24
  --notification-icon-success: var( --success-background );
@@ -30,18 +31,19 @@
30
31
  padding: 8px;
31
32
  border: 1px solid var(--notification-border);
32
33
  border-left: 3px solid var( --accent-background );
34
+ background-color: var( --notification-background );
33
35
 
34
36
  &> .x4hbox {
35
37
  gap: 8px;
36
38
  }
37
39
 
38
40
  .x4icon {
39
- width: 24px;
41
+ width: 2em;
42
+ height: 2em;
40
43
  color: var( --notification-icon-default );
41
44
  }
42
45
 
43
46
  .body {
44
-
45
47
  .title {
46
48
  font-weight: bold;
47
49
  padding: 6px 6px 3px 6px;
@@ -79,12 +79,10 @@ export class Notification extends Popup {
79
79
  content: [
80
80
  _icon,
81
81
  new VBox( { cls: "body", content: [
82
- new Label( { cls: "title", text: props.title } ),
82
+ props.title ? new Label( { cls: "title", text: props.title } ) : null,
83
83
  new Label( { cls: "text", text: props.text } ),
84
84
  ] }),
85
- new Button( { cls: "outline", icon: close_icon, click: ( ) => {
86
- this.close( );
87
- } } )
85
+ props.closable ? new Button( { cls: "outline", icon: close_icon, click: ( ) => {this.close( );} } ) : null
88
86
  ]
89
87
  }) );
90
88
  }
@@ -45,4 +45,16 @@
45
45
  justify-content: start;
46
46
  padding: 8px;
47
47
  }
48
+ }
49
+
50
+ .x4panel.inline {
51
+ border: none;
52
+ border-top: 1px solid var( --border );
53
+ margin-top: 1.5em;
54
+
55
+ legend {
56
+ background: none;
57
+ top: -1.4em;
58
+ left: 0;
59
+ }
48
60
  }
@@ -15,12 +15,12 @@
15
15
  **/
16
16
 
17
17
  :root {
18
- --modal-mask-background: rgba(0,0,0,0.5);
18
+ --modal-mask-background: rgb(0 0 0 / 60% );
19
19
  }
20
20
 
21
21
  .x4popup {
22
+ position: absolute !important;
22
23
  background-color: var(--fill-color);
23
- position: absolute;
24
24
  border: 1px solid var(--border-color);
25
25
  overflow: hidden;
26
26
  z-index: 1000;
@@ -32,8 +32,16 @@
32
32
  }
33
33
  }
34
34
 
35
+ .x4popup.center {
36
+ left: 50%;
37
+ top: 50%;
38
+ transform: translate(-50%, -50%);
39
+ }
40
+
41
+ ::backdrop,
35
42
  .x4modal-mask {
36
43
  background-color: var( --modal-mask-background );
44
+ backdrop-filter: blur(8px);
37
45
  position: absolute;
38
46
  left: 0;
39
47
  top: 0;
@@ -15,43 +15,44 @@
15
15
  **/
16
16
 
17
17
  import { Component, ComponentEvent, ComponentEvents, ComponentProps, componentFromDOM, makeUniqueComponentId } from "../../core/component"
18
+
18
19
  import { CSizer } from '../sizers/sizer';
19
- import { Rect, Point, class_ns } from '../../core/core_tools.js';
20
+ import { Rect, Point, class_ns, asap } from '../../core/core_tools.js';
21
+ import { Box } from '../boxes/boxes'
20
22
 
21
23
  import "./popup.module.scss"
22
24
 
23
-
24
25
  export interface PopupEvents extends ComponentEvents {
25
26
  closed: ComponentEvent;
26
27
  opened: ComponentEvent;
27
28
  }
28
29
 
29
30
  export interface PopupProps extends ComponentProps {
30
- modal?: boolean;
31
31
  autoClose?: boolean | string;
32
32
  sizable?: boolean;
33
33
  movable?: boolean;
34
34
  }
35
35
 
36
-
37
- let modal_mask: Component;
38
- let modal_count = 0;
39
-
40
- let modal_stack: Popup[] = [];
41
36
  let autoclose_list: Popup[] = [];
42
37
  let popup_list: Popup[] = [];
43
38
 
39
+ let modal_stack: Popup[] = [];
40
+ let modal_mask: Component;
44
41
 
45
42
 
43
+ function getRoot( ) {
44
+ return document.body;
45
+ }
46
+
46
47
  /**
47
48
  *
48
49
  */
49
50
 
50
51
  @class_ns( "x4" )
51
- export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = PopupEvents> extends Component<P,E> {
52
+ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = PopupEvents> extends Box<P,E> {
52
53
 
53
- private _isopen = false;
54
54
  private _isshown = false;
55
+ protected _ismodal = false;
55
56
 
56
57
  constructor( props: P ) {
57
58
  super( props );
@@ -59,12 +60,28 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
59
60
  if( this.props.sizable ) {
60
61
  this._createSizers( );
61
62
  }
63
+
64
+ // wait for element to create it's childs
65
+ asap( ( ) => {
66
+ if( this.props.movable===true || (this.props.sizable && this.props.movable===undefined) ) {
67
+ const movers = this.queryAll( ".caption-element" );
68
+ movers.forEach( m => new CMover(m,this) );
69
+
70
+ if( this.hasClass("popup-caption") ) {
71
+ new CMover(this,this);
72
+ }
73
+ }
74
+ } );
62
75
  }
63
76
 
77
+ /**
78
+ *
79
+ */
80
+
64
81
  displayNear( rc: Rect, dst = "top left", src = "top left", offset = {x:0,y:0} ) {
65
82
 
66
83
  this.setStyle( { left: "0px", top: "0px" } ); // avoid scrollbar
67
- this._show( ); // to compute size
84
+ this._do_show( ); // to compute size
68
85
 
69
86
  let rm = this.getBoundingRect();
70
87
 
@@ -85,7 +102,6 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
85
102
  yref = rc.top + rc.height/2;
86
103
  }
87
104
 
88
- let halign = 'l';
89
105
  if (dst.indexOf('right') >= 0) {
90
106
  xref -= rm.width;
91
107
  }
@@ -93,7 +109,6 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
93
109
  xref -= rm.width/2;
94
110
  }
95
111
 
96
- let valign = 't';
97
112
  if (dst.indexOf('bottom') >= 0) {
98
113
  yref -= rm.height;
99
114
  }
@@ -114,11 +129,13 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
114
129
  }
115
130
 
116
131
  /**
117
- *
132
+ * s
118
133
  */
119
134
 
120
- displayCenter( ) {
121
- this.displayNear( new Rect( window.innerWidth/2, window.innerHeight/2, 0, 0 ), "center middle" );
135
+ displayCenter( center = true ) {
136
+ //this.displayNear( new Rect( window.innerWidth/2, window.innerHeight/2, 0, 0 ), "center middle" );
137
+ this.setClass( 'center', center );
138
+ this._do_show( ); // to compute size
122
139
  }
123
140
 
124
141
  /**
@@ -132,7 +149,7 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
132
149
  top: y+"px",
133
150
  })
134
151
 
135
- this._show( );
152
+ this._do_show( ); // to compute size
136
153
 
137
154
  const rc = this.getBoundingRect( );
138
155
  const width = window.innerWidth - 16;
@@ -145,29 +162,65 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
145
162
  if( rc.bottom>height ) {
146
163
  this.setStyleValue( "top", height-rc.height );
147
164
  }
165
+ }
166
+
167
+ isOpen( ) {
168
+ return this._isshown;
169
+ }
148
170
 
149
- if( this.props.movable ) {
150
- const movers = this.queryAll( ".caption-element" );
151
- movers.forEach( m => new CMover(m,this) );
171
+ protected _do_hide( ) {
152
172
 
153
- if( this.hasClass("popup-caption") ) {
154
- new CMover(this,this);
155
- }
173
+ if( !this._isshown ) {
174
+ return;
156
175
  }
157
176
 
158
- this.fire( "opened", {} );
177
+ this.__hide( );
178
+ this.__remove( );
179
+
180
+ if( this._ismodal ) {
181
+ modal_stack.pop( );
182
+ this._hideModalMask( );
183
+ }
184
+
185
+ // remove from popup list
186
+ const idx = popup_list.indexOf( this );
187
+ console.assert( idx>=0 );
188
+ popup_list.splice( idx, 1 );
189
+
190
+ // remove from auto close list
191
+ if( this.props.autoClose ) {
192
+ const idx = autoclose_list.indexOf( this );
193
+ if( idx>=0 ) {
194
+ autoclose_list.splice( idx, 1 );
195
+ if( autoclose_list.length==0 ) {
196
+ document.removeEventListener( "pointerdown", this._dismiss );
197
+ }
198
+ }
199
+ }
200
+
201
+ this._isshown = false;
202
+ this.fire( "closed", {} );
159
203
  }
160
204
 
161
- private _show( ) {
162
-
163
- if( this.props.modal && !this._isshown ) {
164
- this._showModalMask( );
165
- modal_stack.push( this );
166
- modal_count++;
205
+ /**
206
+ *
207
+ */
208
+
209
+ protected _do_show( ) {
210
+ if( this._isshown ) {
211
+ return;
167
212
  }
168
213
 
169
214
  this._isshown = true;
170
-
215
+ this.__append( );
216
+
217
+ if( this._ismodal ) {
218
+ modal_stack.push( this );
219
+ this._showModalMask( );
220
+ }
221
+
222
+ this.__show( );
223
+
171
224
  if( this.props.autoClose ) {
172
225
  if( autoclose_list.length==0 ) {
173
226
  document.addEventListener( "pointerdown", this._dismiss );
@@ -178,52 +231,53 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
178
231
  }
179
232
 
180
233
  popup_list.push( this );
181
- document.body.appendChild( this.dom );
234
+
235
+ this.fire( "opened", {} );
236
+ }
237
+
238
+ /**
239
+ *
240
+ */
182
241
 
183
- this.show( );
242
+ protected __show( ) {
243
+ super.show( true );
184
244
  }
185
245
 
186
- override show( show = true ) {
187
- this._isopen = show;
188
- super.show( show );
246
+ protected __hide( ) {
247
+ super.show( false );
189
248
  }
190
249
 
191
- isOpen( ) {
192
- return this._isopen;
250
+ protected __append( ) {
251
+ const root = getRoot( );
252
+ root.appendChild( this.dom );
253
+ }
254
+
255
+ protected __remove( ) {
256
+ const root = getRoot( );
257
+ root.removeChild( this.dom );
193
258
  }
194
259
 
195
260
  /**
196
261
  *
197
262
  */
198
263
 
199
- close( ) {
200
- document.body.removeChild( this.dom );
201
-
202
- // remove from popup list
203
- const idx = popup_list.indexOf( this );
204
- console.assert( idx>=0 );
205
- popup_list.splice( idx, 1 );
206
-
207
- // remove from auto close list
208
- if( this.props.autoClose ) {
209
- const idx = autoclose_list.indexOf( this );
210
- if( idx>=0 ) {
211
- autoclose_list.splice( idx, 1 );
212
- if( autoclose_list.length==0 ) {
213
- document.removeEventListener( "pointerdown", this._dismiss );
214
- }
215
- }
264
+ override show( show = true ) : this {
265
+ if( show ) {
266
+ this.displayCenter( );
216
267
  }
217
-
218
- // update mask
219
- if( this.props.modal ) {
220
- const top = modal_stack.pop( );
221
- console.assert( top==this );
222
- this._updateModalMask( );
268
+ else {
269
+ this._do_hide( );
223
270
  }
224
271
 
225
- this._isshown = false;
226
- this.fire( "closed", {} );
272
+ return this;
273
+ }
274
+
275
+ /**
276
+ *
277
+ */
278
+
279
+ close( ) {
280
+ this._do_hide( );
227
281
  }
228
282
 
229
283
  /**
@@ -280,38 +334,6 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
280
334
  list.forEach( x => x.close() );
281
335
  }
282
336
 
283
- /**
284
- *
285
- */
286
-
287
- private _showModalMask( ) {
288
-
289
- if( !modal_mask ) {
290
- modal_mask = new Component( {
291
- cls: "x4modal-mask",
292
- domEvents: {
293
- click: this._dismiss
294
- }
295
- });
296
- }
297
-
298
- modal_mask.show( true );
299
- document.body.insertAdjacentElement( "beforeend", modal_mask.dom );
300
- }
301
-
302
- /**
303
- *
304
- */
305
-
306
- private _updateModalMask( ) {
307
- if( --modal_count == 0 ) {
308
- modal_mask.show( false );
309
- }
310
- else {
311
- this.dom.insertAdjacentElement( "beforebegin", modal_mask.dom );
312
- }
313
- }
314
-
315
337
  /**
316
338
  *
317
339
  */
@@ -328,6 +350,29 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
328
350
  new CSizer( "bottom-right" ),
329
351
  ])
330
352
  }
353
+
354
+ private _showModalMask( ) {
355
+ if( !modal_mask ) {
356
+ modal_mask = new Component( { cls: 'x4modal-mask' } )
357
+ //document.body.appendChild( modal_mask.dom );
358
+ }
359
+
360
+ const root = getRoot( );
361
+ root.insertBefore( modal_mask.dom, this.dom );
362
+ }
363
+
364
+ private _hideModalMask( ) {
365
+ if( modal_mask ) {
366
+ const root = getRoot( );
367
+ if( modal_stack.length ) {
368
+ const top = modal_stack[ modal_stack.length-1 ];
369
+ root.insertBefore( modal_mask.dom, top.dom );
370
+ }
371
+ else {
372
+ root.removeChild( modal_mask.dom );
373
+ }
374
+ }
375
+ }
331
376
  }
332
377
 
333
378
 
@@ -335,6 +380,7 @@ export class Popup<P extends PopupProps = PopupProps, E extends PopupEvents = Po
335
380
  *
336
381
  */
337
382
 
383
+ export
338
384
  class CMover {
339
385
  private ref: Component;
340
386
  private delta: Point;
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Pro 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc.--><path class="fa-secondary" opacity=".4" d="M32 224l448 0 0 224L32 448l0-224z"/><path class="fa-primary" d="M32 32l192 0 48 64 208 0 32 0 0 32 0 320 0 32-32 0L32 480 0 480l0-32L0 64 0 32l32 0zm240 96l-16 0-9.6-12.8L208 64 32 64l0 128 448 0 0-64-208 0zM32 224l0 224 448 0 0-224L32 224z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--!Font Awesome Pro 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc.--><path class="fa-secondary" opacity=".4" d="M32 64l0 280.4L108.2 192 448 192l0-64-176 0-13.3 0-9.4-9.4L194.7 64 32 64zM51.8 448L384 448l44.2 0 96-192-376.4 0-96 192z"/><path class="fa-primary" d="M272 96L208 32 32 32 0 32 0 64 0 448l0 32 32 0 3.8 0L384 480l64 0L560 256l16-32-35.8 0L128 224 32 416 32 64l162.7 0 54.6 54.6 9.4 9.4 13.3 0 176 0 0 64 32 0 0-64 0-32-32 0L272 96zM51.8 448l96-192 376.4 0-96 192L384 448 51.8 448z"/></svg>