@lightningjs/blits 1.30.1 → 1.31.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/CHANGELOG.md +17 -0
- package/package.json +4 -3
- package/src/router/router.js +2 -0
- package/vite/preCompiler.js +6 -1
- 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/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
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
|
-
```
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
# Text-to-Speech / Announcer
|
|
2
|
-
|
|
3
|
-
Blits comes with a built-in Text-to-Speech / Announcer functionality, to easily make your App more accessible. This is something that's often overlooked when developing an App, but having speech assistance integrated into your App is a huge deal for those users who are visually impaired.
|
|
4
|
-
|
|
5
|
-
## Integrated with the router
|
|
6
|
-
|
|
7
|
-
The Announcer in Blits is directly integrated with the router functionality. This means that through simple configuration, a descriptive message can be announced, when navigating from page to page, without the need for adding extra custom code.
|
|
8
|
-
|
|
9
|
-
Just add an `announce` key in the configuration of your route, that contains the message you would like to be announced when visiting that route.
|
|
10
|
-
|
|
11
|
-
```js
|
|
12
|
-
const routes = [
|
|
13
|
-
// ...
|
|
14
|
-
{
|
|
15
|
-
path: '/settings',
|
|
16
|
-
component: Settings,
|
|
17
|
-
announce: "Welcome to the Settings page",
|
|
18
|
-
},
|
|
19
|
-
// ...
|
|
20
|
-
]
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Custom announcement messages
|
|
24
|
-
|
|
25
|
-
Furthermore, it's possible to speak out custom messages anywhere in your App logic, for example when a component receives focus, as a reaction to user input, or to announce error messages when a remote API call
|
|
26
|
-
fails.
|
|
27
|
-
|
|
28
|
-
Each component in Blits has a `this.$announcer.speak()` available, which accepts a `string` with the message to be announced.
|
|
29
|
-
|
|
30
|
-
```js
|
|
31
|
-
Blits.Component('MyComponent', {
|
|
32
|
-
// ...
|
|
33
|
-
hooks: {
|
|
34
|
-
focus() {
|
|
35
|
-
this.$announcer.speak('MyComponent just got focus')
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
keys: {
|
|
39
|
-
right() {
|
|
40
|
-
if(this.focused === this.items.length - 1) {
|
|
41
|
-
this.$announcer.speak('End of row reached')
|
|
42
|
-
} else {
|
|
43
|
-
//
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Execute logic when done
|
|
51
|
-
|
|
52
|
-
The `speak()`-function returns a promise that resolves when it's done speaking, or when it's interupted or errors out. The reason of the `speak()` method resolving is passed as an argument into the resolve function.
|
|
53
|
-
|
|
54
|
-
```js
|
|
55
|
-
this.$announcer.speak('Hello').then((reason) => console.log('Speaking hello finished', reason))
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### Announcement queue
|
|
59
|
-
|
|
60
|
-
The `speak()`-method places the messages in an announcement queue and then starts processing that queue. That means that when the queue is empty, it will instantly announce the messages passed. If there are other messages in the queue, the messages will be spoken when all previous messages are announced.
|
|
61
|
-
|
|
62
|
-
Optionally you can set the politeness of a message to `assertive` and pass it a the second argument of the `speak()`-method.
|
|
63
|
-
|
|
64
|
-
```js
|
|
65
|
-
this.$announcer.speak('Very important message that should get priority', 'assertive')
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
This will place the message at the beginning of the queue, making in the first message to be announced after the current message (if any) has finished.
|
|
69
|
-
|
|
70
|
-
#### Clearing and interupting
|
|
71
|
-
|
|
72
|
-
Since each message added into the queue may take a bit of time to actually be announced, it's possible that the user has navigated elsewhere in the mean time, making the queued up messages not relevant.
|
|
73
|
-
|
|
74
|
-
The announcer plugin allows you to clear the entire queue by calling `this.$announcer.clear()`. Additionally if you want to interup the messages being currently spoken, the announcer plugin offers the `this.$announcer.stop()`-method.
|
|
75
|
-
|
|
76
|
-
#### Canceling individual messages
|
|
77
|
-
|
|
78
|
-
In some cases you may not want to clear the entire queue, but instead cancel out a single message.
|
|
79
|
-
|
|
80
|
-
Imagine an App with a row of tiles, it's possible that before the title of the role is being spoken out, the user already navigates through the tiles within the row. Traditionally you'd use the focus event to speak out info about each tile (i.e. adding tot the queue). You don't want all previously focused tiles to still be announced, but would still want the category of the row to be announced, making clearing the queue not required.
|
|
81
|
-
|
|
82
|
-
The `speak()`-method return a Promise that also contains a `cancel()` function. When called, it will cancel that specific message and remove it from the queue before it can be spoken out.
|
|
83
|
-
|
|
84
|
-
Additionally if you want to _interrupt_ a specific messages as it's being spoken out as well and go straight to the next message in the queue (i.e. the newly focused item, for example). You can use the `stop()` message that is returned on the Promise returned by the `speak()`-method.
|
|
85
|
-
|
|
86
|
-
```js
|
|
87
|
-
Blits.Component('MyTile', {
|
|
88
|
-
//
|
|
89
|
-
props: ['title'],
|
|
90
|
-
state() {
|
|
91
|
-
return {
|
|
92
|
-
message: null
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
hooks: {
|
|
96
|
-
focus() {
|
|
97
|
-
// add message to the announcement queue
|
|
98
|
-
this.message = this.$announcer.speak(`This is tile ${this.title}`)
|
|
99
|
-
},
|
|
100
|
-
unfocus() {
|
|
101
|
-
// when unfocused interrupt the message if it's already being spoken out
|
|
102
|
-
this.message.stop()
|
|
103
|
-
// and cancel the message to remove it from the queue
|
|
104
|
-
this.message.cancel()
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
})
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Enabling / disabling the announcer
|
|
111
|
-
|
|
112
|
-
By default the announcer is disabled. This means that whenever you call `this.$announcer.speak()` there will actually not be anything spoken out via the Text To Speech engine.
|
|
113
|
-
|
|
114
|
-
In order to enable utterances being spoken out, you can set the Blits launch setting `announcer` to `true` in the index.js.
|
|
115
|
-
|
|
116
|
-
Alternatively the announcer can be enabled or disabled run time by using one of the following methods on the Announcer pluging:
|
|
117
|
-
|
|
118
|
-
- `this.$announcer.enable()` - activates the announcer
|
|
119
|
-
- `this.$announcer.disable()` - deactivates the announcer
|
|
120
|
-
- `this.$announcer.disable(true/false)` - turns the announcer or on off
|
package/docs/plugins/theme.md
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
# Theme plugin
|
|
2
|
-
|
|
3
|
-
Blits comes with a built-in, lightweight *Theme* plugin, that can be used to easily add theming capabilities to an App.
|
|
4
|
-
|
|
5
|
-
The Blits Theme plugin provides the option to do real time theme switching, with inheritance from a base theme for missing values.
|
|
6
|
-
|
|
7
|
-
## Registering the plugin
|
|
8
|
-
|
|
9
|
-
The Theme plugin is part of the core Blits package, but it's an optional plugin that needs to be registered in the App's `index.js`,
|
|
10
|
-
as demonstrated in the example below.
|
|
11
|
-
|
|
12
|
-
Make sure to place the `Blits.Plugin()` method _before_ calling the `Blits.Launch()` method
|
|
13
|
-
|
|
14
|
-
```js
|
|
15
|
-
// index.js
|
|
16
|
-
|
|
17
|
-
import Blits from '@lightningjs/blits'
|
|
18
|
-
// import the theme plugin
|
|
19
|
-
import { theme } from '@lightningjs/blits/plugins'
|
|
20
|
-
|
|
21
|
-
import App from './App.js'
|
|
22
|
-
|
|
23
|
-
// Use the Blits Theme plugin
|
|
24
|
-
Blits.Plugin(theme, {
|
|
25
|
-
// theme configuration object
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Blits.Launch(App, 'app', {
|
|
30
|
-
// launch settings
|
|
31
|
-
})
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### Configuration
|
|
35
|
-
|
|
36
|
-
The Theme plugin requires configuration that specifies the theming definition(s).
|
|
37
|
-
|
|
38
|
-
For simple use cases, with one single theme where you just want to abstract and centralize the styling information for an App,
|
|
39
|
-
the configuration object can be a simple object that specifies a theme definition.
|
|
40
|
-
|
|
41
|
-
A theme definition is a completely freeform object literal with key values pairs. It can be organized and constructed however makes most sense for the App. See below an example for inspiration:
|
|
42
|
-
|
|
43
|
-
```js
|
|
44
|
-
Blits.Plugin(theme, {
|
|
45
|
-
colors: {
|
|
46
|
-
primary: '#16a34a',
|
|
47
|
-
secondary: '#2563eb',
|
|
48
|
-
highlight: '#ec4899'
|
|
49
|
-
},
|
|
50
|
-
radius: {
|
|
51
|
-
small: 4,
|
|
52
|
-
medium: 8,
|
|
53
|
-
large: 12
|
|
54
|
-
},
|
|
55
|
-
fontSizes: {
|
|
56
|
-
h1: 80,
|
|
57
|
-
h2: 64,
|
|
58
|
-
body: 42
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
> While it's possible to create deeply nested structures in the theme definition, it is recommended to limit the level of nesting for performance reasons.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
When an App has more than 1 theme, the _advanced configuration_ setup can be used. This configuration object can contain the following 3 keys:
|
|
67
|
-
|
|
68
|
-
- `themes` - an object with multiple theme definitions (required)
|
|
69
|
-
- `base` - the name of the base theme in the `themes`-object, that other themes can inherit from (optional, defaults to `default`)
|
|
70
|
-
- `current` - the name of current theme to be used (optional, defaults to `default`)
|
|
71
|
-
|
|
72
|
-
```js
|
|
73
|
-
Blits.Plugin(theme, {
|
|
74
|
-
themes: {
|
|
75
|
-
// Base theme
|
|
76
|
-
base: {
|
|
77
|
-
colors: {
|
|
78
|
-
primary: '#16a34a',
|
|
79
|
-
secondary: '#2563eb',
|
|
80
|
-
highlight: '#ec4899'
|
|
81
|
-
},
|
|
82
|
-
radius: {
|
|
83
|
-
small: 4,
|
|
84
|
-
medium: 8,
|
|
85
|
-
large: 12
|
|
86
|
-
},
|
|
87
|
-
fontSizes: {
|
|
88
|
-
h1: 80,
|
|
89
|
-
h2: 64,
|
|
90
|
-
body: 42
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
// Dark mode theme
|
|
94
|
-
dark: {
|
|
95
|
-
colors: {
|
|
96
|
-
primary: '#042f2e',
|
|
97
|
-
secondary: '#082f49'
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
// Theme with larger font sizes
|
|
101
|
-
large: {
|
|
102
|
-
fontSizes: {
|
|
103
|
-
h1: 160,
|
|
104
|
-
h2: 124,
|
|
105
|
-
body: 84
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
base: 'base',
|
|
110
|
-
current: 'large'
|
|
111
|
-
})
|
|
112
|
-
```
|
|
113
|
-
|
|
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 means that they will inherit missing values from the base theme.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
## Getting theme values
|
|
119
|
-
|
|
120
|
-
With the configuration out of the way, let's look at how to use the specified theme values in an App.
|
|
121
|
-
|
|
122
|
-
The Theme plugin will be available in every component under the `this.$theme`-namespace. It exposes a `get()` method than can be used to
|
|
123
|
-
retrieve values from the currently active theme definition.
|
|
124
|
-
|
|
125
|
-
The `this.$theme.get()`-method accepts a `key`-argument, using _dot-notation_ (i.e. `fonts.large.lineheight`) to reference items in the theme definition. An optional second argument can be provided as a fallback value, in case the key is missing in the theme (as well as in the base theme).
|
|
126
|
-
|
|
127
|
-
Inside of the template, the `this.$theme.get()`-method can be referenced as `$$theme.get()`. The first `$`-sign is used
|
|
128
|
-
to refer to the Component scope (as with any other state variable or computed property in Blits) and the second `$`-sign is the prefix of
|
|
129
|
-
the Theme plugin itself.
|
|
130
|
-
|
|
131
|
-
```js
|
|
132
|
-
Blits.Component('MyComponent', {
|
|
133
|
-
template: `
|
|
134
|
-
<Element>
|
|
135
|
-
<Text content="Hello world"
|
|
136
|
-
:color="$$theme.get('colors.primary', 'blue')"
|
|
137
|
-
:size="$$theme.get('fontSizes.body')"
|
|
138
|
-
/>
|
|
139
|
-
</Element>
|
|
140
|
-
`,
|
|
141
|
-
computed: {
|
|
142
|
-
highlight() {
|
|
143
|
-
return this.$theme.get('colors.highlight')
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
})
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## Changing themes
|
|
150
|
-
|
|
151
|
-
In case you have specified multiple themes, using the advanced configuration, it is possible to do real-time theme switching.
|
|
152
|
-
|
|
153
|
-
Besides the `get()` method, the Theme plugin also exposes a `set()`-method, to change the currently active theme. The `this.$theme.set()`-method accepts the name of the theme as its first argument.
|
|
154
|
-
|
|
155
|
-
```js
|
|
156
|
-
Blits.Component('MyComponent', {
|
|
157
|
-
template: `
|
|
158
|
-
<Element>
|
|
159
|
-
<Text content="Hello world"
|
|
160
|
-
:color="$$theme.get('colors.primary', 'blue')"
|
|
161
|
-
:size="$$theme.get('fontSizes.body')"
|
|
162
|
-
/>
|
|
163
|
-
</Element>
|
|
164
|
-
`,
|
|
165
|
-
input: {
|
|
166
|
-
up() {
|
|
167
|
-
this.$theme.set('dark')
|
|
168
|
-
},
|
|
169
|
-
down() {
|
|
170
|
-
this.$theme.set('default')
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
})
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
All attributes referencing the Theme plugin that are marked as _reactive_ (i.e. those prefixed with a `:`), will update instantly when changing the theme.
|
package/docs/router/basics.md
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
# Router Basics
|
|
2
|
-
|
|
3
|
-
The Blits framework comes with a built-in, performant router that eliminates the need to pull in any additional dependencies into your App.
|
|
4
|
-
|
|
5
|
-
Before we dive into the details, let's first touch base on some key concepts.
|
|
6
|
-
|
|
7
|
-
## Key concepts
|
|
8
|
-
|
|
9
|
-
### Pages are regular Blits Components
|
|
10
|
-
|
|
11
|
-
The router in Blits is primarily used to navigate between Pages in your App. In the context of a Blits App, a Page is just a regular Blits Component. Usually it will be a Component that fills the entire screen. But it is also possible to have only a smaller portion of the screen contain dynamic routed content.
|
|
12
|
-
|
|
13
|
-
### URL hash
|
|
14
|
-
|
|
15
|
-
When navigating to a page, the hash in the URL of the browser will automatically be updated (i.e. `http://localhost:8080/#my/page`) to match the current page. The hash can also be used to _deep-link_ directly into your application. Upon first load, the router functionality will evaluate the URL hash and try to match that to a defined route. If a matching route is found, it will load that page as deep linked content.
|
|
16
|
-
|
|
17
|
-
## Defining Routes
|
|
18
|
-
|
|
19
|
-
Routes are defined in the main Application component, as an Array under the `routes` key of the configuration object.
|
|
20
|
-
|
|
21
|
-
Each route in this array, is an Object literal that includes the following key properties:
|
|
22
|
-
|
|
23
|
-
- `path` - the url hash to the route (i.e. `/my/page`)
|
|
24
|
-
- `component` - the Blits component to render for the route. This can be a direct reference, but also a promise or a dynamic import that resolves to a Blits component
|
|
25
|
-
- `hooks` (optional) - hooks such as `before` can be defined to execute code before navigating to the route
|
|
26
|
-
- `options` (optional) - additional options defining route behaviour, such as `keepAlive` and `inHistory`
|
|
27
|
-
- `transitions` (optional) - used to define custom transitions between pages
|
|
28
|
-
|
|
29
|
-
### Dynamic routes with params
|
|
30
|
-
|
|
31
|
-
Besides static routes such as `/account` and `/settings/wifi/advanced`, the Blits router also supports dynamic routes where URI parts can contain params.
|
|
32
|
-
|
|
33
|
-
To define a param in a route path, prefix a string with a colon (`:`), followed by the name of the param, e.g. `/movies/:genre/:id`. This route path will match a URI hash such as `#/movies/sci-fi/65281918`. The router will take the params and inject them as a `prop` into the Page that's being navigated to.
|
|
34
|
-
|
|
35
|
-
To access these props in the Page component, they must first be defined in the Page component as _props_ first (i.e. `props: ['genre', 'id']`). Once defined, the values (`sci-fi` and `65281918`) in this case, will be available on the `this` scope as `this.genre` and `this.id` (or as `$genre` and `$id` when used in the template), as with any regular Component.
|
|
36
|
-
|
|
37
|
-
#### Using query parameters in routes
|
|
38
|
-
|
|
39
|
-
According to the browser specifications, query parameters are not part of a URL hash. This means that query parameters should be placed _before_ the URL hash (i.e. `http://localhost:5173?id=100&name=john#/my/page/hash`) and implies that "real" query parameters are _not_ part of the route paths.
|
|
40
|
-
|
|
41
|
-
In this case `id` and `name` won't automatically be made available as props inside a Blits component. They can however be retrieved using `document.location.search` in combination with `new URLSearchParams`, and can be used in an App's `index.js` to set dynamic launch settings for example.
|
|
42
|
-
|
|
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
|
-
|
|
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
|
-
|
|
47
|
-
## Router view
|
|
48
|
-
|
|
49
|
-
The routes are loaded into a `<RouterView />` component, which acts as a placeholder for the routed Page components.
|
|
50
|
-
|
|
51
|
-
The `<RouterView />` component can be positioned and sized as you would expect from a normal Blits Component.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
```js
|
|
55
|
-
export default Blits.Application({
|
|
56
|
-
template: `
|
|
57
|
-
<Element>
|
|
58
|
-
<RouterView x="300" y="200" w="1520" h="680" />
|
|
59
|
-
</Element>
|
|
60
|
-
`,
|
|
61
|
-
routes: [
|
|
62
|
-
{ path: '/', component: Home },
|
|
63
|
-
{ path: '/details', component: () => import('./pages/Details.js'), },
|
|
64
|
-
{ path: '/account',
|
|
65
|
-
component: () => {
|
|
66
|
-
// imagine this is an API call or some other async action
|
|
67
|
-
return new Promise((resolve) => {
|
|
68
|
-
resolve(Account)
|
|
69
|
-
})
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
],
|
|
73
|
-
// ...
|
|
74
|
-
})
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Navigation
|
|
78
|
-
|
|
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
|
-
|
|
81
|
-
The `this.$router.to()`-method accepts 3 arguments:
|
|
82
|
-
|
|
83
|
-
- `path` - the path of the route to navigate to
|
|
84
|
-
- `data` (optional) - an object with data to pass into the page as `props`
|
|
85
|
-
- `options` (optional) - additional options defining route behaviour, such as `keepAlive` and `inHistory` (these will overwrite any options specified for a route in the routes array)
|
|
86
|
-
|
|
87
|
-
```js
|
|
88
|
-
export default Blits.Component('Poster', {
|
|
89
|
-
input: {
|
|
90
|
-
enter() {
|
|
91
|
-
this.$router.to('/movie/details', {id: '1', img: 'details.png'}, {inHistory: false})
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Whenever you navigate to a new page, the URL hash will automatically be updated. Unless specified otherwise, navigating to a new page, will add that route to the history stack. The `back` input action is automatically wired up to navigate back down the history stack.
|
|
98
|
-
|
|
99
|
-
## Deeplinking
|
|
100
|
-
|
|
101
|
-
The Router plugin has support for deeplinking. When the App is loaded with a URL hash (i.e. `#/pages/settings/network`), the router will try to match that hash to a defined route. This means that your app can be deep linked into, by simply providing the correct URL hash.
|
|
102
|
-
|
|
103
|
-
This is an important feature for several reasons:
|
|
104
|
-
|
|
105
|
-
- It will allow external sources (like operators and UIs) to link directly to a specific page in your app (i.e. the details page of a specific movie)
|
|
106
|
-
- If dynamic routes are used, the App only loads what is needed, to keep memory usage low and the initial load time fast
|
|
107
|
-
- Data provided in the URL hash can still be used to set the initial state of the App
|
|
108
|
-
|
|
109
|
-
## Backtracking
|
|
110
|
-
|
|
111
|
-
When a user enters your App via a deeplink, there is technically no history available. By default, this means that a Back keypress goes straight to
|
|
112
|
-
the App's `root`-route (i.e. the `Blits.Application()`-component).
|
|
113
|
-
|
|
114
|
-
In some cases, you may want walk back down the logical path of the deeplinked page instead, and navigate to the first existing parent route (i.e. go from `/movies/comedy/american-pie` to `/movies/comedy`).
|
|
115
|
-
|
|
116
|
-
By setting the route option `backtrack` to `true` in the route definition (or in the `this.$router.to()`-method), the router will recursively remove the last part of the route hash, until it finds a valid path to navigate to.
|
|
117
|
-
|
|
118
|
-
```js
|
|
119
|
-
{
|
|
120
|
-
path: '/examples/router-hooks/episode/:id',
|
|
121
|
-
component: Episode,
|
|
122
|
-
transition: PageTransitions.slideInOutUp,
|
|
123
|
-
options: {
|
|
124
|
-
backtrack: true,
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
path: '/examples/router-hooks/episode',
|
|
129
|
-
component: EpisodesOverview,
|
|
130
|
-
},
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
In the example above, the `backtrack` option is set to `true` for the `/examples/router-hooks/episode/:id` route. When the user navigates to `/examples/router-hooks/episode/1`, the `back` input action will navigate to `/examples/router-hooks/episode` instead of exiting the App.
|
|
134
|
-
|
|
135
|
-
## Router API
|
|
136
|
-
|
|
137
|
-
The Router API provides several useful methods and properties for managing routes and navigation:
|
|
138
|
-
|
|
139
|
-
- `this.$router.to()` - navigating to a different location (as discussed above)
|
|
140
|
-
- `this.$router.back()` - programmatically navigate back down the history stack
|
|
141
|
-
- `this.$router.currentRoute` - retrieve the current route
|
|
142
|
-
- `this.$router.routes` - retrieve the list of all routes
|
|
143
|
-
- `this.$router.navigating` - retrieve the current navigating state
|
|
144
|
-
- `this.$router.state` - reactive router state (see below)
|
|
145
|
-
|
|
146
|
-
### Reactive router state
|
|
147
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
154
|
-
```js
|
|
155
|
-
export default Blits.Component('MyComponent', {
|
|
156
|
-
template: `
|
|
157
|
-
<Element w="1920" h="1080">
|
|
158
|
-
<!-- dynamically display the current path -->
|
|
159
|
-
<Text x="100" h="100" :content="$$router.state.path" />
|
|
160
|
-
<!-- show loading text when router is navigating -->
|
|
161
|
-
<Text :show="$showLoader">Loading ...</Text>
|
|
162
|
-
</Element>
|
|
163
|
-
`,
|
|
164
|
-
watch: {
|
|
165
|
-
'$router.state.path'(v, old) {
|
|
166
|
-
Log.info(`Router Path changed from ${old} to ${v}`)
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
computed: {
|
|
170
|
-
showLoader() {
|
|
171
|
-
return this.$router.state.navigating
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
})
|
|
175
|
-
```
|