neo.mjs 10.0.0-alpha.5 → 10.0.0-beta.1
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/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/resources/data/examples_devmode.json +26 -27
- package/apps/portal/resources/data/examples_dist_dev.json +26 -27
- package/apps/portal/resources/data/examples_dist_esm.json +26 -27
- package/apps/portal/resources/data/examples_dist_prod.json +27 -28
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/apps/portal/view/learn/ContentComponent.mjs +102 -111
- package/examples/table/cellEditing/MainContainer.mjs +1 -1
- package/examples/table/container/MainContainer.mjs +3 -3
- package/examples/table/nestedRecordFields/Viewport.mjs +6 -6
- package/examples/tableFiltering/MainContainer.mjs +1 -1
- package/examples/tablePerformance/MainContainer.mjs +1 -1
- package/examples/tablePerformance/MainContainer2.mjs +1 -1
- package/examples/tablePerformance/MainContainer3.mjs +2 -2
- package/examples/tableStore/MainContainer.mjs +2 -2
- package/learn/UsingTheseTopics.md +2 -2
- package/learn/benefits/ConfigSystem.md +2 -2
- package/learn/benefits/FormsEngine.md +14 -14
- package/learn/benefits/MultiWindow.md +2 -2
- package/learn/benefits/OffTheMainThread.md +2 -2
- package/learn/benefits/Speed.md +2 -2
- package/learn/gettingstarted/ComponentModels.md +4 -4
- package/learn/gettingstarted/Config.md +6 -6
- package/learn/gettingstarted/DescribingTheUI.md +4 -4
- package/learn/gettingstarted/Events.md +6 -6
- package/learn/gettingstarted/Extending.md +4 -4
- package/learn/gettingstarted/References.md +6 -6
- package/learn/gettingstarted/Workspaces.md +6 -6
- package/learn/guides/ApplicationBootstrap.md +26 -26
- package/learn/guides/ComponentsAndContainers.md +12 -12
- package/learn/guides/CustomComponents.md +2 -2
- package/learn/guides/MainThreadAddonIntro.md +2 -2
- package/learn/guides/PortalApp.md +2 -2
- package/learn/guides/StateProviders.md +12 -12
- package/learn/guides/events/CustomEvents.md +16 -16
- package/learn/guides/events/DomEvents.md +12 -12
- package/learn/javascript/ClassFeatures.md +3 -2
- package/learn/javascript/Classes.md +8 -8
- package/learn/javascript/NewNode.md +4 -4
- package/learn/javascript/Overrides.md +8 -8
- package/learn/javascript/Super.md +10 -8
- package/learn/tutorials/Earthquakes.md +54 -57
- package/learn/tutorials/TodoList.md +4 -4
- package/package.json +1 -1
- package/resources/scss/src/apps/portal/learn/ContentComponent.scss +12 -0
- package/resources/scss/src/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/src/table/plugin/CellEditing.scss +1 -1
- package/resources/scss/theme-dark/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-light/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-neo-light/Global.scss +1 -2
- package/resources/scss/theme-neo-light/table/{View.scss → Body.scss} +1 -1
- package/src/DefaultConfig.mjs +2 -2
- package/src/core/Base.mjs +59 -12
- package/src/core/Util.mjs +14 -2
- package/src/draggable/grid/header/toolbar/SortZone.mjs +21 -21
- package/src/draggable/table/header/toolbar/SortZone.mjs +1 -1
- package/src/grid/Body.mjs +2 -3
- package/src/grid/_export.mjs +1 -1
- package/src/main/addon/AmCharts.mjs +8 -11
- package/src/main/addon/Base.mjs +150 -42
- package/src/main/addon/GoogleMaps.mjs +9 -16
- package/src/main/addon/HighlightJS.mjs +2 -13
- package/src/main/addon/IntersectionObserver.mjs +21 -21
- package/src/main/addon/MonacoEditor.mjs +1 -6
- package/src/table/{View.mjs → Body.mjs} +19 -20
- package/src/table/Container.mjs +43 -43
- package/src/table/_export.mjs +2 -2
- package/src/table/plugin/CellEditing.mjs +19 -19
- package/src/vdom/Helper.mjs +9 -12
- package/src/worker/Base.mjs +1 -1
- package/src/worker/mixin/RemoteMethodAccess.mjs +1 -1
@@ -3,7 +3,7 @@
|
|
3
3
|
You do not need to define a state tree on your own.
|
4
4
|
It is sufficient to just use namespaces inside the `name` attribute of each field.
|
5
5
|
|
6
|
-
|
6
|
+
```javascript live-preview
|
7
7
|
import Button from '../button/Base.mjs';
|
8
8
|
import FormContainer from '../form/Container.mjs';
|
9
9
|
import TextField from '../form/field/Text.mjs';
|
@@ -38,7 +38,7 @@ class MainView extends FormContainer {
|
|
38
38
|
}
|
39
39
|
}
|
40
40
|
MainView = Neo.setupClass(MainView);
|
41
|
-
|
41
|
+
```
|
42
42
|
|
43
43
|
## Forms can get validated without being mounted
|
44
44
|
|
@@ -49,7 +49,7 @@ Getting the field values still works like before.
|
|
49
49
|
Use case: In case you have a form split into multiple pages and only one of them is mounted to keep
|
50
50
|
the DOM minimal, you can still get all field values.
|
51
51
|
|
52
|
-
|
52
|
+
```javascript live-preview
|
53
53
|
import Button from '../button/Base.mjs';
|
54
54
|
import Container from '../container/Base.mjs';
|
55
55
|
import FormContainer from '../form/Container.mjs';
|
@@ -89,7 +89,7 @@ class MainView extends Container {
|
|
89
89
|
}
|
90
90
|
}
|
91
91
|
MainView = Neo.setupClass(MainView);
|
92
|
-
|
92
|
+
```
|
93
93
|
|
94
94
|
## Nested Forms
|
95
95
|
|
@@ -104,28 +104,28 @@ Inside the example preview, clear the user lastname via hitting the x-button.
|
|
104
104
|
Afterwards, click on the 3 buttons at the bottom and inspect the output inside the main window console carefully.
|
105
105
|
|
106
106
|
The main form will log:
|
107
|
-
|
107
|
+
```javascript readonly
|
108
108
|
{
|
109
109
|
account: 'My Account',
|
110
110
|
product: {brand: 'Tesla', name: 'Car'},
|
111
111
|
user : {firstname: 'John', lastname: null}
|
112
112
|
}
|
113
113
|
'isValid: false'
|
114
|
-
|
114
|
+
```
|
115
115
|
|
116
116
|
The user form will log:
|
117
|
-
|
117
|
+
```javascript readonly
|
118
118
|
{user: {firstname: 'John', lastname: null}}
|
119
119
|
'isValid: false'
|
120
|
-
|
120
|
+
```
|
121
121
|
|
122
122
|
The product form will log:
|
123
|
-
|
123
|
+
```javascript readonly
|
124
124
|
{product: {brand: 'Tesla', name: 'Car'}}
|
125
125
|
'isValid: true'
|
126
|
-
|
126
|
+
```
|
127
127
|
|
128
|
-
|
128
|
+
```javascript live-preview
|
129
129
|
import Button from '../button/Base.mjs';
|
130
130
|
import Container from '../container/Base.mjs';
|
131
131
|
import FormContainer from '../form/Container.mjs';
|
@@ -223,7 +223,7 @@ class MainView extends FormContainer {
|
|
223
223
|
}
|
224
224
|
}
|
225
225
|
MainView = Neo.setupClass(MainView);
|
226
|
-
|
226
|
+
```
|
227
227
|
|
228
228
|
Bonus: Inspect the DOM Inside the `TabContainer`.
|
229
229
|
You will notice that only the active Tab is mounted inside the DOM.
|
@@ -244,7 +244,7 @@ since it does rely on defining child modules inside their own class files
|
|
244
244
|
and dynamically importing them.
|
245
245
|
|
246
246
|
In a nutshell:
|
247
|
-
|
247
|
+
```javascript readonly
|
248
248
|
{
|
249
249
|
module: TabContainer,
|
250
250
|
items : [
|
@@ -252,4 +252,4 @@ In a nutshell:
|
|
252
252
|
{module: () => import('./MyChildForm2.mjs')}
|
253
253
|
]
|
254
254
|
}
|
255
|
-
|
255
|
+
```
|
@@ -14,7 +14,7 @@ running the code. Even though it's running in a new window, it's still part of t
|
|
14
14
|
(In this case, the app is the web site you're looking at now.) That means both the code in both windows
|
15
15
|
seamlessly share events, data, etc. — the code doesn't care that some code is running in a
|
16
16
|
separate window.
|
17
|
-
|
17
|
+
```javascript live-preview
|
18
18
|
import Button from '../button/Base.mjs';
|
19
19
|
import Container from '../container/Base.mjs';
|
20
20
|
|
@@ -31,6 +31,6 @@ class MainView extends Container {
|
|
31
31
|
}
|
32
32
|
|
33
33
|
MainView = Neo.setupClass(MainView);
|
34
|
-
|
34
|
+
```
|
35
35
|
|
36
36
|
</details>
|
@@ -89,13 +89,13 @@ The worst case that could happen now is that your app worker will slow down and
|
|
89
89
|
this will not affect your UI (rendering thread → main).
|
90
90
|
Probably the best solution for single page apps (SPAs) as well as multi-window apps (MWAs) looks like this:
|
91
91
|
|
92
|
-
|
92
|
+
```json neo-component
|
93
93
|
{
|
94
94
|
"cls" : "neo-worker-setup",
|
95
95
|
"tag" : "element-loader",
|
96
96
|
"vdom": {"src": "./resources/images/workers-focus.svg"}
|
97
97
|
}
|
98
|
-
|
98
|
+
```
|
99
99
|
|
100
100
|
To prevent the app worker from handling too much logic, we can optionally spawn more workers.
|
101
101
|
Each thread has its fixed scope. Let us take a quick look into each of them.
|
package/learn/benefits/Speed.md
CHANGED
@@ -20,7 +20,7 @@ Click on Preview, then use your mouse or trackpad to pan and zoom — the he
|
|
20
20
|
If you move quickly, you might reach 20,000 or 30,000 delta updates per second. We've seen some examples that go over 40,000 updates per
|
21
21
|
second — but we've never actually hit the limit.
|
22
22
|
|
23
|
-
|
23
|
+
```javascript live-preview
|
24
24
|
import Container from '../container/Base.mjs';
|
25
25
|
import Helix from '../component/Helix.mjs';
|
26
26
|
|
@@ -43,7 +43,7 @@ class MainView extends Container {
|
|
43
43
|
}
|
44
44
|
}
|
45
45
|
MainView = Neo.setupClass(MainView);
|
46
|
-
|
46
|
+
```
|
47
47
|
|
48
48
|
|
49
49
|
If you're interested, there's <a href="../../examples/component/helix/index.html" target="_blank">a more full-featured helix example</a> that includes showing delta updates,
|
@@ -3,7 +3,7 @@ Neo has a feature that allows shared, bindable, data.
|
|
3
3
|
A _state provider_ — `Neo.state.Provider` — instance holds properties that
|
4
4
|
can be bound to component properties.
|
5
5
|
|
6
|
-
|
6
|
+
```javascript live-preview
|
7
7
|
import Container from '../container/Base.mjs';
|
8
8
|
import Label from '../component/Label.mjs';
|
9
9
|
import TextField from '../form/field/Text.mjs';
|
@@ -35,7 +35,7 @@ class MainView extends Container {
|
|
35
35
|
}
|
36
36
|
}
|
37
37
|
MainView = Neo.setupClass(MainView);
|
38
|
-
|
38
|
+
```
|
39
39
|
|
40
40
|
View model properties are visible down the containment hierarchy:
|
41
41
|
Properties introduced in a parent container will be available to any child component, and properties
|
@@ -55,7 +55,7 @@ usually coded as separate classes.)
|
|
55
55
|
|
56
56
|
Below is another example.
|
57
57
|
|
58
|
-
|
58
|
+
```javascript live-preview
|
59
59
|
import Container from '../container/Base.mjs';
|
60
60
|
import Label from '../component/Label.mjs';
|
61
61
|
import Panel from '../container/Panel.mjs';
|
@@ -107,7 +107,7 @@ class MainView extends Container {
|
|
107
107
|
}
|
108
108
|
}
|
109
109
|
MainView = Neo.setupClass(MainView);
|
110
|
-
|
110
|
+
```
|
111
111
|
|
112
112
|
In this case, the main view has three child items of type `MyPanel`, each containing a label.
|
113
113
|
The main view has a state provider with a `foo` property, and the third child has its own state provider with a `foo` property.
|
@@ -17,7 +17,7 @@ Here's an example of a new component class `Simple` with three config properties
|
|
17
17
|
The `Simple` class introduces syntax. It doesn't have any content, so if you run the code you won't
|
18
18
|
see anything. We'll change that in the next example.
|
19
19
|
|
20
|
-
|
20
|
+
```javascript live-preview
|
21
21
|
import Component from '../component/Base.mjs';
|
22
22
|
import Container from '../container/Base.mjs';
|
23
23
|
|
@@ -48,7 +48,7 @@ class MainView extends Container {
|
|
48
48
|
}
|
49
49
|
}
|
50
50
|
MainView = Neo.setupClass(MainView);
|
51
|
-
|
51
|
+
```
|
52
52
|
|
53
53
|
## Detecting when a value changes
|
54
54
|
|
@@ -57,7 +57,7 @@ a _lifecyle property_. A lifecycle property provides methods that are run as the
|
|
57
57
|
updated or accessed. You're free to implment these methods to provide business rules, normalize
|
58
58
|
values, or have side-effects, such as updating a view or firing an event.
|
59
59
|
|
60
|
-
|
60
|
+
```javascript live-preview
|
61
61
|
import Component from '../component/Base.mjs';
|
62
62
|
import Container from '../container/Base.mjs';
|
63
63
|
|
@@ -98,7 +98,7 @@ class MainView extends Container {
|
|
98
98
|
}
|
99
99
|
}
|
100
100
|
MainView = Neo.setupClass(MainView);
|
101
|
-
|
101
|
+
```
|
102
102
|
|
103
103
|
This time if you run the code you'll see "hi there" in the view. That's because the Simple instance is
|
104
104
|
configured with `bar: 'hi there'`, and since that's a lifecycle property the `afterSetBar()` method
|
@@ -110,7 +110,7 @@ Typically, the _afterSet_ method is used to update a view or to fire an event.
|
|
110
110
|
|
111
111
|
Look at this code: `afterSetBar()` fires an event, and the config in the `items[]` is listening to it.
|
112
112
|
|
113
|
-
|
113
|
+
```javascript live-preview
|
114
114
|
import Component from '../component/Base.mjs';
|
115
115
|
import Container from '../container/Base.mjs';
|
116
116
|
|
@@ -149,5 +149,5 @@ class MainView extends Container {
|
|
149
149
|
}
|
150
150
|
}
|
151
151
|
MainView = Neo.setupClass(MainView);
|
152
|
-
|
152
|
+
```
|
153
153
|
|
@@ -10,7 +10,7 @@ use to describe the component you're creating> You can also access or set the pr
|
|
10
10
|
|
11
11
|
## A view with one component
|
12
12
|
|
13
|
-
|
13
|
+
```javascript live-preview
|
14
14
|
import Button from '../button/Base.mjs';
|
15
15
|
import Container from '../container/Base.mjs';
|
16
16
|
|
@@ -27,7 +27,7 @@ class MainView extends Container {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
MainView = Neo.setupClass(MainView);
|
30
|
-
|
30
|
+
```
|
31
31
|
|
32
32
|
|
33
33
|
The button config is just an object describing the button being created. In the example, it has three
|
@@ -46,7 +46,7 @@ Let's put a second button in the container.
|
|
46
46
|
|
47
47
|
## A view with two components
|
48
48
|
|
49
|
-
|
49
|
+
```javascript live-preview
|
50
50
|
import Button from '../button/Base.mjs';
|
51
51
|
import Container from '../container/Base.mjs';
|
52
52
|
|
@@ -67,7 +67,7 @@ class MainView extends Container {
|
|
67
67
|
}
|
68
68
|
|
69
69
|
MainView = Neo.setupClass(MainView);
|
70
|
-
|
70
|
+
```
|
71
71
|
|
72
72
|
If you run the example you'll see two buttons, arranged according to the `layout`. If you'd like,
|
73
73
|
modify the code to specify `ntype:'hbox'` and run it again.
|
@@ -13,7 +13,7 @@ pairs as you need.
|
|
13
13
|
The code below shows two text fields, with `listeners` for `change` and `focusEnter`.
|
14
14
|
(The events for any component are documented in the API docs.)
|
15
15
|
|
16
|
-
|
16
|
+
```javascript live-preview
|
17
17
|
import Container from '../container/Base.mjs';
|
18
18
|
import TextField from '../form/field/Text.mjs';
|
19
19
|
|
@@ -38,7 +38,7 @@ class MainView extends Container {
|
|
38
38
|
}
|
39
39
|
}
|
40
40
|
MainView = Neo.setupClass(MainView);
|
41
|
-
|
41
|
+
```
|
42
42
|
|
43
43
|
If you run the example, and open the browser's debugger, you'll see the console being logged as you type or give
|
44
44
|
focus to either field.
|
@@ -52,7 +52,7 @@ that with a _component controller_.
|
|
52
52
|
A `Neo.controller.Component` is a simple class associated with a component class. As a view is created, an
|
53
53
|
instance of its associated controller is automatically created.
|
54
54
|
|
55
|
-
|
55
|
+
```javascript live-preview
|
56
56
|
import Base from '../controller/Component.mjs';
|
57
57
|
|
58
58
|
class MainViewController extends Base {
|
@@ -86,7 +86,7 @@ class MainView extends Container {
|
|
86
86
|
}
|
87
87
|
}
|
88
88
|
MainView = Neo.setupClass(MainView);
|
89
|
-
|
89
|
+
```
|
90
90
|
|
91
91
|
|
92
92
|
|
@@ -116,7 +116,7 @@ automatically get lifecycle methods run before the value is assigned, after the
|
|
116
116
|
before the value is accessed. We're using the _after_ method to fire a `change` event.
|
117
117
|
|
118
118
|
|
119
|
-
|
119
|
+
```javascript live-preview
|
120
120
|
import Button from '../button/Base.mjs';
|
121
121
|
import Container from '../container/Base.mjs';
|
122
122
|
|
@@ -154,4 +154,4 @@ class MainView extends Container {
|
|
154
154
|
}
|
155
155
|
}
|
156
156
|
MainView = Neo.setupClass(MainView);
|
157
|
-
|
157
|
+
```
|
@@ -5,7 +5,7 @@ to test.
|
|
5
5
|
|
6
6
|
Consider this code. It's a panel with a header and a table. The table has a store.
|
7
7
|
|
8
|
-
|
8
|
+
```javascript live-preview
|
9
9
|
import Button from '../button/Base.mjs';
|
10
10
|
import Panel from '../container/Panel.mjs';
|
11
11
|
import Table from '../table/Container.mjs';
|
@@ -42,13 +42,13 @@ class MainView extends Panel {
|
|
42
42
|
}
|
43
43
|
|
44
44
|
MainView = Neo.setupClass(MainView);
|
45
|
-
|
45
|
+
```
|
46
46
|
|
47
47
|
If you wanted, any of the configs can be refactored into their own class. Here, the button, store, and table
|
48
48
|
have been refactored into their own classes, and the main view is using them. The main view is simpler and
|
49
49
|
more abstract, and each class can be reused, tested, and maintained independently.
|
50
50
|
|
51
|
-
|
51
|
+
```javascript live-preview
|
52
52
|
import Button from '../button/Base.mjs';
|
53
53
|
import Panel from '../container/Panel.mjs';
|
54
54
|
import Store from '../data/Store.mjs';
|
@@ -103,7 +103,7 @@ class MainView extends Panel {
|
|
103
103
|
}
|
104
104
|
}
|
105
105
|
MainView = Neo.setupClass(MainView);
|
106
|
-
|
106
|
+
```
|
107
107
|
|
108
108
|
There are several use-cases for creating your own classes:
|
109
109
|
|
@@ -10,7 +10,7 @@ There are two common ways of doing that:
|
|
10
10
|
Here's an example with one button. Clicking on the button will disable it.
|
11
11
|
As you can see, the handler uses the component reference pass in via `data.component`.
|
12
12
|
|
13
|
-
|
13
|
+
```javascript live-preview
|
14
14
|
import Button from '../button/Base.mjs';
|
15
15
|
import Container from '../container/Base.mjs';
|
16
16
|
import Controller from '../controller/Component.mjs';
|
@@ -39,7 +39,7 @@ class MainView extends Container {
|
|
39
39
|
}
|
40
40
|
}
|
41
41
|
MainView = Neo.setupClass(MainView);
|
42
|
-
|
42
|
+
```
|
43
43
|
|
44
44
|
## Using getReference()
|
45
45
|
|
@@ -47,7 +47,7 @@ But what if we need to get a reference to another component in the view? In that
|
|
47
47
|
you tag the component you need with a `reference` config, then use `getReference()` in
|
48
48
|
the controller.
|
49
49
|
|
50
|
-
|
50
|
+
```javascript live-preview
|
51
51
|
import Button from '../button/Base.mjs';
|
52
52
|
import Container from '../container/Base.mjs';
|
53
53
|
import Controller from '../controller/Component.mjs';
|
@@ -84,7 +84,7 @@ class MainView extends Container {
|
|
84
84
|
}
|
85
85
|
}
|
86
86
|
MainView = Neo.setupClass(MainView);
|
87
|
-
|
87
|
+
```
|
88
88
|
|
89
89
|
## Getting a reference when debugging
|
90
90
|
|
@@ -102,7 +102,7 @@ But app logic should never use `Neo.findFirst()` and very rarely use `up()` or `
|
|
102
102
|
The following example gets a reference to the _Learn_ button at the top of this site, and changes its `text`.
|
103
103
|
Again — that use of `Neo.findFirst()` might be handy when debugging, but it should never be used in app logic.
|
104
104
|
|
105
|
-
|
105
|
+
```javascript live-preview
|
106
106
|
import Button from '../button/Base.mjs';
|
107
107
|
import Container from '../container/Base.mjs';
|
108
108
|
|
@@ -128,4 +128,4 @@ class MainView extends Container {
|
|
128
128
|
}
|
129
129
|
}
|
130
130
|
MainView = Neo.setupClass(MainView);
|
131
|
-
|
131
|
+
```
|
@@ -40,7 +40,7 @@ as well as create new views classes, their controllers, and other application lo
|
|
40
40
|
|
41
41
|
Now let's look at a source file. This is the contents of `MainView.mjs`.
|
42
42
|
|
43
|
-
|
43
|
+
```javascript readonly
|
44
44
|
import Container from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
45
45
|
import Controller from './MainViewController.mjs';
|
46
46
|
import ViewModel from './MainViewModel.mjs';
|
@@ -58,7 +58,7 @@ class MainView extends Container {
|
|
58
58
|
Neo.setupClass(MainView);
|
59
59
|
|
60
60
|
export default MainView;
|
61
|
-
|
61
|
+
```
|
62
62
|
|
63
63
|
Neo.mjs views are composed of components. A component can be a "container", which means it
|
64
64
|
visually holds or groups other components, or a regular component, like a button. The main
|
@@ -78,7 +78,7 @@ you see how a component is configured let's put a button in the container.
|
|
78
78
|
First, we need to import the class that defines buttons. Then we'll describe the new button in the
|
79
79
|
`items:[].`
|
80
80
|
|
81
|
-
|
81
|
+
```javascript readonly
|
82
82
|
import Button from '../../../node_modules/neo.mjs/src/button/Base.mjs';
|
83
83
|
import Container from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
84
84
|
import Controller from './MainViewController.mjs';
|
@@ -100,7 +100,7 @@ class MainView extends Container {
|
|
100
100
|
Neo.setupClass(MainView);
|
101
101
|
|
102
102
|
export default MainView;
|
103
|
-
|
103
|
+
```
|
104
104
|
|
105
105
|
|
106
106
|
Note the entry in `items:[]`. That's a description of the button that will be the single item in our
|
@@ -120,7 +120,7 @@ Here's a simplified running example. The `model` and `controller` are omitted, b
|
|
120
120
|
actually used in the example, and the import root path is different to reflect the location of the
|
121
121
|
Neo.mjs library relative to the examples.
|
122
122
|
|
123
|
-
|
123
|
+
```javascript live-preview
|
124
124
|
import Button from '../button/Base.mjs';
|
125
125
|
import Container from '../container/Base.mjs';
|
126
126
|
|
@@ -136,5 +136,5 @@ class MainView extends Container {
|
|
136
136
|
}
|
137
137
|
|
138
138
|
MainView = Neo.setupClass(MainView);
|
139
|
-
|
139
|
+
```
|
140
140
|
|
@@ -14,20 +14,20 @@ using Web Workers.
|
|
14
14
|
|
15
15
|
## Bootstrap Sequence
|
16
16
|
|
17
|
-
```
|
17
|
+
```text
|
18
18
|
myapp/
|
19
19
|
├── view/
|
20
20
|
│ └── Viewport.mjs // The app main view
|
21
|
-
├── app.mjs
|
22
|
-
├── index.html
|
23
|
-
└── neo-config.json
|
21
|
+
├── app.mjs // The entry-point for your code inside the app worker
|
22
|
+
├── index.html // The entry-point for a main-thread
|
23
|
+
└── neo-config.json // Framework global configs for your app
|
24
24
|
```
|
25
25
|
|
26
26
|
### 1. Entry Point: index.html
|
27
27
|
|
28
28
|
The bootstrap process begins with a minimal HTML file:
|
29
29
|
|
30
|
-
```html
|
30
|
+
```html readonly
|
31
31
|
<!DOCTYPE HTML>
|
32
32
|
<html>
|
33
33
|
<head>
|
@@ -51,7 +51,7 @@ The only JavaScript file imported is the `MicroLoader.mjs`, which is loaded as a
|
|
51
51
|
|
52
52
|
The `MicroLoader.mjs` is a small script that fetches the application configuration and bootstraps the main thread:
|
53
53
|
|
54
|
-
```javascript
|
54
|
+
```javascript readonly
|
55
55
|
fetch('./neo-config.json').then(r => r.json()).then(d => {
|
56
56
|
globalThis.Neo = {config: {...d}};
|
57
57
|
import(d.mainPath)
|
@@ -69,7 +69,7 @@ It performs these steps:
|
|
69
69
|
The `neo-config.json` file contains essential configuration for the application bootstrap. For a complete overview
|
70
70
|
of all available configuration options, you can refer to the `src/DefaultConfig.mjs` file in the Neo.mjs framework:
|
71
71
|
|
72
|
-
```json
|
72
|
+
```json readonly
|
73
73
|
{
|
74
74
|
"appPath" : "apps/myapp/app.mjs",
|
75
75
|
"basePath" : "../../",
|
@@ -88,23 +88,23 @@ of all available configuration options, you can refer to the `src/DefaultConfig.
|
|
88
88
|
```
|
89
89
|
|
90
90
|
**Key Configuration Properties:**
|
91
|
-
-
|
92
|
-
-
|
93
|
-
-
|
94
|
-
-
|
95
|
-
-
|
96
|
-
-
|
97
|
-
-
|
98
|
-
-
|
99
|
-
-
|
100
|
-
-
|
91
|
+
- `appPath` - Points to your application's entry point (app.mjs)
|
92
|
+
- `basePath` - Root path for resolving other paths
|
93
|
+
- `environment` - Controls optimization and debugging features
|
94
|
+
- `mainPath` - Framework's main thread bootstrap file
|
95
|
+
- `mainThreadAddons` - Additional features to load in the main thread
|
96
|
+
- `themes` - CSS themes to load
|
97
|
+
- `useCanvasWorker` - Controls whether to use a separate worker for canvas operations
|
98
|
+
- `useDataWorker` - Controls whether to use a separate worker for data operations
|
99
|
+
- `useServiceWorker` - Controls whether to use a service worker for caching
|
100
|
+
- `useSharedWorkers` - When set to true, ALL workers (App, VDom, Data, etc.) will be created as SharedWorkers,
|
101
101
|
enabling multi-window applications. When false, all workers will be dedicated workers (better for single-page applications).
|
102
|
-
The
|
102
|
+
The worker.Base class provides an abstraction layer that supports both types with a consistent API, allowing developers
|
103
103
|
to create an app with dedicated workers first (which are easier to debug) and then switch to shared workers with just
|
104
104
|
a one-line configuration change.
|
105
|
-
-
|
106
|
-
-
|
107
|
-
-
|
105
|
+
- `useTaskWorker` - Controls whether to use a separate worker for background tasks
|
106
|
+
- `useVdomWorker` - Controls whether to use a separate worker for virtual DOM operations
|
107
|
+
- `workerBasePath` - Location of worker initialization files
|
108
108
|
|
109
109
|
**Configuration Categories:**
|
110
110
|
- **Path Resolution** - Where to find files and modules (auto-generated by default)
|
@@ -116,7 +116,7 @@ of all available configuration options, you can refer to the `src/DefaultConfig.
|
|
116
116
|
|
117
117
|
The MicroLoader imports `Main.mjs`, which initializes the main thread:
|
118
118
|
|
119
|
-
```javascript
|
119
|
+
```javascript readonly
|
120
120
|
import Neo from './Neo.mjs';
|
121
121
|
import * as core from './core/_export.mjs';
|
122
122
|
import DomAccess from './main/DomAccess.mjs';
|
@@ -160,7 +160,7 @@ The Main class:
|
|
160
160
|
|
161
161
|
### 5. Neo.worker.Manager: Creating Workers
|
162
162
|
|
163
|
-
```javascript
|
163
|
+
```javascript readonly
|
164
164
|
class Manager extends core.Base {
|
165
165
|
// ...
|
166
166
|
|
@@ -230,7 +230,7 @@ The App worker receives the 'loadApplication' message and loads the application.
|
|
230
230
|
in Neo.mjs is an instance of Neo.controller.Application, which is not common in other frameworks like React, Angular,
|
231
231
|
or Vue (which typically just use a tag):
|
232
232
|
|
233
|
-
```javascript
|
233
|
+
```javascript readonly
|
234
234
|
class App extends Base {
|
235
235
|
// ...
|
236
236
|
|
@@ -282,7 +282,7 @@ The App worker:
|
|
282
282
|
|
283
283
|
Finally, the application's `app.mjs` file is loaded and executed:
|
284
284
|
|
285
|
-
```javascript
|
285
|
+
```javascript readonly
|
286
286
|
import Overwrites from './Overwrites.mjs'; // Optional class config default value changes for framework classes
|
287
287
|
import Viewport from './view/Viewport.mjs'; // Your main UI component
|
288
288
|
|
@@ -301,7 +301,7 @@ The app.mjs file:
|
|
301
301
|
|
302
302
|
When Neo.app() is called, it creates an Application controller and instantiates your mainView component:
|
303
303
|
|
304
|
-
```javascript
|
304
|
+
```javascript readonly
|
305
305
|
// Your Viewport component
|
306
306
|
class Viewport extends Container {
|
307
307
|
static config = {
|
@@ -25,7 +25,7 @@ primitive. Components introduce various properties, such as `width`, `height`, `
|
|
25
25
|
|
26
26
|
Here's a container, with one child item.
|
27
27
|
|
28
|
-
|
28
|
+
```javascript live-preview
|
29
29
|
import Container from '../container/Base.mjs';
|
30
30
|
|
31
31
|
class MainView extends Container {
|
@@ -42,12 +42,12 @@ class MainView extends Container {
|
|
42
42
|
}
|
43
43
|
|
44
44
|
MainView = Neo.setupClass(MainView);
|
45
|
-
|
45
|
+
```
|
46
46
|
|
47
47
|
Components also have an `html`. The `html` property is rarely used, and goes against the abstract philosophy of Neo.mjs, but
|
48
48
|
sometimes it's handy as a placeholder as you stub out views.
|
49
49
|
|
50
|
-
|
50
|
+
```javascript live-preview
|
51
51
|
import Container from '../container/Base.mjs';
|
52
52
|
|
53
53
|
class MainView extends Container {
|
@@ -65,7 +65,7 @@ class MainView extends Container {
|
|
65
65
|
}
|
66
66
|
|
67
67
|
MainView = Neo.setupClass(MainView);
|
68
|
-
|
68
|
+
```
|
69
69
|
|
70
70
|
|
71
71
|
## Layout
|
@@ -77,7 +77,7 @@ some commonly-used layouts.
|
|
77
77
|
|
78
78
|
Fix is used when there's a single child. The component is sized to fit the container.
|
79
79
|
|
80
|
-
|
80
|
+
```javascript live-preview
|
81
81
|
import Container from '../container/Base.mjs';
|
82
82
|
|
83
83
|
class MainView extends Container {
|
@@ -92,13 +92,13 @@ class MainView extends Container {
|
|
92
92
|
}
|
93
93
|
|
94
94
|
MainView = Neo.setupClass(MainView);
|
95
|
-
|
95
|
+
```
|
96
96
|
|
97
97
|
### Vbox and hbox
|
98
98
|
|
99
99
|
With `vbox` and `hbox`, items are arranged vertically or horizontally.
|
100
100
|
|
101
|
-
|
101
|
+
```javascript live-preview
|
102
102
|
import Button from '../button/Base.mjs';
|
103
103
|
import Container from '../container/Base.mjs';
|
104
104
|
|
@@ -119,13 +119,13 @@ class MainView extends Container {
|
|
119
119
|
}
|
120
120
|
|
121
121
|
MainView = Neo.setupClass(MainView);
|
122
|
-
|
122
|
+
```
|
123
123
|
|
124
124
|
### Card
|
125
125
|
|
126
126
|
A card container has multiple child items, one of which is visible.
|
127
127
|
|
128
|
-
|
128
|
+
```javascript live-preview
|
129
129
|
import Button from '../button/Base.mjs';
|
130
130
|
import Container from '../container/Base.mjs';
|
131
131
|
|
@@ -167,7 +167,7 @@ class MainView extends Container {
|
|
167
167
|
}
|
168
168
|
|
169
169
|
MainView = Neo.setupClass(MainView);
|
170
|
-
|
170
|
+
```
|
171
171
|
|
172
172
|
|
173
173
|
|
@@ -177,7 +177,7 @@ MainView = Neo.setupClass(MainView);
|
|
177
177
|
Neo.mjs is class-based, and thus, any component or container can be defined as its own class, and reused like any
|
178
178
|
other component in the framework.
|
179
179
|
|
180
|
-
|
180
|
+
```javascript live-preview
|
181
181
|
import Button from '../button/Base.mjs';
|
182
182
|
// In practice this would be some handy reusable component
|
183
183
|
class MySpecialButton extends Button {
|
@@ -209,5 +209,5 @@ class MainView extends Container {
|
|
209
209
|
}
|
210
210
|
|
211
211
|
MainView = Neo.setupClass(MainView);
|
212
|
-
|
212
|
+
```
|
213
213
|
|