@dcl/react-ecs 7.23.4-26723618219.commit-ea97433 → 7.23.4-26770223094.commit-52b9415
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/ScreenInsetArea/index.d.ts +22 -0
- package/dist/components/ScreenInsetArea/index.js +32 -0
- package/dist/components/ScreenInsetArea/types.d.ts +22 -0
- package/dist/components/ScreenInsetArea/types.js +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +2 -0
- package/dist/components/utils.js +51 -2
- package/dist/system.js +11 -2
- package/package.json +3 -3
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ReactEcs } from '../../react-ecs';
|
|
2
|
+
import { UiScreenInsetAreaProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
* ScreenInsetArea component
|
|
7
|
+
*
|
|
8
|
+
* Constrains its children to the area inside the renderer-reported screen
|
|
9
|
+
* inset (safe margins). On mobile this is the area excluding the notch,
|
|
10
|
+
* status bar, home indicator and rounded corners. On desktop the insets are
|
|
11
|
+
* typically zero, so the container fills the canvas.
|
|
12
|
+
*
|
|
13
|
+
* The container is absolutely positioned with top/left/right/bottom matching
|
|
14
|
+
* the current `UiCanvasInformation.screenInsetArea`, so a child sized
|
|
15
|
+
* 100%x100% fills the safe area exactly.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* <ScreenInsetArea><MyHud /></ScreenInsetArea>
|
|
19
|
+
*
|
|
20
|
+
* @category Component
|
|
21
|
+
*/
|
|
22
|
+
export declare function ScreenInsetArea(props: UiScreenInsetAreaProps): ReactEcs.JSX.Element;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ReactEcs } from '../../react-ecs';
|
|
2
|
+
import { UiEntity } from '../index';
|
|
3
|
+
import { getScreenInsetArea } from '../utils';
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
* ScreenInsetArea component
|
|
8
|
+
*
|
|
9
|
+
* Constrains its children to the area inside the renderer-reported screen
|
|
10
|
+
* inset (safe margins). On mobile this is the area excluding the notch,
|
|
11
|
+
* status bar, home indicator and rounded corners. On desktop the insets are
|
|
12
|
+
* typically zero, so the container fills the canvas.
|
|
13
|
+
*
|
|
14
|
+
* The container is absolutely positioned with top/left/right/bottom matching
|
|
15
|
+
* the current `UiCanvasInformation.screenInsetArea`, so a child sized
|
|
16
|
+
* 100%x100% fills the safe area exactly.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* <ScreenInsetArea><MyHud /></ScreenInsetArea>
|
|
20
|
+
*
|
|
21
|
+
* @category Component
|
|
22
|
+
*/
|
|
23
|
+
/* @__PURE__ */
|
|
24
|
+
export function ScreenInsetArea(props) {
|
|
25
|
+
const { top, left, right, bottom } = getScreenInsetArea();
|
|
26
|
+
const { uiTransform, ...otherProps } = props;
|
|
27
|
+
return (ReactEcs.createElement(UiEntity, { ...otherProps, uiTransform: {
|
|
28
|
+
...uiTransform,
|
|
29
|
+
positionType: 'absolute',
|
|
30
|
+
position: { top, left, right, bottom }
|
|
31
|
+
} }));
|
|
32
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { EntityPropTypes } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* ScreenInsetArea component props
|
|
4
|
+
*
|
|
5
|
+
* The container reads the current `screenInsetArea` reported by the renderer
|
|
6
|
+
* via `UiCanvasInformation` (the device safe margins — notch, status bar,
|
|
7
|
+
* home indicator, rounded corners) and constrains its children to the area
|
|
8
|
+
* inside those insets using absolute positioning. Layout props that control
|
|
9
|
+
* the container's own position (`positionType`, `position`) are owned by the
|
|
10
|
+
* component and are not configurable from props — every other layout,
|
|
11
|
+
* background and event prop is forwarded as usual.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export type UiScreenInsetAreaProps = Omit<EntityPropTypes, 'uiTransform'> & {
|
|
16
|
+
/**
|
|
17
|
+
* Layout overrides forwarded to the underlying entity. The
|
|
18
|
+
* `positionType` and `position` fields are reserved by the container and
|
|
19
|
+
* any value provided here is ignored.
|
|
20
|
+
*/
|
|
21
|
+
uiTransform?: Omit<NonNullable<EntityPropTypes['uiTransform']>, 'positionType' | 'position'>;
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -9,10 +9,12 @@ export * from './uiBackground/types';
|
|
|
9
9
|
export * from './Dropdown/types';
|
|
10
10
|
export * from './Label/types';
|
|
11
11
|
export * from './Button/types';
|
|
12
|
+
export * from './ScreenInsetArea/types';
|
|
12
13
|
export { Dropdown } from './Dropdown';
|
|
13
14
|
export { Input } from './Input';
|
|
14
15
|
export { Label, scaleFontSize } from './Label';
|
|
15
16
|
export { Button } from './Button';
|
|
17
|
+
export { ScreenInsetArea } from './ScreenInsetArea';
|
|
16
18
|
/**
|
|
17
19
|
* @public
|
|
18
20
|
* @category Component
|
package/dist/components/index.js
CHANGED
|
@@ -9,10 +9,12 @@ export * from './uiBackground/types';
|
|
|
9
9
|
export * from './Dropdown/types';
|
|
10
10
|
export * from './Label/types';
|
|
11
11
|
export * from './Button/types';
|
|
12
|
+
export * from './ScreenInsetArea/types';
|
|
12
13
|
export { Dropdown } from './Dropdown';
|
|
13
14
|
export { Input } from './Input';
|
|
14
15
|
export { Label, scaleFontSize } from './Label';
|
|
15
16
|
export { Button } from './Button';
|
|
17
|
+
export { ScreenInsetArea } from './ScreenInsetArea';
|
|
16
18
|
/**
|
|
17
19
|
* @public
|
|
18
20
|
* @category Component
|
package/dist/components/utils.js
CHANGED
|
@@ -3,6 +3,9 @@ import { parseUiBackground } from './uiBackground';
|
|
|
3
3
|
import { parseUiTransform } from './uiTransform';
|
|
4
4
|
let uiScaleFactor = 1;
|
|
5
5
|
let uiScaleOwner = undefined;
|
|
6
|
+
const ZERO_INSETS = { top: 0, left: 0, right: 0, bottom: 0 };
|
|
7
|
+
let screenInsetArea = { ...ZERO_INSETS };
|
|
8
|
+
let screenInsetAreaOwner = undefined;
|
|
6
9
|
/**
|
|
7
10
|
* @internal
|
|
8
11
|
*/
|
|
@@ -54,13 +57,22 @@ export function getUiScaleFactor() {
|
|
|
54
57
|
return uiScaleFactor;
|
|
55
58
|
}
|
|
56
59
|
/**
|
|
60
|
+
* Sets the global UI scale factor.
|
|
61
|
+
*
|
|
62
|
+
* The `owner` symbol implements a cooperative reset-protection scheme shared
|
|
63
|
+
* with {@link resetUiScaleFactor}:
|
|
64
|
+
* - Writes always succeed — last writer claims ownership (the most recent
|
|
65
|
+
* `owner` passed to `set` is the one allowed to `reset`).
|
|
66
|
+
* - Resets from a non-matching owner are ignored, so a stale system can't
|
|
67
|
+
* stomp the active scale while another system is driving it.
|
|
68
|
+
* - A reset called without an owner always wins (used by tests / teardown).
|
|
69
|
+
*
|
|
57
70
|
* @internal
|
|
58
71
|
*/
|
|
59
72
|
export function setUiScaleFactor(nextScale, owner) {
|
|
60
73
|
if (!Number.isFinite(nextScale) || nextScale < 0)
|
|
61
74
|
return;
|
|
62
75
|
if (owner) {
|
|
63
|
-
// Mark ownership so only that system can reset the scale.
|
|
64
76
|
uiScaleOwner = owner;
|
|
65
77
|
}
|
|
66
78
|
uiScaleFactor = nextScale;
|
|
@@ -69,12 +81,49 @@ export function setUiScaleFactor(nextScale, owner) {
|
|
|
69
81
|
* @internal
|
|
70
82
|
*/
|
|
71
83
|
export function resetUiScaleFactor(owner) {
|
|
72
|
-
//
|
|
84
|
+
// No-op for non-owners (see ownership rules on `setUiScaleFactor`).
|
|
85
|
+
// A reset with no owner always wins — used by tests and teardown.
|
|
73
86
|
if (owner && uiScaleOwner !== owner)
|
|
74
87
|
return;
|
|
75
88
|
uiScaleOwner = undefined;
|
|
76
89
|
uiScaleFactor = 1;
|
|
77
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
export function getScreenInsetArea() {
|
|
95
|
+
return { ...screenInsetArea };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Sets the global screen inset area.
|
|
99
|
+
*
|
|
100
|
+
* The `owner` symbol implements a cooperative reset-protection scheme shared
|
|
101
|
+
* with {@link resetScreenInsetArea}:
|
|
102
|
+
* - Writes always succeed — last writer claims ownership (the most recent
|
|
103
|
+
* `owner` passed to `set` is the one allowed to `reset`).
|
|
104
|
+
* - Resets from a non-matching owner are ignored, so a stale system can't
|
|
105
|
+
* stomp the active insets while another system is driving them.
|
|
106
|
+
* - A reset called without an owner always wins (used by tests / teardown).
|
|
107
|
+
*
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
export function setScreenInsetArea(next, owner) {
|
|
111
|
+
if (owner) {
|
|
112
|
+
screenInsetAreaOwner = owner;
|
|
113
|
+
}
|
|
114
|
+
screenInsetArea = { top: next.top, left: next.left, right: next.right, bottom: next.bottom };
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* @internal
|
|
118
|
+
*/
|
|
119
|
+
export function resetScreenInsetArea(owner) {
|
|
120
|
+
// No-op for non-owners (see ownership rules on `setScreenInsetArea`).
|
|
121
|
+
// A reset with no owner always wins — used by tests and teardown.
|
|
122
|
+
if (owner && screenInsetAreaOwner !== owner)
|
|
123
|
+
return;
|
|
124
|
+
screenInsetAreaOwner = undefined;
|
|
125
|
+
screenInsetArea = { ...ZERO_INSETS };
|
|
126
|
+
}
|
|
78
127
|
/**
|
|
79
128
|
* @internal
|
|
80
129
|
*/
|
package/dist/system.js
CHANGED
|
@@ -2,7 +2,7 @@ import { EntityState } from '@dcl/ecs';
|
|
|
2
2
|
import * as ecsComponents from '@dcl/ecs/dist/components';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { createReconciler } from './reconciler';
|
|
5
|
-
import { getUiScaleFactor, resetUiScaleFactor, setUiScaleFactor } from './components/utils';
|
|
5
|
+
import { getUiScaleFactor, resetScreenInsetArea, resetUiScaleFactor, setScreenInsetArea, setUiScaleFactor } from './components/utils';
|
|
6
6
|
/**
|
|
7
7
|
* @public
|
|
8
8
|
*/
|
|
@@ -14,6 +14,8 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
|
|
|
14
14
|
const UiCanvasInformation = ecsComponents.UiCanvasInformation(engine);
|
|
15
15
|
// Unique owner to prevent other UI systems resetting this scale factor.
|
|
16
16
|
const uiScaleFactorOwner = Symbol('react-ecs-ui-scale');
|
|
17
|
+
// Unique owner for the screen inset module variable.
|
|
18
|
+
const screenInsetAreaOwner = Symbol('react-ecs-screen-inset-area');
|
|
17
19
|
function getActiveVirtualSize() {
|
|
18
20
|
// Main renderer options win; otherwise use the first additional renderer option.
|
|
19
21
|
if (virtualSize)
|
|
@@ -53,13 +55,19 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
|
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
function UiScaleSystem() {
|
|
58
|
+
const canvasInfo = UiCanvasInformation.getOrNull(engine.RootEntity);
|
|
59
|
+
// Update the screen inset module variable unconditionally — it is
|
|
60
|
+
// independent of the virtual size and useful even when the renderer has no
|
|
61
|
+
// virtual canvas.
|
|
62
|
+
if (canvasInfo?.screenInsetArea) {
|
|
63
|
+
setScreenInsetArea(canvasInfo.screenInsetArea, screenInsetAreaOwner);
|
|
64
|
+
}
|
|
56
65
|
const activeVirtualSize = getActiveVirtualSize();
|
|
57
66
|
if (!activeVirtualSize) {
|
|
58
67
|
// Reset only if this system owns the scale factor.
|
|
59
68
|
resetUiScaleFactor(uiScaleFactorOwner);
|
|
60
69
|
return;
|
|
61
70
|
}
|
|
62
|
-
const canvasInfo = UiCanvasInformation.getOrNull(engine.RootEntity);
|
|
63
71
|
if (!canvasInfo)
|
|
64
72
|
return;
|
|
65
73
|
const { width, height } = canvasInfo;
|
|
@@ -79,6 +87,7 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
|
|
|
79
87
|
engine.removeSystem(UiScaleSystem);
|
|
80
88
|
engine.removeSystem(ReactBasedUiSystem);
|
|
81
89
|
resetUiScaleFactor(uiScaleFactorOwner);
|
|
90
|
+
resetScreenInsetArea(screenInsetAreaOwner);
|
|
82
91
|
for (const entity of renderer.getEntities()) {
|
|
83
92
|
engine.removeEntity(entity);
|
|
84
93
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl/react-ecs",
|
|
3
3
|
"description": "Decentraland ECS",
|
|
4
|
-
"version": "7.23.4-
|
|
4
|
+
"version": "7.23.4-26770223094.commit-52b9415",
|
|
5
5
|
"author": "DCL",
|
|
6
6
|
"bugs": "https://github.com/decentraland/js-sdk-toolchain/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@dcl/ecs": "7.23.4-
|
|
8
|
+
"@dcl/ecs": "7.23.4-26770223094.commit-52b9415",
|
|
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": "52b9415ebab8c77313e9fbc0725fd2e5f916d3c3"
|
|
44
44
|
}
|