x4js 2.2.41 → 2.2.43

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x4js",
3
- "version": "2.2.41",
3
+ "version": "2.2.43",
4
4
  "type": "module",
5
5
  "main": "src/x4.ts",
6
6
  "module": "src/x4.ts",
@@ -0,0 +1,10 @@
1
+
2
+ const x4icons = {
3
+ check: `<svg viewBox="0 0 10 7" fill="none" aria-hidden="true"><path d="M4 4.586L1.707 2.293A1 1 0 1 0 .293 3.707l3 3a.997.997 0 0 0 1.414 0l5-5A1 1 0 1 0 8.293.293L4 4.586z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>`,
4
+ empty: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path opacity=".4" d="M32 96l0 200.6 21.7-54.3C65.9 211.9 95.3 192 128 192l320 0 0-32c0-17.7-14.3-32-32-32l-117.5 0c-25.5 0-49.9-10.1-67.9-28.1L204.1 73.4c-6-6-14.1-9.4-22.6-9.4L64 64C46.3 64 32 78.3 32 96zM49.1 426.1c-2 4.9-1.4 10.5 1.6 14.9s7.9 7 13.2 7l320 0 80 0c6.5 0 12.4-4 14.9-10.1l64-160c2-4.9 1.4-10.5-1.6-14.9s-7.9-7-13.2-7l-400 0c-6.5 0-12.4 4-14.9 10.1l-64 160z"/><path d="M448 160l0 32 32 0 0-32c0-35.3-28.7-64-64-64L298.5 96c-17 0-33.3-6.7-45.3-18.7L226.7 50.7c-12-12-28.3-18.7-45.3-18.7L64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0 80 0c19.6 0 37.3-11.9 44.6-30.2l64-160c5.9-14.8 4.1-31.5-4.8-44.7S543.9 224 528 224l-400 0c-19.6 0-37.3 11.9-44.6 30.2L32 382.8 32 96c0-17.7 14.3-32 32-32l117.5 0c8.5 0 16.6 3.4 22.6 9.4l22.6-22.6L204.1 73.4l26.5 26.5c18 18 42.4 28.1 67.9 28.1L416 128c17.7 0 32 14.3 32 32zM384 448L64 448c-5.3 0-10.3-2.6-13.2-7s-3.6-10-1.6-14.9l64-160c2.4-6.1 8.3-10.1 14.9-10.1l400 0c5.3 0 10.3 2.6 13.2 7s3.6 10 1.6 14.9l-64 160C476.4 444 470.5 448 464 448l-80 0z"/></svg>`,
5
+ radio: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 5 5" aria-hidden="true"><circle class="fa-primary" cx="2.5" cy="2.5" r="2.5" ></circle><circle class="fa-secondary" cx="2.5" cy="2.5" r="1.25"></circle></svg>`,
6
+ chevron: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor"><!--!Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc.--><path d="M267.3 395.3c-6.2 6.2-16.4 6.2-22.6 0l-192-192c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L256 361.4 436.7 180.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6l-192 192z"/></svg>`,
7
+
8
+ };
9
+
10
+ export default x4icons;
@@ -3,12 +3,11 @@ import { EventCallback } from '../../core/core_events';
3
3
 
4
4
  import { Input } from '../input/input';
5
5
  import { Label } from '../label/label';
6
+ import { class_ns } from '../../core/core_tools';
6
7
 
7
- import { svgLoader } from '../icon/icon';
8
+ import icons from "../assets/icons";
8
9
 
9
10
  import "./checkbox.module.scss"
10
- import icon from "./check.svg";
11
- import { class_ns } from '../../core/core_tools';
12
11
 
13
12
  /**
14
13
  * Checkbox events
@@ -76,11 +75,7 @@ export class Checkbox extends Component<CheckboxProps,CheckBoxEvents> {
76
75
  } ),
77
76
  ])
78
77
 
79
-
80
- const svg = `<svg viewBox="0 0 10 7" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M4 4.586L1.707 2.293A1 1 0 1 0 .293 3.707l3 3a.997.997 0 0 0 1.414 0l5-5A1 1 0 1 0 8.293.293L4 4.586z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd">
81
- </path></svg>`
82
-
83
- this.query<Label>( '.inner' ).dom.insertAdjacentHTML( "beforeend", svg );
78
+ this.query<Label>( '.inner' ).dom.insertAdjacentHTML( "beforeend", icons.check );
84
79
 
85
80
  /*
86
81
  svgLoader.load( icon ).then( svg => {
@@ -113,7 +113,8 @@
113
113
  .empty {
114
114
  position: relative;
115
115
  left: 50%;
116
- top: 20%;
116
+ top: 30px;
117
+ transform: translateX(-50%);
117
118
  width: fit-content;
118
119
 
119
120
  #icon {
@@ -27,12 +27,10 @@ import { Box } from '../boxes/boxes';
27
27
  import { CSizer } from '../sizers/sizer'
28
28
  import { Viewport } from '../viewport/viewport';
29
29
  import { Label, SimpleText } from '../label/label';
30
+ import icons from "../assets/icons"
30
31
 
31
32
  import { _tr } from '../../core/core_i18n';
32
33
 
33
- const check_icon = `<svg viewBox="0 0 10 7" fill="none" aria-hidden="true"><path d="M4 4.586L1.707 2.293A1 1 0 1 0 .293 3.707l3 3a.997.997 0 0 0 1.414 0l5-5A1 1 0 1 0 8.293.293L4 4.586z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>`;
34
- const empty_icon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path opacity=".4" d="M32 96l0 200.6 21.7-54.3C65.9 211.9 95.3 192 128 192l320 0 0-32c0-17.7-14.3-32-32-32l-117.5 0c-25.5 0-49.9-10.1-67.9-28.1L204.1 73.4c-6-6-14.1-9.4-22.6-9.4L64 64C46.3 64 32 78.3 32 96zM49.1 426.1c-2 4.9-1.4 10.5 1.6 14.9s7.9 7 13.2 7l320 0 80 0c6.5 0 12.4-4 14.9-10.1l64-160c2-4.9 1.4-10.5-1.6-14.9s-7.9-7-13.2-7l-400 0c-6.5 0-12.4 4-14.9 10.1l-64 160z"/><path d="M448 160l0 32 32 0 0-32c0-35.3-28.7-64-64-64L298.5 96c-17 0-33.3-6.7-45.3-18.7L226.7 50.7c-12-12-28.3-18.7-45.3-18.7L64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0 80 0c19.6 0 37.3-11.9 44.6-30.2l64-160c5.9-14.8 4.1-31.5-4.8-44.7S543.9 224 528 224l-400 0c-19.6 0-37.3 11.9-44.6 30.2L32 382.8 32 96c0-17.7 14.3-32 32-32l117.5 0c8.5 0 16.6 3.4 22.6 9.4l22.6-22.6L204.1 73.4l26.5 26.5c18 18 42.4 28.1 67.9 28.1L416 128c17.7 0 32 14.3 32 32zM384 448L64 448c-5.3 0-10.3-2.6-13.2-7s-3.6-10-1.6-14.9l64-160c2.4-6.1 8.3-10.1 14.9-10.1l400 0c5.3 0 10.3 2.6 13.2 7s3.6 10 1.6 14.9l-64 160C476.4 444 470.5 448 464 448l-80 0z"/></svg>`;
35
-
36
34
  import "./gridview.module.scss"
37
35
 
38
36
  export type CellRenderer = (rec: DataRecord) => Component;
@@ -677,7 +675,7 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
677
675
  switch (type) {
678
676
  case "checkbox": {
679
677
  if (data) {
680
- return new Icon({ cls: "cell-check" + cls, iconId: check_icon });
678
+ return new Icon({ cls: "cell-check" + cls, iconId: icons.check });
681
679
  }
682
680
 
683
681
  return undefined;
@@ -1141,7 +1139,7 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
1141
1139
 
1142
1140
  // empty ?
1143
1141
  if( rowc==0 ) {
1144
- this._body.setContent( new Label( { cls: "empty vertical", icon: empty_icon, text: this.props.emptyMsg ?? _tr.global.empty_list } ) );
1142
+ this._body.setContent( new Label( { cls: "empty vertical", icon: icons.empty, text: this.props.emptyMsg ?? _tr.global.empty_list } ) );
1145
1143
  return;
1146
1144
  }
1147
1145
 
@@ -64,6 +64,20 @@
64
64
  &> .x4viewport {
65
65
  overflow: hidden;
66
66
  display: table;
67
+
68
+ .empty {
69
+ position: relative;
70
+ left: 50%;
71
+ top: 30px;
72
+ transform: translateX(-50%);
73
+ width: fit-content;
74
+
75
+ #icon {
76
+ height: 64px;
77
+ fill: var( --accent-background );
78
+ opacity: 50%;
79
+ }
80
+ }
67
81
  }
68
82
 
69
83
  .x4item {
@@ -24,8 +24,12 @@ import { Header } from '../header/header';
24
24
  import { HBox } from '../boxes/boxes';
25
25
  import { Label, SimpleText } from '../label/label';
26
26
 
27
+ import { _tr } from '../../x4.js';
28
+ import icons from '../assets/icons'
29
+
27
30
  import "./listbox.module.scss"
28
31
 
32
+
29
33
  export type ListboxID = number | string;
30
34
 
31
35
  export interface ListItem {
@@ -63,6 +67,7 @@ export interface ListboxProps extends Omit<ComponentProps,'content'> {
63
67
  footer?: Component,
64
68
  checkable?: true,
65
69
  multisel?: true,
70
+ emptyMsg?: string,
66
71
 
67
72
  dblClick?: EventCallback<EvDblClick>;
68
73
  selectionChange?: EventCallback<EvSelectionChange>;
@@ -120,9 +125,7 @@ export class Listbox extends Component<ListboxProps,ListboxEvents> {
120
125
  contextmenu: (e) => this._on_ctx_menu(e),
121
126
  } );
122
127
 
123
- if( props.items ) {
124
- this.setItems( props.items, false );
125
- }
128
+ this.setItems( props.items, false );
126
129
  }
127
130
 
128
131
  /**
@@ -450,6 +453,7 @@ export class Listbox extends Component<ListboxProps,ListboxEvents> {
450
453
  }
451
454
  else {
452
455
  update_sel = oldSel.length>0;
456
+ this._view.setContent( new Label( { cls: "empty vertical", icon: icons.empty, text: this.props.emptyMsg ?? _tr.global.empty_list } ) );
453
457
  }
454
458
 
455
459
  if( update_sel ) {
@@ -22,6 +22,8 @@ import { Label } from '../label/label';
22
22
  import { Input } from '../input/input'
23
23
  import { HBox } from '../boxes/boxes';
24
24
 
25
+ import icons from "../assets/icons"
26
+
25
27
  import "./radio.module.scss";
26
28
 
27
29
  /**
@@ -84,8 +86,7 @@ export class Radio extends Component<RadioProps,RadioEvents> {
84
86
  } ),
85
87
  ])
86
88
 
87
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 5 5" aria-hidden="true"><circle class="fa-primary" cx="2.5" cy="2.5" r="2.5" ></circle><circle class="fa-secondary" cx="2.5" cy="2.5" r="1.25"></circle></svg>`
88
- this._check.dom.insertAdjacentHTML( "beforeend", svg );
89
+ this._check.dom.insertAdjacentHTML( "beforeend", icons.radio );
89
90
 
90
91
  //svgLoader.load( icon ).then( svg => {
91
92
  // this._check.dom.insertAdjacentHTML( "beforeend", svg );
@@ -58,6 +58,20 @@
58
58
  position: relative;
59
59
 
60
60
  &> .x4viewport {
61
+ .empty {
62
+ position: relative;
63
+ left: 50%;
64
+ top: 30px;
65
+ transform: translateX(-50%);
66
+ width: fit-content;
67
+
68
+ #icon {
69
+ height: 64px;
70
+ fill: var( --accent-background );
71
+ opacity: 50%;
72
+ }
73
+ }
74
+
61
75
  // child + subitems
62
76
  .x4ctreeviewitem {
63
77
  &>.label {
@@ -24,8 +24,10 @@ import { ListboxID, ListItem } from '../listbox/listbox';
24
24
  import { Box, BoxProps, HBox, VBox } from '../boxes/boxes';
25
25
  import { Icon } from '../icon/icon';
26
26
 
27
+ import { _tr } from '../../x4.js';
28
+ import icons from '../assets/icons'
29
+
27
30
  import "./treeview.module.scss";
28
- import folder_icon from "./chevron-down-light.svg"
29
31
 
30
32
 
31
33
  //import folder_closed from "./folder-minus-light.svg"
@@ -53,6 +55,7 @@ export interface TreeItem extends ListItem {
53
55
  interface TreeviewProps extends Omit<ComponentProps,"content"> {
54
56
  items: TreeItem[];
55
57
  footer?: Component;
58
+ emptyMsg?: string;
56
59
  selectionChange?: EventCallback<EvSelectionChange>;
57
60
  dblClick?: EventCallback<EvDblClick>;
58
61
  click?: EventCallback<EvClick>;
@@ -83,7 +86,7 @@ class CTreeViewItem extends Box {
83
86
 
84
87
  if( item ) {
85
88
  this._label = new HBox( {cls:"label item", content: [
86
- this._icon = new Icon( { cls: 'arrow', iconId: item.children ? folder_icon : undefined } ),
89
+ this._icon = new Icon( { cls: 'arrow', iconId: item.children ? icons.chevron : undefined } ),
87
90
  new Label( { tag: "span", cls: "", text: item.text, icon: item.iconId } ),
88
91
  ]});
89
92
 
@@ -150,7 +153,7 @@ class CTreeViewItem extends Box {
150
153
  }
151
154
 
152
155
  setItems( items: TreeItem[ ] ) {
153
- if( items ) {
156
+ if( items && items.length ) {
154
157
  const childs = items.map( itm => {
155
158
  return new CTreeViewItem( {}, itm );
156
159
  })
@@ -203,9 +206,7 @@ export class Treeview extends Component<TreeviewProps,TreeviewEvents> {
203
206
  keydown: ( ev ) => this._onkey( ev ),
204
207
  });
205
208
 
206
- if( props.items ) {
207
- this.setItems( props.items );
208
- }
209
+ this.setItems( props.items );
209
210
  }
210
211
 
211
212
  /**
@@ -219,10 +220,13 @@ export class Treeview extends Component<TreeviewProps,TreeviewEvents> {
219
220
 
220
221
  const root = new CTreeViewItem( { cls: "root"}, null );
221
222
 
222
- if( items ) {
223
+ if( items && items.length ) {
223
224
  root.setItems( items );
224
225
  this._view.setContent( root );
225
226
  }
227
+ else {
228
+ this._view.setContent( new Label( { cls: "empty vertical", icon: icons.empty, text: this.props.emptyMsg ?? _tr.global.empty_list } ) );
229
+ }
226
230
  }
227
231
 
228
232
  private _on_click( ev: UIEvent ) {
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor"><!--!Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc.--><path d="M267.3 395.3c-6.2 6.2-16.4 6.2-22.6 0l-192-192c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L256 361.4 436.7 180.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6l-192 192z"/></svg>