| OLD | NEW |
| 1 Sky Framework | 1 Sky Framework |
| 2 ============= | 2 ============= |
| 3 | 3 |
| 4 Effen is a functional-reactive framework for Sky which takes inspiration from | 4 Effen is a functional-reactive framework for Sky which takes inspiration from |
| 5 [React](http://facebook.github.io/react/). Effen is comprised of three main | 5 [React](http://facebook.github.io/react/). Effen is comprised of three main |
| 6 parts: a virtual-dom and diffing engine, a component mechanism and a very early | 6 parts: a virtual-dom and diffing engine, a component mechanism and a very early |
| 7 set of widgets for use in creating applications. | 7 set of widgets for use in creating applications. |
| 8 | 8 |
| 9 The central idea is that you build your UI out of components. Components | 9 The central idea is that you build your UI out of components. Components |
| 10 describe what their view should look like given their current configuration & | 10 describe what their view should look like given their current configuration & |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 new HelloWorldApp(); | 26 new HelloWorldApp(); |
| 27 } | 27 } |
| 28 </script> | 28 </script> |
| 29 ``` | 29 ``` |
| 30 | 30 |
| 31 ```dart | 31 ```dart |
| 32 // In hello_world.dart | 32 // In hello_world.dart |
| 33 import 'package:sky/framework/fn.dart'; | 33 import 'package:sky/framework/fn.dart'; |
| 34 | 34 |
| 35 class HelloWorldApp extends App { | 35 class HelloWorldApp extends App { |
| 36 Node build() { | 36 UINode build() { |
| 37 return new Text('Hello, world!'); | 37 return new Text('Hello, world!'); |
| 38 } | 38 } |
| 39 } | 39 } |
| 40 ``` | 40 ``` |
| 41 | 41 |
| 42 An app is comprised of (and is, itself, a) components. A component's main job is | 42 An app is comprised of (and is, itself, a) components. A component's main job is |
| 43 to implement `Node build()`. The idea here is that the `build` method describes | 43 to implement `UINode build()`. The idea here is that the `build` method describe
s |
| 44 the DOM of a component at any given point during its lifetime. In this case, our | 44 the DOM of a component at any given point during its lifetime. In this case, our |
| 45 `HelloWorldApp`'s `build` method just returns a `Text` node which displays the | 45 `HelloWorldApp`'s `build` method just returns a `Text` node which displays the |
| 46 obligatory line of text. | 46 obligatory line of text. |
| 47 | 47 |
| 48 Nodes | 48 Nodes |
| 49 ----- | 49 ----- |
| 50 | 50 |
| 51 A component's `build` method must return a single `Node` which *may* have | 51 A component's `build` method must return a single `UINode` which *may* have |
| 52 children (and so on, forming a *subtree*). Effen comes with a few built-in nodes | 52 children (and so on, forming a *subtree*). Effen comes with a few built-in nodes |
| 53 which mirror the built-in nodes/elements of sky: `Text`, `Anchor` (`<a />`, | 53 which mirror the built-in nodes/elements of sky: `Text`, `Anchor` (`<a />`, |
| 54 `Image` (`<img />`) and `Container` (`<div />`). `build` can return a tree of | 54 `Image` (`<img />`) and `Container` (`<div />`). `build` can return a tree of |
| 55 Nodes comprised of any of these nodes and plus any other imported object which | 55 Nodes comprised of any of these nodes and plus any other imported object which |
| 56 extends `Component`. | 56 extends `Component`. |
| 57 | 57 |
| 58 How to structure you app | 58 How to structure you app |
| 59 ------------------------ | 59 ------------------------ |
| 60 | 60 |
| 61 If you're familiar with React, the basic idea is the same: Application data | 61 If you're familiar with React, the basic idea is the same: Application data |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 In many cases, nodes don't require a key because there is only one type amongst | 139 In many cases, nodes don't require a key because there is only one type amongst |
| 140 its siblings -- but if there is more one, you must assign each a key. This is | 140 its siblings -- but if there is more one, you must assign each a key. This is |
| 141 why most nodes will take `({ Object key })` as an optional constructor | 141 why most nodes will take `({ Object key })` as an optional constructor |
| 142 parameter. In development mode (i.e. when sky is built `Debug`) Effen will throw | 142 parameter. In development mode (i.e. when sky is built `Debug`) Effen will throw |
| 143 an error if you forget to do this. | 143 an error if you forget to do this. |
| 144 | 144 |
| 145 Event Handling | 145 Event Handling |
| 146 -------------- | 146 -------------- |
| 147 | 147 |
| 148 Events logically fire through the Effen node tree. If want to handle an event as | 148 Events logically fire through the Effen node tree. If want to handle an event as |
| 149 it bubbles from the target to the root, create an `EventTarget`. `EventTarget` | 149 it bubbles from the target to the root, create an `EventListenerNode`. `EventLis
tenerNode` |
| 150 has named (typed) parameters for a small set of events that we've hit so far, as | 150 has named (typed) parameters for a small set of events that we've hit so far, as |
| 151 well as a 'custom' argument which is a `Map<String, sky.EventListener>`. If | 151 well as a 'custom' argument which is a `Map<String, sky.EventListener>`. If |
| 152 you'd like to add a type argument for an event, just post a patch. | 152 you'd like to add a type argument for an event, just post a patch. |
| 153 | 153 |
| 154 ```dart | 154 ```dart |
| 155 class MyComp extends Component { | 155 class MyComp extends Component { |
| 156 MyComp({ | 156 MyComp({ |
| 157 Object key | 157 Object key |
| 158 }) : super(key: key); | 158 }) : super(key: key); |
| 159 | 159 |
| 160 void _handleTap(sky.GestureEvent e) { | 160 void _handleTap(sky.GestureEvent e) { |
| 161 // do stuff | 161 // do stuff |
| 162 } | 162 } |
| 163 | 163 |
| 164 void _customEventCallback(sky.Event e) { | 164 void _customEventCallback(sky.Event e) { |
| 165 // do other stuff | 165 // do other stuff |
| 166 } | 166 } |
| 167 | 167 |
| 168 Node build() { | 168 UINode build() { |
| 169 new EventTarget( | 169 new EventListenerNode( |
| 170 new Container( | 170 new Container( |
| 171 children: // ... | 171 children: // ... |
| 172 ), | 172 ), |
| 173 onGestureTap: _handleTap, | 173 onGestureTap: _handleTap, |
| 174 custom: { | 174 custom: { |
| 175 'myCustomEvent': _customEventCallback | 175 'myCustomEvent': _customEventCallback |
| 176 } | 176 } |
| 177 ); | 177 ); |
| 178 } | 178 } |
| 179 | 179 |
| 180 _handleScroll(sky.Event e) { | 180 _handleScroll(sky.Event e) { |
| 181 setState(() { | 181 setState(() { |
| 182 // update the scroll position | 182 // update the scroll position |
| 183 }); | 183 }); |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 ``` | 186 ``` |
| 187 | 187 |
| 188 Styling | 188 Styling |
| 189 ------- | 189 ------- |
| 190 | 190 |
| 191 Styling is the part of Effen which is least designed and is likely to change. | 191 Styling is the part of Effen which is least designed and is likely to change. |
| 192 There are two ways to specify styles: | 192 There are three ways to specify styles: |
| 193 | 193 |
| 194 * `Style` objects which are interned and can be applied to Elements via the | 194 * `Style` objects which are interned and can be applied to WrapperNodes via th
e |
| 195 ``style` constructor parameter. Use `Style` objects for styles which are | 195 ``style` constructor parameter. Use `Style` objects for styles which are |
| 196 `*not* animated. | 196 `*not* animated. |
| 197 | 197 |
| 198 * An `inlineStyle` string which can be applied to Elements via the | 198 * An `inlineStyle` string which can be applied to Elements via the |
| 199 `inlineStyle` constructor parameter. Use `inlineStyle` for styles which | 199 `inlineStyle` constructor parameter. Use `inlineStyle` for styles which |
| 200 *are* animated. | 200 *are* animated. |
| 201 | 201 |
| 202 If you need to apply a Style to a Component or Node which you didn't construct | 202 If you need to apply a Style to a Component or UINode which you didn't construct |
| 203 (i.e. one that was handed into your constructor), you can wrap it in a | 203 (i.e. one that was handed into your constructor), you can wrap it in a |
| 204 `StyleNode` which also takes a `Style` constructor in it's `style` constructor | 204 `StyleNode` which also takes a `Style` constructor in it's `style` constructor |
| 205 parameter. | 205 parameter. |
| 206 | 206 |
| 207 Animation | 207 Animation |
| 208 --------- | 208 --------- |
| 209 | 209 |
| 210 Animation is still an area of exploration. Have a look at | 210 Animation is still an area of exploration. Have a look at |
| 211 [AnimatedComponent](components/animated_component.dart) and | 211 [AnimatedComponent](components/animated_component.dart) and |
| 212 [Drawer](components/drawer.dart) for an example of this this currently works. | 212 [Drawer](components/drawer.dart) for an example of this this currently works. |
| 213 | 213 |
| 214 Performance | 214 Performance |
| 215 ----------- | 215 ----------- |
| 216 | 216 |
| 217 It is a design goal that it should be *possible* to arrange that all "build" | 217 It is a design goal that it should be *possible* to arrange that all "build" |
| 218 cycles which happen during animations can complete in less than one milliesecond | 218 cycles which happen during animations can complete in less than one milliesecond |
| 219 on a Nexus 5. | 219 on a Nexus 5. |
| OLD | NEW |