@lightningjs/blits 1.21.1 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/run-blits-tests.yml +69 -0
- package/CHANGELOG.md +22 -0
- package/README.md +1 -1
- package/docs/README.md +1 -2
- package/docs/built-in/directives.md +1 -1
- package/docs/built-in/for-loop.md +8 -8
- package/docs/built-in/layout.md +23 -23
- package/docs/components/user_input.md +3 -3
- package/docs/components/utility_methods.md +11 -7
- package/docs/essentials/displaying_images.md +3 -3
- package/docs/essentials/displaying_text.md +3 -3
- package/docs/essentials/element_attributes.md +3 -3
- package/docs/essentials/template_syntax.md +1 -1
- package/docs/getting_started/intro.md +1 -1
- package/docs/plugins/global_app_state.md +2 -2
- package/docs/plugins/language.md +2 -2
- package/docs/plugins/theme.md +1 -1
- package/docs/router/basics.md +4 -4
- package/docs/router/hooks.md +1 -1
- package/docs/transitions_animations/transitions.md +3 -3
- package/index.d.ts +50 -7
- package/package.json +2 -2
- package/src/component/base/index.js +3 -1
- package/src/component/setup/index.js +4 -3
- package/src/component/setup/routes.js +6 -1
- package/src/component.js +24 -7
- package/src/component.test.js +6 -5
- package/src/components/Circle.js +1 -1
- package/src/components/FPScounter.js +1 -1
- package/src/components/RouterView.js +1 -1
- package/src/components/Sprite.js +1 -1
- package/src/engines/L3/launch.js +26 -22
- package/src/lib/codegenerator/generator.js +61 -8
- package/src/lib/codegenerator/generator.test.js +1089 -167
- package/src/lib/eventListeners.js +3 -3
- package/src/lib/precompiler/precompiler.js +2 -3
- package/src/lib/reactivity/reactive.js +1 -0
- package/src/lib/reactivityguard/computedprops.js +207 -0
- package/src/lib/symbols.js +1 -0
- package/src/router/router.js +28 -6
- package/vite/index.js +3 -1
- package/vite/preCompiler.js +1 -1
- 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.0
|
|
4
|
+
|
|
5
|
+
_13 mar 2025_
|
|
6
|
+
|
|
7
|
+
- Added support for beforeEach router hook
|
|
8
|
+
- Added warning when variables used in the template are not declared on the component scope (only during dev)
|
|
9
|
+
- Added vite plugin that ensures reactivity is setup properly for all state variables in a computed prop
|
|
10
|
+
- Fixed keepAlive functionality in the router on back navigation
|
|
11
|
+
- Fixed various test cases
|
|
12
|
+
- Added useful base methods to the this context of plugins
|
|
13
|
+
- Added workflow to execute test cases for PRs
|
|
14
|
+
- Updated L3 renderer dependency to v2.13.2
|
|
15
|
+
- Fixed various typos in the documentation
|
|
16
|
+
- Fixed reactivity issue when value is set to `null`
|
|
17
|
+
|
|
18
|
+
## v1.22.0
|
|
19
|
+
|
|
20
|
+
_3 mar 2025_
|
|
21
|
+
|
|
22
|
+
- Added default value for `createImageBitmapSupport` to `auto`
|
|
23
|
+
- Added advanced launch settings
|
|
24
|
+
|
|
3
25
|
## v1.21.1
|
|
4
26
|
|
|
5
27
|
_28 feb 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
package/docs/built-in/layout.md
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
# Layout
|
|
2
2
|
|
|
3
|
-
A big portion of building a pixel
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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('
|
|
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
|
|
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
|
|
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
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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
|
-
|
|
299
|
+
this.secondCount++
|
|
300
|
+
console.log(`${this.secondCount} second(s) have passed`)
|
|
298
301
|
}, 1000)
|
|
299
302
|
|
|
300
303
|
this.$setInterval(() => {
|
|
301
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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', {
|
package/docs/plugins/language.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
package/docs/plugins/theme.md
CHANGED
|
@@ -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
|
|
115
|
+
which means that they will inherit missing values from the base theme.
|
|
116
116
|
|
|
117
117
|
|
|
118
118
|
## Getting theme values
|
package/docs/router/basics.md
CHANGED
|
@@ -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
|
|
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()`-
|
|
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
|
|
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
|
|
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', {
|
package/docs/router/hooks.md
CHANGED
|
@@ -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_
|
|
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', {
|
|
@@ -128,7 +128,7 @@ export default Blits.Component('Gold', {
|
|
|
128
128
|
}
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
It is also possible to keep track of the entire progress of a transition. Every frametick during a transition (ideally once every
|
|
131
|
+
It is also possible to keep track of the entire progress of a transition. Every frametick during a transition (ideally once every 16ms), the renderer reports the progress of the transition. You can hook into this event by specifying a `progress` key on the transition configuration object, with a function to excute.
|
|
132
132
|
|
|
133
133
|
This function is executed _every_ frametick, and receives the current progress and the previous progress as its arguments. The progress is indicated as a value between `0` and `1`, where 0 means start and 1 means finished.
|
|
134
134
|
|
|
@@ -141,7 +141,7 @@ export default Blits.Component('Gold', {
|
|
|
141
141
|
`,
|
|
142
142
|
///
|
|
143
143
|
methods: {
|
|
144
|
-
|
|
144
|
+
transitionProgress(progress, previousProgress) {
|
|
145
145
|
if(progress >= 0.5 && previousProgress < 0.5) {
|
|
146
146
|
// halfway through the transition
|
|
147
147
|
}
|