neo.mjs 6.9.9 → 6.9.11

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 (242) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/apps/learnneo/neo-config.json +5 -1
  3. package/apps/learnneo/store/Content.mjs +1 -1
  4. package/apps/learnneo/view/Viewport.mjs +12 -1
  5. package/apps/learnneo/view/home/ContentTreeList.mjs +53 -34
  6. package/apps/learnneo/view/home/ContentView.mjs +60 -0
  7. package/apps/learnneo/view/home/MainContainer.mjs +36 -9
  8. package/apps/learnneo/view/home/MainContainerController.mjs +57 -18
  9. package/apps/newwebsite/app.mjs +6 -0
  10. package/apps/newwebsite/index.html +10 -0
  11. package/apps/newwebsite/neo-config.json +7 -0
  12. package/apps/newwebsite/view/MainContainer.mjs +59 -0
  13. package/buildScripts/webpack/json/myApps.template.json +1 -0
  14. package/examples/ConfigurationViewport.mjs +12 -9
  15. package/examples/ServiceWorker.mjs +2 -2
  16. package/examples/button/base/neo-config.json +1 -2
  17. package/examples/form/field/textarea/MainContainer.mjs +1 -1
  18. package/package.json +2 -2
  19. package/resources/data/{learnneo → deck/learnneo}/p/2023-10-01T18-29-19-158Z.md +3 -6
  20. package/resources/data/deck/learnneo/p/stylesheet.md +40 -0
  21. package/resources/data/{learnneo → deck/learnneo}/t.json +19 -2
  22. package/resources/data/deck/training/p/2022-12-27T21-54-52-300Z.md +11 -0
  23. package/resources/data/deck/training/p/2022-12-27T21-55-23-144Z.md +43 -0
  24. package/resources/data/deck/training/p/2022-12-27T21-55-30-948Z.md +1 -0
  25. package/resources/data/deck/training/p/2022-12-27T21-55-43-542Z.md +84 -0
  26. package/resources/data/deck/training/p/2022-12-27T22-23-55-083Z.md +1 -0
  27. package/resources/data/deck/training/p/2022-12-27T22-24-07-886Z.md +8 -0
  28. package/resources/data/deck/training/p/2022-12-27T22-24-52-295Z.md +8 -0
  29. package/resources/data/deck/training/p/2022-12-27T22-25-03-853Z.md +5 -0
  30. package/resources/data/deck/training/p/2022-12-27T22-43-58-924Z.md +10 -0
  31. package/resources/data/deck/training/p/2022-12-27T22-44-28-881Z.md +3 -0
  32. package/resources/data/deck/training/p/2022-12-27T22-44-41-791Z.md +4 -0
  33. package/resources/data/deck/training/p/2022-12-27T22-45-21-032Z.md +7 -0
  34. package/resources/data/deck/training/p/2022-12-27T22-49-22-078Z.md +4 -0
  35. package/resources/data/deck/training/p/2022-12-27T22-50-20-626Z.md +4 -0
  36. package/resources/data/deck/training/p/2022-12-28T16-58-47-786Z.md +0 -0
  37. package/resources/data/deck/training/p/2022-12-28T16-58-55-192Z.md +9 -0
  38. package/resources/data/deck/training/p/2022-12-28T17-10-18-058Z.md +15 -0
  39. package/resources/data/deck/training/p/2022-12-28T17-10-42-296Z.md +40 -0
  40. package/resources/data/deck/training/p/2022-12-28T17-11-34-653Z.md +41 -0
  41. package/resources/data/deck/training/p/2022-12-28T17-13-09-994Z.md +0 -0
  42. package/resources/data/deck/training/p/2022-12-28T21-32-14-420Z.md +0 -0
  43. package/resources/data/deck/training/p/2022-12-29T01-43-32-431Z.md +7 -0
  44. package/resources/data/deck/training/p/2022-12-29T15-56-54-485Z.md +7 -0
  45. package/resources/data/deck/training/p/2022-12-29T15-57-11-499Z.md +7 -0
  46. package/resources/data/deck/training/p/2022-12-29T16-00-13-223Z.md +7 -0
  47. package/resources/data/deck/training/p/2022-12-29T18-34-25-826Z.md +4 -0
  48. package/resources/data/deck/training/p/2022-12-29T18-36-08-226Z.md +106 -0
  49. package/resources/data/deck/training/p/2022-12-29T18-36-56-893Z.md +112 -0
  50. package/resources/data/deck/training/p/2022-12-29T19-31-30-507Z.md +31 -0
  51. package/resources/data/deck/training/p/2022-12-29T19-31-55-091Z.md +14 -0
  52. package/resources/data/deck/training/p/2022-12-29T20-03-42-628Z.md +9 -0
  53. package/resources/data/deck/training/p/2022-12-29T20-21-20-669Z.md +7 -0
  54. package/resources/data/deck/training/p/2022-12-29T20-37-08-919Z.md +46 -0
  55. package/resources/data/deck/training/p/2022-12-29T20-37-20-344Z.md +43 -0
  56. package/resources/data/deck/training/p/2022-12-30T19-04-30-990Z.md +8 -0
  57. package/resources/data/deck/training/p/2022-12-31T18-43-56-338Z.md +7 -0
  58. package/resources/data/deck/training/p/2022-12-31T18-51-50-682Z.md +1 -0
  59. package/resources/data/deck/training/p/2022-12-31T18-54-04-176Z.md +4 -0
  60. package/resources/data/deck/training/p/2022-12-31T22-11-55-555Z.md +112 -0
  61. package/resources/data/deck/training/p/2022-12-31T23-00-41-222Z.md +6 -0
  62. package/resources/data/deck/training/p/2022-12-31T23-18-55-655Z.md +69 -0
  63. package/resources/data/deck/training/p/2022-12-31T23-25-40-735Z.md +21 -0
  64. package/resources/data/deck/training/p/2022-12-31T23-25-51-014Z.md +7 -0
  65. package/resources/data/deck/training/p/2023-01-01T17-49-18-429Z.md +3 -0
  66. package/resources/data/deck/training/p/2023-01-01T18-44-07-034Z.md +34 -0
  67. package/resources/data/deck/training/p/2023-01-01T18-47-39-766Z.md +15 -0
  68. package/resources/data/deck/training/p/2023-01-01T19-04-22-830Z.md +4 -0
  69. package/resources/data/deck/training/p/2023-01-01T21-11-58-025Z.md +25 -0
  70. package/resources/data/deck/training/p/2023-01-01T21-12-37-340Z.md +23 -0
  71. package/resources/data/deck/training/p/2023-01-01T21-13-13-880Z.md +8 -0
  72. package/resources/data/deck/training/p/2023-01-01T21-14-45-740Z.md +98 -0
  73. package/resources/data/deck/training/p/2023-01-01T21-18-23-886Z.md +26 -0
  74. package/resources/data/deck/training/p/2023-01-01T21-18-31-316Z.md +19 -0
  75. package/resources/data/deck/training/p/2023-01-01T21-18-42-290Z.md +23 -0
  76. package/resources/data/deck/training/p/2023-01-01T21-19-57-020Z.md +24 -0
  77. package/resources/data/deck/training/p/2023-01-01T21-22-31-184Z.md +13 -0
  78. package/resources/data/deck/training/p/2023-01-01T21-22-38-317Z.md +17 -0
  79. package/resources/data/deck/training/p/2023-01-01T21-22-47-693Z.md +20 -0
  80. package/resources/data/deck/training/p/2023-01-01T21-23-17-716Z.md +39 -0
  81. package/resources/data/deck/training/p/2023-01-01T21-23-28-532Z.md +22 -0
  82. package/resources/data/deck/training/p/2023-01-01T21-25-23-899Z.md +3 -0
  83. package/resources/data/deck/training/p/2023-01-01T21-25-59-742Z.md +1 -0
  84. package/resources/data/deck/training/p/2023-01-01T21-26-53-748Z.md +12 -0
  85. package/resources/data/deck/training/p/2023-01-01T23-38-42-863Z.md +2 -0
  86. package/resources/data/deck/training/p/2023-01-03T02-07-19-014Z.md +143 -0
  87. package/resources/data/deck/training/p/2023-01-04T01-52-23-454Z.md +76 -0
  88. package/resources/data/deck/training/p/2023-01-06T23-21-12-009Z.md +127 -0
  89. package/resources/data/deck/training/p/2023-01-06T23-21-31-685Z.md +81 -0
  90. package/resources/data/deck/training/p/2023-01-06T23-21-59-596Z.md +36 -0
  91. package/resources/data/deck/training/p/2023-01-06T23-34-13-897Z.md +87 -0
  92. package/resources/data/deck/training/p/2023-01-06T23-44-02-340Z.md +0 -0
  93. package/resources/data/deck/training/p/2023-01-06T23-46-36-687Z.md +1 -0
  94. package/resources/data/deck/training/p/2023-01-06T23-46-45-783Z.md +33 -0
  95. package/resources/data/deck/training/p/2023-01-08T00-45-11-144Z.md +50 -0
  96. package/resources/data/deck/training/p/2023-01-08T01-06-31-267Z.md +41 -0
  97. package/resources/data/deck/training/p/2023-01-08T01-24-21-088Z.md +95 -0
  98. package/resources/data/deck/training/p/2023-01-08T01-25-12-557Z.md +11 -0
  99. package/resources/data/deck/training/p/2023-01-08T01-46-50-723Z.md +25 -0
  100. package/resources/data/deck/training/p/2023-01-08T02-09-07-802Z.md +18 -0
  101. package/resources/data/deck/training/p/2023-01-08T02-09-19-678Z.md +66 -0
  102. package/resources/data/deck/training/p/2023-01-08T02-11-26-333Z.md +29 -0
  103. package/resources/data/deck/training/p/2023-01-08T17-22-48-841Z.md +14 -0
  104. package/resources/data/deck/training/p/2023-01-08T20-46-11-806Z.md +5 -0
  105. package/resources/data/deck/training/p/2023-01-08T20-47-23-682Z.md +5 -0
  106. package/resources/data/deck/training/p/2023-01-08T20-47-32-064Z.md +13 -0
  107. package/resources/data/deck/training/p/2023-01-08T20-47-57-045Z.md +0 -0
  108. package/resources/data/deck/training/p/2023-01-08T20-48-03-791Z.md +18 -0
  109. package/resources/data/deck/training/p/2023-01-08T20-48-32-466Z.md +9 -0
  110. package/resources/data/deck/training/p/2023-01-08T20-48-51-322Z.md +20 -0
  111. package/resources/data/deck/training/p/2023-01-08T20-49-52-741Z.md +0 -0
  112. package/resources/data/deck/training/p/2023-01-08T20-52-03-556Z.md +0 -0
  113. package/resources/data/deck/training/p/2023-01-08T20-57-36-333Z.md +2 -0
  114. package/resources/data/deck/training/p/2023-01-08T20-57-51-136Z.md +5 -0
  115. package/resources/data/deck/training/p/2023-01-09T00-07-37-951Z.md +0 -0
  116. package/resources/data/deck/training/p/2023-01-09T00-35-40-671Z.md +3 -0
  117. package/resources/data/deck/training/p/2023-01-10T01-29-38-148Z.md +10 -0
  118. package/resources/data/deck/training/p/2023-01-10T01-43-12-166Z.md +31 -0
  119. package/resources/data/deck/training/p/2023-01-10T02-21-54-303Z.md +10 -0
  120. package/resources/data/deck/training/p/2023-01-12T01-50-54-617Z.md +74 -0
  121. package/resources/data/deck/training/p/2023-01-13T19-55-24-735Z.md +14 -0
  122. package/resources/data/deck/training/p/2023-01-13T20-08-27-068Z.md +28 -0
  123. package/resources/data/deck/training/p/2023-01-13T20-23-38-411Z.md +25 -0
  124. package/resources/data/deck/training/p/2023-01-13T20-37-06-267Z.md +13 -0
  125. package/resources/data/deck/training/p/2023-01-13T21-05-57-708Z.md +8 -0
  126. package/resources/data/deck/training/p/2023-01-13T21-48-17-258Z.md +20 -0
  127. package/resources/data/deck/training/p/2023-01-13T22-05-05-799Z.md +14 -0
  128. package/resources/data/deck/training/p/2023-01-13T22-08-30-863Z.md +17 -0
  129. package/resources/data/deck/training/p/2023-01-13T23-01-50-449Z.md +4 -0
  130. package/resources/data/deck/training/p/2023-01-14T00-33-05-958Z.md +62 -0
  131. package/resources/data/deck/training/p/2023-01-14T00-40-27-784Z.md +229 -0
  132. package/resources/data/deck/training/p/2023-01-14T00-41-59-081Z.md +153 -0
  133. package/resources/data/deck/training/p/2023-01-14T13-50-28-199Z.md +19 -0
  134. package/resources/data/deck/training/p/2023-01-14T13-59-20-275Z.md +6 -0
  135. package/resources/data/deck/training/p/2023-01-14T14-03-29-456Z.md +3 -0
  136. package/resources/data/deck/training/p/2023-01-14T14-27-57-678Z.md +7 -0
  137. package/resources/data/deck/training/p/2023-01-14T17-30-18-228Z.md +33 -0
  138. package/resources/data/deck/training/p/2023-01-14T18-28-39-316Z.md +1 -0
  139. package/resources/data/deck/training/p/2023-01-14T18-28-44-115Z.md +4 -0
  140. package/resources/data/deck/training/p/2023-01-14T18-28-49-548Z.md +18 -0
  141. package/resources/data/deck/training/p/2023-01-14T18-40-13-758Z.md +10 -0
  142. package/resources/data/deck/training/p/2023-01-14T19-29-15-291Z.md +12 -0
  143. package/resources/data/deck/training/p/2023-01-15T18-51-52-134Z.md +83 -0
  144. package/resources/data/deck/training/p/2023-01-15T20-03-30-073Z.md +11 -0
  145. package/resources/data/deck/training/p/2023-01-15T22-07-52-073Z.md +16 -0
  146. package/resources/data/deck/training/p/2023-01-15T22-22-13-517Z.md +12 -0
  147. package/resources/data/deck/training/p/2023-01-15T22-28-57-508Z.md +131 -0
  148. package/resources/data/deck/training/p/2023-01-15T22-36-30-913Z.md +115 -0
  149. package/resources/data/deck/training/p/2023-01-16T16-03-40-770Z.md +12 -0
  150. package/resources/data/deck/training/p/2023-01-16T20-21-56-859Z.md +5 -0
  151. package/resources/data/deck/training/p/2023-01-16T20-24-09-690Z.md +24 -0
  152. package/resources/data/deck/training/p/2023-01-20T12-51-22-646Z.md +21 -0
  153. package/resources/data/deck/training/p/2023-01-20T13-06-46-614Z.md +9 -0
  154. package/resources/data/deck/training/p/2023-01-20T13-08-51-600Z.md +7 -0
  155. package/resources/data/deck/training/p/2023-01-20T15-20-13-363Z.md +26 -0
  156. package/resources/data/deck/training/p/2023-01-20T15-34-58-813Z.md +75 -0
  157. package/resources/data/deck/training/p/2023-01-21T16-33-20-458Z.md +33 -0
  158. package/resources/data/deck/training/p/2023-01-21T16-45-28-263Z.md +28 -0
  159. package/resources/data/deck/training/p/2023-01-21T16-56-25-452Z.md +3 -0
  160. package/resources/data/deck/training/p/2023-01-21T17-28-31-493Z.md +6 -0
  161. package/resources/data/deck/training/p/2023-01-21T19-49-51-918Z.md +13 -0
  162. package/resources/data/deck/training/p/2023-01-21T20-08-24-452Z.md +15 -0
  163. package/resources/data/deck/training/p/2023-01-21T20-35-54-947Z.md +20 -0
  164. package/resources/data/deck/training/p/2023-01-21T20-54-47-603Z.md +39 -0
  165. package/resources/data/deck/training/p/2023-01-21T20-56-28-184Z.md +25 -0
  166. package/resources/data/deck/training/p/2023-01-21T20-57-32-927Z.md +4 -0
  167. package/resources/data/deck/training/p/2023-01-21T23-13-33-394Z.md +6 -0
  168. package/resources/data/deck/training/p/2023-01-28T19-11-37-464Z.md +24 -0
  169. package/resources/data/deck/training/p/2023-01-28T20-43-41-188Z.md +9 -0
  170. package/resources/data/deck/training/p/2023-01-28T20-53-56-476Z.md +8 -0
  171. package/resources/data/deck/training/p/2023-01-28T20-58-43-776Z.md +10 -0
  172. package/resources/data/deck/training/p/2023-01-28T22-18-41-259Z.md +33 -0
  173. package/resources/data/deck/training/p/2023-01-28T22-24-34-808Z.md +24 -0
  174. package/resources/data/deck/training/p/2023-01-29T16-25-24-528Z.md +44 -0
  175. package/resources/data/deck/training/p/2023-01-29T21-14-32-588Z.md +12 -0
  176. package/resources/data/deck/training/p/2023-01-31T19-24-53-504Z.md +8 -0
  177. package/resources/data/deck/training/p/2023-01-31T20-33-55-855Z.md +11 -0
  178. package/resources/data/deck/training/p/2023-01-31T20-34-30-261Z.md +7 -0
  179. package/resources/data/deck/training/p/2023-01-31T20-52-53-367Z.md +43 -0
  180. package/resources/data/deck/training/p/2023-02-04T15-18-35-682Z.md +20 -0
  181. package/resources/data/deck/training/p/2023-02-04T15-49-47-597Z.md +14 -0
  182. package/resources/data/deck/training/p/2023-02-04T18-58-57-808Z.md +1 -0
  183. package/resources/data/deck/training/p/2023-02-04T20-07-11-288Z.md +1 -0
  184. package/resources/data/deck/training/p/2023-02-04T20-09-50-169Z.md +1 -0
  185. package/resources/data/deck/training/p/2023-02-04T20-19-42-740Z.md +8 -0
  186. package/resources/data/deck/training/p/2023-02-04T20-23-56-013Z.md +12 -0
  187. package/resources/data/deck/training/p/2023-02-04T20-28-12-391Z.md +20 -0
  188. package/resources/data/deck/training/p/2023-02-05T00-20-32-554Z.md +16 -0
  189. package/resources/data/deck/training/p/2023-02-05T00-35-56-282Z.md +13 -0
  190. package/resources/data/deck/training/p/2023-02-05T15-36-57-182Z.md +24 -0
  191. package/resources/data/deck/training/p/2023-02-05T17-39-51-712Z.md +70 -0
  192. package/resources/data/deck/training/p/2023-02-05T17-44-53-815Z.md +195 -0
  193. package/resources/data/deck/training/p/2023-02-05T17-45-40-114Z.md +92 -0
  194. package/resources/data/deck/training/p/2023-02-05T18-12-14-489Z.md +60 -0
  195. package/resources/data/deck/training/p/2023-02-06T00-14-54-457Z.md +9 -0
  196. package/resources/data/deck/training/p/2023-06-28T18-03-14-313Z.md +8 -0
  197. package/resources/data/deck/training/p/2023-06-28T18-26-17-290Z.md +7 -0
  198. package/resources/data/deck/training/p/2023-06-28T21-16-24-034Z.md +40 -0
  199. package/resources/data/deck/training/p/2023-06-28T21-16-34-972Z.md +16 -0
  200. package/resources/data/deck/training/p/2023-06-28T21-28-28-379Z.md +4 -0
  201. package/resources/data/deck/training/p/2023-06-29T23-15-10-411Z.md +5 -0
  202. package/resources/data/deck/training/p/2023-07-01T15-42-45-193Z.md +433 -0
  203. package/resources/data/deck/training/p/2023-07-01T21-54-31-329Z.md +6 -0
  204. package/resources/data/deck/training/p/2023-07-02T16-14-06-970Z.md +14 -0
  205. package/resources/data/deck/training/p/2023-07-31T00-26-03-842Z.md +4 -0
  206. package/resources/data/deck/training/p/2023-07-31T00-31-51-933Z.md +10 -0
  207. package/resources/data/deck/training/p/2023-07-31T00-37-21-927Z.md +205 -0
  208. package/resources/data/deck/training/p/2023-10-01T18-29-19-158Z.md +76 -0
  209. package/resources/data/deck/training/p/2023-10-07T19-18-28-517Z.md +102 -0
  210. package/resources/data/deck/training/p/2023-10-08T20-20-07-934Z.md +75 -0
  211. package/resources/data/deck/training/p/2023-10-08T20-20-37-336Z.md +29 -0
  212. package/resources/data/deck/training/p/2023-10-08T20-37-30-658Z.md +0 -0
  213. package/resources/data/deck/training/p/2023-10-08T21-58-25-809Z.md +68 -0
  214. package/resources/data/deck/training/p/2023-10-08T22-22-11-013Z.md +0 -0
  215. package/resources/data/deck/training/p/2023-10-14T19-25-08-153Z.md +119 -0
  216. package/resources/data/deck/training/t.json +1 -0
  217. package/resources/scss/src/apps/learnneo/Viewport.scss +0 -106
  218. package/resources/scss/src/apps/learnneo/home/ContentTreeList.scss +37 -0
  219. package/resources/scss/src/apps/learnneo/home/ContentView.scss +55 -0
  220. package/resources/scss/src/form/field/FileUpload.scss +4 -4
  221. package/resources/scss/src/form/field/TextArea.scss +1 -1
  222. package/resources/scss/theme-neo-light/Global.scss +46 -0
  223. package/resources/scss/theme-neo-light/design-tokens/Core.scss +7 -0
  224. package/resources/scss/theme-neo-light/design-tokens/Semantic.scss +0 -0
  225. package/resources/scss/theme-neo-light/design-tokens/_all.scss +4 -0
  226. package/src/DefaultConfig.mjs +4 -4
  227. package/src/form/field/FileUpload.mjs +9 -2
  228. package/src/form/field/TextArea.mjs +19 -34
  229. package/src/main/DomAccess.mjs +34 -0
  230. package/test/components/files/form/field/Select.mjs +1 -1
  231. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-07T19-18-28-517Z.md +0 -0
  232. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T20-20-07-934Z.md +0 -0
  233. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T20-20-37-336Z.md +0 -0
  234. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T20-37-30-658Z.md +0 -0
  235. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T21-58-25-809Z.md +0 -0
  236. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T22-22-11-013Z.md +0 -0
  237. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-14T19-25-08-153Z.md +0 -0
  238. /package/resources/data/{learnneo → deck/learnneo}/pages/whyneo.md +0 -0
  239. /package/resources/data/{learnneo → deck/learnneo}/tree.json +0 -0
  240. /package/resources/{deck → data/deck}/whyneo.md +0 -0
  241. /package/resources/scss/src/apps/newwebsite/{MainContainer.css → MainContainer.scss} +0 -0
  242. /package/resources/scss/theme-neo-light/design-tokens/{Components.scss → Component.scss} +0 -0
@@ -0,0 +1,19 @@
1
+ The component base class introduces many important properties.
2
+
3
+ - `html:string` — for simple content or placeholder text
4
+
5
+
6
+ - `height`, `minHeight`, `maxHeight`
7
+ - `width`, `minWidth`, `maxWidth`
8
+
9
+ - `style:{}` — sometimes convenient, although using css styles via `cls` is probably better
10
+ - `cls:[string]` — a array of CSS class strings
11
+
12
+ - `disabled:boolean`
13
+
14
+ - `_vdom` — for low-level content
15
+
16
+
17
+ - `mounted:boolean` — useful for `afterSetMounted`
18
+
19
+ There are also drag-and-drop hooks, and many other properties.
@@ -0,0 +1,6 @@
1
+ Component also introduces a few events:
2
+
3
+ - `focusEnter`
4
+ - `focusChange`
5
+ - `focusLeave`
6
+ - `focusMove`
@@ -0,0 +1,3 @@
1
+ - `up(config)` — Finds a parent container using `Neo.find()` syntax
2
+
3
+ - `addCls(str)`, `removeCls(str)`, `toggleCls(str)`
@@ -0,0 +1,7 @@
1
+ You've seen that get/set properties (using the underscore suffix)
2
+ have `afterSet...` methods.
3
+
4
+ Recall that `Neo.component.Base` introduces some key properties.
5
+ Since these properties have `afterSet` methods, you can easily
6
+ "detect" when those properties change by overriding the corresponding `afterSet`
7
+ method.
@@ -0,0 +1,33 @@
1
+ To conditionally call the ancestor for `afterSet...` methods.<small><sup>*</sup></small>
2
+ use the _optional chaining_ operator.
3
+
4
+ super.afterSetBar?.(value, oldValue);
5
+
6
+ <pre class="runnable readonly text 280">
7
+ class Simple extends Base {
8
+ static getConfig() {
9
+ return {
10
+ className: 'ComponentBasics.view.component.Simple',
11
+
12
+ bar_: null, // A get/set field
13
+
14
+ }
15
+ }
16
+ afterSetBar(value, oldValue) {
17
+ // Do important processing here.
18
+ }
19
+ }
20
+ </pre>
21
+
22
+ <pre class="runnable readonly text 140">
23
+ class ExtendsSimple extends Simple {
24
+ afterSetBar(value, oldValue) {
25
+ super.afterSetBar?.(value, oldValue);
26
+ // Do important processing here.
27
+ }
28
+ }
29
+ </pre>
30
+ <br>
31
+ <small>* The framework doesn't actually create the `beforeSet...`,
32
+ `afterSet...`, and `beforeGet...` methods. Instead, the framework
33
+ conditionally calls the methods using the chaining operator.</small>
@@ -0,0 +1 @@
1
+ Used when the container has one item &mdash; the item fills the entire container.
@@ -0,0 +1,4 @@
1
+ Multiple child items, with one visible. The visible item
2
+ fills the container.
3
+
4
+ To change the visible item assign a value to `this.layout.activeIndex`
@@ -0,0 +1,18 @@
1
+ layout:{
2
+ ntype: 'vbox',
3
+ pack: 'start', // 'start', 'center', 'end', null
4
+ align: 'start', // 'start', 'center', 'end', 'stretch', null
5
+ }
6
+
7
+ The _pack_ config species how items are packed on the major
8
+ axis.
9
+ - _start_ &mdash; items at the top
10
+ - _center_ &mdash; items at the top-to-bottom middle
11
+ - _end_ &mdash; items at the end
12
+
13
+ The _align_ config specifies how items are justified on the minor
14
+ axis.
15
+ - _start_ &mdash; items are left justified
16
+ - _center_ &mdash; items ae center justified
17
+ - _end_ &mdash; items are right justified
18
+ - _stretch_ &mdash; items take up the full width
@@ -0,0 +1,10 @@
1
+ Uses CSS flexbox.
2
+
3
+ style: {
4
+ overflow: 'scroll', // For the container
5
+ alignContent: 'flex-start', // For the flexbox
6
+ },
7
+ layout: {
8
+ ntype: 'flexbox',
9
+ wrap: 'wrap', // nowrap, wrap, wrapreverse
10
+ },
@@ -0,0 +1,12 @@
1
+ The `style` config takes an object, with the names
2
+ being a camel-case version of the style you're specifying.
3
+
4
+ style: {
5
+ backgroundColor: 'red',
6
+ fontSize: '2em',
7
+ },
8
+
9
+
10
+ The kinds of things you'd use style for should be done as CSS classes,
11
+ but using `style:{}` might be handy until you get around to coding
12
+ the CSS.
@@ -0,0 +1,83 @@
1
+ #Introduction
2
+
3
+ In this lab you'll add `city` and `category` properties.
4
+
5
+ #Steps
6
+
7
+ ??Define a city_ property
8
+
9
+ Add a `city_:''` config.
10
+
11
+ As you know, this creates a get/set property.
12
+
13
+ Save your changes, then in the Chrome debugger's app-worker context
14
+ get a reference to the filter component and confirm that the property
15
+ exists.
16
+
17
+ Is the property there? This statement should evaluate to '' (and not undefined).
18
+
19
+ Neo.findFirst({ntype:'yelp-filter'}).city
20
+
21
+ Assign a value.
22
+
23
+ Neo.findFirst({ntype:'yelp-filter'}).city = 'Madison'
24
+
25
+ Read the value. This should evaluate the city you assigned above.
26
+
27
+ Neo.findFirst({ntype:'yelp-filter'}).city
28
+
29
+ None of this is very surprising yet. The `city` property would behave
30
+ the same whether it was a simple property or a get/set property.
31
+
32
+
33
+ ??Detect when `city` changes
34
+
35
+ We need a function to be run when the city property changes. Later,
36
+ we'll use that function to update the text field.
37
+
38
+ How do you detect a change to a get/set property? Via its `afterSet...`
39
+ method!
40
+
41
+ Add that method, with a single statement that logs the passed value.
42
+
43
+ <pre class="runnable readonly text 320">
44
+ import Base from '../../../../node_modules/neo.mjs/src/container/Base.mjs';
45
+ import TextField from '../../../../node_modules/neo.mjs/src/form/field/Text.mjs';
46
+ class Filter extends Base {
47
+ static config = {
48
+ ...
49
+ }
50
+
51
+ afterSetCity(city) {
52
+ console.log(city);
53
+ }
54
+ }
55
+
56
+ Neo.applyClassConfig(Filter);
57
+
58
+ export default Filter;
59
+ </pre>
60
+
61
+ ??Test the filter on the command line
62
+
63
+ Use the debugger's console (in the app worker context) and verify that
64
+ you see the value logged. In other words, runing the following should result
65
+ in `afterSetCity()` being run.
66
+
67
+ Neo.findFirst({ntype:'yelp-filter'}).city = 'Madison'
68
+
69
+
70
+ ??Add a `category` get/set
71
+
72
+ Now add a `category_:'',` config, and a corresponding `afterSetCategory()`
73
+ method. The code will be almost identical to what you did for city.
74
+
75
+ Test your code by setting and getting `category` on the command line.
76
+
77
+ Neo.findFirst({ntype:'yelp-filter'}).category
78
+
79
+ Neo.findFirst({ntype:'yelp-filter'}).category = 'pizza'
80
+
81
+ Neo.findFirst({ntype:'yelp-filter'}).category
82
+
83
+ You should see the value updating and the value being logged.
@@ -0,0 +1,11 @@
1
+ `Neo.component.Base` also has a `reference` config.
2
+
3
+ If you code a component with `reference:'foo',`, then you can get
4
+ a reference from the view or controller via `this.getReference('foo')`.
5
+
6
+ This is similar to using the Neo find methods, but references are
7
+ resolved in a more efficient manner and the scope is limited to
8
+ what the view can "see".
9
+
10
+ <span style="color:lightgray">(Controllers keep a map of references, keyed by the reference name. The <code style="color:lightgray">getReference()</code> method
11
+ uses bracket notiation to retrieve the value from the map &mdash; it's lighting fast.)</span>
@@ -0,0 +1,16 @@
1
+ Those labs were lengthy because we worked _very_ slowly and methodically.
2
+
3
+ On a project, encapsulating code like this isn't usually needed. You code
4
+ views that show data, and you nest those in containers.
5
+
6
+ But if you need a propertly encapsulated class you'll do something like you
7
+ did with the `Yelp.view.businesses.Filter`.
8
+
9
+ But there isn't much code in there!
10
+
11
+ - It has a property
12
+ - Updates to the properties are reflected in the view
13
+ - Updates to the view are reflected in the properies
14
+
15
+ After you code a couple of such classes it becomes a matter of minutes
16
+ to code them.
@@ -0,0 +1,12 @@
1
+ The following four labs are elaborate.
2
+
3
+ They give you
4
+ practice with a common coding task: creating a de-coupled
5
+ class with a well-defined API.
6
+
7
+ Neo has features that makes this easy. Later we'll cover
8
+ additional techniques for having a de-coupled class interact
9
+ with the rest of an application via events and bindings.
10
+
11
+ The labs feature common coding use-cases. Take your time &mdash;
12
+ make sure everything makes sense!
@@ -0,0 +1,131 @@
1
+ #Introduction
2
+
3
+ In this lab you'll udpate the text fields as the properties change.
4
+
5
+ #Steps
6
+
7
+ ??Add `reference` to the fields
8
+
9
+ First, add a `reference:'city',` to the city field config
10
+ and `reference:'category',` to the category field.
11
+
12
+ As you recall from lecture, `reference` is used in component
13
+ or controller methods to get a reference to the field via
14
+ `this.getReference()`.
15
+
16
+ ??Update the city field
17
+ You already have an `afterSetCity()` method.
18
+
19
+ Modify it to udpdate the city.
20
+
21
+ this.getReference('city').value = city;
22
+
23
+ If you save and run the code you get a runtime error!
24
+ That happens because when the value is first applied (to assign
25
+ the initial defined in `city_:'',`) the view hasn't
26
+ been rendered yet! `Neo.component.Base` has a `rendered` property.
27
+ We need a statement to test that. Add this statement before
28
+ you assign the city to the field.
29
+
30
+ if (!this.rendered) return;
31
+
32
+ <pre style="border: thin solid gray; padding: 8px; color: lightgray; font-size:14pt;">
33
+ import Base from '../../../../node_modules/neo.mjs/src/container/Base.mjs';
34
+ import TextField from '../../../../node_modules/neo.mjs/src/form/field/Text.mjs';
35
+ import Function from '../../util/Function.mjs';
36
+ class Filter extends Base {
37
+ static config = {
38
+ className: 'Yelp.view.businesses.Filter',
39
+ ntype: 'yelp-filter',
40
+
41
+ city_: '',
42
+ category_: '',
43
+
44
+ layout: { ntype: 'hbox' },
45
+ itemDefaults: {module: TextField, clearable: true,},
46
+ items: [
47
+ ...
48
+ ]
49
+ }
50
+ afterSetCity(city) {
51
+ console.log(city);
52
+ <span style="color:#b91010;">if (!this.rendered) return;
53
+ this.getReference('city').value = city;</span>
54
+ }
55
+ afterSetCategory(category) {
56
+ console.log(category);
57
+ }
58
+ }
59
+
60
+ Neo.applyClassConfig(Filter);
61
+
62
+ export default Filter;
63
+ </pre>
64
+
65
+ ??Test the code
66
+
67
+ In the Chrome debugger update the city property. You should see the
68
+ text field update to reflect the change.
69
+
70
+ Neo.findFirst({ntype:'yelp-filter'}).city = 'Madison'
71
+
72
+ ??Add the same logic for category
73
+
74
+ Modify the `afterSetCategory()` method to work like the after city method.
75
+
76
+ Test it in the Chrome debugger. You should see the category text field updating.
77
+
78
+ Neo.findFirst({ntype:'yelp-filter'}).category = 'pizza'
79
+
80
+ ??Notice a timing issue
81
+
82
+ Currently, the initial city and category are just empty strings.
83
+ But if there had some other values we'd want the city and category
84
+ text fields to reflect those values as we start the app.
85
+
86
+ For example, change the city and category like this:
87
+
88
+ city_: 'Madison',
89
+ category_: 'pizza',
90
+
91
+ Upon refresh these values are _not_ seen in the fields, but you _will_
92
+ see the values in the Crome debugger
93
+
94
+ console.log(Neo.findFirst({ntype:'yelp-filter'}).city); // Logs "Madison"
95
+
96
+ The initial values _are_ assigned, and the `afterSet...` methods are run,
97
+ but since the view hasn't been rendered the `after` methods can't initialize
98
+ the fields.
99
+
100
+ ??Fix the issue
101
+
102
+ We need to detect when the view is rendered, then update
103
+ the text fields to their initial values.
104
+
105
+ Since `Neo.component.Base` has a `mounted` get/set,
106
+ there's a corresponding `afterSetMounted()` method. We'll add the code
107
+ there.
108
+
109
+ Use the following code. Note the 20ms delay. That's there because
110
+ after a view is mounted, the DOM may not update until one "frame"
111
+ later, which is about 18ms.
112
+
113
+ afterSetMounted() {
114
+ // Wait for one "frame" using a framerate of 60 per second = 17.7 ms
115
+ setTimeout(() => {
116
+ this.afterSetCity(this.city);
117
+ this.afterSetCategory(this.category);
118
+ }, 20);
119
+ }
120
+
121
+ Save and refresh. You should see the new default values as the initial
122
+ values for the city and category text fields.
123
+
124
+ ??Make sure `city` and `category` have their normal default values
125
+
126
+ Change city and category back to their normal default values.
127
+
128
+ city_: '',
129
+ category_: '',
130
+
131
+ In an upcoming lab we'll use another method of initializing the city and category.
@@ -0,0 +1,115 @@
1
+ #Introduction
2
+
3
+ In this lab you'll update the property as the text fields change.
4
+
5
+ #Steps
6
+
7
+ ??Update `city` as the user types.
8
+
9
+ We want changes in the text field to be reflected in the filter's `city` property.
10
+
11
+ To do that, listen to the field's `change` event, and in the handler get a
12
+ reference to the parent container, and assign the value to it's `city` property.
13
+
14
+ listeners: {
15
+ change: (data) => data.component.up('yelp-filter').city = data.value
16
+ }
17
+
18
+ Test this by entering text in the city field &mdash; you should see a the console
19
+ log being run on each keypress.
20
+
21
+ ??Do the same for `category`
22
+
23
+ Add a similer `listeners` config to the category field.
24
+
25
+ Test this by entering text in the category field &mdash; you should see a the console
26
+ log being run on each keypress.
27
+
28
+ ??Plan a way to buffer or _debounce_ the updates
29
+
30
+ Conceptually, `Yelp.view.business.Filter` has `city` and `category` properties.
31
+
32
+ "Madison" is a city, but "M" and "Ma" and "Mad" are not cities, so the
33
+ _city_ property shouldn't reflect those intermediate values. Therefore,
34
+ we need code to defer updating the property until the user appears to have
35
+ finished typing.
36
+
37
+ There are various ways to create a _buffer_ or _debouce_ fuctions, and
38
+ we found one via an internet search. We need a place to hold our implementation.
39
+
40
+ ??Add a utility class with a `debounce` function
41
+
42
+ Use a terminal to navigate to the Neo workspace, and run `npm run create-class`.
43
+
44
+ - Name the class "Yelp.util.Function"
45
+ - Extend `Neo.core.Base
46
+ - Make it a singleton
47
+
48
+ Edit the new file and add the debounce routine highlighted below.
49
+
50
+ <pre style="border: thin solid gray; padding: 8px; color: lightgray;font-size:14pt;">
51
+ import Base from '../../../node_modules/neo.mjs/src/core/Base.mjs';
52
+
53
+ class Function extends Base {
54
+ static config = {
55
+ className: 'Yelp.util.Function',
56
+ singleton: true
57
+ }
58
+ <span style="color:#b91010;">debounce(func, wait, immediate) {
59
+ let timeout
60
+ return function (...args) {
61
+ clearTimeout(timeout)
62
+ timeout = setTimeout(() => {
63
+ timeout = null
64
+ if (!immediate) func.apply(this, args)
65
+ }, wait)
66
+ if (immediate && !timeout) func.apply(this, [...args])
67
+ }
68
+ }</span>
69
+ }
70
+
71
+ Neo.applyClassConfig(Function);
72
+
73
+ let instance = Neo.create(Function);
74
+
75
+ Neo.applyToGlobalNs(instance);
76
+
77
+ export default instance;
78
+ </pre>
79
+
80
+ ??Buffer the updates
81
+
82
+ Edit `view/businesses/Filter.mjs` and add this import.
83
+
84
+ import Function from '../../util/Function.mjs';
85
+
86
+ And add a method designed to do a buffered update to a property.
87
+
88
+ doBufferedUpdate(property, value) {
89
+ this._bufferedUpdate = this._bufferedUpdate || Function.debounce((property, value) => this[property] = value, 500);
90
+ this._bufferedUpdate(property, value);
91
+ }
92
+
93
+ ??Use the new function when the city text field changes
94
+
95
+ Modify the city's `change` listener to use the new function.
96
+
97
+ listeners: {
98
+ change: (data) => data.component.up('yelp-filter').doBufferedUpdate('city', data.value)
99
+ }
100
+
101
+ Test the changes by running the app, and type a city name. After the 500ms delay
102
+ you should see the city name logged. Note that running
103
+
104
+ Neo.findFirst({ntype:'yelp-filter'}).city = 'Madison'
105
+
106
+ logs the city name immediately. Changing the city to a new value updates
107
+ immediately. We only need to buffer changes when the user is typing.
108
+
109
+ ??Have the category field do the same thing
110
+
111
+ Make a similar change to the category field config.
112
+
113
+ listeners: {
114
+ change: (data) => data.component.up('yelp-filter').doBufferedUpdate('category', data.value)
115
+ }
@@ -0,0 +1,12 @@
1
+ You simply assign or read values to access a property.
2
+
3
+ console.log(component.bar); // Results in the secret getter being run
4
+ component.bar = 'hi'; // Results in the secret setter being run
5
+
6
+ You can set multiple values simultaneously via `Neo.component.Bases#set({})`
7
+
8
+ component.set({
9
+ bar: 'hi',
10
+ baz: 'there'
11
+ });
12
+
@@ -0,0 +1,5 @@
1
+ The `headers:[{}]` // An array of component configs
2
+
3
+ Components in the headers array are tagged with a `dock` property
4
+ used to specify where the header is placed: top, right, bottom, or left.
5
+
@@ -0,0 +1,24 @@
1
+ A tab container is a card-layout container with a tab bar and styled buttons.
2
+ Do not specify a `layout` for tab containers.
3
+
4
+ The buttons are configured via `tabButtonConfig`
5
+
6
+ activeIndex: 2,
7
+ tabBarPosition: 'left', // top, right, bottom, left
8
+ itemDefaults: { module: Button },
9
+ items: [{
10
+ tabButtonConfig: {
11
+ iconCls: 'fa fa-home',
12
+ text: 'Tab 1'
13
+ }
14
+ }, {
15
+ tabButtonConfig: {
16
+ iconCls: 'fa fa-play-circle',
17
+ text: 'Tab 2'
18
+ }
19
+ }, {
20
+ tabButtonConfig: {
21
+ iconCls: 'fa fa-bell',
22
+ text: 'Tab 3'
23
+ }
24
+ }]
@@ -0,0 +1,21 @@
1
+
2
+
3
+ <div class="expander" caption="High-level Goal">
4
+ <h2>To learn how to properly encapsulate a class with a well defined API.</h2>
5
+ <p>
6
+ You'll code a class that's encapsulated and de-coupled, where the code creating
7
+ the instance uses class properties and otherwise has no awareness of its
8
+ implementation details.
9
+ </p>
10
+ </div>
11
+
12
+
13
+ <div class="expander" caption="Low-level Goal">
14
+ <h2>To get practice using the syntax and features we just learned.</h2>
15
+ <ul>
16
+ <li>Defining get/set properties
17
+ <li>Using `afterSet` methods to detect property change
18
+ <li>Using `reference` and `getReference()`
19
+ </ul>
20
+ </div>
21
+
@@ -0,0 +1,9 @@
1
+ - A view controller holds a view's event handlers
2
+ - The controller can hold any other logic you might need
3
+
4
+
5
+ The existence of a controller should be unknown outside of the class.
6
+ The decision of the view's author to use (or not use) a controller
7
+ should be transparent outside of the class.
8
+
9
+ this.lookup('someComponent').controller.someMethod(); // This is bad
@@ -0,0 +1,7 @@
1
+ Within controller methods you can get a reference to a view component
2
+ via
3
+
4
+ - `this.getReference('name')` returns a component with the specified reference
5
+ - In the view, you specify the reference via `reference: 'somename`
6
+
7
+ - `onComponentConstructed()` is a controller lifecycle method you can override if you need to do something at time of component creation
@@ -0,0 +1,26 @@
1
+ #Introduction
2
+
3
+ In this lab you'll put the view model into its own class.
4
+
5
+ #Steps
6
+
7
+
8
+ ??Create the view model
9
+
10
+ Use `npm run create-class` to create`Yelp.view.MainViewModel` that extends `model/Component`.
11
+
12
+ ??Use it
13
+
14
+ Move the `data` property from the main view to the view model.
15
+
16
+ Then import the view model, and change the `model` config to use the new class.
17
+
18
+ ??Create and use a controller
19
+
20
+ We don't need controller logic yet, but we will, so while we're at it, create a
21
+ `Yelp.view.MainViewController` that extends `controller/Component`. Import it in the
22
+ main view, and configure a controller block to use it.
23
+
24
+ controller: {
25
+ module: MainViewController
26
+ }