@dcl/react-ecs 7.24.4-28592331167.commit-697ce9e → 7.24.4-28656241733.commit-c65544e

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.
@@ -0,0 +1,23 @@
1
+ import { ReactEcs } from '../../react-ecs';
2
+ import { UiInteractableAreaProps } from './types';
3
+ /**
4
+ *
5
+ * @public
6
+ * InteractableArea component
7
+ *
8
+ * Constrains its children to the area inside the renderer-reported interactable
9
+ * area. This is the portion of the screen not covered by client UI such as the
10
+ * minimap, chat window, or other platform overlays. On the Unity desktop client
11
+ * the left 25% of the screen is reserved for client UI, so this container
12
+ * positions its children within the remaining 75%.
13
+ *
14
+ * The container is absolutely positioned with top/left/right/bottom matching
15
+ * the current `UiCanvasInformation.interactableArea`, so a child sized
16
+ * 100%x100% fills the interactable area exactly.
17
+ *
18
+ * @example
19
+ * <InteractableArea><MyHud /></InteractableArea>
20
+ *
21
+ * @category Component
22
+ */
23
+ export declare function InteractableArea(props: UiInteractableAreaProps): ReactEcs.JSX.Element;
@@ -0,0 +1,33 @@
1
+ import { ReactEcs } from '../../react-ecs';
2
+ import { UiEntity } from '../index';
3
+ import { getInteractableArea } from '../utils';
4
+ /**
5
+ *
6
+ * @public
7
+ * InteractableArea component
8
+ *
9
+ * Constrains its children to the area inside the renderer-reported interactable
10
+ * area. This is the portion of the screen not covered by client UI such as the
11
+ * minimap, chat window, or other platform overlays. On the Unity desktop client
12
+ * the left 25% of the screen is reserved for client UI, so this container
13
+ * positions its children within the remaining 75%.
14
+ *
15
+ * The container is absolutely positioned with top/left/right/bottom matching
16
+ * the current `UiCanvasInformation.interactableArea`, so a child sized
17
+ * 100%x100% fills the interactable area exactly.
18
+ *
19
+ * @example
20
+ * <InteractableArea><MyHud /></InteractableArea>
21
+ *
22
+ * @category Component
23
+ */
24
+ /* @__PURE__ */
25
+ export function InteractableArea(props) {
26
+ const { top, left, right, bottom } = getInteractableArea();
27
+ const { uiTransform, ...otherProps } = props;
28
+ return (ReactEcs.createElement(UiEntity, { ...otherProps, uiTransform: {
29
+ ...uiTransform,
30
+ positionType: 'absolute',
31
+ position: { top, left, right, bottom }
32
+ } }));
33
+ }
@@ -0,0 +1,23 @@
1
+ import { EntityPropTypes } from '../types';
2
+ /**
3
+ * InteractableArea component props
4
+ *
5
+ * The container reads the current `interactableArea` reported by the renderer
6
+ * via `UiCanvasInformation` (the HUD-safe zone — the portion of the screen not
7
+ * covered by client UI such as the minimap, chat window, or other overlays) and
8
+ * constrains its children to the area inside those insets using absolute
9
+ * positioning. Layout props that control the container's own position
10
+ * (`positionType`, `position`) are owned by the component and are not
11
+ * configurable from props — every other layout, background and event prop is
12
+ * forwarded as usual.
13
+ *
14
+ * @public
15
+ */
16
+ export type UiInteractableAreaProps = Omit<EntityPropTypes, 'uiTransform'> & {
17
+ /**
18
+ * Layout overrides forwarded to the underlying entity. The
19
+ * `positionType` and `position` fields are reserved by the container and
20
+ * any value provided here is ignored.
21
+ */
22
+ uiTransform?: Omit<NonNullable<EntityPropTypes['uiTransform']>, 'positionType' | 'position'>;
23
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -10,11 +10,13 @@ export * from './Dropdown/types';
10
10
  export * from './Label/types';
11
11
  export * from './Button/types';
12
12
  export * from './ScreenInsetArea/types';
13
+ export * from './InteractableArea/types';
13
14
  export { Dropdown } from './Dropdown';
14
15
  export { Input } from './Input';
15
16
  export { Label, scaleFontSize } from './Label';
16
17
  export { Button } from './Button';
17
18
  export { ScreenInsetArea } from './ScreenInsetArea';
19
+ export { InteractableArea } from './InteractableArea';
18
20
  /**
19
21
  * @public
20
22
  * @category Component
@@ -10,11 +10,13 @@ export * from './Dropdown/types';
10
10
  export * from './Label/types';
11
11
  export * from './Button/types';
12
12
  export * from './ScreenInsetArea/types';
13
+ export * from './InteractableArea/types';
13
14
  export { Dropdown } from './Dropdown';
14
15
  export { Input } from './Input';
15
16
  export { Label, scaleFontSize } from './Label';
16
17
  export { Button } from './Button';
17
18
  export { ScreenInsetArea } from './ScreenInsetArea';
19
+ export { InteractableArea } from './InteractableArea';
18
20
  /**
19
21
  * @public
20
22
  * @category Component
@@ -6,6 +6,8 @@ let uiScaleOwner = undefined;
6
6
  const ZERO_INSETS = { top: 0, left: 0, right: 0, bottom: 0 };
7
7
  let screenInsetArea = { ...ZERO_INSETS };
8
8
  let screenInsetAreaOwner = undefined;
9
+ let interactableArea = { ...ZERO_INSETS };
10
+ let interactableAreaOwner = undefined;
9
11
  /**
10
12
  * @internal
11
13
  */
@@ -124,6 +126,42 @@ export function resetScreenInsetArea(owner) {
124
126
  screenInsetAreaOwner = undefined;
125
127
  screenInsetArea = { ...ZERO_INSETS };
126
128
  }
129
+ /**
130
+ * @internal
131
+ */
132
+ export function getInteractableArea() {
133
+ return { ...interactableArea };
134
+ }
135
+ /**
136
+ * Sets the global interactable area.
137
+ *
138
+ * The `owner` symbol implements a cooperative reset-protection scheme shared
139
+ * with {@link resetInteractableArea}:
140
+ * - Writes always succeed — last writer claims ownership (the most recent
141
+ * `owner` passed to `set` is the one allowed to `reset`).
142
+ * - Resets from a non-matching owner are ignored, so a stale system can't
143
+ * stomp the active area while another system is driving it.
144
+ * - A reset called without an owner always wins (used by tests / teardown).
145
+ *
146
+ * @internal
147
+ */
148
+ export function setInteractableArea(next, owner) {
149
+ if (owner) {
150
+ interactableAreaOwner = owner;
151
+ }
152
+ interactableArea = { top: next.top, left: next.left, right: next.right, bottom: next.bottom };
153
+ }
154
+ /**
155
+ * @internal
156
+ */
157
+ export function resetInteractableArea(owner) {
158
+ // No-op for non-owners (see ownership rules on `setInteractableArea`).
159
+ // A reset with no owner always wins — used by tests and teardown.
160
+ if (owner && interactableAreaOwner !== owner)
161
+ return;
162
+ interactableAreaOwner = undefined;
163
+ interactableArea = { ...ZERO_INSETS };
164
+ }
127
165
  /**
128
166
  * @internal
129
167
  */
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, resetScreenInsetArea, resetUiScaleFactor, setScreenInsetArea, setUiScaleFactor } from './components/utils';
5
+ import { getUiScaleFactor, resetInteractableArea, resetScreenInsetArea, resetUiScaleFactor, setInteractableArea, setScreenInsetArea, setUiScaleFactor } from './components/utils';
6
6
  /**
7
7
  * @public
8
8
  */
@@ -16,6 +16,8 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
16
16
  const uiScaleFactorOwner = Symbol('react-ecs-ui-scale');
17
17
  // Unique owner for the screen inset module variable.
18
18
  const screenInsetAreaOwner = Symbol('react-ecs-screen-inset-area');
19
+ // Unique owner for the interactable area module variable.
20
+ const interactableAreaOwner = Symbol('react-ecs-interactable-area');
19
21
  function getActiveVirtualSize() {
20
22
  // Main renderer options win; otherwise use the first additional renderer option.
21
23
  if (virtualSize)
@@ -62,6 +64,10 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
62
64
  if (canvasInfo?.screenInsetArea) {
63
65
  setScreenInsetArea(canvasInfo.screenInsetArea, screenInsetAreaOwner);
64
66
  }
67
+ // Update the interactable area module variable unconditionally.
68
+ if (canvasInfo?.interactableArea) {
69
+ setInteractableArea(canvasInfo.interactableArea, interactableAreaOwner);
70
+ }
65
71
  const activeVirtualSize = getActiveVirtualSize();
66
72
  if (!activeVirtualSize) {
67
73
  // Reset only if this system owns the scale factor.
@@ -91,6 +97,7 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
91
97
  engine.removeSystem(ReactBasedUiSystem);
92
98
  resetUiScaleFactor(uiScaleFactorOwner);
93
99
  resetScreenInsetArea(screenInsetAreaOwner);
100
+ resetInteractableArea(interactableAreaOwner);
94
101
  for (const entity of renderer.getEntities()) {
95
102
  engine.removeEntity(entity);
96
103
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@dcl/react-ecs",
3
3
  "description": "Decentraland ECS",
4
- "version": "7.24.4-28592331167.commit-697ce9e",
4
+ "version": "7.24.4-28656241733.commit-c65544e",
5
5
  "author": "DCL",
6
6
  "bugs": "https://github.com/decentraland/js-sdk-toolchain/issues",
7
7
  "dependencies": {
8
- "@dcl/ecs": "7.24.4-28592331167.commit-697ce9e",
8
+ "@dcl/ecs": "7.24.4-28656241733.commit-c65544e",
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": "697ce9e4c717549d30c0a0bc927a173df5d0febf"
43
+ "commit": "c65544e970e6bc383df8954be6ef562616ef892b"
44
44
  }