@dcl/react-ecs 7.21.1-22917715332.commit-e5d969d → 7.21.1-23203004012.commit-7c64ac2
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/dist/components/Button/index.js +2 -2
- package/dist/components/Dropdown/index.js +2 -10
- package/dist/components/Input/index.js +2 -10
- package/dist/components/Label/index.js +3 -13
- package/dist/components/Label/types.d.ts +0 -4
- package/dist/components/listeners/types.d.ts +6 -37
- package/dist/components/listeners/types.js +1 -9
- package/dist/components/uiBackground/types.d.ts +1 -12
- package/dist/components/uiBackground/utils.js +0 -8
- package/dist/components/uiTransform/index.d.ts +1 -1
- package/dist/components/uiTransform/index.js +3 -6
- package/dist/components/uiTransform/types.d.ts +0 -12
- package/dist/components/uiTransform/utils.js +0 -37
- package/dist/react-ecs.d.ts +6 -14
- package/dist/reconciler/index.d.ts +3 -4
- package/dist/reconciler/index.js +91 -68
- package/dist/reconciler/utils.js +0 -8
- package/dist/system.d.ts +0 -5
- package/dist/system.js +1 -14
- package/package.json +3 -3
|
@@ -29,7 +29,7 @@ function getButtonProps(props) {
|
|
|
29
29
|
*/
|
|
30
30
|
/* @__PURE__ */
|
|
31
31
|
export function Button(props) {
|
|
32
|
-
const { uiTransform, uiBackground, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave,
|
|
32
|
+
const { uiTransform, uiBackground, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave, ...otherProps } = props;
|
|
33
33
|
const buttonProps = getButtonProps(props);
|
|
34
34
|
const uiBackgroundProps = parseUiBackground({
|
|
35
35
|
...buttonProps.uiBackground,
|
|
@@ -54,5 +54,5 @@ export function Button(props) {
|
|
|
54
54
|
if (uiBackgroundProps && uiBackgroundProps.color)
|
|
55
55
|
uiBackgroundProps.color.a /= 2;
|
|
56
56
|
}
|
|
57
|
-
return (ReactEcs.createElement("entity", { onMouseDown: !!props.disabled ? undefined : onMouseDown, onMouseUp: !!props.disabled ? undefined : onMouseUp, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave,
|
|
57
|
+
return (ReactEcs.createElement("entity", { onMouseDown: !!props.disabled ? undefined : onMouseDown, onMouseUp: !!props.disabled ? undefined : onMouseUp, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, uiTransform: uiTransformProps, uiText: textProps, uiBackground: uiBackgroundProps }));
|
|
58
58
|
}
|
|
@@ -34,7 +34,7 @@ function parseUiDropdown(props) {
|
|
|
34
34
|
*/
|
|
35
35
|
/* @__PURE__ */
|
|
36
36
|
export function Dropdown(props) {
|
|
37
|
-
const { uiTransform, uiBackground, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave,
|
|
37
|
+
const { uiTransform, uiBackground, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave, ...otherProps } = props;
|
|
38
38
|
const dropdownProps = parseUiDropdown(otherProps);
|
|
39
39
|
const commonProps = parseProps({
|
|
40
40
|
uiTransform,
|
|
@@ -42,15 +42,7 @@ export function Dropdown(props) {
|
|
|
42
42
|
onMouseDown,
|
|
43
43
|
onMouseUp,
|
|
44
44
|
onMouseEnter,
|
|
45
|
-
onMouseLeave
|
|
46
|
-
onMouseDrag,
|
|
47
|
-
onMouseDragLocked,
|
|
48
|
-
onMouseDragEnd,
|
|
49
|
-
onInputDown,
|
|
50
|
-
onInputUp,
|
|
51
|
-
onInputDrag,
|
|
52
|
-
onInputDragLocked,
|
|
53
|
-
onInputDragEnd
|
|
45
|
+
onMouseLeave
|
|
54
46
|
});
|
|
55
47
|
return ReactEcs.createElement("entity", { ...commonProps, uiDropdown: dropdownProps });
|
|
56
48
|
}
|
|
@@ -35,7 +35,7 @@ function parseUiInput(props) {
|
|
|
35
35
|
* @category Component
|
|
36
36
|
*/ /* @__PURE__ */
|
|
37
37
|
export function Input(props) {
|
|
38
|
-
const { uiTransform, uiBackground, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave,
|
|
38
|
+
const { uiTransform, uiBackground, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave, ...otherProps } = props;
|
|
39
39
|
const inputProps = parseUiInput(otherProps);
|
|
40
40
|
const commonProps = parseProps({
|
|
41
41
|
uiTransform,
|
|
@@ -43,15 +43,7 @@ export function Input(props) {
|
|
|
43
43
|
onMouseDown,
|
|
44
44
|
onMouseUp,
|
|
45
45
|
onMouseEnter,
|
|
46
|
-
onMouseLeave
|
|
47
|
-
onMouseDrag,
|
|
48
|
-
onMouseDragLocked,
|
|
49
|
-
onMouseDragEnd,
|
|
50
|
-
onInputDown,
|
|
51
|
-
onInputUp,
|
|
52
|
-
onInputDrag,
|
|
53
|
-
onInputDragLocked,
|
|
54
|
-
onInputDragEnd
|
|
46
|
+
onMouseLeave
|
|
55
47
|
});
|
|
56
48
|
return ReactEcs.createElement("entity", { ...commonProps, uiInput: inputProps });
|
|
57
49
|
}
|
|
@@ -16,22 +16,14 @@ export { scaleFontSize } from './utils';
|
|
|
16
16
|
*/
|
|
17
17
|
/* @__PURE__ */
|
|
18
18
|
export function Label(props) {
|
|
19
|
-
const { uiTransform, uiBackground, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave,
|
|
19
|
+
const { uiTransform, uiBackground, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave, ...uiTextProps } = props;
|
|
20
20
|
const commonProps = parseProps({
|
|
21
21
|
uiTransform,
|
|
22
22
|
uiBackground,
|
|
23
23
|
onMouseDown,
|
|
24
24
|
onMouseUp,
|
|
25
25
|
onMouseEnter,
|
|
26
|
-
onMouseLeave
|
|
27
|
-
onMouseDrag,
|
|
28
|
-
onMouseDragLocked,
|
|
29
|
-
onMouseDragEnd,
|
|
30
|
-
onInputDown,
|
|
31
|
-
onInputUp,
|
|
32
|
-
onInputDrag,
|
|
33
|
-
onInputDragLocked,
|
|
34
|
-
onInputDragEnd
|
|
26
|
+
onMouseLeave
|
|
35
27
|
});
|
|
36
28
|
const { font, textAlign, fontSize, textWrap, ...textProps } = uiTextProps;
|
|
37
29
|
const uiText = {
|
|
@@ -39,9 +31,7 @@ export function Label(props) {
|
|
|
39
31
|
...getFont(font),
|
|
40
32
|
...getTextAlign(textAlign),
|
|
41
33
|
...getFontSize(fontSize),
|
|
42
|
-
...getTextWrap(textWrap)
|
|
43
|
-
outlineWidth: props.outlineWidth,
|
|
44
|
-
outlineColor: props.outlineColor
|
|
34
|
+
...getTextWrap(textWrap)
|
|
45
35
|
};
|
|
46
36
|
return ReactEcs.createElement("entity", { ...commonProps, uiText: uiText });
|
|
47
37
|
}
|
|
@@ -15,10 +15,6 @@ export interface UiLabelProps {
|
|
|
15
15
|
textAlign?: TextAlignType | undefined;
|
|
16
16
|
/** Label font type. @defaultValue 'sans-serif' */
|
|
17
17
|
font?: UiFontType | undefined;
|
|
18
|
-
/** Outline width of the text. @defaultValue 0 */
|
|
19
|
-
outlineWidth?: number | undefined;
|
|
20
|
-
/** Outline color of the text. @defaultValue `{ r: 0, g: 0, b: 0, a: 1 }` */
|
|
21
|
-
outlineColor?: Color4 | undefined;
|
|
22
18
|
/** Behaviour when text reached. @defaultValue 'wrap' */
|
|
23
19
|
textWrap?: UiTextWrapType | undefined;
|
|
24
20
|
}
|
|
@@ -1,50 +1,19 @@
|
|
|
1
|
-
import { EventSystemCallback, InputAction } from '@dcl/ecs';
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @public @deprecated This type is no longer used in the sdk api, EventSystemCallback is
|
|
6
|
-
* used for listeners instead
|
|
7
|
-
*/
|
|
8
|
-
export type Callback = () => void;
|
|
9
|
-
/**
|
|
10
|
-
* a record object mapping `InputAction`s to functions.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* onInputDown={{
|
|
14
|
-
* [InputAction.IA_PRIMARY]: (eventData) => { console.log("primary") },
|
|
15
|
-
* [InputAction.IA_SECONDARY]: () => { console.log("secondary") },
|
|
16
|
-
* }}
|
|
17
|
-
*
|
|
2
|
+
* Callback function to be triggered on a specified event
|
|
18
3
|
* @public
|
|
19
4
|
*/
|
|
20
|
-
export type
|
|
5
|
+
export type Callback = () => void;
|
|
21
6
|
/**
|
|
22
7
|
* User key event Listeners
|
|
23
8
|
* @public
|
|
24
9
|
*/
|
|
25
10
|
export type Listeners = {
|
|
26
11
|
/** triggered on mouse down event */
|
|
27
|
-
onMouseDown?:
|
|
12
|
+
onMouseDown?: Callback;
|
|
28
13
|
/** triggered on mouse up event */
|
|
29
|
-
onMouseUp?:
|
|
14
|
+
onMouseUp?: Callback;
|
|
30
15
|
/** triggered on mouse hover event */
|
|
31
|
-
onMouseEnter?:
|
|
16
|
+
onMouseEnter?: Callback;
|
|
32
17
|
/** triggered on mouse leave event */
|
|
33
|
-
onMouseLeave?:
|
|
34
|
-
/** triggered on mouse drag event */
|
|
35
|
-
onMouseDrag?: EventSystemCallback;
|
|
36
|
-
/** triggered on mouse drag event */
|
|
37
|
-
onMouseDragLocked?: EventSystemCallback;
|
|
38
|
-
/** triggered on mouse drag event */
|
|
39
|
-
onMouseDragEnd?: EventSystemCallback;
|
|
40
|
-
/** triggered on input down event */
|
|
41
|
-
onInputDown?: MultiCallback;
|
|
42
|
-
/** triggered on input up event */
|
|
43
|
-
onInputUp?: MultiCallback;
|
|
44
|
-
/** triggered on input drag event */
|
|
45
|
-
onInputDrag?: MultiCallback;
|
|
46
|
-
/** triggered on input drag event */
|
|
47
|
-
onInputDragLocked?: MultiCallback;
|
|
48
|
-
/** triggered on input drag event */
|
|
49
|
-
onInputDragEnd?: MultiCallback;
|
|
18
|
+
onMouseLeave?: Callback;
|
|
50
19
|
};
|
|
@@ -2,15 +2,7 @@ const listeners = {
|
|
|
2
2
|
onMouseDown: undefined,
|
|
3
3
|
onMouseUp: undefined,
|
|
4
4
|
onMouseEnter: undefined,
|
|
5
|
-
onMouseLeave: undefined
|
|
6
|
-
onMouseDrag: undefined,
|
|
7
|
-
onMouseDragLocked: undefined,
|
|
8
|
-
onMouseDragEnd: undefined,
|
|
9
|
-
onInputDown: undefined,
|
|
10
|
-
onInputUp: undefined,
|
|
11
|
-
onInputDrag: undefined,
|
|
12
|
-
onInputDragLocked: undefined,
|
|
13
|
-
onInputDragEnd: undefined
|
|
5
|
+
onMouseLeave: undefined
|
|
14
6
|
};
|
|
15
7
|
const listenersKey = Object.keys(listeners);
|
|
16
8
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BorderRect
|
|
1
|
+
import { BorderRect } from '@dcl/ecs';
|
|
2
2
|
import { Color4 } from '@dcl/ecs/dist/components/generated/pb/decentraland/common/colors.gen';
|
|
3
3
|
/**
|
|
4
4
|
* @public
|
|
@@ -15,8 +15,6 @@ export interface UiBackgroundProps {
|
|
|
15
15
|
uvs?: number[];
|
|
16
16
|
/** AvatarTexture for the background */
|
|
17
17
|
avatarTexture?: UiAvatarTexture;
|
|
18
|
-
/** VideoTexture for the background */
|
|
19
|
-
videoTexture?: UiVideoTexture;
|
|
20
18
|
/** Texture for the background */
|
|
21
19
|
texture?: UiTexture;
|
|
22
20
|
}
|
|
@@ -29,15 +27,6 @@ export interface UiAvatarTexture {
|
|
|
29
27
|
wrapMode?: TextureWrapType;
|
|
30
28
|
filterMode?: TextureFilterType;
|
|
31
29
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Texture
|
|
34
|
-
* @public
|
|
35
|
-
*/
|
|
36
|
-
export interface UiVideoTexture {
|
|
37
|
-
videoPlayerEntity: Entity;
|
|
38
|
-
wrapMode?: TextureWrapType;
|
|
39
|
-
filterMode?: TextureFilterType;
|
|
40
|
-
}
|
|
41
30
|
/**
|
|
42
31
|
* Texture
|
|
43
32
|
* @public
|
|
@@ -30,14 +30,6 @@ export function getTexture(props) {
|
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
if (props.videoTexture) {
|
|
34
|
-
return {
|
|
35
|
-
tex: {
|
|
36
|
-
$case: 'videoTexture',
|
|
37
|
-
videoTexture: parseTexture(props.videoTexture)
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
33
|
return undefined;
|
|
42
34
|
}
|
|
43
35
|
function parseTexture(texture) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getAlign, getDisplay, getFlexDirection, getFlexWrap, getJustify, getOverflow, getPointerFilter, getPositionType, parseBorderColor, parseBorderRadius, parseBorderWidth,
|
|
1
|
+
import { getAlign, getDisplay, getFlexDirection, getFlexWrap, getJustify, getOverflow, getPointerFilter, getPositionType, parseBorderColor, parseBorderRadius, parseBorderWidth, parsePosition, parseSize } from './utils';
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
@@ -60,7 +60,7 @@ const defaultUiTransform = {
|
|
|
60
60
|
*/
|
|
61
61
|
/* @__PURE__ */
|
|
62
62
|
export function parseUiTransform(props = {}) {
|
|
63
|
-
const {
|
|
63
|
+
const { height, minHeight, maxHeight, width, minWidth, maxWidth, alignItems, alignContent, flexWrap, borderRadius, borderWidth, borderColor, ...otherProps } = props;
|
|
64
64
|
return {
|
|
65
65
|
...defaultUiTransform,
|
|
66
66
|
...otherProps,
|
|
@@ -86,9 +86,6 @@ export function parseUiTransform(props = {}) {
|
|
|
86
86
|
...(flexWrap && getFlexWrap(flexWrap)),
|
|
87
87
|
...(borderRadius && parseBorderRadius(borderRadius)),
|
|
88
88
|
...(borderWidth && parseBorderWidth(borderWidth)),
|
|
89
|
-
...(borderColor && parseBorderColor(borderColor))
|
|
90
|
-
...(scrollPosition && getScrollPosition(scrollPosition)),
|
|
91
|
-
...(scrollVisible && getScrollVisible(scrollVisible)),
|
|
92
|
-
...(zIndex && { zIndex })
|
|
89
|
+
...(borderColor && parseBorderColor(borderColor))
|
|
93
90
|
};
|
|
94
91
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Color4 } from '@dcl/ecs/dist/components/generated/pb/decentraland/common/colors.gen';
|
|
2
|
-
import { Vector2 } from '@dcl/ecs/dist/components/generated/pb/decentraland/common/vectors.gen';
|
|
3
2
|
import { ScaleUnit } from '../types';
|
|
4
3
|
/**
|
|
5
4
|
* unit value specified. i.e. 1 || '100%' || '1px' || '10vw'
|
|
@@ -74,11 +73,6 @@ export type PositionType = 'absolute' | 'relative';
|
|
|
74
73
|
* The pointer filter property determines if the ui element blocks the pointer or not (elements with pointer events always block the pointer regardless of this property)
|
|
75
74
|
*/
|
|
76
75
|
export type PointerFilterType = 'none' | 'block';
|
|
77
|
-
/**
|
|
78
|
-
* @public
|
|
79
|
-
* The scroll-visible determines if the scrollbars are shown when the scroll overflow is enabled
|
|
80
|
-
*/
|
|
81
|
-
export type ScrollVisibleType = 'horizontal' | 'vertical' | 'both' | 'hidden';
|
|
82
76
|
/**
|
|
83
77
|
* Layout props to position things in the canvas
|
|
84
78
|
* @public
|
|
@@ -135,12 +129,6 @@ export interface UiTransformProps {
|
|
|
135
129
|
borderWidth?: Partial<Position> | PositionUnit;
|
|
136
130
|
/** The opacity property sets the opacity level for an element, it's accumulated across children @defaultValue 1 */
|
|
137
131
|
opacity?: number;
|
|
138
|
-
/** A reference value to identify the element, default empty */
|
|
139
|
-
elementId?: string;
|
|
140
|
-
/** default position=(0,0) if it aplies, a vector or a reference-id */
|
|
141
|
-
scrollPosition?: Vector2 | string;
|
|
142
|
-
/** default ShowScrollBar.SSB_BOTH */
|
|
143
|
-
scrollVisible?: ScrollVisibleType;
|
|
144
132
|
/** default 0 */
|
|
145
133
|
zIndex?: number;
|
|
146
134
|
}
|
|
@@ -244,40 +244,3 @@ const parsePointerFilter = {
|
|
|
244
244
|
none: 0 /* PointerFilterMode.PFM_NONE */,
|
|
245
245
|
block: 1 /* PointerFilterMode.PFM_BLOCK */
|
|
246
246
|
};
|
|
247
|
-
/**
|
|
248
|
-
* @internal
|
|
249
|
-
*/
|
|
250
|
-
export function getScrollPosition(scrollPosition) {
|
|
251
|
-
if (typeof scrollPosition === 'string') {
|
|
252
|
-
return {
|
|
253
|
-
scrollPosition: {
|
|
254
|
-
value: {
|
|
255
|
-
$case: 'reference',
|
|
256
|
-
reference: scrollPosition
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
return {
|
|
263
|
-
scrollPosition: {
|
|
264
|
-
value: {
|
|
265
|
-
$case: 'position',
|
|
266
|
-
position: scrollPosition
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
const parseScrollVisible = {
|
|
273
|
-
both: 0 /* ShowScrollBar.SSB_BOTH */,
|
|
274
|
-
hidden: 3 /* ShowScrollBar.SSB_HIDDEN */,
|
|
275
|
-
horizontal: 2 /* ShowScrollBar.SSB_ONLY_HORIZONTAL */,
|
|
276
|
-
vertical: 1 /* ShowScrollBar.SSB_ONLY_VERTICAL */
|
|
277
|
-
};
|
|
278
|
-
/**
|
|
279
|
-
* @internal
|
|
280
|
-
*/
|
|
281
|
-
export function getScrollVisible(scrollVisible) {
|
|
282
|
-
return { scrollVisible: parseScrollVisible[scrollVisible] };
|
|
283
|
-
}
|
package/dist/react-ecs.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PBUiBackground, PBUiText, PBUiTransform, PBUiInput, PBUiDropdown
|
|
2
|
-
import {
|
|
1
|
+
import { PBUiBackground, PBUiText, PBUiTransform, PBUiInput, PBUiDropdown } from '@dcl/ecs';
|
|
2
|
+
import { Callback, Key } from './components';
|
|
3
3
|
/**
|
|
4
4
|
* @public
|
|
5
5
|
*/
|
|
@@ -18,18 +18,10 @@ export type EntityComponents = {
|
|
|
18
18
|
uiBackground: PBUiBackground;
|
|
19
19
|
uiInput: PBUiInput;
|
|
20
20
|
uiDropdown: PBUiDropdown;
|
|
21
|
-
onMouseDown:
|
|
22
|
-
onMouseUp:
|
|
23
|
-
onMouseEnter:
|
|
24
|
-
onMouseLeave:
|
|
25
|
-
onMouseDrag: EventSystemCallback;
|
|
26
|
-
onMouseDragLocked: EventSystemCallback;
|
|
27
|
-
onMouseDragEnd: EventSystemCallback;
|
|
28
|
-
onInputDown: MultiCallback;
|
|
29
|
-
onInputUp: MultiCallback;
|
|
30
|
-
onInputDrag: MultiCallback;
|
|
31
|
-
onInputDragLocked: MultiCallback;
|
|
32
|
-
onInputDragEnd: MultiCallback;
|
|
21
|
+
onMouseDown: Callback;
|
|
22
|
+
onMouseUp: Callback;
|
|
23
|
+
onMouseEnter: Callback;
|
|
24
|
+
onMouseLeave: Callback;
|
|
33
25
|
};
|
|
34
26
|
/**
|
|
35
27
|
* @hidden
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Entity, IEngine, PointerEventsSystem } from '@dcl/ecs';
|
|
2
2
|
import { ReactEcs } from '../react-ecs';
|
|
3
|
-
export
|
|
4
|
-
update: (component: ReactEcs.JSX.ReactNode) =>
|
|
3
|
+
export declare function createReconciler(engine: Pick<IEngine, 'getComponent' | 'addEntity' | 'removeEntity' | 'defineComponentFromSchema' | 'getEntitiesWith'>, pointerEvents: PointerEventsSystem): {
|
|
4
|
+
update: (component: ReactEcs.JSX.ReactNode) => number;
|
|
5
5
|
getEntities: () => Entity[];
|
|
6
|
-
}
|
|
7
|
-
export declare function createReconciler(engine: Pick<IEngine, 'getComponent' | 'addEntity' | 'removeEntity' | 'defineComponentFromSchema' | 'getEntitiesWith'>, pointerEvents: PointerEventsSystem, rootEntity: Entity | undefined): DclReconciler;
|
|
6
|
+
};
|
package/dist/reconciler/index.js
CHANGED
|
@@ -3,11 +3,24 @@ import Reconciler from 'react-reconciler';
|
|
|
3
3
|
import { isListener } from '../components';
|
|
4
4
|
import { CANVAS_ROOT_ENTITY } from '../components/uiTransform';
|
|
5
5
|
import { componentKeys, isNotUndefined, noopConfig, propsChanged } from './utils';
|
|
6
|
-
|
|
6
|
+
function getPointerEnum(pointerKey) {
|
|
7
|
+
const pointers = {
|
|
8
|
+
onMouseDown: 1 /* PointerEventType.PET_DOWN */,
|
|
9
|
+
onMouseUp: 0 /* PointerEventType.PET_UP */,
|
|
10
|
+
onMouseEnter: 2 /* PointerEventType.PET_HOVER_ENTER */,
|
|
11
|
+
onMouseLeave: 3 /* PointerEventType.PET_HOVER_LEAVE */
|
|
12
|
+
};
|
|
13
|
+
return pointers[pointerKey];
|
|
14
|
+
}
|
|
15
|
+
export function createReconciler(engine, pointerEvents) {
|
|
7
16
|
// Store all the entities so when we destroy the UI we can also destroy them
|
|
8
17
|
const entities = new Set();
|
|
9
18
|
// Store the onChange callbacks to be runned every time a Result has changed
|
|
10
19
|
const changeEvents = new Map();
|
|
20
|
+
const clickEvents = new Map();
|
|
21
|
+
// Track the last value reported by the renderer for each input entity,
|
|
22
|
+
// so we can avoid echoing it back and causing keystroke drops.
|
|
23
|
+
const lastInputResultValues = new Map();
|
|
11
24
|
// Initialize components
|
|
12
25
|
const UiTransform = components.UiTransform(engine);
|
|
13
26
|
const UiText = components.UiText(engine);
|
|
@@ -16,8 +29,6 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
16
29
|
const UiInputResult = components.UiInputResult(engine);
|
|
17
30
|
const UiDropdown = components.UiDropdown(engine);
|
|
18
31
|
const UiDropdownResult = components.UiDropdownResult(engine);
|
|
19
|
-
const UiScrollResult = components.UiScrollResult(engine);
|
|
20
|
-
const Transform = components.Transform(engine);
|
|
21
32
|
// Component ID Helper
|
|
22
33
|
const getComponentId = {
|
|
23
34
|
uiTransform: UiTransform.componentId,
|
|
@@ -26,15 +37,22 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
26
37
|
uiInput: UiInput.componentId,
|
|
27
38
|
uiDropdown: UiDropdown.componentId
|
|
28
39
|
};
|
|
40
|
+
function pointerEventCallback(entity, pointerEvent) {
|
|
41
|
+
const callback = clickEvents.get(entity)?.get(pointerEvent);
|
|
42
|
+
if (callback)
|
|
43
|
+
callback();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
29
46
|
function updateTree(instance, props) {
|
|
30
47
|
upsertComponent(instance, props, 'uiTransform');
|
|
31
48
|
}
|
|
32
49
|
function upsertListener(instance, update) {
|
|
33
50
|
if (update.type === 'delete' || !update.props) {
|
|
34
|
-
|
|
51
|
+
clickEvents.get(instance.entity)?.delete(getPointerEnum(update.component));
|
|
52
|
+
if (update.component === 'onMouseDown') {
|
|
35
53
|
pointerEvents.removeOnPointerDown(instance.entity);
|
|
36
54
|
}
|
|
37
|
-
else if (update.component === 'onMouseUp'
|
|
55
|
+
else if (update.component === 'onMouseUp') {
|
|
38
56
|
pointerEvents.removeOnPointerUp(instance.entity);
|
|
39
57
|
}
|
|
40
58
|
else if (update.component === 'onMouseEnter') {
|
|
@@ -43,57 +61,32 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
43
61
|
else if (update.component === 'onMouseLeave') {
|
|
44
62
|
pointerEvents.removeOnPointerHoverLeave(instance.entity);
|
|
45
63
|
}
|
|
46
|
-
else if (update.component === 'onMouseDrag' || update.component === 'onInputDrag') {
|
|
47
|
-
pointerEvents.removeOnPointerDrag(instance.entity);
|
|
48
|
-
}
|
|
49
|
-
else if (update.component === 'onMouseDragLocked' || update.component === 'onInputDragLocked') {
|
|
50
|
-
pointerEvents.removeOnPointerDragLocked(instance.entity);
|
|
51
|
-
}
|
|
52
|
-
else if (update.component === 'onMouseDragEnd' || update.component === 'onInputDragEnd') {
|
|
53
|
-
pointerEvents.removeOnPointerDragEnd(instance.entity);
|
|
54
|
-
}
|
|
55
64
|
return;
|
|
56
65
|
}
|
|
57
66
|
if (update.props) {
|
|
58
|
-
const
|
|
67
|
+
const pointerEvent = getPointerEnum(update.component);
|
|
68
|
+
const entityEvent = clickEvents.get(instance.entity) || clickEvents.set(instance.entity, new Map()).get(instance.entity);
|
|
69
|
+
const alreadyHasPointerEvent = entityEvent.get(pointerEvent);
|
|
70
|
+
entityEvent.set(pointerEvent, update.props);
|
|
71
|
+
if (alreadyHasPointerEvent)
|
|
72
|
+
return;
|
|
73
|
+
const pointerEventSystem = update.component === 'onMouseDown'
|
|
59
74
|
? pointerEvents.onPointerDown
|
|
60
|
-
: update.component === 'onMouseUp'
|
|
75
|
+
: update.component === 'onMouseUp'
|
|
61
76
|
? pointerEvents.onPointerUp
|
|
62
77
|
: update.component === 'onMouseEnter'
|
|
63
78
|
? pointerEvents.onPointerHoverEnter
|
|
64
|
-
: update.component === 'onMouseLeave'
|
|
65
|
-
? pointerEvents.onPointerHoverLeave
|
|
66
|
-
: update.component === 'onMouseDrag' || update.component === 'onInputDrag'
|
|
67
|
-
? pointerEvents.onPointerDrag
|
|
68
|
-
: update.component === 'onMouseDragLocked' || update.component === 'onInputDragLocked'
|
|
69
|
-
? pointerEvents.onPointerDragLocked
|
|
70
|
-
: (update.component === 'onMouseDragEnd' || update.component === 'onInputDragEnd') &&
|
|
71
|
-
pointerEvents.onPointerDragEnd;
|
|
79
|
+
: update.component === 'onMouseLeave' && pointerEvents.onPointerHoverLeave;
|
|
72
80
|
if (pointerEventSystem) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}, update.props);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
// force the right overload (the single arg version doesn't exist for onPointerHoverEnter or onPointerHoverLeave,
|
|
86
|
-
// but we don't have onInputXXX components for those)
|
|
87
|
-
;
|
|
88
|
-
pointerEventSystem({
|
|
89
|
-
entity: instance.entity,
|
|
90
|
-
optsList: Object.entries(update.props).map(([button, cb]) => ({
|
|
91
|
-
button: Number(button),
|
|
92
|
-
showFeedback: true,
|
|
93
|
-
cb
|
|
94
|
-
}))
|
|
95
|
-
});
|
|
96
|
-
}
|
|
81
|
+
pointerEventSystem({
|
|
82
|
+
entity: instance.entity,
|
|
83
|
+
opts: {
|
|
84
|
+
button: 0 /* InputAction.IA_POINTER */,
|
|
85
|
+
// We add this showFeedBack so the pointerEventSystem creates a PointerEvent component with our entity
|
|
86
|
+
// This is needed for the renderer to know which entities are clickeables
|
|
87
|
+
showFeedback: true
|
|
88
|
+
}
|
|
89
|
+
}, () => pointerEventCallback(instance.entity, pointerEvent));
|
|
97
90
|
}
|
|
98
91
|
}
|
|
99
92
|
}
|
|
@@ -121,6 +114,15 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
121
114
|
delete props.onChange;
|
|
122
115
|
delete props.onSubmit;
|
|
123
116
|
}
|
|
117
|
+
// Prevent keystroke drops: when React echoes back the same value the renderer
|
|
118
|
+
// reported, strip it from the props so the component isn't marked dirty for it.
|
|
119
|
+
// This avoids sending a stale value that overwrites what the user is currently typing.
|
|
120
|
+
if (componentName === 'uiInput' &&
|
|
121
|
+
'value' in props &&
|
|
122
|
+
lastInputResultValues.has(instance.entity) &&
|
|
123
|
+
props.value === lastInputResultValues.get(instance.entity)) {
|
|
124
|
+
delete props.value;
|
|
125
|
+
}
|
|
124
126
|
// We check if there is any key pending to be changed to avoid updating the existing component
|
|
125
127
|
if (!Object.keys(props).length) {
|
|
126
128
|
return;
|
|
@@ -134,6 +136,8 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
134
136
|
}
|
|
135
137
|
function removeChildEntity(instance) {
|
|
136
138
|
changeEvents.delete(instance.entity);
|
|
139
|
+
clickEvents.delete(instance.entity);
|
|
140
|
+
lastInputResultValues.delete(instance.entity);
|
|
137
141
|
engine.removeEntity(instance.entity);
|
|
138
142
|
for (const child of instance._child) {
|
|
139
143
|
removeChildEntity(child);
|
|
@@ -152,11 +156,15 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
152
156
|
const rightOfChild = parent._child.find((c) => c.rightOf === child.entity);
|
|
153
157
|
if (rightOfChild) {
|
|
154
158
|
rightOfChild.rightOf = child.rightOf;
|
|
155
|
-
// Re-order parent._child array
|
|
156
|
-
parent._child = parent._child.filter((c) => c.entity !== child.entity);
|
|
157
|
-
parent._child.push(child);
|
|
158
159
|
updateTree(rightOfChild, { rightOf: rightOfChild.rightOf });
|
|
159
160
|
}
|
|
161
|
+
// Always remove from old position and push to end for reorders.
|
|
162
|
+
// Previously, filter/push was inside the if(rightOfChild) block, so when
|
|
163
|
+
// rightOfChild was not found (child was last), the child stayed at its old
|
|
164
|
+
// position. This caused _child[length-2] to potentially be the child itself,
|
|
165
|
+
// producing a self-referencing rightOf.
|
|
166
|
+
parent._child = parent._child.filter((c) => c.entity !== child.entity);
|
|
167
|
+
parent._child.push(child);
|
|
160
168
|
// Its a re-order. We are the last element, so we need to fetch the element before us.
|
|
161
169
|
child.rightOf = parent._child[parent._child.length - 2]?.entity;
|
|
162
170
|
}
|
|
@@ -170,13 +178,14 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
170
178
|
}
|
|
171
179
|
function removeChild(parentInstance, child) {
|
|
172
180
|
const childIndex = parentInstance._child.findIndex((c) => c.entity === child.entity);
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
childToModify
|
|
176
|
-
|
|
181
|
+
if (childIndex !== -1) {
|
|
182
|
+
const childToModify = parentInstance._child[childIndex + 1];
|
|
183
|
+
if (childToModify) {
|
|
184
|
+
childToModify.rightOf = child.rightOf;
|
|
185
|
+
updateTree(childToModify, { rightOf: child.rightOf });
|
|
186
|
+
}
|
|
187
|
+
parentInstance._child.splice(childIndex, 1);
|
|
177
188
|
}
|
|
178
|
-
// Mutate 💀
|
|
179
|
-
parentInstance._child.splice(childIndex, 1);
|
|
180
189
|
removeChildEntity(child);
|
|
181
190
|
}
|
|
182
191
|
function updateOnChange(entity, componentId, state) {
|
|
@@ -189,6 +198,9 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
189
198
|
if (!hasEvent) {
|
|
190
199
|
const resultComponentId = componentId === UiDropdown.componentId ? UiDropdownResult.componentId : UiInputResult.componentId;
|
|
191
200
|
engine.getComponent(resultComponentId).onChange(entity, (value) => {
|
|
201
|
+
if (resultComponentId === UiInputResult.componentId) {
|
|
202
|
+
lastInputResultValues.set(entity, value?.value);
|
|
203
|
+
}
|
|
192
204
|
if (value?.isSubmit) {
|
|
193
205
|
const onSubmit = changeEvents.get(entity)?.get(componentId)?.onSubmitCallback;
|
|
194
206
|
onSubmit && onSubmit(value?.value);
|
|
@@ -202,10 +214,6 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
202
214
|
...noopConfig,
|
|
203
215
|
createInstance(type, props) {
|
|
204
216
|
const entity = engine.addEntity();
|
|
205
|
-
// set root
|
|
206
|
-
if (rootEntity !== undefined) {
|
|
207
|
-
Transform.createOrReplace(entity, { parent: rootEntity });
|
|
208
|
-
}
|
|
209
217
|
entities.add(entity);
|
|
210
218
|
const instance = {
|
|
211
219
|
entity,
|
|
@@ -219,13 +227,11 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
219
227
|
continue;
|
|
220
228
|
}
|
|
221
229
|
if (isListener(keyTyped)) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
});
|
|
228
|
-
}
|
|
230
|
+
upsertListener(instance, {
|
|
231
|
+
type: 'add',
|
|
232
|
+
props: props[keyTyped],
|
|
233
|
+
component: keyTyped
|
|
234
|
+
});
|
|
229
235
|
}
|
|
230
236
|
else {
|
|
231
237
|
upsertComponent(instance, props[keyTyped], keyTyped);
|
|
@@ -257,6 +263,23 @@ export function createReconciler(engine, pointerEvents, rootEntity) {
|
|
|
257
263
|
}
|
|
258
264
|
},
|
|
259
265
|
insertBefore(parentInstance, child, beforeChild) {
|
|
266
|
+
// Handle reorder: if child already exists in this parent, remove it from its old position
|
|
267
|
+
// and fix up the old neighbor's rightOf before inserting at the new position.
|
|
268
|
+
const existingIndex = parentInstance._child.findIndex((c) => c.entity === child.entity);
|
|
269
|
+
if (existingIndex !== -1) {
|
|
270
|
+
// If beforeChild.rightOf already points to child, child is already in the correct
|
|
271
|
+
// position in the rightOf chain. Setting child.rightOf = beforeChild.rightOf would
|
|
272
|
+
// produce a self-cycle (child.rightOf = child.entity).
|
|
273
|
+
if (beforeChild.rightOf === child.entity) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const oldNextSibling = parentInstance._child[existingIndex + 1];
|
|
277
|
+
if (oldNextSibling) {
|
|
278
|
+
oldNextSibling.rightOf = child.rightOf;
|
|
279
|
+
updateTree(oldNextSibling, { rightOf: oldNextSibling.rightOf });
|
|
280
|
+
}
|
|
281
|
+
parentInstance._child.splice(existingIndex, 1);
|
|
282
|
+
}
|
|
260
283
|
const beforeChildIndex = parentInstance._child.findIndex((c) => c.entity === beforeChild.entity);
|
|
261
284
|
parentInstance._child = [
|
|
262
285
|
...parentInstance._child.slice(0, beforeChildIndex),
|
package/dist/reconciler/utils.js
CHANGED
|
@@ -35,14 +35,6 @@ const entityComponent = {
|
|
|
35
35
|
onMouseUp: undefined,
|
|
36
36
|
onMouseEnter: undefined,
|
|
37
37
|
onMouseLeave: undefined,
|
|
38
|
-
onMouseDrag: undefined,
|
|
39
|
-
onMouseDragLocked: undefined,
|
|
40
|
-
onMouseDragEnd: undefined,
|
|
41
|
-
onInputDown: undefined,
|
|
42
|
-
onInputUp: undefined,
|
|
43
|
-
onInputDrag: undefined,
|
|
44
|
-
onInputDragLocked: undefined,
|
|
45
|
-
onInputDragEnd: undefined,
|
|
46
38
|
uiInput: undefined,
|
|
47
39
|
uiDropdown: undefined
|
|
48
40
|
};
|
package/dist/system.d.ts
CHANGED
|
@@ -23,11 +23,6 @@ export interface ReactBasedUiSystem {
|
|
|
23
23
|
* Set the main UI renderer. Optional virtual size defines the global UI scale factor.
|
|
24
24
|
*/
|
|
25
25
|
setUiRenderer(ui: UiComponent, options?: UiRendererOptions): void;
|
|
26
|
-
/**
|
|
27
|
-
* Set a texture renderer for a specific entity.
|
|
28
|
-
* @deprecated Use addUiRenderer instead
|
|
29
|
-
*/
|
|
30
|
-
setTextureRenderer(entity: Entity, ui: UiComponent): void;
|
|
31
26
|
/**
|
|
32
27
|
* Add a UI renderer associated with an entity. The UI will be automatically cleaned up
|
|
33
28
|
* when the entity is removed from the engine.
|
package/dist/system.js
CHANGED
|
@@ -7,11 +7,10 @@ import { getUiScaleFactor, resetUiScaleFactor, setUiScaleFactor } from './compon
|
|
|
7
7
|
* @public
|
|
8
8
|
*/
|
|
9
9
|
export function createReactBasedUiSystem(engine, pointerSystem) {
|
|
10
|
-
const renderer = createReconciler(engine, pointerSystem
|
|
10
|
+
const renderer = createReconciler(engine, pointerSystem);
|
|
11
11
|
let uiComponent = undefined;
|
|
12
12
|
let virtualSize = undefined;
|
|
13
13
|
const additionalRenderers = new Map();
|
|
14
|
-
const textureRenderersAndUis = [];
|
|
15
14
|
const UiCanvasInformation = ecsComponents.UiCanvasInformation(engine);
|
|
16
15
|
// Unique owner to prevent other UI systems resetting this scale factor.
|
|
17
16
|
const uiScaleFactorOwner = Symbol('react-ecs-ui-scale');
|
|
@@ -52,10 +51,6 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
|
|
|
52
51
|
else {
|
|
53
52
|
renderer.update(null);
|
|
54
53
|
}
|
|
55
|
-
// Update texture renderers (deprecated, kept for backwards compatibility)
|
|
56
|
-
for (const [textureRenderer, ui] of textureRenderersAndUis) {
|
|
57
|
-
textureRenderer.update(React.createElement(ui));
|
|
58
|
-
}
|
|
59
54
|
}
|
|
60
55
|
function UiScaleSystem() {
|
|
61
56
|
const activeVirtualSize = getActiveVirtualSize();
|
|
@@ -87,19 +82,11 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
|
|
|
87
82
|
for (const entity of renderer.getEntities()) {
|
|
88
83
|
engine.removeEntity(entity);
|
|
89
84
|
}
|
|
90
|
-
for (const [textureRenderer, _] of textureRenderersAndUis) {
|
|
91
|
-
for (const entity of textureRenderer.getEntities()) {
|
|
92
|
-
engine.removeEntity(entity);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
85
|
},
|
|
96
86
|
setUiRenderer(ui, options) {
|
|
97
87
|
uiComponent = ui;
|
|
98
88
|
virtualSize = options;
|
|
99
89
|
},
|
|
100
|
-
setTextureRenderer(entity, ui) {
|
|
101
|
-
textureRenderersAndUis.push([createReconciler(engine, pointerSystem, entity), ui]);
|
|
102
|
-
},
|
|
103
90
|
addUiRenderer(entity, ui, options) {
|
|
104
91
|
additionalRenderers.set(entity, { ui, options });
|
|
105
92
|
},
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl/react-ecs",
|
|
3
3
|
"description": "Decentraland ECS",
|
|
4
|
-
"version": "7.21.1-
|
|
4
|
+
"version": "7.21.1-23203004012.commit-7c64ac2",
|
|
5
5
|
"author": "DCL",
|
|
6
6
|
"bugs": "https://github.com/decentraland/js-sdk-toolchain/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@dcl/ecs": "7.21.1-
|
|
8
|
+
"@dcl/ecs": "7.21.1-23203004012.commit-7c64ac2",
|
|
9
9
|
"react": "^18.2.0",
|
|
10
10
|
"react-reconciler": "^0.29.0"
|
|
11
11
|
},
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"tsconfig": "./tsconfig.json"
|
|
41
41
|
},
|
|
42
42
|
"types": "./dist/index.d.ts",
|
|
43
|
-
"commit": "
|
|
43
|
+
"commit": "7c64ac29ee3f34e79019b4435854537a261721ab"
|
|
44
44
|
}
|