@lightningjs/blits 1.22.0 → 1.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.github/workflows/run-blits-tests.yml +69 -0
  2. package/CHANGELOG.md +22 -0
  3. package/README.md +1 -1
  4. package/docs/README.md +1 -2
  5. package/docs/built-in/directives.md +1 -1
  6. package/docs/built-in/for-loop.md +8 -8
  7. package/docs/built-in/layout.md +23 -23
  8. package/docs/components/user_input.md +3 -3
  9. package/docs/components/utility_methods.md +11 -7
  10. package/docs/essentials/displaying_images.md +3 -3
  11. package/docs/essentials/displaying_text.md +3 -3
  12. package/docs/essentials/element_attributes.md +3 -3
  13. package/docs/essentials/template_syntax.md +1 -1
  14. package/docs/getting_started/intro.md +1 -1
  15. package/docs/plugins/global_app_state.md +2 -2
  16. package/docs/plugins/language.md +2 -2
  17. package/docs/plugins/theme.md +1 -1
  18. package/docs/router/basics.md +4 -4
  19. package/docs/router/hooks.md +1 -1
  20. package/docs/transitions_animations/transitions.md +2 -2
  21. package/index.d.ts +37 -1
  22. package/package.json +2 -2
  23. package/src/component/base/index.js +3 -1
  24. package/src/component/setup/index.js +4 -3
  25. package/src/component/setup/routes.js +6 -1
  26. package/src/component.js +24 -7
  27. package/src/component.test.js +6 -5
  28. package/src/components/Circle.js +1 -1
  29. package/src/components/FPScounter.js +1 -1
  30. package/src/components/RouterView.js +1 -1
  31. package/src/components/Sprite.js +1 -1
  32. package/src/lib/codegenerator/generator.js +61 -8
  33. package/src/lib/codegenerator/generator.test.js +1089 -167
  34. package/src/lib/eventListeners.js +3 -3
  35. package/src/lib/precompiler/precompiler.js +2 -3
  36. package/src/lib/reactivity/effect.js +5 -5
  37. package/src/lib/reactivity/reactive.js +1 -0
  38. package/src/lib/reactivityguard/computedprops.js +218 -0
  39. package/src/lib/symbols.js +1 -0
  40. package/src/router/router.js +28 -6
  41. package/vite/index.js +3 -1
  42. package/vite/preCompiler.js +1 -1
  43. package/vite/reactivityGuard.js +45 -0
@@ -0,0 +1,69 @@
1
+ name: Run Blits Tests
2
+
3
+ on:
4
+ pull_request_target:
5
+ branches:
6
+ - dev
7
+
8
+ jobs:
9
+ run-blits-tests:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout Code
14
+ uses: actions/checkout@v3
15
+
16
+ - name: Set up Node.js
17
+ uses: actions/setup-node@v3
18
+ with:
19
+ node-version: 20.16.0
20
+
21
+ - name: Install Dependencies
22
+ run: npm install
23
+
24
+ - name: Run Tests
25
+ run: npm run test > test-report.txt
26
+ #To ensure subsequent steps run even if tests fail
27
+ continue-on-error: true
28
+
29
+ - name: Get Current Timestamp
30
+ id: timestamp
31
+ run: echo "timestamp=$(date)" >> $GITHUB_OUTPUT
32
+
33
+ - name: Extract Test Summary
34
+ id: extracted-test-summary
35
+ run: |
36
+ # Search for a line containing both "passed:" and "failed:"
37
+ summary=$(grep -E "passed:.*failed:" test-report.txt | head -n1)
38
+
39
+ # Extract the number of failed tests
40
+ failed=$(echo "$summary" | sed -E 's/.*failed:\s*([0-9]+).*/\1/')
41
+
42
+ echo "summary=$summary" >> $GITHUB_OUTPUT
43
+
44
+ # If the number of failed tests is greater than 1, exit with error.
45
+ if [ "$failed" -gt 1 ]; then
46
+ exit 1
47
+ fi
48
+
49
+ - name: Post Test Results as PR Comment
50
+ if: always()
51
+ uses: actions/github-script@v6
52
+ env:
53
+ SUMMARY: ${{ steps.extracted-test-summary.outputs.summary }}
54
+ TIMESTAMP: ${{ steps.timestamp.outputs.timestamp }}
55
+ with:
56
+ script: |
57
+ github.rest.issues.createComment({
58
+ owner: context.repo.owner,
59
+ repo: context.repo.repo,
60
+ issue_number: context.issue.number,
61
+ body: `**Test Results Summary:** (Ran at: ${process.env.TIMESTAMP})\n${process.env.SUMMARY}`
62
+ });
63
+
64
+ - name: Upload Test Report Artifact
65
+ if: always()
66
+ uses: actions/upload-artifact@v4
67
+ with:
68
+ name: test-report
69
+ path: test-report.txt
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.23.1
4
+
5
+ _17 mar 2025_
6
+
7
+ - Fixed issue in vite plugin that ensures reacitivity setup in computed props when code block has a comment
8
+ - Fixed warnings for non-declared variables in template when they refer to plugins (i.e. `$$apState.foo`)
9
+
10
+ ## v1.23.0
11
+
12
+ _13 mar 2025_
13
+
14
+ - Added support for beforeEach router hook
15
+ - Added warning when variables used in the template are not declared on the component scope (only during dev)
16
+ - Added vite plugin that ensures reactivity is setup properly for all state variables in a computed prop
17
+ - Fixed keepAlive functionality in the router on back navigation
18
+ - Fixed various test cases
19
+ - Added useful base methods to the this context of plugins
20
+ - Added workflow to execute test cases for PRs
21
+ - Updated L3 renderer dependency to v2.13.2
22
+ - Fixed various typos in the documentation
23
+ - Fixed reactivity issue when value is set to `null`
24
+
3
25
  ## v1.22.0
4
26
 
5
27
  _3 mar 2025_
package/README.md CHANGED
@@ -16,7 +16,7 @@ You may be wondering where the name Blits comes from?
16
16
 
17
17
  Firstly, it's short, memorable and just has a nice ring to it.
18
18
 
19
- "Blits" is a Dutch word (a significant portion of the Lightning Open Source teams is based in the Netherlands). It means _flashy_ and it's often used to for things that are _great_ or _cool_.
19
+ "Blits" is a Dutch word (a significant portion of the Lightning Open Source team is based in the Netherlands). It means _flashy_ and it's often used for things that are _great_ or _cool_.
20
20
 
21
21
  Finally it's a nerdy reference to the computer term "Bit Blits" commonly used in graphics processing, for rapidly moving a block of data into memory - quite similar to what Lightning is doing 🙂
22
22
 
package/docs/README.md CHANGED
@@ -14,7 +14,6 @@ You may be wondering where the name Blits comes from?
14
14
 
15
15
  Firstly, it's short, memorable and just has a nice ring to it.
16
16
 
17
- "Blits" is a Dutch word (a significant portion of the Lightning Open Source teams is based in the Netherlands). It means _flashy_ and it's often used to for things that are _great_ or _cool_.
17
+ "Blits" is a Dutch word (a significant portion of the Lightning Open Source team is based in the Netherlands). It means _flashy_ and it's often used for things that are _great_ or _cool_.
18
18
 
19
19
  Finally it's a nerdy reference to the computer term "Bit Blits" commonly used in graphics processing, for rapidly moving a block of data into memory - quite similar to what Lightning is doing 🙂
20
-
@@ -41,7 +41,7 @@ At the moment it's not possible to use the `is`-attribute as a _reactive_ attrib
41
41
 
42
42
  The declarative coding style that is promoted in Blits components, should generally remove the need to directly interact with individual Elements or Components in your template. However, in some cases you may need to reference them directly. For example, in order to delegate the focus.
43
43
 
44
- For this use case, you can specify a `ref`-attribute on Elements (or Components). And by using the helper function `this.select()`, which is vailable on every Blits component, you can gain access to the child Element or Component inside your business logic.
44
+ For this use case, you can specify a `ref`-attribute on Elements (or Components). And by using the helper function `this.select()`, which is available on every Blits component, you can gain access to the child Element or Component inside your business logic.
45
45
 
46
46
  The `select()`-function accepts the `ref`-value that you are looking for as a single argument, and returns the Element or Component if found.
47
47
 
@@ -1,10 +1,10 @@
1
1
  # For loop
2
2
 
3
- The for loop is technically also a [directive](../directives.md), but such an important one that it deserves it's own section.
3
+ The for loop is technically also a [directive](../directives.md), but such an important one that it deserves its own section.
4
4
 
5
5
  The for loop directive can be used when you want to repeat multiple instances of an Element or a Component, without having to specify them hardcoded one by one in your template.
6
6
 
7
- The for loop take an `Array` of data, loops over it and for each Array-item an Element or Component is created. The `Array` can be a fixed one, but it' can also dynamically be filled or modified and have it's changes reflect in the rendered result.
7
+ The for loop takes an `Array` of data, loops over it and for each Array-item an Element or Component is created. The `Array` can be a fixed one, but it can also dynamically be filled or modified and have it's changes reflect in the rendered result.
8
8
 
9
9
  > Important: the for loop is a powerful and often used directive. Within Blits it's optimized to be as performant as possible. But if used incorrectly, it can be the cause of slow performance. So please read carefully through this entire section.
10
10
 
@@ -33,9 +33,9 @@ The example above will generate 3 _lime green_ elements, based on the array of `
33
33
 
34
34
  ## Using the index
35
35
 
36
- In order to fix the example above and make all 3 elements visible, we can use the `index` of the Array, to position each item correctly.
36
+ In order to fix the example above and make all 3 elements visible, we can use the `index` of the Array to position each item correctly.
37
37
 
38
- All we need to do is declare the `index` in the `for`-directive and subsequently use it in the the `x`-attribute, with a simple calculation.
38
+ All we need to do is declare the `index` in the `for`-directive and subsequently use it in the `x`-attribute, with a simple calculation.
39
39
 
40
40
  You may choose any name for the `index` variable (like `i` or `forIndex`). This may be useful when you already have the `index`-key specified as a `state` or `prop` variable on your component, causing a conflict.
41
41
 
@@ -95,13 +95,13 @@ export default Blits.Component('ForLoop', {
95
95
  })
96
96
  ```
97
97
 
98
- This will generate 3 squares aligned next to each other, each with a differrent color and they will use the _alpha_ specific in the Component state.
98
+ This will generate 3 squares aligned next to each other, each with a different color and they will use the _alpha_ specific in the Component state.
99
99
 
100
100
  ## The importance of using the key attribute
101
101
 
102
102
  The examples above have demonstrated the basic usage of the for-loop. But they are all missing one _very important_ ingredient to make sure that for-loops that are subject to change, continue to perform well. Meet the `key`-attribute.
103
103
 
104
- For perfomance reasons, it is essential to be able track the _identity_ of an Element or Component, whenever changes are made to the Array in the for loop.
104
+ For performance reasons, it is essential to be able track the _identity_ of an Element or Component, whenever changes are made to the Array in the for loop.
105
105
 
106
106
  Think of _identity_ as the field that makes an item in the Array unique, such as an `id` or a `hash`. It's basically the thing that allows you to distinguish between the poster of _The Matrix_ and the poster of _Frozen 2_, for example.
107
107
 
@@ -109,7 +109,7 @@ Providing this information, allows the for-loop to decide whether it should _upd
109
109
 
110
110
  Correctly using the `key`-attribute enables Blits to _reuse_ existing instances whenever possible - which obviously is good for performance.
111
111
 
112
- It's important that the `key`-attribute is _unique_ for each Array item. Also beware that we can't rely on the `index` parameter provided in for loop, because that only indentifies the position in the Array, and not the actual item itself.
112
+ It's important that the `key`-attribute is _unique_ for each Array item. Also beware that we can't rely on the `index` parameter provided in for loop, because that only identifies the position in the Array, and not the actual item itself.
113
113
 
114
114
 
115
115
  ```js
@@ -156,7 +156,7 @@ export default Blits.Component('ForLoop', {
156
156
 
157
157
  In the example above we have added the `key`-attribute in the template. Now whenever we push a new item to the `items`-array, the for-loop will reuse the Elements previously created and only instantiate a new Element for the newly added item.
158
158
 
159
- If we would ommit the `key`-attribute, then whenever we push a new item to the Array, the for-loop would dispose all the old Elements and create new instances for _each_ item in the array.
159
+ If we would omit the `key`-attribute, then whenever we push a new item to the Array, the for-loop would dispose all the old Elements and create new instances for _each_ item in the array.
160
160
 
161
161
  ## Referencing elements in the for loop
162
162
 
@@ -1,22 +1,22 @@
1
1
  # Layout
2
2
 
3
- A big portion of building a pixel perfect App is all about correctly positioning Elements and Components on screen. In Lightning and Blits _absolute_ positions are used. This fits the whole concept of building a TV app where the viewport dimensions are known and fixed. Absolute positioning (versus spacing Elements relative to each other) is also more performant.
3
+ A big portion of building a pixel-perfect App is all about correctly positioning Elements and Components on the screen. In Lightning and Blits, _absolute_ positions are used. This fits the whole concept of building a TV app where the viewport dimensions are known and fixed. Absolute positioning (versus spacing Elements relative to each other) is also more performant.
4
4
 
5
- Imagine a complex design with several nested layers. Relying solely on _relative_ positioning and elements automatically floating as space is available, may lead to heavy and recursive calculations. Then throw some dynamically changing dimensions and animations in the mix as well, and your App may be starting to noticeably drop frames due to expensive re-calculations.
5
+ Imagine a complex design with several nested layers. Relying solely on _relative_ positioning and elements automatically floating as space is available may lead to heavy and recursive calculations. Then throw some dynamically changing dimensions and animations in the mix as well, and your App may be starting to noticeably drop frames due to expensive re-calculations.
6
6
 
7
7
  That being said, there are often cases where it becomes very cumbersome to calculate all the positions manually. Especially when dimensions are not known in advance and elements may load asynchronously.
8
8
 
9
9
  If you come from a CSS background, you may be tempted to say: "_this is why we have Flexbox!_". And while Flexbox is great and versatile in CSS and running on a powerful device, a full flexbox implementation does come at a cost and the risk of slowing down your App, when applied extensively or incorrectly.
10
10
 
11
- In order to address the core problem "_how do I easily position a bunch of Elements and Components, without writing a lot of code with `@loaded` event handlers_", Blits offers the built-in `<Layout>`-component - a basic and performant solution that automatically puts your Elements in the right place.
11
+ In order to address the core problem of "_how do I easily position a bunch of Elements and Components without writing a lot of code with `@loaded` event handlers_", Blits offers the built-in `<Layout>` component - a basic and performant solution that automatically puts your Elements in the right place.
12
12
 
13
13
  ## How to use
14
14
 
15
- Since the Layout-component is a built-in component, there is no need to register it separately. You can use the `<Layout>`-tag anywhere in your templates, just as you would use `<Element>` and `<Text>`.
15
+ Since the Layout component is a built-in component, there is no need to register it separately. You can use the `<Layout>` tag anywhere in your templates, just as you would use `<Element>` and `<Text>`.
16
16
 
17
- The Layout component is a wrapper component, that encloses a number of children. All the direct children that are wrapped in a `<Layout>`-tag are automatically positioned in order, one next to the other.
17
+ The Layout component is a wrapper component that encloses a number of children. All direct children wrapped in a `<Layout>` tag are automatically positioned in order, one next to the other.
18
18
 
19
- Whenever the dimensions of a child change, the positioning of the next children is automatically recalculated and re-applied.
19
+ Whenever dimensions of a child change, the positioning of the next children is automatically recalculated and reapplied.
20
20
 
21
21
  ```xml
22
22
  <Layout>
@@ -29,31 +29,31 @@ Whenever the dimensions of a child change, the positioning of the next children
29
29
 
30
30
  ### Horizontal and vertical layout
31
31
 
32
- By default the Layout component lays out it's contents _horizontally_. The Layout component accepts a `direction` attribute which allows you to control the direction.
32
+ By default, the Layout component lays out its contents _horizontally_. The Layout component accepts a `direction` attribute that allows you to control the direction.
33
33
 
34
- In order to align vertically use `<Layout direction="vertical"></Layout>`. And use `<Layout direction="horizontal"></Layout>` to explicitly apply the default horizontal layout.
34
+ In order to align vertically, use `<Layout direction="vertical"></Layout>`. And use `<Layout direction="horizontal"></Layout>` to explicitly apply the default horizontal layout.
35
35
 
36
36
  ### Spacing between children
37
37
 
38
- By default the Layout-component places each Element directly besides (or below) the previous one. By adding the `gap`-attribute you can control how much space will be added between each Element or Component. The `gap`-attribute accepts a number in pixels.
38
+ By default, the Layout-component places each Element directly besides (or below) the previous one. By adding the `gap`-attribute, you can control how much space will be added between each Element or Component. The `gap`-attribute accepts a number in pixels.
39
39
 
40
40
  ### Aligning items
41
41
 
42
- The layout component positions its children based on the provided direction (`horizontal` or `vertical`). With the `align-items`-attribute you can specify how to align the children on the opposite axis:
42
+ The layout component positions its children based on the provided direction (`horizontal` or `vertical`). With the `align-items`-attribute, you can specify how to align the children on the opposite axis:
43
43
 
44
- - `start` (the default value) - aligns the children in the _top_ for horizontal layouts, and on the _left_ for vertical layouts
44
+ - `start` (the default value) - aligns the children at the _top_ for horizontal layouts and on the _left_ for vertical layouts
45
45
  - `center` - align the children in the center
46
46
  - `end` - aligns the children in the _bottom_ for horizontal layouts, and on the _right_ for vertical layouts
47
47
 
48
48
  ### Dynamic dimensions
49
49
 
50
- For the Layout component to work properly, the direct children all need to have dimensions (i.e `w` and `h` attributes). The exception here being Text elements.
50
+ For the Layout component to work properly, all direct children need to have dimensions (i.e., `w` and `h` attributes). The exception here being Text elements.
51
51
 
52
- Due to the asynchronous nature of rendering text, the final text dimensions are not known beforehand. The width and height of Text elements are automatically set when the text has been loaded. This fires a `@loaded` event, that you can tap into as described [here](../essentials/displaying_text#text-dimensions).
52
+ Due to the asynchronous nature of rendering text, the final text dimensions are not known beforehand. The width and height of Text elements are automatically set when the text has been loaded. This fires a `@loaded` event that you can tap into as described [here](../essentials/displaying_text#text-dimensions).
53
53
 
54
- The Layout component also uses this event, to execute its calculation and position the text and other elements around it properly.
54
+ The Layout component also uses this event to execute its calculation and properly position the text and other elements around it.
55
55
 
56
- When the children of the Layout-component have _reactive_ dimensions (i.e. `<Element :w="$mywidth" :h="$myheight" />), the Layout component ensures that all child elements are properly re-positioned whenever a dimension changes.
56
+ When the children of the Layout-component have _reactive_ dimensions (i.e., `<Element :w="$mywidth" :h="$myheight" />`), the Layout component ensures that all child elements are properly repositioned whenever a dimension changes.
57
57
 
58
58
  ### Components inside a Layout
59
59
 
@@ -85,11 +85,11 @@ export default Blits.Component('MyButton', {
85
85
  }
86
86
  })
87
87
  ```
88
- At this moment Blits does not have support for automatically growing the dimensions of a Component based on it's contents, because of the performance impact that this functionality has.
88
+ At this moment, Blits does not support automatically growing a Component's dimensions based on its contents due to the performance impact of this functionality.
89
89
 
90
90
  ### Nesting Layouts
91
91
 
92
- It's also possible to nest layouts. Simply place a new `<Layout>`-tag, with it's own children in between the children of another Layout-component. The Layout-component itself will grow automatically with the dimensions of it's children. In other words, it's not required to specify a width (`w`) or height (`h`) on the `<Layout>`-tag itself.
92
+ It's also possible to nest layouts. Simply place a new `<Layout>`-tag, with it's own children in between the children of another Layout-component. The Layout component itself will grow automatically with the dimensions of its children. In other words, it's not required to specify a width (`w`) or height (`h`) on the `<Layout>` tag itself.
93
93
 
94
94
  And of course you can nest _vertical_ Layouts inside a _horizontal_ one - and vice versa.
95
95
 
@@ -123,7 +123,7 @@ The `<Layout>`-component can also take into account when dimensions of children
123
123
 
124
124
  ### Updated event
125
125
 
126
- The `<Layout>`-tag automatically updates its dimensions based on the dimensions of its children. After each update in the children, the an `updated`-event is emitted on the `<Layout>`-tag. It will receive the current dimensions of the layout.
126
+ The `<Layout>`-tag automatically updates its dimensions based on the dimensions of its children. After each update in the children, an `updated`-event is emitted on the `<Layout>`-tag. It will receive the current dimensions of the layout.
127
127
 
128
128
  You can tap into this event by adding an `@updated`-attribute to the `<Layout />`-tag and refer to a method in your Component logic.
129
129
 
@@ -151,18 +151,18 @@ export default Blits.Component('LayoutUpdate', {
151
151
 
152
152
  ## Performance
153
153
 
154
- The Layout-component is a very useful utility, that will make it a lot easier to put together complex layouts. It will reduce the code required, it means less hardcoding of values and removes the need to manually wire up `@loaded` events when working with dynamic / asynchronous elements.
154
+ The Layout component is a very useful utility that will make it a lot easier to put together complex layouts. It will reduce the code required, it means less hardcoding of values and removes the need to manually wire up `@loaded` events when working with dynamic / asynchronous elements.
155
155
 
156
- We've done our best to make the Component as performant as possible, by deliberately keeping it simple and straight forward. But it's important to understand that the Layout component does come at a cost. Depending on the use case these costs may be negligible, but there are cases where the Layout component might prove to be a bottle-neck.
156
+ We have done our best to make the Component as performant as possible by deliberately keeping it simple and straightforward. However, it is important to understand that the Layout component does come at a cost. Depending on the use case these costs may be negligible, but there are cases where the Layout component might prove to be a bottleneck.
157
157
 
158
- The performance costs may always be there to some degree. Whether it's the Layout component that does the complex calculations, or you do it in your custom code. So please feel encouraged to use the `<Layout>`-tag!
158
+ The performance costs may always be there to some degree. Whether it's the Layout component that does the complex calculations, or you do it in your custom code. So, please feel encouraged to use the `<Layout>` tag!
159
159
 
160
160
  Some pointers to keep in mind, though:
161
161
 
162
162
  - Every change in the dimensions of a child, triggers the Layout component to recalculate and reposition. If your child elements change frequently, the Layout component may have a performance impact.
163
163
 
164
- - The Layout component support transitions, but beware that when transitioning child dimensions a recalculation happens every frame-tick. If you see frame-drops in your App, you may want to see if the `<Layout>`-tag has an impact on this.
164
+ - The Layout component support transitions, but beware that when transitioning child dimensions a recalculation happens every frame tick. If you see frame-drops in your App, you may want to see if the `<Layout>`-tag has an impact on this.
165
165
 
166
166
  - Be mindful to not apply unnecessary deep nesting of Layout tags. Each change in a deep child, will trigger recalculations up the tree of Layout tags.
167
167
 
168
- - When using the `<Layout>`-tag with a for-loop, it may be more performant to use the `$index` of the for-loop and manually position the elements yourself (i.e. `<Element :for="(item, index) in $items" :$x="$item * 200" w="150" h="150" />`). Especially if the dimensions are know before hand and possibly are the same for each child.
168
+ - When using the `<Layout>`-tag with a for-loop, it may be more performant to use the `$index` of the for-loop and manually position the elements yourself (i.e. `<Element :for="(item, index) in $items" :$x="$item * 200" w="150" h="150" />`). Especially if the dimensions are known beforehand and possibly are the same for each child.
@@ -86,15 +86,15 @@ The `intercept`-method can also be an asynchronous method.
86
86
 
87
87
  The functions specified in the `input` configuration are invoked when a key is _pressed down_ (i.e. the `keydown` event listener). But sometimes you may also want to execute some logic when a key is _released_ (i.e. the `keyup` event listener).
88
88
 
89
- Instead of introducing a separate key on the Component configuration object for key release callbacks, Blits relies on the concept that a `keyup` event is always preceeded by a `keydown` event.
89
+ Instead of introducing a separate key on the Component configuration object for key release callbacks, Blits relies on the concept that a `keyup` event is always preceded by a `keydown` event.
90
90
 
91
91
  Following this logic, whenever you return a function in an input (key down) handler, this function will be executed upon release (i.e. the `keyup` event) of that key .
92
92
 
93
- When an input key is being a hold down, it will execute the key down handler multipe times. Upon key release, only the last returned key up callback function will be executed.
93
+ When an input key is being a hold down, it will execute the key down handler multiple times. Upon key release, only the last returned key up callback function will be executed.
94
94
 
95
95
 
96
96
  ```javascript
97
- Blits.Component('MyComponemnt', {
97
+ Blits.Component('MyComponent', {
98
98
  //
99
99
  input: {
100
100
  enter() {
@@ -267,13 +267,13 @@ export default Blits.Component('MyComponent', {
267
267
 
268
268
  Timeouts are a great way to execute recurring logic, such as polling for updates or periodically updating an animation.
269
269
 
270
- But simular to timeouts, intervals (more specifically failing to clear them) are a common source of memory leaks - maybe even more than dangling timeouts.
270
+ But similar to timeouts, intervals (more specifically failing to clear them) are a common source of memory leaks - maybe even more than dangling timeouts.
271
271
 
272
272
  For this reason Blits has 3 built-in utility methods to help registering and clearing intervals.
273
273
 
274
274
  ### $setInterval
275
275
 
276
- The `this.$setInterval()`-method create an interval, using a thin wrapper around the `window.setInterval()` method. The first argument is the `callback` to be executed after each interval `delay` specified in the second argument. The method returns an `interval id`, which can be used to mannually clear the interval.
276
+ The `this.$setInterval()`-method create an interval, using a thin wrapper around the `window.setInterval()` method. The first argument is the `callback` to be executed after each interval `delay` specified in the second argument. The method returns an `interval id`, which can be used to manually clear the interval.
277
277
 
278
278
  ### $clearInterval
279
279
 
@@ -287,18 +287,22 @@ The `this.$clearIntervals()`-method is a utility method that is used to clear al
287
287
  ```js
288
288
  export default Blits.Component('MyComponent', {
289
289
  state() {
290
- interval: null,
291
- secondCount: 0,
292
- minuteCount: 0,
290
+ return {
291
+ interval: null,
292
+ secondCount: 0,
293
+ minuteCount: 0,
294
+ }
293
295
  },
294
296
  hooks: {
295
297
  init() {
296
298
  this.interval = this.$setInterval(() => {
297
- console.log(`${secondCount} second(s) have passed`)
299
+ this.secondCount++
300
+ console.log(`${this.secondCount} second(s) have passed`)
298
301
  }, 1000)
299
302
 
300
303
  this.$setInterval(() => {
301
- console.log(`${minuteCount} minute(s) have passed`)
304
+ this.minuteCount++
305
+ console.log(`${this.minuteCount} minute(s) have passed`)
302
306
  }, 60000)
303
307
  },
304
308
  unfocus() {
@@ -2,7 +2,7 @@
2
2
 
3
3
  Now that we've covered the basics of creating Elements, as well as styling and positioning them, it's time to move away from these boring rectangles and explore how you can incorporate _images_ into your App.
4
4
 
5
- In Blits is very easy to display an image. Simply add the `src` attribute to an Element, specifying the image's location.
5
+ In Blits, it is very easy to display an image. Simply add the `src` attribute to an Element, specifying the image's location.
6
6
 
7
7
  For local images, make sure to place them in the `public` folder of your App (e.g., `public/assets/background.jpg` or `public/images/logo.png`) and refer to them with a _relative_ path (but omitting the `public` folder as root).
8
8
 
@@ -15,7 +15,7 @@ Remote images are also supported and can be linked directly (e.g., `http://mycdn
15
15
 
16
16
  ## Sizing and Scaling
17
17
 
18
- Make sure to give your Element a width (`w` ) and a height (`h`) attribute. Images will _not_ be rendered if they don't have both attributes present. The Lightning renderer will scale the image to fit these exact dimensions
18
+ Make sure to give your Element a width (`w` ) and a height (`h`) attribute. Images will _not_ be rendered if they don't have both attributes present. The Lightning renderer will scale the image to fit these exact dimensions.
19
19
 
20
20
  For the best performance, it's important to keep your source images as small as possible. If you're displaying an image at `200px x 200px`, make sure the image is exactly that size or _smaller_. The latter option may lead to some quality loss, but can positively impact the overall performance of your App.
21
21
 
@@ -38,7 +38,7 @@ By default, all Elements with a `src` attribute get a solid white background, wi
38
38
 
39
39
  All images are loaded asynchronously (and can possibly fail to load), even those local to your App. Blits allows you to easily hook into the `loaded` and `error` events of image Elements.
40
40
 
41
- You can use this, for example, to only make something visible once an image is fully loaded. Or to display a fallback image when an remote image can't be retrieved.
41
+ You can use this, for example, to only make something visible once an image is fully loaded. Or to display a fallback image when a remote image can't be retrieved.
42
42
 
43
43
  ```xml
44
44
  <Element src="http://mycdn.com/lightning.jpg" @loaded="$revealPage" @error="$showFallback" />
@@ -34,7 +34,7 @@ The Text-tag accepts the following attributes:
34
34
 
35
35
  ## Text dimensions
36
36
 
37
- When you want to center your Text element, or properly position other Elements around your text, it is useful know the exact dimensions of your text.
37
+ When you want to center your Text element, or properly position other Elements around your text, it is useful to know the exact dimensions of your text.
38
38
 
39
39
  Similar to the Image element (i.e. an Element with a `src`), Text elements also accept the `@loaded` attribute. This event is called, as soon as the text is rendered, and passes in the dimensions of the generated text texture.
40
40
 
@@ -91,7 +91,7 @@ When you create a new Blits app using the available [getting started boilerplate
91
91
 
92
92
  But of course, you can also use any custom font that you want, to give your App the unique look and feel that fits with the design.
93
93
 
94
- Adding is custom font to a Blits App is quite straightforward. First, you'll need to place a `.ttf`, `.woff` or `.otf` version of your font in the `public` folder (i.e. `public/fonts/comic-sans.ttf`).
94
+ Adding a custom font to a Blits App is quite straightforward. First, you'll need to place a `.ttf`, `.woff` or `.otf` version of your font in the `public` folder (i.e. `public/fonts/comic-sans.ttf`).
95
95
 
96
96
  Then you'll need to register the custom font in the Launch settings of your app (in `src/index.js`). The `fonts`-key in the settings is an `Array` that specifies all available fonts in your App.
97
97
 
@@ -117,7 +117,7 @@ From this moment on you'll be able to use the font `ComicSans` anywhere in your
117
117
 
118
118
  ### Custom characters
119
119
 
120
- For MSDF font, a font atlas is created. By default this atlas includes all printable main ASCII characters. If you know before hand that you won't need certain characters, it would be more optimal to generate only those characters that are actually needed.
120
+ For MSDF font, a font atlas is created. By default this atlas includes all printable main ASCII characters. If you know beforehand that you won't need certain characters, it would be more optimal to generate only those characters that are actually needed.
121
121
 
122
122
  Similarly, if you need characters outside of the default set, like accents or other special characters, then these will need to be included in the generated font atlas.
123
123
 
@@ -43,9 +43,9 @@ In addition to the absolute positions that Blits and Lightning use, there are a
43
43
 
44
44
  On the `x`-axis the following _placement_ options can be used: `left` (default), `center` and `right`. On the `y`-axis the _placement_ attribute accepts `top` (default), `middle` and `bottom`.
45
45
 
46
- The _placement_ attribute also accepts and object with an `x` and a `y` key, to specify a placement for both axes.
46
+ The _placement_ attribute also accepts an object with an `x` and a `y` key, to specify a placement for both axes.
47
47
 
48
- The placement of an Element is calculated based on the dimensions of it's direct parent. This means that the containing Element _must_ have it's own dimensions (i.e. a `w` and a `h` attribute).
48
+ The placement of an Element is calculated based on the dimensions of its direct parent. This means that the containing Element _must_ have its own dimensions (i.e. a `w` and a `h` attribute).
49
49
 
50
50
  ```xml
51
51
  <Element w="300" h="300">
@@ -190,6 +190,6 @@ In the case where the `x` and `y` values are the same, you can also just supply
190
190
 
191
191
  By default contents inside an Element (i.e. child Elements) will overflow the boundaries of the parent, even when you give the parent Element fixed dimensions.
192
192
 
193
- In order to contain / cut off the content inside an Elements' `w` and `h`, you can add the `clipping="true"`-attribute. Setting `clipping` to `false` restores the default behaviour of content overflowing.
193
+ In order to contain / cut off the content inside an Element's `w` and `h`, you can add the `clipping="true"`-attribute. Setting `clipping` to `false` restores the default behaviour of content overflowing.
194
194
 
195
195
  Alternatively you can also use the `overflow`-attribute (and pass it `true` or `false`), which works similar to clipping just mapped inversly (i.e. `overflow="false"` ensures content that surpasses the parent dimensions is clipped-off).
@@ -4,7 +4,7 @@ Blits uses an easy-to-read _XML-style_ template syntax. The syntax is inspired b
4
4
 
5
5
  The `template` key in the _Component configuration object_ is used to specify a string with this XML-like template structure. Templates can often span multiple lines. In those cases, it's advisable to use `template literals` (enclosed by backticks).
6
6
 
7
- Similar to HTML you can use arguments and nested tags. Self-closing tags and HTML-style comments are also supported in Blits templates.
7
+ Similar to HTML, you can use arguments and nested tags. Self-closing tags and HTML-style comments are also supported in Blits templates.
8
8
 
9
9
  The default tag that can be used in templates is the `<Element>` tag. The Element tag corresponds to a node in the Lightning 3 renderer.
10
10
 
@@ -14,7 +14,7 @@ You may be wondering where the name Blits comes from.
14
14
 
15
15
  Firstly, it's short, memorable and just has a nice ring to it.
16
16
 
17
- "Blits" is a Dutch word (a significant portion of the Lightning Open Source teams is based in the Netherlands). It means _flashy_ and it's often used for things that are _great_ or _cool_.
17
+ "Blits" is a Dutch word (a significant portion of the Lightning Open Source team is based in the Netherlands). It means _flashy_ and it's often used for things that are _great_ or _cool_.
18
18
 
19
19
  Finally, it's a nerdy reference to the computer term "Bit Blits" commonly used in graphics processing, for rapidly moving a block of data into memory - quite similar to what Lightning is doing 🙂
20
20
 
@@ -44,7 +44,7 @@ Blits.Launch(App, 'app', {
44
44
 
45
45
  ### State object
46
46
 
47
- When registering the Global App State plugin, you pass it a state object as the second argument. This is a plain object literal that will be converted into a _reactive_ object, and is used to keep track the global state variables.
47
+ When registering the Global App State plugin, you pass it a state object as the second argument. This is a plain object literal that will be converted into a _reactive_ object, and is used to keep track of the global state variables.
48
48
 
49
49
  The newly created Global App state works exactly the same as an internal Component state. You can read values and you can directly change values. And when you do change a value, it automatically triggers reactive updates. Either via reactive attributes in the template, or in the form of watchers / computed values in the Component logic.
50
50
 
@@ -77,7 +77,7 @@ In order to read or update variables on the global app state inside the componen
77
77
 
78
78
  ### Watching global state
79
79
 
80
- Similar to component state, you can watch for changes in the global state as well. You can to refer to global state variables using _dot-notation_ in the watcher function name, and _prefixing_ it with `$appState`. This means that you need to define your watcher as a `String`, matching one of the examples below, depending on your style preference.
80
+ Similar to component state, you can watch for changes in the global state as well. You can refer to global state variables using _dot-notation_ in the watcher function name, and _prefixing_ it with `$appState`. This means that you need to define your watcher as a `String`, matching one of the examples below, depending on your style preference.
81
81
 
82
82
  ```js
83
83
  Blits.Component('MyComponent', {
@@ -39,7 +39,7 @@ The Language plugin accepts an optional configuration object with 2 keys:
39
39
  - `file` - the JSON file with translations to be loaded at initialization
40
40
  - `language` - the default language to use
41
41
 
42
- After registration of the Language plugin, it will be availabe in each Blits Component as `this.$language`.
42
+ After registration of the Language plugin, it will be available in each Blits Component as `this.$language`.
43
43
 
44
44
  ## Translations file
45
45
 
@@ -78,7 +78,7 @@ When the JSON file is specified in the Plugin registration method, the language
78
78
 
79
79
  In case you want to load the file with translations manually, you can use the `this.$language.load()`-method anywhere in a Component and pass in the path to the JSON file as the first argument.
80
80
 
81
- ## Defining translations manualy
81
+ ## Defining translations manually
82
82
 
83
83
  As an alternative to a JSON file with translations, you can also define translations directly via an object, using the `translations()`-method.
84
84
 
@@ -112,7 +112,7 @@ Blits.Plugin(theme, {
112
112
  ```
113
113
 
114
114
  In the definition above we've specified 3 different themes: `base`, `dark` and `large`. The dark and large theme are not complete definitions,
115
- which mean that they will inherit missing values from the base theme.
115
+ which means that they will inherit missing values from the base theme.
116
116
 
117
117
 
118
118
  ## Getting theme values
@@ -42,7 +42,7 @@ In this case `id` and `name` won't automatically be made available as props insi
42
42
 
43
43
  Sometimes you may actually want pass custom data into a Blits component, without it being part of the dynamic route path or `data`-object during navigation. For these cases Blits allows you to use query parameters as part of a route (i.e. `#/series/simpsons/5/10?id=100&name=john`).
44
44
 
45
- This URL hash will match the route `/series/:show/:season/:episode` and it will pass `id` and `name` as additional props into the Page component. Note: similar to dynamic path params, route query params should also be be defined in the Page component as _props_ first (i.e. `props: ['id', 'name']`) in order to be accessed on the `this`-scope.
45
+ This URL hash will match the route `/series/:show/:season/:episode` and it will pass `id` and `name` as additional props into the Page component. Note: similar to dynamic path params, route query params should also be defined in the Page component as _props_ first (i.e. `props: ['id', 'name']`) in order to be accessed on the `this`-scope.
46
46
 
47
47
  ## Router view
48
48
 
@@ -78,7 +78,7 @@ export default Blits.Application({
78
78
 
79
79
  Each component in a routed Blits app has a `this.$router` object that provides access to the Router instance. It can be used to programmatically navigate to pages, by calling the `to()` method on it.
80
80
 
81
- The `this.$router.to()`-methods accepts 3 arguments:
81
+ The `this.$router.to()`-method accepts 3 arguments:
82
82
 
83
83
  - `path` - the path of the route to navigate to
84
84
  - `data` (optional) - an object with data to pass into the page as `props`
@@ -147,9 +147,9 @@ The Router API provides several useful methods and properties for managing route
147
147
 
148
148
  The reactive router state (`this.$router.state`) can be useful in situations where you want to hook up reactive changes in your App to Route changes.
149
149
 
150
- The `state` variable on the `this.$router` object returns a reactive object with 2 keys: `path` and `navigating`. The values of these keys will automaticaly update when the router navigates from one page to another.
150
+ The `state` variable on the `this.$router` object returns a reactive object with 2 keys: `path` and `navigating`. The values of these keys will automatically update when the router navigates from one page to another.
151
151
 
152
- The router state changes can be used in a Blits template, they can be _watched_ and they can be used in generic busines logic, as demonstrated in the example below.
152
+ The router state changes can be used in a Blits template, they can be _watched_ and they can be used in generic business logic, as demonstrated in the example below.
153
153
 
154
154
  ```js
155
155
  export default Blits.Component('MyComponent', {
@@ -33,7 +33,7 @@ export default Blits.Application({
33
33
  The before hook can optionally return a value, which will influence the behaviour of the route change:
34
34
 
35
35
  - when `false` is returned, the router will fail to finish the routing, and act as if _no matching route was found_
36
- - when a `string` is returned, the router will interpret this a _new route path to redirect to_
36
+ - when a `string` is returned, the router will interpret this as a _new route path to redirect to_
37
37
  - when an `object` is returned, the router will interpret this as a route object, allowing to _modify (or completely replace) the route object_ being navigated to
38
38
 
39
39
  Returning an `object` is a simple, yet powerful, mechanism to add advanced runtime configuration to your routes. A common scenario is to overwrite certain parts of the route object provided in the `to`-argument, such as the route options (such as `inHistory` or `stayAlive`) or define conditional page transitions.
@@ -3,7 +3,7 @@
3
3
  So far we have explored how to create components and draw elements on the screen. But everything has
4
4
  been rather static so far.
5
5
 
6
- We did learn how to _reactively_ changes values and trigger rerenders based on that. So if you try the example below, you'll see that indeed our golden element changes position. But it just jumps from one place to another:
6
+ We did learn how to _reactively_ change values and trigger rerenders based on that. So if you try the example below, you'll see that indeed our golden element changes position. But it just jumps from one place to another:
7
7
 
8
8
  ```js
9
9
  export default Blits.Component('Gold', {
@@ -141,7 +141,7 @@ export default Blits.Component('Gold', {
141
141
  `,
142
142
  ///
143
143
  methods: {
144
- transitionprogress(progress, previousProgress) {
144
+ transitionProgress(progress, previousProgress) {
145
145
  if(progress >= 0.5 && previousProgress < 0.5) {
146
146
  // halfway through the transition
147
147
  }