@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.
Files changed (42) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/boilerplate/js/default/src/index.js +2 -8
  3. package/docs/README.md +0 -21
  4. package/docs/_sidebar.md +25 -13
  5. package/docs/built-in/directives.md +44 -0
  6. package/docs/{component_state.md → components/component_state.md} +37 -5
  7. package/docs/components/computed_properties.md +48 -0
  8. package/docs/{lifecycle_events.md → components/lifecycle_events.md} +4 -2
  9. package/docs/components/methods.md +47 -0
  10. package/docs/components/props.md +58 -0
  11. package/docs/{user_input.md → components/user_input.md} +31 -26
  12. package/docs/components/utilities.md +4 -0
  13. package/docs/components/watchers.md +36 -0
  14. package/docs/essentials/application_root.md +21 -0
  15. package/docs/{components.md → essentials/components.md} +17 -5
  16. package/docs/{displaying_images.md → essentials/displaying_images.md} +7 -7
  17. package/docs/essentials/displaying_text.md +77 -0
  18. package/docs/{element_attributes.md → essentials/element_attributes.md} +17 -12
  19. package/docs/essentials/template_syntax.md +85 -0
  20. package/docs/getting_started/file_structure.md +61 -0
  21. package/docs/getting_started/getting_started.md +47 -0
  22. package/docs/{introduction.md → getting_started/intro.md} +2 -1
  23. package/docs/sidebar.json +70 -26
  24. package/docs/transitions_animations/transitions.md +132 -0
  25. package/package.json +1 -1
  26. package/src/component.js +12 -3
  27. package/src/fontLoader.js +20 -21
  28. package/src/launch.d.ts +5 -6
  29. package/src/launch.js +12 -2
  30. package/src/lib/codegenerator/generator.js +2 -2
  31. package/src/lib/hooks.js +7 -7
  32. package/src/lib/lifecycle.js +3 -2
  33. package/src/lib/setup/base.js +9 -1
  34. package/src/lib/setup/state.js +1 -1
  35. package/src/lib/symbols.js +2 -0
  36. package/boilerplate/js/default/src/fontloader.js +0 -4
  37. package/docs/computed_properties.md +0 -18
  38. package/docs/getting_started.md +0 -40
  39. package/docs/props.md +0 -46
  40. package/docs/template_syntax.md +0 -65
  41. package/docs/watchers.md +0 -38
  42. /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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightningjs/blits",
3
- "version": "0.8.1",
3
+ "version": "0.9.0",
4
4
  "description": "Blits: The Lightning 3 App Development Framework",
5
5
  "bin": "bin/index.js",
6
6
  "exports": {
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, name)
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) => emit('frameTick', name, this, [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: (config.state && typeof config.state === 'function' && config.state.apply(this)) || {},
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 { CoreExtension, WebTrFontFace, SdfTrFontFace } from '@lightningjs/renderer/core'
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 class FontLoader extends CoreExtension {
6
- async run(stage) {
7
- Settings.get('fonts', []).forEach((font) => {
8
- if (font.type === 'sdf' || font.type === 'msdf') {
9
- // automatically map png key to file name
10
- if (!font.png && font.file) {
11
- font.png = font.file.replace(/\.[^.]+$/, `.${font.type}.png`)
12
- }
13
- // automatically map json to file name
14
- if (!font.json && font.file) {
15
- font.json = font.file.replace(/\.[^.]+$/, `.${font.type}.json`)
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(() => initApp())
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, name, scope, data = []) => {
23
- cbs[name] && cbs[name][hook] && cbs[name][hook].apply(scope, data)
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, name, scope) => {
26
+ export const privateEmit = (hook, identifier, scope) => {
27
27
  const symHook = symbols[hook]
28
- cbs[name] && cbs[name][symHook] && cbs[name][symHook].apply(scope)
28
+ cbs[identifier] && cbs[identifier][symHook] && cbs[identifier][symHook].apply(scope)
29
29
  }
30
30
 
31
- export const registerHooks = (hooks = {}, name) => {
32
- cbs[name] = {}
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[name][hook] = hooks[hook]
36
+ if (typeof hooks[hook] === 'function') cbs[identifier][hook] = hooks[hook]
37
37
  })
38
38
  }
@@ -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.name, this.component)
38
+ privateEmit(v, this.component[symbols.identifier], this.component)
38
39
  // emit 'public' hook
39
- emit(v, this.component.name, this.component)
40
+ emit(v, this.component[symbols.identifier], this.component)
40
41
  }
41
42
  },
42
43
  }
@@ -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,
@@ -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`)
@@ -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,4 +0,0 @@
1
- // temporary workaround for Vite importChunkUrl plugin
2
- // @ts-ignore
3
- import FontLoader from '@lightningjs/blits/fontloader'
4
- export default FontLoader
@@ -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.
@@ -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.
@@ -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.