x4js 2.3.25 → 2.3.27

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 (68) hide show
  1. package/aicontext.md +87 -13
  2. package/package.json +1 -1
  3. package/src/components/autocomplete/autocomplete.ts +3 -3
  4. package/src/components/boxes/boxes.module.scss +16 -2
  5. package/src/components/boxes/boxes.ts +24 -11
  6. package/src/components/breadcrumb/breadcrumb.ts +1 -2
  7. package/src/components/btngroup/btngroup.ts +2 -2
  8. package/src/components/button/button.ts +2 -2
  9. package/src/components/calendar/calendar.ts +5 -3
  10. package/src/components/canvas/canvas.ts +1 -2
  11. package/src/components/chart/chart.ts +4 -4
  12. package/src/components/checkbox/checkbox.ts +2 -2
  13. package/src/components/colorinput/colorinput.ts +3 -2
  14. package/src/components/colorpicker/colorpicker.ts +5 -5
  15. package/src/components/combobox/combobox.ts +3 -3
  16. package/src/components/components.ts +1 -0
  17. package/src/components/dialog/dialog.ts +2 -2
  18. package/src/components/dockingview/dockingview.ts +2 -3
  19. package/src/components/filedrop/filedrop.ts +3 -2
  20. package/src/components/form/form.ts +4 -3
  21. package/src/components/gauge/gauge.ts +2 -2
  22. package/src/components/gridview/gridview.module.scss +8 -5
  23. package/src/components/gridview/gridview.ts +11 -13
  24. package/src/components/header/header.ts +2 -2
  25. package/src/components/icon/icon.ts +1 -2
  26. package/src/components/image/image.ts +1 -2
  27. package/src/components/input/input.ts +3 -2
  28. package/src/components/keyboard/keyboard.ts +2 -2
  29. package/src/components/label/label.ts +3 -3
  30. package/src/components/link/link.ts +3 -2
  31. package/src/components/listbox/listbox.ts +33 -47
  32. package/src/components/menu/menu.ts +5 -4
  33. package/src/components/messages/messages.module.scss +29 -5
  34. package/src/components/messages/messages.ts +42 -50
  35. package/src/components/monaco/monaco.ts +1 -2
  36. package/src/components/notification/notification.ts +3 -2
  37. package/src/components/panel/panel.ts +2 -2
  38. package/src/components/popup/popup.ts +4 -4
  39. package/src/components/progress/progress.ts +1 -2
  40. package/src/components/propgrid/progrid.module.scss +2 -3
  41. package/src/components/propgrid/propgrid.ts +2 -2
  42. package/src/components/radio/radio.ts +1 -2
  43. package/src/components/rating/rating.ts +3 -3
  44. package/src/components/select/select.ts +2 -2
  45. package/src/components/settingsview/settingsview.module.scss +6 -5
  46. package/src/components/settingsview/settingsview.ts +3 -3
  47. package/src/components/sizers/sizer.ts +21 -29
  48. package/src/components/slider/slider.ts +2 -2
  49. package/src/components/spreadsheet/spreadsheet.ts +8 -10
  50. package/src/components/switch/switch.ts +2 -2
  51. package/src/components/tabs/tabs.ts +4 -4
  52. package/src/components/tag/tag.ts +2 -2
  53. package/src/components/textarea/textarea.ts +3 -3
  54. package/src/components/textedit/textedit.ts +2 -2
  55. package/src/components/themes.scss +2 -0
  56. package/src/components/tickline/tickline.ts +3 -3
  57. package/src/components/timeline/timeline.module.scss +147 -0
  58. package/src/components/timeline/timeline.ts +146 -0
  59. package/src/components/tooltips/tooltips.ts +2 -2
  60. package/src/components/treeview/treeview.ts +19 -25
  61. package/src/components/video/video.ts +1 -2
  62. package/src/components/viewport/viewport.ts +4 -3
  63. package/src/core/component.ts +46 -26
  64. package/src/core/core_application.ts +29 -1
  65. package/src/core/core_i18n.ts +39 -0
  66. package/src/core/core_shortcuts.ts +2 -1
  67. package/src/core/core_svg.ts +1 -0
  68. package/src/core/core_tools.ts +83 -24
@@ -45,6 +45,7 @@ export * from "./tag/tag"
45
45
  export * from "./textarea/textarea"
46
46
  export * from "./textedit/textedit"
47
47
  export * from "./tickline/tickline"
48
+ export * from "./timeline/timeline"
48
49
  export * from "./tooltips/tooltips"
49
50
  export * from "./treeview/treeview"
50
51
  export * from "./video/video"
@@ -20,7 +20,7 @@ import { BtnGroup, BtnGroupItem } from "../btngroup/btngroup"
20
20
  import { HBox } from '../boxes/boxes';
21
21
  import { Label } from '../label/label';
22
22
  import { CoreEvent, EventCallback } from '../../core/core_events';
23
- import { asap, class_ns, getFocusableElements, IComponentInterface, isString, ITabHandler } from '../../core/core_tools';
23
+ import { asap, getFocusableElements, IComponentInterface, isString, ITabHandler } from '../../core/core_tools';
24
24
  import { ComponentEvent } from '../../core/component';
25
25
  import { Button } from '../button/button';
26
26
  import icons from "../assets/icons"
@@ -58,8 +58,8 @@ interface DialogEvents extends PopupEvents {
58
58
  * ```
59
59
  */
60
60
 
61
- @class_ns("x4")
62
61
  export class Dialog<P extends DialogProps = DialogProps, E extends DialogEvents = DialogEvents> extends Popup<P, E> {
62
+ static classPrefix = "x4";
63
63
 
64
64
  private form: Form;
65
65
  private _title: Label;
@@ -14,7 +14,6 @@
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';
18
17
  import { Component, ComponentEvent, ComponentEvents, ComponentProps } from '../../core/component';
19
18
  import { EventCallback } from '../../core/core_events';
20
19
  import { CSizer } from '../sizers/sizer';
@@ -185,8 +184,8 @@ interface Drag {
185
184
  * ```
186
185
  */
187
186
 
188
- @class_ns( "x4" )
189
187
  export class DockingView extends Component<DockingViewProps, DockingViewEvents> {
188
+ static classPrefix = "x4";
190
189
 
191
190
  private layout: DockLayout;
192
191
  private saved: { layout: DockLayout } = null; // the state that remembers it
@@ -405,7 +404,7 @@ export class DockingView extends Component<DockingViewProps, DockingViewEvents>
405
404
  this.fills.forEach( fill => fill( ) );
406
405
  this.placeFloats( );
407
406
 
408
- if( focused instanceof HTMLElement && this.dom.contains( focused ) ) {
407
+ if( focused instanceof HTMLElement && this.contains( focused ) ) {
409
408
  focused.focus( );
410
409
  }
411
410
  }
@@ -18,7 +18,7 @@ import { Component, ComponentEvents, ComponentProps } from '../../core/component
18
18
  import { _tr } from '../../core/core_i18n';
19
19
  import { dragManager } from '../../core/core_dragdrop';
20
20
  import { CoreEvent, EventCallback } from '../../core/core_events';
21
- import { class_ns, UnsafeHtml } from '../../core/core_tools';
21
+ import { UnsafeHtml } from '../../core/core_tools';
22
22
 
23
23
  import { VBox } from '../boxes/boxes';
24
24
  import { SimpleText } from '../label/label';
@@ -47,6 +47,7 @@ interface FileDialogProps extends ComponentProps {
47
47
  */
48
48
 
49
49
  export class FileDialog extends Component {
50
+ static classPrefix = "x4";
50
51
 
51
52
  constructor( props: FileDialogProps ) {
52
53
  super( {
@@ -97,8 +98,8 @@ interface FileDropProps extends ComponentProps {
97
98
  *
98
99
  */
99
100
 
100
- @class_ns( "x4" )
101
101
  export class FileDrop extends VBox<FileDropProps,FileDropEvents> {
102
+ static classPrefix = "x4";
102
103
 
103
104
  constructor( props: FileDropProps ) {
104
105
  super( props );
@@ -14,7 +14,8 @@
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, IFormElement } from '../../core/core_tools';
17
+ import { IFormElement } from '../../core/core_tools';
18
+ import { ComponentEvents } from '../../core/component';
18
19
  import { Box, BoxProps } from '../boxes/boxes';
19
20
 
20
21
  import "./form.module.scss"
@@ -35,8 +36,8 @@ type ValidationFn = ( values: FormValues, is_valid: boolean ) => boolean;
35
36
  * ```
36
37
  */
37
38
 
38
- @class_ns( "x4" )
39
- export class Form<P extends FormProps = FormProps> extends Box<P> {
39
+ export class Form<P extends FormProps = FormProps, E extends ComponentEvents = ComponentEvents> extends Box<P,E> {
40
+ static classPrefix = "x4";
40
41
 
41
42
  private validator: ValidationFn;
42
43
 
@@ -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 { centerRect, class_ns } from '../../core/core_tools';
17
+ import { centerRect } from '../../core/core_tools';
18
18
  import { Component, ComponentProps } from '../../core/component'
19
19
  import { SvgBuilder, SvgComponent } from '../../core/core_svg';
20
20
 
@@ -49,8 +49,8 @@ export const simpleColorStop = [
49
49
  * ```
50
50
  */
51
51
 
52
- @class_ns( "x4" )
53
52
  export class Gauge extends Component<GaugeProps> {
53
+ static classPrefix = "x4";
54
54
 
55
55
  private pos: number;
56
56
  private stops: string[];
@@ -22,6 +22,7 @@
22
22
 
23
23
  --gridview-header-cell-background: var( --background-primary );
24
24
  --gridview-header-cell-color: var( --text-primary );
25
+ --gridview-header-sort-color: var( --gridview-header-cell-color ); // the arrow of the column sorted
25
26
  --gridview-header-cell-vline: var( --border );
26
27
  --gridview-header-cell-border: var( --border );
27
28
 
@@ -245,17 +246,19 @@
245
246
  width: 1em;
246
247
  }
247
248
 
249
+ // the arrow is the mask of the box: its colour follows the theme
248
250
  &.sorted .sorter {
249
- background-image: url("./arrow-down-light.svg");
250
251
  display: block;
251
252
  width: 20px;
252
253
  height: 0.7em;
253
- background-repeat: no-repeat;
254
- background-position: 50% 50%;
254
+ background-color: var( --gridview-header-sort-color );
255
+ -webkit-mask: url("./arrow-down-light.svg") no-repeat 50% 50% / contain;
256
+ mask: url("./arrow-down-light.svg") no-repeat 50% 50% / contain;
255
257
  }
256
-
258
+
257
259
  &.sorted.desc .sorter {
258
- background-image: url("./arrow-up-light.svg");
260
+ -webkit-mask-image: url("./arrow-up-light.svg");
261
+ mask-image: url("./arrow-up-light.svg");
259
262
  }
260
263
 
261
264
  .x-c-sizer:hover {
@@ -16,7 +16,7 @@
16
16
 
17
17
 
18
18
  import { Component, ComponentContent, ComponentEvents, ComponentProps, EvClick, EvContextMenu, EvDblClick, EvSelectionChange } from '../../core/component';
19
- import { class_ns, isNumber, isString, setWaitCursor, UnsafeHtml } from '../../core/core_tools';
19
+ import { formatDate, formatDateTime, formatMoney, formatNumber, isNumber, isString, setWaitCursor, UnsafeHtml } from '../../core/core_tools';
20
20
  import { DataModel, DataStore, DataView, DataRecord, EvViewChange, SortCallback } from '../../core/core_data';
21
21
  import { EventCallback } from '../../core/core_events';
22
22
  import { kbNav } from '../../core/core_tools';
@@ -108,6 +108,7 @@ export interface GridviewProps extends ComponentProps {
108
108
  * --gridview-border
109
109
  * --gridview-header-cell-background
110
110
  * --gridview-header-cell-color
111
+ * --gridview-header-sort-color
111
112
  * --gridview-header-cell-vline
112
113
  * --gridview-header-cell-border
113
114
  * --grid-check-background
@@ -132,8 +133,8 @@ export interface GridviewProps extends ComponentProps {
132
133
  * ```
133
134
  */
134
135
 
135
- @class_ns("x4")
136
136
  export class Gridview<P extends GridviewProps = GridviewProps, E extends GridviewEvents = GridviewEvents> extends Component<P,E> {
137
+ static classPrefix = "x4";
137
138
 
138
139
  private _dataview: DataView;
139
140
  private _datamodel: DataModel;
@@ -165,10 +166,6 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
165
166
 
166
167
 
167
168
  // TODO: that
168
- private _num_fmt = new Intl.NumberFormat('fr-FR');
169
- private _mny_fmt = new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' });
170
- private _dte_fmt = new Intl.DateTimeFormat('fr-FR', {});
171
- private _dtetme_fmt = new Intl.DateTimeFormat('fr-FR', {day:'2-digit',month:'2-digit',year:'numeric',hour:'2-digit',minute:"2-digit"});
172
169
 
173
170
  private _has_fixed: boolean;
174
171
  private _has_footer: boolean;
@@ -744,12 +741,13 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
744
741
  })
745
742
 
746
743
  sizer.on("resize", (ev) => {
747
- cdata.width = ev.size;
744
+ const size = Math.max( ev.size, 16 ); // 16px at least: the min-width of a .cell
745
+ cdata.width = size;
748
746
  cdata.flex = 0;
749
-
747
+
750
748
  const cols = this.queryAll(`[data-col="${col}"]`)
751
749
  cols.forEach(c => {
752
- c.setStyleValue("width", ev.size + "px");
750
+ c.setStyleValue("width", size + "px");
753
751
  });
754
752
 
755
753
  const rh = header.getBoundingRect();
@@ -1005,7 +1003,7 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
1005
1003
  return "NaN";
1006
1004
  }
1007
1005
 
1008
- data = this._num_fmt.format(data as number);
1006
+ data = formatNumber(data as number);
1009
1007
  break;
1010
1008
  }
1011
1009
 
@@ -1014,7 +1012,7 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
1014
1012
  return "NaN";
1015
1013
  }
1016
1014
 
1017
- data = this._mny_fmt.format(data as number);
1015
+ data = formatMoney(data as number);
1018
1016
  break;
1019
1017
  }
1020
1018
 
@@ -1034,7 +1032,7 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
1034
1032
  data = new Date( data );
1035
1033
  }
1036
1034
 
1037
- data = this._dte_fmt.format(data as Date);
1035
+ data = formatDate(data as Date);
1038
1036
  break;
1039
1037
  }
1040
1038
 
@@ -1043,7 +1041,7 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
1043
1041
  data = new Date( data );
1044
1042
  }
1045
1043
 
1046
- data = this._dtetme_fmt.format(data as Date);
1044
+ data = formatDateTime(data as Date);
1047
1045
  break;
1048
1046
  }
1049
1047
 
@@ -1,4 +1,4 @@
1
- import { class_ns, getScrollbarSize } from '../../core/core_tools';
1
+ import { getScrollbarSize } from '../../core/core_tools';
2
2
  import { Component, ComponentProps } from '../../core/component';
3
3
  import { HBox } from '../boxes/boxes';
4
4
  import { Label } from '../label/label';
@@ -36,8 +36,8 @@ const MAX_COLS = 10; // columns with a default name (ref-c1...ref-c10) handled b
36
36
  * ```
37
37
  */
38
38
 
39
- @class_ns( "x4" )
40
39
  export class Header extends HBox<HeaderProps> {
40
+ static classPrefix = "x4";
41
41
 
42
42
  private _els: Component[];
43
43
  private _vwp: Component;
@@ -14,7 +14,6 @@
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';
18
17
  import { Component, ComponentProps } from '../../core/component';
19
18
 
20
19
  import "./icon.module.scss"
@@ -111,8 +110,8 @@ export interface IconProps extends ComponentProps {
111
110
  * The CSS class for this component is automatically generated as `x4icon`.
112
111
  */
113
112
 
114
- @class_ns( "x4" )
115
113
  export class Icon extends Component<IconProps> {
114
+ static classPrefix = "x4";
116
115
 
117
116
  /**
118
117
  * Create a new Icon.
@@ -14,7 +14,6 @@
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';
18
17
  import { Component, ComponentEvents, ComponentProps } from '../../core/component';
19
18
  import { EventCallback, CoreEvent } from '../../core/core_events';
20
19
  import { dragManager } from '../../core/core_dragdrop';
@@ -56,8 +55,8 @@ export interface ImageProps extends ComponentProps {
56
55
  * ```
57
56
  */
58
57
 
59
- @class_ns( "x4" )
60
58
  export class Image<P extends ImageProps = ImageProps, E extends ImageEvents = ImageEvents> extends Component<P,E> {
59
+ static classPrefix = "x4";
61
60
 
62
61
  private _img: Component;
63
62
 
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { EventCallback } from '../../core/core_events';
18
18
  import { Component, ComponentEvent, ComponentProps, EvChange, EvFocus } from '../../core/component';
19
- import { class_ns, formatIntlDate, IComponentInterface, IFormElement, isString } from '../../core/core_tools';
19
+ import { formatIntlDate, IComponentInterface, IFormElement, isString } from '../../core/core_tools';
20
20
 
21
21
  import "./input.module.scss"
22
22
 
@@ -214,8 +214,9 @@ interface InputEvents extends ComponentEvent {
214
214
  * ```
215
215
  */
216
216
 
217
- @class_ns( "x4" )
218
217
  export class Input extends Component<InputProps,InputEvents> {
218
+ static classPrefix = "x4";
219
+
219
220
  constructor( props: InputProps ) {
220
221
  super( { tag: "input", ...props } );
221
222
 
@@ -19,7 +19,6 @@ import { Box, BoxProps, Button, HBox, VBox } from '../components';
19
19
  import { _tr } from '../../core/core_i18n';
20
20
 
21
21
  import "./keyboard.module.scss"
22
- import { class_ns } from '../../core/core_tools';
23
22
  import { Application } from '../../core/core_application';
24
23
 
25
24
  import icon_bksp from "./delete-left.svg";
@@ -275,9 +274,10 @@ interface KeyboardProps extends BoxProps {
275
274
  * --keyboard-zoom
276
275
  * ```
277
276
  */
278
- @class_ns( "x4" )
279
277
  export class Keyboard extends HBox<KeyboardProps>
280
278
  {
279
+ static classPrefix = "x4";
280
+
281
281
  mode: KbMode;
282
282
  upper: boolean;
283
283
  locale: string;
@@ -18,7 +18,7 @@ import { Component, ComponentProps } from "../../core/component"
18
18
  import { Icon } from "../icon/icon"
19
19
 
20
20
  import "./label.module.scss";
21
- import { class_ns, UnsafeHtml } from '../../core/core_tools';
21
+ import { UnsafeHtml } from '../../core/core_tools';
22
22
 
23
23
  export interface LabelProps extends ComponentProps {
24
24
  text?: string | UnsafeHtml;
@@ -37,8 +37,8 @@ export interface LabelProps extends ComponentProps {
37
37
  * ```
38
38
  */
39
39
 
40
- @class_ns( "x4" )
41
40
  export class Label extends Component<LabelProps> {
41
+ static classPrefix = "x4";
42
42
 
43
43
  constructor( p: LabelProps ) {
44
44
  super( { ...p, content: null } );
@@ -79,8 +79,8 @@ export interface SimpleTextProps extends ComponentProps {
79
79
  align?: "left" | "center" | "right";
80
80
  }
81
81
 
82
- @class_ns( "x4" )
83
82
  export class SimpleText extends Component<SimpleTextProps> {
83
+ static classPrefix = "x4";
84
84
 
85
85
  /**
86
86
  *
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { Component, ComponentEvents, ComponentProps, EvClick } from '../../core/component';
18
18
  import { EventCallback } from '../../core/core_events';
19
- import { class_ns, UnsafeHtml } from '../../core/core_tools';
19
+ import { UnsafeHtml } from '../../core/core_tools';
20
20
  import { Label } from '../label/label';
21
21
 
22
22
  import "./link.module.scss"
@@ -45,8 +45,9 @@ interface LinkProps extends ComponentProps {
45
45
  *
46
46
  */
47
47
 
48
- @class_ns( "x4" )
49
48
  export class Link extends Component<LinkProps,LinkEvents> {
49
+ static classPrefix = "x4";
50
+
50
51
  constructor( props: LinkProps ) {
51
52
  super( { tag: "a", ...props} );
52
53
 
@@ -14,9 +14,9 @@
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, componentFromDOM, ComponentProps, EvChange, EvClick, EvContextMenu, EvDblClick, EvSelectionChange } from '../../core/component';
17
+ import { Component, ComponentEvent, ComponentEvents, ComponentProps, EvChange, EvClick, EvContextMenu, EvDblClick, EvSelectionChange } from '../../core/component';
18
18
  import { EventCallback } from '../../core/core_events';
19
- import { kbNav, class_ns, isArray, UnsafeHtml, asap } from '../../core/core_tools';
19
+ import { kbNav, isArray, UnsafeHtml, asap } from '../../core/core_tools';
20
20
 
21
21
  import { ScrollView, Viewport } from '../viewport/viewport';
22
22
  import { Header } from '../header/header';
@@ -118,8 +118,8 @@ export interface ListboxProps extends Omit<ComponentProps,'content'> {
118
118
  * ```
119
119
  */
120
120
 
121
- @class_ns( "x4" )
122
121
  export class Listbox extends Component<ListboxProps,ListboxEvents> {
122
+ static classPrefix = "x4";
123
123
 
124
124
  private _view: Viewport;
125
125
  private _lastsel: ListboxID;
@@ -283,47 +283,38 @@ private _view: Viewport;
283
283
  */
284
284
 
285
285
  private _on_click( ev: MouseEvent ) {
286
- let target = ev.target as HTMLElement;
287
- let on_check = false;
286
+ const target = ev.target as Element;
288
287
 
289
- while( target && target!=this.dom ) {
290
- const c = componentFromDOM( target );
288
+ // avoid trapping child click
289
+ if( Component.closest( target, "input" ) ) {
290
+ return;
291
+ }
291
292
 
292
- // avoid trapping child click
293
- if( c && c.dom.tagName==='INPUT' ) {
293
+ // an item of this list, not of a list around it
294
+ const c = Component.closest( target, ".x4item" );
295
+ if( c && this.contains( c ) ) {
296
+ // the case changes alone; a double click on it is ignored
297
+ if( Component.closest( target, ".x4check" ) ) {
298
+ if( ev.type == 'click' ) {
299
+ this._toggleCheck( c );
300
+ }
294
301
  return;
295
302
  }
296
303
 
297
- if( c && c.hasClass("x4check") ) {
298
- on_check = true;
304
+ const id = c.getInternalData( "id" );
305
+ const fev: EvClick = { context:id };
306
+ if (ev.type == 'click') {
307
+ this.fire('click', fev );
308
+ }
309
+ else {
310
+ this.fire('dblClick', fev );
299
311
  }
300
312
 
301
- if( c && c.hasClass("x4item") ) {
302
- // the case changes alone; a double click on it is ignored
303
- if( on_check ) {
304
- if( ev.type == 'click' ) {
305
- this._toggleCheck( c );
306
- }
307
- return;
308
- }
309
-
310
- const id = c.getInternalData( "id" );
311
- const fev: EvClick = { context:id };
312
- if (ev.type == 'click') {
313
- this.fire('click', fev );
314
- }
315
- else {
316
- this.fire('dblClick', fev );
317
- }
318
-
319
- if (!fev.defaultPrevented) {
320
- this._selectItem( id, c, ev.ctrlKey ? 'toggle' : 'single', ev.type == 'click' && this.props.reselect );
321
- }
322
-
323
- return;
313
+ if (!fev.defaultPrevented) {
314
+ this._selectItem( id, c, ev.ctrlKey ? 'toggle' : 'single', ev.type == 'click' && this.props.reselect );
324
315
  }
325
316
 
326
- target = target.parentElement;
317
+ return;
327
318
  }
328
319
 
329
320
  if (ev.type == 'click') {
@@ -344,19 +335,14 @@ private _view: Viewport;
344
335
 
345
336
  ev.preventDefault();
346
337
 
347
- let target = ev.target as HTMLElement;
348
- while( target && target!=this.dom ) {
349
- const c = componentFromDOM( target );
350
- if( c && c.hasClass("x4item") ) {
351
- const id = c.getInternalData( "id" );
352
-
353
- this._selectItem(id, c, 'single' );
354
- this.fire('contextMenu', {uievent: ev, context: id } );
355
-
356
- return;
357
- }
338
+ const c = Component.closest( ev.target as Element, ".x4item" );
339
+ if( c && this.contains( c ) ) {
340
+ const id = c.getInternalData( "id" );
358
341
 
359
- target = target.parentElement;
342
+ this._selectItem(id, c, 'single' );
343
+ this.fire('contextMenu', {uievent: ev, context: id } );
344
+
345
+ return;
360
346
  }
361
347
 
362
348
  this.fire('contextMenu', { uievent:ev, context: null } );
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { Component } from "../../core/component"
18
18
  import { DOMEventHandler } from '../../core/core_dom';
19
- import { Timer, UnsafeHtml, class_ns, isFunction, isString } from '../../core/core_tools';
19
+ import { Timer, UnsafeHtml, isFunction, isString } from '../../core/core_tools';
20
20
 
21
21
  import { Popup, PopupProps } from '../popup/popup';
22
22
  import { Icon } from '../icon/icon';
@@ -59,8 +59,9 @@ export interface MenuProps extends Omit<PopupProps,"content"> {
59
59
  * ```
60
60
  */
61
61
 
62
- @class_ns( "x4" )
63
62
  class CMenuSep extends Component {
63
+ static classPrefix = "x4";
64
+
64
65
  constructor( ) {
65
66
  super( { } );
66
67
  }
@@ -73,8 +74,8 @@ const openTimer = new Timer( );
73
74
  *
74
75
  */
75
76
 
76
- @class_ns( "x4" )
77
77
  class CMenuItem extends Component {
78
+ static classPrefix = "x4";
78
79
 
79
80
  private menu: Menu;
80
81
 
@@ -164,8 +165,8 @@ class CMenuItem extends Component {
164
165
  *
165
166
  */
166
167
 
167
- @class_ns( "x4" )
168
168
  export class Menu extends Popup {
169
+ static classPrefix = "x4";
169
170
 
170
171
  constructor( props: MenuProps ) {
171
172
  super( { ...props, autoClose: "menu" } );
@@ -25,8 +25,10 @@
25
25
  --msgbox-log-background: var( --background-ternary ); // the lines of a ProgressionBox
26
26
  --msgbox-log-border: var( --border );
27
27
  --msgbox-log-border-focus: var( --border-focus );
28
- --msgbox-log-error-color: var( --alert-background );
28
+ --msgbox-log-error-color: var( --alert-background ); // the text and the bar of an error
29
+ --msgbox-log-error-background: var( --alert-background-light );
29
30
  --msgbox-log-warning-color: var( --warning-background );
31
+ --msgbox-log-warning-background: var( --warning-background-light );
30
32
  --msgbox-log-scrollbar: var( --border-hover ); // the thumb; the track is the background of the lines
31
33
  }
32
34
 
@@ -158,9 +160,10 @@
158
160
  margin: 0 6px 0 16px;
159
161
  }
160
162
 
161
- // the lines: a <pre>, 10 lines high at least; its text gives it no size (contain): it
162
- // scrolls, the box does not grow; a line is not wrapped. An error, a warning: their
163
- // icon, their colour
163
+ // the lines: a <pre> in a fixed font, 10 lines high at least; its text gives it no size
164
+ // (contain): it scrolls, the box does not grow; a line is not wrapped. Each line is a
165
+ // <div>, all of them as wide as the longest one (the column of the grid): an error, a
166
+ // warning, coloured on all their width, a bar on their left
164
167
  #sub-text {
165
168
  flex-grow: 1;
166
169
  min-height: calc( 10lh + 10px ); // its padding and its border too
@@ -168,15 +171,35 @@
168
171
  overflow: auto;
169
172
  white-space: pre;
170
173
  contain: size;
174
+ display: grid;
175
+ grid-template-columns: minmax( max-content, 1fr );
176
+ align-content: start;
171
177
  font: inherit;
178
+ font-family: monospace, monospace;
172
179
  line-height: 1.3em;
173
180
  scrollbar-color: var( --msgbox-log-scrollbar ) transparent;
174
181
  outline: none;
175
182
  border: 1px solid var( --msgbox-log-border );
176
183
  background-color: var( --msgbox-log-background );
177
- padding: 4px 8px;
184
+ padding: 4px 0;
178
185
  margin: 0 6px 0 16px;
179
186
 
187
+ .line {
188
+ min-height: 1lh; // an empty line too
189
+ padding: 0 8px;
190
+ border-left: 3px solid transparent;
191
+
192
+ &.error {
193
+ background-color: var( --msgbox-log-error-background );
194
+ border-left-color: var( --msgbox-log-error-color );
195
+ }
196
+
197
+ &.warning {
198
+ background-color: var( --msgbox-log-warning-background );
199
+ border-left-color: var( --msgbox-log-warning-color );
200
+ }
201
+ }
202
+
180
203
  &, * {
181
204
  user-select: text;
182
205
  }
@@ -207,6 +230,7 @@
207
230
 
208
231
  summary {
209
232
  margin-left: -1em;
233
+ padding-left: 11px; // as the text of a line: its padding and its bar
210
234
  cursor: pointer;
211
235
  font-weight: bold;
212
236
  }