neo.mjs 6.9.10 → 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.
- package/apps/ServiceWorker.mjs +2 -2
- package/apps/learnneo/neo-config.json +5 -1
- package/apps/learnneo/store/Content.mjs +1 -1
- package/apps/learnneo/view/Viewport.mjs +12 -1
- package/apps/learnneo/view/home/ContentTreeList.mjs +8 -5
- package/apps/learnneo/view/home/ContentView.mjs +60 -0
- package/apps/learnneo/view/home/MainContainer.mjs +22 -14
- package/apps/learnneo/view/home/MainContainerController.mjs +57 -18
- package/apps/newwebsite/app.mjs +6 -0
- package/apps/newwebsite/index.html +10 -0
- package/apps/newwebsite/neo-config.json +7 -0
- package/apps/newwebsite/view/MainContainer.mjs +59 -0
- package/buildScripts/webpack/json/myApps.template.json +1 -0
- package/examples/ConfigurationViewport.mjs +12 -9
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/button/base/neo-config.json +1 -2
- package/package.json +2 -2
- package/resources/data/{learnneo → deck/learnneo}/p/2023-10-01T18-29-19-158Z.md +3 -6
- package/resources/data/deck/learnneo/p/stylesheet.md +40 -0
- package/resources/data/{learnneo → deck/learnneo}/t.json +19 -2
- package/resources/data/deck/training/p/2022-12-27T21-54-52-300Z.md +11 -0
- package/resources/data/deck/training/p/2022-12-27T21-55-23-144Z.md +43 -0
- package/resources/data/deck/training/p/2022-12-27T21-55-30-948Z.md +1 -0
- package/resources/data/deck/training/p/2022-12-27T21-55-43-542Z.md +84 -0
- package/resources/data/deck/training/p/2022-12-27T22-23-55-083Z.md +1 -0
- package/resources/data/deck/training/p/2022-12-27T22-24-07-886Z.md +8 -0
- package/resources/data/deck/training/p/2022-12-27T22-24-52-295Z.md +8 -0
- package/resources/data/deck/training/p/2022-12-27T22-25-03-853Z.md +5 -0
- package/resources/data/deck/training/p/2022-12-27T22-43-58-924Z.md +10 -0
- package/resources/data/deck/training/p/2022-12-27T22-44-28-881Z.md +3 -0
- package/resources/data/deck/training/p/2022-12-27T22-44-41-791Z.md +4 -0
- package/resources/data/deck/training/p/2022-12-27T22-45-21-032Z.md +7 -0
- package/resources/data/deck/training/p/2022-12-27T22-49-22-078Z.md +4 -0
- package/resources/data/deck/training/p/2022-12-27T22-50-20-626Z.md +4 -0
- package/resources/data/deck/training/p/2022-12-28T16-58-47-786Z.md +0 -0
- package/resources/data/deck/training/p/2022-12-28T16-58-55-192Z.md +9 -0
- package/resources/data/deck/training/p/2022-12-28T17-10-18-058Z.md +15 -0
- package/resources/data/deck/training/p/2022-12-28T17-10-42-296Z.md +40 -0
- package/resources/data/deck/training/p/2022-12-28T17-11-34-653Z.md +41 -0
- package/resources/data/deck/training/p/2022-12-28T17-13-09-994Z.md +0 -0
- package/resources/data/deck/training/p/2022-12-28T21-32-14-420Z.md +0 -0
- package/resources/data/deck/training/p/2022-12-29T01-43-32-431Z.md +7 -0
- package/resources/data/deck/training/p/2022-12-29T15-56-54-485Z.md +7 -0
- package/resources/data/deck/training/p/2022-12-29T15-57-11-499Z.md +7 -0
- package/resources/data/deck/training/p/2022-12-29T16-00-13-223Z.md +7 -0
- package/resources/data/deck/training/p/2022-12-29T18-34-25-826Z.md +4 -0
- package/resources/data/deck/training/p/2022-12-29T18-36-08-226Z.md +106 -0
- package/resources/data/deck/training/p/2022-12-29T18-36-56-893Z.md +112 -0
- package/resources/data/deck/training/p/2022-12-29T19-31-30-507Z.md +31 -0
- package/resources/data/deck/training/p/2022-12-29T19-31-55-091Z.md +14 -0
- package/resources/data/deck/training/p/2022-12-29T20-03-42-628Z.md +9 -0
- package/resources/data/deck/training/p/2022-12-29T20-21-20-669Z.md +7 -0
- package/resources/data/deck/training/p/2022-12-29T20-37-08-919Z.md +46 -0
- package/resources/data/deck/training/p/2022-12-29T20-37-20-344Z.md +43 -0
- package/resources/data/deck/training/p/2022-12-30T19-04-30-990Z.md +8 -0
- package/resources/data/deck/training/p/2022-12-31T18-43-56-338Z.md +7 -0
- package/resources/data/deck/training/p/2022-12-31T18-51-50-682Z.md +1 -0
- package/resources/data/deck/training/p/2022-12-31T18-54-04-176Z.md +4 -0
- package/resources/data/deck/training/p/2022-12-31T22-11-55-555Z.md +112 -0
- package/resources/data/deck/training/p/2022-12-31T23-00-41-222Z.md +6 -0
- package/resources/data/deck/training/p/2022-12-31T23-18-55-655Z.md +69 -0
- package/resources/data/deck/training/p/2022-12-31T23-25-40-735Z.md +21 -0
- package/resources/data/deck/training/p/2022-12-31T23-25-51-014Z.md +7 -0
- package/resources/data/deck/training/p/2023-01-01T17-49-18-429Z.md +3 -0
- package/resources/data/deck/training/p/2023-01-01T18-44-07-034Z.md +34 -0
- package/resources/data/deck/training/p/2023-01-01T18-47-39-766Z.md +15 -0
- package/resources/data/deck/training/p/2023-01-01T19-04-22-830Z.md +4 -0
- package/resources/data/deck/training/p/2023-01-01T21-11-58-025Z.md +25 -0
- package/resources/data/deck/training/p/2023-01-01T21-12-37-340Z.md +23 -0
- package/resources/data/deck/training/p/2023-01-01T21-13-13-880Z.md +8 -0
- package/resources/data/deck/training/p/2023-01-01T21-14-45-740Z.md +98 -0
- package/resources/data/deck/training/p/2023-01-01T21-18-23-886Z.md +26 -0
- package/resources/data/deck/training/p/2023-01-01T21-18-31-316Z.md +19 -0
- package/resources/data/deck/training/p/2023-01-01T21-18-42-290Z.md +23 -0
- package/resources/data/deck/training/p/2023-01-01T21-19-57-020Z.md +24 -0
- package/resources/data/deck/training/p/2023-01-01T21-22-31-184Z.md +13 -0
- package/resources/data/deck/training/p/2023-01-01T21-22-38-317Z.md +17 -0
- package/resources/data/deck/training/p/2023-01-01T21-22-47-693Z.md +20 -0
- package/resources/data/deck/training/p/2023-01-01T21-23-17-716Z.md +39 -0
- package/resources/data/deck/training/p/2023-01-01T21-23-28-532Z.md +22 -0
- package/resources/data/deck/training/p/2023-01-01T21-25-23-899Z.md +3 -0
- package/resources/data/deck/training/p/2023-01-01T21-25-59-742Z.md +1 -0
- package/resources/data/deck/training/p/2023-01-01T21-26-53-748Z.md +12 -0
- package/resources/data/deck/training/p/2023-01-01T23-38-42-863Z.md +2 -0
- package/resources/data/deck/training/p/2023-01-03T02-07-19-014Z.md +143 -0
- package/resources/data/deck/training/p/2023-01-04T01-52-23-454Z.md +76 -0
- package/resources/data/deck/training/p/2023-01-06T23-21-12-009Z.md +127 -0
- package/resources/data/deck/training/p/2023-01-06T23-21-31-685Z.md +81 -0
- package/resources/data/deck/training/p/2023-01-06T23-21-59-596Z.md +36 -0
- package/resources/data/deck/training/p/2023-01-06T23-34-13-897Z.md +87 -0
- package/resources/data/deck/training/p/2023-01-06T23-44-02-340Z.md +0 -0
- package/resources/data/deck/training/p/2023-01-06T23-46-36-687Z.md +1 -0
- package/resources/data/deck/training/p/2023-01-06T23-46-45-783Z.md +33 -0
- package/resources/data/deck/training/p/2023-01-08T00-45-11-144Z.md +50 -0
- package/resources/data/deck/training/p/2023-01-08T01-06-31-267Z.md +41 -0
- package/resources/data/deck/training/p/2023-01-08T01-24-21-088Z.md +95 -0
- package/resources/data/deck/training/p/2023-01-08T01-25-12-557Z.md +11 -0
- package/resources/data/deck/training/p/2023-01-08T01-46-50-723Z.md +25 -0
- package/resources/data/deck/training/p/2023-01-08T02-09-07-802Z.md +18 -0
- package/resources/data/deck/training/p/2023-01-08T02-09-19-678Z.md +66 -0
- package/resources/data/deck/training/p/2023-01-08T02-11-26-333Z.md +29 -0
- package/resources/data/deck/training/p/2023-01-08T17-22-48-841Z.md +14 -0
- package/resources/data/deck/training/p/2023-01-08T20-46-11-806Z.md +5 -0
- package/resources/data/deck/training/p/2023-01-08T20-47-23-682Z.md +5 -0
- package/resources/data/deck/training/p/2023-01-08T20-47-32-064Z.md +13 -0
- package/resources/data/deck/training/p/2023-01-08T20-47-57-045Z.md +0 -0
- package/resources/data/deck/training/p/2023-01-08T20-48-03-791Z.md +18 -0
- package/resources/data/deck/training/p/2023-01-08T20-48-32-466Z.md +9 -0
- package/resources/data/deck/training/p/2023-01-08T20-48-51-322Z.md +20 -0
- package/resources/data/deck/training/p/2023-01-08T20-49-52-741Z.md +0 -0
- package/resources/data/deck/training/p/2023-01-08T20-52-03-556Z.md +0 -0
- package/resources/data/deck/training/p/2023-01-08T20-57-36-333Z.md +2 -0
- package/resources/data/deck/training/p/2023-01-08T20-57-51-136Z.md +5 -0
- package/resources/data/deck/training/p/2023-01-09T00-07-37-951Z.md +0 -0
- package/resources/data/deck/training/p/2023-01-09T00-35-40-671Z.md +3 -0
- package/resources/data/deck/training/p/2023-01-10T01-29-38-148Z.md +10 -0
- package/resources/data/deck/training/p/2023-01-10T01-43-12-166Z.md +31 -0
- package/resources/data/deck/training/p/2023-01-10T02-21-54-303Z.md +10 -0
- package/resources/data/deck/training/p/2023-01-12T01-50-54-617Z.md +74 -0
- package/resources/data/deck/training/p/2023-01-13T19-55-24-735Z.md +14 -0
- package/resources/data/deck/training/p/2023-01-13T20-08-27-068Z.md +28 -0
- package/resources/data/deck/training/p/2023-01-13T20-23-38-411Z.md +25 -0
- package/resources/data/deck/training/p/2023-01-13T20-37-06-267Z.md +13 -0
- package/resources/data/deck/training/p/2023-01-13T21-05-57-708Z.md +8 -0
- package/resources/data/deck/training/p/2023-01-13T21-48-17-258Z.md +20 -0
- package/resources/data/deck/training/p/2023-01-13T22-05-05-799Z.md +14 -0
- package/resources/data/deck/training/p/2023-01-13T22-08-30-863Z.md +17 -0
- package/resources/data/deck/training/p/2023-01-13T23-01-50-449Z.md +4 -0
- package/resources/data/deck/training/p/2023-01-14T00-33-05-958Z.md +62 -0
- package/resources/data/deck/training/p/2023-01-14T00-40-27-784Z.md +229 -0
- package/resources/data/deck/training/p/2023-01-14T00-41-59-081Z.md +153 -0
- package/resources/data/deck/training/p/2023-01-14T13-50-28-199Z.md +19 -0
- package/resources/data/deck/training/p/2023-01-14T13-59-20-275Z.md +6 -0
- package/resources/data/deck/training/p/2023-01-14T14-03-29-456Z.md +3 -0
- package/resources/data/deck/training/p/2023-01-14T14-27-57-678Z.md +7 -0
- package/resources/data/deck/training/p/2023-01-14T17-30-18-228Z.md +33 -0
- package/resources/data/deck/training/p/2023-01-14T18-28-39-316Z.md +1 -0
- package/resources/data/deck/training/p/2023-01-14T18-28-44-115Z.md +4 -0
- package/resources/data/deck/training/p/2023-01-14T18-28-49-548Z.md +18 -0
- package/resources/data/deck/training/p/2023-01-14T18-40-13-758Z.md +10 -0
- package/resources/data/deck/training/p/2023-01-14T19-29-15-291Z.md +12 -0
- package/resources/data/deck/training/p/2023-01-15T18-51-52-134Z.md +83 -0
- package/resources/data/deck/training/p/2023-01-15T20-03-30-073Z.md +11 -0
- package/resources/data/deck/training/p/2023-01-15T22-07-52-073Z.md +16 -0
- package/resources/data/deck/training/p/2023-01-15T22-22-13-517Z.md +12 -0
- package/resources/data/deck/training/p/2023-01-15T22-28-57-508Z.md +131 -0
- package/resources/data/deck/training/p/2023-01-15T22-36-30-913Z.md +115 -0
- package/resources/data/deck/training/p/2023-01-16T16-03-40-770Z.md +12 -0
- package/resources/data/deck/training/p/2023-01-16T20-21-56-859Z.md +5 -0
- package/resources/data/deck/training/p/2023-01-16T20-24-09-690Z.md +24 -0
- package/resources/data/deck/training/p/2023-01-20T12-51-22-646Z.md +21 -0
- package/resources/data/deck/training/p/2023-01-20T13-06-46-614Z.md +9 -0
- package/resources/data/deck/training/p/2023-01-20T13-08-51-600Z.md +7 -0
- package/resources/data/deck/training/p/2023-01-20T15-20-13-363Z.md +26 -0
- package/resources/data/deck/training/p/2023-01-20T15-34-58-813Z.md +75 -0
- package/resources/data/deck/training/p/2023-01-21T16-33-20-458Z.md +33 -0
- package/resources/data/deck/training/p/2023-01-21T16-45-28-263Z.md +28 -0
- package/resources/data/deck/training/p/2023-01-21T16-56-25-452Z.md +3 -0
- package/resources/data/deck/training/p/2023-01-21T17-28-31-493Z.md +6 -0
- package/resources/data/deck/training/p/2023-01-21T19-49-51-918Z.md +13 -0
- package/resources/data/deck/training/p/2023-01-21T20-08-24-452Z.md +15 -0
- package/resources/data/deck/training/p/2023-01-21T20-35-54-947Z.md +20 -0
- package/resources/data/deck/training/p/2023-01-21T20-54-47-603Z.md +39 -0
- package/resources/data/deck/training/p/2023-01-21T20-56-28-184Z.md +25 -0
- package/resources/data/deck/training/p/2023-01-21T20-57-32-927Z.md +4 -0
- package/resources/data/deck/training/p/2023-01-21T23-13-33-394Z.md +6 -0
- package/resources/data/deck/training/p/2023-01-28T19-11-37-464Z.md +24 -0
- package/resources/data/deck/training/p/2023-01-28T20-43-41-188Z.md +9 -0
- package/resources/data/deck/training/p/2023-01-28T20-53-56-476Z.md +8 -0
- package/resources/data/deck/training/p/2023-01-28T20-58-43-776Z.md +10 -0
- package/resources/data/deck/training/p/2023-01-28T22-18-41-259Z.md +33 -0
- package/resources/data/deck/training/p/2023-01-28T22-24-34-808Z.md +24 -0
- package/resources/data/deck/training/p/2023-01-29T16-25-24-528Z.md +44 -0
- package/resources/data/deck/training/p/2023-01-29T21-14-32-588Z.md +12 -0
- package/resources/data/deck/training/p/2023-01-31T19-24-53-504Z.md +8 -0
- package/resources/data/deck/training/p/2023-01-31T20-33-55-855Z.md +11 -0
- package/resources/data/deck/training/p/2023-01-31T20-34-30-261Z.md +7 -0
- package/resources/data/deck/training/p/2023-01-31T20-52-53-367Z.md +43 -0
- package/resources/data/deck/training/p/2023-02-04T15-18-35-682Z.md +20 -0
- package/resources/data/deck/training/p/2023-02-04T15-49-47-597Z.md +14 -0
- package/resources/data/deck/training/p/2023-02-04T18-58-57-808Z.md +1 -0
- package/resources/data/deck/training/p/2023-02-04T20-07-11-288Z.md +1 -0
- package/resources/data/deck/training/p/2023-02-04T20-09-50-169Z.md +1 -0
- package/resources/data/deck/training/p/2023-02-04T20-19-42-740Z.md +8 -0
- package/resources/data/deck/training/p/2023-02-04T20-23-56-013Z.md +12 -0
- package/resources/data/deck/training/p/2023-02-04T20-28-12-391Z.md +20 -0
- package/resources/data/deck/training/p/2023-02-05T00-20-32-554Z.md +16 -0
- package/resources/data/deck/training/p/2023-02-05T00-35-56-282Z.md +13 -0
- package/resources/data/deck/training/p/2023-02-05T15-36-57-182Z.md +24 -0
- package/resources/data/deck/training/p/2023-02-05T17-39-51-712Z.md +70 -0
- package/resources/data/deck/training/p/2023-02-05T17-44-53-815Z.md +195 -0
- package/resources/data/deck/training/p/2023-02-05T17-45-40-114Z.md +92 -0
- package/resources/data/deck/training/p/2023-02-05T18-12-14-489Z.md +60 -0
- package/resources/data/deck/training/p/2023-02-06T00-14-54-457Z.md +9 -0
- package/resources/data/deck/training/p/2023-06-28T18-03-14-313Z.md +8 -0
- package/resources/data/deck/training/p/2023-06-28T18-26-17-290Z.md +7 -0
- package/resources/data/deck/training/p/2023-06-28T21-16-24-034Z.md +40 -0
- package/resources/data/deck/training/p/2023-06-28T21-16-34-972Z.md +16 -0
- package/resources/data/deck/training/p/2023-06-28T21-28-28-379Z.md +4 -0
- package/resources/data/deck/training/p/2023-06-29T23-15-10-411Z.md +5 -0
- package/resources/data/deck/training/p/2023-07-01T15-42-45-193Z.md +433 -0
- package/resources/data/deck/training/p/2023-07-01T21-54-31-329Z.md +6 -0
- package/resources/data/deck/training/p/2023-07-02T16-14-06-970Z.md +14 -0
- package/resources/data/deck/training/p/2023-07-31T00-26-03-842Z.md +4 -0
- package/resources/data/deck/training/p/2023-07-31T00-31-51-933Z.md +10 -0
- package/resources/data/deck/training/p/2023-07-31T00-37-21-927Z.md +205 -0
- package/resources/data/deck/training/p/2023-10-01T18-29-19-158Z.md +76 -0
- package/resources/data/deck/training/p/2023-10-07T19-18-28-517Z.md +102 -0
- package/resources/data/deck/training/p/2023-10-08T20-20-07-934Z.md +75 -0
- package/resources/data/deck/training/p/2023-10-08T20-20-37-336Z.md +29 -0
- package/resources/data/deck/training/p/2023-10-08T20-37-30-658Z.md +0 -0
- package/resources/data/deck/training/p/2023-10-08T21-58-25-809Z.md +68 -0
- package/resources/data/deck/training/p/2023-10-08T22-22-11-013Z.md +0 -0
- package/resources/data/deck/training/p/2023-10-14T19-25-08-153Z.md +119 -0
- package/resources/data/deck/training/t.json +1 -0
- package/resources/scss/src/apps/learnneo/home/{ContentComponent.scss → ContentView.scss} +9 -15
- package/resources/scss/theme-neo-light/Global.scss +46 -0
- package/resources/scss/theme-neo-light/design-tokens/Core.scss +7 -0
- package/resources/scss/theme-neo-light/design-tokens/Semantic.scss +0 -0
- package/resources/scss/theme-neo-light/design-tokens/_all.scss +4 -0
- package/src/DefaultConfig.mjs +4 -4
- package/src/form/field/Text.mjs +2 -2
- package/apps/learnneo/view/home/ContentComponent.mjs +0 -24
- /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-07T19-18-28-517Z.md +0 -0
- /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T20-20-07-934Z.md +0 -0
- /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T20-20-37-336Z.md +0 -0
- /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T20-37-30-658Z.md +0 -0
- /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T21-58-25-809Z.md +0 -0
- /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T22-22-11-013Z.md +0 -0
- /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-14T19-25-08-153Z.md +0 -0
- /package/resources/data/{learnneo → deck/learnneo}/pages/whyneo.md +0 -0
- /package/resources/data/{learnneo → deck/learnneo}/tree.json +0 -0
- /package/resources/{deck → data/deck}/whyneo.md +0 -0
- /package/resources/scss/src/apps/newwebsite/{MainContainer.css → MainContainer.scss} +0 -0
- /package/resources/scss/theme-neo-light/design-tokens/{Components.scss → Component.scss} +0 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
A side effect is a state change outside of setting the value.
|
2
|
+
|
3
|
+
Another common use the afterSet method is to fire some kind of change event.
|
4
|
+
|
5
|
+
<pre class="runnable readonly text 340">
|
6
|
+
/**
|
7
|
+
* Account balance
|
8
|
+
* @member {Number} balance_=0
|
9
|
+
*/
|
10
|
+
balance_: 0,
|
11
|
+
|
12
|
+
...
|
13
|
+
|
14
|
+
afterSetBalance(balance){
|
15
|
+
|
16
|
+
if (balance < 0) this.status = this.OVERDRAWN; // Side-effect
|
17
|
+
|
18
|
+
this.fire('balanceChange', {
|
19
|
+
component: this,
|
20
|
+
balance
|
21
|
+
});
|
22
|
+
|
23
|
+
}
|
24
|
+
</pre>
|
25
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<pre class="runnable readonly text 240">
|
2
|
+
/**
|
3
|
+
* Account balance
|
4
|
+
* @member {Number} balance_=0
|
5
|
+
*/
|
6
|
+
balance_: 0,
|
7
|
+
|
8
|
+
...
|
9
|
+
|
10
|
+
beforeGetBalance(balance){
|
11
|
+
return this.governmentAudit?(balance * .8):balance; // Claim lower balances when audits are underway
|
12
|
+
}
|
13
|
+
</pre>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
You rarely need `Neo.component.Base` instances — they're just too primitive.
|
2
|
+
|
3
|
+
A `Neo.component.Base` might be used as a placeholder, to be replaced
|
4
|
+
later on with some other component type.
|
5
|
+
|
6
|
+
However, if you need to code a custom component — where you specify
|
7
|
+
your own DOM structure — then you'll extend `Ext.component.Base`.
|
8
|
+
We'll see an example of that later.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Compont content is defined via a `_vdom` config, and by procedurally changing the `vdom` property.
|
2
|
+
|
3
|
+
We'll go further in-depth with low-level components and vdom later in the course.
|
4
|
+
|
5
|
+
<pre style="font-size: 14pt; padding: 8pt; border: solid thin lightgray">
|
6
|
+
name_: '',
|
7
|
+
|
8
|
+
_vdom: {
|
9
|
+
tag: 'div',
|
10
|
+
style: 'fontWeight:bold',
|
11
|
+
innerHTML: ''
|
12
|
+
}
|
13
|
+
|
14
|
+
...
|
15
|
+
|
16
|
+
afterSetName(name, oldName) {
|
17
|
+
this.vdom.innerHTML = name;
|
18
|
+
this.update();
|
19
|
+
}
|
20
|
+
</pre>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<pre class="runnable readonly text 240">
|
2
|
+
/**
|
3
|
+
* An array of ducks
|
4
|
+
* @member {[Duck]} ducks=[]
|
5
|
+
*/
|
6
|
+
ducks_: [],
|
7
|
+
|
8
|
+
...
|
9
|
+
|
10
|
+
beforeSetDucks(ducks){
|
11
|
+
return Neo.clone(ducks); // Use a defensive copy so we don't mess up the original array
|
12
|
+
}
|
13
|
+
</pre>
|
14
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<pre class="runnable readonly text 300">
|
2
|
+
/**
|
3
|
+
* An array of ducks
|
4
|
+
* @member {[Duck]} ducks=[]
|
5
|
+
*/
|
6
|
+
ducks_: [],
|
7
|
+
|
8
|
+
...
|
9
|
+
|
10
|
+
beforeSetDucks(ducks){
|
11
|
+
return Neo.clone(ducks); // Use a defensive copy so we don't mess up the original array
|
12
|
+
}
|
13
|
+
beforeGetDucks(ducks){
|
14
|
+
return Neo.clone(ducks); // Use a defensive copy so the other code doesn't mess up our copy
|
15
|
+
}
|
16
|
+
</pre>
|
17
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#Introduction
|
2
|
+
|
3
|
+
In this lab you'll bind the map's center to the city.
|
4
|
+
|
5
|
+
#Steps
|
6
|
+
|
7
|
+
|
8
|
+
??Configure an in-line view model in the main view
|
9
|
+
|
10
|
+
You'll need to import
|
11
|
+
`src/model/Component.mjs', named something like `ViewModel`, then
|
12
|
+
configure the model:
|
13
|
+
|
14
|
+
model: {
|
15
|
+
module: ViewModel,
|
16
|
+
data: {},
|
17
|
+
stores: {}
|
18
|
+
}
|
19
|
+
|
20
|
+
|
21
|
+
??Create a `center` property in the view model
|
22
|
+
|
23
|
+
<pre style="color:lightgray">
|
24
|
+
model: {
|
25
|
+
module: ViewModel,
|
26
|
+
data: {
|
27
|
+
<span style="color:firebrick">center: {
|
28
|
+
lat: lat: -27.1259626,
|
29
|
+
lng: -109.4088545
|
30
|
+
}</span>
|
31
|
+
},
|
32
|
+
},
|
33
|
+
</pre>
|
34
|
+
|
35
|
+
??Watch the values change
|
36
|
+
|
37
|
+
Just for the fun of it, and to gain insights into how view model changes occur, add
|
38
|
+
a listener to the view model config.
|
39
|
+
|
40
|
+
<pre style="color:lightgray">
|
41
|
+
model: {
|
42
|
+
module: ViewModel,
|
43
|
+
<span style="color:firebrick">listeners: {
|
44
|
+
dataPropertyChange: data => console.log(data.key, data.value)
|
45
|
+
},</span>
|
46
|
+
data: {
|
47
|
+
center: {
|
48
|
+
lat: lat: -27.1259626,
|
49
|
+
lng: -109.4088545
|
50
|
+
}
|
51
|
+
},
|
52
|
+
},
|
53
|
+
</pre>
|
54
|
+
|
55
|
+
??Bind the map center to that property
|
56
|
+
|
57
|
+
Edit `Yelp.view.businessses.Tabs` and modify the map
|
58
|
+
config to bind the center to the view model property.
|
59
|
+
|
60
|
+
bind: { center: data => data.center }
|
61
|
+
|
62
|
+
Save and refresh, and you should see the map centered at the specified location.
|
@@ -0,0 +1,229 @@
|
|
1
|
+
#Introduction
|
2
|
+
|
3
|
+
In this lab you'll fetch Yelp data based on the latitude and longitude corresponding
|
4
|
+
to the city.
|
5
|
+
|
6
|
+
#Steps
|
7
|
+
|
8
|
+
??Define the store
|
9
|
+
|
10
|
+
Edit the main view model.
|
11
|
+
|
12
|
+
Import `data/Store.mjs`.
|
13
|
+
|
14
|
+
import Store from '../../../node_modules/neo.mjs/src/data/Store.mjs';
|
15
|
+
|
16
|
+
Add a config _businesses_ in the `stores` config block
|
17
|
+
|
18
|
+
stores: {
|
19
|
+
businesses: {
|
20
|
+
module: Store,
|
21
|
+
url:"https://nameless-tundra-27404.herokuapp.com/go/?fn=yelp&latitude=43.084&longitude=-89.546&term=pizza&limit=1",
|
22
|
+
responseRoot: 'businesses',
|
23
|
+
autoLoad: true
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
Save and refresh then look in the debugger's Network tab. You should see the data being fetched.
|
28
|
+
|
29
|
+
<img style="border: thin solid gray" src="resources/images/yelp/initialNetworkTraffic.png"></img>
|
30
|
+
|
31
|
+
??Load the store procedurally
|
32
|
+
|
33
|
+
Remove the `autoLoad:true,`.
|
34
|
+
|
35
|
+
Edit the main view controller and add a statement to load the store.
|
36
|
+
|
37
|
+
<pre style='color:lightgray; padding: 8px;'>
|
38
|
+
doFetchYelpData() {
|
39
|
+
const model = this.getModel();
|
40
|
+
<span style="color:firebrick">model.stores.businesses.load();</span>
|
41
|
+
}
|
42
|
+
</pre>
|
43
|
+
|
44
|
+
If you were to save and refresh, and look in network traffic, you'd see
|
45
|
+
the url being run twice: once when the _center_ changed and once when
|
46
|
+
the _category_ changed. (In theory we could buffer the method that calls
|
47
|
+
the Yelp service, but for the lab we're not going to bother.)
|
48
|
+
|
49
|
+
??Update search parameters dynamically
|
50
|
+
|
51
|
+
Edit the main view model and replace the `url` with this value.
|
52
|
+
|
53
|
+
url:"https://nameless-tundra-27404.herokuapp.com/go/",
|
54
|
+
|
55
|
+
That URL omits the query fields — we'll be adding those dynamically.
|
56
|
+
|
57
|
+
Edit the main view controller and update the `load()` params to include
|
58
|
+
the _method_, _latitude_, and _longitude_, and _category.
|
59
|
+
|
60
|
+
<pre style='color:lightgray; padding: 8px;'>
|
61
|
+
doFetchYelpData() {
|
62
|
+
const model = this.getModel();
|
63
|
+
<span style="color:firebrick">const params = {
|
64
|
+
fn: 'yelp',
|
65
|
+
latitude: model.data.center.lat,
|
66
|
+
longitude: model.data.center.lng,
|
67
|
+
term: model.data.category
|
68
|
+
};
|
69
|
+
model.stores.businesses.load({ method: 'GET', params });</span>
|
70
|
+
}
|
71
|
+
</pre>
|
72
|
+
|
73
|
+
Test this by saving, refreshing, then changing the city a few times.
|
74
|
+
With each city changes you should see a new call to the Yelp web service.
|
75
|
+
|
76
|
+
<img style="border:thin solid gray" src="resources/images/yelp/CityChangesReflectedInTheFeed.png"></img>
|
77
|
+
|
78
|
+
??Add two fields to the store's model config
|
79
|
+
|
80
|
+
As you probably recall, the Google Maps component expects a store whose records specify
|
81
|
+
a _title_, and a _position_. The Yelp feed has values that looks like this:
|
82
|
+
|
83
|
+
...
|
84
|
+
"name": "Joe's Diner",
|
85
|
+
"coordinates": {
|
86
|
+
"latitude": 43.0753733442932,
|
87
|
+
"longitude": -89.5296266588608
|
88
|
+
},
|
89
|
+
...
|
90
|
+
|
91
|
+
Therefore, we need to add a two fields in the store's `fields:[]`.
|
92
|
+
|
93
|
+
model: {
|
94
|
+
fields: [{
|
95
|
+
name: 'title',
|
96
|
+
mapping: 'name'
|
97
|
+
}, {
|
98
|
+
name: 'position',
|
99
|
+
calculate: (data, field, item) => ({ lat: item.coordinates.latitude, lng: item.coordinates.longitude })
|
100
|
+
}]
|
101
|
+
},
|
102
|
+
|
103
|
+
Save, refresh, then use the debugger console to verity that the records reflect those values.
|
104
|
+
|
105
|
+
This should show the title of the first record.
|
106
|
+
|
107
|
+
Neo.findFirst({ntype:'yelp-main'}).model.stores.businesses.items[0].title;
|
108
|
+
|
109
|
+
This should show the position (lat, lng) of the first record.
|
110
|
+
|
111
|
+
Neo.findFirst({ntype:'yelp-main'}).model.stores.businesses.items[0].position
|
112
|
+
|
113
|
+
|
114
|
+
??Don't peek...
|
115
|
+
|
116
|
+
You can peek. If you get stuck, or just to compare to another implementation, here's the
|
117
|
+
full store and controller logic in invisible writing. Highlight the code to read it.
|
118
|
+
|
119
|
+
Your code may differ slightly to reflect your preferences for default city, etc.,
|
120
|
+
but this code will show how the store is configured and how the controller dynamically
|
121
|
+
fetches the data.
|
122
|
+
|
123
|
+
Here's the view model.
|
124
|
+
|
125
|
+
<pre style="border:thin solid #dddddd; padding: 4px; color: white">
|
126
|
+
|
127
|
+
import Base from '../../../node_modules/neo.mjs/src/model/Component.mjs';
|
128
|
+
import Store from '../../../node_modules/neo.mjs/src/data/Store.mjs';
|
129
|
+
|
130
|
+
class MainViewModel extends Base {
|
131
|
+
static config = {
|
132
|
+
className: 'Y.view.MainViewModel',
|
133
|
+
|
134
|
+
data: {
|
135
|
+
city: 'Oconomowoc, Wisconsin',
|
136
|
+
category: 'pizza',
|
137
|
+
center: {
|
138
|
+
lat: -27.1259626,
|
139
|
+
lng: -109.4088545
|
140
|
+
},
|
141
|
+
},
|
142
|
+
stores: {
|
143
|
+
businesses: {
|
144
|
+
module: Store,
|
145
|
+
url: "https://nameless-tundra-27404.herokuapp.com/go/",
|
146
|
+
responseRoot: 'businesses',
|
147
|
+
model: {
|
148
|
+
fields: [{
|
149
|
+
name: 'title',
|
150
|
+
mapping: 'name'
|
151
|
+
}, {
|
152
|
+
name: 'position',
|
153
|
+
calculate: (data, field, item) => ({lat: item.coordinates.latitude, lng: item.coordinates.longitude})
|
154
|
+
}]
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
Neo.applyClassConfig(MainViewModel);
|
163
|
+
|
164
|
+
export default MainViewModel;
|
165
|
+
</pre>
|
166
|
+
|
167
|
+
Here's the main view controller.
|
168
|
+
|
169
|
+
<pre style="border:thin solid #dddddd; padding: 4px; color: white">
|
170
|
+
import Base from '../../../node_modules/neo.mjs/src/controller/Component.mjs';
|
171
|
+
|
172
|
+
class MainViewController extends Base {
|
173
|
+
static config = {
|
174
|
+
className: 'Y.view.MainViewController',
|
175
|
+
}
|
176
|
+
|
177
|
+
onComponentConstructed() {
|
178
|
+
const model = this.getModel();
|
179
|
+
this.onCityChange(model.data.city);
|
180
|
+
model.on('dataPropertyChange', data => {
|
181
|
+
if (data.key === 'city') this.onCityChange(data.value);
|
182
|
+
if (data.key === 'center') this.doFetchYData();
|
183
|
+
if (data.key === 'category') this.doFetchYData();
|
184
|
+
});
|
185
|
+
}
|
186
|
+
onCityChange(city) {
|
187
|
+
if (!city) return;
|
188
|
+
Neo.main.addon.GoogleMaps.geocode({address: city})
|
189
|
+
.then(data => this.getModel().data.center = data.results[0].geometry.location);
|
190
|
+
}
|
191
|
+
|
192
|
+
doFetchYData() {
|
193
|
+
const model = this.getModel();
|
194
|
+
console.log('Fetch Yelp data', model.data.center, model.data.category);
|
195
|
+
const params = {
|
196
|
+
fn: 'yelp',
|
197
|
+
latitude: model.data.center.lat,
|
198
|
+
longitude: model.data.center.lng,
|
199
|
+
term: model.data.category,
|
200
|
+
limit: 20,
|
201
|
+
};
|
202
|
+
model.stores.businesses.load({method: 'GET', params});
|
203
|
+
}
|
204
|
+
|
205
|
+
|
206
|
+
}
|
207
|
+
|
208
|
+
Neo.applyClassConfig(MainViewController);
|
209
|
+
|
210
|
+
export default MainViewController;
|
211
|
+
</pre>
|
212
|
+
|
213
|
+
??Bind the store to the map
|
214
|
+
|
215
|
+
You have the map center, and a store that holds the information the map expects.
|
216
|
+
|
217
|
+
Edit `view/businesses/Tabs.mjs` and add an additional binding to the map:
|
218
|
+
|
219
|
+
<pre style='color:lightgray'>
|
220
|
+
bind: {
|
221
|
+
center: data => data.center,
|
222
|
+
<span style="color:firebrick">markerStore: 'stores.businesses'</span>
|
223
|
+
},
|
224
|
+
</pre>
|
225
|
+
|
226
|
+
Save, refresh, then change the category a few times — the markers should
|
227
|
+
update at the specification city. Change city and see the markers for that
|
228
|
+
location and category.
|
229
|
+
|
@@ -0,0 +1,153 @@
|
|
1
|
+
#Introduction
|
2
|
+
|
3
|
+
In this lab you'll show Yelp information in a `Neo.table.Container`.
|
4
|
+
|
5
|
+
#Steps
|
6
|
+
|
7
|
+
??Import Table
|
8
|
+
|
9
|
+
Edit `yelp/view/businesses/Tabs.mjs` and import _src/table/Container.mjs_ —
|
10
|
+
make sure you use the correct relative path.
|
11
|
+
|
12
|
+
??Make the second tab the table
|
13
|
+
|
14
|
+
Configure the second tab to use imported `Neo.table.Container`. Configure the
|
15
|
+
button text to be _Table_, and use `iconCls:'fas fa-table-list'` (or any other icon
|
16
|
+
you think looks good).
|
17
|
+
|
18
|
+
If you save and refresh you should see the warning _Attempting to create a table.Container without defined columns..._. We'll fix that in the next step.
|
19
|
+
|
20
|
+
??Start to configure the columns
|
21
|
+
|
22
|
+
We want to show the business name, street address, telephone, star rating, and review count.
|
23
|
+
|
24
|
+
Configure a `columns:[]` with five columns whose `text` is: _Name_, _Address_, _Telephone_, _Rating_, and _Reviews_.
|
25
|
+
|
26
|
+
??Plan how to show the data
|
27
|
+
|
28
|
+
Here's what a business looks like in the data feed:
|
29
|
+
|
30
|
+
{
|
31
|
+
"name": "Pizza Brutta",
|
32
|
+
"review_count": 422,
|
33
|
+
"rating": 4.5,
|
34
|
+
"coordinates": {
|
35
|
+
"latitude": 43.06512,
|
36
|
+
"longitude": -89.41629
|
37
|
+
},
|
38
|
+
"location": {
|
39
|
+
"display_address": [
|
40
|
+
"1805 Monroe St",
|
41
|
+
"Madison, WI 53711"
|
42
|
+
]
|
43
|
+
},
|
44
|
+
"display_phone": "(608) 257-2120"
|
45
|
+
}
|
46
|
+
|
47
|
+
There are already two fields in each record. The fields match what the Google Maps component expects
|
48
|
+
for its store:
|
49
|
+
|
50
|
+
- _title_, which is mapped to _name_
|
51
|
+
- _position_, which uses a `calculate` to create a object with _lat_ and _lng_
|
52
|
+
|
53
|
+
We need four more values: _address_, _telephone_, _rating_, and _reviews_.
|
54
|
+
|
55
|
+
Some of those map directly to their value in the feed, some need a `mapping` config.
|
56
|
+
|
57
|
+
Showing `address` is a little trickier. We have two choices: we can configure a `calculate`
|
58
|
+
in the store model's `fields[]`, or code a table column renderer to get the value.
|
59
|
+
|
60
|
+
We'll try both techniques.
|
61
|
+
|
62
|
+
??Add field definitions
|
63
|
+
|
64
|
+
Edit the main view model `businesses` store config and add four fields:
|
65
|
+
|
66
|
+
- _reviews_, which is mapped to _review_count_
|
67
|
+
- _rating_
|
68
|
+
- _phone_, which is mapped to _display_phone_
|
69
|
+
- _address_, which is mapped to _location.display_address_
|
70
|
+
|
71
|
+
We aren't using these in the table yet, but you can still verify that the store
|
72
|
+
is getting the right data by getting a reference to the map and looking at its
|
73
|
+
store items.
|
74
|
+
|
75
|
+
Neo.findFirst({ntype:'googlemaps'}).markerStore.items
|
76
|
+
|
77
|
+
Each item should six properties that look like this:
|
78
|
+
|
79
|
+
{
|
80
|
+
"title": "Pizza Brutta",
|
81
|
+
"position": {
|
82
|
+
"lat": 43.06512,
|
83
|
+
"lng": -89.41629
|
84
|
+
},
|
85
|
+
"reviews": 422,
|
86
|
+
"rating": 4.5,
|
87
|
+
"telephone": "(608) 257-2120",
|
88
|
+
"address": [
|
89
|
+
"1805 Monroe St",
|
90
|
+
"Madison, WI 53711"
|
91
|
+
],
|
92
|
+
"id": -1
|
93
|
+
}
|
94
|
+
|
95
|
+
??Continue to configure the table
|
96
|
+
|
97
|
+
Edit `yelp/view/businesses/Tabs.mjs` and add a `dataField` config for each column using
|
98
|
+
the corresponding value specified in store's `fields:[]`.
|
99
|
+
|
100
|
+
Also specify `align:'right'` for ratings and review count.
|
101
|
+
|
102
|
+
Of course, we won't see anything until you bind the table to the store. Configure the
|
103
|
+
binding. This is the same as the map binding, except table has a _store_ rather than
|
104
|
+
a _markerStore_.
|
105
|
+
|
106
|
+
Save and refresh, and you should see data in the store. If you change the city or category
|
107
|
+
the table should update accordingly.
|
108
|
+
|
109
|
+
??Use renderers
|
110
|
+
|
111
|
+
We need some renderers.
|
112
|
+
|
113
|
+
Configure a renderer for the address.
|
114
|
+
|
115
|
+
renderer: data => data.value.join(', ')
|
116
|
+
|
117
|
+
Configure a renderer for the review count.
|
118
|
+
|
119
|
+
renderer: data => new Intl.NumberFormat().format(data.value)
|
120
|
+
|
121
|
+
Configure a renderer for the rating.
|
122
|
+
|
123
|
+
renderer: data => new Intl.NumberFormat('en-US', {minimumFractionDigits: 1})
|
124
|
+
.format(data.value)
|
125
|
+
|
126
|
+
Save, refresh and try it out. You should see the renderers being used.
|
127
|
+
|
128
|
+
??Use a calculated value in the store
|
129
|
+
|
130
|
+
Go back to the main view model and modify the _address_ field config to use a `calculate`.
|
131
|
+
|
132
|
+
calculate: (record, field, data) => data.location.display_address.join(', ')
|
133
|
+
|
134
|
+
Then remove the `renderer` from the table.
|
135
|
+
|
136
|
+
??Calculating store values versus table renderers
|
137
|
+
|
138
|
+
Is it better to calculate values as you populate a store, or is it better
|
139
|
+
to user renderer functions to do the calculation?
|
140
|
+
|
141
|
+
Ideally, you want good data-view separation. In other words, you create your data stuctures
|
142
|
+
to use sensible primitive values, then have the UI display those in ways that makes sense
|
143
|
+
for a given part of the UI. That may mean formatting values.
|
144
|
+
|
145
|
+
Dates are a good example: stores will hold dates, but you don't want to store date strings,
|
146
|
+
because the view will decide how to format a date for that particular part of the UI. The
|
147
|
+
same holds for numbers, which may or may not be displayed with thousands separators, etc.
|
148
|
+
|
149
|
+
In the case of the address — which Yelp provides as an array of address parts — it's a
|
150
|
+
toss-up. An array of address parts seems more primitive and flexible, so maybe it's
|
151
|
+
preferable to have the view provide the renderer. But maybe not!
|
152
|
+
|
153
|
+
|
@@ -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,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 — the item fills the entire container.
|
@@ -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_ — items at the top
|
10
|
+
- _center_ — items at the top-to-bottom middle
|
11
|
+
- _end_ — items at the end
|
12
|
+
|
13
|
+
The _align_ config specifies how items are justified on the minor
|
14
|
+
axis.
|
15
|
+
- _start_ — items are left justified
|
16
|
+
- _center_ — items ae center justified
|
17
|
+
- _end_ — items are right justified
|
18
|
+
- _stretch_ — items take up the full width
|
@@ -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.
|