@lightningjs/blits 1.48.0 → 2.0.0-beta.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/element-test-full.txt +0 -0
- package/index.d.ts +19 -48
- package/package.json +4 -3
- package/src/component/base/methods.js +16 -76
- package/src/component/base/utils.js +18 -4
- package/src/component/setup/props.js +37 -28
- package/src/component/setup/state.js +4 -4
- package/src/component.js +26 -17
- package/src/components/Circle.js +49 -7
- package/src/components/FPScounter.js +226 -88
- package/src/components/RouterView.js +57 -6
- package/src/components/Sprite.js +54 -8
- package/src/engines/L3/element.js +109 -86
- package/src/engines/L3/fontLoader.js +26 -31
- package/src/engines/L3/shaderLoader.js +56 -6
- package/src/focus.js +9 -9
- package/src/launch.js +1 -2
- package/src/lib/codegenerator/generator.js +116 -15
- package/src/lib/colors/colors.js +0 -1
- package/src/lib/lifecycle.js +4 -4
- package/src/lib/shaders/shaders.js +164 -0
- package/src/lib/symbols.js +8 -0
- package/src/lib/templateparser/parser.js +6 -2
- package/src/lib/utils.js +36 -0
- package/src/router/router.js +9 -9
- package/test-output.txt +0 -0
- package/vite/blitsTips.js +57 -0
- package/vite/msdfGenerator.js +52 -6
- package/vscode/data/template-attributes.json +112 -0
|
Binary file
|
package/index.d.ts
CHANGED
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
// blits file type reference
|
|
19
19
|
/// <reference path="./blits.d.ts" />
|
|
20
20
|
|
|
21
|
+
import {type ShaderEffect as RendererShaderEffect, type RendererMainSettings} from '@lightningjs/renderer'
|
|
22
|
+
import { CanvasShaderType } from '@lightningjs/renderer/canvas';
|
|
23
|
+
import { WebGlShaderType } from '@lightningjs/renderer/webgl';
|
|
24
|
+
|
|
21
25
|
declare module '@lightningjs/blits' {
|
|
22
26
|
type RendererShaderEffect = import('@lightningjs/renderer').ShaderEffect
|
|
23
27
|
type WebGlCoreShader = import('@lightningjs/renderer').WebGlCoreShader
|
|
@@ -389,7 +393,7 @@ declare module '@lightningjs/blits' {
|
|
|
389
393
|
*
|
|
390
394
|
* @returns Boolean
|
|
391
395
|
*/
|
|
392
|
-
hasFocus: boolean,
|
|
396
|
+
readonly $hasFocus: boolean,
|
|
393
397
|
|
|
394
398
|
/**
|
|
395
399
|
* Listen to events emitted by other components
|
|
@@ -478,12 +482,6 @@ declare module '@lightningjs/blits' {
|
|
|
478
482
|
* @returns Returns true if this component or a parent component handled the event, false otherwise
|
|
479
483
|
*/
|
|
480
484
|
$input: (event: KeyboardEvent) => boolean
|
|
481
|
-
/**
|
|
482
|
-
* @deprecated
|
|
483
|
-
* Deprecated: use `this.$focus()` instead
|
|
484
|
-
*/
|
|
485
|
-
focus: (event?: KeyboardEvent) => void
|
|
486
|
-
|
|
487
485
|
/**
|
|
488
486
|
* Select a child Element or Component by ref
|
|
489
487
|
*
|
|
@@ -501,12 +499,6 @@ declare module '@lightningjs/blits' {
|
|
|
501
499
|
*/
|
|
502
500
|
$select: (ref: string) => ComponentBase
|
|
503
501
|
|
|
504
|
-
/**
|
|
505
|
-
* @deprecated
|
|
506
|
-
* Deprecated: use `this.$select()` instead
|
|
507
|
-
*/
|
|
508
|
-
select: (ref: string) => ComponentBase
|
|
509
|
-
|
|
510
502
|
/**
|
|
511
503
|
* Announcer methods for screen reader support
|
|
512
504
|
*/
|
|
@@ -516,13 +508,6 @@ declare module '@lightningjs/blits' {
|
|
|
516
508
|
* Triggers a forced update on state variables.
|
|
517
509
|
*/
|
|
518
510
|
$trigger: (key: string) => void
|
|
519
|
-
/**
|
|
520
|
-
* @deprecated
|
|
521
|
-
*
|
|
522
|
-
* Triggers a forced update on state variables.
|
|
523
|
-
* Deprecated: use `this.$trigger()` instead
|
|
524
|
-
*/
|
|
525
|
-
trigger: (key: string) => void
|
|
526
511
|
/**
|
|
527
512
|
* Router instance
|
|
528
513
|
*/
|
|
@@ -572,20 +557,22 @@ declare module '@lightningjs/blits' {
|
|
|
572
557
|
cast?: () => any
|
|
573
558
|
};
|
|
574
559
|
|
|
575
|
-
|
|
576
|
-
export type Props = (string | PropObject)[];
|
|
560
|
+
export type Props = Record<string, any>
|
|
577
561
|
|
|
578
|
-
|
|
579
|
-
type ExtractPropNames<P extends Props> = {
|
|
580
|
-
readonly [K in P[number] as K extends string ? K : K extends { key: infer Key } ? Key : never]: any;
|
|
581
|
-
};
|
|
562
|
+
type InferProp<T> = T extends (...args: any[]) => any ? ReturnType<T> : T
|
|
582
563
|
|
|
583
|
-
|
|
584
|
-
|
|
564
|
+
type InferProps<T extends Record<string, any>> = {
|
|
565
|
+
[K in keyof T]: InferProp<T[K]>
|
|
566
|
+
}
|
|
585
567
|
|
|
586
|
-
export type ComponentContext<
|
|
568
|
+
export type ComponentContext<
|
|
569
|
+
P extends Record<string, any>,
|
|
570
|
+
S,
|
|
571
|
+
M,
|
|
572
|
+
C
|
|
573
|
+
> = ThisType<Readonly<InferProps<P>> & S & M & Readonly<C> & ComponentBase>
|
|
587
574
|
|
|
588
|
-
export interface ComponentConfig<P extends Props, S, M, C, W> {
|
|
575
|
+
export interface ComponentConfig<P extends Props = {}, S, M, C, W> {
|
|
589
576
|
components?: {
|
|
590
577
|
[key: string]: ComponentFactory,
|
|
591
578
|
},
|
|
@@ -641,7 +628,7 @@ declare module '@lightningjs/blits' {
|
|
|
641
628
|
* }
|
|
642
629
|
* ```
|
|
643
630
|
*/
|
|
644
|
-
state?: (this:
|
|
631
|
+
state?: (this: InferProps<P>) => S;
|
|
645
632
|
/**
|
|
646
633
|
* Methods for abstracting more complex business logic into separate function
|
|
647
634
|
*/
|
|
@@ -930,7 +917,7 @@ declare module '@lightningjs/blits' {
|
|
|
930
917
|
|
|
931
918
|
type Shader = {
|
|
932
919
|
name: string,
|
|
933
|
-
type:
|
|
920
|
+
type: WebGlShaderType | CanvasShaderType
|
|
934
921
|
}
|
|
935
922
|
|
|
936
923
|
type ScreenResolutions = 'hd' | '720p' | 720 | 'fhd' | 'fullhd' | '1080p' | 1080 | '4k' | '2160p' | 2160
|
|
@@ -966,10 +953,6 @@ declare module '@lightningjs/blits' {
|
|
|
966
953
|
* Fonts to be used in the Application
|
|
967
954
|
*/
|
|
968
955
|
fonts?: Font[],
|
|
969
|
-
/**
|
|
970
|
-
* Effects to be used by DynamicShader
|
|
971
|
-
*/
|
|
972
|
-
effects?: ShaderEffect[],
|
|
973
956
|
/**
|
|
974
957
|
* Shaders to be used in the application
|
|
975
958
|
*/
|
|
@@ -1102,18 +1085,6 @@ declare module '@lightningjs/blits' {
|
|
|
1102
1085
|
* Defaults to `0`
|
|
1103
1086
|
*/
|
|
1104
1087
|
viewportMargin?: number | [number, number, number, number],
|
|
1105
|
-
/**
|
|
1106
|
-
* Threshold in `Megabytes` after which all the textures that are currently not visible
|
|
1107
|
-
* within the configured viewport margin will be be freed and cleaned up
|
|
1108
|
-
*
|
|
1109
|
-
* When passed `0` the threshold is disabled and textures will not be actively freed
|
|
1110
|
-
* and cleaned up
|
|
1111
|
-
*
|
|
1112
|
-
* Defaults to `200` (mb)
|
|
1113
|
-
* @deprecated
|
|
1114
|
-
* Deprecated: use `gpuMemory` launch setting instead
|
|
1115
|
-
*/
|
|
1116
|
-
gpuMemoryLimit?: number,
|
|
1117
1088
|
/**
|
|
1118
1089
|
* Configures the gpu memory settings used by the renderer
|
|
1119
1090
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightningjs/blits",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
4
|
"description": "Blits: The Lightning 3 App Development Framework",
|
|
5
5
|
"bin": "bin/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"test": "c8 node scripts/runTests.js",
|
|
36
36
|
"test:ci": "c8 npm run test:run",
|
|
37
37
|
"test:run": "node -r global-jsdom/register ./node_modules/.bin/tape '{,!(node_modules|packages)/**/}*.test.js' | tap-diff",
|
|
38
|
+
"test:run:failures": "node -r global-jsdom/register ./node_modules/.bin/tape '{,!(node_modules|packages)/**/}*.test.js' | tap-filter test-fail | tap-diff",
|
|
38
39
|
"lint": "node scripts/lint.js",
|
|
39
40
|
"lint:fix": "node scripts/lint.js fix",
|
|
40
41
|
"prepublishOnly": "node scripts/prepublishOnly.js",
|
|
@@ -70,11 +71,11 @@
|
|
|
70
71
|
"prettier": "^3.6.2",
|
|
71
72
|
"sinon": "^21.0.0",
|
|
72
73
|
"tap-diff": "^0.1.1",
|
|
74
|
+
"tap-filter": "^1.0.3",
|
|
73
75
|
"tape": "^5.5.0"
|
|
74
76
|
},
|
|
75
77
|
"dependencies": {
|
|
76
|
-
"@lightningjs/
|
|
77
|
-
"@lightningjs/renderer": "^2.21.0",
|
|
78
|
+
"@lightningjs/renderer": "3.0.0-beta21",
|
|
78
79
|
"magic-string": "^0.30.21"
|
|
79
80
|
},
|
|
80
81
|
"repository": {
|
|
@@ -26,26 +26,14 @@ import { renderer } from '../../launch.js'
|
|
|
26
26
|
import { keyMap } from '../../application.js'
|
|
27
27
|
|
|
28
28
|
export default {
|
|
29
|
-
focus: {
|
|
30
|
-
/**
|
|
31
|
-
* @this {import('../../component').BlitsComponent}
|
|
32
|
-
*/
|
|
33
|
-
value: function (e) {
|
|
34
|
-
Log.warn('this.focus is deprecated, use this.$focus instead')
|
|
35
|
-
return this.$focus(e)
|
|
36
|
-
},
|
|
37
|
-
writable: false,
|
|
38
|
-
enumerable: true,
|
|
39
|
-
configurable: false,
|
|
40
|
-
},
|
|
41
29
|
$focus: {
|
|
42
30
|
/**
|
|
43
31
|
* @this {import('../../component').BlitsComponent}
|
|
44
32
|
*/
|
|
45
33
|
value: function (e) {
|
|
46
34
|
// force refocus when the component is already in focused state
|
|
47
|
-
if (this.lifecycle.state === 'focus') {
|
|
48
|
-
this.lifecycle.state = 'refocus'
|
|
35
|
+
if (this[symbols.lifecycle].state === 'focus') {
|
|
36
|
+
this[symbols.lifecycle].state = 'refocus'
|
|
49
37
|
}
|
|
50
38
|
Focus.set(this, e)
|
|
51
39
|
},
|
|
@@ -93,8 +81,8 @@ export default {
|
|
|
93
81
|
* @this {import('../../component').BlitsComponent}
|
|
94
82
|
*/
|
|
95
83
|
value: function () {
|
|
96
|
-
this[symbols.state]
|
|
97
|
-
this.lifecycle.state = 'unfocus'
|
|
84
|
+
this[symbols.state].$hasFocus = false
|
|
85
|
+
this[symbols.lifecycle].state = 'unfocus'
|
|
98
86
|
},
|
|
99
87
|
writable: false,
|
|
100
88
|
enumerable: true,
|
|
@@ -106,11 +94,11 @@ export default {
|
|
|
106
94
|
*/
|
|
107
95
|
value: function () {
|
|
108
96
|
this.eol = true
|
|
109
|
-
this.lifecycle.state = 'destroy'
|
|
97
|
+
this[symbols.lifecycle].state = 'destroy'
|
|
110
98
|
|
|
111
99
|
// when destroying a component that currently has focus
|
|
112
100
|
// pass focus to the parent so we don't get lost in focus limbo
|
|
113
|
-
if (this
|
|
101
|
+
if (this.$hasFocus === true) this[symbols.parent].$focus()
|
|
114
102
|
|
|
115
103
|
// @todo - is this really necessary?
|
|
116
104
|
// This cause an issue with auto sizing of parent (and required an extra eol check there)
|
|
@@ -143,26 +131,25 @@ export default {
|
|
|
143
131
|
this[symbols.state] = {}
|
|
144
132
|
|
|
145
133
|
this[symbols.props] = {}
|
|
146
|
-
this[symbols.
|
|
147
|
-
this.lifecycle = {}
|
|
134
|
+
this[symbols.computedKeys] = null
|
|
135
|
+
this[symbols.lifecycle] = {}
|
|
148
136
|
this[symbols.effects].length = 0
|
|
149
|
-
this.parent = null
|
|
150
|
-
this.rootParent = null
|
|
137
|
+
this[symbols.parent] = null
|
|
138
|
+
this[symbols.rootParent] = null
|
|
151
139
|
this[symbols.wrapper] = null
|
|
152
140
|
this[symbols.originalState] = null
|
|
153
141
|
this[symbols.slots].length = 0
|
|
154
142
|
|
|
155
|
-
delete this[symbols.
|
|
156
|
-
delete this.parent
|
|
157
|
-
delete this.rootParent
|
|
143
|
+
delete this[symbols.computedKeys]
|
|
144
|
+
delete this[symbols.parent]
|
|
145
|
+
delete this[symbols.rootParent]
|
|
158
146
|
delete this[symbols.wrapper]
|
|
159
147
|
delete this[symbols.originalState]
|
|
160
148
|
delete this[symbols.children]
|
|
161
149
|
delete this[symbols.slots]
|
|
162
|
-
delete this.componentId
|
|
163
150
|
delete this[symbols.id]
|
|
164
151
|
delete this.ref
|
|
165
|
-
delete this[symbols.state]
|
|
152
|
+
delete this[symbols.state].$hasFocus
|
|
166
153
|
|
|
167
154
|
this[symbols.holder].destroy()
|
|
168
155
|
this[symbols.holder] = null
|
|
@@ -173,7 +160,8 @@ export default {
|
|
|
173
160
|
|
|
174
161
|
delete this[symbols.effects]
|
|
175
162
|
|
|
176
|
-
Log.debug(`Destroyed component ${this
|
|
163
|
+
Log.debug(`Destroyed component ${this.$componentId}`)
|
|
164
|
+
delete this.$componentId
|
|
177
165
|
},
|
|
178
166
|
writable: false,
|
|
179
167
|
enumerable: true,
|
|
@@ -190,18 +178,6 @@ export default {
|
|
|
190
178
|
enumerable: false,
|
|
191
179
|
configurable: false,
|
|
192
180
|
},
|
|
193
|
-
select: {
|
|
194
|
-
/**
|
|
195
|
-
* @this {import('../../component').BlitsComponent}
|
|
196
|
-
*/
|
|
197
|
-
value: function (ref) {
|
|
198
|
-
Log.warn('this.select is deprecated, use this.$select instead')
|
|
199
|
-
return this.$select(ref)
|
|
200
|
-
},
|
|
201
|
-
writable: false,
|
|
202
|
-
enumerable: true,
|
|
203
|
-
configurable: false,
|
|
204
|
-
},
|
|
205
181
|
$select: {
|
|
206
182
|
/**
|
|
207
183
|
* @this {import('../../component').BlitsComponent}
|
|
@@ -230,18 +206,6 @@ export default {
|
|
|
230
206
|
enumerable: true,
|
|
231
207
|
configurable: false,
|
|
232
208
|
},
|
|
233
|
-
trigger: {
|
|
234
|
-
/**
|
|
235
|
-
* @this {import('../../component').BlitsComponent}
|
|
236
|
-
*/
|
|
237
|
-
value: function (key) {
|
|
238
|
-
Log.warn('this.trigger is deprecated, use this.$trigger instead')
|
|
239
|
-
return this.$trigger(key)
|
|
240
|
-
},
|
|
241
|
-
writable: false,
|
|
242
|
-
enumerable: true,
|
|
243
|
-
configurable: false,
|
|
244
|
-
},
|
|
245
209
|
$trigger: {
|
|
246
210
|
/**
|
|
247
211
|
* @this {import('../../component').BlitsComponent}
|
|
@@ -263,30 +227,6 @@ export default {
|
|
|
263
227
|
enumerable: true,
|
|
264
228
|
configurable: false,
|
|
265
229
|
},
|
|
266
|
-
shader: {
|
|
267
|
-
/**
|
|
268
|
-
* @this {import('../../component').BlitsComponent}
|
|
269
|
-
*/
|
|
270
|
-
value: function (type, args) {
|
|
271
|
-
return {
|
|
272
|
-
type: type,
|
|
273
|
-
props: args,
|
|
274
|
-
}
|
|
275
|
-
// const shaders = renderer.driver.stage.shManager.getRegisteredEffects()
|
|
276
|
-
|
|
277
|
-
// if (target in shaders) {
|
|
278
|
-
// return {
|
|
279
|
-
// type: target,
|
|
280
|
-
// props: args,
|
|
281
|
-
// }
|
|
282
|
-
// } else {
|
|
283
|
-
// Log.error(`Shader ${type} not found`)
|
|
284
|
-
// }
|
|
285
|
-
},
|
|
286
|
-
writable: false,
|
|
287
|
-
enumerable: true,
|
|
288
|
-
configurable: false,
|
|
289
|
-
},
|
|
290
230
|
}
|
|
291
231
|
|
|
292
232
|
/**
|
|
@@ -29,6 +29,20 @@ export default {
|
|
|
29
29
|
enumerable: true,
|
|
30
30
|
configurable: false,
|
|
31
31
|
},
|
|
32
|
+
$parent: {
|
|
33
|
+
get: function () {
|
|
34
|
+
return this[symbols.parent]
|
|
35
|
+
},
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: false,
|
|
38
|
+
},
|
|
39
|
+
$id: {
|
|
40
|
+
get: function () {
|
|
41
|
+
return this[symbols.id]
|
|
42
|
+
},
|
|
43
|
+
enumerable: true,
|
|
44
|
+
configurable: false,
|
|
45
|
+
},
|
|
32
46
|
[symbols.renderer]: {
|
|
33
47
|
value: () => renderer,
|
|
34
48
|
writable: false,
|
|
@@ -37,7 +51,7 @@ export default {
|
|
|
37
51
|
},
|
|
38
52
|
[symbols.getChildren]: {
|
|
39
53
|
value() {
|
|
40
|
-
const parent = this.rootParent || this.parent
|
|
54
|
+
const parent = this[symbols.rootParent] || this[symbols.parent]
|
|
41
55
|
return (this[symbols.children] || []).concat(
|
|
42
56
|
(parent &&
|
|
43
57
|
parent[symbols.getChildren]()
|
|
@@ -46,7 +60,7 @@ export default {
|
|
|
46
60
|
return Object.values(child).map((c) => {
|
|
47
61
|
// ugly hack .. but the point is to reference the right component
|
|
48
62
|
c.forComponent =
|
|
49
|
-
c[Symbol.for('config')] && c[Symbol.for('config')].parent.component
|
|
63
|
+
c[Symbol.for('config')] && c[Symbol.for('config')][symbols.parent].component
|
|
50
64
|
return c
|
|
51
65
|
})
|
|
52
66
|
}
|
|
@@ -57,8 +71,8 @@ export default {
|
|
|
57
71
|
// problem is that component of a forloop in a slot has component of root component
|
|
58
72
|
if (child && child.component) {
|
|
59
73
|
return (
|
|
60
|
-
(child.component && child.component
|
|
61
|
-
(child.forComponent && child.forComponent
|
|
74
|
+
(child.component && child.component.$componentId === this.$componentId) ||
|
|
75
|
+
(child.forComponent && child.forComponent.$componentId === this.$componentId)
|
|
62
76
|
)
|
|
63
77
|
}
|
|
64
78
|
})) ||
|
|
@@ -16,46 +16,55 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { Log } from '../../lib/log.js'
|
|
19
|
-
|
|
20
19
|
import symbols from '../../lib/symbols.js'
|
|
21
20
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const normalizeProps = (props) => {
|
|
22
|
+
Log.warn(
|
|
23
|
+
'Defining props as an Array has been deprecated and will stop working in future versions. Please use the new notation instead (an object with key values pairs).',
|
|
24
|
+
props
|
|
25
|
+
)
|
|
26
|
+
const out = {}
|
|
27
|
+
const propLength = props.length
|
|
28
|
+
for (let i = 0; i < propLength; i++) {
|
|
29
|
+
const prop = props[i]
|
|
30
|
+
if (typeof prop === 'string') {
|
|
31
|
+
out[prop] = undefined
|
|
32
|
+
} else {
|
|
33
|
+
Log.error(
|
|
34
|
+
'Defining props as an array of objects is no longer supported. Please use the new format: an object with key-value pairs.'
|
|
35
|
+
)
|
|
36
|
+
break
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return out
|
|
25
40
|
}
|
|
26
41
|
|
|
27
|
-
export default (component, props =
|
|
28
|
-
if (
|
|
29
|
-
props
|
|
42
|
+
export default (component, props = {}) => {
|
|
43
|
+
if (Array.isArray(props) === true) {
|
|
44
|
+
props = normalizeProps(props)
|
|
45
|
+
}
|
|
46
|
+
if (!('ref' in props)) {
|
|
47
|
+
props.ref = undefined
|
|
30
48
|
}
|
|
31
|
-
|
|
49
|
+
const keys = Object.keys(props)
|
|
50
|
+
component[symbols.propKeys] = keys
|
|
32
51
|
|
|
33
|
-
|
|
52
|
+
for (let i = 0; i < keys.length; i++) {
|
|
53
|
+
const key = keys[i]
|
|
54
|
+
const defaultPropValue = props[key]
|
|
34
55
|
|
|
35
|
-
|
|
36
|
-
const prop = { ...baseProp, ...(typeof props[i] === 'object' ? props[i] : { key: props[i] }) }
|
|
37
|
-
component[symbols.propKeys].push(prop.key)
|
|
38
|
-
Object.defineProperty(component, prop.key, {
|
|
56
|
+
Object.defineProperty(component, key, {
|
|
39
57
|
get() {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
? prop.default
|
|
45
|
-
: undefined
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
if (prop.required === true && value === undefined) {
|
|
49
|
-
Log.warn(`${prop.key} is required`)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return value
|
|
58
|
+
if (this[symbols.props] === undefined) return undefined
|
|
59
|
+
// if the key is specified independent of the value (falsy, null, undefined) use that value
|
|
60
|
+
// otherwise return the default prop value
|
|
61
|
+
return key in this[symbols.props] ? this[symbols.props][key] : defaultPropValue
|
|
53
62
|
},
|
|
54
63
|
set(v) {
|
|
55
64
|
Log.warn(
|
|
56
|
-
`Warning! Avoid mutating props directly (prop "${
|
|
65
|
+
`Warning! Avoid mutating props directly (prop "${key}" in component "${this.componentId}")`
|
|
57
66
|
)
|
|
58
|
-
this[symbols.props][
|
|
67
|
+
this[symbols.props][key] = v
|
|
59
68
|
},
|
|
60
69
|
})
|
|
61
70
|
}
|
|
@@ -28,13 +28,13 @@ export default (component, state = () => {}) => {
|
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
const stateKeys = Object.keys(state.apply(component) || {})
|
|
31
|
-
if (stateKeys.indexOf('hasFocus') > -1) {
|
|
31
|
+
if (stateKeys.indexOf('$hasFocus') > -1) {
|
|
32
32
|
Log.warn(
|
|
33
|
-
'State
|
|
33
|
+
'State `$hasFocus` already exists as a built-in Component variable (to indicate whether the component currently has focus). Avoid using your own `$hasFocus` key in the Component state'
|
|
34
34
|
)
|
|
35
35
|
} else {
|
|
36
|
-
// add built-in hasFocus key
|
|
37
|
-
stateKeys.push(
|
|
36
|
+
// add built-in $hasFocus key
|
|
37
|
+
stateKeys.push('$hasFocus')
|
|
38
38
|
}
|
|
39
39
|
const stateKeysLength = stateKeys.length
|
|
40
40
|
|
package/src/component.js
CHANGED
|
@@ -135,7 +135,7 @@ const required = (name) => {
|
|
|
135
135
|
* @property {any[]} [stateKeys] - The keys of the state of the component instance
|
|
136
136
|
* Single props:
|
|
137
137
|
* @property {object} activeView - The active view of the component instance
|
|
138
|
-
* @property {boolean} hasFocus - Indicates if the component has focus
|
|
138
|
+
* @property {boolean} $hasFocus - Indicates if the component has focus
|
|
139
139
|
* @property {string} ref - The reference name of the component instance
|
|
140
140
|
* @property {number|undefined} index - The index in a for loop
|
|
141
141
|
* @property {number|undefined} activeRow - The active row in a for loop
|
|
@@ -194,22 +194,23 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
194
194
|
|
|
195
195
|
const component = function (opts, parentEl, parentComponent, rootComponent) {
|
|
196
196
|
// generate a human readable ID for the component instance (i.e. Blits::ComponentName1)
|
|
197
|
-
this
|
|
197
|
+
this.$componentId = createHumanReadableId(name)
|
|
198
|
+
|
|
199
|
+
this[symbols.effects] = []
|
|
198
200
|
|
|
199
201
|
this[symbols.effects] = []
|
|
200
202
|
|
|
201
203
|
// instantiate a lifecycle object for this instance
|
|
202
|
-
this.lifecycle = Object.assign(Object.create(Lifecycle), {
|
|
204
|
+
this[symbols.lifecycle] = Object.assign(Object.create(Lifecycle), {
|
|
203
205
|
component: this,
|
|
204
206
|
previous: null,
|
|
205
207
|
current: null,
|
|
206
208
|
})
|
|
207
209
|
|
|
208
210
|
// set a reference to the parent component
|
|
209
|
-
this.parent = parentComponent
|
|
211
|
+
this[symbols.parent] = parentComponent
|
|
210
212
|
|
|
211
|
-
|
|
212
|
-
this.rootParent = rootComponent
|
|
213
|
+
this[symbols.rootParent] = rootComponent
|
|
213
214
|
|
|
214
215
|
// set a reference to the holder / parentElement
|
|
215
216
|
// Components are wrapped in a holder node (used to apply positioning and transforms
|
|
@@ -235,19 +236,19 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
235
236
|
// and store a reference to this original state
|
|
236
237
|
this[symbols.originalState] =
|
|
237
238
|
(config.state && typeof config.state === 'function' && config.state.apply(this)) || {}
|
|
238
|
-
// add hasFocus key in
|
|
239
|
-
this[symbols.originalState]['hasFocus'] = false
|
|
239
|
+
// add $hasFocus key in
|
|
240
|
+
this[symbols.originalState]['$hasFocus'] = false
|
|
240
241
|
|
|
241
242
|
// generate a reactive state (using the result of previously execute state function)
|
|
242
243
|
// and store it
|
|
243
244
|
this[symbols.state] = reactive(this[symbols.originalState], Settings.get('reactivityMode'))
|
|
244
245
|
|
|
245
246
|
// all basic setup has been done now, set the lifecycle to state 'init'
|
|
246
|
-
this.lifecycle.state = 'init'
|
|
247
|
+
this[symbols.lifecycle].state = 'init'
|
|
247
248
|
|
|
248
249
|
// execute the render code that constructs the initial state of the component
|
|
249
250
|
// and store the children result (a flat map of elements and components)
|
|
250
|
-
const { elms, cleanup } = config.code.render.apply(stage, [
|
|
251
|
+
const { elms, cleanup, skips } = config.code.render.apply(stage, [
|
|
251
252
|
parentEl,
|
|
252
253
|
this,
|
|
253
254
|
config,
|
|
@@ -300,28 +301,28 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
300
301
|
// inBounds event emiting a lifecycle attach event
|
|
301
302
|
if (config.hooks.attach) {
|
|
302
303
|
this[symbols.wrapper].node.on('inBounds', () => {
|
|
303
|
-
this.lifecycle.state = 'attach'
|
|
304
|
+
this[symbols.lifecycle].state = 'attach'
|
|
304
305
|
})
|
|
305
306
|
}
|
|
306
307
|
|
|
307
308
|
// outOfBounds event emiting a lifeycle detach event
|
|
308
309
|
if (config.hooks.detach) {
|
|
309
310
|
this[symbols.wrapper].node.on('outOfBounds', (node, { previous }) => {
|
|
310
|
-
if (previous > 0) this.lifecycle.state = 'detach'
|
|
311
|
+
if (previous > 0) this[symbols.lifecycle].state = 'detach'
|
|
311
312
|
})
|
|
312
313
|
}
|
|
313
314
|
|
|
314
315
|
// inViewport event emiting a lifecycle enter event
|
|
315
316
|
if (config.hooks.enter) {
|
|
316
317
|
this[symbols.wrapper].node.on('inViewport', () => {
|
|
317
|
-
this.lifecycle.state = 'enter'
|
|
318
|
+
this[symbols.lifecycle].state = 'enter'
|
|
318
319
|
})
|
|
319
320
|
}
|
|
320
321
|
|
|
321
322
|
// outOfViewport event emitting a lifecycle exit event
|
|
322
323
|
if (config.hooks.exit) {
|
|
323
324
|
this[symbols.wrapper].node.on('outOfBounds', () => {
|
|
324
|
-
this.lifecycle.state = 'exit'
|
|
325
|
+
this[symbols.lifecycle].state = 'exit'
|
|
325
326
|
})
|
|
326
327
|
}
|
|
327
328
|
}
|
|
@@ -331,7 +332,15 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
331
332
|
const effects = config.code.effects
|
|
332
333
|
for (let i = 0; i < effects.length; i++) {
|
|
333
334
|
const eff = () => {
|
|
334
|
-
effects[i](
|
|
335
|
+
effects[i](
|
|
336
|
+
this,
|
|
337
|
+
this[symbols.children],
|
|
338
|
+
config,
|
|
339
|
+
globalComponents,
|
|
340
|
+
rootComponent,
|
|
341
|
+
skips,
|
|
342
|
+
effect
|
|
343
|
+
)
|
|
335
344
|
}
|
|
336
345
|
// store reference to the effect
|
|
337
346
|
this[symbols.effects].push(eff)
|
|
@@ -355,7 +364,7 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
355
364
|
}
|
|
356
365
|
}
|
|
357
366
|
|
|
358
|
-
let old =
|
|
367
|
+
let old = target[key]
|
|
359
368
|
|
|
360
369
|
const eff = (force = false) => {
|
|
361
370
|
const newValue = target[key]
|
|
@@ -372,7 +381,7 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
372
381
|
}
|
|
373
382
|
|
|
374
383
|
// finaly set the lifecycle state to ready (in the next tick)
|
|
375
|
-
setTimeout(() => (this.lifecycle.state = 'ready'))
|
|
384
|
+
setTimeout(() => (this[symbols.lifecycle].state = 'ready'))
|
|
376
385
|
|
|
377
386
|
// and return this
|
|
378
387
|
return this
|