neo.mjs 9.15.0 → 10.0.0-alpha.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/email/view/Viewport.mjs +2 -2
- package/apps/form/view/Viewport.mjs +1 -1
- package/apps/portal/index.html +1 -1
- package/apps/portal/view/examples/List.mjs +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/apps/portal/view/learn/ContentComponent.mjs +5 -5
- package/apps/realworld2/view/HomeContainer.mjs +1 -1
- package/apps/route/view/center/CardAdministration.mjs +3 -3
- package/apps/route/view/center/CardAdministrationDenied.mjs +2 -2
- package/apps/route/view/center/CardContact.mjs +2 -2
- package/apps/route/view/center/CardHome.mjs +2 -2
- package/apps/route/view/center/CardSection1.mjs +2 -2
- package/apps/route/view/center/CardSection2.mjs +2 -2
- package/buildScripts/createApp.mjs +2 -2
- package/docs/app/view/classdetails/HeaderComponent.mjs +3 -3
- package/docs/app/view/classdetails/MembersList.mjs +43 -46
- package/docs/app/view/classdetails/SourceViewComponent.mjs +1 -1
- package/docs/app/view/classdetails/TutorialComponent.mjs +1 -1
- package/examples/component/toast/MainContainer.mjs +16 -16
- package/examples/component/wrapper/googleMaps/MarkerDialog.mjs +4 -4
- package/examples/fields/MainContainer.mjs +1 -1
- package/examples/panel/MainContainer.mjs +2 -2
- package/examples/tab/container/MainContainer.mjs +3 -3
- package/examples/tabs/MainContainer.mjs +2 -2
- package/examples/tabs/MainContainer2.mjs +3 -3
- package/examples/viewport/MainContainer.mjs +2 -2
- package/package.json +3 -3
- package/resources/data/deck/learnneo/pages/UsingTheseTopics.md +65 -0
- package/resources/data/deck/learnneo/pages/benefits/ConfigSystem.md +1 -1
- package/resources/data/deck/learnneo/pages/benefits/FormsEngine.md +7 -7
- package/resources/data/deck/learnneo/pages/benefits/FourEnvironments.md +10 -11
- package/resources/data/deck/learnneo/pages/benefits/Introduction.md +38 -5
- package/resources/data/deck/learnneo/pages/benefits/MultiWindow.md +1 -1
- package/resources/data/deck/learnneo/pages/benefits/Speed.md +1 -1
- package/resources/data/deck/learnneo/pages/gettingstarted/ComponentModels.md +2 -2
- package/resources/data/deck/learnneo/pages/gettingstarted/Config.md +3 -3
- package/resources/data/deck/learnneo/pages/gettingstarted/DescribingTheUI.md +2 -2
- package/resources/data/deck/learnneo/pages/gettingstarted/Events.md +3 -3
- package/resources/data/deck/learnneo/pages/gettingstarted/Extending.md +2 -2
- package/resources/data/deck/learnneo/pages/gettingstarted/References.md +3 -3
- package/resources/data/deck/learnneo/pages/gettingstarted/Workspaces.md +3 -3
- package/resources/data/deck/learnneo/pages/guides/ComponentsAndContainers.md +6 -6
- package/resources/data/deck/learnneo/pages/guides/CustomComponents.md +1 -1
- package/resources/data/deck/learnneo/pages/guides/MainThreadAddonIntro.md +1 -1
- package/resources/data/deck/learnneo/pages/guides/StateProviders.md +6 -6
- package/resources/data/deck/learnneo/pages/guides/events/CustomEvents.md +8 -8
- package/resources/data/deck/learnneo/pages/guides/events/DomEvents.md +11 -11
- package/resources/data/deck/learnneo/pages/javascript/Classes.md +4 -4
- package/resources/data/deck/learnneo/pages/javascript/NewNode.md +2 -2
- package/resources/data/deck/learnneo/pages/javascript/Overrides.md +4 -4
- package/resources/data/deck/learnneo/pages/tutorials/Earthquakes.md +21 -21
- package/resources/data/deck/learnneo/pages/tutorials/TodoList.md +2 -2
- package/resources/data/deck/learnneo/tree.json +1 -1
- package/resources/data/deck/training/pages/2022-12-27T21-55-23-144Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-29T18-36-08-226Z.md +1 -1
- package/resources/data/deck/training/pages/2022-12-29T18-36-56-893Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-29T20-37-08-919Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-29T20-37-20-344Z.md +2 -2
- package/resources/data/deck/training/pages/2023-01-13T21-48-17-258Z.md +2 -2
- package/resources/data/deck/training/pages/2023-02-05T17-44-53-815Z.md +9 -9
- package/resources/data/deck/training/pages/2023-10-14T19-25-08-153Z.md +1 -1
- package/resources/scss/src/apps/portal/learn/ContentComponent.scss +17 -13
- package/src/DefaultConfig.mjs +14 -2
- package/src/Main.mjs +14 -5
- package/src/button/Base.mjs +1 -1
- package/src/calendar/view/calendars/List.mjs +1 -1
- package/src/component/Base.mjs +11 -11
- package/src/component/Chip.mjs +1 -1
- package/src/component/Helix.mjs +3 -3
- package/src/component/Process.mjs +2 -2
- package/src/component/StatusBadge.mjs +2 -2
- package/src/component/Timer.mjs +1 -1
- package/src/component/Toast.mjs +2 -2
- package/src/container/Base.mjs +1 -1
- package/src/form/field/CheckBox.mjs +2 -2
- package/src/form/field/FileUpload.mjs +14 -14
- package/src/form/field/Range.mjs +1 -1
- package/src/form/field/Text.mjs +1 -1
- package/src/form/field/trigger/Base.mjs +2 -2
- package/src/form/field/trigger/SpinUpDown.mjs +2 -2
- package/src/grid/View.mjs +1 -1
- package/src/main/DeltaUpdates.mjs +382 -0
- package/src/main/DomAccess.mjs +13 -36
- package/src/main/render/DomApiRenderer.mjs +138 -0
- package/src/main/render/StringBasedRenderer.mjs +58 -0
- package/src/table/View.mjs +1 -1
- package/src/table/plugin/CellEditing.mjs +1 -1
- package/src/tree/Accordion.mjs +11 -11
- package/src/tree/List.mjs +12 -5
- package/src/vdom/Helper.mjs +174 -292
- package/src/vdom/VNode.mjs +47 -11
- package/src/vdom/domConstants.mjs +65 -0
- package/src/vdom/util/DomApiVnodeCreator.mjs +51 -0
- package/src/vdom/util/StringFromVnode.mjs +123 -0
- package/src/worker/mixin/RemoteMethodAccess.mjs +13 -1
- package/resources/data/deck/learnneo/pages/Welcome.md +0 -64
- package/src/main/mixin/DeltaUpdates.mjs +0 -352
@@ -34,7 +34,7 @@ the class. If you add `console.log(this);`, the output is most likely not want y
|
|
34
34
|
For the second Button we are defining a non-bound function, in which case `this` will point
|
35
35
|
to the Component instance.
|
36
36
|
|
37
|
-
<pre data-
|
37
|
+
<pre data-code-livepreview>
|
38
38
|
import Container from '../container/Base.mjs';
|
39
39
|
|
40
40
|
class MainView extends Container {
|
@@ -44,14 +44,14 @@ class MainView extends Container {
|
|
44
44
|
style : {padding: '1em'},
|
45
45
|
|
46
46
|
items: [{
|
47
|
-
vdom: {tag: 'button',
|
47
|
+
vdom: {tag: 'button', html: 'Button 1'},
|
48
48
|
|
49
49
|
domListeners: [{
|
50
50
|
click: data => Neo.Main.log({value: `Clicked on ${data.component.id}`})
|
51
51
|
}]
|
52
52
|
}, {
|
53
53
|
style: {marginTop: '1em'},
|
54
|
-
vdom : {tag: 'button',
|
54
|
+
vdom : {tag: 'button', html: 'Button 2'},
|
55
55
|
|
56
56
|
domListeners: [{
|
57
57
|
click(data) {
|
@@ -72,7 +72,7 @@ A good example would be `tab.header.Toolbar`, where clicking on a Button will ch
|
|
72
72
|
You can use string based listeners. In case the handler method lives within the parent tree (any level),
|
73
73
|
we need to prefix these listeners with `up.`.
|
74
74
|
|
75
|
-
<pre data-
|
75
|
+
<pre data-code-livepreview>
|
76
76
|
import Container from '../container/Base.mjs';
|
77
77
|
|
78
78
|
class MainView extends Container {
|
@@ -82,7 +82,7 @@ class MainView extends Container {
|
|
82
82
|
style : {padding: '1em'},
|
83
83
|
|
84
84
|
items: [{
|
85
|
-
vdom: {tag: 'button',
|
85
|
+
vdom: {tag: 'button', html: 'Button 1'},
|
86
86
|
|
87
87
|
domListeners: [{
|
88
88
|
click: 'up.onButtonClick'
|
@@ -107,7 +107,7 @@ to find the closest match.
|
|
107
107
|
|
108
108
|
A good use case would be a form submit Button, where a click will trigger a communication to the backend.
|
109
109
|
|
110
|
-
<pre data-
|
110
|
+
<pre data-code-livepreview>
|
111
111
|
import Container from '../container/Base.mjs';
|
112
112
|
import Controller from '../controller/Component.mjs';
|
113
113
|
|
@@ -129,7 +129,7 @@ class MainView extends Container {
|
|
129
129
|
style : {padding: '1em'},
|
130
130
|
|
131
131
|
items: [{
|
132
|
-
vdom: {tag: 'button',
|
132
|
+
vdom: {tag: 'button', html: 'Button 1'},
|
133
133
|
|
134
134
|
domListeners: [{
|
135
135
|
click: 'onButtonClick'
|
@@ -146,7 +146,7 @@ MainView = Neo.setupClass(MainView);
|
|
146
146
|
|
147
147
|
We can further delegate listeners to specific DOM nodes within our Component:
|
148
148
|
|
149
|
-
<pre data-
|
149
|
+
<pre data-code-livepreview>
|
150
150
|
import Container from '../container/Base.mjs';
|
151
151
|
|
152
152
|
class MainView extends Container {
|
@@ -184,7 +184,7 @@ we will get logs when clicking on the blue div too.
|
|
184
184
|
|
185
185
|
We can prevent listeners from bubbling upwards:
|
186
186
|
|
187
|
-
<pre data-
|
187
|
+
<pre data-code-livepreview>
|
188
188
|
import Container from '../container/Base.mjs';
|
189
189
|
|
190
190
|
class MainView extends Container {
|
@@ -237,7 +237,7 @@ While we could just manually order the array inside the following example,
|
|
237
237
|
there can be use cases where multiple subscribers get added at run-time and developers
|
238
238
|
can not be sure about the adding order.
|
239
239
|
|
240
|
-
<pre data-
|
240
|
+
<pre data-code-livepreview>
|
241
241
|
import Container from '../container/Base.mjs';
|
242
242
|
|
243
243
|
class MainView extends Container {
|
@@ -247,7 +247,7 @@ class MainView extends Container {
|
|
247
247
|
style : {padding: '1em'},
|
248
248
|
|
249
249
|
items: [{
|
250
|
-
vdom : {tag: 'button',
|
250
|
+
vdom : {tag: 'button', html: 'Button 1'},
|
251
251
|
|
252
252
|
domListeners: [
|
253
253
|
{click: data => Neo.Main.log({value: 'Listener 1'})},
|
@@ -2,7 +2,7 @@ Neo.mjs classes are standard JavaScript classes. Every source file
|
|
2
2
|
you write will be a class definition, extending some Neo.mjs
|
3
3
|
class.
|
4
4
|
|
5
|
-
<pre data-
|
5
|
+
<pre data-code-readonly>
|
6
6
|
import Base from '../../../node_modules/neo.mjs/src/core/Base.mjs';
|
7
7
|
|
8
8
|
class Mammal extends Base {
|
@@ -29,7 +29,7 @@ and create instances as needed.
|
|
29
29
|
|
30
30
|
Let's add a `name` propery to the class.
|
31
31
|
|
32
|
-
<pre data-
|
32
|
+
<pre data-code-readonly>
|
33
33
|
import Base from '../../../node_modules/neo.mjs/src/core/Base.mjs';
|
34
34
|
|
35
35
|
class Mammal extends Base {
|
@@ -61,7 +61,7 @@ anywhere in the class hierarchy.
|
|
61
61
|
Since our class defines a `name` property, we can specify that when creating
|
62
62
|
the instance, using the second argument to the `create` method.
|
63
63
|
|
64
|
-
<pre data-
|
64
|
+
<pre data-code-readonly>
|
65
65
|
const myMammal = Neo.create(Mammal, {
|
66
66
|
name: 'Creature'
|
67
67
|
});
|
@@ -73,7 +73,7 @@ Since _you_ define those properties, you can
|
|
73
73
|
look for them in class methods and use them as needed.
|
74
74
|
Let's add a `speak()` method that uses the `name` property.
|
75
75
|
|
76
|
-
<pre data-
|
76
|
+
<pre data-code-readonly>
|
77
77
|
import Base from '../../../node_modules/neo.mjs/src/core/Base.mjs';
|
78
78
|
|
79
79
|
class Mammal extends Base {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<pre data-
|
1
|
+
<pre data-code-readonly>
|
2
2
|
import Base from '../../../node_modules/neo.mjs/src/core/Base.mjs';
|
3
3
|
|
4
4
|
class Mammal extends Base {
|
@@ -15,7 +15,7 @@ export default Mammal; // Makes the class available elsewhere.
|
|
15
15
|
|
16
16
|
|
17
17
|
|
18
|
-
<pre data-
|
18
|
+
<pre data-code-livepreview>
|
19
19
|
import Base from '../../../node_modules/neo.mjs/src/core/Base.mjs';
|
20
20
|
|
21
21
|
class Mammal extends Base {
|
@@ -3,7 +3,7 @@ In Neo.mjs you sub-class and override methods in the usual way.
|
|
3
3
|
Here, we'll extend `Mammal` and override the `speak()` method.
|
4
4
|
(For brevity, we'll exclude `export` and `import` statements.)
|
5
5
|
|
6
|
-
<pre data-
|
6
|
+
<pre data-code-readonly>
|
7
7
|
class Mammal extends Base {
|
8
8
|
static config = {
|
9
9
|
className: 'Simple.example.Mammal',
|
@@ -17,7 +17,7 @@ class Mammal extends Base {
|
|
17
17
|
Neo.setupClass(Mammal);
|
18
18
|
</pre>
|
19
19
|
|
20
|
-
<pre data-
|
20
|
+
<pre data-code-readonly>
|
21
21
|
class Human extends Mammal {
|
22
22
|
static config = {
|
23
23
|
className: 'Simple.example.Human',
|
@@ -38,7 +38,7 @@ Neo.setupClass(Mammal);
|
|
38
38
|
Any class in the hierarchy is free to add new properties and methods. Let's add
|
39
39
|
a property and behavior (method) to the Human class.
|
40
40
|
|
41
|
-
<pre data-
|
41
|
+
<pre data-code-readonly>
|
42
42
|
import Base from '../../../node_modules/neo.mjs/src/core/Base.mjs';
|
43
43
|
|
44
44
|
class Mammal extends Base {
|
@@ -53,7 +53,7 @@ class Mammal extends Base {
|
|
53
53
|
}
|
54
54
|
</pre>
|
55
55
|
|
56
|
-
<pre data-
|
56
|
+
<pre data-code-readonly>
|
57
57
|
class Human extends Mammal {
|
58
58
|
static config = {
|
59
59
|
className: 'Simple.example.Human',
|
@@ -187,7 +187,7 @@ later in the lab.
|
|
187
187
|
Use a code editor and look at `workspace/apps/earthquakes/src/view/MainView.mjs`. You'll see the
|
188
188
|
following class definition:
|
189
189
|
|
190
|
-
<pre data-
|
190
|
+
<pre data-code-readonly>
|
191
191
|
import Base from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
192
192
|
import Controller from './MainViewController.mjs';
|
193
193
|
import MainStateProvider from './MainStateProvider.mjs';
|
@@ -223,7 +223,7 @@ that buttons have various configs, such as `text`, which is the button text, `ic
|
|
223
223
|
is typically a FontAwesome CSS class used to show an icon, and `handler`, which specifies
|
224
224
|
which method to run when the button is clicked. We'll use `text`.
|
225
225
|
|
226
|
-
<pre data-
|
226
|
+
<pre data-code-readonly>
|
227
227
|
|
228
228
|
import Base from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
229
229
|
import Button from '../../../node_modules/neo.mjs/src/button/Base.mjs';
|
@@ -271,7 +271,7 @@ for the classes you define.
|
|
271
271
|
|
272
272
|
Let's change the layout to arrange items vertically, with items aligned horizontally at the start.
|
273
273
|
|
274
|
-
<pre data-
|
274
|
+
<pre data-code-readonly>
|
275
275
|
layout: {
|
276
276
|
ntype: 'vbox',
|
277
277
|
align: 'start'
|
@@ -422,7 +422,7 @@ its methods. Let's try that out by adding a method.
|
|
422
422
|
|
423
423
|
Edit `apps/earthquakes/view/MainView.mjs` and add a method.
|
424
424
|
|
425
|
-
<pre data-
|
425
|
+
<pre data-code-readonly>
|
426
426
|
|
427
427
|
import Base from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
428
428
|
import Button from '../../../node_modules/neo.mjs/src/button/Base.mjs';
|
@@ -494,7 +494,7 @@ At this point we have a application with minimal content. You also know how to d
|
|
494
494
|
|
495
495
|
Replace the button with a table by replacing `MainView.mjs` with the following content.
|
496
496
|
|
497
|
-
<pre data-
|
497
|
+
<pre data-code-readonly>
|
498
498
|
|
499
499
|
import Base from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
500
500
|
import Table from '../../../node_modules/neo.mjs/src/table/Container.mjs';
|
@@ -582,7 +582,7 @@ Let's review the code and see what it's doing.
|
|
582
582
|
A store is a collection of records. A record is described in the `model` and the model's `fields`.
|
583
583
|
Here's the config for the store.
|
584
584
|
|
585
|
-
<pre data-
|
585
|
+
<pre data-code-readonly>
|
586
586
|
{
|
587
587
|
module: Store,
|
588
588
|
model: {
|
@@ -602,7 +602,7 @@ Here's the config for the store.
|
|
602
602
|
</pre>
|
603
603
|
|
604
604
|
The feed looks like this.
|
605
|
-
<pre data-
|
605
|
+
<pre data-code-readonly>
|
606
606
|
{
|
607
607
|
"data": [{
|
608
608
|
"timestamp": "2024-09-29T16:45:14.000Z",
|
@@ -632,7 +632,7 @@ of items.
|
|
632
632
|
|
633
633
|
Tables have two key configs: `store` and `columns`. Here's the columns config:
|
634
634
|
|
635
|
-
<pre data-
|
635
|
+
<pre data-code-readonly>
|
636
636
|
columns: [{
|
637
637
|
dataField: "timestamp",
|
638
638
|
text: "Date",
|
@@ -672,7 +672,7 @@ abstract, and it allows those classes to be tested in isolation.
|
|
672
672
|
|
673
673
|
Create a new file named `apps/earthquakes/view/earthquakes/Table.mjs` with this content.
|
674
674
|
|
675
|
-
<pre data-
|
675
|
+
<pre data-code-readonly>
|
676
676
|
import Base from '../../../../node_modules/neo.mjs/src/table/Container.mjs';
|
677
677
|
|
678
678
|
class Table extends Base {
|
@@ -735,7 +735,7 @@ You can confirm that an instance _was created_ by using the DevTools console and
|
|
735
735
|
<details>
|
736
736
|
<summary>Here's the code</summary>
|
737
737
|
|
738
|
-
<pre data-
|
738
|
+
<pre data-code-readonly>
|
739
739
|
import Base from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
740
740
|
import Controller from './MainViewController.mjs';
|
741
741
|
import EarthquakesTable from './earthquakes/Table.mjs';
|
@@ -858,7 +858,7 @@ State Providers have two key configs: `data` and `stores`.
|
|
858
858
|
|
859
859
|
Add a `stores` property to the state provider config that holds a copy of the store.
|
860
860
|
|
861
|
-
<pre data-
|
861
|
+
<pre data-code-readonly>
|
862
862
|
import Base from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
863
863
|
import Controller from './MainViewController.mjs';
|
864
864
|
import EarthquakesTable from './earthquakes/Table.mjs';
|
@@ -972,7 +972,7 @@ value is assigned to the table's `store` property.
|
|
972
972
|
|
973
973
|
Replace each table's `store` config with the binding.
|
974
974
|
|
975
|
-
<pre data-
|
975
|
+
<pre data-code-readonly>
|
976
976
|
|
977
977
|
import Base from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
978
978
|
import Controller from './MainViewController.mjs';
|
@@ -1033,7 +1033,7 @@ Save, refresh, and look at network traffic: you'll see a _single_ call to the we
|
|
1033
1033
|
|
1034
1034
|
You can further prove we're using a shared instance by running these statements in the console.
|
1035
1035
|
|
1036
|
-
<pre data-
|
1036
|
+
<pre data-code-readonly>
|
1037
1037
|
a = Neo.findFirst({ntype:'earthquakes-main'}).stateProvider.stores.earthquakes;
|
1038
1038
|
b = Neo.find({ntype:'earthquakes-table'})[0].store;
|
1039
1039
|
c = Neo.find({ntype:'earthquakes-table'})[1].store;
|
@@ -1056,7 +1056,7 @@ Since the starter app already provides `MainStateProvider`, all we need to do is
|
|
1056
1056
|
|
1057
1057
|
Here's the resulting code you should place into `MainStateProvider.mjs`.
|
1058
1058
|
|
1059
|
-
<pre data-
|
1059
|
+
<pre data-code-readonly>
|
1060
1060
|
import StateProvider from '../../../node_modules/neo.mjs/src/state/Provider.mjs';
|
1061
1061
|
import Store from '../../../node_modules/neo.mjs/src/data/Store.mjs';
|
1062
1062
|
|
@@ -1091,7 +1091,7 @@ export default Neo.setupClass(MainStateProvider);
|
|
1091
1091
|
|
1092
1092
|
And you need to remove the `stores` config from the main view as follows.
|
1093
1093
|
|
1094
|
-
<pre data-
|
1094
|
+
<pre data-code-readonly>
|
1095
1095
|
import Container from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
1096
1096
|
import Controller from './MainViewController.mjs';
|
1097
1097
|
import EarthquakesTable from './earthquakes/Table.mjs';
|
@@ -1188,7 +1188,7 @@ directory, but instead, move the files to their individual locations.
|
|
1188
1188
|
|
1189
1189
|
Edit `apps/earthquakes/neo-config.json` and add entries for the Google Maps add-on and the map key.
|
1190
1190
|
|
1191
|
-
<pre data-
|
1191
|
+
<pre data-code-readonly>
|
1192
1192
|
{
|
1193
1193
|
"appPath": "../../apps/earthquakes/app.mjs",
|
1194
1194
|
"basePath": "../../",
|
@@ -1227,7 +1227,7 @@ lets us implement those via two properties:
|
|
1227
1227
|
|
1228
1228
|
Edit `apps/earthquakes/view/MainStateProvider.mjs` and modify `fields` as follows.
|
1229
1229
|
|
1230
|
-
<pre data-
|
1230
|
+
<pre data-code-readonly>
|
1231
1231
|
fields: [{
|
1232
1232
|
name: "location",
|
1233
1233
|
}, {
|
@@ -1278,7 +1278,7 @@ and show it implace of the top table. The map should be centered on Iceland. To
|
|
1278
1278
|
|
1279
1279
|
If we replace the top table with the map, `view/MainView.mjs` ends up with this content.
|
1280
1280
|
|
1281
|
-
<pre data-
|
1281
|
+
<pre data-code-readonly>
|
1282
1282
|
|
1283
1283
|
import Container from '../container/Base.mjs';
|
1284
1284
|
import Controller from './MainViewController.mjs';
|
@@ -1333,7 +1333,7 @@ export default Neo.setupClass(MainView);
|
|
1333
1333
|
|
1334
1334
|
Add this config to the map.
|
1335
1335
|
|
1336
|
-
<pre data-
|
1336
|
+
<pre data-code-readonly>
|
1337
1337
|
bind: {
|
1338
1338
|
markerStore: 'stores.earthquakes'
|
1339
1339
|
}
|
@@ -1365,7 +1365,7 @@ Table Views fire a select event, passing an object that contains a reference to
|
|
1365
1365
|
|
1366
1366
|
Add this table config:
|
1367
1367
|
|
1368
|
-
<pre data-
|
1368
|
+
<pre data-code-readonly>
|
1369
1369
|
viewConfig: {
|
1370
1370
|
listeners: {
|
1371
1371
|
select: (data) => console.log(data.record)
|
@@ -1391,7 +1391,7 @@ After changing the value you should immediately see it reflected in the table ro
|
|
1391
1391
|
|
1392
1392
|
Now add a `markerClick` listener to the Google Map.
|
1393
1393
|
|
1394
|
-
<pre data-
|
1394
|
+
<pre data-code-readonly>
|
1395
1395
|
listeners: {
|
1396
1396
|
markerClick: data => console.log(data.data.record)
|
1397
1397
|
}
|
@@ -3,7 +3,7 @@
|
|
3
3
|
In case you did not work with neo yet, but come from a more HTML driven ecosystem,
|
4
4
|
you could achieve the task in a similar way.
|
5
5
|
|
6
|
-
<pre data-
|
6
|
+
<pre data-code-livepreview>
|
7
7
|
import Component from '../component/Base.mjs';
|
8
8
|
import NeoArray from '../util/Array.mjs';
|
9
9
|
import VdomUtil from '../util/VDom.mjs';
|
@@ -116,7 +116,7 @@ MainComponent = Neo.setupClass(MainComponent);
|
|
116
116
|
|
117
117
|
content
|
118
118
|
|
119
|
-
<pre data-
|
119
|
+
<pre data-code-livepreview>
|
120
120
|
import Container from '../container/Base.mjs';
|
121
121
|
import List from '../list/Base.mjs';
|
122
122
|
import Model from '../data/Model.mjs';
|
@@ -1,5 +1,5 @@
|
|
1
1
|
{"data": [
|
2
|
-
{"name": "
|
2
|
+
{"name": "Using These Topics", "parentId": null, "id": "UsingTheseTopics" },
|
3
3
|
{"name": "Benefits", "parentId": null, "isLeaf": false, "id": "Benefits"},
|
4
4
|
{"name": "Introduction ", "parentId": "Benefits", "id": "benefits.Introduction"},
|
5
5
|
{"name": "Off the Main Thread", "parentId": "Benefits", "id": "benefits.OffTheMainThread"},
|
@@ -27,13 +27,13 @@ class MainContainer extends Viewport {
|
|
27
27
|
iconCls: 'fa fa-home',
|
28
28
|
text: 'Tab 1'
|
29
29
|
},
|
30
|
-
vdom: {
|
30
|
+
vdom: { html: 'Welcome to your new Neo App.' }
|
31
31
|
}, {
|
32
32
|
header: {
|
33
33
|
iconCls: 'fa fa-play-circle',
|
34
34
|
text: 'Tab 2'
|
35
35
|
},
|
36
|
-
vdom: {
|
36
|
+
vdom: { html: 'Have fun creating something awesome!' }
|
37
37
|
}]
|
38
38
|
}]
|
39
39
|
}
|
@@ -85,7 +85,7 @@ class MainContainer extends Viewport {
|
|
85
85
|
text: 'Tab 1'
|
86
86
|
},
|
87
87
|
vdom: {
|
88
|
-
|
88
|
+
html: 'Welcome to your new Neo App.'
|
89
89
|
}
|
90
90
|
}, {
|
91
91
|
header: {
|
@@ -93,7 +93,7 @@ class MainContainer extends Viewport {
|
|
93
93
|
text: 'Tab 2'
|
94
94
|
},
|
95
95
|
vdom: {
|
96
|
-
|
96
|
+
html: 'Have fun creating something awesome!'
|
97
97
|
}
|
98
98
|
}]
|
99
99
|
}],
|
@@ -30,13 +30,13 @@ class MainContainer extends Viewport {
|
|
30
30
|
iconCls: 'fa fa-home',
|
31
31
|
text: 'Tab 1'
|
32
32
|
},
|
33
|
-
vdom: {
|
33
|
+
vdom: { html: 'Welcome to your new Neo App.' }
|
34
34
|
}, {
|
35
35
|
header: {
|
36
36
|
iconCls: 'fa fa-play-circle',
|
37
37
|
text: 'Tab 2'
|
38
38
|
},
|
39
|
-
vdom: {
|
39
|
+
vdom: { html: 'Have fun creating something awesome!' }
|
40
40
|
}]
|
41
41
|
}]
|
42
42
|
}
|
@@ -27,13 +27,13 @@ class MainContainer extends Viewport {
|
|
27
27
|
iconCls: 'fa fa-home',
|
28
28
|
text: 'Tab 1'
|
29
29
|
},
|
30
|
-
vdom: {
|
30
|
+
vdom: { html: 'Welcome to your new Neo App.' }
|
31
31
|
}, {
|
32
32
|
header: {
|
33
33
|
iconCls: 'fa fa-play-circle',
|
34
34
|
text: 'Tab 2'
|
35
35
|
},
|
36
|
-
vdom: {
|
36
|
+
vdom: { html: 'Have fun creating something awesome!' }
|
37
37
|
}]
|
38
38
|
}]
|
39
39
|
}
|
@@ -27,8 +27,8 @@ in the `afterSetBusiness()` method.
|
|
27
27
|
},
|
28
28
|
vdom: {
|
29
29
|
cn: [{
|
30
|
-
tag: 'h2',
|
31
|
-
|
30
|
+
tag : 'h2',
|
31
|
+
html: 'foo'
|
32
32
|
}]
|
33
33
|
}
|
34
34
|
}, {
|
@@ -47,14 +47,14 @@ Change the detail view's `afterSetBusiness()` method to update the `vdom`.
|
|
47
47
|
afterSetBusiness(business){
|
48
48
|
if (!business) return;
|
49
49
|
const view = this.getReference('view');
|
50
|
-
view.vdom.cn[0].
|
50
|
+
view.vdom.cn[0].html = business.title;
|
51
51
|
view.update();
|
52
52
|
}
|
53
53
|
|
54
54
|
<b>Important: </b>The `update()` method tells Neo to apply vdom changes to the DOM.
|
55
55
|
Any time you change a set of vdom properties you need to run `update()`.
|
56
56
|
|
57
|
-
You don't need the first item's `
|
57
|
+
You don't need the first item's `html:'foo'` property any more, so you can
|
58
58
|
remove that from the first item's config.
|
59
59
|
|
60
60
|
Save, refresh, and confirm that the title is shown as the business is set.
|
@@ -76,8 +76,8 @@ The util method lets you find the node using the id (or using a more complex sel
|
|
76
76
|
Use the utility method, replacing the statement referencing the vdom hierarchy.
|
77
77
|
|
78
78
|
<pre>
|
79
|
-
<s>view.vdom.cn[0].
|
80
|
-
Neo.util.VDom.find(view.vdom, 'title').vdom.
|
79
|
+
<s>view.vdom.cn[0].html = business.title;</s>
|
80
|
+
Neo.util.VDom.find(view.vdom, 'title').vdom.html = business.title;
|
81
81
|
</pre>
|
82
82
|
|
83
83
|
|
@@ -96,7 +96,7 @@ find = Neo.util.VDom.find;
|
|
96
96
|
afterSetBusiness(business){
|
97
97
|
if (!business) return;
|
98
98
|
const view = this.getReference('view');
|
99
|
-
this.find(view.vdom, 'title').vdom.
|
99
|
+
this.find(view.vdom, 'title').vdom.html = business.title;
|
100
100
|
view.update();
|
101
101
|
}
|
102
102
|
</pre>
|
@@ -173,7 +173,7 @@ be a div that shows the address.
|
|
173
173
|
|
174
174
|
Then modify the `afterSetBusiness()` method to update the _address_ element's
|
175
175
|
`cn` to be an array of items, one per item in the address array. Each item should
|
176
|
-
be a _div_ with its `
|
176
|
+
be a _div_ with its `html` set to that part of the address.
|
177
177
|
|
178
178
|
Hint: The business record's `address` property is an array, and the `cn` is
|
179
179
|
also an array. Maybe there's a easy way to map the address array into a new
|
@@ -186,7 +186,7 @@ Here's one way to code it. How does this compare to your solution?
|
|
186
186
|
|
187
187
|
this.find(view.vdom, 'address').vdom.cn = business
|
188
188
|
.address
|
189
|
-
.map(item => ({tag: 'div',
|
189
|
+
.map(item => ({tag: 'div', html: item}));
|
190
190
|
|
191
191
|
??One last point...
|
192
192
|
|
@@ -98,7 +98,7 @@ item in our container. In Neo.mjs terms we're _configuring_ the button. Neo.mjs
|
|
98
98
|
which components and objects are _described_. It's an abstraction. In other words we're saying
|
99
99
|
what we want, but not how it's done. We want a button with some text — how that's done
|
100
100
|
isn't important here in the container. A non-declarative approach would be more focused on _how_,
|
101
|
-
where you might way "I want a <button> HTML element with its
|
101
|
+
where you might way "I want a <button> HTML element with its html set to some value."
|
102
102
|
|
103
103
|
In another topic you'll learn about the Neo.mjs config system and declaratively describing
|
104
104
|
views, controllers, and other things.
|
@@ -63,8 +63,21 @@
|
|
63
63
|
color: #3E63DD;
|
64
64
|
}
|
65
65
|
|
66
|
-
|
67
|
-
|
66
|
+
.lab {
|
67
|
+
box-shadow : 0 4px 8px 0 rgba(0, 0, 0, 0.2);
|
68
|
+
font-size : 1em;
|
69
|
+
margin-bottom: 1em;
|
70
|
+
padding : 2px 16px;
|
71
|
+
transition : 0.3s;
|
72
|
+
|
73
|
+
&:hover {
|
74
|
+
/* On mouse-over, add a deeper shadow */
|
75
|
+
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
li::marker {
|
80
|
+
color: #3E63DD;
|
68
81
|
}
|
69
82
|
|
70
83
|
p {
|
@@ -78,17 +91,8 @@
|
|
78
91
|
padding : 12px;
|
79
92
|
}
|
80
93
|
|
81
|
-
|
82
|
-
|
83
|
-
font-size : 1em;
|
84
|
-
margin-bottom: 1em;
|
85
|
-
padding : 2px 16px;
|
86
|
-
transition : 0.3s;
|
87
|
-
|
88
|
-
&:hover {
|
89
|
-
/* On mouse-over, add a deeper shadow */
|
90
|
-
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
|
91
|
-
}
|
94
|
+
summary::-webkit-details-marker {
|
95
|
+
display: none;
|
92
96
|
}
|
93
97
|
}
|
94
98
|
|
package/src/DefaultConfig.mjs
CHANGED
@@ -246,6 +246,18 @@ const DefaultConfig = {
|
|
246
246
|
* @type Boolean
|
247
247
|
*/
|
248
248
|
useSharedWorkers: false,
|
249
|
+
/**
|
250
|
+
* `true` will let the `vdom.Helper` create a String-based representation of the vnode tree.
|
251
|
+
* Main will then use e.g.`parentNode.insertAdjacentHTML('beforeend', delta.outerHTML);`
|
252
|
+
* This affects the initial painting of your apps, but also the creation of new component trees at run-time.
|
253
|
+
* `false` will skip the creation of the String, and instead use DOM APIs to generate a fragment inside Main,
|
254
|
+
* into which the vnode tree will get applied.
|
255
|
+
* @default false
|
256
|
+
* @memberOf! module:Neo
|
257
|
+
* @name config.useStringBasedMounting
|
258
|
+
* @type Boolean
|
259
|
+
*/
|
260
|
+
useStringBasedMounting: false,
|
249
261
|
/**
|
250
262
|
* True will generate a new task worker, which can get filled with own expensive remote methods
|
251
263
|
* @default false
|
@@ -264,12 +276,12 @@ const DefaultConfig = {
|
|
264
276
|
useVdomWorker: true,
|
265
277
|
/**
|
266
278
|
* buildScripts/injectPackageVersion.mjs will update this value
|
267
|
-
* @default '
|
279
|
+
* @default '10.0.0-alpha.1'
|
268
280
|
* @memberOf! module:Neo
|
269
281
|
* @name config.version
|
270
282
|
* @type String
|
271
283
|
*/
|
272
|
-
version: '
|
284
|
+
version: '10.0.0-alpha.1'
|
273
285
|
};
|
274
286
|
|
275
287
|
Object.assign(DefaultConfig, {
|