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.
Files changed (98) hide show
  1. package/ServiceWorker.mjs +2 -2
  2. package/apps/email/view/Viewport.mjs +2 -2
  3. package/apps/form/view/Viewport.mjs +1 -1
  4. package/apps/portal/index.html +1 -1
  5. package/apps/portal/view/examples/List.mjs +1 -1
  6. package/apps/portal/view/home/FooterContainer.mjs +1 -1
  7. package/apps/portal/view/learn/ContentComponent.mjs +5 -5
  8. package/apps/realworld2/view/HomeContainer.mjs +1 -1
  9. package/apps/route/view/center/CardAdministration.mjs +3 -3
  10. package/apps/route/view/center/CardAdministrationDenied.mjs +2 -2
  11. package/apps/route/view/center/CardContact.mjs +2 -2
  12. package/apps/route/view/center/CardHome.mjs +2 -2
  13. package/apps/route/view/center/CardSection1.mjs +2 -2
  14. package/apps/route/view/center/CardSection2.mjs +2 -2
  15. package/buildScripts/createApp.mjs +2 -2
  16. package/docs/app/view/classdetails/HeaderComponent.mjs +3 -3
  17. package/docs/app/view/classdetails/MembersList.mjs +43 -46
  18. package/docs/app/view/classdetails/SourceViewComponent.mjs +1 -1
  19. package/docs/app/view/classdetails/TutorialComponent.mjs +1 -1
  20. package/examples/component/toast/MainContainer.mjs +16 -16
  21. package/examples/component/wrapper/googleMaps/MarkerDialog.mjs +4 -4
  22. package/examples/fields/MainContainer.mjs +1 -1
  23. package/examples/panel/MainContainer.mjs +2 -2
  24. package/examples/tab/container/MainContainer.mjs +3 -3
  25. package/examples/tabs/MainContainer.mjs +2 -2
  26. package/examples/tabs/MainContainer2.mjs +3 -3
  27. package/examples/viewport/MainContainer.mjs +2 -2
  28. package/package.json +3 -3
  29. package/resources/data/deck/learnneo/pages/UsingTheseTopics.md +65 -0
  30. package/resources/data/deck/learnneo/pages/benefits/ConfigSystem.md +1 -1
  31. package/resources/data/deck/learnneo/pages/benefits/FormsEngine.md +7 -7
  32. package/resources/data/deck/learnneo/pages/benefits/FourEnvironments.md +10 -11
  33. package/resources/data/deck/learnneo/pages/benefits/Introduction.md +38 -5
  34. package/resources/data/deck/learnneo/pages/benefits/MultiWindow.md +1 -1
  35. package/resources/data/deck/learnneo/pages/benefits/Speed.md +1 -1
  36. package/resources/data/deck/learnneo/pages/gettingstarted/ComponentModels.md +2 -2
  37. package/resources/data/deck/learnneo/pages/gettingstarted/Config.md +3 -3
  38. package/resources/data/deck/learnneo/pages/gettingstarted/DescribingTheUI.md +2 -2
  39. package/resources/data/deck/learnneo/pages/gettingstarted/Events.md +3 -3
  40. package/resources/data/deck/learnneo/pages/gettingstarted/Extending.md +2 -2
  41. package/resources/data/deck/learnneo/pages/gettingstarted/References.md +3 -3
  42. package/resources/data/deck/learnneo/pages/gettingstarted/Workspaces.md +3 -3
  43. package/resources/data/deck/learnneo/pages/guides/ComponentsAndContainers.md +6 -6
  44. package/resources/data/deck/learnneo/pages/guides/CustomComponents.md +1 -1
  45. package/resources/data/deck/learnneo/pages/guides/MainThreadAddonIntro.md +1 -1
  46. package/resources/data/deck/learnneo/pages/guides/StateProviders.md +6 -6
  47. package/resources/data/deck/learnneo/pages/guides/events/CustomEvents.md +8 -8
  48. package/resources/data/deck/learnneo/pages/guides/events/DomEvents.md +11 -11
  49. package/resources/data/deck/learnneo/pages/javascript/Classes.md +4 -4
  50. package/resources/data/deck/learnneo/pages/javascript/NewNode.md +2 -2
  51. package/resources/data/deck/learnneo/pages/javascript/Overrides.md +4 -4
  52. package/resources/data/deck/learnneo/pages/tutorials/Earthquakes.md +21 -21
  53. package/resources/data/deck/learnneo/pages/tutorials/TodoList.md +2 -2
  54. package/resources/data/deck/learnneo/tree.json +1 -1
  55. package/resources/data/deck/training/pages/2022-12-27T21-55-23-144Z.md +2 -2
  56. package/resources/data/deck/training/pages/2022-12-29T18-36-08-226Z.md +1 -1
  57. package/resources/data/deck/training/pages/2022-12-29T18-36-56-893Z.md +2 -2
  58. package/resources/data/deck/training/pages/2022-12-29T20-37-08-919Z.md +2 -2
  59. package/resources/data/deck/training/pages/2022-12-29T20-37-20-344Z.md +2 -2
  60. package/resources/data/deck/training/pages/2023-01-13T21-48-17-258Z.md +2 -2
  61. package/resources/data/deck/training/pages/2023-02-05T17-44-53-815Z.md +9 -9
  62. package/resources/data/deck/training/pages/2023-10-14T19-25-08-153Z.md +1 -1
  63. package/resources/scss/src/apps/portal/learn/ContentComponent.scss +17 -13
  64. package/src/DefaultConfig.mjs +14 -2
  65. package/src/Main.mjs +14 -5
  66. package/src/button/Base.mjs +1 -1
  67. package/src/calendar/view/calendars/List.mjs +1 -1
  68. package/src/component/Base.mjs +11 -11
  69. package/src/component/Chip.mjs +1 -1
  70. package/src/component/Helix.mjs +3 -3
  71. package/src/component/Process.mjs +2 -2
  72. package/src/component/StatusBadge.mjs +2 -2
  73. package/src/component/Timer.mjs +1 -1
  74. package/src/component/Toast.mjs +2 -2
  75. package/src/container/Base.mjs +1 -1
  76. package/src/form/field/CheckBox.mjs +2 -2
  77. package/src/form/field/FileUpload.mjs +14 -14
  78. package/src/form/field/Range.mjs +1 -1
  79. package/src/form/field/Text.mjs +1 -1
  80. package/src/form/field/trigger/Base.mjs +2 -2
  81. package/src/form/field/trigger/SpinUpDown.mjs +2 -2
  82. package/src/grid/View.mjs +1 -1
  83. package/src/main/DeltaUpdates.mjs +382 -0
  84. package/src/main/DomAccess.mjs +13 -36
  85. package/src/main/render/DomApiRenderer.mjs +138 -0
  86. package/src/main/render/StringBasedRenderer.mjs +58 -0
  87. package/src/table/View.mjs +1 -1
  88. package/src/table/plugin/CellEditing.mjs +1 -1
  89. package/src/tree/Accordion.mjs +11 -11
  90. package/src/tree/List.mjs +12 -5
  91. package/src/vdom/Helper.mjs +174 -292
  92. package/src/vdom/VNode.mjs +47 -11
  93. package/src/vdom/domConstants.mjs +65 -0
  94. package/src/vdom/util/DomApiVnodeCreator.mjs +51 -0
  95. package/src/vdom/util/StringFromVnode.mjs +123 -0
  96. package/src/worker/mixin/RemoteMethodAccess.mjs +13 -1
  97. package/resources/data/deck/learnneo/pages/Welcome.md +0 -64
  98. package/src/main/mixin/DeltaUpdates.mjs +0 -352
@@ -0,0 +1,65 @@
1
+
2
+ ***Welcome to these Neo.mjs guides and learning resources!*** Neo.mjs is a groundbreaking JavaScript framework designed
3
+ to help you build lightning-fast, highly scalable, and exceptionally maintainable web applications. This guide will help
4
+ you understand the structure of these topics and get the most out of our comprehensive content.
5
+
6
+ ## Documentation Sections
7
+
8
+ This documentation is organized into the following main sections, each serving a distinct purpose:
9
+
10
+ * ***Benefits***: Describes the technical and business reasons for choosing Neo.mjs, highlighting its unique advantages.
11
+ * ***Getting Started***: Provides installation instructions, along with fundamental concepts that are good to understand
12
+ before diving deeper into Neo.mjs.
13
+ * ***Tutorials***: Offers hands-on tutorials where you'll code a few simple Neo.mjs applications.
14
+ * ***Guides***: Contains in-depth discussions of various topics related to Neo.mjs concepts and features.
15
+
16
+ ## Navigating These Topics
17
+
18
+ As you can see, the table of contents is on the left. Topic sections and sub-sections are shown on the right, and the
19
+ content is here in the middle. There are "next" and "previous" buttons at the bottom of each page to make it easier to
20
+ read several topics in sequence.
21
+
22
+ ## Special Features
23
+
24
+ You'll find a few special features integrated into our content to enhance your learning experience:
25
+
26
+ ### Disclosure widgets
27
+
28
+ Topics sometimes contain "disclosure" widgets, which are just `<details>` tags. These are used in cases
29
+ where we want to present high-level points and reveal details when the disclosure is expanded.
30
+
31
+ <details>
32
+ <summary>This is a disclosure widget</summary>
33
+ <p style="background-color:lightgreen;padding:8px">This is a fascinating piece of information which is revealed when the widget is expanded.</p>
34
+ </details>
35
+
36
+ ### Runnable examples
37
+
38
+ Topics also sometimes contain runnable examples. These are shown as tab panels with Source and Preview tabs.
39
+
40
+ You can also launch the preview in a window by going to the Preview tab, then clicking on the little window
41
+ icon on the right <span class="far fa-xs fa-window-maximize"></span>. This web site is a Neo.mjs application,
42
+ and the ability to launch browser windows &mdash; all integrated within a single app &mdash; is a unique feature of Neo.mjs!
43
+
44
+ <pre data-code-livepreview>
45
+ import Button from '../button/Base.mjs';
46
+ import Container from '../container/Base.mjs';
47
+
48
+ class MainView extends Container {
49
+ static config = {
50
+ className: 'Example.view.MainView',
51
+ layout : {ntype:'vbox', align:'start'},
52
+ items : [{
53
+ module: Button,
54
+ text : 'Button'
55
+ }]
56
+ }
57
+ }
58
+
59
+ MainView = Neo.setupClass(MainView);
60
+ </pre>
61
+
62
+ ---
63
+
64
+ Your journey into Neo.mjs starts here. The next page will guide you through its core benefits, or if you're ready to get
65
+ hands-on, jump directly to [Getting Started](#/learn/gettingstarted.Setup) to build your first application.
@@ -10,7 +10,7 @@ and nested approach to their configuration, a gap that a class config system aim
10
10
  ## A bad example
11
11
  I recently found this Angular code snippet (new public API draft) on LinkedIn:
12
12
 
13
- <pre data-javascript>
13
+ <pre data-code-readonly>
14
14
  // MyComponent with an attribute
15
15
  <MyComponent myAttribute="someValue" />
16
16
 
@@ -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
- <pre data-neo>
6
+ <pre data-code-livepreview>
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';
@@ -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
- <pre data-neo>
52
+ <pre data-code-livepreview>
53
53
  import Button from '../button/Base.mjs';
54
54
  import Container from '../container/Base.mjs';
55
55
  import FormContainer from '../form/Container.mjs';
@@ -104,7 +104,7 @@ 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
- <pre data-javascript>
107
+ <pre data-code-readonly>
108
108
  {
109
109
  account: 'My Account',
110
110
  product: {brand: 'Tesla', name: 'Car'},
@@ -114,18 +114,18 @@ The main form will log:
114
114
  </pre>
115
115
 
116
116
  The user form will log:
117
- <pre data-javascript>
117
+ <pre data-code-readonly>
118
118
  {user: {firstname: 'John', lastname: null}}
119
119
  'isValid: false'
120
120
  </pre>
121
121
 
122
122
  The product form will log:
123
- <pre data-javascript>
123
+ <pre data-code-readonly>
124
124
  {product: {brand: 'Tesla', name: 'Car'}}
125
125
  'isValid: true'
126
126
  </pre>
127
127
 
128
- <pre data-neo>
128
+ <pre data-code-livepreview>
129
129
  import Button from '../button/Base.mjs';
130
130
  import Container from '../container/Base.mjs';
131
131
  import FormContainer from '../form/Container.mjs';
@@ -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
- <pre data-javascript>
247
+ <pre data-code-readonly>
248
248
  {
249
249
  module: TabContainer,
250
250
  items : [
@@ -1,7 +1,10 @@
1
1
  ## Introduction
2
2
 
3
- Neo.mjs was the very first frontend framework, which enabled full support for a zero builds instant development mode,
4
- while sticking to the latest ECMAScript features (e.g. the ES6 class system, modules and dynamic imports).
3
+ Neo.mjs was the very first frontend framework, which enabled full support for a ***zero builds instant development mode***,
4
+ while sticking to the latest ECMAScript features (e.g., the ES6 class system, modules and dynamic imports).
5
+ This means that your ***primary development workflow*** with Neo.mjs involves creating and debugging your application
6
+ ***entirely within this instant, zero-builds environment***, with builds typically reserved only for ***deployment or
7
+ specific testing scenarios***.
5
8
 
6
9
  Developers can save massive amounts of time when creating and debugging their apps, but at some point apps want to be
7
10
  deployed. To do this right, it is crucial to have an overview of the available environments.
@@ -78,7 +81,7 @@ rendering for dynamic content.
78
81
  Since the code remains in its modular, unbundled form (though optimized compared to dev mode), debugging issues in a
79
82
  live `dist/esm` environment is dramatically simpler. You're working directly with the actual files and module structure.
80
83
 
81
- ### Seamless Shared Worker Integration
84
+ ### Seamless Web Worker Integration
82
85
 
83
86
  The same modular `dist/esm` code is efficiently loaded into both the main thread and the application worker(s), ensuring
84
87
  consistent environments and maximizing the benefits of multi-threading for responsive interfaces.
@@ -122,12 +125,8 @@ The Webpack build pipeline in `dist/production` applies aggressive optimizations
122
125
  * ***Dead Code Elimination*** (Tree Shaking): Removing any code that is not actually used by the application, further
123
126
  reducing bundle size.
124
127
 
125
- ### Broadest Browser Compatibility
126
-
127
- Bundling typically includes polyfills and transpilation for older ECMAScript features, ensuring your application runs
128
- smoothly even on browsers that don't fully support the latest web standards (which dist/esm relies upon).
129
-
130
128
  ### Simplified Single-File Deployment
129
+
131
130
  For environments where serving multiple module files isn't optimal, or for legacy server setups, `dist/production`
132
131
  provides the convenience of deploying just a few highly optimized bundle files.
133
132
 
@@ -185,14 +184,14 @@ it's running in.
185
184
 
186
185
  * ***Zero Builds Development Mode***: Dynamically loaded code-based modules will, naturally, load from the dev mode
187
186
  structure itself, leveraging its instant, direct-from-source capabilities.
188
- * `dist/esm`: When running in the `dist/esm` environment, dynamically loaded code-based modules will be sourced from
187
+ * ***dist/esm***: When running in the `dist/esm` environment, dynamically loaded code-based modules will be sourced from
189
188
  the dist/esm structure. This means your application consistently utilizes native ES Modules for both its core and any
190
189
  dynamically extended functionalities.
191
- * `dist/development`: Surprisingly, when running in the `dist/development` environment (the Webpack-bundled, unminified
190
+ * ***dist/development***: Surprisingly, when running in the `dist/development` environment (the Webpack-bundled, unminified
192
191
  version), dynamically loaded code-based modules will revert to loading from the dev mode structure. This is because
193
192
  dist/development bundles your primary application code, but it doesn't pre-bundle every potential dynamic extension.
194
193
  Relying on the dev mode for these ensures they are unminified and retain debugging fidelity.
195
- * `dist/production`: Similarly, if your core application is deployed in `dist/production` (the fully optimized Webpack
194
+ * ***dist/production***: Similarly, if your core application is deployed in `dist/production` (the fully optimized Webpack
196
195
  bundle), dynamically loaded code-based modules will be sourced from the `dist/esm` structure. This is the optimal fallback,
197
196
  as `dist/esm` provides highly performant, modular, and standards-compliant loading for individual files, which is critical
198
197
  for code that wasn't part of the initial production bundle.
@@ -1,10 +1,43 @@
1
- Why do organizations choose Neo.mjs?
1
+ ## Why Organizations Choose Neo.mjs
2
2
 
3
- - Neo.mjs provides a lightning fast user experience, and is unique in its ability to allow multi-window applications.
3
+ Are your development teams burdened by slow build times, the debugging complexities introduced by transpilation and
4
+ unreliable source maps, or battling UI freezes because ***traditional frameworks (like Angular, React, or Vue) often limit
5
+ your application to a single CPU core?*** Traditional frontend development often comes with these frustrating compromises.
4
6
 
5
- - Neo.mjs applications scale well, from simple to extremely complex
7
+ ***Neo.mjs fundamentally redefines the web development experience, offering a solution that is both revolutionary for
8
+ developers and unmatched in performance.***
6
9
 
7
- - Neo.mjs uses standards-based Javascript, without library-specific addons or special transpilation
10
+ ### Lightning-Fast Development & App-Centric Creation
8
11
 
12
+ Forget the constant interruptions of build processes in your daily workflow. Neo.mjs empowers an instant, zero-builds
13
+ development mode, allowing you to work directly with 100% web standards-based JavaScript. This dramatically accelerates
14
+ your team's velocity and simplifies debugging, letting you focus purely on innovation.
9
15
 
10
- Read on to learn more about Neo.mjs key features and benefits...
16
+ Moreover, Neo.mjs shifts the paradigm: instead of just writing UI components that feel like HTML, you'll ***create entire
17
+ applications***. Thanks to its revolutionary ***Unified Config System***, you define complex application structures—from
18
+ components and layouts to data models—purely through declarative configurations, gaining exceptional control and efficiency.
19
+
20
+ ### Unparalleled Performance & Scalability
21
+
22
+ Neo.mjs is engineered from the ground up for extreme performance. Unlike most frameworks that are limited to a single CPU
23
+ core per browser tab, Neo.mjs leverages a ***truly multi-threaded architecture***. Your application logic runs ***off the
24
+ main thread*** across Web Workers, ensuring your UI remains silky smooth, responsive, and free from freezes,
25
+ even under heavy computation.
26
+
27
+ This unique design enables your applications to scale not just in raw performance, but also in ***complexity and scope,
28
+ growing effortlessly from a tiny proof-of-concept to a massive enterprise application with hundreds of dynamic views.***
29
+ Features like intelligent lazy loading and runtime-built state trees ensure the framework effortlessly manages large-scale
30
+ application growth and intricate multi-window experiences.
31
+
32
+ ### Architectural Brilliance & Future-Proofing
33
+
34
+ Built on cutting-edge web standards, Neo.mjs embraces an "Application Worker being the Main Actor" paradigm.
35
+ This robust architecture inherently prevents common issues like UI blocking, and its isolated thread model significantly
36
+ helps to mitigate memory leaks by containing them within specific worker contexts. Furthermore, Neo.mjs
37
+ uniquely handles ***dynamic, run-time module imports*** without the traditional bundler overhead, offering flexibility
38
+ for advanced scenarios like user-editable code.
39
+
40
+ ---
41
+
42
+ ***Read on to learn more about Neo.mjs's key features and benefits, and how it can transform your web application
43
+ development.***
@@ -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. &mdash; the code doesn't care that some code is running in a
16
16
  separate window.
17
- <pre data-neo>
17
+ <pre data-code-livepreview>
18
18
  import Button from '../button/Base.mjs';
19
19
  import Container from '../container/Base.mjs';
20
20
 
@@ -20,7 +20,7 @@ Click on Preview, then use your mouse or trackpad to pan and zoom &mdash; 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 &mdash; but we've never actually hit the limit.
22
22
 
23
- <pre data-neo>
23
+ <pre data-code-livepreview>
24
24
  import Container from '../container/Base.mjs';
25
25
  import Helix from '../component/Helix.mjs';
26
26
 
@@ -3,7 +3,7 @@ Neo has a feature that allows shared, bindable, data.
3
3
  A _state provider_ &mdash; `Neo.state.Provider` &mdash; instance holds properties that
4
4
  can be bound to component properties.
5
5
 
6
- <pre data-neo>
6
+ <pre data-code-livepreview>
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';
@@ -55,7 +55,7 @@ usually coded as separate classes.)
55
55
 
56
56
  Below is another example.
57
57
 
58
- <pre data-neo>
58
+ <pre data-code-livepreview>
59
59
  import Container from '../container/Base.mjs';
60
60
  import Label from '../component/Label.mjs';
61
61
  import Panel from '../container/Panel.mjs';
@@ -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
- <pre data-neo>
20
+ <pre data-code-livepreview>
21
21
  import Component from '../component/Base.mjs';
22
22
  import Container from '../container/Base.mjs';
23
23
 
@@ -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
- <pre data-neo>
60
+ <pre data-code-livepreview>
61
61
  import Component from '../component/Base.mjs';
62
62
  import Container from '../container/Base.mjs';
63
63
 
@@ -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
- <pre data-neo>
113
+ <pre data-code-livepreview>
114
114
  import Component from '../component/Base.mjs';
115
115
  import Container from '../container/Base.mjs';
116
116
 
@@ -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
- <pre data-neo>
13
+ <pre data-code-livepreview>
14
14
  import Button from '../button/Base.mjs';
15
15
  import Container from '../container/Base.mjs';
16
16
 
@@ -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
- <pre data-neo>
49
+ <pre data-code-livepreview>
50
50
  import Button from '../button/Base.mjs';
51
51
  import Container from '../container/Base.mjs';
52
52
 
@@ -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
- <pre data-neo>
16
+ <pre data-code-livepreview>
17
17
  import Container from '../container/Base.mjs';
18
18
  import TextField from '../form/field/Text.mjs';
19
19
 
@@ -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
- <pre data-neo>
55
+ <pre data-code-livepreview>
56
56
  import Base from '../controller/Component.mjs';
57
57
 
58
58
  class MainViewController extends Base {
@@ -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
- <pre data-neo>
119
+ <pre data-code-livepreview>
120
120
  import Button from '../button/Base.mjs';
121
121
  import Container from '../container/Base.mjs';
122
122
 
@@ -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
- <pre data-neo>
8
+ <pre data-code-livepreview>
9
9
  import Button from '../button/Base.mjs';
10
10
  import Panel from '../container/Panel.mjs';
11
11
  import Table from '../table/Container.mjs';
@@ -48,7 +48,7 @@ If you wanted, any of the configs can be refactored into their own class. Here,
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
- <pre data-neo>
51
+ <pre data-code-livepreview>
52
52
  import Button from '../button/Base.mjs';
53
53
  import Panel from '../container/Panel.mjs';
54
54
  import Store from '../data/Store.mjs';
@@ -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
- <pre data-neo>
13
+ <pre data-code-livepreview>
14
14
  import Button from '../button/Base.mjs';
15
15
  import Container from '../container/Base.mjs';
16
16
  import Controller from '../controller/Component.mjs';
@@ -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
- <pre data-neo>
50
+ <pre data-code-livepreview>
51
51
  import Button from '../button/Base.mjs';
52
52
  import Container from '../container/Base.mjs';
53
53
  import Controller from '../controller/Component.mjs';
@@ -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 &mdash; that use of `Neo.findFirst()` might be handy when debugging, but it should never be used in app logic.
104
104
 
105
- <pre data-neo>
105
+ <pre data-code-livepreview>
106
106
  import Button from '../button/Base.mjs';
107
107
  import Container from '../container/Base.mjs';
108
108
 
@@ -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
- <pre data-javascript>
43
+ <pre data-code-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';
@@ -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
- <pre data-javascript>
81
+ <pre data-code-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';
@@ -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
- <pre data-neo>
123
+ <pre data-code-livepreview>
124
124
  import Button from '../button/Base.mjs';
125
125
  import Container from '../container/Base.mjs';
126
126
 
@@ -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
- <pre data-neo>
28
+ <pre data-code-livepreview>
29
29
  import Container from '../container/Base.mjs';
30
30
 
31
31
  class MainView extends Container {
@@ -47,7 +47,7 @@ MainView = Neo.setupClass(MainView);
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
- <pre data-neo>
50
+ <pre data-code-livepreview>
51
51
  import Container from '../container/Base.mjs';
52
52
 
53
53
  class MainView extends Container {
@@ -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
- <pre data-neo>
80
+ <pre data-code-livepreview>
81
81
  import Container from '../container/Base.mjs';
82
82
 
83
83
  class MainView extends Container {
@@ -98,7 +98,7 @@ MainView = Neo.setupClass(MainView);
98
98
 
99
99
  With `vbox` and `hbox`, items are arranged vertically or horizontally.
100
100
 
101
- <pre data-neo>
101
+ <pre data-code-livepreview>
102
102
  import Button from '../button/Base.mjs';
103
103
  import Container from '../container/Base.mjs';
104
104
 
@@ -125,7 +125,7 @@ MainView = Neo.setupClass(MainView);
125
125
 
126
126
  A card container has multiple child items, one of which is visible.
127
127
 
128
- <pre data-neo>
128
+ <pre data-code-livepreview>
129
129
  import Button from '../button/Base.mjs';
130
130
  import Container from '../container/Base.mjs';
131
131
 
@@ -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
- <pre data-neo>
180
+ <pre data-code-livepreview>
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 {
@@ -9,7 +9,7 @@ Neo.mjs is class-based, which means you're free to extend any component (or any
9
9
 
10
10
  ## Lifecycle config properties
11
11
 
12
- <pre data-neo>
12
+ <pre data-code-livepreview>
13
13
  import Button from '../button/Base.mjs';
14
14
  // In practice this would be some handy reusable component
15
15
  class MySpecialButton extends Button {
@@ -18,7 +18,7 @@ please return a specified `window` property." Neo.mjs
18
18
  lets you do that via `Neo.Main.getByPath()`. For
19
19
  example, the following statement logs the URL query string.
20
20
 
21
- <pre data-javascript>
21
+ <pre data-code-readonly>
22
22
  const search = await Neo.Main.getByPath({path: 'window.location.search'});
23
23
  console.log(search); // Logs the search string
24
24
  </pre>
@@ -10,7 +10,7 @@ Other libraries or frameworks often call state providers "Stores".
10
10
 
11
11
  ## Inline State Providers
12
12
  ### Direct Bindings
13
- <pre data-neo>
13
+ <pre data-code-livepreview>
14
14
  import Button from '../button/Base.mjs';
15
15
  import Container from '../container/Base.mjs';
16
16
  import Label from '../component/Label.mjs';
@@ -58,7 +58,7 @@ We can easily bind 1:1 to specific data props using the following syntax:</br>
58
58
  `bind: {text: data => data.hello}`
59
59
 
60
60
  ### Bindings with multiple data props
61
- <pre data-neo>
61
+ <pre data-code-livepreview>
62
62
  import Button from '../button/Base.mjs';
63
63
  import Container from '../container/Base.mjs';
64
64
  import Label from '../component/Label.mjs';
@@ -128,7 +128,7 @@ data.component equals to the Button instance itself. Since the Button instance d
128
128
  `getStateProvider()` will return the closest stateProvider inside the parent chain.
129
129
 
130
130
  ### Nested Inline State Providers
131
- <pre data-neo>
131
+ <pre data-code-livepreview>
132
132
  import Button from '../button/Base.mjs';
133
133
  import Container from '../container/Base.mjs';
134
134
  import Label from '../component/Label.mjs';
@@ -203,7 +203,7 @@ We can even change data props which live inside different stateProviders at once
203
203
  Hint: Modify the example code (Button handler) to try it out right away!
204
204
 
205
205
  ### Nested Data Properties
206
- <pre data-neo>
206
+ <pre data-code-livepreview>
207
207
  import Button from '../button/Base.mjs';
208
208
  import Container from '../container/Base.mjs';
209
209
  import Label from '../component/Label.mjs';
@@ -262,7 +262,7 @@ Or we can directly pass the object containing the change(s):</br>
262
262
  Hint: This will not override left out nested data props (lastname in this case).
263
263
 
264
264
  ### Dialog connecting to a Container
265
- <pre data-neo>
265
+ <pre data-code-livepreview>
266
266
  import Controller from '../controller/Component.mjs';
267
267
  import Dialog from '../dialog/Base.mjs';
268
268
  import Panel from '../container/Panel.mjs';
@@ -384,7 +384,7 @@ MainView = Neo.setupClass(MainView);
384
384
  When your stateProviders contain many data props or need custom logic, you can easily move them into their own classes.
385
385
 
386
386
  ### Direct Bindings
387
- <pre data-neo>
387
+ <pre data-code-livepreview>
388
388
  import Button from '../button/Base.mjs';
389
389
  import Container from '../container/Base.mjs';
390
390
  import Label from '../component/Label.mjs';
@@ -1,7 +1,7 @@
1
1
  As you read in the <a href="#/learn/Events">Getting Started > Events</a> topic, components, stores, and many other objects fire events.
2
2
 
3
3
 
4
- <pre data-neo>
4
+ <pre data-code-livepreview>
5
5
  import Container from '../container/Base.mjs';
6
6
  import TextField from '../form/field/Text.mjs';
7
7
 
@@ -35,7 +35,7 @@ MainView = Neo.setupClass(MainView);
35
35
  The event listener function can be coded in-line. Normally you want event handlers to be in a view's
36
36
  controller, but for very simple situation it can be convenient to use this syntax.
37
37
 
38
- <pre data-neo>
38
+ <pre data-code-livepreview>
39
39
  import Container from '../container/Base.mjs';
40
40
  import TextField from '../form/field/Text.mjs';
41
41
 
@@ -62,7 +62,7 @@ You can also use the `up.` qualifier to specify a method in the component's pare
62
62
  in-line syntax you saw above, using the `up.` syntax might be convenient for simple classees,
63
63
  or when you simply haven't gotten around to defining a view's controller.
64
64
 
65
- <pre data-neo>
65
+ <pre data-code-livepreview>
66
66
  import Container from '../container/Base.mjs';
67
67
  import TextField from '../form/field/Text.mjs';
68
68
 
@@ -92,7 +92,7 @@ Despite the examples above, the most correct way of setting up event handlers is
92
92
  Any view class can specify a controller &mdash; wWhen the view is created a controller instance is
93
93
  also created.
94
94
 
95
- <pre data-neo>
95
+ <pre data-code-livepreview>
96
96
  import Controller from '../controller/Component.mjs';
97
97
 
98
98
  class MainViewController extends Controller {
@@ -134,7 +134,7 @@ a listener procedurally.
134
134
 
135
135
  Any observable class has an `addListener` method, along with an easier-to-type version called `on`.
136
136
 
137
- <pre data-neo>
137
+ <pre data-code-livepreview>
138
138
  import Controller from '../controller/Component.mjs';
139
139
 
140
140
  class MainViewController extends Controller {
@@ -171,7 +171,7 @@ MainView = Neo.setupClass(MainView);
171
171
 
172
172
  The method specified in `on()` doesn't have to be an arrow function; you can use a controller function.
173
173
 
174
- <pre data-neo>
174
+ <pre data-code-livepreview>
175
175
  import Controller from '../controller/Component.mjs';
176
176
 
177
177
  class MainViewController extends Controller {
@@ -241,7 +241,7 @@ will automatically be reflected in the view model.
241
241
  To contrast syntax, and to illustrate the simplicity of a binding, let's look at two exmaples of updating a component
242
242
  to reflect the value of a text field. THe first example uses events; the second uses bindings.
243
243
 
244
- <pre data-neo>
244
+ <pre data-code-livepreview>
245
245
  import Component from '../component/Base.mjs';
246
246
  import Container from '../container/Base.mjs';
247
247
  import TextField from '../form/field/Text.mjs';
@@ -279,7 +279,7 @@ class MainView extends Container {
279
279
  MainView = Neo.setupClass(MainView);
280
280
  </pre>
281
281
 
282
- <pre data-neo>
282
+ <pre data-code-livepreview>
283
283
  import Component from '../component/Base.mjs';
284
284
  import Container from '../container/Base.mjs';
285
285
  import TextField from '../form/field/Text.mjs';