@lightningjs/blits 0.3.0 → 0.3.2
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/README.md +10 -2
- package/boilerplate/.vscode/extensions.json +1 -1
- package/boilerplate/package.json +1 -1
- package/docs/README.md +12 -4
- package/docs/_sidebar.md +2 -0
- package/docs/element_attributes.md +126 -0
- package/foo.js +22 -0
- package/package.json +1 -1
- package/src/lib/codegenerator/generator.js +53 -17
- package/src/lib/setup/base.js +7 -3
- package/src/lib/setup/props.js +2 -2
package/README.md
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# Blits - Lightning 3 App Development Framework
|
|
2
2
|
|
|
3
|
-
With Blits, the App Development Framework for Lightning 3, it becomes a breeze to build great Lightning 3 applications.
|
|
3
|
+
With Blits (formaly know as Bolt), the App Development Framework for Lightning 3, it becomes a breeze to build great Lightning 3 applications.
|
|
4
4
|
|
|
5
5
|
Blits is built on top of the Lightning 3 Rendererer and aims to provide a **great developer experience**, making it fun and easy to build your apps!
|
|
6
6
|
|
|
7
7
|
Built from the ground up by the LightningJS team, we're offering a **Complete App framework**, full of features to speed up development, while keeping it **lightweight** with a focus on **performance**.
|
|
8
8
|
|
|
9
|
-
The Blits framework uses **readable** XML-style template syntax and comes with built-in reactivity.
|
|
9
|
+
The Blits framework uses a **readable** XML-style template syntax and comes with built-in reactivity.
|
|
10
|
+
|
|
11
|
+
## Why Blits?
|
|
12
|
+
|
|
13
|
+
You may be wondering where the name Blits comes from?
|
|
14
|
+
|
|
15
|
+
Firstly, it short, memorable and has a nice ring to it. The name is derived from the word "Blitz", which means Lightning in German. Additionally, "Blits" is a Dutch term (a significant portion of the Lightning Open Source teams is based in the Netherlands) used to showcase something great or simply refer to things that are cool.
|
|
16
|
+
|
|
17
|
+
Finally it's a nerdy reference to the computer term "Bit Blits" commonly used in graphics processing, for rapidly moving a block of data into memory - quite similar to what Lightning is doing 🙂
|
|
10
18
|
|
|
11
19
|
Check out the [documentation](https://lightning-js.github.io/blits) to learn more.
|
package/boilerplate/package.json
CHANGED
package/docs/README.md
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
# Blits - Lightning 3 App Development Framework
|
|
2
2
|
|
|
3
|
-
With Blits, the App Development Framework for Lightning 3, it becomes a breeze to build great Lightning 3 applications.
|
|
3
|
+
With Blits (formaly know as Bolt), the App Development Framework for Lightning 3, it becomes a breeze to build great Lightning 3 applications.
|
|
4
4
|
|
|
5
5
|
Blits is built on top of the Lightning 3 Rendererer and aims to provide a **great developer experience**, making it fun and easy to build your apps!
|
|
6
6
|
|
|
7
7
|
Built from the ground up by the LightningJS team, we're offering a **Complete App framework**, full of features to speed up development, while keeping it **lightweight** with a focus on **performance**.
|
|
8
8
|
|
|
9
|
-
The Blits framework uses **readable** XML-style template syntax and comes with built-in reactivity.
|
|
9
|
+
The Blits framework uses a **readable** XML-style template syntax and comes with built-in reactivity.
|
|
10
|
+
|
|
11
|
+
## Why Blits?
|
|
12
|
+
|
|
13
|
+
You may be wondering where the name Blits comes from?
|
|
14
|
+
|
|
15
|
+
Firstly, it short, memorable and has a nice ring to it. The name is derived from the word "Blitz", which means Lightning in German. Additionally, "Blits" is a Dutch term (a significant portion of the Lightning Open Source teams is based in the Netherlands) used to showcase something great or simply refer to things that are cool.
|
|
16
|
+
|
|
17
|
+
Finally it's a nerdy reference to the computer term "Bit Blits" commonly used in graphics processing, for rapidly moving a block of data into memory - quite similar to what Lightning is doing 🙂
|
|
10
18
|
|
|
11
19
|
## Table of contents
|
|
12
20
|
|
|
@@ -19,12 +27,12 @@ The Blits framework uses **readable** XML-style template syntax and comes with b
|
|
|
19
27
|
- [Handling user input](user_input.md)
|
|
20
28
|
- [Computed properties](computed_properties.md)
|
|
21
29
|
- [Watching for changes](watchers.md)
|
|
30
|
+
- [Styling and positioning Elements](element_attributes.md)
|
|
22
31
|
<!---
|
|
23
32
|
- More complex logic in methods
|
|
24
|
-
- Overview of default Element properties
|
|
25
33
|
- Transitions
|
|
26
34
|
- Implementing Custom components
|
|
27
35
|
- Handling Text
|
|
28
|
-
- Handling
|
|
36
|
+
- Handling Images
|
|
29
37
|
- Routing
|
|
30
38
|
-->
|
package/docs/_sidebar.md
CHANGED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Blits - Lightning 3 App Development Framework
|
|
2
|
+
|
|
3
|
+
## Styling and positioning Elements
|
|
4
|
+
|
|
5
|
+
The core building block of a Blits template is the Element tag. The Element tag corresponds directly to a node in the Lightning 3 Renderer. You can style and position Elements via _attributes_, much like you would do in HTML.
|
|
6
|
+
|
|
7
|
+
Blits Elements have a specific set of attributes that can be set, loosely modeled after the properties of a Lightning 3 renderer node. In certain cases Blits provides more developer friendly names or accepts a wider range of values, and transparently takes care of the translation into L3 renderer instructions.
|
|
8
|
+
|
|
9
|
+
### Positioning and Dimensions
|
|
10
|
+
|
|
11
|
+
In order to position and set the dimensions of an Element, the following attributes can be used.
|
|
12
|
+
|
|
13
|
+
- `x` - the x position of the Element in pixels, relative to it's parent - allows negative values and decimals
|
|
14
|
+
- `y` - the y position of the Element in pixels, relative to it's parent - allows negative values and decimals
|
|
15
|
+
- `z` - the z index of the element (optionally `zIndex` can be used as an alias)
|
|
16
|
+
- `w` - the width of the element in pixels (optionaly `width` can be used as an alias)
|
|
17
|
+
- `h` - the height of the element in pixels (optionaly `height` can be used as an alias)
|
|
18
|
+
|
|
19
|
+
All positioning and dimension related attributes, when not specified, default to `0`.
|
|
20
|
+
|
|
21
|
+
```xml
|
|
22
|
+
<Element x="100" y="100" w="800" h="400">
|
|
23
|
+
<Element x="40" y="80" w="300" h="300" z="10" />
|
|
24
|
+
<Element x="60" y="120" w="200" h="200" z="0" />
|
|
25
|
+
</Element>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Colors
|
|
29
|
+
|
|
30
|
+
By default Elements have a transparent background color. The `color` attribute can be used to give an Element a color.
|
|
31
|
+
|
|
32
|
+
For those familiar with Lightning 2: colors have gotten a lot easier with Blits! Under the hood the Lightning 3 renderer still uses the somewhat unfamiliar, but efficient `0xffc0ffee` syntax. In Blits you can specify colors as you are used to in HTML and CSS.
|
|
33
|
+
|
|
34
|
+
Blits accepts the following color formats and makes sure that they are mapped in a way the Lightning 3 renderer can understand.
|
|
35
|
+
|
|
36
|
+
- hexadecimal (i.e. `#ff4433`)
|
|
37
|
+
- hexadecimal with an alpha channel (i.e `#55553380`)
|
|
38
|
+
- hexadecimal shorthands (i.e. `#333`)
|
|
39
|
+
- rgb (i.e. `rgb(180, 30, 50)`)
|
|
40
|
+
- rgba (i.e `rgba(40, 30, 180, 0.5)`)
|
|
41
|
+
- html color names (i.e. `red`, `blue`, `skyblue`, `tomato`)
|
|
42
|
+
|
|
43
|
+
HSL and HSLA formats are planned to be added in the future.
|
|
44
|
+
|
|
45
|
+
```xml
|
|
46
|
+
<Element w="200" h="200" color="#ff4433" />
|
|
47
|
+
<Element w="200" h="200" color="#55553380" />
|
|
48
|
+
<Element w="200" h="200" color="#333" />
|
|
49
|
+
<Element w="200" h="200" color="rgb(180, 30, 50)" />
|
|
50
|
+
<Element w="200" h="200" color="rgba(40, 30, 180, 0.5)" />
|
|
51
|
+
<Element w="200" h="200" color="black" />
|
|
52
|
+
<Element w="200" h="200" color="red" />
|
|
53
|
+
<Element w="200" h="200" color="skyblue" />
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### Basic linear gradients
|
|
57
|
+
|
|
58
|
+
The color attribute can also be used to specify basic linear gradients.
|
|
59
|
+
|
|
60
|
+
A linear gradient can be defined by specifying an _object literal_ as the `color` attribute instead of a single color. The object can consist of a mix of `top`, `bottom`, `left`, `right` keys, with the color to use for that side as a value. If a specific side isn't specified, it defaults to `transparent`. Again you can use "normal" notation for the colors (like hexadecimal or rgba) and you are free to mix and match formats.
|
|
61
|
+
|
|
62
|
+
```xml
|
|
63
|
+
<Element w="200" h="200" color="{top: 'red', bottom: 'blue'}" />
|
|
64
|
+
<Element w="200" h="200" color="{left: 'rgba(255,255,255,.5)', right: '#000'}" />
|
|
65
|
+
<Element w="200" h="200" color="{left: '#aaa333', top: 'aqua', bottom: rgb(255,100,20)'}" />
|
|
66
|
+
<Element w="200" h="200" color="{bottom: 'black'}" />
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Alpha and visibility
|
|
70
|
+
|
|
71
|
+
The opacity of an Element, can be controlled by setting the `alpha` attribute. This attribute accepts a value between `0` (fully transparent) and `1` (completely visible).
|
|
72
|
+
|
|
73
|
+
The value of alpha is also being applied recursively to the children of the Element that has its alpha set. If you just want the background color of an Element to be semi-transparent, you should set the alpha channel in the color instead of applying the alpha attribute.
|
|
74
|
+
|
|
75
|
+
```xml
|
|
76
|
+
<Element w="200" h="200" color="blue" alpha="0.8">
|
|
77
|
+
<Element w="100" h="100" color="red" alpha="0.3" />
|
|
78
|
+
</Element>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Rotation and scaling
|
|
82
|
+
|
|
83
|
+
If you want to rotate an Element, you can use the `rotation` attribute. The rotation attribute in Blits accepts values in degrees. The rotation of an Element is also automatically applied to any children down the tree.
|
|
84
|
+
|
|
85
|
+
```xml
|
|
86
|
+
<Element w="200" h="200" color="blue" rotation="90">
|
|
87
|
+
<Element w="100" h="100" color="red" rotation="240" />
|
|
88
|
+
</Element>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
For scaling an Element the `scale` attribute is used. This attribute can be any numeric value starting at `0`. The default value is `1`, which means no scaling. Any value below `1` will scale down the element and values greater than `1` will scale the element up.
|
|
92
|
+
|
|
93
|
+
Similar to rotation, scale is also applied recursively to children down the tree of the Element that has it's `scale` attribute set.
|
|
94
|
+
|
|
95
|
+
```xml
|
|
96
|
+
<Element w="200" h="200" color="blue" scale="0.5" />
|
|
97
|
+
<Element w="200" h="200" color="#000" scale="2.3" />
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Mounting point
|
|
101
|
+
|
|
102
|
+
For advanced positioning the `mount` attribute can come in handy. By default when you set the `x` and `y` position of an Element, the _top-left_ corner will be set to that position. But in some cases you may want to align the position starting at a different corner, or even any arbitray point in between.
|
|
103
|
+
|
|
104
|
+
The `mount` attribute accepts an _object literal_ that allows you to precisely control the mount position on the _x-axis_ and the mount position on the _y-axis_. The default value is `{x: 0, y: 0}`, which refers to the _top-left_ corner.
|
|
105
|
+
|
|
106
|
+
In order to align the position starting at the _bottom-right_ corner, we would set `mount` to `{x: 1, y: 1}` and `{x: 0.5, y: 0.5}` would align the position at the _center_ of the Element.
|
|
107
|
+
|
|
108
|
+
If you omit either the `x` or the `y` key from the _object literal_, it's value will default to `0`.
|
|
109
|
+
|
|
110
|
+
```xml
|
|
111
|
+
<Element w="200" h="200" x="20" y="100" color="#333" mount="{x: 0.5, y: 0.8}" />
|
|
112
|
+
<Element w="200" h="200" x="800" y="400" color="#333" mount="{y: 1}" />
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Pivot point
|
|
116
|
+
|
|
117
|
+
The pivot point of an Element comes into play when it's rotated or scaled. The pivot point defaults to the center of the Element, which means that when setting `rotation` it rotates around the middle. And when the Element is scaled it scales from the center out.
|
|
118
|
+
|
|
119
|
+
But sometimes you may want rotate around the left corner, or scale from the right side out. This can be controlled by adding the `pivot` attribute to the Element and, similar to the `mount` attribute, specify an _object literal_ with a `x` and a `y` key.
|
|
120
|
+
|
|
121
|
+
Both `y` and `x` values should be anything between `0` and `1`, where `{x: 0, y: 0}` sets the pivot point to the _top-left_ corner and `{x: 1, y: 1}` refers to the _bottom-right_ corner. The default pivot value is `{x: 0.5, y: 0.5}` (i.e. the center) and if you omit `x` or `y` in your pivot object, it will default to `0.5`.
|
|
122
|
+
|
|
123
|
+
```xml
|
|
124
|
+
<Element w="200" h="200" x="20" y="100" pivot="{x: 0.5, y: 0.8}" rotation="69" />
|
|
125
|
+
<Element w="200" h="200" x="800" y="400" pivot="{y: 1}" scale="3" />
|
|
126
|
+
```
|
package/foo.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const items1 = [{ foo: 'bar' }, { foo: 'baz' }]
|
|
2
|
+
|
|
3
|
+
const items2 = {
|
|
4
|
+
1: { foo: 'bar' },
|
|
5
|
+
2: { foo: 'baz' },
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const loop = (items) => {
|
|
9
|
+
if (!Array.isArray(items)) {
|
|
10
|
+
items = Object.keys(items).map((k) => {
|
|
11
|
+
return items[k]
|
|
12
|
+
})
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
for (let i = 0; i < items.length; i++) {
|
|
16
|
+
console.log(items[i].foo)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
loop(items1)
|
|
21
|
+
|
|
22
|
+
loop(items2)
|
package/package.json
CHANGED
|
@@ -38,23 +38,26 @@ export default function (templateObject = { children: [] }) {
|
|
|
38
38
|
const generateElementCode = function (
|
|
39
39
|
templateObject,
|
|
40
40
|
parent = false,
|
|
41
|
-
options = {
|
|
41
|
+
options = { key: false, component: 'component.', forceEffect: false }
|
|
42
42
|
) {
|
|
43
43
|
const renderCode = options.forceEffect ? this.effectsCode : this.renderCode
|
|
44
44
|
if (parent) {
|
|
45
45
|
renderCode.push(`parent = ${parent}`)
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
if ('key' in templateObject) options.key = interpolate(templateObject.key, options.component)
|
|
49
|
+
const elm = options.key ? `elms[${counter}][${options.key}]` : `elms[${counter}]`
|
|
49
50
|
|
|
50
|
-
if (options.
|
|
51
|
+
if (options.key) {
|
|
51
52
|
renderCode.push(`
|
|
52
|
-
elms[${counter}] = elms[${counter}] ||
|
|
53
|
+
elms[${counter}] = elms[${counter}] || {}
|
|
53
54
|
`)
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
renderCode.push(`
|
|
57
|
-
|
|
58
|
+
if(!${elm}) {
|
|
59
|
+
${elm} = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'})
|
|
60
|
+
}
|
|
58
61
|
const elementConfig${counter} = {}
|
|
59
62
|
`)
|
|
60
63
|
|
|
@@ -85,7 +88,11 @@ const generateElementCode = function (
|
|
|
85
88
|
`)
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
renderCode.push(
|
|
91
|
+
renderCode.push(`
|
|
92
|
+
if(!${elm}.nodeId) {
|
|
93
|
+
${elm}.populate(elementConfig${counter})
|
|
94
|
+
}
|
|
95
|
+
`)
|
|
89
96
|
|
|
90
97
|
if (children) {
|
|
91
98
|
generateCode.call(this, { children }, `elms[${counter}]`)
|
|
@@ -95,7 +102,7 @@ const generateElementCode = function (
|
|
|
95
102
|
const generateComponentCode = function (
|
|
96
103
|
templateObject,
|
|
97
104
|
parent = false,
|
|
98
|
-
options = {
|
|
105
|
+
options = { key: false, component: 'component.', forceEffect: false, holder: false }
|
|
99
106
|
) {
|
|
100
107
|
const renderCode = options.forceEffect ? this.effectsCode : this.renderCode
|
|
101
108
|
|
|
@@ -105,17 +112,21 @@ const generateComponentCode = function (
|
|
|
105
112
|
component.___components['${templateObject.type}']
|
|
106
113
|
`)
|
|
107
114
|
|
|
115
|
+
if ('key' in templateObject) {
|
|
116
|
+
options.key = interpolate(templateObject.key, options.component)
|
|
117
|
+
}
|
|
118
|
+
|
|
108
119
|
generateElementCode.call(this, templateObject, parent, { ...options, ...{ holder: true } })
|
|
109
120
|
|
|
110
|
-
parent = options.
|
|
121
|
+
parent = options.key ? `elms[${counter}][${options.key}]` : `elms[${counter}]`
|
|
111
122
|
|
|
112
123
|
counter++
|
|
113
124
|
|
|
114
|
-
const elm = options.
|
|
125
|
+
const elm = options.key ? `elms[${counter}][${options.key}]` : `elms[${counter}]`
|
|
115
126
|
|
|
116
|
-
if (options.
|
|
127
|
+
if (options.key) {
|
|
117
128
|
renderCode.push(`
|
|
118
|
-
elms[${counter}] = elms[${counter}] ||
|
|
129
|
+
elms[${counter}] = elms[${counter}] || {}
|
|
119
130
|
`)
|
|
120
131
|
}
|
|
121
132
|
|
|
@@ -146,7 +157,9 @@ const generateComponentCode = function (
|
|
|
146
157
|
})
|
|
147
158
|
|
|
148
159
|
renderCode.push(`
|
|
149
|
-
|
|
160
|
+
if(!${elm}) {
|
|
161
|
+
${elm} = (context.components && context.components['${templateObject.type}'] || component.___components['${templateObject.type}'] || (() => { console.log('component ${templateObject.type} not found')})).call(null, {props: props${counter}}, ${parent}, component)
|
|
162
|
+
}
|
|
150
163
|
`)
|
|
151
164
|
}
|
|
152
165
|
|
|
@@ -177,23 +190,35 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
177
190
|
}
|
|
178
191
|
ctx.renderCode.push(`
|
|
179
192
|
const collection = ${cast(result[2], ':for')}
|
|
193
|
+
const keys = []
|
|
180
194
|
for(let __index = 0; __index < collection.length; __index++) {
|
|
181
195
|
parent = ${parent}
|
|
182
|
-
const scope = {
|
|
196
|
+
const scope = Object.assign(component, {
|
|
197
|
+
key: Math.random(),
|
|
183
198
|
${index}: __index,
|
|
184
199
|
${item}: collection[__index]
|
|
185
|
-
}
|
|
186
|
-
|
|
200
|
+
})
|
|
201
|
+
`)
|
|
202
|
+
|
|
203
|
+
if ('key' in templateObject) {
|
|
204
|
+
ctx.renderCode.push(`
|
|
205
|
+
keys.push(${interpolate(templateObject.key, 'scope.')})
|
|
206
|
+
`)
|
|
207
|
+
} else {
|
|
208
|
+
ctx.renderCode.push(`
|
|
209
|
+
keys.push(scope.key.toString())
|
|
210
|
+
`)
|
|
211
|
+
}
|
|
187
212
|
|
|
188
213
|
if (templateObject.type !== 'Element') {
|
|
189
214
|
generateComponentCode.call(ctx, templateObject, false, {
|
|
190
|
-
|
|
215
|
+
key: 'scope.key',
|
|
191
216
|
component: 'scope.',
|
|
192
217
|
forceEffect: false,
|
|
193
218
|
})
|
|
194
219
|
} else {
|
|
195
220
|
generateElementCode.call(ctx, templateObject, parent, {
|
|
196
|
-
|
|
221
|
+
key: 'scope.key',
|
|
197
222
|
component: 'scope.',
|
|
198
223
|
forceEffect: false,
|
|
199
224
|
})
|
|
@@ -201,6 +226,17 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
201
226
|
ctx.renderCode = ctx.renderCode.concat(ctx.effectsCode)
|
|
202
227
|
ctx.renderCode.push('}')
|
|
203
228
|
|
|
229
|
+
ctx.renderCode.push(`
|
|
230
|
+
if(elms[${counter}]) {
|
|
231
|
+
Object.keys(elms[${counter}]).forEach(key => {
|
|
232
|
+
if(keys.indexOf(key) === -1) {
|
|
233
|
+
elms[${counter}][key].delete && elms[${counter}][key].delete()
|
|
234
|
+
elms[${counter}][key].destroy && elms[${counter}][key].destroy()
|
|
235
|
+
delete elms[${counter}][key]
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
}
|
|
239
|
+
`)
|
|
204
240
|
this.effectsCode.push(ctx.renderCode.join('\n'))
|
|
205
241
|
}
|
|
206
242
|
|
package/src/lib/setup/base.js
CHANGED
|
@@ -70,15 +70,19 @@ export default (component) => {
|
|
|
70
70
|
configurable: false,
|
|
71
71
|
},
|
|
72
72
|
select: {
|
|
73
|
-
value: function (
|
|
73
|
+
value: function (ref) {
|
|
74
74
|
let selected = null
|
|
75
75
|
this.___children.forEach((child) => {
|
|
76
76
|
if (Array.isArray(child)) {
|
|
77
77
|
child.forEach((c) => {
|
|
78
|
-
if (c['
|
|
78
|
+
if (c['ref'] === ref) selected = c
|
|
79
|
+
})
|
|
80
|
+
} else if (Object.getPrototypeOf(child) === Object.prototype) {
|
|
81
|
+
Object.keys(child).forEach((k) => {
|
|
82
|
+
if (child[k]['ref'] === ref) selected = child[k]
|
|
79
83
|
})
|
|
80
84
|
} else {
|
|
81
|
-
if (child['
|
|
85
|
+
if (child['ref'] === ref) selected = child
|
|
82
86
|
}
|
|
83
87
|
})
|
|
84
88
|
|
package/src/lib/setup/props.js
CHANGED