@lightningjs/blits 0.3.13 → 0.3.15

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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.3.15
4
+
5
+ _23 oct 2023_
6
+
7
+ - Added support for slots
8
+ - Added support for defining custom keymapping
9
+ - Improved error handling of the template parser
10
+
11
+ ## v0.3.14
12
+
13
+ _19 oct 2023_
14
+
15
+ - Fixed error when `<Text />`-component doesn't have any content
16
+ - Removed generic escape key handler that closed the App
17
+ - Introduced `quit()`-method on the root Application component
18
+ - Updated to v0.4.0 of the renderer
19
+
3
20
  ## v0.3.13
4
21
 
5
22
  _18 oct 2023_
@@ -7,7 +24,8 @@ _18 oct 2023_
7
24
  - Added support for `borderTop`, `borderBottom`, `borderLeft`, `borderRight` and `grayScale` effects
8
25
  - Fixed `@loaded` and `@error` events on `<Text/>` componenent only firing once (and not for each change)
9
26
  - Fixed loading of web canvas2d fonts
10
- - Firex error when using `this`-reference in component state
27
+ - Fixed error when using `this`-reference in component state
28
+ - Added basic support for inline text (i.e. `<Text>My text with a {{$dynamic}} value</Text>`)
11
29
 
12
30
  ## v0.3.12
13
31
 
@@ -31,6 +31,6 @@
31
31
  "vite": "^4.0.4"
32
32
  },
33
33
  "dependencies": {
34
- "@lightningjs/blits": "^0.3.13"
34
+ "@lightningjs/blits": "^0.3.15"
35
35
  }
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightningjs/blits",
3
- "version": "0.3.13",
3
+ "version": "0.3.15",
4
4
  "description": "Blits: The Lightning 3 App Development Framework",
5
5
  "bin": "bin/index.cjs",
6
6
  "exports": {
@@ -41,7 +41,7 @@
41
41
  "tape": "^5.5.0"
42
42
  },
43
43
  "dependencies": {
44
- "@lightningjs/renderer": "^0.3.6",
44
+ "@lightningjs/renderer": "^0.4.0",
45
45
  "@lightningjs/vite-plugin-import-chunk-url": "^0.3.0"
46
46
  }
47
47
  }
@@ -16,12 +16,11 @@
16
16
  */
17
17
 
18
18
  import Component from './component.js'
19
-
20
19
  import Focus from './focus.js'
20
+ import Settings from './settings.js'
21
21
 
22
22
  const Application = (config) => {
23
- // make configurable?
24
- const mapping = {
23
+ const defaultKeyMap = {
25
24
  ArrowLeft: 'left',
26
25
  ArrowRight: 'right',
27
26
  ArrowUp: 'up',
@@ -29,24 +28,38 @@ const Application = (config) => {
29
28
  Enter: 'enter',
30
29
  ' ': 'space',
31
30
  Backspace: 'back',
31
+ Escape: 'escape',
32
+ 37: 'left',
33
+ 39: 'right',
34
+ 38: 'up',
35
+ 40: 'down',
36
+ 13: 'enter',
37
+ 32: 'space',
38
+ 8: 'back',
39
+ 27: 'escape',
32
40
  }
33
41
 
34
- const handler = (e) => {
35
- const key = mapping[e.key] || e.key
36
- Focus.input(key, e)
37
- }
38
-
39
- document.addEventListener('keydown', handler)
40
-
41
42
  config.hooks = config.hooks || {}
42
- config.hooks.___init = function () {
43
- Focus.set(this)
44
- }
43
+
44
+ let handler
45
45
 
46
46
  config.hooks.___destroy = function () {
47
47
  document.removeEventListener('keydown', handler)
48
48
  }
49
49
 
50
+ config.hooks.___init = function () {
51
+ const keyMap = { ...defaultKeyMap, ...Settings.get('keymap', {}) }
52
+
53
+ handler = (e) => {
54
+ const key = keyMap[e.key] || keyMap[e.keyCode] || e.key || e.keyCode
55
+ Focus.input(key, e)
56
+ }
57
+
58
+ document.addEventListener('keydown', handler)
59
+
60
+ Focus.set(this)
61
+ }
62
+
50
63
  const App = Component('App', config)
51
64
 
52
65
  return App
package/src/component.js CHANGED
@@ -120,6 +120,12 @@ const Component = (name = required('name'), config = required('config')) => {
120
120
  this.parent = parentComponent
121
121
 
122
122
  Object.defineProperties(this, {
123
+ type: {
124
+ value: name,
125
+ writable: false,
126
+ enumerable: true,
127
+ configurable: false,
128
+ },
123
129
  componentId: {
124
130
  value: createHumanReadableId(name),
125
131
  writable: false,
@@ -158,6 +164,13 @@ const Component = (name = required('name'), config = required('config')) => {
158
164
  configurable: false,
159
165
  })
160
166
 
167
+ Object.defineProperty(this, '___slots', {
168
+ value: this.___children.filter((child) => child.___isSlot),
169
+ writable: false,
170
+ enumerable: false,
171
+ configurable: false,
172
+ })
173
+
161
174
  code.effects.forEach((eff) => {
162
175
  effect(() => {
163
176
  eff.apply(stage, [this, this.___children, code.context])
package/src/element.js CHANGED
@@ -133,7 +133,7 @@ const transformations = {
133
133
  props.rotation = props.rotation * (Math.PI / 180)
134
134
  },
135
135
  text(props) {
136
- props.text = props.text.toString()
136
+ props.text = props.text !== undefined ? props.text.toString() : ''
137
137
  },
138
138
  textureColor(props) {
139
139
  if (!('color' in props)) {
@@ -174,6 +174,10 @@ const Element = {
174
174
  }
175
175
  this.initData = data
176
176
 
177
+ if (props.___isSlot) {
178
+ this.___isSlot = true
179
+ }
180
+
177
181
  transformations.remap(props)
178
182
  Object.keys(props).forEach((prop) => {
179
183
  if (transformations[prop]) {
package/src/launch.d.ts CHANGED
@@ -86,7 +86,11 @@ export interface Settings {
86
86
  /**
87
87
  * Fonts to be used in the Application
88
88
  */
89
- fonts?: Font[]
89
+ fonts?: Font[],
90
+ /**
91
+ * Custom keymapping
92
+ */
93
+ keymap?: object
90
94
  }
91
95
 
92
96
  /**
package/src/launch.js CHANGED
@@ -18,7 +18,7 @@
18
18
  import { MainRenderDriver, RendererMain, ThreadXRenderDriver } from '@lightningjs/renderer'
19
19
  // import RendererWorker from '@lightningjs/renderer/workers/renderer?worker'
20
20
  import Settings from './settings.js'
21
- import { initLog } from './lib/log.js'
21
+ import { initLog, Log } from './lib/log.js'
22
22
 
23
23
  // import coreExtensionModule from './fontLoader.js?importChunkUrl'
24
24
 
@@ -46,18 +46,15 @@ export default (App, target, settings) => {
46
46
  driver
47
47
  )
48
48
 
49
- let app
50
-
51
- const handler = (e) => {
52
- if (e.key === 'Escape') {
53
- document.removeEventListener('keydown', handler)
49
+ const initApp = () => {
50
+ let app = App()
51
+ app.quit = () => {
52
+ Log.info('Closing App')
54
53
  app.destroy()
55
54
  app = null
56
55
  renderer = null
57
56
  }
58
57
  }
59
58
 
60
- document.addEventListener('keydown', handler)
61
-
62
- renderer.init().then(() => (app = App()))
59
+ renderer.init().then(() => initApp())
63
60
  }
@@ -65,7 +65,18 @@ const generateElementCode = function (
65
65
  delete templateObject['children']
66
66
 
67
67
  Object.keys(templateObject).forEach((key) => {
68
- if (key === 'type') return
68
+ if (key === 'type') {
69
+ if (templateObject[key] === 'Slot') {
70
+ renderCode.push(`elementConfig${counter}['___isSlot'] = true`)
71
+ }
72
+ return
73
+ }
74
+
75
+ if (key === 'slot') {
76
+ renderCode.push(`
77
+ elementConfig${counter}['parent'] = component.___slots.filter(slot => slot.ref === '${templateObject.slot}').shift() || component.___slots[0] || parent
78
+ `)
79
+ }
69
80
 
70
81
  if (isReactiveKey(key)) {
71
82
  this.effectsCode.push(
@@ -116,6 +127,8 @@ const generateComponentCode = function (
116
127
  options.key = interpolate(templateObject.key, options.component)
117
128
  }
118
129
 
130
+ const children = templateObject.children
131
+ delete templateObject.children
119
132
  generateElementCode.call(this, templateObject, parent, { ...options, ...{ holder: true } })
120
133
 
121
134
  parent = options.key ? `elms[${counter}][${options.key}]` : `elms[${counter}]`
@@ -159,8 +172,17 @@ const generateComponentCode = function (
159
172
  renderCode.push(`
160
173
  if(!${elm}) {
161
174
  ${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)
175
+ if (${elm}.___slots[0]) {
176
+ parent = ${elm}.___slots[0]
177
+ component = ${elm}
178
+ } else {
179
+ parent = ${elm}.___children[0]
180
+ }
162
181
  }
163
182
  `)
183
+
184
+ counter++
185
+ generateElementCode.call(this, { children }, false, { ...options })
164
186
  }
165
187
 
166
188
  const generateForLoopCode = function (templateObject, parent) {
@@ -210,14 +232,14 @@ const generateForLoopCode = function (templateObject, parent) {
210
232
  `)
211
233
  }
212
234
 
213
- if (templateObject.type !== 'Element') {
214
- generateComponentCode.call(ctx, templateObject, false, {
235
+ if (templateObject.type === 'Element' || templateObject.type === 'Slot') {
236
+ generateElementCode.call(ctx, templateObject, parent, {
215
237
  key: 'scope.key',
216
238
  component: 'scope.',
217
239
  forceEffect: false,
218
240
  })
219
241
  } else {
220
- generateElementCode.call(ctx, templateObject, parent, {
242
+ generateComponentCode.call(ctx, templateObject, false, {
221
243
  key: 'scope.key',
222
244
  component: 'scope.',
223
245
  forceEffect: false,
@@ -248,10 +270,10 @@ const generateCode = function (templateObject, parent = false) {
248
270
  if (Object.keys(childTemplateObject).indexOf(':for') > -1) {
249
271
  generateForLoopCode.call(this, childTemplateObject, parent)
250
272
  } else {
251
- if (childTemplateObject.type !== 'Element') {
252
- generateComponentCode.call(this, childTemplateObject, parent)
253
- } else {
273
+ if (childTemplateObject.type === 'Element' || childTemplateObject.type === 'Slot') {
254
274
  generateElementCode.call(this, childTemplateObject, parent)
275
+ } else {
276
+ generateComponentCode.call(this, childTemplateObject, parent)
255
277
  }
256
278
  }
257
279
  })
@@ -16,8 +16,8 @@
16
16
  */
17
17
 
18
18
  class TemplateParseError extends Error {
19
- constructor(name, context) {
20
- super('TemplateParseError')
19
+ constructor(message, name, context) {
20
+ super(`TemplateParseError ${message}`)
21
21
  this.name = name
22
22
  this.context = context
23
23
  }
@@ -44,7 +44,13 @@ export default (template = '') => {
44
44
  try {
45
45
  return format(tags)
46
46
  } catch (error) {
47
- console.error('Error:', error.message)
47
+ if (error instanceof TemplateParseError) {
48
+ console.error(`${error.message} | ${error.name}`)
49
+ } else {
50
+ console.error(error)
51
+ }
52
+ // return errors gracefully
53
+ return null
48
54
  }
49
55
  }
50
56