@eclipse-scout/core 22.0.0-beta.1 → 22.0.0

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 (60) hide show
  1. package/dist/eclipse-scout-core-theme-dark.css +135 -46
  2. package/dist/eclipse-scout-core-theme-dark.css.map +1 -1
  3. package/dist/eclipse-scout-core-theme.css +134 -45
  4. package/dist/eclipse-scout-core-theme.css.map +1 -1
  5. package/dist/eclipse-scout-core.js +744 -640
  6. package/dist/eclipse-scout-core.js.map +1 -1
  7. package/package.json +2 -2
  8. package/src/App.js +86 -17
  9. package/src/RemoteApp.js +1 -0
  10. package/src/desktop/Desktop.js +3 -3
  11. package/src/desktop/desktoptab/DesktopTab.less +14 -0
  12. package/src/desktop/notification/DesktopNotification.js +33 -8
  13. package/src/desktop/outline/Outline.js +2 -32
  14. package/src/desktop/outline/Outline.less +14 -6
  15. package/src/desktop/outline/OutlineViewButton.js +1 -0
  16. package/src/desktop/viewbutton/ViewButtonBox.js +2 -2
  17. package/src/filechooser/FileChooser.js +2 -1
  18. package/src/form/Form.js +11 -3
  19. package/src/form/fields/groupbox/GroupBox.less +3 -1
  20. package/src/glasspane/DeferredGlassPaneTarget.js +2 -2
  21. package/src/index.js +2 -1
  22. package/src/login/LoginBox.less +8 -1
  23. package/src/main.less +1 -1
  24. package/src/menu/ComboMenu.js +22 -17
  25. package/src/menu/ComboMenu.less +71 -26
  26. package/src/menu/ContextMenuPopup.js +3 -2
  27. package/src/menu/ContextMenuPopup.less +1 -1
  28. package/src/menu/EllipsisMenu.js +4 -0
  29. package/src/menu/Menu.js +24 -11
  30. package/src/menu/menubar/MenuBar.js +2 -19
  31. package/src/menu/menubar/MenuBarBox.js +3 -34
  32. package/src/menu/menubar/MenuBarLayout.js +6 -19
  33. package/src/menu/menubox/MenuBoxLayout.js +1 -1
  34. package/src/menu/menus.js +4 -10
  35. package/src/messagebox/MessageBox.js +3 -22
  36. package/src/modeselector/ModeSelectorLayout.js +11 -6
  37. package/src/notification/Notification.js +15 -14
  38. package/src/popup/Popup.js +3 -20
  39. package/src/session/BusyIndicator.js +2 -1
  40. package/src/session/Session.js +4 -63
  41. package/src/status/Status.js +2 -1
  42. package/src/style/colors-dark.less +3 -1
  43. package/src/style/colors.less +2 -0
  44. package/src/style/sizes.less +5 -3
  45. package/src/table/Table.js +7 -3
  46. package/src/table/Table.less +13 -3
  47. package/src/table/columns/Column.js +4 -0
  48. package/src/tile/fields/htmlfield/TileHtmlField.js +28 -0
  49. package/src/tooltip/Tooltip.less +7 -5
  50. package/src/tree/LazyNodeFilter.js +24 -15
  51. package/src/tree/Tree.js +112 -143
  52. package/src/tree/Tree.less +2 -2
  53. package/src/tree/TreeLayout.js +1 -1
  54. package/src/tree/TreeNode.js +2 -2
  55. package/src/util/Device.js +6 -2
  56. package/src/widget/FilterSupport.js +6 -4
  57. package/src/widget/FilterSupport.less +38 -9
  58. package/src/widget/LoadingSupport.js +1 -1
  59. package/src/widget/Widget.js +41 -36
  60. package/src/widget/WidgetSupport.js +1 -1
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2010-2021 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
@@ -10,11 +10,12 @@
10
10
  */
11
11
  .filter-field {
12
12
  position: absolute;
13
+ --filter-field-height: @filter-field-height;
13
14
  --filter-field-bottom: @filter-field-bottom;
14
- --filter-field-max-bottom: calc(~'50% - ' @filter-field-height / 2);
15
+ --filter-field-max-bottom: calc(~'50% - ' var(--filter-field-height) / 2);
15
16
  bottom: min(var(--filter-field-bottom), var(--filter-field-max-bottom));
16
17
  right: @filter-field-right;
17
- height: @filter-field-height;
18
+ height: var(--filter-field-height);
18
19
  width: @filter-field-width;
19
20
  min-width: @filter-field-min-width;
20
21
  max-width: @filter-field-max-width;
@@ -25,6 +26,13 @@
25
26
  #scout.drop-shadow();
26
27
  background-color: var(--filter-field-background-color);
27
28
  opacity: 1;
29
+ visibility: visible;
30
+
31
+ // delay the "fade in" transition
32
+ --filter-field-opacity-transition-delay: 100ms;
33
+ // the visibility transition is not a smooth transition but allows to set the value visibility delayed
34
+ // set visibility to visible right before the "fade in" transition starts
35
+ --filter-field-visibility-transition-delay: var(--filter-field-opacity-transition-delay);
28
36
 
29
37
  transition: bottom @filter-field-transition-duration ease-in-out,
30
38
  right @filter-field-transition-duration ease-in-out,
@@ -33,10 +41,17 @@
33
41
  min-width @filter-field-transition-duration ease-in-out,
34
42
  max-width @filter-field-transition-duration ease-in-out,
35
43
  box-shadow @filter-field-transition-duration ease-in-out,
36
- opacity @filter-field-transition-duration ease-in-out;
44
+ opacity @filter-field-transition-duration ease-in-out var(--filter-field-opacity-transition-delay),
45
+ visibility 0s var(--filter-field-visibility-transition-delay);
37
46
 
38
47
  :not(:hover) > &:not(.focused):not(.focus-inside-widget).empty {
39
48
  opacity: 0;
49
+ visibility: hidden;
50
+
51
+ // start the "fade out" transition right away
52
+ --filter-field-opacity-transition-delay: 0s;
53
+ // set visibility to hidden right after the "fade out" transition ends
54
+ --filter-field-visibility-transition-delay: calc(@filter-field-transition-duration + var(--filter-field-opacity-transition-delay));
40
55
  }
41
56
 
42
57
  &::before {
@@ -46,7 +61,7 @@
46
61
  justify-content: center;
47
62
  align-items: center;
48
63
  position: absolute;
49
- bottom: (@filter-field-height - @filter-field-icon-size) / 2;
64
+ bottom: calc((var(--filter-field-height) - @filter-field-icon-size) / 2);
50
65
  right: @text-field-icon-margin-x + 1px;
51
66
  height: @filter-field-icon-size;
52
67
  width: @filter-field-icon-size;
@@ -93,7 +108,7 @@
93
108
  }
94
109
 
95
110
  &:not(.focused).empty {
96
- --filter-field-bottom: @filter-field-bottom + ((@filter-field-height - @filter-field-icon-size) / 2);
111
+ --filter-field-bottom: @filter-field-bottom + ((var(--filter-field-height) - @filter-field-icon-size) / 2);
97
112
  --filter-field-max-bottom: calc(~'50% - ' @filter-field-icon-size / 2);
98
113
  right: @filter-field-right + @text-field-icon-margin-x + 1px;
99
114
  height: @filter-field-icon-size;
@@ -101,7 +116,7 @@
101
116
  min-width: @filter-field-icon-size;
102
117
  max-width: @filter-field-icon-size;
103
118
  box-shadow: none;
104
- #scout.backdrop-filter(@background-color: var(--filter-field-transparent-background-color), @backdrop-filter: blur(2px), @fallback-background-color: var(--filter-field-background-color));
119
+ #scout.backdrop-filter(@background-color: var(--filter-field-transparent-50-background-color), @backdrop-filter: blur(2px), @fallback-background-color: var(--filter-field-transparent-80-background-color));
105
120
 
106
121
  &::before {
107
122
  bottom: 0;
@@ -130,8 +145,9 @@
130
145
 
131
146
  .filter-field-container {
132
147
  position: sticky;
148
+ --filter-field-height: @filter-field-height;
133
149
  --filter-field-container-top: calc(~'100% - ' @filter-field-bottom);
134
- --filter-field-container-min-top: calc(~'50% + ' @filter-field-height / 2);
150
+ --filter-field-container-min-top: calc(~'50% + ' var(--filter-field-height) / 2);
135
151
  top: max(var(--filter-field-container-top), var(--filter-field-container-min-top));
136
152
  left: calc(~'100% - ' @filter-field-right);
137
153
  width: 0;
@@ -143,6 +159,10 @@
143
159
 
144
160
  &:not(:hover) > .filter-field:not(.focused):not(.focus-inside-widget).empty {
145
161
  opacity: 1;
162
+ visibility: visible;
163
+
164
+ --filter-field-opacity-transition-delay: 100ms;
165
+ --filter-field-visibility-transition-delay: var(--filter-field-opacity-transition-delay);
146
166
  }
147
167
 
148
168
  & > .filter-field {
@@ -152,10 +172,14 @@
152
172
 
153
173
  :not(:hover) > &:not(.focused):not(.focus-inside-widget).empty {
154
174
  opacity: 0;
175
+ visibility: hidden;
176
+
177
+ --filter-field-opacity-transition-delay: 0s;
178
+ --filter-field-visibility-transition-delay: calc(@filter-field-transition-duration + var(--filter-field-opacity-transition-delay));
155
179
  }
156
180
 
157
181
  &:not(.focused).empty {
158
- bottom: ((@filter-field-height - @filter-field-icon-size) / 2);
182
+ bottom: calc((var(--filter-field-height) - @filter-field-icon-size) / 2);
159
183
  right: @text-field-icon-margin-x + 1px;
160
184
  }
161
185
  }
@@ -166,4 +190,9 @@
166
190
  .filter-field {
167
191
  .hidden();
168
192
  }
193
+ }
194
+
195
+ .dense .filter-field,
196
+ .dense .filter-field-container {
197
+ --filter-field-height: @filter-field-height-dense;
169
198
  }
@@ -15,7 +15,7 @@ export default class LoadingSupport extends WidgetSupport {
15
15
 
16
16
  /**
17
17
  * @typedef {WidgetSupportOptions} LoadingSupportOptions
18
- * @property {number} loadingIndicatorDelay if not set: 250 ms
18
+ * @property {number} [loadingIndicatorDelay] if not set: 250 ms
19
19
  */
20
20
 
21
21
  /**
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2010-2021 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
@@ -8,27 +8,7 @@
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
10
10
  */
11
- import {
12
- arrays,
13
- DeferredGlassPaneTarget,
14
- Desktop,
15
- Device,
16
- Event,
17
- EventDelegator,
18
- EventSupport,
19
- filters,
20
- focusUtils,
21
- Form,
22
- graphics,
23
- icons,
24
- inspector,
25
- objects,
26
- scout,
27
- scrollbars,
28
- strings,
29
- texts,
30
- TreeVisitResult
31
- } from '../index';
11
+ import {arrays, DeferredGlassPaneTarget, Desktop, Device, Event, EventDelegator, EventSupport, filters, focusUtils, Form, graphics, icons, inspector, objects, scout, scrollbars, strings, texts, TreeVisitResult} from '../index';
32
12
  import $ from 'jquery';
33
13
 
34
14
  export default class Widget {
@@ -59,7 +39,7 @@ export default class Widget {
59
39
  this.cloneOf = null;
60
40
 
61
41
  /**
62
- * The 'rendering' flag is set the true while the _inital_ rendering is performed.
42
+ * The 'rendering' flag is set the true while the _initial_ rendering is performed.
63
43
  * It is used to to something different in a _render* method when the method is
64
44
  * called for the first time.
65
45
  */
@@ -144,6 +124,12 @@ export default class Widget {
144
124
  READ_ONLY: 1
145
125
  };
146
126
 
127
+ /**
128
+ * Initializes the widget instance. All properties of the model parameter (object) are set as properties on the widget instance.
129
+ * Calls {@link Widget#_init} and triggers an <em>init</em> event when initialization has been completed.
130
+ *
131
+ * @param {object} model
132
+ */
147
133
  init(model) {
148
134
  let staticModel = this._jsonModel();
149
135
  if (staticModel) {
@@ -168,9 +154,12 @@ export default class Widget {
168
154
  }
169
155
 
170
156
  /**
171
- * @param {object} options
172
- * - parent (required): The parent widget
173
- * - session (optional): If not specified the session of the parent is used
157
+ * Initializes the widget instance. All properties of the model parameter (object) are set as properties on the widget instance.
158
+ * Override this function to initialize widget specific properties in sub-classes.
159
+ *
160
+ * @param {object} model Properties:<ul>
161
+ * <li>parent (required): parent widget</li>
162
+ * <li>session (optional): If not specified, session of parent widget is used</li></ul>
174
163
  */
175
164
  _init(model) {
176
165
  if (!model.parent) {
@@ -541,8 +530,9 @@ export default class Widget {
541
530
  return;
542
531
  }
543
532
 
544
- // Destroy open popups first, they are not animated
545
- this.session.desktop.destroyPopupsFor(this);
533
+ // Remove open popups first, they would be positioned wrongly during the animation
534
+ // Normally they would be closed automatically by a user interaction (click),
535
+ this.session.desktop.removePopupsFor(this);
546
536
 
547
537
  this.removalPending = true;
548
538
  // Don't execute immediately to make sure nothing interferes with the animation (e.g. layouting) which could make it laggy
@@ -806,13 +796,17 @@ export default class Widget {
806
796
  }
807
797
 
808
798
  let computedStateForChildren = scout.nvl(enabledComputedForChildren, enabledComputed);
809
- this.children.forEach(child => {
799
+ this._childrenForEnabledComputed().forEach(child => {
810
800
  if (child.inheritAccessibility) {
811
801
  child.recomputeEnabled(computedStateForChildren);
812
802
  }
813
803
  });
814
804
  }
815
805
 
806
+ _childrenForEnabledComputed() {
807
+ return this.children;
808
+ }
809
+
816
810
  _computeEnabled(inheritAccessibility, parentEnabled) {
817
811
  return this.enabled && (inheritAccessibility ? parentEnabled : true);
818
812
  }
@@ -1415,19 +1409,22 @@ export default class Widget {
1415
1409
 
1416
1410
  /**
1417
1411
  * Sets the value of the property 'propertyName' to 'newValue' and then fires a propertyChange event for that property.
1412
+ * @return {boolean} true if the property was changed, false if not.
1418
1413
  */
1419
1414
  _setProperty(propertyName, newValue) {
1420
1415
  scout.assertParameter('propertyName', propertyName);
1421
1416
  let oldValue = this[propertyName];
1422
1417
  if (objects.equals(oldValue, newValue)) {
1423
- return;
1418
+ return false;
1424
1419
  }
1425
1420
  this[propertyName] = newValue;
1426
1421
  let event = this.triggerPropertyChange(propertyName, oldValue, newValue);
1427
1422
  if (event.defaultPrevented) {
1428
1423
  // Revert to old value if property change should be prevented
1429
1424
  this[propertyName] = oldValue;
1425
+ return false; // not changed
1430
1426
  }
1427
+ return true;
1431
1428
  }
1432
1429
 
1433
1430
  /**
@@ -1439,10 +1436,11 @@ export default class Widget {
1439
1436
  * If there is a custom remove function (e.g. _removeXY where XY is the property name), it will be called instead of removing the widgets directly.
1440
1437
  * 3. Model update: If there is a custom set function (e.g. _setXY where XY is the property name), it will be called. Otherwise the default set function _setProperty is called.
1441
1438
  * 4. DOM rendering: If the widget is rendered and there is a custom render function (e.g. _renderXY where XY is the property name), it will be called. Otherwise nothing happens.
1439
+ * @return {boolean} true if the property was changed, false if not.
1442
1440
  */
1443
1441
  setProperty(propertyName, value) {
1444
1442
  if (objects.equals(this[propertyName], value)) {
1445
- return;
1443
+ return false;
1446
1444
  }
1447
1445
 
1448
1446
  value = this._prepareProperty(propertyName, value);
@@ -1453,6 +1451,7 @@ export default class Widget {
1453
1451
  if (this.rendered) {
1454
1452
  this._callRenderProperty(propertyName);
1455
1453
  }
1454
+ return true;
1456
1455
  }
1457
1456
 
1458
1457
  _prepareProperty(propertyName, value) {
@@ -1556,9 +1555,11 @@ export default class Widget {
1556
1555
  * Returns the DOM elements to paint a glassPanes over, once a modal Form, message-box or file-chooser is shown with this widget as its 'displayParent'.<br>
1557
1556
  * If the widget is not rendered yet, a scout.DeferredGlassPaneTarget is returned.<br>
1558
1557
  * In both cases the method _glassPaneTargets is called which may be overridden by the actual widget.
1558
+ * @param {Widget} element widget that requested a glass pane
1559
+ * @returns [$]|[DeferredGlassPaneTarget]
1559
1560
  */
1560
1561
  glassPaneTargets(element) {
1561
- let resolveGlassPanes = function(element) {
1562
+ let resolveGlassPanes = element => {
1562
1563
  // contributions
1563
1564
  let targets = arrays.flatMap(this._glassPaneContributions, cont => {
1564
1565
  let $elements = cont(element);
@@ -1568,7 +1569,7 @@ export default class Widget {
1568
1569
  return [];
1569
1570
  });
1570
1571
  return targets.concat(this._glassPaneTargets(element));
1571
- }.bind(this);
1572
+ };
1572
1573
  if (this.rendered) {
1573
1574
  return resolveGlassPanes(element);
1574
1575
  }
@@ -1576,13 +1577,17 @@ export default class Widget {
1576
1577
  return DeferredGlassPaneTarget.createFor(this, resolveGlassPanes.bind(this, element));
1577
1578
  }
1578
1579
 
1580
+ /**
1581
+ *
1582
+ * @param {Widget} element widget that requested a glass pane
1583
+ * @returns [$]
1584
+ */
1579
1585
  _glassPaneTargets(element) {
1580
1586
  // since popups are rendered outside the DOM of the widget parent-child hierarchy, get glassPaneTargets of popups belonging to this widget separately.
1581
1587
  return [this.$container].concat(
1582
1588
  this.session.desktop.getPopupsFor(this)
1583
- .reduce((acc, popup) => {
1584
- return acc.concat(popup.glassPaneTargets());
1585
- }, []));
1589
+ .filter(popup => !element.has(popup))
1590
+ .reduce((acc, popup) => acc.concat(popup.glassPaneTargets()), []));
1586
1591
  }
1587
1592
 
1588
1593
  addGlassPaneContribution(contribution) {
@@ -15,7 +15,7 @@ export default class WidgetSupport {
15
15
  /**
16
16
  * @typedef WidgetSupportOptions
17
17
  * @property {Widget} widget Widget that created the support
18
- * @property {$|function} $container jQuery element that will be used for the visualization.
18
+ * @property {$|function} [$container] jQuery element that will be used for the visualization.
19
19
  * It may be a function to resolve the container later.
20
20
  * If this property is not set the $container of the widget is used by default.
21
21
  */