neo.mjs 6.15.2 → 6.15.4

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 (37) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/apps/portal/view/Viewport.mjs +73 -10
  3. package/apps/portal/view/ViewportModel.mjs +29 -0
  4. package/apps/portal/view/learn/MainContainer.mjs +7 -8
  5. package/apps/portal/view/learn/MainContainerController.mjs +1 -1
  6. package/apps/portal/view/learn/PageSectionsContainer.mjs +51 -0
  7. package/examples/ServiceWorker.mjs +2 -2
  8. package/package.json +2 -2
  9. package/resources/data/deck/learnneo/pages/2023-10-14T19-25-08-153Z.md +0 -2
  10. package/resources/data/deck/learnneo/pages/ComponentsAndContainers.md +44 -11
  11. package/resources/data/deck/learnneo/pages/Config.md +0 -2
  12. package/resources/data/deck/learnneo/pages/CustomComponents.md +45 -0
  13. package/resources/data/deck/learnneo/pages/DescribingTheUI.md +0 -2
  14. package/resources/data/deck/learnneo/pages/Earthquakes.md +0 -2
  15. package/resources/data/deck/learnneo/pages/Events.md +0 -2
  16. package/resources/data/deck/learnneo/pages/Extending.md +0 -1
  17. package/resources/data/deck/learnneo/pages/References.md +0 -2
  18. package/resources/data/deck/learnneo/pages/Setup.md +0 -2
  19. package/resources/data/deck/learnneo/tree.json +2 -2
  20. package/resources/scss/src/apps/portal/learn/ContentView.scss +25 -20
  21. package/resources/scss/src/apps/portal/learn/LivePreview.scss +27 -6
  22. package/resources/scss/src/apps/portal/learn/MainContainer.scss +3 -33
  23. package/resources/scss/src/apps/portal/learn/PageContainer.scss +8 -3
  24. package/resources/scss/src/apps/portal/learn/PageSectionsContainer.scss +14 -0
  25. package/resources/scss/src/apps/portal/learn/PageSectionsList.scss +14 -4
  26. package/resources/scss/src/component/wrapper/MonacoEditor.scss +3 -0
  27. package/resources/scss/theme-neo-light/Global.scss +9 -0
  28. package/src/DefaultConfig.mjs +2 -2
  29. package/src/component/Base.mjs +0 -1
  30. package/src/component/wrapper/MonacoEditor.mjs +5 -0
  31. package/src/core/Base.mjs +24 -4
  32. package/src/form/field/ComboBox.mjs +7 -7
  33. package/src/list/Base.mjs +12 -5
  34. package/src/main/addon/IntersectionObserver.mjs +29 -5
  35. package/src/main/addon/Navigator.mjs +207 -155
  36. package/apps/portal/view/learn/PageSectionsPanel.mjs +0 -53
  37. package/resources/scss/src/apps/portal/learn/PageSectionsPanel.scss +0 -24
@@ -6,39 +6,9 @@
6
6
  }
7
7
  }
8
8
 
9
-
10
-
11
-
12
-
13
- // Live preview Container
14
- .live-preview-container {
15
-
16
- box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
17
- border-radius: calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
18
-
19
- .neo-tab-header-toolbar {
20
- background-color: var(--sem-color-surface-neutral-default);
21
- padding: var(--cmp-tab-strip-height);
22
- border: 1px solid #e6e6e6;
23
- border-top-left-radius: calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
24
- border-top-right-radius: calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
25
- }
26
-
27
- .neo-tab-strip {
28
- margin-top: calc(var(--cmp-tab-strip-height) * (-1) - 1px);
29
- }
30
-
31
- .neo-tab-content-container {
32
- background-color: transparent;
33
- border: 1px solid #e6e6e6;
34
- border-top: 0;
35
- border-bottom-left-radius: calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
36
- border-bottom-right-radius: calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
37
- }
38
- }
39
-
9
+ // todo: @mxmrtns this makes scrollbars globally(!) invisible
40
10
  // Scrollbar Behaviour
41
- ::-webkit-scrollbar {
11
+ /*::-webkit-scrollbar {
42
12
  width: 6px;
43
13
  }
44
14
 
@@ -62,4 +32,4 @@ background: transparent;
62
32
  background: #b2b2b2;
63
33
  border-radius: 100px;
64
34
  }
65
- }
35
+ }*/
@@ -1,11 +1,10 @@
1
1
  .learn-content-container {
2
- // align-items: center !important;
3
- // padding: 0 3rem;
4
- overflow: scroll;
2
+ overflow: auto;
5
3
 
6
4
  .content-bottom-toolbar {
7
5
  gap : 8px;
8
6
  padding: 0 3rem;
7
+ margin-top: 100px;
9
8
 
10
9
  .neo-button {
11
10
  flex : 1 !important;
@@ -33,3 +32,9 @@
33
32
  }
34
33
  }
35
34
  }
35
+
36
+ .portal-size-large {
37
+ .content-bottom-toolbar {
38
+ margin-right: 250px;
39
+ }
40
+ }
@@ -0,0 +1,14 @@
1
+ .portal-page-sections-container.neo-container {
2
+ background-color: transparent;
3
+ border : none; // reset the default 1px
4
+ display : block;
5
+ flex-shrink : 0;
6
+ position : fixed;
7
+ right : 0;
8
+ width : 250px;
9
+ z-index : 1;
10
+
11
+ h3 {
12
+ margin-left: 16px;
13
+ }
14
+ }
@@ -4,9 +4,19 @@
4
4
  }
5
5
 
6
6
  .neo-list-item {
7
- color : #7d7d7d;
8
- height : 32px;
9
- line-height: 1;
10
- white-space: normal;
7
+ color : var(--sem-color-text-neutral-subdued);
8
+ height : unset;
9
+ margin-bottom: 0;
10
+ padding : 5px 0 5px 5px !important;
11
+ white-space : normal;
12
+
13
+ &[aria-selected=true] {
14
+ background-color: transparent !important;
15
+ color : var(--list-item-color-selected) !important;
16
+ font-weight : 600 !important;
17
+ cursor : default !important;
18
+
19
+ }
11
20
  }
12
21
  }
22
+
@@ -0,0 +1,3 @@
1
+ .neo-monaco-editor {
2
+ overflow: hidden;
3
+ }
@@ -26,6 +26,15 @@ h2 {
26
26
  line-height : var(--core-lineheight-headline);
27
27
  }
28
28
 
29
+ h3 {
30
+ color : var(--sem-color-fg-neutral-contrast);
31
+ font-family : var(--core-fontfamily-sans);
32
+ font-size : var(--core-fontsize-h3);
33
+ font-weight : var(--core-fontweight-semibold);
34
+ letter-spacing : -0.02em;
35
+ line-height : var(--core-lineheight-headline);
36
+ }
37
+
29
38
  p {
30
39
  color : var(--sem-color-fg-neutral-contrast);
31
40
  font-family : var(--core-fontfamily-sans);
@@ -260,12 +260,12 @@ const DefaultConfig = {
260
260
  useVdomWorker: true,
261
261
  /**
262
262
  * buildScripts/injectPackageVersion.mjs will update this value
263
- * @default '6.15.2'
263
+ * @default '6.15.4'
264
264
  * @memberOf! module:Neo
265
265
  * @name config.version
266
266
  * @type String
267
267
  */
268
- version: '6.15.2'
268
+ version: '6.15.4'
269
269
  };
270
270
 
271
271
  Object.assign(DefaultConfig, {
@@ -370,7 +370,6 @@ class Base extends CoreBase {
370
370
  * @member {String[]} childUpdateCache=[]
371
371
  */
372
372
  childUpdateCache = []
373
-
374
373
  /**
375
374
  * @member {Function[]} resolveUpdateCache=[]
376
375
  */
@@ -40,6 +40,11 @@ class MonacoEditor extends Base {
40
40
  * @protected
41
41
  */
42
42
  ntype: 'monaco-editor',
43
+ /**
44
+ * @member {String[]} baseCls=['neo-monaco-editor']
45
+ * @protected
46
+ */
47
+ baseCls: ['neo-monaco-editor'],
43
48
  /**
44
49
  * @member {Boolean} contextmenu_=false
45
50
  */
package/src/core/Base.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import {buffer, debounce, throttle} from '../util/Function.mjs';
2
- import IdGenerator from './IdGenerator.mjs'
1
+ import {buffer, debounce, intercept, throttle} from '../util/Function.mjs';
2
+ import IdGenerator from './IdGenerator.mjs'
3
3
 
4
4
  const configSymbol = Symbol.for('configSymbol'),
5
5
  forceAssignConfigs = Symbol('forceAssignConfigs'),
@@ -150,6 +150,13 @@ class Base {
150
150
 
151
151
  me.applyDelayable();
152
152
 
153
+ /*
154
+ * We do not want to force devs to check for the `isDestroyed` flag in every possible class extension.
155
+ * So, we are intercepting the top-most `destroy()` call to check for the flag there.
156
+ * Rationale: `destroy()` must only get called once.
157
+ */
158
+ intercept(me, 'destroy', me.isDestroyedCheck, me);
159
+
153
160
  me.remote && setTimeout(me.initRemote.bind(me), 1)
154
161
  }
155
162
 
@@ -305,9 +312,14 @@ class Base {
305
312
 
306
313
  Object.keys(me).forEach(key => {
307
314
  if (Object.getOwnPropertyDescriptor(me, key).writable) {
308
- delete me[key]
315
+ // We must not delete some custom destroy() interceptor
316
+ if (key !== 'destroy' && key !== '_id') {
317
+ delete me[key]
318
+ }
309
319
  }
310
- })
320
+ });
321
+
322
+ me.isDestroyed = true
311
323
  }
312
324
 
313
325
  /**
@@ -387,6 +399,14 @@ class Base {
387
399
  }
388
400
  }
389
401
 
402
+ /**
403
+ * Intercepts destroy() calls to ensure they will only get called once
404
+ * @returns {Boolean}
405
+ */
406
+ isDestroyedCheck() {
407
+ return !this.isDestroyed
408
+ }
409
+
390
410
  /**
391
411
  * Override this method to change the order configs are applied to this instance.
392
412
  * @param {Object} config
@@ -48,9 +48,9 @@ class ComboBox extends Picker {
48
48
  /**
49
49
  * The millisecond time to delay between input field mutation and applying the input field's
50
50
  * new value to the filter
51
- * @member {Number} filterDelay=300
51
+ * @member {Number} filterDelay=50
52
52
  */
53
- filterDelay : 300,
53
+ filterDelay : 50,
54
54
  /**
55
55
  * @member {String} filterOperator_='like'
56
56
  */
@@ -141,7 +141,7 @@ class ComboBox extends Picker {
141
141
  let me = this;
142
142
 
143
143
  // Create buffered function to respond to input field mutation
144
- //me.filterOnInput = buffer(me.filterOnInput, me, me.filterDelay);
144
+ me.filterOnInput = buffer(me.filterOnInput, me, me.filterDelay);
145
145
 
146
146
  me.typeAhead && me.updateTypeAhead()
147
147
  }
@@ -206,10 +206,11 @@ class ComboBox extends Picker {
206
206
  * @protected
207
207
  */
208
208
  afterSetValue(value, oldValue) {
209
- super.afterSetValue(value, oldValue);
210
-
211
209
  let me = this;
212
210
 
211
+ // input value changes (super call) need a flag to prevent showing the picker
212
+ me.programmaticValueChange = true;
213
+ super.afterSetValue(value, oldValue);
213
214
  me.programmaticValueChange = false;
214
215
 
215
216
  if (me._picker?.isVisible) {
@@ -304,8 +305,6 @@ class ComboBox extends Picker {
304
305
  store = me.store,
305
306
  record;
306
307
 
307
- me.programmaticValueChange = true;
308
-
309
308
  // getting a record, nothing to do
310
309
  if (Neo.isObject(value)) {
311
310
  return value
@@ -343,6 +342,7 @@ class ComboBox extends Picker {
343
342
  displayField : me.displayField,
344
343
  itemRole : 'option',
345
344
  itemsFocusable: false,
345
+ keepFocusIndex: true,
346
346
  navigator : {eventSource: me.getInputElId()},
347
347
  parentId : me.id,
348
348
  role : 'listbox',
package/src/list/Base.mjs CHANGED
@@ -98,6 +98,12 @@ class Base extends Component {
98
98
  * @member {Boolean} itemsFocusable=true
99
99
  */
100
100
  itemsFocusable: true,
101
+ /**
102
+ * The config will get passed to the navigator main thread addon.
103
+ * E.g. for ComboBoxes, which shall preserve their focussed list item when filtering the store, use true.
104
+ * @member {Boolean} keepFocusIndex=false
105
+ */
106
+ keepFocusIndex: false,
101
107
  /**
102
108
  * Additional used keys for the selection model
103
109
  * @member {Object} keys
@@ -146,7 +152,7 @@ class Base extends Component {
146
152
  * @member {Object} _vdom
147
153
  */
148
154
  _vdom:
149
- {tag: 'ul', cn: []}
155
+ {tag: 'ul', cn: []}
150
156
  }
151
157
 
152
158
  /**
@@ -288,10 +294,11 @@ class Base extends Component {
288
294
  // Set up item navigation in the list
289
295
  if (!me.hasNavigator) {
290
296
  me.navigator = {
291
- appName : me.appName,
292
- id : me.id,
293
- selector : `.${me.itemCls}:not(.neo-disabled,.neo-list-header)`,
294
- windowId : me.windowId,
297
+ appName : me.appName,
298
+ id : me.id,
299
+ keepFocusIndex: me.keepFocusIndex,
300
+ selector : `.${me.itemCls}:not(.neo-disabled,.neo-list-header)`,
301
+ windowId : me.windowId,
295
302
  ...me.navigator
296
303
  };
297
304
 
@@ -28,6 +28,12 @@ class NeoIntersectionObserver extends Base {
28
28
  }
29
29
  }
30
30
 
31
+ /**
32
+ * Storing data from observe() calls which arrived prior to register()
33
+ * @member {Object} map={}
34
+ * @protected
35
+ */
36
+ cache = {}
31
37
  /**
32
38
  * Storing component ids and their IntersectionObservers
33
39
  * @member {Object} map={}
@@ -77,17 +83,29 @@ class NeoIntersectionObserver extends Base {
77
83
  * @param {Boolean} data.disconnect=false true removes all currently observed targets
78
84
  * @param {String} data.id
79
85
  * @param {String} data.observe The querySelector to match elements
86
+ * @returns {Boolean} true in case the targets got observed, false in case they got cached prior to a register() call
80
87
  */
81
88
  observe(data) {
82
89
  let me = this,
90
+ cache = me.cache,
83
91
  targets = document.querySelectorAll(data.observe),
84
92
  observer = me.map[data.id];
85
93
 
86
- data.disconnect && observer.disconnect();
94
+ if (observer) {
95
+ data.disconnect && observer.disconnect();
87
96
 
88
- targets.forEach(target => {
89
- observer.observe(target)
90
- })
97
+ targets.forEach(target => {
98
+ observer.observe(target)
99
+ })
100
+ } else {
101
+ if (!cache[data.id]) {
102
+ cache[data.id] = []
103
+ }
104
+
105
+ cache[data.id].push(data);
106
+ }
107
+
108
+ return !!observer
91
109
  }
92
110
 
93
111
  /**
@@ -101,6 +119,7 @@ class NeoIntersectionObserver extends Base {
101
119
  */
102
120
  register(data) {
103
121
  let me = this,
122
+ cache = me.cache,
104
123
  targets = data.observe && document.querySelectorAll(data.observe),
105
124
  observer;
106
125
 
@@ -114,7 +133,12 @@ class NeoIntersectionObserver extends Base {
114
133
 
115
134
  targets?.forEach(target => {
116
135
  observer.observe(target)
117
- })
136
+ });
137
+
138
+ if (cache[data.id]) {
139
+ cache[data.id].forEach(item => me.observe(item));
140
+ delete cache[data.id]
141
+ }
118
142
  }
119
143
 
120
144
  /**