@lightningjs/blits 1.30.2 → 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.
Files changed (152) hide show
  1. package/CHANGELOG.md +1029 -1019
  2. package/LICENSE +202 -202
  3. package/NOTICE +12 -12
  4. package/README.md +33 -33
  5. package/bin/index.js +8 -8
  6. package/blits.d.ts +6 -6
  7. package/index.d.ts +1099 -1099
  8. package/index.js +28 -28
  9. package/package.json +57 -56
  10. package/public/assets/fps_sprite.base64.js +1 -1
  11. package/scripts/postpublish.js +59 -59
  12. package/scripts/prepublishOnly.js +84 -84
  13. package/scripts/prepush.js +78 -78
  14. package/src/announcer/announcer.js +162 -162
  15. package/src/announcer/speechSynthesis.js +107 -107
  16. package/src/application.js +100 -100
  17. package/src/component/base/announcer.js +27 -27
  18. package/src/component/base/events.js +69 -69
  19. package/src/component/base/index.js +33 -33
  20. package/src/component/base/methods.js +244 -244
  21. package/src/component/base/router.js +41 -41
  22. package/src/component/base/timeouts_intervals.js +99 -99
  23. package/src/component/base/utils.js +72 -72
  24. package/src/component/setup/computed.js +48 -48
  25. package/src/component/setup/index.js +62 -62
  26. package/src/component/setup/input.js +30 -30
  27. package/src/component/setup/methods.js +37 -37
  28. package/src/component/setup/props.js +62 -62
  29. package/src/component/setup/routes.js +42 -42
  30. package/src/component/setup/state.js +59 -59
  31. package/src/component/setup/watch.js +35 -35
  32. package/src/component.js +437 -437
  33. package/src/components/Circle.js +73 -73
  34. package/src/components/FPScounter.js +1510 -1510
  35. package/src/components/RouterView.js +81 -81
  36. package/src/components/Sprite.js +94 -94
  37. package/src/components/index.js +28 -28
  38. package/src/constants.js +21 -21
  39. package/src/engine.js +1 -1
  40. package/src/engines/L3/element.js +744 -744
  41. package/src/engines/L3/fontLoader.js +38 -38
  42. package/src/engines/L3/index.js +7 -7
  43. package/src/engines/L3/launch.js +123 -123
  44. package/src/engines/L3/shaderLoader.js +12 -12
  45. package/src/engines/index.js +1 -1
  46. package/src/focus.js +90 -90
  47. package/src/helpers/deepEqualArray.js +50 -50
  48. package/src/helpers/fetchJson.js +34 -34
  49. package/src/helpers/sequence.js +26 -26
  50. package/src/launch.js +123 -123
  51. package/src/lib/blitsfileconverter/blitsfileconverter.js +52 -52
  52. package/src/lib/codegenerator/generator.js +788 -788
  53. package/src/lib/colors/colors.js +92 -92
  54. package/src/lib/colors/htmlColors.js +168 -168
  55. package/src/lib/componentId.js +49 -49
  56. package/src/lib/eventListeners.js +123 -123
  57. package/src/lib/hooks.js +59 -59
  58. package/src/lib/lifecycle.js +85 -85
  59. package/src/lib/log.js +117 -117
  60. package/src/lib/precompiler/precompiler.js +73 -73
  61. package/src/lib/reactivity/effect.js +93 -93
  62. package/src/lib/reactivity/reactive.js +208 -208
  63. package/src/lib/reactivityguard/computedprops.js +218 -218
  64. package/src/lib/symbols.js +108 -108
  65. package/src/lib/templateparser/parser.js +386 -386
  66. package/src/lib/utils.js +27 -27
  67. package/src/plugin.js +27 -27
  68. package/src/plugins/appstate.js +26 -26
  69. package/src/plugins/index.js +20 -20
  70. package/src/plugins/language.js +152 -152
  71. package/src/plugins/log.js +25 -25
  72. package/src/plugins/theme.js +94 -94
  73. package/src/router/router.js +516 -514
  74. package/src/router/transitions/fadeIn.js +27 -27
  75. package/src/router/transitions/fadeInOut.js +33 -33
  76. package/src/router/transitions/index.js +21 -21
  77. package/src/router/transitions/slideIn.js +28 -28
  78. package/src/router/transitions/slideInOut.js +33 -33
  79. package/src/settings.js +40 -40
  80. package/vite/blitsFileConverter.js +67 -67
  81. package/vite/index.js +28 -28
  82. package/vite/msdfGenerator.js +269 -269
  83. package/vite/preCompiler.js +47 -42
  84. package/vite/reactivityGuard.js +45 -45
  85. package/vscode/data/template-attributes.json +589 -589
  86. package/.editorconfig +0 -7
  87. package/.eslintignore +0 -1
  88. package/.eslintrc.cjs +0 -65
  89. package/.github/workflows/comment-lint-results.yml +0 -125
  90. package/.github/workflows/comment-test-results.yml +0 -109
  91. package/.github/workflows/deploy-docs.yml +0 -27
  92. package/.github/workflows/run-blits-tests.yml +0 -142
  93. package/.github/workflows/run-lint.yml +0 -128
  94. package/.husky/pre-commit +0 -1
  95. package/.husky/pre-push +0 -1
  96. package/.vscode/extensions.json +0 -7
  97. package/.vscode/settings.json +0 -9
  98. package/COPYING +0 -1
  99. package/banner.png +0 -0
  100. package/docs/.nojekyll +0 -0
  101. package/docs/README.md +0 -19
  102. package/docs/_sidebar.md +0 -37
  103. package/docs/built-in/directives.md +0 -50
  104. package/docs/built-in/for-loop.md +0 -204
  105. package/docs/built-in/layout.md +0 -168
  106. package/docs/components/component_state.md +0 -90
  107. package/docs/components/computed_properties.md +0 -45
  108. package/docs/components/lifecycle_events.md +0 -42
  109. package/docs/components/methods.md +0 -45
  110. package/docs/components/props.md +0 -56
  111. package/docs/components/user_input.md +0 -186
  112. package/docs/components/utility_methods.md +0 -320
  113. package/docs/components/watchers.md +0 -34
  114. package/docs/essentials/application_root.md +0 -19
  115. package/docs/essentials/components.md +0 -68
  116. package/docs/essentials/displaying_images.md +0 -67
  117. package/docs/essentials/displaying_text.md +0 -135
  118. package/docs/essentials/element_attributes.md +0 -195
  119. package/docs/essentials/settings.md +0 -117
  120. package/docs/essentials/template_syntax.md +0 -83
  121. package/docs/getting_started/file_structure.md +0 -58
  122. package/docs/getting_started/getting_started.md +0 -45
  123. package/docs/getting_started/intro.md +0 -20
  124. package/docs/index.html +0 -47
  125. package/docs/performance/lazy-loading.md +0 -161
  126. package/docs/plugins/global_app_state.md +0 -98
  127. package/docs/plugins/language.md +0 -172
  128. package/docs/plugins/text-to-speech-announcer.md +0 -120
  129. package/docs/plugins/theme.md +0 -176
  130. package/docs/router/basics.md +0 -175
  131. package/docs/router/hooks.md +0 -70
  132. package/docs/router/transitions.md +0 -146
  133. package/docs/sidebar.json +0 -171
  134. package/docs/transitions_animations/transitions.md +0 -150
  135. package/jsconfig.json +0 -12
  136. package/src/component/setup/props.test.js +0 -238
  137. package/src/component.test.js +0 -388
  138. package/src/components/Circle.orig.js +0 -31
  139. package/src/components/FPScounter.orig.js +0 -121
  140. package/src/components/RouterView.orig.js +0 -54
  141. package/src/components/Sprite.orig.js +0 -58
  142. package/src/components/index.orig.js +0 -28
  143. package/src/engines/L3/element.test.js +0 -579
  144. package/src/helpers/deepEqualArray.test.js +0 -127
  145. package/src/lib/codegenerator/generator.test.js +0 -3801
  146. package/src/lib/colors/colors.test.js +0 -290
  147. package/src/lib/componentId.test.js +0 -84
  148. package/src/lib/eventListeners.test.js +0 -236
  149. package/src/lib/reactivity/effect.test.js +0 -35
  150. package/src/lib/reactivity/reactive.test.js +0 -27
  151. package/src/lib/templateparser/parser.test.js +0 -1411
  152. package/src/router/router.test.js +0 -473
@@ -1,45 +0,0 @@
1
- # Methods
2
-
3
- Within a Blits component, you have quite some freedom where to put specific logic.
4
-
5
- Template related logic can be either placed directly in a _reactive / interpolated_ attribute or you can move it out to a _computed property_ if the logic is more complex.
6
-
7
- Business logic for your App can be placed directly in a _watcher_, a _lifecycle hook_ or an _input handling_ function.
8
-
9
- If you notice that you're duplicating logic in these different places, or if you just like to keep all your business logic nicely grouped together, you can move these business logic functions under the `methods` key of the _Component configuration object_.
10
-
11
- You can reference your Component's methods in the template by using a `$`-sign (for example in the `@loaded`-attribute when your element has a `src` attribute).
12
-
13
- In the javascript code of a Component, you can reference methods directly on the `this`-scope (i.e. `this.getData()`). Similar to `internal` state and `props`, there is no need to prefix with `methods`, for easy access.
14
-
15
- ```js
16
- export default Blits.Component('Carousel', {
17
- template: `
18
- <Element>
19
- <!-- .... -->
20
- </Element>
21
- `,
22
- state() {
23
- return {
24
- items: [],
25
- page: 0
26
- }
27
- },
28
- hooks: {
29
- ready() {
30
- this.fetchData()
31
- }
32
- },
33
- input: {
34
- down() {
35
- this.page++
36
- this.fetchData()
37
- }
38
- },
39
- methods: {
40
- async fetchData() {
41
- this.items = await API.get(['movies', 'tvshows', 'documentaries'], this.page)
42
- },
43
- }
44
- })
45
- ```
@@ -1,56 +0,0 @@
1
- # Props
2
-
3
- Components in Blits have their own [internal state](./component_state.md) and logic, and as such a Component is self-contained. However, as each component is part of a larger App scope, they may need to display different behaviors or appearances based on the rest of the app.
4
-
5
- To achieve this, components can receive `props` from their parent component.
6
-
7
- ## Defining and passing props
8
-
9
- In the Component configuration object, you can specify exactly which props a component accepts. These props are passed to the component via attributes in the parent component's template. Any attributes that are not explicitly defined as a prop will be ignored.
10
-
11
- The `props` key in the Component configuration object should be an `Array`, where each item corresponds to a prop that the component can accept.
12
-
13
- The simplest way to define props is to just list their names within the `props` array:
14
-
15
- ```js
16
- {
17
- props: ['x', 'color', 'index', 'alpha']
18
- }
19
- ```
20
-
21
- Once specified, you can refer to these props inside the template of your component using the `$` sign, similar to how you would reference variables defined within the component's [internal state](./component_state.md) (i.e. `<Element color="$color" />`).
22
-
23
- You can also access a prop inside a component's code using `this.color` (without a dollar sign!). And similar to component `state` variables,
24
- there is no need to specifically reference the `props`-key. Blits automatically maps all props directly on the `this`-scope, for easy access.
25
-
26
- Since props are used to pass information from a parent to a child, it's important not to attempt to _modify_ props inside your child component. If changes based on the prop from the parent are needed, you should probably use the prop in a so called [computed property](./computed_properties.md).
27
-
28
- ## Advanced usage
29
-
30
- For more advanced usage, you can define props using an array with an `object` for each prop, instead of just a string with the accepted name. Within each prop object, you can:
31
-
32
- - Specify a _default value_ for the prop if it's omitted.
33
- - _Validate_ the value of the prop based on certain criteria.
34
- - Mark the prop as _required_.
35
- - Apply a `cast` function to modify the value passed as a prop.
36
-
37
- As you can see in the following example, you can mix and match the simple string notation with the advanced object notation within the same `props` array.
38
-
39
-
40
- ```js
41
- export default Blits.Component('MyComponent', {
42
- // ...
43
- props: [
44
- 'color',
45
- {
46
- key: 'alpha',
47
- default: 0.5,
48
- required: true,
49
- validate(v) {
50
- return v <= 1 && v >= 0;
51
- },
52
- cast: Number
53
- }
54
- ]
55
- })
56
- ```
@@ -1,186 +0,0 @@
1
- # Handling User Input
2
-
3
- In order to allow users to interact with your app, you will want to capture and handle _user input_. If you are developing a TV based app this will often be key input via a remote control.
4
-
5
- Blits offers an intuitive and straightforward interface to handle key input in Components.
6
-
7
- ## Focus
8
-
9
- Before diving into the specifics of key handling, it is important to understand the basic concept of _focus_.
10
-
11
- In a Blits app, there is always _one_ Component that has the focus. By default, this will be the root Application component.
12
-
13
- The component that has focus, is the one that is responsible for handling the user input at that moment.
14
-
15
- For example, when a user clicks the _right_ or _left_ button while a _Poster Component_ has focus, it is that instance of the Poster Component that will _receive_ the first key press event.
16
-
17
- ## Configuring Input Handling
18
-
19
- Within the Component configuration object, the `input` key is used to define how the component should react to specific key presses when it has focus. The `input` key should be an `object literal` of `functions` for each input event that the component wants to handle.
20
-
21
- Each function corresponds to a _key press name_, such as `up`, `down`, `enter`, `space`, `back`, `1`, `2`, `a` etc and each function defined in the `input` object, receives the full `InputEvent` object as its first argument.
22
-
23
- ```js
24
- export default Blits.Component('MyComponent', {
25
- // ...
26
- input: {
27
- up(e) {
28
- // Logic to execute when users press up
29
- },
30
- down(e) {
31
- // Logic to execute when users press down
32
- },
33
- enter(e) {
34
- // Logic to execute when users press enter
35
- },
36
- }
37
- }
38
- ```
39
-
40
- ## Catch-All Handling
41
-
42
- To allow a focused component to respond to any key and act as a _catch-all_, you can add an `any()` function to the input object. As it receives the `InputEvent` object as the first argument, you can abstract the key press in there and handle (or ignore) it as you wish.
43
-
44
- ```javascript
45
- {
46
- input: {
47
- any(e) {
48
- // Logic to execute for any key press
49
- },
50
- }
51
- }
52
- ```
53
-
54
- ## Event Handling Chain
55
-
56
- If the currently focused component does not handle a key press, Blits will traverse up the component hierarchy, checking for any _parent_ component that does have a function defined for that key press in the `input`-key. This input event handling chain continues until it reaches the root Application component.
57
-
58
- When a component handles a key press by having a corresponding function specified, said component receives focus, and the event handling chain stops by default. However, if you want the input event to propagate up the hierarchy further, you can move the focus to the parent element and pass the `InputEvent` object on in that function call.
59
-
60
- ```javascript
61
- {
62
- input: {
63
- enter() {
64
- // Give focus to the parent
65
- this.parent.focus();
66
- },
67
- back(e) {
68
- // Give focus to the parent and let the user input event bubble
69
- this.parent.focus(e);
70
- },
71
- }
72
- }
73
- ```
74
-
75
- ## Intercepting key input
76
-
77
- In addition to the Event handling chain explained above. Blits offers the option to _intercept_ key presses at the root level of the Application, before they reach the currently focused Component. This can be useful in certain situation where you want to globally disable all key presses, or when implementing an override key press handler.
78
-
79
- The `intercept()` input-method can only be implemented in the `Blits.Application`-component. When present, the method acts as a _catch-all_ method, and will be executed for _all_ key presses. It receives the `KeyboardEvent` as its argument, allowing you to execute logic based on the key being pressed.
80
-
81
- Only when the `intercept()` input-method returns the `KeyboardEvent` (possibly modified), the keypress will continue to be handled (by the currently focused Component).
82
-
83
- The `intercept`-method can also be an asynchronous method.
84
-
85
- ## Key-up handling
86
-
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
-
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
-
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
-
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
-
95
-
96
- ```javascript
97
- Blits.Component('MyComponent', {
98
- //
99
- input: {
100
- enter() {
101
- // execute logic on key down
102
- this.pressedEnter = true
103
- return () => {
104
- // execute logic on key up
105
- this.pressedEnter = false
106
- }
107
- },
108
- space(e) {
109
- // not logic on key down
110
- return () => {
111
- // only execute logic on key up
112
- console.log('Space key released')
113
- }
114
- },
115
- left() {
116
- // some logic on key down here ..
117
- this.leftHold = true
118
- // return a reference to a Component method
119
- // (instead of creating a new function on the fly)
120
- return this.leftKeyUp
121
- }
122
- },
123
- methods: {
124
- leftKeyUp() {
125
- console.log('Left key up')
126
- this.leftHold = false
127
- }
128
- }
129
- }
130
- ```
131
-
132
- ## Custom Keycode mapping
133
-
134
- Blits comes with a default keycode mapping. This mapping is a sensible default that works in your desktop browser and with most RDK based devices.
135
-
136
- But it's possible that the keycodes and mapping of your target device are slightly or even completely different.
137
-
138
- In Blits, you can easily configure the key mapping to match your needs. In the `src/index.js` file where we instantiate the App via the `Blits.Launch` function, we can add an extra key, called `keymap`, to the _settings object_.
139
-
140
- The `keymap` should contain an object literal, where you map a `key` or `keyCode` (from the `KeyboardEvent`) to an event name that you can use in your Components.
141
-
142
- > You can use a site like [keyjs.dev](https://keyjs.dev/) to find the appropriate key and keyCode for your device
143
-
144
- ```js
145
- // src/index.js
146
- Blits.Launch(App, 'app', {
147
- w: 1920,
148
- h: 1080,
149
- //...
150
- keymap: {
151
- // switch left and right using the key
152
- ArrowLeft: 'right',
153
- ArrowRight: 'left',
154
- // switch up and down using the keyCode
155
- 38: 'down',
156
- 40: 'up',
157
- // register new handlers
158
- '.': 'dot', // dot() can now be used in the input object
159
- // key code for letter 's'
160
- 83: 'search' // search() can now be used in the input object
161
- }
162
- })
163
- ```
164
-
165
- The custom keymap object will be merged with the default key mapping, that looks like this:
166
-
167
- ```js
168
- const defaultKeyMap = {
169
- ArrowLeft: 'left',
170
- ArrowRight: 'right',
171
- ArrowUp: 'up',
172
- ArrowDown: 'down',
173
- Enter: 'enter',
174
- ' ': 'space',
175
- Backspace: 'back',
176
- Escape: 'escape',
177
- 37: 'left',
178
- 39: 'right',
179
- 38: 'up',
180
- 40: 'down',
181
- 13: 'enter',
182
- 32: 'space',
183
- 8: 'back',
184
- 27: 'escape',
185
- }
186
- ```
@@ -1,320 +0,0 @@
1
- # Utility methods
2
-
3
- Besides the methods that are specified in the Component configuration object, each Blits Component comes with a number of
4
- _utility methods_ built in.
5
-
6
- Utility methods are prefixed with a `$`-sign, to clearly indicate they are _framework provided_ methods, that are _not private_, but
7
- intended to be _used by the developer_. The `$`-prefix also helps prevent accidental naming collisions.
8
-
9
- ### $select
10
-
11
- `this.$select()` is used to search for child Elements and Components by reference (`ref`).
12
-
13
- The `$select()`-method accepts a string pointing to a reference as it's only argument, and returns the Element or Component that
14
- matches that `ref`. In order to make an Element or Component findable, the `ref`-attribute should be provided on said Element of Component
15
- in the template.
16
-
17
- ```js
18
- export default Blits.Component('MyComponent', {
19
- components: {
20
- Button,
21
- },
22
- template: `
23
- <Element>
24
- <Element w="1920" h="5" color="green" ref="topBorder" />
25
- <Button text="Button 1" ref="btn1" y="100" />
26
- <Button text="Button 2" ref="btn2" y="200" />
27
- <Button text="Button 3" ref="btn3" y="200" />
28
- </Element>
29
- `,
30
- hooks: {
31
- ready() {
32
- const topBorderElement = this.$select('topBorder')
33
- const button2 = this.$select('btn2')
34
- }
35
- }
36
- })
37
- ```
38
-
39
- > As the `this.$select()` gives direct access to an Element or a Component, it allows the developer to directly interact with it. There are valid use cases, but direct manipulation of Elements, calling methods and changing properties on a Component comes with risks. It circumvents the whole structure of reactivity and props communication built into Blits, and can lead to unexpected situations or anti-patterns. So use with care!
40
-
41
- ### $focus
42
-
43
- The `$focus()`-method can be used to set the focus to a Component instance. It can either be called on the instance itself, in order to "claim"
44
- the focus. But more often it will be used to delegate the focus from on Component to another.
45
-
46
- > It is important to understand that only a Component can receive focus in Blits. Elements don't have a focus method, and also have no way of reacting to focus changes (because they have no hooks etc.).
47
-
48
- Often focus will be passed onto a child component, for example in the case of a list or swimlane, where you want to delegate the focus to a poster.
49
- In this case the focus method will be used in combination with `this.$select()` to first select the desired child Component by ref, and subsequently call the `$focus()` method on that Component.
50
-
51
- ```js
52
- export default Blits.Component('MyComponent', {
53
- components: {
54
- Button,
55
- },
56
- template: `
57
- <Element>
58
- <Element w="1920" h="5" color="green" ref="topBorder" />
59
- <Button text="Button 1" ref="btn1" y="100" />
60
- <Button text="Button 2" ref="btn2" y="200" />
61
- <Button text="Button 3" ref="btn3" y="200" />
62
- </Element>
63
- `,
64
- state() {
65
- focusIndex: 1
66
- },
67
- input: {
68
- down() {
69
- this.focusIndex--
70
- const button = this.$select(`btn${this.focusIndex}`)
71
- if(button) {
72
- button.$focus()
73
- }
74
- },
75
- up() {
76
- this.focusIndex++
77
- const button = this.$select(`btn${this.focusIndex}`)
78
- if(button) {
79
- button.$focus()
80
- }
81
- },
82
- }
83
- })
84
- ```
85
-
86
- Another frequent case is that focus is passed on to the parent Component. The parent component is available on the Component scope as `this.parent`. So passing the focus to the parent is as simple as calling `this.parent.$focus()`.
87
-
88
- The `$focus`-method accepts an optional `event` parameter, which is of the type `KeyboardEvent`. When the `event` parameter is provided, not only will the selected Component receive focus, but the input event will be emitted again on the component that just received focus.
89
-
90
- This can be used to _bubble up_ input events (specified in the `input` key of the component configuration object) and helps to create a smooth experience, preventing a user to click multiple times.
91
-
92
-
93
- ### $trigger
94
-
95
- Blits has reactivity built-in, which means that re-renders in the template, as well as watchers and computed properties, are automatically fired whenever a state value changes. But sometimes you may want trigger the side effects of a state values change, without actually changing the value. This often is useful when a Component first receives focus and you want to ensure that the default state values are applied.
96
-
97
- Instead of setting a value to `null` and then setting it back to the initial value (which would trigger side effects), the `this.$trigger()` method can be used. The method accepts the name of the state variable as its argument.
98
-
99
- ```js
100
- export default Blits.Component('MyComponent', {
101
- state() {
102
- focusIndex: 1
103
- },
104
- watchers: {
105
- focusIndex(v) {
106
- console.log('I trigger when focusIndex changes')
107
- }
108
- },
109
- hooks: {
110
- focus() {
111
- // even though focusIndex didn't change
112
- // the watcher on focusIndex will be fired
113
- this.$trigger('focusIndex')
114
- }
115
- }
116
- })
117
- ```
118
-
119
- ## Emitting events and passing data
120
-
121
- ### $emit
122
-
123
- When working with Components in Blits you will often want to send data from one to another. In the case of (direct) child Component, using
124
- props is the defacto way for inter-component communication.
125
-
126
- For passing data from a child to a parent component, you may be tempted to use the `this.parent` reference and change the state directly. While this works, it does create a strict dependency on the parent, meaning the child Component only works properly when tied directly to a specific parent. This reduces reusability of Components and may cause limitations or problems later on.
127
-
128
- Instead the `this.$emit()` method can be used, which is available on each Component as a utility function. It's designed to easily emit data to anywhere in an App. The first argument is the `name` of the event that will be emitted (i.e. `changeBackground`) and optionally a second argument with additional `data` can be passed.
129
-
130
- ```js
131
- export default Blits.Component('MyComponent', {
132
- input: {
133
- enter() {
134
- // sending a activate event, without any additional data
135
- this.$emit('activate')
136
- },
137
- space() {
138
- // sending a changeBackground event, with additional data
139
- this.$emit('changeBackground', {
140
- img: './assets/background1.jpg',
141
- delay: 400
142
- })
143
- }
144
- }
145
- })
146
- ```
147
-
148
- ### $listen
149
-
150
- The `$listen` utility method (which is available on each Blits Component) is designed to listen for events emitted by `this.$emit()`.
151
- Any Component can subscribe to any event emitted and as such a flexible system of passing data around can be constructed.
152
-
153
- The first argument of the `$listen()`-method is the event `name` to listen for, and the second argument is a `callback` to be executed
154
- anytime the event occurs. When the event is emitted with additional data, it's passed as the first argument in the callback.
155
-
156
- Generally the listeners are registered in the Component `ready` or `init` hook. Blits automatically takes care of deregistering the listeners whenever a Component is destroyed.
157
-
158
- ```js
159
- export default Blits.Component('MyComponent', {
160
- hooks: {
161
- init() {
162
- // activate event without any additional value
163
- this.$listen('activate', () => {
164
- console.log('activated')
165
- // set a text state valuye
166
- this.text = 'We are active!'
167
- })
168
-
169
- // change background event
170
- this.$listen('changeBackground', (data) => {
171
- setTimeout(() => {
172
- this.backgroundImage = data.img
173
- }, data.delay)
174
- })
175
- },
176
- }
177
- })
178
- ```
179
-
180
- ### $unlisten
181
-
182
- The `$unlisten` utility method (which is available on each Blits Component) is designed to remove event listeners that were previously registered using `$listen()`. This method helps in managing event listeners manually when needed.
183
-
184
- The first argument of the `$unlisten()` method is the event `name` to stop listening for. This ensures that all listeners for the specified event are removed from the component.
185
-
186
- Generally, you might not need to call `$unlisten()` manually, as Blits automatically deregisters listeners when a Component is destroyed. However, it can be useful in scenarios where you need to stop listening for events before the Component is destroyed.
187
-
188
- ```js
189
- export default Blits.Component('MyComponent', {
190
- hooks: {
191
- init() {
192
- this.activateListener = () => {
193
- console.log('activated')
194
- this.text = 'We are active!'
195
- }
196
-
197
- this.changeBackgroundListener = (data) => {
198
- setTimeout(() => {
199
- this.backgroundImage = data.img
200
- }, data.delay)
201
- }
202
-
203
- // Register listeners
204
- this.$listen('activate', this.activateListener)
205
- this.$listen('changeBackground', this.changeBackgroundListener)
206
- },
207
- unfocus() {
208
- // Remove listeners when Component is unfocused
209
- this.$unlisten('activate')
210
- this.$unlisten('changeBackground')
211
- }
212
- }
213
- })
214
- ```
215
-
216
- ## Timeouts
217
-
218
- Setting a timeout is a typical way in JS to execute functionality with a delay. But timeouts can also be a common cause of
219
- memory leaks.
220
-
221
- As long as the timeout is still pending it, it will hold on to references which can prevent a proper garbage collection from happening. That's why it's important to clear timeouts when destroying a component.
222
-
223
- Blits comes with some built-in methods to register and clear timeouts. Under the hood these methods use regular timeouts, but using the Blits built-in methods ensures that timeouts properly are cleared whenever a component is being disposed.
224
-
225
- ### $setTimeout
226
-
227
- The `this.$setTimeout()`-method creates a timeout, using a thin wrapper around the `window.setTimeout()` method. The first argument is the `callback` to be executed after the `delay` specified in the second argument. The method returns a `timeout id`, which can be used to mannually clear the timeout.
228
-
229
- ### $clearTimeout
230
-
231
- The `this.$clearTimeout()`-method is a thin wrapper around the `window.clearTimeout()`-method. By passing in the `id` of a timeout, it will clear and remove the timeout.
232
-
233
- ### $clearTimeouts
234
-
235
- The `this.$clearTimeouts()`-method is a utility method that is used to clear all the timeouts created via the `this.$setTimeout()` method in one go. The method doesn't require to pass any timeout ids. This method is automatically called when destroying a Component, and with that it prevents memory leaks due to dangling timeouts.
236
-
237
- ```js
238
- export default Blits.Component('MyComponent', {
239
- state() {
240
- timeout: null
241
- },
242
- hooks: {
243
- init() {
244
- this.timeout = this.$setTimeout(() => {
245
- console.log('1 minute has passed!')
246
- }, 60000)
247
-
248
- this.$setTimeout(() => {
249
- console.log('10 seconds have passed!')
250
- }, 10000)
251
- },
252
- unfocus() {
253
- // clear all timeouts when Component is unfocused
254
- this.$clearTimeouts()
255
- }
256
- },
257
- input: {
258
- enter() {
259
- // clear the timeout
260
- this.$clearTimeout(this.timeout)
261
- }
262
- }
263
- })
264
- ```
265
-
266
- ## Intervals
267
-
268
- Timeouts are a great way to execute recurring logic, such as polling for updates or periodically updating an animation.
269
-
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
-
272
- For this reason Blits has 3 built-in utility methods to help registering and clearing intervals.
273
-
274
- ### $setInterval
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 manually clear the interval.
277
-
278
- ### $clearInterval
279
-
280
- The `this.$clearInterval()`-method is a thin wrapper around the `window.clearInterval()`-method. By passing in the `id` of an interval, it will clear and remove the interval.
281
-
282
-
283
- ### $clearIntervals
284
-
285
- The `this.$clearIntervals()`-method is a utility method that is used to clear all the intervals created via the `this.$setInterval()` method in one go. The method doesn't require to pass any interval ids. This method is automatically called when destroying a Component, and with that it prevents memory leaks due to dangling intervals.
286
-
287
- ```js
288
- export default Blits.Component('MyComponent', {
289
- state() {
290
- return {
291
- interval: null,
292
- secondCount: 0,
293
- minuteCount: 0,
294
- }
295
- },
296
- hooks: {
297
- init() {
298
- this.interval = this.$setInterval(() => {
299
- this.secondCount++
300
- console.log(`${this.secondCount} second(s) have passed`)
301
- }, 1000)
302
-
303
- this.$setInterval(() => {
304
- this.minuteCount++
305
- console.log(`${this.minuteCount} minute(s) have passed`)
306
- }, 60000)
307
- },
308
- unfocus() {
309
- // clear all intervals when Component is unfocused
310
- this.$clearIntervals()
311
- }
312
- },
313
- input: {
314
- enter() {
315
- // clear the interval
316
- this.$clearInterval(this.interval)
317
- }
318
- }
319
- })
320
- ```
@@ -1,34 +0,0 @@
1
- # Watchers
2
-
3
- In some cases, you may want to execute specific actions whenever the value of a state variable, a prop, or a computed property changes. These actions could involve dispatching an event or updating another state variable.
4
-
5
- You might be tempted to handle this functionality inside a computed property, but this is not recommended. Computed properties should not have side effects, to prevent the risk of falling into an endless loop.
6
-
7
- Instead, Blits allows you to specify **watchers** to trigger functionality when certain variables change.
8
-
9
- ## Using Watchers
10
-
11
- Within the `watch` key of the _Component configuration object_, you can define an object of _watcher functions_.
12
-
13
- The name of each function should correspond with the name of the state variable, the prop, or the computed property that you want to observe. Whenever the value of the observed target changes, the respective watcher function will be invoked.
14
-
15
- The watcher function receives two arguments: the _new value_ and the _old value_ of the observed property. This allows you to perform specific actions based on the changes.
16
-
17
- ```javascript
18
- {
19
- state() {
20
- return {
21
- alpha: 0.2
22
- }
23
- },
24
- watch: {
25
- alpha(value, oldValue) {
26
- if(value > oldValue) {
27
- // Execute some logic when the 'alpha' value increases
28
- }
29
- },
30
- }
31
- }
32
- ```
33
-
34
- In this example, whenever the value of state variable `alpha` changes, the `alpha` watcher function will be invoked. The function checks if the new value is greater than the old value and executes custom logic accordingly.
@@ -1,19 +0,0 @@
1
- # Application root
2
-
3
- Every Blits App starts with a base Application component.
4
-
5
- Ultimately this Application is a component like any regular Blits component. But it is augmented with some extra functionality. `Blits.Application` is responsible for setting up the listeners for keyhandling for example.
6
-
7
- You can only have 1 Application component per App. By default, this file is named `App.js` and it is placed in the root of the `src`-folder.
8
-
9
- `src/App.js` will look something like this:
10
-
11
- ```js
12
- import Blits from '@lightningjs/blits'
13
-
14
- export default Blits.Application({
15
- template: `
16
- <Element></Element>
17
- `,
18
- })
19
- ```