@lightningjs/blits 0.8.1 → 0.9.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 +10 -0
- package/boilerplate/js/default/src/index.js +2 -8
- package/docs/README.md +0 -21
- package/docs/_sidebar.md +25 -13
- package/docs/built-in/directives.md +44 -0
- package/docs/{component_state.md → components/component_state.md} +37 -5
- package/docs/components/computed_properties.md +48 -0
- package/docs/{lifecycle_events.md → components/lifecycle_events.md} +4 -2
- package/docs/components/methods.md +47 -0
- package/docs/components/props.md +58 -0
- package/docs/{user_input.md → components/user_input.md} +31 -26
- package/docs/components/utilities.md +4 -0
- package/docs/components/watchers.md +36 -0
- package/docs/essentials/application_root.md +21 -0
- package/docs/{components.md → essentials/components.md} +17 -5
- package/docs/{displaying_images.md → essentials/displaying_images.md} +7 -7
- package/docs/essentials/displaying_text.md +77 -0
- package/docs/{element_attributes.md → essentials/element_attributes.md} +17 -12
- package/docs/essentials/template_syntax.md +85 -0
- package/docs/getting_started/file_structure.md +61 -0
- package/docs/getting_started/getting_started.md +47 -0
- package/docs/{introduction.md → getting_started/intro.md} +2 -1
- package/docs/sidebar.json +70 -26
- package/docs/transitions_animations/transitions.md +132 -0
- package/package.json +1 -1
- package/src/component.js +12 -3
- package/src/fontLoader.js +20 -21
- package/src/launch.d.ts +5 -6
- package/src/launch.js +12 -2
- package/src/lib/codegenerator/generator.js +2 -2
- package/src/lib/hooks.js +7 -7
- package/src/lib/lifecycle.js +3 -2
- package/src/lib/setup/base.js +9 -1
- package/src/lib/setup/state.js +1 -1
- package/src/lib/symbols.js +2 -0
- package/boilerplate/js/default/src/fontloader.js +0 -4
- package/docs/computed_properties.md +0 -18
- package/docs/getting_started.md +0 -40
- package/docs/props.md +0 -46
- package/docs/template_syntax.md +0 -65
- package/docs/watchers.md +0 -38
- /package/docs/{text-to-speech-announcer.md → plugins/text-to-speech-announcer.md} +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Blits - Lightning 3 App Development Framework
|
|
2
|
+
|
|
3
|
+
## Transitions
|
|
4
|
+
|
|
5
|
+
So far we have explored how to create components and draw elements on the screen. But everything has
|
|
6
|
+
been rather static so far.
|
|
7
|
+
|
|
8
|
+
We did learn how to _reactively_ changes values and trigger rerenders based on that. So if you try the example below, you'll see that indeed our golden element changes position. But it just jumps from one place to another:
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
export default Blits('Gold', {
|
|
12
|
+
template: `
|
|
13
|
+
<Element color="gold" w="100" h="100" :x="$x" :y=:"$y" />
|
|
14
|
+
`,
|
|
15
|
+
state() {
|
|
16
|
+
return {
|
|
17
|
+
x: 0,
|
|
18
|
+
y: 0,
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
input: {
|
|
22
|
+
enter() {
|
|
23
|
+
this.x = this.x + 100
|
|
24
|
+
this.y = this.y + 50
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Using _transitions_ we really make our App come alive.
|
|
30
|
+
|
|
31
|
+
### Applying a transition
|
|
32
|
+
|
|
33
|
+
Blits offers an easy and intuitive way to apply transitions. All you need to do is add the `.transition` modifier to a reactive attribute, and now whenever you change the value referenced in the attribute, it will automatically _smooth_ into the new value.
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
export default Blits('Gold', {
|
|
37
|
+
template: `
|
|
38
|
+
<Element color="gold" w="100" h="100" :x.transiton="$x" :y.transition=:"$y" />
|
|
39
|
+
`,
|
|
40
|
+
state() {
|
|
41
|
+
return {
|
|
42
|
+
x: 0,
|
|
43
|
+
y: 0,
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
input: {
|
|
47
|
+
enter() {
|
|
48
|
+
this.x = this.x + 100
|
|
49
|
+
this.y = this.y + 50
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
If we try out the modified example above, you'll notice how difference adding a simple transition makes.
|
|
55
|
+
|
|
56
|
+
When the `.transition`-modifier is added to a reactive attribute, a default `ease-in` transition with a duration of `300ms` is applied
|
|
57
|
+
|
|
58
|
+
### Customizing transitions
|
|
59
|
+
|
|
60
|
+
While the default transition will look pretty good out of the box and is great for quickly improving the look of your App, you may want to customize specific transitions.
|
|
61
|
+
|
|
62
|
+
Blits gives you full control over your transitions, with a simple to use format, right inside your template.
|
|
63
|
+
|
|
64
|
+
Instead of referencing your component's state variable directly, you can also supply an inlien `object literal` in the attribute with a `.transition`-modifier. This will allow you to pass a number of options to change the way the transition will work.
|
|
65
|
+
|
|
66
|
+
The transition object must have a `value` key, which references the state variable (or prop or computed property) that triggers the transition.
|
|
67
|
+
|
|
68
|
+
Further more you can specify:
|
|
69
|
+
|
|
70
|
+
- `duration` - the duration of the transition in `ms`
|
|
71
|
+
- `delay` - the time in `ms` after which the transition should initiate
|
|
72
|
+
- `easing` - the easing function of the transition. Can be one of the defaults easing options listed below, or a custom `cubic-bezier` definitions (i.e. `cubic-bezier(0,1.35,.99,-0.07)`).
|
|
73
|
+
|
|
74
|
+
```xml
|
|
75
|
+
<Element color="gold" w="100" h="100"
|
|
76
|
+
:x.transiton="{value: $x, duration: 300, easing: 'ease-in-back', delay: 400}"
|
|
77
|
+
:y.transition=:"{value: $x, duration: 300, easing: 'cubic-bezier(1,-0.64,0.39,1.44)'}">
|
|
78
|
+
</Element>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Besides a reference to the `value`, you can also use dynamic values for the other keys in the transition object. This way you'll be able to dynamically control the delay, duration or easing function.
|
|
82
|
+
|
|
83
|
+
```xml
|
|
84
|
+
<Element color="gold" w="100" h="100"
|
|
85
|
+
:x.transiton="{value: $x, duration: $dynamicDuration, delay: $dynamicDelay}">
|
|
86
|
+
</Element>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Available easing functions
|
|
90
|
+
|
|
91
|
+
- `ease-in`
|
|
92
|
+
- `ease-out`
|
|
93
|
+
- `ease-in-out`
|
|
94
|
+
- `ease-in-sine`
|
|
95
|
+
- `ease-out-sine`
|
|
96
|
+
- `ease-in-out-sine`
|
|
97
|
+
- `ease-in-cubic`
|
|
98
|
+
- `ease-out-cubic`
|
|
99
|
+
- `ease-in-out-cubic`
|
|
100
|
+
- `ease-in-circ`
|
|
101
|
+
- `ease-out-circ`
|
|
102
|
+
- `ease-in-out-circ`
|
|
103
|
+
- `ease-in-back`
|
|
104
|
+
- `ease-out-back`
|
|
105
|
+
- `ease-in-out-back`
|
|
106
|
+
|
|
107
|
+
### Listening to transition events
|
|
108
|
+
|
|
109
|
+
Sometimes you may want to perform an action when a transition ends or when it starts.
|
|
110
|
+
|
|
111
|
+
You can easily hook into these transiti)on events by adding a `start` and `end` key to the transition object. Both value should be a function (or a reference to a `method` on your component).
|
|
112
|
+
|
|
113
|
+
The `start` function will be called when the transition actually starts (after a possible specified delay) and the `end` function is called as soon as the transitions is finished.
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
export default Blits('Gold', {
|
|
117
|
+
template: `
|
|
118
|
+
<Element color="gold" w="100" h="100"
|
|
119
|
+
:x.transiton="{value: $x, start: $transitionBegin, end: $transitionEnd}"
|
|
120
|
+
/>
|
|
121
|
+
`,
|
|
122
|
+
///
|
|
123
|
+
methods: {
|
|
124
|
+
transitionBegin() {
|
|
125
|
+
//
|
|
126
|
+
},
|
|
127
|
+
transitionEnd() {
|
|
128
|
+
//
|
|
129
|
+
},
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
package/package.json
CHANGED
package/src/component.js
CHANGED
|
@@ -40,6 +40,8 @@ import lifecycle from './lib/lifecycle.js'
|
|
|
40
40
|
import Settings from './settings.js'
|
|
41
41
|
import symbols from './lib/symbols.js'
|
|
42
42
|
|
|
43
|
+
let counter = 0
|
|
44
|
+
|
|
43
45
|
const stage = {
|
|
44
46
|
element,
|
|
45
47
|
}
|
|
@@ -56,10 +58,12 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
56
58
|
config.code = codegenerator.call(config, parser(config.template, name, parentComponent))
|
|
57
59
|
}
|
|
58
60
|
|
|
61
|
+
component[symbols.identifier] = ++counter
|
|
62
|
+
|
|
59
63
|
setupBase(component, name)
|
|
60
64
|
|
|
61
65
|
// setup hooks
|
|
62
|
-
registerHooks(config.hooks,
|
|
66
|
+
registerHooks(config.hooks, component[symbols.identifier])
|
|
63
67
|
|
|
64
68
|
// setup props
|
|
65
69
|
// if (config.props) // because of the default props like id - might change this
|
|
@@ -97,7 +101,9 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
97
101
|
setupComponent(parentComponent)
|
|
98
102
|
}
|
|
99
103
|
if (config.hooks && config.hooks.frameTick) {
|
|
100
|
-
renderer.on('frameTick', (r, data) =>
|
|
104
|
+
renderer.on('frameTick', (r, data) =>
|
|
105
|
+
emit('frameTick', component[symbols.identifier], this, [data])
|
|
106
|
+
)
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
this.parent = parentComponent
|
|
@@ -137,7 +143,10 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
137
143
|
})
|
|
138
144
|
|
|
139
145
|
Object.defineProperty(this, symbols.originalState, {
|
|
140
|
-
value:
|
|
146
|
+
value: {
|
|
147
|
+
...((config.state && typeof config.state === 'function' && config.state.apply(this)) || {}),
|
|
148
|
+
...{ hasFocus: false },
|
|
149
|
+
},
|
|
141
150
|
writable: false,
|
|
142
151
|
enumerable: false,
|
|
143
152
|
configurable: false,
|
package/src/fontLoader.js
CHANGED
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { WebTrFontFace, SdfTrFontFace } from '@lightningjs/renderer/core'
|
|
2
2
|
|
|
3
3
|
import Settings from './settings'
|
|
4
|
+
import { renderer } from './launch'
|
|
4
5
|
|
|
5
|
-
export default
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
stage.fontManager.addFontFace(
|
|
19
|
-
new SdfTrFontFace(font.family, {}, font.type, stage, font.png, font.json)
|
|
20
|
-
)
|
|
21
|
-
} else if (font.type === 'web') {
|
|
22
|
-
stage.fontManager.addFontFace(new WebTrFontFace(font.family, {}, font.file))
|
|
6
|
+
export default () => {
|
|
7
|
+
const stage = renderer.driver.stage
|
|
8
|
+
Settings.get('fonts', []).forEach((font) => {
|
|
9
|
+
if (font.type === 'sdf' || font.type === 'msdf') {
|
|
10
|
+
// automatically map png key to file name
|
|
11
|
+
if (!font.png && font.file) {
|
|
12
|
+
font.png = font.file.replace(/\.[^.]+$/, `.${font.type}.png`)
|
|
13
|
+
}
|
|
14
|
+
// automatically map json to file name
|
|
15
|
+
if (!font.json && font.file) {
|
|
16
|
+
font.json = font.file.replace(/\.[^.]+$/, `.${font.type}.json`)
|
|
23
17
|
}
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
stage.fontManager.addFontFace(
|
|
19
|
+
new SdfTrFontFace(font.family, {}, font.type, stage, font.png, font.json)
|
|
20
|
+
)
|
|
21
|
+
} else if (font.type === 'web') {
|
|
22
|
+
stage.fontManager.addFontFace(new WebTrFontFace(font.family, {}, font.file))
|
|
23
|
+
}
|
|
24
|
+
})
|
|
26
25
|
}
|
package/src/launch.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import ApplicationInstance from './application'
|
|
19
|
-
|
|
19
|
+
import {type Stage} from '@lightningjs/renderer'
|
|
20
20
|
interface WebFont {
|
|
21
21
|
/**
|
|
22
22
|
* Name of the font family
|
|
@@ -70,6 +70,9 @@ export type DebugLevel = 0 | 1 | 2
|
|
|
70
70
|
export type LogTypes = 'info' | 'warn' | 'error' | 'debug'
|
|
71
71
|
export type ReactivityModes = 'Proxy' | 'defineProperty'
|
|
72
72
|
|
|
73
|
+
interface ExtensionLoader {
|
|
74
|
+
async (stage: Stage): void
|
|
75
|
+
}
|
|
73
76
|
/**
|
|
74
77
|
* Settings
|
|
75
78
|
*
|
|
@@ -92,11 +95,7 @@ export interface Settings {
|
|
|
92
95
|
/**
|
|
93
96
|
* Debug level for console log messages
|
|
94
97
|
*/
|
|
95
|
-
debugLevel?: DebugLevel | LogTypes[]
|
|
96
|
-
/**
|
|
97
|
-
* Font loader file
|
|
98
|
-
*/
|
|
99
|
-
fontLoader?: any
|
|
98
|
+
debugLevel?: DebugLevel | LogTypes[],
|
|
100
99
|
/**
|
|
101
100
|
* Fonts to be used in the Application
|
|
102
101
|
*/
|
package/src/launch.js
CHANGED
|
@@ -21,6 +21,7 @@ import Settings from './settings.js'
|
|
|
21
21
|
import { initLog, Log } from './lib/log.js'
|
|
22
22
|
import { screenResolutions } from './lib/utils.js'
|
|
23
23
|
import colors from './lib/colors/colors.js'
|
|
24
|
+
import fontLoader from './fontLoader.js'
|
|
24
25
|
|
|
25
26
|
export let renderer
|
|
26
27
|
|
|
@@ -36,11 +37,20 @@ export default (App, target, settings) => {
|
|
|
36
37
|
// })
|
|
37
38
|
// : new MainCoreDriver()
|
|
38
39
|
|
|
40
|
+
if ('fontLoader' in settings) {
|
|
41
|
+
Log.warn(
|
|
42
|
+
`
|
|
43
|
+
|
|
44
|
+
Starting version 0.9.0 of Blits, the Launch setting \`fontLoader\` is not supported / required anymore.
|
|
45
|
+
You can remove the option from your \`src/index.js\`-file. And you can safely remove the file \`src/fontLoader.js\` from your project.
|
|
46
|
+
`
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
39
50
|
renderer = new RendererMain(
|
|
40
51
|
{
|
|
41
52
|
appWidth: settings.w || 1920,
|
|
42
53
|
appHeight: settings.h || 1080,
|
|
43
|
-
coreExtensionModule: settings.fontLoader,
|
|
44
54
|
fpsUpdateInterval: settings.fpsInterval || 1000,
|
|
45
55
|
deviceLogicalPixelRatio:
|
|
46
56
|
settings.pixelRatio ||
|
|
@@ -68,5 +78,5 @@ export default (App, target, settings) => {
|
|
|
68
78
|
}
|
|
69
79
|
}
|
|
70
80
|
|
|
71
|
-
renderer.init().then((
|
|
81
|
+
renderer.init().then(fontLoader).then(initApp)
|
|
72
82
|
}
|
|
@@ -223,7 +223,7 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
223
223
|
parent = ${parent}
|
|
224
224
|
if(!component.key) keys.length = 0
|
|
225
225
|
const scope = Object.assign(component, {
|
|
226
|
-
key: Math.random(),
|
|
226
|
+
key: Math.random().toString(),
|
|
227
227
|
${index}: __index,
|
|
228
228
|
${item}: collection[__index],
|
|
229
229
|
`)
|
|
@@ -241,7 +241,7 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
241
241
|
|
|
242
242
|
if ('key' in templateObject) {
|
|
243
243
|
ctx.renderCode.push(`
|
|
244
|
-
keys.push(${interpolate(templateObject.key, 'scope.')})
|
|
244
|
+
keys.push(${interpolate(templateObject.key, 'scope.')}.toString())
|
|
245
245
|
`)
|
|
246
246
|
} else {
|
|
247
247
|
ctx.renderCode.push(`
|
package/src/lib/hooks.js
CHANGED
|
@@ -19,20 +19,20 @@ import symbols from './symbols.js'
|
|
|
19
19
|
|
|
20
20
|
const cbs = {}
|
|
21
21
|
|
|
22
|
-
export const emit = (hook,
|
|
23
|
-
cbs[
|
|
22
|
+
export const emit = (hook, identifier, scope, data = []) => {
|
|
23
|
+
cbs[identifier] && cbs[identifier][hook] && cbs[identifier][hook].apply(scope, data)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export const privateEmit = (hook,
|
|
26
|
+
export const privateEmit = (hook, identifier, scope) => {
|
|
27
27
|
const symHook = symbols[hook]
|
|
28
|
-
cbs[
|
|
28
|
+
cbs[identifier] && cbs[identifier][symHook] && cbs[identifier][symHook].apply(scope)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export const registerHooks = (hooks = {},
|
|
32
|
-
cbs[
|
|
31
|
+
export const registerHooks = (hooks = {}, identifier) => {
|
|
32
|
+
cbs[identifier] = {}
|
|
33
33
|
// Combines enumerable keys and symbol properties of the 'hooks' object
|
|
34
34
|
const hookKeys = [...Object.keys(hooks), ...Object.getOwnPropertySymbols(hooks)]
|
|
35
35
|
hookKeys.forEach((hook) => {
|
|
36
|
-
if (typeof hooks[hook] === 'function') cbs[
|
|
36
|
+
if (typeof hooks[hook] === 'function') cbs[identifier][hook] = hooks[hook]
|
|
37
37
|
})
|
|
38
38
|
}
|
package/src/lib/lifecycle.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { Log } from './log.js'
|
|
19
19
|
import { emit, privateEmit } from './hooks.js'
|
|
20
|
+
import symbols from './symbols.js'
|
|
20
21
|
|
|
21
22
|
const states = ['init', 'ready', 'focus', 'unfocus', 'destroy']
|
|
22
23
|
|
|
@@ -34,9 +35,9 @@ export default {
|
|
|
34
35
|
this.previous = this.current
|
|
35
36
|
this.current = v
|
|
36
37
|
// emit 'private' hook
|
|
37
|
-
privateEmit(v, this.component.
|
|
38
|
+
privateEmit(v, this.component[symbols.identifier], this.component)
|
|
38
39
|
// emit 'public' hook
|
|
39
|
-
emit(v, this.component.
|
|
40
|
+
emit(v, this.component[symbols.identifier], this.component)
|
|
40
41
|
}
|
|
41
42
|
},
|
|
42
43
|
}
|
package/src/lib/setup/base.js
CHANGED
|
@@ -35,7 +35,7 @@ const shaderAlias = {
|
|
|
35
35
|
rounded: 'radius',
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
export default (component, name) => {
|
|
38
|
+
export default (component, name, identifier) => {
|
|
39
39
|
Object.defineProperties(component.prototype, {
|
|
40
40
|
name: {
|
|
41
41
|
value: name,
|
|
@@ -43,8 +43,15 @@ export default (component, name) => {
|
|
|
43
43
|
enumerable: true,
|
|
44
44
|
configurable: false,
|
|
45
45
|
},
|
|
46
|
+
[symbols.identifier]: {
|
|
47
|
+
value: component[symbols.identifier],
|
|
48
|
+
writable: false,
|
|
49
|
+
enumerable: false,
|
|
50
|
+
configurable: false,
|
|
51
|
+
},
|
|
46
52
|
focus: {
|
|
47
53
|
value: function (e) {
|
|
54
|
+
this[symbols.state].hasFocus = true
|
|
48
55
|
Focus.set(this, e)
|
|
49
56
|
},
|
|
50
57
|
writable: false,
|
|
@@ -53,6 +60,7 @@ export default (component, name) => {
|
|
|
53
60
|
},
|
|
54
61
|
unfocus: {
|
|
55
62
|
value: function () {
|
|
63
|
+
this[symbols.state].hasFocus = false
|
|
56
64
|
this.lifecycle.state = 'unfocus'
|
|
57
65
|
},
|
|
58
66
|
writable: false,
|
package/src/lib/setup/state.js
CHANGED
|
@@ -22,7 +22,7 @@ import symbols from '../symbols.js'
|
|
|
22
22
|
export default (component, state) => {
|
|
23
23
|
component[symbols.stateKeys] = []
|
|
24
24
|
|
|
25
|
-
state = state.apply(component.prototype)
|
|
25
|
+
state = { ...state.apply(component.prototype), ...{ hasFocus: false } }
|
|
26
26
|
Object.keys(state).forEach((key) => {
|
|
27
27
|
if (component[symbols.propKeys] && component[symbols.propKeys].indexOf(key) > -1) {
|
|
28
28
|
Log.error(`State ${key} already exists as a prop`)
|
package/src/lib/symbols.js
CHANGED
|
@@ -3,6 +3,8 @@ export default {
|
|
|
3
3
|
cursorTagStart: Symbol('cursorTagStart'),
|
|
4
4
|
computedKeys: Symbol('computedKeys'),
|
|
5
5
|
destroy: Symbol('destroy'),
|
|
6
|
+
id: Symbol('id'),
|
|
7
|
+
identifier: Symbol('identifier'),
|
|
6
8
|
index: Symbol('index'),
|
|
7
9
|
init: Symbol('init'),
|
|
8
10
|
inputEvents: Symbol('inputEvents'),
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# Blits - Lightning 3 App Development Framework
|
|
2
|
-
|
|
3
|
-
## Computed properties
|
|
4
|
-
|
|
5
|
-
So far we've learned how to utilize internal state variables and props passed by a parent in (the template of) our component.
|
|
6
|
-
We can even perform simple operations like `Math.max()` or `str.toUpperCase()` directly within an argument of the template.
|
|
7
|
-
|
|
8
|
-
However, sometimes it's more clear and more maintainable to abstract these operations into what we call _computed properties_.
|
|
9
|
-
|
|
10
|
-
Within the computed key of the Component configuration object, you can specify a set of functions. Each function name you define (`offset()` for example) becomes accessible as a computed property.
|
|
11
|
-
|
|
12
|
-
In your template, you can reference these computed properties by prefixing them with a dollar sign (e.g., `$offset`). In the rest of your app's code, you can access these computed properties (but not modify them) using `this.offset`.
|
|
13
|
-
|
|
14
|
-
Within a computed property, you can reference one or more state variables or props and return a value based on calculations or logical operations.
|
|
15
|
-
|
|
16
|
-
Whenever the value of any referenced variable changes, the computed property will automatically recalculate. If a computed property is referenced reactively in the template (i.e., prefixed with colons `:`), it will also trigger an automatic rerender of that portion of the template.
|
|
17
|
-
|
|
18
|
-
Computed properties are a powerful tool for enhancing the readability of your component code. By abstracting complex or frequently used calculations into computed properties, you can make your code (and especially your template) more concise and easier to understand.
|
package/docs/getting_started.md
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Blits - Lightning 3 App Development Framework
|
|
2
|
-
|
|
3
|
-
## Getting Started
|
|
4
|
-
|
|
5
|
-
To begin with Blits, follow these simple steps to set up your development environment and create your first Lightning 3 App.
|
|
6
|
-
|
|
7
|
-
### Installation
|
|
8
|
-
|
|
9
|
-
1. Open your terminal or command prompt.
|
|
10
|
-
|
|
11
|
-
2. Run the following command to start a new Blits Lightning 3 App project:
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npx @lightningjs/blits@latest
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
You will be guide through a few short questions, to generate a new project with all the boilerplate code you need to start building your own Lightning 3 App.
|
|
18
|
-
|
|
19
|
-
3. Navigate to the newly created project directory and install the project dependencies:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
cd my_blits_app
|
|
23
|
-
npm install
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
### Running Your App
|
|
27
|
-
|
|
28
|
-
4. After installing the dependencies, you can start your development server by running:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npm run dev
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
This command will create an application bundle and launch a development server using Vite.
|
|
35
|
-
|
|
36
|
-
2. 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.
|
|
37
|
-
|
|
38
|
-
### Next steps
|
|
39
|
-
|
|
40
|
-
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.
|
package/docs/props.md
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# Blits - Lightning 3 App Development Framework
|
|
2
|
-
|
|
3
|
-
## Props
|
|
4
|
-
|
|
5
|
-
Components in Blits have their own internal state and logic. However, as each component is part of the larger app's scope, they may need to display different behaviors or appearances based on the rest of the app. To achieve this, components can receive `props` from their parent component.
|
|
6
|
-
|
|
7
|
-
In the Component configuration object, you can specify exactly which props a component can accept. These props are passed to the child component via attributes in the parent component's template. Any attributes not explicitly defined as a prop will be ignored.
|
|
8
|
-
|
|
9
|
-
The `props` key in the Component configuration object should be an `Array`, where each item corresponds to a prop that the component can accept. The simplest way to define props is to list their names within the `props` array.
|
|
10
|
-
|
|
11
|
-
```javascript
|
|
12
|
-
{
|
|
13
|
-
props: ['x', 'color', 'index', 'alpha']
|
|
14
|
-
}
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
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 your component's state (i.e. `<Element color="$color" />`). Likewise, you can access a prop inside a component's code (e.g., inside the `ready()` lifecycle hook) using `this.color` (note: without a dollar sign!).
|
|
18
|
-
|
|
19
|
-
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 can either reference the prop inside the component state (using `this.myprop`) or use the prop in a `computed` property.
|
|
20
|
-
|
|
21
|
-
For more advanced usage, you can define props using an array of objects for each prop. Within each prop object, you can:
|
|
22
|
-
|
|
23
|
-
- Specify a _default value_ for the prop if it's omitted.
|
|
24
|
-
- _Validate_ the value of the prop based on certain criteria.
|
|
25
|
-
- Mark the prop as _required_.
|
|
26
|
-
- Apply a `cast` function to modify the value passed as a prop.
|
|
27
|
-
|
|
28
|
-
```js
|
|
29
|
-
export default Blits.Component('MyComponent', {
|
|
30
|
-
// ...
|
|
31
|
-
props: [
|
|
32
|
-
'color',
|
|
33
|
-
{
|
|
34
|
-
key: 'alpha',
|
|
35
|
-
default: 0.5,
|
|
36
|
-
required: true,
|
|
37
|
-
validate(v) {
|
|
38
|
-
return v <= 1 && v >= 0;
|
|
39
|
-
},
|
|
40
|
-
cast: Number
|
|
41
|
-
}
|
|
42
|
-
]
|
|
43
|
-
})
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
You can mix and match the simple string notation with the more advanced object notation within the same `props` array.
|
package/docs/template_syntax.md
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Blits - Lightning 3 App Development Framework
|
|
2
|
-
|
|
3
|
-
## Template structure
|
|
4
|
-
|
|
5
|
-
Blits uses an easy-to-read _XML-style_ template syntax. The syntax is inspired by frameworks like VueJS, so developers familiar with Vue will recognize certain concepts.
|
|
6
|
-
|
|
7
|
-
The _template_ key in the Componentn configuration object holds a string with an XML-like structure. Templates often span multiple lines, so it's advisable to use a JS template literal.
|
|
8
|
-
|
|
9
|
-
You can use different tags in your templates. And similar to HTML you can use arguments and nested tags. Self-closing tags and HTML-style comments are also supported.
|
|
10
|
-
|
|
11
|
-
The default tag within a template is the `<Element>` tag, which corresponds to a node in the Lightning 3 renderer. For each element, you can define a set of predefined render properties, such as `x`, `y`, `w`, `color`, and more. Detailed information regarding the attributes supported by the `<Element>` tag can be found [here](./element_attributes.md).
|
|
12
|
-
|
|
13
|
-
Consider the following template example:
|
|
14
|
-
|
|
15
|
-
```xml
|
|
16
|
-
<Element x="20" y="20">
|
|
17
|
-
<Element w="100" h="100" x="360" color="#0891b2" />
|
|
18
|
-
<Element w="$width" h="$height" color="$color" />
|
|
19
|
-
<Element :w="$changingWidth" :h="Math.floor($height / 5)" :color="$highlight" />
|
|
20
|
-
</Element>
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Hardcoded arguments
|
|
24
|
-
|
|
25
|
-
In this template, you'll observe certain arguments with hardcoded values. You use these to configure the parts of your component that never change.
|
|
26
|
-
|
|
27
|
-
### Dynamic arguments
|
|
28
|
-
|
|
29
|
-
Additionally, some arguments contain a value prefixed with a dollar sign (`$`), representing _dynamic_ arguments. When the component renders, it automatically populates these dynamic values based on the component's state (or props or computed properties).
|
|
30
|
-
|
|
31
|
-
### Reactive arguments
|
|
32
|
-
|
|
33
|
-
Furthermore, certain arguments are prefixed with a colon sign (`:`), indicating _reactive_ arguments. These are not only dynamically set when your component renders, but also _rerender_ the corresponding part of the template whenever the referenced value in your component's internal state changes. This reactive data binding eliminates the need for manual template patching, as seen in Lightning 2.
|
|
34
|
-
|
|
35
|
-
Reactive arguments support _interpolation_, enabling the use of simple JavaScript instructions, such as ternary conditions or basic string and Math manipulations. For more complex logic, it's recommended to abstract this into a Component method or a Computed property.
|
|
36
|
-
|
|
37
|
-
## Custom components
|
|
38
|
-
|
|
39
|
-
As your component grows in complexity, you may want to reorganize your codebase with custom components, abstracting and reusing both templates and logic.
|
|
40
|
-
|
|
41
|
-
Inside a component template, you can utilize sub-components (i.e. a `Menu` component) and reference them with tags like `<Menu></Menu>`.
|
|
42
|
-
|
|
43
|
-
In order for the `<Menu />` tag to become available for use in a component's template, you first have to `import` the file that exports that component.
|
|
44
|
-
|
|
45
|
-
Next you have to _register_ this imported component using the `components`-key in the configuration object. The `components` key is an _object literal_, where the value is the reference to the Blits component. The key will correspond with the _tag_ that can be used to invoke the component.
|
|
46
|
-
|
|
47
|
-
```js
|
|
48
|
-
|
|
49
|
-
import Menu from './components/menu.js'
|
|
50
|
-
import Button from './components/button.js'
|
|
51
|
-
|
|
52
|
-
export default Blits.Component('MyComponent', {
|
|
53
|
-
components: {
|
|
54
|
-
Menu, // makes <Menu /> available for use in the template
|
|
55
|
-
MyButton: Button, // makes Button available as <MyButton /> in the template
|
|
56
|
-
},
|
|
57
|
-
template: `
|
|
58
|
-
<Element>
|
|
59
|
-
<Menu />
|
|
60
|
-
<MyButton />
|
|
61
|
-
</Element>
|
|
62
|
-
`
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
```
|
package/docs/watchers.md
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# Blits - Lightning 3 App Development Framework
|
|
2
|
-
|
|
3
|
-
## Watching for Changes
|
|
4
|
-
|
|
5
|
-
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.
|
|
6
|
-
|
|
7
|
-
You might be tempted to handle this functionality inside a computed property, but this is not recommended. Computed properties should not have side effects, as side effects could potentially lead your app into an endless loop if not handled carefully.
|
|
8
|
-
|
|
9
|
-
Instead, Blits allows you to specify **watchers**.
|
|
10
|
-
|
|
11
|
-
### Using Watchers
|
|
12
|
-
|
|
13
|
-
Within the `watch` key of the Component configuration object, you can define an object of _watcher functions_.
|
|
14
|
-
|
|
15
|
-
The name of each function should correspond to the name of the internal state variable, prop, or computed property that you want to watch. Whenever the target value changes, the respective watcher function will be invoked.
|
|
16
|
-
|
|
17
|
-
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.
|
|
18
|
-
|
|
19
|
-
### Example:
|
|
20
|
-
|
|
21
|
-
```javascript
|
|
22
|
-
{
|
|
23
|
-
state() {
|
|
24
|
-
return {
|
|
25
|
-
alpha: 0.2
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
watch: {
|
|
29
|
-
alpha(value, oldValue) {
|
|
30
|
-
if(value > oldValue) {
|
|
31
|
-
// Execute some logic when the 'alpha' value increases
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
In this example, whenever the 'alpha' value changes, the watcher function associated with 'alpha' will be invoked. The function checks if the new value is greater than the old value and executes custom logic accordingly.
|
|
File without changes
|