@realitycollective/xrblocks-uiextensions 0.1.0-preview.1 → 0.1.0-preview.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/CHANGELOG.md +9 -0
- package/README.md +22 -1
- package/dist/host.d.ts +38 -21
- package/dist/host.js +32 -10
- package/dist/host.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,11 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
|
14
14
|
- `@realitycollective/uix-devtools` - dev-only tooling: edit-session launch gate, runtime UIKitML compilation, and the `uix-dev` CLI (Cloudflare quick tunnel, QR onboarding, environment doctor).
|
|
15
15
|
- Demo clients: the IWSDK showcase, the devtools playground, and the multiplatform lab that picks its pipeline from the hardware.
|
|
16
16
|
- `uixComponentSet`, exported from `@realitycollective/iwsdk-uiextensions`. Pass it to `spatialUI.componentSets` so the IWSDK 0.5 parser accepts the `<uix-*>` control elements. Without it a panel using any control fails to parse and never attaches. No equivalent is needed on the three.js or XR Blocks adapters.
|
|
17
|
+
- `WindowHandle` and `WindowOptionsBase` in `@realitycollective/webxr-uiextensions`. `WindowHandle` is what every adapter's `createWindow` hands back: an `id`, a `panel` that is `undefined` until the adapter has attached the document, and `onReady(listener)`, which runs once and fires immediately if the panel is already there. `WindowOptionsBase` holds the options every adapter understands, and both adapters' option types now extend it, so an option name means the same thing on each. `createWindow` itself stays adapter-specific, because the `config` payload differs per engine.
|
|
18
|
+
- `WindowHost.supportsStandalonePanels`. It says whether `createPanel` works on a host, rather than leaving callers to find out by catching. `false` on the IWSDK host, where the ECS owns panel lifecycles and `createPanel` throws; `true` on the three.js / XR Blocks host.
|
|
19
|
+
- `PanelReadyEvent.kind`, either `window` or `panel`. `window` means the panel came from the adapter's window factory and is managed by the window manager. `panel` means a bare panel the adapter noticed, whose `id` is then the adapter's best stable identifier for it - the config path on IWSDK. The field is optional, so existing listeners keep compiling.
|
|
20
|
+
- `createWindow` on the IWSDK scene host, returning an `IwsdkWindowHandle`: a `WindowHandle` plus the ECS `entity`. It spawns through `createUIWindow`, names the window `uix-window-<n>` when no id is given, and resolves `panel` and `onReady` once the document attaches, so wiring one window needs neither an ECS query nor a filtered `onPanelReady`. `createUIWindow` is unchanged and still returns the entity.
|
|
21
|
+
- `getPanelHandle(entity)` in `@realitycollective/iwsdk-uiextensions`: the panel handle for an entity you already hold, or `undefined` while IWSDK is still loading its document.
|
|
17
22
|
|
|
18
23
|
### Changed
|
|
19
24
|
|
|
@@ -25,5 +30,9 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
|
25
30
|
- Example and demo markup uses `rgba()` or eight-digit hex rather than `background-opacity`, which the 0.5 parser removed. Both parsers accept the replacement, so one stylesheet serves every adapter.
|
|
26
31
|
- The IWSDK component kit is selected by name, `spatialUI: { kit: 'horizon' }`, rather than by passing an imported kit module. The kits now live inside the parser.
|
|
27
32
|
- `@types/three` is pinned to `0.184.0` across the workspace. IWSDK 0.5.3 and xrblocks resolved different copies, and two copies of the three typings make structurally identical `Object3D` types mutually unassignable, which surfaces as spurious errors far from their cause.
|
|
33
|
+
- `onPanelReady` on the IWSDK host announces bare panels as well as managed windows. A `PanelUI` entity with no `UIWindow`, or with an empty `windowId`, used to be dropped silently; it is now announced with `kind: 'panel'` and its config path as the id. Listeners that only want managed windows should check `kind`.
|
|
34
|
+
- `id` is optional in the XR Blocks host's `CreateWindowOptions`; a window created without one is named `uix-window-<n>`, as on IWSDK. The options also accept `movable` for parity, but this host has no title-bar drag of its own yet, so the flag is recorded and not acted on.
|
|
35
|
+
- The XR Blocks window handle gains `panel` - the document, which already implements `PanelHandle` - and `onReady`, which fires synchronously because uikitml interprets the markup during `createWindow`. The interface is now named `XrBlocksWindowHandle`, with `WindowHandle` kept as an alias, because the core exports a `WindowHandle` of its own.
|
|
36
|
+
- Coverage gates `packages/iwsdk-uiextensions/src/factory.ts` and `src/scene-host.ts` at the same 100% as the core. `new World()` from `@iwsdk/core` constructs headlessly - no renderer, no WebGL, no XR session - so the factories, the scene host and its ECS query all run for real in a node test. The per-frame ECS systems still need a live world and stay outside the gate.
|
|
28
37
|
|
|
29
38
|
[0.1.0]: https://github.com/realitycollective/WebXR-UIExtensions/commits/main
|
package/README.md
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
| Desktop mouse input (hover, click, drag-to-look) | ✅ | ✅ via `@pmndrs/pointer-events` |
|
|
18
18
|
| Desktop locomotion (WASD, jump, crouch, sprint) | n/a | ✅ `DesktopControls` |
|
|
19
19
|
| XR select-ray click forwarding | ✅ | ✅ minimal (`forwardClick`) |
|
|
20
|
-
|
|
|
20
|
+
| Bare panels (`createPanel`) | ⬜ ECS owns the lifecycle | ✅ `supportsStandalonePanels` is `true` |
|
|
21
|
+
| Title-bar ray drag (`@pmndrs/handle`) | ✅ | ⬜ roadmap (`movable` is accepted and ignored) |
|
|
21
22
|
| Drop-to-dock by dragging | ✅ | ⬜ roadmap (needs drag) |
|
|
22
23
|
| System keyboard text input | ✅ | ⬜ untested on Android XR |
|
|
23
24
|
|
|
@@ -72,6 +73,26 @@ await xb.init();
|
|
|
72
73
|
|
|
73
74
|
Nothing here imports `xrblocks` - the glue binds to plain three.js shapes (`scene: Object3D`, `camera`), so the same host works in a hand-rolled three.js WebXR app.
|
|
74
75
|
|
|
76
|
+
### Window options and handles
|
|
77
|
+
|
|
78
|
+
`createWindow` takes the portable `WindowOptionsBase` fields plus `config`, so an option means here what it means on the IWSDK adapter. Two notes specific to this host:
|
|
79
|
+
|
|
80
|
+
- `id` is optional. Omit it and the window is named `uix-window-<n>`.
|
|
81
|
+
- `movable` is accepted and recorded, but nothing acts on it yet: this host has no title-bar drag of its own, so there is no gate to close. It is in the options so a scene descriptor written for IWSDK loads here unchanged.
|
|
82
|
+
|
|
83
|
+
The handle it returns satisfies the core `WindowHandle` and adds the three.js specifics:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
const handle = host.createWindow({ title: 'Status', config });
|
|
87
|
+
handle.id; // 'uix-window-1'
|
|
88
|
+
handle.group; // the scene-graph node - position and rotate freely
|
|
89
|
+
handle.document; // the UixPanelDocument
|
|
90
|
+
handle.panel; // the same document, under the portable name
|
|
91
|
+
handle.onReady((panel) => wire(panel)); // fires straight away here
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`onReady` fires synchronously because uikitml interprets the markup during `createWindow`; only LAYOUT is async. It still returns an unsubscribe function, so code that runs on both adapters has one shape. `supportsStandalonePanels` is `true`: `createPanel(config)` gives an unmanaged panel with no chrome and no window record.
|
|
95
|
+
|
|
75
96
|
## Known constraint: three versions
|
|
76
97
|
|
|
77
98
|
`xrblocks@0.19` declares a peer of `three@^0.184`, while IWSDK mandates the `super-three@0.181` fork used workspace-wide. Vite resolves a single `three` per bundle so the pairing works in practice, but npm's peer check cannot express it - this workspace uses `legacy-peer-deps` (see the root `.npmrc`). Revisit when IWSDK's three catches up.
|
package/dist/host.d.ts
CHANGED
|
@@ -13,25 +13,22 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { Group, type Object3D } from 'three';
|
|
15
15
|
import { type Kit } from '@pmndrs/uikitml';
|
|
16
|
-
import { RegionRegistry, WindowManager, type
|
|
16
|
+
import { RegionRegistry, WindowManager, type HeadPoseSource, type PanelHandle, type PanelReadyEvent, type RegionDefinition, type SceneRegion, type SceneTarget, type SceneWindow, type Vec3Tuple, type WindowHandle as CoreWindowHandle, type WindowHost, type WindowOptionsBase } from '@realitycollective/webxr-uiextensions';
|
|
17
17
|
import { UixPanelDocument } from './panel-document.js';
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Options for {@link UixWindowHost.createWindow}.
|
|
20
|
+
*
|
|
21
|
+
* Everything but `config` comes from the portable {@link WindowOptionsBase},
|
|
22
|
+
* so an option means the same thing here as on the IWSDK adapter. `id` is
|
|
23
|
+
* optional: leave it out and the host names the window `uix-window-<n>`.
|
|
24
|
+
*
|
|
25
|
+
* One option is accepted but not acted on: `movable`. This host has no
|
|
26
|
+
* title-bar drag of its own yet - dragging comes from the XR Blocks / desktop
|
|
27
|
+
* input layer above it - so the flag is recorded and otherwise ignored.
|
|
28
|
+
*/
|
|
29
|
+
export interface CreateWindowOptions extends WindowOptionsBase {
|
|
20
30
|
/** Compiled UIKitML JSON (the `{ element, classes }` shape). */
|
|
21
31
|
config: unknown;
|
|
22
|
-
title?: string;
|
|
23
|
-
dockMode?: DockModeValue;
|
|
24
|
-
position?: Vec3Tuple;
|
|
25
|
-
maxWidth?: number;
|
|
26
|
-
maxHeight?: number;
|
|
27
|
-
closable?: boolean;
|
|
28
|
-
minimizable?: boolean;
|
|
29
|
-
pinnable?: boolean;
|
|
30
|
-
followOffset?: Vec3Tuple;
|
|
31
|
-
followSpeed?: number;
|
|
32
|
-
followTolerance?: number;
|
|
33
|
-
/** Dock straight into this region on spawn. */
|
|
34
|
-
region?: string;
|
|
35
32
|
}
|
|
36
33
|
export interface CreateRegionOptions extends Partial<RegionDefinition> {
|
|
37
34
|
id: string;
|
|
@@ -40,12 +37,25 @@ export interface CreateRegionOptions extends Partial<RegionDefinition> {
|
|
|
40
37
|
follow?: boolean;
|
|
41
38
|
followOffset?: Vec3Tuple;
|
|
42
39
|
}
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
/**
|
|
41
|
+
* A window spawned by {@link UixWindowHost.createWindow}.
|
|
42
|
+
*
|
|
43
|
+
* Satisfies the core {@link CoreWindowHandle} and adds the three.js specifics.
|
|
44
|
+
* `panel` is the document itself, which already implements `PanelHandle`, and
|
|
45
|
+
* is never `undefined` here: uikitml interprets the markup synchronously, so
|
|
46
|
+
* the panel exists the moment `createWindow` returns.
|
|
47
|
+
*/
|
|
48
|
+
export interface XrBlocksWindowHandle extends CoreWindowHandle {
|
|
49
|
+
readonly id: string;
|
|
45
50
|
/** The scene-graph node - position/rotate freely. */
|
|
46
51
|
group: Group;
|
|
47
52
|
document: UixPanelDocument;
|
|
53
|
+
/** Same object as {@link document}, under the portable name. */
|
|
54
|
+
readonly panel: UixPanelDocument;
|
|
55
|
+
onReady(listener: (panel: PanelHandle) => void): () => void;
|
|
48
56
|
}
|
|
57
|
+
/** Back-compatible name for {@link XrBlocksWindowHandle}. */
|
|
58
|
+
export type WindowHandle = XrBlocksWindowHandle;
|
|
49
59
|
export interface RegionHandle {
|
|
50
60
|
id: string;
|
|
51
61
|
group: Group;
|
|
@@ -69,6 +79,8 @@ export interface UixWindowHostOptions {
|
|
|
69
79
|
loadConfig?: (path: string) => Promise<unknown>;
|
|
70
80
|
}
|
|
71
81
|
export declare class UixWindowHost implements WindowHost, SceneTarget {
|
|
82
|
+
/** Bare panels work here - the host does not own a panel lifecycle. */
|
|
83
|
+
readonly supportsStandalonePanels: boolean;
|
|
72
84
|
readonly manager: WindowManager;
|
|
73
85
|
readonly regions: RegionRegistry;
|
|
74
86
|
private readonly scene;
|
|
@@ -80,8 +92,13 @@ export declare class UixWindowHost implements WindowHost, SceneTarget {
|
|
|
80
92
|
private readonly readyListeners;
|
|
81
93
|
/** Panels already live - replayed to late `onPanelReady` subscribers. */
|
|
82
94
|
private readonly ready;
|
|
95
|
+
/** Feeds `uix-window-<n>` ids to windows created without one. */
|
|
96
|
+
private windowSequence;
|
|
83
97
|
constructor(options: UixWindowHostOptions);
|
|
84
|
-
/**
|
|
98
|
+
/**
|
|
99
|
+
* PanelHost - bare panel, unmanaged (used by devtools and tests). Always
|
|
100
|
+
* available here, which is what `supportsStandalonePanels` reports.
|
|
101
|
+
*/
|
|
85
102
|
createPanel(configJson: unknown): UixPanelDocument;
|
|
86
103
|
/**
|
|
87
104
|
* Observe panel readiness. Windows already live are replayed immediately,
|
|
@@ -101,8 +118,8 @@ export declare class UixWindowHost implements WindowHost, SceneTarget {
|
|
|
101
118
|
/** Dock a window into a region (or undock it with `undefined`). */
|
|
102
119
|
dock(windowId: string, regionId: string | undefined): void;
|
|
103
120
|
/** Spawn a managed window from compiled UIKitML JSON. */
|
|
104
|
-
createWindow(options: CreateWindowOptions):
|
|
105
|
-
window(id: string):
|
|
121
|
+
createWindow(options: CreateWindowOptions): XrBlocksWindowHandle;
|
|
122
|
+
window(id: string): XrBlocksWindowHandle | undefined;
|
|
106
123
|
/** Drive per-frame from the engine loop (delta in SECONDS). */
|
|
107
124
|
update(deltaSeconds: number): void;
|
|
108
125
|
private applyFollow;
|
package/dist/host.js
CHANGED
|
@@ -33,6 +33,8 @@ import { UixPanelDocument } from './panel-document.js';
|
|
|
33
33
|
const DEFAULT_FOLLOW_OFFSET = [0, -0.15, -1.2];
|
|
34
34
|
const DEFAULT_REGION_FOLLOW_OFFSET = [0, -0.2, -1.4];
|
|
35
35
|
export class UixWindowHost {
|
|
36
|
+
/** Bare panels work here - the host does not own a panel lifecycle. */
|
|
37
|
+
supportsStandalonePanels = true;
|
|
36
38
|
manager = new WindowManager();
|
|
37
39
|
regions = new RegionRegistry();
|
|
38
40
|
scene;
|
|
@@ -44,6 +46,8 @@ export class UixWindowHost {
|
|
|
44
46
|
readyListeners = new Set();
|
|
45
47
|
/** Panels already live - replayed to late `onPanelReady` subscribers. */
|
|
46
48
|
ready = new Map();
|
|
49
|
+
/** Feeds `uix-window-<n>` ids to windows created without one. */
|
|
50
|
+
windowSequence = 0;
|
|
47
51
|
constructor(options) {
|
|
48
52
|
this.scene = options.scene;
|
|
49
53
|
this.headPose = options.headPose;
|
|
@@ -73,7 +77,10 @@ export class UixWindowHost {
|
|
|
73
77
|
});
|
|
74
78
|
}
|
|
75
79
|
// --- WindowHost -----------------------------------------------------------
|
|
76
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* PanelHost - bare panel, unmanaged (used by devtools and tests). Always
|
|
82
|
+
* available here, which is what `supportsStandalonePanels` reports.
|
|
83
|
+
*/
|
|
77
84
|
createPanel(configJson) {
|
|
78
85
|
return new UixPanelDocument(configJson, this.kit);
|
|
79
86
|
}
|
|
@@ -134,6 +141,7 @@ export class UixWindowHost {
|
|
|
134
141
|
...(window.followTolerance !== undefined
|
|
135
142
|
? { followTolerance: window.followTolerance }
|
|
136
143
|
: {}),
|
|
144
|
+
...(window.movable !== undefined ? { movable: window.movable } : {}),
|
|
137
145
|
...(window.closable !== undefined ? { closable: window.closable } : {}),
|
|
138
146
|
...(window.minimizable !== undefined
|
|
139
147
|
? { minimizable: window.minimizable }
|
|
@@ -181,18 +189,32 @@ export class UixWindowHost {
|
|
|
181
189
|
// --- Windows --------------------------------------------------------------
|
|
182
190
|
/** Spawn a managed window from compiled UIKitML JSON. */
|
|
183
191
|
createWindow(options) {
|
|
192
|
+
const id = options.id ?? `uix-window-${(this.windowSequence += 1)}`;
|
|
184
193
|
const document = new UixPanelDocument(options.config, this.kit);
|
|
185
194
|
document.setTargetDimensions(options.maxWidth ?? 1, options.maxHeight ?? 1);
|
|
186
195
|
const group = new Group();
|
|
187
|
-
group.name = `uix-window:${
|
|
196
|
+
group.name = `uix-window:${id}`;
|
|
188
197
|
group.add(document);
|
|
189
198
|
if (options.position) {
|
|
190
199
|
group.position.set(...options.position);
|
|
191
200
|
}
|
|
192
201
|
this.scene.add(group);
|
|
193
|
-
const handle = {
|
|
194
|
-
|
|
202
|
+
const handle = {
|
|
203
|
+
id,
|
|
204
|
+
group,
|
|
205
|
+
document,
|
|
206
|
+
panel: document,
|
|
207
|
+
// The panel exists already, so readiness is immediate. The unsubscribe
|
|
208
|
+
// is returned anyway, so callers can write one shape of code for both
|
|
209
|
+
// adapters.
|
|
210
|
+
onReady(listener) {
|
|
211
|
+
listener(document);
|
|
212
|
+
return () => { };
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
this.states.set(id, {
|
|
195
216
|
handle,
|
|
217
|
+
movable: options.movable ?? true,
|
|
196
218
|
options: {
|
|
197
219
|
followOffset: options.followOffset ?? DEFAULT_FOLLOW_OFFSET,
|
|
198
220
|
followSpeed: options.followSpeed ?? 3,
|
|
@@ -202,25 +224,25 @@ export class UixWindowHost {
|
|
|
202
224
|
pin: undefined,
|
|
203
225
|
minimize: undefined,
|
|
204
226
|
});
|
|
205
|
-
this.manager.open(
|
|
227
|
+
this.manager.open(id, {
|
|
206
228
|
title: options.title ?? '',
|
|
207
229
|
dockMode: options.dockMode ?? DockMode.WorldLocked,
|
|
208
230
|
});
|
|
209
231
|
this.wireChrome(options, handle);
|
|
210
232
|
if (options.region !== undefined) {
|
|
211
|
-
this.dock(
|
|
233
|
+
this.dock(id, options.region);
|
|
212
234
|
}
|
|
213
235
|
// The panel's element tree exists synchronously (uikitml interprets on
|
|
214
236
|
// construction); only its LAYOUT is async. Announce readiness now so
|
|
215
237
|
// wiring can attach handlers immediately.
|
|
216
|
-
const event = { id
|
|
217
|
-
this.ready.set(
|
|
238
|
+
const event = { id, panel: document, kind: 'window' };
|
|
239
|
+
this.ready.set(id, event);
|
|
218
240
|
for (const listener of this.readyListeners) {
|
|
219
241
|
try {
|
|
220
242
|
listener(event);
|
|
221
243
|
}
|
|
222
244
|
catch (error) {
|
|
223
|
-
console.error(`[uix] panel-ready listener failed for "${
|
|
245
|
+
console.error(`[uix] panel-ready listener failed for "${id}":`, error);
|
|
224
246
|
}
|
|
225
247
|
}
|
|
226
248
|
return handle;
|
|
@@ -292,7 +314,7 @@ export class UixWindowHost {
|
|
|
292
314
|
}
|
|
293
315
|
wireChrome(options, handle) {
|
|
294
316
|
const element = (id) => handle.document.getElementById(id);
|
|
295
|
-
const id =
|
|
317
|
+
const id = handle.id;
|
|
296
318
|
const title = element(WINDOW_CHROME_IDS.title);
|
|
297
319
|
if (title && options.title) {
|
|
298
320
|
title.setProperties({ text: options.title });
|
package/dist/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * UixWindowHost - the engine binding for plain three.js / XR Blocks scenes.\n *\n * Owns a core `WindowManager` + `RegionRegistry` and applies their decisions\n * to the scene graph: spawn UIKitML windows and dock regions, wire chrome\n * buttons (focus / PIN / MIN / X), collapse content while minimized, place\n * docked windows into their region's slots, and ease `body-follow` windows\n * (and body-locked regions) toward the viewer each frame.\n *\n * It implements the core's `WindowHost` (so app code can wire behaviour\n * through `onPanelReady` with no engine knowledge) and `SceneTarget` (so a\n * portable `SceneDescriptor` builds the same playground here as on IWSDK).\n */\nimport { Group, type Object3D } from 'three';\nimport { parse, type Kit } from '@pmndrs/uikitml';\n\n/**\n * Default `config` resolver: fetch UIKitML source and parse it.\n *\n * IWSDK 0.5 dropped the build-time compile step and parses `PanelUI.config`\n * as source at runtime, so descriptors carry `.uikitml` paths. This parses the\n * same file for the three.js and XR Blocks hosts, which interpret an AST.\n */\nasync function loadUikitmlSource(path: string): Promise<unknown> {\n const response = await fetch(path);\n if (!response.ok) {\n throw new Error(`UIKitML source ${path} -> HTTP ${response.status}`);\n }\n return parse(await response.text());\n}\nimport {\n DockMode,\n RegionRegistry,\n WINDOW_CHROME_IDS,\n WindowManager,\n minimizeLabelFor,\n pinLabelFor,\n slotOffset,\n type DockModeValue,\n type HeadPoseSource,\n type PanelReadyEvent,\n type RegionDefinition,\n type SceneRegion,\n type SceneTarget,\n type SceneWindow,\n type UixElement,\n type Vec3Tuple,\n type WindowHost,\n} from '@realitycollective/webxr-uiextensions';\nimport {\n approach,\n approachAlpha,\n distanceSquared,\n followTarget,\n} from './follow-math.js';\nimport { UixPanelDocument } from './panel-document.js';\n\nexport interface CreateWindowOptions {\n id: string;\n /** Compiled UIKitML JSON (the `{ element, classes }` shape). */\n config: unknown;\n title?: string;\n dockMode?: DockModeValue;\n position?: Vec3Tuple;\n maxWidth?: number;\n maxHeight?: number;\n closable?: boolean;\n minimizable?: boolean;\n pinnable?: boolean;\n followOffset?: Vec3Tuple;\n followSpeed?: number;\n followTolerance?: number;\n /** Dock straight into this region on spawn. */\n region?: string;\n}\n\nexport interface CreateRegionOptions extends Partial<RegionDefinition> {\n id: string;\n position?: Vec3Tuple;\n /** Body-lock the region so it follows the viewer. */\n follow?: boolean;\n followOffset?: Vec3Tuple;\n}\n\nexport interface WindowHandle {\n id: string;\n /** The scene-graph node - position/rotate freely. */\n group: Group;\n document: UixPanelDocument;\n}\n\nexport interface RegionHandle {\n id: string;\n group: Group;\n}\n\nexport interface UixWindowHostOptions {\n /** Parent for spawned windows (the scene, or any group inside it). */\n scene: Object3D;\n /** Viewer pose provider - camera on desktop, HMD pose in XR. */\n headPose: HeadPoseSource;\n /** Optional UIKitML component kit(s) (e.g. horizon kit). */\n kit?: Kit;\n /**\n * Resolver for a window's `config` when it arrives as a string path (as\n * portable `SceneDescriptor`s carry it).\n *\n * Defaults to fetching the `.uikitml` source and parsing it, which is the\n * same artefact IWSDK loads - so one markup file serves every adapter and\n * no build step is required. Override only for an unusual transport; you do\n * not need to supply this to load a normal panel.\n */\n loadConfig?: (path: string) => Promise<unknown>;\n}\n\ninterface FollowOptions {\n followOffset: Vec3Tuple;\n followSpeed: number;\n followTolerance: number;\n}\n\ninterface WindowState {\n handle: WindowHandle;\n options: FollowOptions;\n content: UixElement | undefined;\n pin: UixElement | undefined;\n minimize: UixElement | undefined;\n}\n\ninterface RegionState {\n handle: RegionHandle;\n follow: boolean;\n followOffset: Vec3Tuple;\n}\n\nconst DEFAULT_FOLLOW_OFFSET: Vec3Tuple = [0, -0.15, -1.2];\nconst DEFAULT_REGION_FOLLOW_OFFSET: Vec3Tuple = [0, -0.2, -1.4];\n\nexport class UixWindowHost implements WindowHost, SceneTarget {\n readonly manager = new WindowManager();\n readonly regions = new RegionRegistry();\n private readonly scene: Object3D;\n private readonly headPose: HeadPoseSource;\n private readonly kit: Kit | undefined;\n private readonly loadConfig: (path: string) => Promise<unknown>;\n private readonly states = new Map<string, WindowState>();\n private readonly regionStates = new Map<string, RegionState>();\n private readonly readyListeners = new Set<(event: PanelReadyEvent) => void>();\n /** Panels already live - replayed to late `onPanelReady` subscribers. */\n private readonly ready = new Map<string, PanelReadyEvent>();\n\n constructor(options: UixWindowHostOptions) {\n this.scene = options.scene;\n this.headPose = options.headPose;\n this.kit = options.kit;\n this.loadConfig = options.loadConfig ?? loadUikitmlSource;\n\n this.manager.events.on('closed', (record) => {\n const state = this.states.get(record.id);\n if (state) {\n this.states.delete(record.id);\n this.ready.delete(record.id);\n this.regions.undock(record.id);\n state.handle.document.dispose();\n state.handle.group.removeFromParent();\n this.layoutRegions();\n }\n });\n this.manager.events.on('minimized', (record) => {\n this.setContentCollapsed(record.id, true);\n this.syncMinimizeLabel(record.id);\n });\n this.manager.events.on('restored', (record) => {\n this.setContentCollapsed(record.id, false);\n this.syncMinimizeLabel(record.id);\n });\n this.manager.events.on('dockChanged', ({ window }) => {\n this.syncPinLabel(window.id);\n });\n }\n\n // --- WindowHost -----------------------------------------------------------\n\n /** PanelHost - bare panel, unmanaged (used by devtools and tests). */\n createPanel(configJson: unknown): UixPanelDocument {\n return new UixPanelDocument(configJson, this.kit);\n }\n\n /**\n * Observe panel readiness. Windows already live are replayed immediately,\n * so wiring code never races window creation.\n */\n onPanelReady(listener: (event: PanelReadyEvent) => void): () => void {\n this.readyListeners.add(listener);\n for (const event of this.ready.values()) {\n listener(event);\n }\n return () => void this.readyListeners.delete(listener);\n }\n\n // --- SceneTarget (portable scene descriptors) -----------------------------\n\n spawnRegion(region: SceneRegion): void {\n this.createRegion({\n id: region.id,\n ...(region.flow !== undefined ? { flow: region.flow } : {}),\n ...(region.pitch !== undefined ? { pitch: region.pitch } : {}),\n ...(region.columns !== undefined ? { columns: region.columns } : {}),\n ...(region.capacity !== undefined ? { capacity: region.capacity } : {}),\n ...(region.snapRadius !== undefined ? { snapRadius: region.snapRadius } : {}),\n ...(region.position !== undefined\n ? { position: [...region.position] as Vec3Tuple }\n : {}),\n ...(region.follow !== undefined ? { follow: region.follow } : {}),\n ...(region.followOffset !== undefined\n ? { followOffset: [...region.followOffset] as Vec3Tuple }\n : {}),\n });\n }\n\n /**\n * Scene descriptors carry config PATHS; this resolves the path and spawns\n * the window when it arrives. Fire-and-forget by design - subscribe with\n * {@link onPanelReady} to wire behaviour once the panel exists.\n */\n spawnWindow(window: SceneWindow): void {\n void this.loadConfig(window.config)\n .then((config) => {\n this.createWindow({\n id: window.id,\n config,\n title: window.title,\n ...(window.position !== undefined\n ? { position: [...window.position] as Vec3Tuple }\n : {}),\n ...(window.maxWidth !== undefined ? { maxWidth: window.maxWidth } : {}),\n ...(window.maxHeight !== undefined ? { maxHeight: window.maxHeight } : {}),\n ...(window.dockMode !== undefined ? { dockMode: window.dockMode } : {}),\n ...(window.region !== undefined ? { region: window.region } : {}),\n ...(window.followOffset !== undefined\n ? { followOffset: [...window.followOffset] as Vec3Tuple }\n : {}),\n ...(window.followSpeed !== undefined\n ? { followSpeed: window.followSpeed }\n : {}),\n ...(window.followTolerance !== undefined\n ? { followTolerance: window.followTolerance }\n : {}),\n ...(window.closable !== undefined ? { closable: window.closable } : {}),\n ...(window.minimizable !== undefined\n ? { minimizable: window.minimizable }\n : {}),\n ...(window.pinnable !== undefined ? { pinnable: window.pinnable } : {}),\n });\n })\n .catch((error) => {\n console.error(`[uix] failed to load panel \"${window.id}\":`, error);\n });\n }\n\n // --- Regions --------------------------------------------------------------\n\n /** Create a dock region anchored in the scene. */\n createRegion(options: CreateRegionOptions): RegionHandle {\n const { id, position, follow, followOffset, ...definition } = options;\n this.regions.register(id, definition);\n\n const group = new Group();\n group.name = `uix-region:${id}`;\n if (position) {\n group.position.set(...position);\n }\n this.scene.add(group);\n\n const handle: RegionHandle = { id, group };\n this.regionStates.set(id, {\n handle,\n follow: follow ?? false,\n followOffset: followOffset ?? DEFAULT_REGION_FOLLOW_OFFSET,\n });\n return handle;\n }\n\n region(id: string): RegionHandle | undefined {\n return this.regionStates.get(id)?.handle;\n }\n\n /** Dock a window into a region (or undock it with `undefined`). */\n dock(windowId: string, regionId: string | undefined): void {\n if (regionId === undefined) {\n this.regions.undock(windowId);\n } else {\n this.regions.dock(windowId, regionId);\n this.manager.setDockMode(windowId, DockMode.WorldLocked);\n }\n this.layoutRegions();\n }\n\n // --- Windows --------------------------------------------------------------\n\n /** Spawn a managed window from compiled UIKitML JSON. */\n createWindow(options: CreateWindowOptions): WindowHandle {\n const document = new UixPanelDocument(options.config, this.kit);\n document.setTargetDimensions(options.maxWidth ?? 1, options.maxHeight ?? 1);\n\n const group = new Group();\n group.name = `uix-window:${options.id}`;\n group.add(document);\n if (options.position) {\n group.position.set(...options.position);\n }\n this.scene.add(group);\n\n const handle: WindowHandle = { id: options.id, group, document };\n this.states.set(options.id, {\n handle,\n options: {\n followOffset: options.followOffset ?? DEFAULT_FOLLOW_OFFSET,\n followSpeed: options.followSpeed ?? 3,\n followTolerance: options.followTolerance ?? 0.35,\n },\n content: undefined,\n pin: undefined,\n minimize: undefined,\n });\n\n this.manager.open(options.id, {\n title: options.title ?? '',\n dockMode: options.dockMode ?? DockMode.WorldLocked,\n });\n this.wireChrome(options, handle);\n\n if (options.region !== undefined) {\n this.dock(options.id, options.region);\n }\n\n // The panel's element tree exists synchronously (uikitml interprets on\n // construction); only its LAYOUT is async. Announce readiness now so\n // wiring can attach handlers immediately.\n const event: PanelReadyEvent = { id: options.id, panel: handle.document };\n this.ready.set(options.id, event);\n for (const listener of this.readyListeners) {\n try {\n listener(event);\n } catch (error) {\n console.error(`[uix] panel-ready listener failed for \"${options.id}\":`, error);\n }\n }\n\n return handle;\n }\n\n window(id: string): WindowHandle | undefined {\n return this.states.get(id)?.handle;\n }\n\n /** Drive per-frame from the engine loop (delta in SECONDS). */\n update(deltaSeconds: number): void {\n for (const [id, state] of this.states) {\n state.handle.document.update(deltaSeconds);\n const record = this.manager.get(id);\n const docked = this.regions.regionOf(id) !== undefined;\n if (\n record &&\n record.dockMode === DockMode.BodyFollow &&\n !record.dragging &&\n !docked\n ) {\n this.applyFollow(state.handle.group, state.options, deltaSeconds, true);\n }\n }\n for (const state of this.regionStates.values()) {\n if (state.follow) {\n this.applyFollow(\n state.handle.group,\n {\n followOffset: state.followOffset,\n followSpeed: 3,\n followTolerance: 0.2,\n },\n deltaSeconds,\n false,\n );\n this.layoutRegion(state.handle.id);\n }\n }\n }\n\n private applyFollow(\n group: Group,\n options: FollowOptions,\n deltaSeconds: number,\n faceViewer: boolean,\n ): void {\n const pose = this.headPose.getHeadPose();\n const target = followTarget(pose, options.followOffset);\n const position = group.position;\n const current: Vec3Tuple = [position.x, position.y, position.z];\n const tolerance = options.followTolerance;\n if (distanceSquared(current, target) <= tolerance * tolerance) {\n return;\n }\n const next = approach(\n current,\n target,\n approachAlpha(options.followSpeed, deltaSeconds),\n );\n position.set(...next);\n if (faceViewer) {\n group.lookAt(pose.position[0], position.y, pose.position[2]);\n }\n }\n\n /** Re-place every docked window into its region's slot. */\n private layoutRegions(): void {\n for (const id of this.regionStates.keys()) {\n this.layoutRegion(id);\n }\n }\n\n private layoutRegion(regionId: string): void {\n const regionState = this.regionStates.get(regionId);\n const registered = this.regions.get(regionId);\n if (!regionState || !registered) {\n return;\n }\n const origin = regionState.handle.group.position;\n registered.members.forEach((windowId, index) => {\n const windowState = this.states.get(windowId);\n if (!windowState) {\n return;\n }\n const [dx, dy, dz] = slotOffset(registered.definition, index);\n windowState.handle.group.position.set(\n origin.x + dx,\n origin.y + dy,\n origin.z + dz,\n );\n windowState.handle.group.quaternion.copy(regionState.handle.group.quaternion);\n });\n }\n\n private wireChrome(options: CreateWindowOptions, handle: WindowHandle): void {\n const element = (id: string) => handle.document.getElementById(id);\n const id = options.id;\n\n const title = element(WINDOW_CHROME_IDS.title);\n if (title && options.title) {\n title.setProperties({ text: options.title });\n }\n\n // Chrome presses must not bubble to the window root's focus handler:\n // a press on CLOSE would otherwise focus a window that is about to be\n // destroyed, and `focus()` on a removed window throws. (Same guard the\n // IWSDK adapter applies.)\n const swallowPress = (button: UixElement | undefined): void => {\n button?.addEventListener('pointerdown', (event) => {\n (event as { stopPropagation?: () => void } | undefined)?.stopPropagation?.();\n });\n };\n swallowPress(element(WINDOW_CHROME_IDS.pin));\n swallowPress(element(WINDOW_CHROME_IDS.dock));\n swallowPress(element(WINDOW_CHROME_IDS.minimize));\n swallowPress(element(WINDOW_CHROME_IDS.close));\n\n // Any press anywhere on the window brings it to the front. Guarded:\n // events can still arrive for a window that was just closed.\n element(WINDOW_CHROME_IDS.window)?.addEventListener('pointerdown', () => {\n if (this.manager.has(id)) {\n this.manager.focus(id);\n }\n });\n\n const close = element(WINDOW_CHROME_IDS.close);\n if (options.closable === false) {\n close?.setProperties({ display: 'none' });\n } else {\n close?.addEventListener('click', () => {\n if (this.manager.has(id)) {\n this.manager.close(id);\n }\n });\n }\n\n const minimize = element(WINDOW_CHROME_IDS.minimize);\n if (options.minimizable === false) {\n minimize?.setProperties({ display: 'none' });\n } else {\n minimize?.addEventListener('click', () => {\n if (this.manager.has(id)) {\n this.manager.toggleMinimized(id);\n }\n });\n this.syncMinimizeLabel(id);\n }\n\n const pin = element(WINDOW_CHROME_IDS.pin);\n const state = this.states.get(id);\n if (state) {\n state.content = element(WINDOW_CHROME_IDS.content);\n state.pin = pin;\n state.minimize = element(WINDOW_CHROME_IDS.minimize);\n }\n if (options.pinnable === false) {\n pin?.setProperties({ display: 'none' });\n } else {\n pin?.addEventListener('click', () => {\n if (!this.manager.has(id)) {\n return;\n }\n // Pinning a docked window pops it out of its region first.\n if (this.regions.regionOf(id) !== undefined) {\n this.regions.undock(id);\n }\n this.manager.togglePin(id);\n });\n this.syncPinLabel(id);\n }\n }\n\n private setContentCollapsed(id: string, collapsed: boolean): void {\n this.states\n .get(id)\n ?.content?.setProperties({ display: collapsed ? 'none' : 'flex' });\n }\n\n /** MIN when open, MAX when minimized - the label names the next action. */\n private syncMinimizeLabel(id: string): void {\n const record = this.manager.get(id);\n const minimize = this.states.get(id)?.minimize;\n if (record && minimize) {\n minimize.setProperties({ text: minimizeLabelFor(record) });\n }\n }\n\n private syncPinLabel(id: string): void {\n const record = this.manager.get(id);\n const pin = this.states.get(id)?.pin;\n if (record && pin) {\n pin.setProperties({ text: pinLabelFor(record) });\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * UixWindowHost - the engine binding for plain three.js / XR Blocks scenes.\n *\n * Owns a core `WindowManager` + `RegionRegistry` and applies their decisions\n * to the scene graph: spawn UIKitML windows and dock regions, wire chrome\n * buttons (focus / PIN / MIN / X), collapse content while minimized, place\n * docked windows into their region's slots, and ease `body-follow` windows\n * (and body-locked regions) toward the viewer each frame.\n *\n * It implements the core's `WindowHost` (so app code can wire behaviour\n * through `onPanelReady` with no engine knowledge) and `SceneTarget` (so a\n * portable `SceneDescriptor` builds the same playground here as on IWSDK).\n */\nimport { Group, type Object3D } from 'three';\nimport { parse, type Kit } from '@pmndrs/uikitml';\n\n/**\n * Default `config` resolver: fetch UIKitML source and parse it.\n *\n * IWSDK 0.5 dropped the build-time compile step and parses `PanelUI.config`\n * as source at runtime, so descriptors carry `.uikitml` paths. This parses the\n * same file for the three.js and XR Blocks hosts, which interpret an AST.\n */\nasync function loadUikitmlSource(path: string): Promise<unknown> {\n const response = await fetch(path);\n if (!response.ok) {\n throw new Error(`UIKitML source ${path} -> HTTP ${response.status}`);\n }\n return parse(await response.text());\n}\nimport {\n DockMode,\n RegionRegistry,\n WINDOW_CHROME_IDS,\n WindowManager,\n minimizeLabelFor,\n pinLabelFor,\n slotOffset,\n type HeadPoseSource,\n type PanelHandle,\n type PanelReadyEvent,\n type RegionDefinition,\n type SceneRegion,\n type SceneTarget,\n type SceneWindow,\n type UixElement,\n type Vec3Tuple,\n type WindowHandle as CoreWindowHandle,\n type WindowHost,\n type WindowOptionsBase,\n} from '@realitycollective/webxr-uiextensions';\nimport {\n approach,\n approachAlpha,\n distanceSquared,\n followTarget,\n} from './follow-math.js';\nimport { UixPanelDocument } from './panel-document.js';\n\n/**\n * Options for {@link UixWindowHost.createWindow}.\n *\n * Everything but `config` comes from the portable {@link WindowOptionsBase},\n * so an option means the same thing here as on the IWSDK adapter. `id` is\n * optional: leave it out and the host names the window `uix-window-<n>`.\n *\n * One option is accepted but not acted on: `movable`. This host has no\n * title-bar drag of its own yet - dragging comes from the XR Blocks / desktop\n * input layer above it - so the flag is recorded and otherwise ignored.\n */\nexport interface CreateWindowOptions extends WindowOptionsBase {\n /** Compiled UIKitML JSON (the `{ element, classes }` shape). */\n config: unknown;\n}\n\nexport interface CreateRegionOptions extends Partial<RegionDefinition> {\n id: string;\n position?: Vec3Tuple;\n /** Body-lock the region so it follows the viewer. */\n follow?: boolean;\n followOffset?: Vec3Tuple;\n}\n\n/**\n * A window spawned by {@link UixWindowHost.createWindow}.\n *\n * Satisfies the core {@link CoreWindowHandle} and adds the three.js specifics.\n * `panel` is the document itself, which already implements `PanelHandle`, and\n * is never `undefined` here: uikitml interprets the markup synchronously, so\n * the panel exists the moment `createWindow` returns.\n */\nexport interface XrBlocksWindowHandle extends CoreWindowHandle {\n readonly id: string;\n /** The scene-graph node - position/rotate freely. */\n group: Group;\n document: UixPanelDocument;\n /** Same object as {@link document}, under the portable name. */\n readonly panel: UixPanelDocument;\n onReady(listener: (panel: PanelHandle) => void): () => void;\n}\n\n/** Back-compatible name for {@link XrBlocksWindowHandle}. */\nexport type WindowHandle = XrBlocksWindowHandle;\n\nexport interface RegionHandle {\n id: string;\n group: Group;\n}\n\nexport interface UixWindowHostOptions {\n /** Parent for spawned windows (the scene, or any group inside it). */\n scene: Object3D;\n /** Viewer pose provider - camera on desktop, HMD pose in XR. */\n headPose: HeadPoseSource;\n /** Optional UIKitML component kit(s) (e.g. horizon kit). */\n kit?: Kit;\n /**\n * Resolver for a window's `config` when it arrives as a string path (as\n * portable `SceneDescriptor`s carry it).\n *\n * Defaults to fetching the `.uikitml` source and parsing it, which is the\n * same artefact IWSDK loads - so one markup file serves every adapter and\n * no build step is required. Override only for an unusual transport; you do\n * not need to supply this to load a normal panel.\n */\n loadConfig?: (path: string) => Promise<unknown>;\n}\n\ninterface FollowOptions {\n followOffset: Vec3Tuple;\n followSpeed: number;\n followTolerance: number;\n}\n\ninterface WindowState {\n handle: XrBlocksWindowHandle;\n /**\n * Recorded from the create options and not acted on - see\n * {@link CreateWindowOptions}. Kept so a future drag path here, or a caller\n * inspecting the host, reads the value the scene descriptor asked for.\n */\n movable: boolean;\n options: FollowOptions;\n content: UixElement | undefined;\n pin: UixElement | undefined;\n minimize: UixElement | undefined;\n}\n\ninterface RegionState {\n handle: RegionHandle;\n follow: boolean;\n followOffset: Vec3Tuple;\n}\n\nconst DEFAULT_FOLLOW_OFFSET: Vec3Tuple = [0, -0.15, -1.2];\nconst DEFAULT_REGION_FOLLOW_OFFSET: Vec3Tuple = [0, -0.2, -1.4];\n\nexport class UixWindowHost implements WindowHost, SceneTarget {\n /** Bare panels work here - the host does not own a panel lifecycle. */\n readonly supportsStandalonePanels: boolean = true;\n readonly manager = new WindowManager();\n readonly regions = new RegionRegistry();\n private readonly scene: Object3D;\n private readonly headPose: HeadPoseSource;\n private readonly kit: Kit | undefined;\n private readonly loadConfig: (path: string) => Promise<unknown>;\n private readonly states = new Map<string, WindowState>();\n private readonly regionStates = new Map<string, RegionState>();\n private readonly readyListeners = new Set<(event: PanelReadyEvent) => void>();\n /** Panels already live - replayed to late `onPanelReady` subscribers. */\n private readonly ready = new Map<string, PanelReadyEvent>();\n /** Feeds `uix-window-<n>` ids to windows created without one. */\n private windowSequence = 0;\n\n constructor(options: UixWindowHostOptions) {\n this.scene = options.scene;\n this.headPose = options.headPose;\n this.kit = options.kit;\n this.loadConfig = options.loadConfig ?? loadUikitmlSource;\n\n this.manager.events.on('closed', (record) => {\n const state = this.states.get(record.id);\n if (state) {\n this.states.delete(record.id);\n this.ready.delete(record.id);\n this.regions.undock(record.id);\n state.handle.document.dispose();\n state.handle.group.removeFromParent();\n this.layoutRegions();\n }\n });\n this.manager.events.on('minimized', (record) => {\n this.setContentCollapsed(record.id, true);\n this.syncMinimizeLabel(record.id);\n });\n this.manager.events.on('restored', (record) => {\n this.setContentCollapsed(record.id, false);\n this.syncMinimizeLabel(record.id);\n });\n this.manager.events.on('dockChanged', ({ window }) => {\n this.syncPinLabel(window.id);\n });\n }\n\n // --- WindowHost -----------------------------------------------------------\n\n /**\n * PanelHost - bare panel, unmanaged (used by devtools and tests). Always\n * available here, which is what `supportsStandalonePanels` reports.\n */\n createPanel(configJson: unknown): UixPanelDocument {\n return new UixPanelDocument(configJson, this.kit);\n }\n\n /**\n * Observe panel readiness. Windows already live are replayed immediately,\n * so wiring code never races window creation.\n */\n onPanelReady(listener: (event: PanelReadyEvent) => void): () => void {\n this.readyListeners.add(listener);\n for (const event of this.ready.values()) {\n listener(event);\n }\n return () => void this.readyListeners.delete(listener);\n }\n\n // --- SceneTarget (portable scene descriptors) -----------------------------\n\n spawnRegion(region: SceneRegion): void {\n this.createRegion({\n id: region.id,\n ...(region.flow !== undefined ? { flow: region.flow } : {}),\n ...(region.pitch !== undefined ? { pitch: region.pitch } : {}),\n ...(region.columns !== undefined ? { columns: region.columns } : {}),\n ...(region.capacity !== undefined ? { capacity: region.capacity } : {}),\n ...(region.snapRadius !== undefined ? { snapRadius: region.snapRadius } : {}),\n ...(region.position !== undefined\n ? { position: [...region.position] as Vec3Tuple }\n : {}),\n ...(region.follow !== undefined ? { follow: region.follow } : {}),\n ...(region.followOffset !== undefined\n ? { followOffset: [...region.followOffset] as Vec3Tuple }\n : {}),\n });\n }\n\n /**\n * Scene descriptors carry config PATHS; this resolves the path and spawns\n * the window when it arrives. Fire-and-forget by design - subscribe with\n * {@link onPanelReady} to wire behaviour once the panel exists.\n */\n spawnWindow(window: SceneWindow): void {\n void this.loadConfig(window.config)\n .then((config) => {\n this.createWindow({\n id: window.id,\n config,\n title: window.title,\n ...(window.position !== undefined\n ? { position: [...window.position] as Vec3Tuple }\n : {}),\n ...(window.maxWidth !== undefined ? { maxWidth: window.maxWidth } : {}),\n ...(window.maxHeight !== undefined ? { maxHeight: window.maxHeight } : {}),\n ...(window.dockMode !== undefined ? { dockMode: window.dockMode } : {}),\n ...(window.region !== undefined ? { region: window.region } : {}),\n ...(window.followOffset !== undefined\n ? { followOffset: [...window.followOffset] as Vec3Tuple }\n : {}),\n ...(window.followSpeed !== undefined\n ? { followSpeed: window.followSpeed }\n : {}),\n ...(window.followTolerance !== undefined\n ? { followTolerance: window.followTolerance }\n : {}),\n ...(window.movable !== undefined ? { movable: window.movable } : {}),\n ...(window.closable !== undefined ? { closable: window.closable } : {}),\n ...(window.minimizable !== undefined\n ? { minimizable: window.minimizable }\n : {}),\n ...(window.pinnable !== undefined ? { pinnable: window.pinnable } : {}),\n });\n })\n .catch((error) => {\n console.error(`[uix] failed to load panel \"${window.id}\":`, error);\n });\n }\n\n // --- Regions --------------------------------------------------------------\n\n /** Create a dock region anchored in the scene. */\n createRegion(options: CreateRegionOptions): RegionHandle {\n const { id, position, follow, followOffset, ...definition } = options;\n this.regions.register(id, definition);\n\n const group = new Group();\n group.name = `uix-region:${id}`;\n if (position) {\n group.position.set(...position);\n }\n this.scene.add(group);\n\n const handle: RegionHandle = { id, group };\n this.regionStates.set(id, {\n handle,\n follow: follow ?? false,\n followOffset: followOffset ?? DEFAULT_REGION_FOLLOW_OFFSET,\n });\n return handle;\n }\n\n region(id: string): RegionHandle | undefined {\n return this.regionStates.get(id)?.handle;\n }\n\n /** Dock a window into a region (or undock it with `undefined`). */\n dock(windowId: string, regionId: string | undefined): void {\n if (regionId === undefined) {\n this.regions.undock(windowId);\n } else {\n this.regions.dock(windowId, regionId);\n this.manager.setDockMode(windowId, DockMode.WorldLocked);\n }\n this.layoutRegions();\n }\n\n // --- Windows --------------------------------------------------------------\n\n /** Spawn a managed window from compiled UIKitML JSON. */\n createWindow(options: CreateWindowOptions): XrBlocksWindowHandle {\n const id = options.id ?? `uix-window-${(this.windowSequence += 1)}`;\n const document = new UixPanelDocument(options.config, this.kit);\n document.setTargetDimensions(options.maxWidth ?? 1, options.maxHeight ?? 1);\n\n const group = new Group();\n group.name = `uix-window:${id}`;\n group.add(document);\n if (options.position) {\n group.position.set(...options.position);\n }\n this.scene.add(group);\n\n const handle: XrBlocksWindowHandle = {\n id,\n group,\n document,\n panel: document,\n // The panel exists already, so readiness is immediate. The unsubscribe\n // is returned anyway, so callers can write one shape of code for both\n // adapters.\n onReady(listener: (panel: PanelHandle) => void): () => void {\n listener(document);\n return () => {};\n },\n };\n this.states.set(id, {\n handle,\n movable: options.movable ?? true,\n options: {\n followOffset: options.followOffset ?? DEFAULT_FOLLOW_OFFSET,\n followSpeed: options.followSpeed ?? 3,\n followTolerance: options.followTolerance ?? 0.35,\n },\n content: undefined,\n pin: undefined,\n minimize: undefined,\n });\n\n this.manager.open(id, {\n title: options.title ?? '',\n dockMode: options.dockMode ?? DockMode.WorldLocked,\n });\n this.wireChrome(options, handle);\n\n if (options.region !== undefined) {\n this.dock(id, options.region);\n }\n\n // The panel's element tree exists synchronously (uikitml interprets on\n // construction); only its LAYOUT is async. Announce readiness now so\n // wiring can attach handlers immediately.\n const event: PanelReadyEvent = { id, panel: document, kind: 'window' };\n this.ready.set(id, event);\n for (const listener of this.readyListeners) {\n try {\n listener(event);\n } catch (error) {\n console.error(`[uix] panel-ready listener failed for \"${id}\":`, error);\n }\n }\n\n return handle;\n }\n\n window(id: string): XrBlocksWindowHandle | undefined {\n return this.states.get(id)?.handle;\n }\n\n /** Drive per-frame from the engine loop (delta in SECONDS). */\n update(deltaSeconds: number): void {\n for (const [id, state] of this.states) {\n state.handle.document.update(deltaSeconds);\n const record = this.manager.get(id);\n const docked = this.regions.regionOf(id) !== undefined;\n if (\n record &&\n record.dockMode === DockMode.BodyFollow &&\n !record.dragging &&\n !docked\n ) {\n this.applyFollow(state.handle.group, state.options, deltaSeconds, true);\n }\n }\n for (const state of this.regionStates.values()) {\n if (state.follow) {\n this.applyFollow(\n state.handle.group,\n {\n followOffset: state.followOffset,\n followSpeed: 3,\n followTolerance: 0.2,\n },\n deltaSeconds,\n false,\n );\n this.layoutRegion(state.handle.id);\n }\n }\n }\n\n private applyFollow(\n group: Group,\n options: FollowOptions,\n deltaSeconds: number,\n faceViewer: boolean,\n ): void {\n const pose = this.headPose.getHeadPose();\n const target = followTarget(pose, options.followOffset);\n const position = group.position;\n const current: Vec3Tuple = [position.x, position.y, position.z];\n const tolerance = options.followTolerance;\n if (distanceSquared(current, target) <= tolerance * tolerance) {\n return;\n }\n const next = approach(\n current,\n target,\n approachAlpha(options.followSpeed, deltaSeconds),\n );\n position.set(...next);\n if (faceViewer) {\n group.lookAt(pose.position[0], position.y, pose.position[2]);\n }\n }\n\n /** Re-place every docked window into its region's slot. */\n private layoutRegions(): void {\n for (const id of this.regionStates.keys()) {\n this.layoutRegion(id);\n }\n }\n\n private layoutRegion(regionId: string): void {\n const regionState = this.regionStates.get(regionId);\n const registered = this.regions.get(regionId);\n if (!regionState || !registered) {\n return;\n }\n const origin = regionState.handle.group.position;\n registered.members.forEach((windowId, index) => {\n const windowState = this.states.get(windowId);\n if (!windowState) {\n return;\n }\n const [dx, dy, dz] = slotOffset(registered.definition, index);\n windowState.handle.group.position.set(\n origin.x + dx,\n origin.y + dy,\n origin.z + dz,\n );\n windowState.handle.group.quaternion.copy(regionState.handle.group.quaternion);\n });\n }\n\n private wireChrome(\n options: CreateWindowOptions,\n handle: XrBlocksWindowHandle,\n ): void {\n const element = (id: string) => handle.document.getElementById(id);\n const id = handle.id;\n\n const title = element(WINDOW_CHROME_IDS.title);\n if (title && options.title) {\n title.setProperties({ text: options.title });\n }\n\n // Chrome presses must not bubble to the window root's focus handler:\n // a press on CLOSE would otherwise focus a window that is about to be\n // destroyed, and `focus()` on a removed window throws. (Same guard the\n // IWSDK adapter applies.)\n const swallowPress = (button: UixElement | undefined): void => {\n button?.addEventListener('pointerdown', (event) => {\n (event as { stopPropagation?: () => void } | undefined)?.stopPropagation?.();\n });\n };\n swallowPress(element(WINDOW_CHROME_IDS.pin));\n swallowPress(element(WINDOW_CHROME_IDS.dock));\n swallowPress(element(WINDOW_CHROME_IDS.minimize));\n swallowPress(element(WINDOW_CHROME_IDS.close));\n\n // Any press anywhere on the window brings it to the front. Guarded:\n // events can still arrive for a window that was just closed.\n element(WINDOW_CHROME_IDS.window)?.addEventListener('pointerdown', () => {\n if (this.manager.has(id)) {\n this.manager.focus(id);\n }\n });\n\n const close = element(WINDOW_CHROME_IDS.close);\n if (options.closable === false) {\n close?.setProperties({ display: 'none' });\n } else {\n close?.addEventListener('click', () => {\n if (this.manager.has(id)) {\n this.manager.close(id);\n }\n });\n }\n\n const minimize = element(WINDOW_CHROME_IDS.minimize);\n if (options.minimizable === false) {\n minimize?.setProperties({ display: 'none' });\n } else {\n minimize?.addEventListener('click', () => {\n if (this.manager.has(id)) {\n this.manager.toggleMinimized(id);\n }\n });\n this.syncMinimizeLabel(id);\n }\n\n const pin = element(WINDOW_CHROME_IDS.pin);\n const state = this.states.get(id);\n if (state) {\n state.content = element(WINDOW_CHROME_IDS.content);\n state.pin = pin;\n state.minimize = element(WINDOW_CHROME_IDS.minimize);\n }\n if (options.pinnable === false) {\n pin?.setProperties({ display: 'none' });\n } else {\n pin?.addEventListener('click', () => {\n if (!this.manager.has(id)) {\n return;\n }\n // Pinning a docked window pops it out of its region first.\n if (this.regions.regionOf(id) !== undefined) {\n this.regions.undock(id);\n }\n this.manager.togglePin(id);\n });\n this.syncPinLabel(id);\n }\n }\n\n private setContentCollapsed(id: string, collapsed: boolean): void {\n this.states\n .get(id)\n ?.content?.setProperties({ display: collapsed ? 'none' : 'flex' });\n }\n\n /** MIN when open, MAX when minimized - the label names the next action. */\n private syncMinimizeLabel(id: string): void {\n const record = this.manager.get(id);\n const minimize = this.states.get(id)?.minimize;\n if (record && minimize) {\n minimize.setProperties({ text: minimizeLabelFor(record) });\n }\n }\n\n private syncPinLabel(id: string): void {\n const record = this.manager.get(id);\n const pin = this.states.get(id)?.pin;\n if (record && pin) {\n pin.setProperties({ text: pinLabelFor(record) });\n }\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,sEAAsE;AACtE,cAAc,uCAAuC,CAAC;AAEtD,+BAA+B;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAE9B,qCAAqC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC","sourcesContent":["/**\n * @realitycollective/xrblocks-uiextensions - EXPERIMENTAL Google XR Blocks /\n * plain three.js adapter for the Reality Collective UI Extensions.\n *\n * Binds the engine-free `@realitycollective/webxr-uiextensions` core to any\n * three.js WebXR scene graph - which is exactly what an XR Blocks Script\n * provides. See the README for the current feature matrix versus the IWSDK\n * adapter.\n */\n// The portable core - re-exported for a single-dependency experience.\nexport * from '@realitycollective/webxr-uiextensions';\n\n// three.js / XR Blocks binding\nexport * from './renderer-setup.js';\nexport * from './scale-math.js';\nexport * from './follow-math.js';\nexport * from './panel-document.js';\nexport * from './host.js';\nexport * from './pointer-forward.js';\nexport * from './xrblocks.js';\n\n// Desktop (mouse + keyboard) support\nexport * from './desktop-locomotion.js';\nexport * from './desktop-controls.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,sEAAsE;AACtE,cAAc,uCAAuC,CAAC;AAEtD,+BAA+B;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAE9B,qCAAqC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC","sourcesContent":["/**\n * @realitycollective/xrblocks-uiextensions - EXPERIMENTAL Google XR Blocks /\n * plain three.js adapter for the Reality Collective UI Extensions.\n *\n * Binds the engine-free `@realitycollective/webxr-uiextensions` core to any\n * three.js WebXR scene graph - which is exactly what an XR Blocks Script\n * provides. See the README for the current feature matrix versus the IWSDK\n * adapter.\n */\n// The portable core - re-exported for a single-dependency experience.\nexport * from '@realitycollective/webxr-uiextensions';\n\n// three.js / XR Blocks binding\nexport * from './renderer-setup.js';\nexport * from './scale-math.js';\nexport * from './follow-math.js';\nexport * from './panel-document.js';\nexport * from './host.js';\nexport * from './pointer-forward.js';\nexport * from './xrblocks.js';\n\n// Desktop (mouse + keyboard) support\nexport * from './desktop-locomotion.js';\nexport * from './desktop-controls.js';\n\n// `WindowHandle` is declared twice above - once as the core's portable\n// interface, once as this host's richer handle. Name the winner explicitly,\n// or both star exports drop it. The host's handle satisfies the core one, so\n// code written against either keeps compiling.\nexport type { XrBlocksWindowHandle as WindowHandle } from './host.js';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@realitycollective/xrblocks-uiextensions",
|
|
3
|
-
"version": "0.1.0-preview.
|
|
3
|
+
"version": "0.1.0-preview.2",
|
|
4
4
|
"description": "EXPERIMENTAL Google XR Blocks / plain three.js adapter for the Reality Collective UI Extensions - hosts the engine-free @realitycollective/webxr-uiextensions windowing core (UIKitML panels, window chrome, follow mode) in any three.js WebXR scene, including XR Blocks Scripts.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"realitycollective",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@pmndrs/uikitml": "^0.1.12",
|
|
39
|
-
"@realitycollective/webxr-uiextensions": "^0.1.0-preview.
|
|
39
|
+
"@realitycollective/webxr-uiextensions": "^0.1.0-preview.2"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"three": ">=0.170.0"
|