@lightningjs/blits 1.30.2 → 1.31.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.
- package/CHANGELOG.md +1035 -1019
- package/LICENSE +202 -202
- package/NOTICE +12 -12
- package/README.md +33 -33
- package/bin/index.js +8 -8
- package/blits.d.ts +6 -6
- package/index.d.ts +1099 -1099
- package/index.js +28 -28
- package/package.json +57 -56
- package/public/assets/fps_sprite.base64.js +1 -1
- package/scripts/postpublish.js +59 -59
- package/scripts/prepublishOnly.js +84 -84
- package/scripts/prepush.js +78 -78
- package/src/announcer/announcer.js +162 -162
- package/src/announcer/speechSynthesis.js +107 -107
- package/src/application.js +100 -100
- package/src/component/base/announcer.js +27 -27
- package/src/component/base/events.js +69 -69
- package/src/component/base/index.js +33 -33
- package/src/component/base/methods.js +244 -244
- package/src/component/base/router.js +41 -41
- package/src/component/base/timeouts_intervals.js +99 -99
- package/src/component/base/utils.js +72 -72
- package/src/component/setup/computed.js +48 -48
- package/src/component/setup/index.js +62 -62
- package/src/component/setup/input.js +30 -30
- package/src/component/setup/methods.js +37 -37
- package/src/component/setup/props.js +62 -62
- package/src/component/setup/routes.js +42 -42
- package/src/component/setup/state.js +59 -59
- package/src/component/setup/watch.js +35 -35
- package/src/component.js +437 -437
- package/src/components/Circle.js +73 -73
- package/src/components/FPScounter.js +1510 -1510
- package/src/components/RouterView.js +81 -81
- package/src/components/Sprite.js +94 -94
- package/src/components/index.js +28 -28
- package/src/constants.js +21 -21
- package/src/engine.js +1 -1
- package/src/engines/L3/element.js +744 -744
- package/src/engines/L3/fontLoader.js +38 -38
- package/src/engines/L3/index.js +7 -7
- package/src/engines/L3/launch.js +123 -123
- package/src/engines/L3/shaderLoader.js +12 -12
- package/src/engines/index.js +1 -1
- package/src/focus.js +90 -90
- package/src/helpers/deepEqualArray.js +50 -50
- package/src/helpers/fetchJson.js +34 -34
- package/src/helpers/sequence.js +26 -26
- package/src/launch.js +123 -123
- package/src/lib/blitsfileconverter/blitsfileconverter.js +52 -52
- package/src/lib/codegenerator/generator.js +788 -788
- package/src/lib/colors/colors.js +92 -92
- package/src/lib/colors/htmlColors.js +168 -168
- package/src/lib/componentId.js +49 -49
- package/src/lib/eventListeners.js +123 -123
- package/src/lib/hooks.js +59 -59
- package/src/lib/lifecycle.js +85 -85
- package/src/lib/log.js +117 -117
- package/src/lib/precompiler/precompiler.js +73 -73
- package/src/lib/reactivity/effect.js +93 -93
- package/src/lib/reactivity/reactive.js +208 -208
- package/src/lib/reactivityguard/computedprops.js +218 -218
- package/src/lib/symbols.js +108 -108
- package/src/lib/templateparser/parser.js +386 -386
- package/src/lib/utils.js +27 -27
- package/src/plugin.js +27 -27
- package/src/plugins/appstate.js +26 -26
- package/src/plugins/index.js +20 -20
- package/src/plugins/language.js +152 -152
- package/src/plugins/log.js +25 -25
- package/src/plugins/theme.js +94 -94
- package/src/router/router.js +516 -514
- package/src/router/transitions/fadeIn.js +27 -27
- package/src/router/transitions/fadeInOut.js +33 -33
- package/src/router/transitions/index.js +21 -21
- package/src/router/transitions/slideIn.js +28 -28
- package/src/router/transitions/slideInOut.js +33 -33
- package/src/settings.js +40 -40
- package/vite/blitsFileConverter.js +67 -67
- package/vite/index.js +28 -28
- package/vite/msdfGenerator.js +269 -269
- package/vite/preCompiler.js +47 -42
- package/vite/reactivityGuard.js +45 -45
- package/vscode/data/template-attributes.json +589 -589
- package/.editorconfig +0 -7
- package/.eslintignore +0 -1
- package/.eslintrc.cjs +0 -65
- package/.github/workflows/comment-lint-results.yml +0 -125
- package/.github/workflows/comment-test-results.yml +0 -109
- package/.github/workflows/deploy-docs.yml +0 -27
- package/.github/workflows/run-blits-tests.yml +0 -142
- package/.github/workflows/run-lint.yml +0 -128
- package/.husky/pre-commit +0 -1
- package/.husky/pre-push +0 -1
- package/.vscode/extensions.json +0 -7
- package/.vscode/settings.json +0 -9
- package/COPYING +0 -1
- package/banner.png +0 -0
- package/docs/.nojekyll +0 -0
- package/docs/README.md +0 -19
- package/docs/_sidebar.md +0 -37
- package/docs/built-in/directives.md +0 -50
- package/docs/built-in/for-loop.md +0 -204
- package/docs/built-in/layout.md +0 -168
- package/docs/components/component_state.md +0 -90
- package/docs/components/computed_properties.md +0 -45
- package/docs/components/lifecycle_events.md +0 -42
- package/docs/components/methods.md +0 -45
- package/docs/components/props.md +0 -56
- package/docs/components/user_input.md +0 -186
- package/docs/components/utility_methods.md +0 -320
- package/docs/components/watchers.md +0 -34
- package/docs/essentials/application_root.md +0 -19
- package/docs/essentials/components.md +0 -68
- package/docs/essentials/displaying_images.md +0 -67
- package/docs/essentials/displaying_text.md +0 -135
- package/docs/essentials/element_attributes.md +0 -195
- package/docs/essentials/settings.md +0 -117
- package/docs/essentials/template_syntax.md +0 -83
- package/docs/getting_started/file_structure.md +0 -58
- package/docs/getting_started/getting_started.md +0 -45
- package/docs/getting_started/intro.md +0 -20
- package/docs/index.html +0 -47
- package/docs/performance/lazy-loading.md +0 -161
- package/docs/plugins/global_app_state.md +0 -98
- package/docs/plugins/language.md +0 -172
- package/docs/plugins/text-to-speech-announcer.md +0 -120
- package/docs/plugins/theme.md +0 -176
- package/docs/router/basics.md +0 -175
- package/docs/router/hooks.md +0 -70
- package/docs/router/transitions.md +0 -146
- package/docs/sidebar.json +0 -171
- package/docs/transitions_animations/transitions.md +0 -150
- package/jsconfig.json +0 -12
- package/src/component/setup/props.test.js +0 -238
- package/src/component.test.js +0 -388
- package/src/components/Circle.orig.js +0 -31
- package/src/components/FPScounter.orig.js +0 -121
- package/src/components/RouterView.orig.js +0 -54
- package/src/components/Sprite.orig.js +0 -58
- package/src/components/index.orig.js +0 -28
- package/src/engines/L3/element.test.js +0 -579
- package/src/helpers/deepEqualArray.test.js +0 -127
- package/src/lib/codegenerator/generator.test.js +0 -3801
- package/src/lib/colors/colors.test.js +0 -290
- package/src/lib/componentId.test.js +0 -84
- package/src/lib/eventListeners.test.js +0 -236
- package/src/lib/reactivity/effect.test.js +0 -35
- package/src/lib/reactivity/reactive.test.js +0 -27
- package/src/lib/templateparser/parser.test.js +0 -1411
- package/src/router/router.test.js +0 -473
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# File structure
|
|
2
|
-
|
|
3
|
-
Once you have created a new Blits App using the boilerplate described in the [Getting started](getting_started.md), you should have a project with all the basics you need.
|
|
4
|
-
|
|
5
|
-
Let's review the basic file structure, and take a closer look at the important ones.
|
|
6
|
-
|
|
7
|
-
## package.json
|
|
8
|
-
|
|
9
|
-
In the root of your newly created app, you will obviously find a `package.json` with all the necessary (dev) dependencies.
|
|
10
|
-
|
|
11
|
-
In order to build a Blits based Lightning 3 app, all you need is `@lightningjs/blits` as a dependency. Blits will take care of hooking up the Lightning 3 renderer for you behind the scenes.
|
|
12
|
-
|
|
13
|
-
Feel free to install and import any custom library that your App may need. But always be mindful of the size and impact an external dependency may have - especially when developing for low powered devices (as is often the case with Lightning apps).
|
|
14
|
-
|
|
15
|
-
## index.html
|
|
16
|
-
|
|
17
|
-
You will also find an `index.html` at the root of your project. This is where the browser will be pointed to, in order to launch your Blits App.
|
|
18
|
-
|
|
19
|
-
If you inspect the source you will see some minimal HTML. The essential parts of the HTML are the `<div>` where the canvas will be injected into, and the `<script>`-tag that points to the `index.js` of the App.
|
|
20
|
-
|
|
21
|
-
## public
|
|
22
|
-
|
|
23
|
-
There is also a `public` folder in your project. This folder is used for storing public assets, such as App images and fonts.
|
|
24
|
-
|
|
25
|
-
During development, your assets are loaded directly from this folder. And if you run a production build, the entire `public` folder is copied over to the distributable version.
|
|
26
|
-
|
|
27
|
-
## src
|
|
28
|
-
|
|
29
|
-
The `src`-folder is where all your custom App code lives.
|
|
30
|
-
|
|
31
|
-
### index.js
|
|
32
|
-
|
|
33
|
-
`src/index.js` is the entry point of your App. This file imports the Blits `Launch`-method which initializes the App.
|
|
34
|
-
|
|
35
|
-
The `Blits.Launch()`-method accepts 3 parameters:
|
|
36
|
-
|
|
37
|
-
1) `app` - the root application component
|
|
38
|
-
2) `target` - the HTML target to append the canvas to. This can either be an `id` of an HTML element in `index.html`, or you can pass a reference to HTML element itself
|
|
39
|
-
3) `settings` - an `object` with settings
|
|
40
|
-
|
|
41
|
-
### App.js
|
|
42
|
-
|
|
43
|
-
`src/App.js` is the default file where the root application component lives. It's expected to export a `Blits.Application()`-instance, which is the base component of your App.
|
|
44
|
-
|
|
45
|
-
## components and pages folder
|
|
46
|
-
|
|
47
|
-
The rest of your App can be built out using components. You are free to organize your components as you wish, but we recommend using a separate file for each component and placing them in the `src/components`-folder.
|
|
48
|
-
|
|
49
|
-
The convention is to start the component file name with a capital letter, matching the name of the component (e.g. `src/components/Loader.js` or `src/components/MenuItem.js`).
|
|
50
|
-
|
|
51
|
-
Feel free to further organize and possibly nest your Component files to your own preferences.
|
|
52
|
-
|
|
53
|
-
Pages in your App are technically just Blits components as well. But to keep things clear, we often place them in a separate `pages`-folder alongside the `components`-folder (e.g. `src/pages/Home.js` and `src/pages/Details.js`)
|
|
54
|
-
|
|
55
|
-
### Custom code
|
|
56
|
-
|
|
57
|
-
If your App needs libraries for specific (business) logic that can be shared across components (such as API calls) you can place them anywhere in your `src` folder. For example in a folder named `src/lib` or `src/api`.
|
|
58
|
-
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Getting Started
|
|
2
|
-
|
|
3
|
-
To get started with Blits, follow these simple steps to set up your development environment and create your first Lightning 3 App.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
1. Open your terminal or command prompt.
|
|
8
|
-
|
|
9
|
-
2. Run the following command to start a new Blits Lightning 3 App project:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm create @lightningjs/app
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
You will be guided through a short series of questions to generate a new project with all the boilerplate code you need to start building your own Lightning 3 App.
|
|
16
|
-
|
|
17
|
-
3. Navigate to the newly created project directory and install the project dependencies:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
cd my_blits_app
|
|
21
|
-
npm install
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Running Your App
|
|
25
|
-
|
|
26
|
-
4. After installing the dependencies, you can start your development server by running:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm run dev
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
This command will create an application bundle and launch a development server using Vite.
|
|
33
|
-
|
|
34
|
-
Once the server is up and running, open your web browser and navigate to the URL displayed in the console. Congratulations! You now have your brand new Blits Lightning 3 App up and running.
|
|
35
|
-
|
|
36
|
-
## Coding environment
|
|
37
|
-
|
|
38
|
-
You can use any code editor of your preference to further develop your Blits App.
|
|
39
|
-
|
|
40
|
-
We recommend using VS code, since we have a dedicated [VS code extension for Blits](https://marketplace.visualstudio.com/items?itemName=LightningJS.lightning-blits) that provides better syntax highlighting, code completion, error
|
|
41
|
-
checking, and other features to make working with Blits easier.
|
|
42
|
-
|
|
43
|
-
## Next steps
|
|
44
|
-
|
|
45
|
-
You are now ready to dive into the world of App development using Blits. In the following sections, we will explore the core concepts and guide you through building your TV applications step by step.
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# Blits - Lightning 3 App Development Framework
|
|
2
|
-
|
|
3
|
-
With Blits, the App Development Framework for Lightning 3, it becomes a breeze to build great Lightning 3 applications.
|
|
4
|
-
|
|
5
|
-
Blits is built on top of the Lightning 3 Renderer and aims to provide a **great developer experience**, making it fun and easy to build your apps!
|
|
6
|
-
|
|
7
|
-
Built from the ground up by the LightningJS team, we're offering a **Complete App framework**, full of features to speed up development, while keeping it **lightweight** with a focus on **performance**.
|
|
8
|
-
|
|
9
|
-
The Blits framework uses a **readable** XML-style template syntax and comes with built-in reactivity.
|
|
10
|
-
|
|
11
|
-
## Why Blits?
|
|
12
|
-
|
|
13
|
-
You may be wondering where the name Blits comes from.
|
|
14
|
-
|
|
15
|
-
Firstly, it's short, memorable and just has a nice ring to it.
|
|
16
|
-
|
|
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
|
-
|
|
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
|
-
|
package/docs/index.html
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<title>Blits Lightning App Development Framework</title>
|
|
6
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
|
7
|
-
<meta name="description" content="Description">
|
|
8
|
-
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
9
|
-
<!--link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple.css"-->
|
|
10
|
-
<link
|
|
11
|
-
rel="stylesheet"
|
|
12
|
-
href="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/style.min.css"
|
|
13
|
-
title="docsify-darklight-theme"
|
|
14
|
-
type="text/css"
|
|
15
|
-
/>
|
|
16
|
-
</head>
|
|
17
|
-
<body>
|
|
18
|
-
<div id="app"></div>
|
|
19
|
-
<script>
|
|
20
|
-
window.$docsify = {
|
|
21
|
-
name: 'Blits <br />L3 App Development Framework',
|
|
22
|
-
repo: 'https://github.com/lightning-js/blits/',
|
|
23
|
-
loadSidebar: true,
|
|
24
|
-
relativePath: true,
|
|
25
|
-
auto2top: true,
|
|
26
|
-
search: {
|
|
27
|
-
maxAge: 24*60*60*1000, // one day
|
|
28
|
-
paths: 'auto',
|
|
29
|
-
placeholder: 'Type to search',
|
|
30
|
-
noData: 'No Results!',
|
|
31
|
-
depth: 6,
|
|
32
|
-
},
|
|
33
|
-
darklightTheme: {
|
|
34
|
-
defaultTheme : 'dark',
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
</script>
|
|
39
|
-
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
|
40
|
-
<script src="https://cdn.jsdelivr.net/npm/docsify-themeable@0"></script>
|
|
41
|
-
<script
|
|
42
|
-
src="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/index.min.js"
|
|
43
|
-
type="text/javascript">
|
|
44
|
-
</script>
|
|
45
|
-
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
|
|
46
|
-
</body>
|
|
47
|
-
</html>
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
# Lazy Loading with the :range Parameter
|
|
2
|
-
|
|
3
|
-
The for-loop in Blits comes with a [`:range` parameter](../built-in/for-loop.html#using-the-range-attribute) that allows you to render only a portion of an array rather than all the items.
|
|
4
|
-
|
|
5
|
-
This `:range` parameter can also be used to easily implement an efficient form of _lazy loading_. Lazy loading is a crucial concept for performance in TV applications where rails can contain hundreds of items, but only a small subset is visible at any time.
|
|
6
|
-
|
|
7
|
-
## Basic range implementation
|
|
8
|
-
|
|
9
|
-
For the basic syntax of the `:range` attribute, we typically set dynamic `from` and `to` values, which define the subset of items to display.
|
|
10
|
-
|
|
11
|
-
```js
|
|
12
|
-
<Tile :for="(item, index) in $items" :range="{from: $from, to: $to}" />
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
A full example of a Rail component with a range would look something like this:
|
|
16
|
-
|
|
17
|
-
```js
|
|
18
|
-
export default Blits.Component('RangedRail', {
|
|
19
|
-
template: `
|
|
20
|
-
<Element :x.transition="0 - $focused * 300">
|
|
21
|
-
<Tile
|
|
22
|
-
:for="(item, index) in $items"
|
|
23
|
-
:range="{from: $range, to: $range + 7}"
|
|
24
|
-
:key="$item.id"
|
|
25
|
-
:focused="$focused"
|
|
26
|
-
w="300"
|
|
27
|
-
h="200"
|
|
28
|
-
:x="$index * 320"
|
|
29
|
-
/>
|
|
30
|
-
</Element>
|
|
31
|
-
`,
|
|
32
|
-
state() {
|
|
33
|
-
return {
|
|
34
|
-
range: 0,
|
|
35
|
-
focused: 0,
|
|
36
|
-
items: [] // Array of 100+ items
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
input: {
|
|
40
|
-
right() {
|
|
41
|
-
this.focus = Math.min(this.focus + 1, items.length)
|
|
42
|
-
this.range++
|
|
43
|
-
},
|
|
44
|
-
left() {
|
|
45
|
-
this.focus = Math.max(this.focus - 1, 0)
|
|
46
|
-
this.range--
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Benefits of this approach are:
|
|
53
|
-
|
|
54
|
-
- **Selective Rendering**: Only items within the specified range are actually created as elements
|
|
55
|
-
- **Performance Optimization**: Reduces memory usage and improves rendering performance
|
|
56
|
-
- **Dynamic Range Updates**: The range can be computed based on user interaction and scroll position
|
|
57
|
-
|
|
58
|
-
A downside of this approach is that, as we scroll we are also **destroying** components that are out of range. And we may need those
|
|
59
|
-
same items when we scroll back (and thus recreate them). On top of that, destroying Components and Elements also comes at a cost.
|
|
60
|
-
|
|
61
|
-
## Lazy loading with the range attribute
|
|
62
|
-
|
|
63
|
-
We can solve the problem of destroying Components that we may want to use again by slightly changing the logic of the Rail component.
|
|
64
|
-
|
|
65
|
-
1) We set `from: 0`, to ensure we always start from the first item (and _keep_ the first items)
|
|
66
|
-
2) We use `to: $range + 7` to render up to the current position plus a lookahead buffer
|
|
67
|
-
3) The `$range` value tracks how far the user has navigated through the rail, but it doesn't decrement when navigating back
|
|
68
|
-
|
|
69
|
-
With these changes a full example of a LazyRail component would look something like this:
|
|
70
|
-
|
|
71
|
-
```js
|
|
72
|
-
export default Blits.Component('LazyRail', {
|
|
73
|
-
template: `
|
|
74
|
-
<Element :x.transition="0 - $focused * 300">
|
|
75
|
-
<Tile
|
|
76
|
-
:for="(item, index) in $items"
|
|
77
|
-
:range="{from: 0, to: $range + 7}"
|
|
78
|
-
:key="$item.id"
|
|
79
|
-
w="300"
|
|
80
|
-
h="200"
|
|
81
|
-
:x="$index * 320"
|
|
82
|
-
/>
|
|
83
|
-
</Element>
|
|
84
|
-
`,
|
|
85
|
-
state() {
|
|
86
|
-
return {
|
|
87
|
-
range: 0,
|
|
88
|
-
items: [] // Array of 100+ items
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
input: {
|
|
92
|
-
right() {
|
|
93
|
-
this.focus = Math.min(this.focus + 1, items.length)
|
|
94
|
-
// push the range update to the next tick to spread out the work
|
|
95
|
-
// and ease the CPU a bit
|
|
96
|
-
this.$setTimeout(() => this.range = this.focus)
|
|
97
|
-
|
|
98
|
-
},
|
|
99
|
-
left() {
|
|
100
|
-
this.focus = Math.max(this.focus - 1, 0)
|
|
101
|
-
// we don't decrement the range when scrolling back to keep components alive
|
|
102
|
-
// this.range--
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
})
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Performance Benefits
|
|
109
|
-
|
|
110
|
-
Properly applying the range attribute provides **Memory Efficiency**:
|
|
111
|
-
|
|
112
|
-
- Instead of creating 100+ elements, only ~8-15 are active
|
|
113
|
-
- Reduces GPU memory usage on constrained TV hardware
|
|
114
|
-
- Lower overall memory footprint
|
|
115
|
-
|
|
116
|
-
It also is beneficial for **Faster Rendering**
|
|
117
|
-
|
|
118
|
-
- Initial page load only renders visible items
|
|
119
|
-
- Scroll performance improves as fewer elements need updates
|
|
120
|
-
- Reduced layout calculations
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
It **optimizes bandwidth**
|
|
124
|
-
|
|
125
|
-
- Images and assets only load for rendered items
|
|
126
|
-
- Reduces network requests on page load
|
|
127
|
-
- Progressive content loading
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
### Alpha Transitions
|
|
131
|
-
|
|
132
|
-
For a smoother experience you consider applying an alpha transition, that fades out items at the end of the rang.e
|
|
133
|
-
|
|
134
|
-
```js
|
|
135
|
-
:alpha.transition="$index <= $range ? 1 : ($index <= $range + 3 ? 0.8 : 0.6)"
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
This creates a dimming effect for previously viewed items while maintaining full opacity for the current and upcoming items.
|
|
139
|
-
|
|
140
|
-
## Best Practices
|
|
141
|
-
|
|
142
|
-
### Buffer Size
|
|
143
|
-
|
|
144
|
-
Use a buffer of 5-10 items ahead of current position:
|
|
145
|
-
|
|
146
|
-
```js
|
|
147
|
-
// Conservative buffer for low-end devices
|
|
148
|
-
:range="{from: $currentIndex - 1, to: $currentIndex + 6}"
|
|
149
|
-
|
|
150
|
-
// Larger buffer for smoother experience
|
|
151
|
-
:range="{from: $currentIndex - 2, to: $currentIndex + 10}"
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Performance Impact
|
|
155
|
-
|
|
156
|
-
On typical TV hardware:
|
|
157
|
-
|
|
158
|
-
- **Memory Usage**: 70-80% reduction compared to full rendering
|
|
159
|
-
- **Initial Load Time**: 3-5x faster page initialization
|
|
160
|
-
- **Scroll Performance**: Consistent fps maintained vs potential frame drops
|
|
161
|
-
- **Network Requests**: Reduced by 80-90% on initial load
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# Global App State plugin
|
|
2
|
-
|
|
3
|
-
Each Blits Component has its own, internal component state that is reactive and can automatically trigger updates in the template upon changes. The internal state is fully encapsulated, which ensures predictable component state and promotes a pattern of clear separation of concerns.
|
|
4
|
-
|
|
5
|
-
But a Component usually doesn't live on its own, instead it's part of a bigger App. And there may arise a need for components to exchange data - intercomponent communication in other words.
|
|
6
|
-
|
|
7
|
-
Blits offers the option to _emit_ and _listen_ to events, as explained in the section on Blits [utility methods](../components/utility_methods.md). For simple use cases, this is a convenient method to pass data along. But when used extensively, it may be easy to lose track of data flows.
|
|
8
|
-
|
|
9
|
-
For more advanced cases, Blits offers an optional Global App State plugin that will act as a global state store that all components have direct access to. It's a simple implementation, focused on providing a _performant_ and _easy to use_ solution for global state. It's not a full flux / redux style state management solution, as we know from experience that these solutions (while very useful and cool), may lead to performance issues on low-end devices.
|
|
10
|
-
|
|
11
|
-
## Registering the plugin
|
|
12
|
-
|
|
13
|
-
The Global App state plugin is provided in the core Blits package, but as it's an _optional_ plugin it first needs to be registered.
|
|
14
|
-
|
|
15
|
-
The plugin can be imported from Blits and registered in the App's `index.js`, as demonstrated in the example below.
|
|
16
|
-
|
|
17
|
-
Make sure to place the `Blits.Plugin()` method _before_ calling the `Blits.Launch()` method.
|
|
18
|
-
|
|
19
|
-
```js
|
|
20
|
-
// index.js
|
|
21
|
-
|
|
22
|
-
import Blits from '@lightningjs/blits'
|
|
23
|
-
// import the app state plugin
|
|
24
|
-
import { appState } from '@lightningjs/blits/plugins'
|
|
25
|
-
|
|
26
|
-
import App from './App.js'
|
|
27
|
-
|
|
28
|
-
// Use the Blits App State plugin
|
|
29
|
-
Blits.Plugin(appState, {
|
|
30
|
-
loggedIn: false,
|
|
31
|
-
user: {
|
|
32
|
-
id: null,
|
|
33
|
-
name: '',
|
|
34
|
-
lastname: ''
|
|
35
|
-
},
|
|
36
|
-
languages: ['en', 'nl', 'pt', 'es'],
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Blits.Launch(App, 'app', {
|
|
41
|
-
// launch settings
|
|
42
|
-
})
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### State object
|
|
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 of the global state variables.
|
|
48
|
-
|
|
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
|
-
|
|
51
|
-
### Using global app state in a Component
|
|
52
|
-
|
|
53
|
-
Any variable in the Global App state can be used directly in the template, much like a local Component state. Changing values in the global app state also works exactly the same as updating the internal component state.
|
|
54
|
-
|
|
55
|
-
```js
|
|
56
|
-
Blits.Component('MyComponent', {
|
|
57
|
-
template: `
|
|
58
|
-
<Element>
|
|
59
|
-
<Text :content="$$appState.loggedIn ? $$appState.user.name : 'Not logged in'" />
|
|
60
|
-
</Element>
|
|
61
|
-
`,
|
|
62
|
-
input: {
|
|
63
|
-
enter() {
|
|
64
|
-
this.$appState.user.name = 'John'
|
|
65
|
-
this.$appState.loggedIn = true
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
})
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Note that in the template definition, 2 consecutive dollars signs are used (`$$appState`). The first `$`-sign is used
|
|
72
|
-
to refer to the Component scope, as with any other state variable or computed property referenced in the template.
|
|
73
|
-
|
|
74
|
-
The second `$`-sign is needed, since the appState plugin itself is prefixed with a dollar sign, to prevent accidental naming collisions.
|
|
75
|
-
|
|
76
|
-
In order to read or update variables on the global app state inside the component logic, you can access the entire state via `this.$appState`.
|
|
77
|
-
|
|
78
|
-
### Watching global state
|
|
79
|
-
|
|
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
|
-
|
|
82
|
-
```js
|
|
83
|
-
Blits.Component('MyComponent', {
|
|
84
|
-
template: `
|
|
85
|
-
<Element>
|
|
86
|
-
<Text :content="$$appState.loggedIn ? $$appState.user.name : 'Not logged in'" />
|
|
87
|
-
</Element>
|
|
88
|
-
`,
|
|
89
|
-
watch: {
|
|
90
|
-
'$appState.fooBar'(v, old) {
|
|
91
|
-
console.log(`$appState.fooBar changed from ${old} to ${v}`)
|
|
92
|
-
},
|
|
93
|
-
'$appState.my.nested.data': function(v, old) {
|
|
94
|
-
console.log(`My nested App state data changed!`)
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
})
|
|
98
|
-
```
|
package/docs/plugins/language.md
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
# Language plugin
|
|
2
|
-
|
|
3
|
-
Blits comes with a built-in Language plugin, that can be used to add internationalization (i18n) to your App.
|
|
4
|
-
|
|
5
|
-
The Blits Language plugin is a simple and lightweight implementation, closely modeled after the tried and tested Language plugin in the Lightning-SDK (for Lightning 2). It is designed to provide a flexible and easy way of translating texts to multiple languages, in a performant way.
|
|
6
|
-
|
|
7
|
-
## Registering the plugin
|
|
8
|
-
|
|
9
|
-
While the Language plugin is provided in the core Blits package, it's an _optional_ plugin that needs to be registered before you're able to use it. As such the Language plugin is _tree-shakable_, i.e. for Apps that don't have a need for translation functionality, the Language plugin will not be part of the final App bundle.
|
|
10
|
-
|
|
11
|
-
The Language plugin should be imported from Blits and registered in the App's `index.js`, as demonstrated in the example below.
|
|
12
|
-
|
|
13
|
-
Make sure to place the `Blits.Plugin()` method _before_ calling the `Blits.Launch()` method
|
|
14
|
-
|
|
15
|
-
```js
|
|
16
|
-
// index.js
|
|
17
|
-
|
|
18
|
-
import Blits from '@lightningjs/blits'
|
|
19
|
-
// import the language plugin
|
|
20
|
-
import { language } from '@lightningjs/blits/plugins'
|
|
21
|
-
|
|
22
|
-
import App from './App.js'
|
|
23
|
-
|
|
24
|
-
// Use the Blits Language plugin and
|
|
25
|
-
// optionally pass in a settings object
|
|
26
|
-
Blits.Plugin(language, {
|
|
27
|
-
file: '/assets/translations.json', // file with translations
|
|
28
|
-
language: 'EN-us', // default language
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Blits.Launch(App, 'app', {
|
|
33
|
-
// launch settings
|
|
34
|
-
})
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
The Language plugin accepts an optional configuration object with 2 keys:
|
|
38
|
-
|
|
39
|
-
- `file` - the JSON file with translations to be loaded at initialization
|
|
40
|
-
- `language` - the default language to use
|
|
41
|
-
|
|
42
|
-
After registration of the Language plugin, it will be available in each Blits Component as `this.$language`.
|
|
43
|
-
|
|
44
|
-
## Translations file
|
|
45
|
-
|
|
46
|
-
The most common way of defining a set of translations, is to use a dedicated JSON file, modeled after
|
|
47
|
-
the following format:
|
|
48
|
-
|
|
49
|
-
```json
|
|
50
|
-
{
|
|
51
|
-
"nl-NL": {
|
|
52
|
-
"hello": "Hallo, alles goed?",
|
|
53
|
-
"bye": "Doei!",
|
|
54
|
-
"replacement": "Mijn naam is {first} {last}, ik ben {age} jaar"
|
|
55
|
-
},
|
|
56
|
-
"en-US": {
|
|
57
|
-
"hello": "Hello, how are you doing?",
|
|
58
|
-
"bye": "Goodbye!",
|
|
59
|
-
"replacement": "My name is {first} {last}, I'm {age} years old"
|
|
60
|
-
},
|
|
61
|
-
"fr-FR": {
|
|
62
|
-
"hello": "Bonjour, ça va?",
|
|
63
|
-
"bye": "Au revoir!",
|
|
64
|
-
"replacement": "Je m'appelle {first} {last}, j'ai {age} ans"
|
|
65
|
-
},
|
|
66
|
-
"de-DE": {
|
|
67
|
-
"hello": "Gutentag, wie geht's?",
|
|
68
|
-
"bye": "Tschüss!",
|
|
69
|
-
"replacement": "Mein Name ist {first} {last}, ich bin {age} Jahre alt"
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Each top level key represents a language, which contains an object with translation key-value pairs. The language key
|
|
75
|
-
doesn't require to be in a specific format, but it's recommended to use ISO-codes.
|
|
76
|
-
|
|
77
|
-
When the JSON file is specified in the Plugin registration method, the language file is loaded automatically upon instantiation.
|
|
78
|
-
|
|
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
|
-
|
|
81
|
-
## Defining translations manually
|
|
82
|
-
|
|
83
|
-
As an alternative to a JSON file with translations, you can also define translations directly via an object, using the `translations()`-method.
|
|
84
|
-
|
|
85
|
-
The `this.$language.translations()`-methods accepts a translations object as it's first argument, following the same format as the JSON file. The method is typically used in an `init` or `ready` hook
|
|
86
|
-
|
|
87
|
-
```js
|
|
88
|
-
Blits.Component('MyComponent', {
|
|
89
|
-
// ...
|
|
90
|
-
hooks: {
|
|
91
|
-
init() {
|
|
92
|
-
this.$language.translations({
|
|
93
|
-
english: {
|
|
94
|
-
hello: "Hello",
|
|
95
|
-
world: "World"
|
|
96
|
-
},
|
|
97
|
-
italian: {
|
|
98
|
-
hello: "Ciao",
|
|
99
|
-
world: "Mondo"
|
|
100
|
-
}
|
|
101
|
-
})
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
})
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Setting the language
|
|
108
|
-
|
|
109
|
-
In order to set (or change) the current language, the `this.$language.set()`-method can be used, passing in the new language code (matching one of the languages defined in the translations).
|
|
110
|
-
|
|
111
|
-
```js
|
|
112
|
-
Blits.Component('MyComponent', {
|
|
113
|
-
// ...
|
|
114
|
-
input: {
|
|
115
|
-
enter() {
|
|
116
|
-
this.$language.set('pt-BR')
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
})
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Getting the current language
|
|
123
|
-
|
|
124
|
-
The current language can be retrieved via the `this.$language.language` property. It will return the currently set language code.
|
|
125
|
-
|
|
126
|
-
## Translating
|
|
127
|
-
|
|
128
|
-
The most important functionality in the Language plugin is translating. The Language plugin exposes a `translate()` method that takes as string to translate as it's first argument. It will return the translated value in the currently set language. If either the language or the string to translate can't be found, it will return the inputed string.
|
|
129
|
-
|
|
130
|
-
The translate method can be used both inside the javascript business logic, but also directly in the template.
|
|
131
|
-
|
|
132
|
-
```js
|
|
133
|
-
Blits.Component('MyComponent', {
|
|
134
|
-
template: `
|
|
135
|
-
<Element>
|
|
136
|
-
<Text :content="$$language.translate('hello')" />
|
|
137
|
-
<Text y="100" :content="$$language.get()" />
|
|
138
|
-
</Element>
|
|
139
|
-
`,
|
|
140
|
-
hooks: {
|
|
141
|
-
ready() {
|
|
142
|
-
console.log(this.$language.translate('world'))
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
})
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
Note that in the template definition 2 consecutive dollars signs are used (`$$language`). The first `$`-sign is used
|
|
149
|
-
to refer to the Component scope, as with any other state variable or computed property refereced in the template.
|
|
150
|
-
|
|
151
|
-
The second `$`-sign is needed, since the Language plugin itself is prefixed with a dollar sign on the Component scope as well (i.e `this.$language`).
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
### Dynamic replacements
|
|
155
|
-
|
|
156
|
-
The `tranlate()`-method also supports dynamic replacements. This allows you to specify variables inside your translation string, and replace them with dynamic values passed into the `translate()`-method.
|
|
157
|
-
|
|
158
|
-
Replacements are marked in the translation value using _handlebars_, like so:
|
|
159
|
-
|
|
160
|
-
```js
|
|
161
|
-
{
|
|
162
|
-
replacements = "My name is {first} {last}, I'm {age} years old"
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
Now when you call the `translate()`-method and pass in an object with dynamic values, those will be replaced
|
|
167
|
-
in the final string accordingly:
|
|
168
|
-
|
|
169
|
-
```js
|
|
170
|
-
this.$language.translate('replacements', {name: 'John', last: 'Doe', age: 18})
|
|
171
|
-
// result: My name is John Doe, I'm 18 years old
|
|
172
|
-
```
|