neo.mjs 6.15.3 → 6.15.5
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/apps/ServiceWorker.mjs +2 -2
- package/apps/portal/view/Viewport.mjs +73 -10
- package/apps/portal/view/ViewportModel.mjs +29 -0
- package/apps/portal/view/learn/MainContainer.mjs +7 -10
- package/apps/portal/view/learn/MainContainerController.mjs +1 -1
- package/apps/portal/view/learn/PageSectionsContainer.mjs +51 -0
- package/examples/ServiceWorker.mjs +2 -2
- package/package.json +4 -4
- package/resources/data/deck/learnneo/pages/2023-10-14T19-25-08-153Z.md +0 -2
- package/resources/data/deck/learnneo/pages/ComponentsAndContainers.md +44 -11
- package/resources/data/deck/learnneo/pages/Config.md +0 -2
- package/resources/data/deck/learnneo/pages/CustomComponents.md +45 -0
- package/resources/data/deck/learnneo/pages/DescribingTheUI.md +0 -2
- package/resources/data/deck/learnneo/pages/Earthquakes.md +0 -2
- package/resources/data/deck/learnneo/pages/Events.md +0 -2
- package/resources/data/deck/learnneo/pages/Extending.md +0 -1
- package/resources/data/deck/learnneo/pages/References.md +0 -2
- package/resources/data/deck/learnneo/pages/Setup.md +0 -2
- package/resources/data/deck/learnneo/pages/TestLivePreview.md +1 -2
- package/resources/data/deck/learnneo/pages/Welcome.md +60 -0
- package/resources/data/deck/learnneo/pages/WhyNeo-Multi-Threaded.md +2 -0
- package/resources/data/deck/learnneo/pages/WhyNeo-Multi-Window.md +3 -3
- package/resources/data/deck/learnneo/pages/WhyNeo-Speed.md +34 -12
- package/resources/data/deck/learnneo/tree.json +3 -2
- package/resources/scss/src/apps/portal/learn/ContentView.scss +25 -20
- package/resources/scss/src/apps/portal/learn/LivePreview.scss +27 -6
- package/resources/scss/src/apps/portal/learn/MainContainer.scss +3 -33
- package/resources/scss/src/apps/portal/learn/PageContainer.scss +11 -6
- package/resources/scss/src/apps/portal/learn/PageSectionsContainer.scss +14 -0
- package/resources/scss/src/apps/portal/learn/PageSectionsList.scss +5 -6
- package/resources/scss/src/component/wrapper/MonacoEditor.scss +3 -0
- package/src/DefaultConfig.mjs +2 -2
- package/src/component/Base.mjs +0 -1
- package/src/component/wrapper/MonacoEditor.mjs +5 -0
- package/src/core/Base.mjs +24 -4
- package/src/form/field/ComboBox.mjs +2 -0
- package/src/list/Base.mjs +12 -5
- package/src/main/addon/IntersectionObserver.mjs +29 -5
- package/src/main/addon/Navigator.mjs +207 -155
- package/test/components/app.mjs +1 -0
- package/test/components/files/component/Base.mjs +88 -0
- package/test/components/siesta.js +1 -0
- package/apps/portal/view/learn/PageSectionsPanel.mjs +0 -59
- package/resources/scss/src/apps/portal/learn/PageSectionsPanel.scss +0 -40
@@ -1,4 +1,5 @@
|
|
1
1
|
{"data": [
|
2
|
+
{"name": "Welcome!", "parentId": null, "isLeaf": true, "id": "Welcome" },
|
2
3
|
{"name": "Why Neo.mjs?", "parentId": null, "isLeaf": false, "id": "WhyNeo"},
|
3
4
|
{"name": "Introduction ", "parentId": "WhyNeo", "isLeaf": true, "id": "WhyNeo-Intro"},
|
4
5
|
{"name": "Multi-Threaded", "parentId": "WhyNeo", "isLeaf": true, "id": "WhyNeo-Multi-Threaded"},
|
@@ -23,9 +24,9 @@
|
|
23
24
|
{"name": "Config", "parentId": "InDepth", "isLeaf": false, "id": "Config"},
|
24
25
|
{"name": "Instance Lifecycle", "parentId": "InDepth", "isLeaf": false, "id": "InstanceLifecycle"},
|
25
26
|
{"name": "User Input (Forms)", "parentId": "InDepth", "isLeaf": false, "id": "Forms"},
|
26
|
-
{"name": "
|
27
|
+
{"name": "Component and Container Basics", "parentId": "InDepth", "isLeaf": true, "id": "ComponentsAndContainers"},
|
27
28
|
{"name": "Layouts", "parentId": "InDepth", "isLeaf": false, "id": "Layouts"},
|
28
|
-
{"name": "Custom Components", "parentId": "InDepth", "isLeaf":
|
29
|
+
{"name": "Custom Components", "parentId": "InDepth", "isLeaf": true, "id": "CustomComponents"},
|
29
30
|
{"name": "Events", "parentId": "InDepth", "isLeaf": true, "expanded": false, "id": "GuideEvents"},
|
30
31
|
{"name": "Tables (Stores)", "parentId": "InDepth", "isLeaf": false, "id": "Tables"},
|
31
32
|
{"name": "Shared Bindable Data (Component Models)", "parentId": "InDepth", "isLeaf": false, "id": "InDepthComponentModels"},
|
@@ -1,25 +1,25 @@
|
|
1
1
|
.learn-content {
|
2
|
-
|
3
|
-
max-width: 900px;
|
4
|
-
padding: 0 250px 0 3rem;
|
5
|
-
margin: 0 auto;
|
6
2
|
background-color: white;
|
7
|
-
border-radius: 8px;
|
8
|
-
letter-spacing: 1px;
|
9
|
-
|
3
|
+
border-radius : 8px;
|
4
|
+
letter-spacing : 1px;
|
5
|
+
margin : 0 auto;
|
6
|
+
max-width : 900px;
|
7
|
+
overflow : unset;
|
8
|
+
padding : 0 3rem;
|
9
|
+
width : -webkit-fill-available;
|
10
10
|
|
11
11
|
pre[data-javascript] {
|
12
|
+
border : thin solid lightgray;
|
12
13
|
border-radius: 4px;
|
13
|
-
padding: 12px;
|
14
|
-
border: thin solid lightgray;
|
14
|
+
padding : 12px;
|
15
15
|
}
|
16
16
|
|
17
17
|
p {
|
18
|
-
margin: 0.5em
|
18
|
+
margin: 0.5em 0 0.7em 0;
|
19
19
|
}
|
20
20
|
|
21
21
|
details summary {
|
22
|
-
cursor: pointer;
|
22
|
+
cursor : pointer;
|
23
23
|
transition: margin 300ms ease-out;
|
24
24
|
}
|
25
25
|
|
@@ -28,12 +28,11 @@
|
|
28
28
|
}
|
29
29
|
|
30
30
|
details summary {
|
31
|
-
list-style: none;
|
32
|
-
color: #555;
|
33
|
-
display: flex;
|
34
|
-
/* also removes the list marker */
|
35
31
|
align-items: center;
|
32
|
+
color : #555;
|
33
|
+
display : flex;
|
36
34
|
font-weight: bold;
|
35
|
+
list-style : none;
|
37
36
|
}
|
38
37
|
|
39
38
|
details summary::before {
|
@@ -45,11 +44,11 @@
|
|
45
44
|
}
|
46
45
|
|
47
46
|
details summary::before {
|
48
|
-
color: #c4c4c4;
|
47
|
+
color : #c4c4c4;
|
49
48
|
font-family: var(--fa-style-family, "Font Awesome 6 Free");
|
50
|
-
font-size: 1em;
|
49
|
+
font-size : 1em;
|
51
50
|
font-weight: var(--fa-style, 900);
|
52
|
-
margin: 0.4em 0.4em 0.4em 0;
|
51
|
+
margin : 0.4em 0.4em 0.4em 0;
|
53
52
|
}
|
54
53
|
|
55
54
|
summary::-webkit-details-marker {
|
@@ -61,8 +60,8 @@
|
|
61
60
|
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
|
62
61
|
transition: 0.3s;
|
63
62
|
/* Add some padding inside the card container */
|
64
|
-
padding: 2px 16px;
|
65
|
-
font-size: 1em;
|
63
|
+
padding : 2px 16px;
|
64
|
+
font-size : 1em;
|
66
65
|
margin-bottom: 1em;
|
67
66
|
}
|
68
67
|
|
@@ -71,3 +70,9 @@
|
|
71
70
|
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
|
72
71
|
}
|
73
72
|
}
|
73
|
+
|
74
|
+
.portal-size-large {
|
75
|
+
.learn-content {
|
76
|
+
padding: 0 250px 0 3rem;
|
77
|
+
}
|
78
|
+
}
|
@@ -1,8 +1,29 @@
|
|
1
1
|
.learn-live-preview {
|
2
|
-
textarea {
|
3
|
-
height: 100%;
|
4
|
-
font-family: monospace !important;
|
5
|
-
}
|
6
|
-
|
7
2
|
margin-bottom: 2em;
|
8
|
-
|
3
|
+
|
4
|
+
.live-preview-container {
|
5
|
+
border-radius: calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
|
6
|
+
box-shadow : rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
|
7
|
+
overflow : hidden;
|
8
|
+
|
9
|
+
.neo-tab-header-toolbar {
|
10
|
+
background-color : var(--sem-color-surface-neutral-default);
|
11
|
+
border : 1px solid #e6e6e6;
|
12
|
+
border-top-left-radius : calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
|
13
|
+
border-top-right-radius: calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
|
14
|
+
padding : var(--cmp-tab-strip-height);
|
15
|
+
}
|
16
|
+
|
17
|
+
.neo-tab-strip {
|
18
|
+
margin-top: calc(var(--cmp-tab-strip-height) * (-1) - 1px);
|
19
|
+
}
|
20
|
+
|
21
|
+
.neo-tab-content-container {
|
22
|
+
background-color : transparent;
|
23
|
+
border : 1px solid #e6e6e6;
|
24
|
+
border-bottom-left-radius : calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
|
25
|
+
border-bottom-right-radius: calc(var(--cmp-tab-strip-height) + var(--cmp-button-borderradius));
|
26
|
+
border-top : 0;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
@@ -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
|
-
|
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,12 +1,11 @@
|
|
1
1
|
.learn-content-container {
|
2
|
-
|
3
|
-
// padding: 0 3rem;
|
4
|
-
overflow: scroll;
|
2
|
+
overflow: auto;
|
5
3
|
|
6
4
|
.content-bottom-toolbar {
|
7
|
-
gap
|
8
|
-
padding: 0 3rem;
|
9
|
-
margin-
|
5
|
+
gap : 8px;
|
6
|
+
padding : 0 3rem;
|
7
|
+
margin-bottom: 3rem;
|
8
|
+
margin-top : 3rem;
|
10
9
|
|
11
10
|
.neo-button {
|
12
11
|
flex : 1 !important;
|
@@ -34,3 +33,9 @@
|
|
34
33
|
}
|
35
34
|
}
|
36
35
|
}
|
36
|
+
|
37
|
+
.portal-size-large {
|
38
|
+
.content-bottom-toolbar {
|
39
|
+
margin-right: 250px;
|
40
|
+
}
|
41
|
+
}
|
@@ -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
|
+
}
|
@@ -1,15 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
1
|
.portal-page-sections-list.neo-list {
|
4
2
|
.neo-h3 {
|
5
3
|
margin-left: 1.5em;
|
6
4
|
}
|
7
5
|
|
8
6
|
.neo-list-item {
|
9
|
-
color
|
10
|
-
height
|
11
|
-
|
12
|
-
padding:
|
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;
|
13
12
|
|
14
13
|
&[aria-selected=true] {
|
15
14
|
background-color: transparent !important;
|
package/src/DefaultConfig.mjs
CHANGED
@@ -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.
|
263
|
+
* @default '6.15.5'
|
264
264
|
* @memberOf! module:Neo
|
265
265
|
* @name config.version
|
266
266
|
* @type String
|
267
267
|
*/
|
268
|
-
version: '6.15.
|
268
|
+
version: '6.15.5'
|
269
269
|
};
|
270
270
|
|
271
271
|
Object.assign(DefaultConfig, {
|
package/src/component/Base.mjs
CHANGED
@@ -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
|
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
|
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
|
@@ -342,6 +342,7 @@ class ComboBox extends Picker {
|
|
342
342
|
displayField : me.displayField,
|
343
343
|
itemRole : 'option',
|
344
344
|
itemsFocusable: false,
|
345
|
+
keepFocusIndex: true,
|
345
346
|
navigator : {eventSource: me.getInputElId()},
|
346
347
|
parentId : me.id,
|
347
348
|
role : 'listbox',
|
@@ -760,6 +761,7 @@ class ComboBox extends Picker {
|
|
760
761
|
if (!me.programmaticValueChange) {
|
761
762
|
// changing the input => silent record reset
|
762
763
|
me._value = null;
|
764
|
+
me.list?.selectionModel.deselectAll();
|
763
765
|
|
764
766
|
me.filterOnInput(inputValue)
|
765
767
|
}
|
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
|
-
|
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
|
292
|
-
id
|
293
|
-
|
294
|
-
|
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
|
-
|
94
|
+
if (observer) {
|
95
|
+
data.disconnect && observer.disconnect();
|
87
96
|
|
88
|
-
|
89
|
-
|
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
|
/**
|