neo.mjs 6.18.2 → 6.19.0

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 (108) hide show
  1. package/README.md +28 -214
  2. package/apps/ServiceWorker.mjs +2 -2
  3. package/apps/colors/view/ViewportController.mjs +7 -3
  4. package/apps/portal/data/blog.json +13 -0
  5. package/apps/portal/view/HeaderToolbar.mjs +2 -2
  6. package/apps/portal/view/Viewport.mjs +4 -2
  7. package/apps/portal/view/ViewportController.mjs +89 -8
  8. package/apps/portal/view/blog/Container.mjs +8 -8
  9. package/apps/portal/view/blog/List.mjs +6 -6
  10. package/apps/portal/view/home/MainContainer.mjs +9 -10
  11. package/apps/portal/view/home/parts/BaseContainer.mjs +8 -1
  12. package/apps/portal/view/home/parts/Colors.mjs +4 -4
  13. package/apps/portal/view/home/parts/Helix.mjs +2 -2
  14. package/apps/portal/view/home/parts/How.mjs +3 -3
  15. package/apps/portal/view/home/parts/MainNeo.mjs +6 -7
  16. package/apps/portal/view/home/parts/References.mjs +88 -0
  17. package/apps/portal/view/learn/ContentView.mjs +3 -1
  18. package/apps/portal/view/learn/MainContainer.mjs +3 -2
  19. package/apps/portal/view/learn/MainContainerController.mjs +11 -0
  20. package/apps/portal/view/learn/PageContainer.mjs +5 -3
  21. package/apps/portal/view/services/Component.mjs +73 -0
  22. package/apps/website/data/blog.json +13 -0
  23. package/examples/ServiceWorker.mjs +2 -2
  24. package/examples/component/carousel/MainContainer.mjs +42 -33
  25. package/examples/layout/cube/MainContainer.mjs +217 -0
  26. package/examples/layout/cube/app.mjs +6 -0
  27. package/examples/layout/cube/index.html +11 -0
  28. package/examples/layout/cube/neo-config.json +6 -0
  29. package/package.json +7 -7
  30. package/resources/data/deck/learnneo/pages/2023-10-14T19-25-08-153Z.md +2 -2
  31. package/resources/data/deck/learnneo/pages/ComponentModels.md +6 -6
  32. package/resources/data/deck/learnneo/pages/ComponentsAndContainers.md +10 -10
  33. package/resources/data/deck/learnneo/pages/Config.md +6 -6
  34. package/resources/data/deck/learnneo/pages/CustomComponents.md +4 -4
  35. package/resources/data/deck/learnneo/pages/DescribingTheUI.md +4 -4
  36. package/resources/data/deck/learnneo/pages/Earthquakes-01-goals.md +32 -0
  37. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-01-generate-a-workspace.md +47 -0
  38. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-02-generate-the-starter-app.md +150 -0
  39. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-03-debugging.md +136 -0
  40. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-04-fetch-data.md +146 -0
  41. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-05-refactor-the-table.md +146 -0
  42. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-06-use-a-view-model.md +301 -0
  43. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-07-use-the-google-maps-addon.md +175 -0
  44. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-08-events.md +38 -0
  45. package/resources/data/deck/learnneo/pages/Earthquakes.md +10 -10
  46. package/resources/data/deck/learnneo/pages/Events.md +7 -7
  47. package/resources/data/deck/learnneo/pages/Extending.md +7 -7
  48. package/resources/data/deck/learnneo/pages/Glossary.md +0 -0
  49. package/resources/data/deck/learnneo/pages/GuideEvents.md +97 -19
  50. package/resources/data/deck/learnneo/pages/GuideViewModels.md +21 -21
  51. package/resources/data/deck/learnneo/pages/References.md +8 -8
  52. package/resources/data/deck/learnneo/pages/TestLivePreview.md +5 -4
  53. package/resources/data/deck/learnneo/pages/TodoList.md +9 -9
  54. package/resources/data/deck/learnneo/pages/Welcome.md +3 -3
  55. package/resources/data/deck/learnneo/pages/WhyNeo-Multi-Window.md +2 -2
  56. package/resources/data/deck/learnneo/pages/WhyNeo-Speed.md +2 -2
  57. package/resources/data/deck/learnneo/tree.json +2 -1
  58. package/resources/images/apps/portal/neo-references.png +0 -0
  59. package/resources/scss/src/apps/portal/HeaderToolbar.scss +0 -46
  60. package/resources/scss/src/apps/portal/Viewport.scss +16 -1
  61. package/resources/scss/src/apps/portal/blog/Container.scss +7 -7
  62. package/resources/scss/src/apps/portal/blog/List.scss +20 -16
  63. package/resources/scss/src/apps/portal/home/parts/BaseContainer.scss +33 -4
  64. package/resources/scss/src/apps/portal/home/parts/MainNeo.scss +4 -5
  65. package/resources/scss/src/apps/portal/home/parts/References.scss +46 -0
  66. package/resources/scss/src/apps/portal/learn/ContentTreeList.scss +20 -0
  67. package/resources/scss/src/apps/portal/learn/ContentView.scss +4 -0
  68. package/resources/scss/src/apps/portal/learn/MainContainer.scss +1 -1
  69. package/resources/scss/src/apps/portal/learn/PageContainer.scss +22 -16
  70. package/resources/scss/src/apps/portal/services/Component.scss +20 -0
  71. package/resources/scss/src/{apps/portal/learn → code}/LivePreview.scss +1 -1
  72. package/resources/scss/src/component/Carousel.scss +21 -0
  73. package/resources/scss/src/component/Helix.scss +1 -2
  74. package/resources/scss/src/examples/layout/cube/MainContainer.scss +7 -0
  75. package/resources/scss/src/layout/Cube.scss +80 -0
  76. package/resources/scss/src/tab/Container.scss +10 -10
  77. package/resources/scss/theme-neo-light/apps/portal/blog/Container.scss +3 -0
  78. package/resources/scss/theme-neo-light/form/field/Search.scss +1 -1
  79. package/resources/scss/theme-neo-light/tooltip/Base.scss +1 -1
  80. package/src/DefaultConfig.mjs +2 -2
  81. package/src/Main.mjs +15 -1
  82. package/src/Neo.mjs +14 -3
  83. package/{apps/portal/view/learn → src/code}/LivePreview.mjs +43 -27
  84. package/src/component/Base.mjs +18 -1
  85. package/src/container/Base.mjs +3 -1
  86. package/src/dialog/Base.mjs +1 -2
  87. package/src/layout/Base.mjs +43 -6
  88. package/src/layout/Card.mjs +21 -59
  89. package/src/layout/Cube.mjs +428 -0
  90. package/src/layout/Fit.mjs +9 -38
  91. package/src/layout/Flexbox.mjs +16 -17
  92. package/src/layout/Form.mjs +13 -70
  93. package/src/layout/Grid.mjs +6 -18
  94. package/src/main/addon/ResizeObserver.mjs +18 -2
  95. package/src/main/mixin/DeltaUpdates.mjs +16 -3
  96. package/src/util/Array.mjs +36 -0
  97. package/src/vdom/Helper.mjs +328 -445
  98. package/src/vdom/VNode.mjs +12 -1
  99. package/test/siesta/siesta.js +16 -1
  100. package/test/siesta/tests/VdomCalendar.mjs +2111 -37
  101. package/test/siesta/tests/VdomHelper.mjs +283 -47
  102. package/test/siesta/tests/vdom/Advanced.mjs +367 -0
  103. package/test/siesta/tests/vdom/layout/Cube.mjs +189 -0
  104. package/test/siesta/tests/vdom/table/Container.mjs +133 -0
  105. package/apps/portal/view/home/parts/HelloWorld.mjs +0 -83
  106. package/apps/portal/view/home/preview/PageCodeContainer.mjs +0 -55
  107. package/resources/scss/src/apps/portal/home/preview/PageCodeContainer.scss +0 -115
  108. package/resources/scss/theme-neo-light/apps/portal/learn/ContentTreeList.scss +0 -23
@@ -2,6 +2,39 @@
2
2
  min-height : 100%;
3
3
  scroll-snap-align: center;
4
4
 
5
+ @keyframes appear-left {
6
+ 0% {opacity: 0; transform: translateX(-400%);}
7
+ 90% {opacity: .3;}
8
+ 100% {opacity: 1; transform: translateX(0);}
9
+ }
10
+
11
+ @keyframes appear-right {
12
+ 0% {opacity: 0; transform: translateX(400%);}
13
+ 90% {opacity: .3;}
14
+ 100% {opacity: 1; transform: translateX(0);}
15
+ }
16
+
17
+ &:not(:first-child) {
18
+ &:not(:last-child) {
19
+ animation-timeline : view(block 100% -500%);
20
+ animation-fill-mode : both;
21
+ animation-duration : 1ms; /* Firefox requires this to apply the animation */
22
+ animation-timing-function: linear;
23
+
24
+ &:nth-child(even) {
25
+ animation-name: appear-right;
26
+ }
27
+
28
+ &:nth-child(odd) {
29
+ animation-name: appear-left;
30
+ }
31
+ }
32
+ }
33
+
34
+ .neo-content {
35
+ font-size: min(max(2.3vw, 16px), 30px);
36
+ }
37
+
5
38
  .neo-h1 {
6
39
  font-size : min(max(5.5vw, 30px), 64px);
7
40
  text-align : center;
@@ -17,10 +50,6 @@
17
50
  line-height: 1em;
18
51
  }
19
52
 
20
- .neo-content {
21
- font-size: min(max(2.3vw, 16px), 30px);
22
- }
23
-
24
53
  .page-live-preview {
25
54
  margin: 0;
26
55
  }
@@ -2,13 +2,13 @@
2
2
  padding: 3em;
3
3
 
4
4
  .button-group {
5
- display : flex !important;
6
- flex-direction: row-reverse !important;
7
- gap : 8px !important;
5
+ display : flex;
6
+ flex-direction: row-reverse;
7
+ gap : 8px;
8
8
  }
9
9
 
10
10
  .neo-h1 {
11
- margin-bottom: 1.25em;
11
+ margin: 3rem;
12
12
  }
13
13
 
14
14
  .vector {
@@ -17,7 +17,6 @@
17
17
  background-repeat : no-repeat;
18
18
  background-size : contain;
19
19
  height : 10vW;
20
- margin : 0 0 3rem 0;
21
20
  max-height : 130px;
22
21
  width : 100%;
23
22
  }
@@ -0,0 +1,46 @@
1
+ .portal-references {
2
+ user-select: none;
3
+
4
+ .neo-carousel {
5
+ width: 90%;
6
+ height: 350px;
7
+ margin: 0 auto;
8
+
9
+ .neo-carousel-inner {
10
+ border-radius: 15px;
11
+ border: 1px solid var(--sem-color-fg-neutral-contrast);
12
+ color: var(--sem-color-fg-neutral-contrast);
13
+
14
+
15
+ &:before {
16
+ content: '';
17
+ position: absolute;
18
+ top: 0;
19
+ bottom: 0;
20
+ left: 0;
21
+ width: 90px;
22
+ z-index: 11;
23
+ background: {
24
+ color: var(--toolbar-background-color);
25
+ image: url('../../../../../../../../resources/images/apps/portal/neo-references.png');
26
+ position: center;
27
+ repeat: no-repeat;
28
+ size: 70% auto;
29
+ }
30
+ }
31
+
32
+ .neo-carousel-item {
33
+ padding-left: 110px;
34
+ display: flex;
35
+ flex-direction: column;
36
+ justify-content: space-evenly;
37
+
38
+ .neo-details {
39
+ margin-top: 1em;
40
+ font-weight: 700;
41
+ font-style: italic;
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
@@ -6,6 +6,26 @@
6
6
  background-color: white;
7
7
  padding : 8px 2px 8px 8px;
8
8
 
9
+ &.neo-tree-list {
10
+ .neo-list-container {
11
+ .neo-list-item {
12
+ .neo-list-item-content:before {
13
+ content: unset !important;
14
+ }
15
+
16
+ &.neo-list-folder {
17
+ .neo-list-item-content:before {
18
+ content: unset !important;
19
+ }
20
+
21
+ &.neo-folder-open .neo-list-item-content:before {
22
+ content: unset !important;
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }
28
+
9
29
  .neo-list-container {
10
30
  padding: 3px;
11
31
  }
@@ -18,6 +18,10 @@
18
18
  margin: 0.5em 0 0.7em 0;
19
19
  }
20
20
 
21
+ details {
22
+ margin: 1em 0 1em 0;
23
+ }
24
+
21
25
  details summary {
22
26
  cursor : pointer;
23
27
  transition: margin 300ms ease-out;
@@ -1,4 +1,4 @@
1
- .learnneo-maincontainer {
1
+ .portal-learn-maincontainer {
2
2
  background-color: #f2f2f2;
3
3
 
4
4
  .main-content-splitter {
@@ -1,11 +1,12 @@
1
- .learn-content-container {
1
+ .portal-learn-page-container {
2
2
  overflow: auto;
3
3
 
4
4
  .content-bottom-toolbar {
5
- gap : 8px;
6
- padding : 0 3rem;
7
- margin-bottom: 3rem;
8
- margin-top : 3rem;
5
+ gap : 8px;
6
+ grid-template-columns: repeat(2, 1fr);
7
+ margin-bottom : 3rem;
8
+ margin-top : 3rem;
9
+ padding : 0 3rem;
9
10
 
10
11
  .neo-button {
11
12
  flex : 1 !important;
@@ -18,18 +19,23 @@
18
19
  }
19
20
 
20
21
  .content-bottom-toolbar-previous:before {
21
- content : 'Previous Page';
22
- font-family : var(--core-fontfamily-sans);
23
- position : absolute;
24
- top : var(--cmp-button-spacinghorizontal);
25
- left : var(--cmp-button-spacinghorizontal);
22
+ content : 'Previous Page';
23
+ font-family: var(--core-fontfamily-sans);
24
+ left : var(--cmp-button-spacinghorizontal);
25
+ position : absolute;
26
+ top : var(--cmp-button-spacinghorizontal);
26
27
  }
27
- .content-bottom-toolbar-next:before {
28
- content : 'Next Page';
29
- font-family : var(--core-fontfamily-sans);
30
- position : absolute;
31
- top : var(--cmp-button-spacinghorizontal);
32
- right : var(--cmp-button-spacinghorizontal);
28
+
29
+ .content-bottom-toolbar-next {
30
+ grid-column: 2/3;
31
+
32
+ &:before {
33
+ content : 'Next Page';
34
+ font-family: var(--core-fontfamily-sans);
35
+ position : absolute;
36
+ right : var(--cmp-button-spacinghorizontal);
37
+ top : var(--cmp-button-spacinghorizontal);
38
+ }
33
39
  }
34
40
  }
35
41
  }
@@ -0,0 +1,20 @@
1
+ .portal-services-component {
2
+ background-color: #fff !important;
3
+ padding : 1em 6em;
4
+
5
+ .info-block {
6
+ background-color: lighten(#8BA6FF, 10%);
7
+ border-radius : 10px;
8
+ margin-left : auto;
9
+ margin-right : auto;
10
+ margin-top : 2em;
11
+ max-width : 800px;
12
+ padding : 0.5em 3em 1em 3em;
13
+ }
14
+
15
+ h1 {
16
+ margin-left : auto;
17
+ margin-right: auto;
18
+ width : fit-content;
19
+ }
20
+ }
@@ -1,4 +1,4 @@
1
- .learn-live-preview {
1
+ .neo-code-live-preview {
2
2
  margin-bottom: 2em;
3
3
 
4
4
  .live-preview-container {
@@ -68,9 +68,30 @@
68
68
  height : 9rem;
69
69
  overflow : hidden;
70
70
 
71
+ &:before {
72
+ content: '';
73
+ position: absolute;
74
+ background: linear-gradient(90deg, var(--button-text-color-active) 0%, var(--button-text-color-active) 50%, rgba(0, 0, 0, 0) 100%);
75
+ top: 0;
76
+ bottom: 0;
77
+ left: 0;
78
+ width: 30px;
79
+ z-index: 11;
80
+ }
81
+ &:after {
82
+ content: '';
83
+ position: absolute;
84
+ background: linear-gradient(270deg, var(--button-text-color-active) 0%, var(--button-text-color-active) 50%, rgba(0, 0, 0, 0) 100%);
85
+ top: 0;
86
+ bottom: 0;
87
+ right: 0;
88
+ width: 30px;
89
+ z-index: 11;
90
+ }
71
91
  .neo-carousel-item {
72
92
  height : 9rem;
73
93
  padding: 15px;
94
+ text-align: center;
74
95
  }
75
96
  }
76
97
  }
@@ -4,7 +4,6 @@
4
4
  display : flex;
5
5
  font-family : var(--neo-font-family);
6
6
  margin : 0;
7
- overflow : hidden;
8
7
  padding : 0;
9
8
  perspective : 800px;
10
9
  transform : translateZ(0px);
@@ -65,7 +64,7 @@
65
64
  height : 160px;
66
65
  overflow : hidden;
67
66
  width : 120px;
68
- will-change : transform;
67
+ will-change : auto;
69
68
 
70
69
  &:focus {
71
70
  outline: 0;
@@ -0,0 +1,7 @@
1
+ .examples-layout-cube-maincontainer {
2
+ .neo-face {
3
+ align-items : center;
4
+ display : flex;
5
+ justify-content: center;
6
+ }
7
+ }
@@ -0,0 +1,80 @@
1
+ /*
2
+ * Container Structure:
3
+ * div.neo-layout-cube
4
+ * div.neo-plane
5
+ * div.neo-box
6
+ * div.neo-face.neo-face-z.front
7
+ * div.neo-face.neo-face-z.back
8
+ * div.neo-face.neo-face-x.left
9
+ * div.neo-face.neo-face-x.right
10
+ * div.neo-face.neo-face-y.top
11
+ * div.neo-face.neo-face-y.bottom
12
+ */
13
+ .neo-layout-cube {
14
+ --backface-visibility: visible;
15
+ --perspective : 600px;
16
+
17
+ --rot-x: 0deg;
18
+ --rot-y: 0deg;
19
+ --rot-z: 0deg;
20
+
21
+ --side-x: 300px; /* horizontal */
22
+ --side-y: 300px; /* vertical */
23
+ --side-z: 300px; /* depth */
24
+
25
+ background-color : transparent;
26
+ height : var(--side-y);
27
+ overflow : visible;
28
+ perspective : var(--perspective);
29
+ perspective-origin: center center;
30
+ width : var(--side-x);
31
+
32
+ .neo-plane {
33
+ transform : translateZ(calc(var(--side-z) / -2));
34
+ transform-style: preserve-3d;
35
+ }
36
+
37
+ .neo-box {
38
+ height : var(--side-y);
39
+ position : relative;
40
+ transform : rotateX(var(--rot-x)) rotateY(var(--rot-y)) rotateZ(var(--rot-z));
41
+ transform-style : preserve-3d;
42
+ transform-origin: center center;
43
+ translate : 0 0 calc(var(--side-z) / -2);
44
+ width : var(--side-x);
45
+ }
46
+
47
+ &.neo-animate {
48
+ .neo-box {
49
+ transition: transform 300ms ease-out;
50
+ }
51
+ }
52
+
53
+ .neo-face {
54
+ backface-visibility: var(--backface-visibility);
55
+ background : center/cover no-repeat;
56
+ position : absolute;
57
+
58
+ &.front {transform: rotateY( 0deg) translateZ(calc(var(--side-z) / 2));}
59
+ &.back {transform: rotateY(180deg) translateZ(calc(var(--side-z) / 2));}
60
+ &.left {transform: rotateY(-90deg) translateZ(calc(var(--side-z) / 2));}
61
+ &.right {transform: rotateY( 90deg) translateZ(calc(var(--side-x) - var(--side-z) / 2));}
62
+ &.top {transform: rotateX( 90deg) translateZ(calc(var(--side-z) / 2));}
63
+ &.bottom {transform: rotateX(-90deg) translateZ(calc(var(--side-y) - var(--side-z) / 2));}
64
+ }
65
+
66
+ .neo-face-x {
67
+ height: var(--side-y);
68
+ width : var(--side-z);
69
+ }
70
+
71
+ .neo-face-y {
72
+ height: var(--side-z);
73
+ width : var(--side-x);
74
+ }
75
+
76
+ .neo-face-z {
77
+ height: var(--side-y);
78
+ width : var(--side-x);
79
+ }
80
+ }
@@ -22,18 +22,18 @@
22
22
  border-top: 0;
23
23
  }
24
24
  }
25
- }
26
25
 
27
- .neo-tab-container-plain {
26
+ &.neo-tab-container-plain {
28
27
 
29
- }
28
+ }
30
29
 
31
- .neo-tab-content-container {
32
- border : var(--tab-container-content-border);
33
- overflow: hidden;
34
- }
30
+ .neo-tab-content-container {
31
+ border : var(--tab-container-content-border);
32
+ overflow: hidden;
33
+ }
35
34
 
36
- .neo-tab-header-toolbar {
37
- background-color: transparent;
38
- padding : 0;
35
+ .neo-tab-header-toolbar {
36
+ background-color: transparent;
37
+ padding : 0;
38
+ }
39
39
  }
@@ -0,0 +1,3 @@
1
+ :root .neo-theme-neo-light { // .portal-blog-container
2
+ --portal-blog-toolbar-background-color: #8BA6FF;
3
+ }
@@ -1,3 +1,3 @@
1
1
  :root .neo-theme-neo-light { // .neo-searchfield
2
- --searchfield-glyph-color: #1c60a0;
2
+ --searchfield-glyph-color: #3E63DD;
3
3
  }
@@ -1,6 +1,6 @@
1
1
  :root .neo-theme-neo-light { // .neo-tooltip
2
2
  // --tooltip-bg : var(--cmp-tooltip-bg);
3
- --tooltip-bg : red;
3
+ --tooltip-bg : #3E63DD;
4
4
  --tooltip-border : none;
5
5
  --tooltip-borderradius : var(--cmp-tooltip-borderradius);
6
6
  --tooltip-boxshadow : none;
@@ -260,12 +260,12 @@ const DefaultConfig = {
260
260
  useVdomWorker: true,
261
261
  /**
262
262
  * buildScripts/injectPackageVersion.mjs will update this value
263
- * @default '6.18.2'
263
+ * @default '6.19.0'
264
264
  * @memberOf! module:Neo
265
265
  * @name config.version
266
266
  * @type String
267
267
  */
268
- version: '6.18.2'
268
+ version: '6.19.0'
269
269
  };
270
270
 
271
271
  Object.assign(DefaultConfig, {
package/src/Main.mjs CHANGED
@@ -56,6 +56,7 @@ class Main extends core.Base {
56
56
  'setNeoConfig',
57
57
  'setRoute',
58
58
  'windowClose',
59
+ 'windowCloseAll',
59
60
  'windowMoveTo',
60
61
  'windowOpen',
61
62
  'windowResizeTo'
@@ -471,7 +472,7 @@ class Main extends core.Base {
471
472
  /**
472
473
  * Closes popup windows
473
474
  * @param {Object} data
474
- * @param {Array|String} data.names
475
+ * @param {String|String[]} data.names
475
476
  */
476
477
  windowClose(data) {
477
478
  if (!Array.isArray(data.names)) {
@@ -484,6 +485,19 @@ class Main extends core.Base {
484
485
  })
485
486
  }
486
487
 
488
+ /**
489
+ * Closes all popup windows
490
+ * @param {Object} data
491
+ */
492
+ windowCloseAll(data) {
493
+ Object.values(this.openWindows).forEach(value => {
494
+ console.log(value);
495
+ value.close()
496
+ });
497
+
498
+ this.openWindows = {}
499
+ }
500
+
487
501
  /**
488
502
  * Move a popup window
489
503
  * @param {Object} data
package/src/Neo.mjs CHANGED
@@ -430,7 +430,7 @@ Neo = globalThis.Neo = Object.assign({
430
430
  {ntypeMap} = Neo,
431
431
  proto = cls.prototype || cls,
432
432
  protos = [],
433
- cfg, config, ctor, ntype;
433
+ cfg, config, ctor, ns, ntype;
434
434
 
435
435
  while (proto.__proto__) {
436
436
  ctor = proto.constructor;
@@ -531,8 +531,19 @@ Neo = globalThis.Neo = Object.assign({
531
531
  });
532
532
 
533
533
  if (proto.singleton) {
534
- cls = Neo.create(cls);
535
- Neo.applyToGlobalNs(cls)
534
+ ns = Neo.ns(proto.className);
535
+
536
+ // Only create new singleton instances, in case the namespace is not in use. Using multiple neo versions
537
+ // will cause issues otherwise (e.g. combining dist/production & development). Example: code.LivePreview.
538
+ if (!ns) {
539
+ cls = Neo.create(cls);
540
+ Neo.applyToGlobalNs(cls)
541
+ }
542
+ // If the singleton already exists, just return this version instead.
543
+ // This enables us to still use it with default import statements.
544
+ else {
545
+ return ns
546
+ }
536
547
  }
537
548
 
538
549
  return cls
@@ -1,6 +1,6 @@
1
- import Container from '../../../../src/container/Base.mjs';
2
- import MonacoEditor from '../../../../src/component/wrapper/MonacoEditor.mjs'
3
- import TabContainer from '../../../../src/tab/Container.mjs';
1
+ import Container from '../container/Base.mjs';
2
+ import MonacoEditor from '../component/wrapper/MonacoEditor.mjs'
3
+ import TabContainer from '../tab/Container.mjs';
4
4
 
5
5
  const
6
6
  classDeclarationRegex = /class\s+([a-zA-Z$_][a-zA-Z0-9$_]*)\s*(?:extends\s+[a-zA-Z$_][a-zA-Z0-9$_]*)?\s*{[\s\S]*?}/g,
@@ -8,7 +8,7 @@ const
8
8
  importRegex = /import\s+([\w-]+)\s+from\s+['"]([^'"]+)['"]/;
9
9
 
10
10
  /**
11
- * @class Portal.view.learn.LivePreview
11
+ * @class Neo.code.LivePreview
12
12
  * @extends Neo.container.Base
13
13
  */
14
14
  class LivePreview extends Container {
@@ -22,10 +22,10 @@ class LivePreview extends Container {
22
22
 
23
23
  static config = {
24
24
  /**
25
- * @member {String} className='Portal.view.learn.LivePreview'
25
+ * @member {String} className='Neo.code.LivePreview'
26
26
  * @protected
27
27
  */
28
- className: 'Portal.view.learn.LivePreview',
28
+ className: 'Neo.code.LivePreview',
29
29
  /**
30
30
  * @member {String} ntype='live-preview'
31
31
  * @protected
@@ -36,14 +36,22 @@ class LivePreview extends Container {
36
36
  * @member {String} activeView_='source'
37
37
  */
38
38
  activeView_: 'source',
39
-
40
- baseCls : ['learn-live-preview'],
41
- value_ : null,
42
- autoMount : true,
43
- autoRender : true,
39
+ /**
40
+ * @member {String[]} baseCls=['neo-code-live-preview']
41
+ */
42
+ baseCls: ['neo-code-live-preview'],
43
+ /**
44
+ * @member {Boolean} disableRunSource=false
45
+ */
44
46
  disableRunSource: false,
45
- height : 400,
46
- layout : 'fit',
47
+ /**
48
+ * @member {Number} height=400
49
+ */
50
+ height: 400,
51
+ /**
52
+ * @member {Object|String} layout='fit'
53
+ */
54
+ layout: 'fit',
47
55
  /**
48
56
  * @member {Object[]} items
49
57
  */
@@ -56,27 +64,21 @@ class LivePreview extends Container {
56
64
  items: [{
57
65
  module : MonacoEditor,
58
66
  hideLabel : true,
67
+ listeners : {editorChange: 'up.onEditorChange'},
59
68
  style : {height: '100%'},
60
69
  reference : 'editor',
61
- tabButtonConfig: {
62
- text: 'Source'
63
- },
64
- listeners : {
65
- editorChange: data => {
66
- let container = data.component.up({className: 'Portal.view.learn.LivePreview'});
67
- container.editorValue = data.value;
68
-
69
- if (container.previewContainer) {
70
- container.doRunSource()
71
- }
72
- }
73
- }
70
+ tabButtonConfig: {text: 'Source'}
74
71
  }, {
75
72
  module : Container,
76
73
  reference : 'preview',
77
74
  tabButtonConfig: {text: 'Preview'}
78
75
  }]
79
- }]
76
+ }],
77
+ /**
78
+ * The code to display inside the Monaco editor
79
+ * @member {String|null} value_=null
80
+ */
81
+ value_: null,
80
82
  }
81
83
 
82
84
  /**
@@ -300,6 +302,20 @@ class LivePreview extends Container {
300
302
  me.activeView === 'preview' && me.doRunSource()
301
303
  }
302
304
 
305
+ /**
306
+ * @param {Object} data
307
+ */
308
+ onEditorChange(data) {
309
+ let me = this;
310
+
311
+ me.editorValue = data.value;
312
+
313
+ // We are not using getPreviewContainer(), since we only want to update the LivePreview in case it is visible.
314
+ if (me.previewContainer) {
315
+ me.doRunSource()
316
+ }
317
+ }
318
+
303
319
  /**
304
320
  * @param {Object} data
305
321
  */
@@ -333,6 +333,13 @@ class Base extends CoreBase {
333
333
  * @member {String|null} theme_=null
334
334
  */
335
335
  theme_: null,
336
+ /**
337
+ * While it is recommended to define tags inside the vdom of classes,
338
+ * this shortcut enables us to change the vdom root tag on instance level.
339
+ * Use cases: switch a Toolbar to a "nav" tag, switch a SideNav to an "aside" tag.
340
+ * @member {String|null} tag_=null
341
+ */
342
+ tag_: null,
336
343
  /**
337
344
  * Add tooltip config object or a string containing the display text
338
345
  * See tooltip/Base.mjs
@@ -920,6 +927,16 @@ class Base extends CoreBase {
920
927
  }
921
928
  }
922
929
 
930
+ /**
931
+ * Triggered after the tag config got changed
932
+ * @param {String|null} value
933
+ * @param {String|null} oldValue
934
+ * @protected
935
+ */
936
+ afterSetTag(value, oldValue) {
937
+ value && this.changeVdomRootKey('tag', value)
938
+ }
939
+
923
940
  /**
924
941
  * Triggered after the theme config got changed
925
942
  * @param {String|null} value
@@ -1459,7 +1476,7 @@ class Base extends CoreBase {
1459
1476
  // we can not set the config directly => it could already be false,
1460
1477
  // and we still want to pass it further into subtrees
1461
1478
  me._needsVdomUpdate = false;
1462
- me.afterSetNeedsVdomUpdate?.(false, true)
1479
+ me.afterSetNeedsVdomUpdate?.(false, true);
1463
1480
 
1464
1481
  Neo.vdom.Helper.update(opts).catch(err => {
1465
1482
  me.isVdomUpdating = false;