@webspatial/react-sdk 0.0.6 → 0.0.9

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.
@@ -742,6 +742,127 @@ function parseCornerRadius(computedStyle) {
742
742
  var import_react7 = require("react");
743
743
  var SpatialDebugNameContext = (0, import_react7.createContext)("");
744
744
 
745
+ // src/XRApp.ts
746
+ var defaultSceneConfig = {
747
+ defaultSize: {
748
+ width: 900,
749
+ height: 700
750
+ },
751
+ resizability: "automatic"
752
+ };
753
+ var CONTEXT_WINDOW_URL = "webspatial://createWindowContext";
754
+ var originalOpen = window.open;
755
+ var XRApp = class _XRApp {
756
+ static instance;
757
+ static getInstance() {
758
+ if (!_XRApp.instance) {
759
+ _XRApp.instance = new _XRApp();
760
+ }
761
+ return _XRApp.instance;
762
+ }
763
+ handleATag(event) {
764
+ const targetElement = event.target;
765
+ if (targetElement.tagName === "A") {
766
+ const link = targetElement;
767
+ const target = link.target;
768
+ const url = link.href;
769
+ if (target && target !== "_self") {
770
+ event.preventDefault();
771
+ window.open(url, target);
772
+ } else {
773
+ window.location.href = url;
774
+ }
775
+ }
776
+ }
777
+ init() {
778
+ ;
779
+ window.open = this.open;
780
+ document.addEventListener("click", this.handleATag);
781
+ }
782
+ deinit() {
783
+ ;
784
+ window.open = originalOpen;
785
+ document.removeEventListener("click", this.handleATag);
786
+ }
787
+ configMap = {};
788
+ // name=>config
789
+ getConfig(name) {
790
+ if (name === void 0 || !this.configMap[name]) return void 0;
791
+ return this.configMap[name];
792
+ }
793
+ async show(window2, cfg) {
794
+ try {
795
+ let session = getSession();
796
+ await session._createScene(
797
+ "Plain",
798
+ // only support Plain for now
799
+ {
800
+ sceneData: {
801
+ method: "showRoot",
802
+ sceneConfig: cfg,
803
+ // url: url,
804
+ window: window2
805
+ }
806
+ }
807
+ );
808
+ } catch (error) {
809
+ console.error(error);
810
+ }
811
+ }
812
+ open = (url, target, features) => {
813
+ const newWindow = originalOpen(url, target, features);
814
+ if (url === CONTEXT_WINDOW_URL) return newWindow;
815
+ if (target === "_self" || target === "_parent" || target === "_top") {
816
+ return newWindow;
817
+ }
818
+ let cnt = 2;
819
+ let timer = setInterval(async () => {
820
+ cnt -= 1;
821
+ if (cnt < 0) {
822
+ clearInterval(timer);
823
+ return;
824
+ }
825
+ if (newWindow._webSpatialID) {
826
+ clearInterval(timer);
827
+ let session = getSession();
828
+ if (!session) {
829
+ console.error("no session");
830
+ } else {
831
+ const cfg = this.getConfig(target);
832
+ try {
833
+ await session._createScene(
834
+ "Plain",
835
+ // only support Plain for now
836
+ {
837
+ sceneData: {
838
+ method: "createRoot",
839
+ sceneConfig: cfg,
840
+ url,
841
+ window: newWindow
842
+ // windowID: (newWindow as any)._webSpatialID,
843
+ // windowContainerID: (newWindow as any)._webSpatialGroupID,
844
+ }
845
+ }
846
+ );
847
+ if (typeof target === "string" && this.configMap[target]) {
848
+ delete this.configMap[target];
849
+ }
850
+ } catch (error) {
851
+ console.error(error);
852
+ }
853
+ }
854
+ }
855
+ }, 0);
856
+ return newWindow;
857
+ };
858
+ initScene(name, callback) {
859
+ this.configMap[name] = callback({ ...defaultSceneConfig });
860
+ }
861
+ };
862
+ function initScene(name, callback) {
863
+ return XRApp.getInstance().initScene(name, callback);
864
+ }
865
+
745
866
  // src/spatial-react-components/SpatialReactComponent/PortalInstance.tsx
746
867
  var import_jsx_runtime2 = require("react/jsx-runtime");
747
868
  function renderJSXPortalInstance(inProps, elWidth, elHeight, inheritedPortalStyle, className) {
@@ -782,9 +903,7 @@ function handleOpenWindowDocumentClick(openedWindow) {
782
903
  let found = false;
783
904
  while (!found) {
784
905
  if (element && element.tagName == "A") {
785
- if (!element.onclick) {
786
- window.location.href = element.href;
787
- }
906
+ XRApp.getInstance().handleATag(e);
788
907
  return false;
789
908
  }
790
909
  if (element && element.parentElement) {
@@ -830,6 +949,7 @@ async function syncParentHeadToChild(childWindow, debugName) {
830
949
  if (debugName) {
831
950
  childWindow.document.title = debugName;
832
951
  }
952
+ childWindow.document.documentElement.className = document.documentElement.className;
833
953
  return Promise.all(styleLoadedPromises);
834
954
  }
835
955
  async function syncHeaderStyle(openedWindow, debugName) {
@@ -1100,10 +1220,12 @@ function PortalInstance(inProps) {
1100
1220
  "div",
1101
1221
  {
1102
1222
  className,
1223
+ "data-subportal-spatialid": spatialId,
1103
1224
  style: {
1104
1225
  position: "relative",
1105
1226
  width: `${domRect.width}px`,
1106
- height: `${domRect.height}px`
1227
+ height: `${domRect.height}px`,
1228
+ visibility: "hidden"
1107
1229
  }
1108
1230
  }
1109
1231
  ),
@@ -2058,6 +2180,15 @@ var import_react27 = require("react");
2058
2180
  var import_react22 = require("react");
2059
2181
  function useDetectLayoutDomUpdated(onDomUpdated) {
2060
2182
  const ref = (0, import_react22.useRef)(null);
2183
+ (0, import_react22.useEffect)(() => {
2184
+ const handleResize = () => {
2185
+ onDomUpdated();
2186
+ };
2187
+ window.addEventListener("resize", handleResize);
2188
+ return () => {
2189
+ window.removeEventListener("resize", handleResize);
2190
+ };
2191
+ }, []);
2061
2192
  (0, import_react22.useEffect)(() => {
2062
2193
  if (!ref.current) {
2063
2194
  console.warn("Ref is not attached to the DOM");
@@ -2230,8 +2361,8 @@ var Model3DNative = class {
2230
2361
  if (!this.entity || !this.spatialModel3DComponent) {
2231
2362
  return;
2232
2363
  }
2233
- const targetPosX = rect.x + (rect.width - rect.x) / 2;
2234
- const targetPosY = rect.y + (rect.height - rect.y) / 2 + window.scrollY;
2364
+ const targetPosX = rect.x + rect.width / 2;
2365
+ const targetPosY = rect.y + rect.height / 2 + window.scrollY;
2235
2366
  const { position, rotation, scale } = spatialTransform;
2236
2367
  const entity = this.entity;
2237
2368
  entity.transform.position.x = targetPosX + position.x;
@@ -3098,7 +3229,6 @@ var CSSModel3D = (0, import_react30.forwardRef)(CSSModel3DBase);
3098
3229
  CSSModel3D.displayName = "CSSModel3D";
3099
3230
 
3100
3231
  // src/spatial-react-components/Model/index.tsx
3101
- var import_model_viewer = require("@google/model-viewer");
3102
3232
  var import_jsx_runtime15 = require("react/jsx-runtime");
3103
3233
  function renderInModel3D(inProps, ref, modelUrl, placeHolder) {
3104
3234
  const { poster, ...props } = inProps;
@@ -3146,7 +3276,25 @@ function ModelBase(inProps, ref) {
3146
3276
  if (isWebEnv) {
3147
3277
  const myModelViewer = (0, import_react31.useRef)(null);
3148
3278
  const { className, style = {}, ...props2 } = inProps;
3279
+ let [modelViewerExists, setModelViewerExists] = (0, import_react31.useState)(false);
3149
3280
  (0, import_react31.useEffect)(() => {
3281
+ customElements.whenDefined("model-viewer").then(function() {
3282
+ setModelViewerExists(true);
3283
+ });
3284
+ }, []);
3285
+ (0, import_react31.useEffect)(() => {
3286
+ if (!modelViewerExists) {
3287
+ return;
3288
+ }
3289
+ myModelViewer.current.addEventListener("error", (event) => {
3290
+ if (event.detail.type == "loadfailure") {
3291
+ if (props2.onLoad) {
3292
+ props2.onLoad({
3293
+ target: { ready: false, currentSrc: gltfSourceURL }
3294
+ });
3295
+ }
3296
+ }
3297
+ });
3150
3298
  myModelViewer.current.addEventListener("load", (event) => {
3151
3299
  if (props2.onLoad) {
3152
3300
  props2.onLoad({
@@ -3184,7 +3332,7 @@ function ModelBase(inProps, ref) {
3184
3332
  });
3185
3333
  }
3186
3334
  });
3187
- }, []);
3335
+ }, [modelViewerExists]);
3188
3336
  (0, import_react31.useEffect)(() => {
3189
3337
  if (props2.contentMode !== void 0 && props2.contentMode !== "fit") {
3190
3338
  console.warn(
@@ -3202,7 +3350,7 @@ function ModelBase(inProps, ref) {
3202
3350
  );
3203
3351
  }
3204
3352
  }, [props2.contentMode, props2.resizable, props2.aspectRatio]);
3205
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className, style, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3353
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className, style, children: modelViewerExists ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3206
3354
  "model-viewer",
3207
3355
  {
3208
3356
  ref: myModelViewer,
@@ -3215,132 +3363,13 @@ function ModelBase(inProps, ref) {
3215
3363
  "touch-action": "pan-y",
3216
3364
  poster: props2.poster
3217
3365
  }
3218
- ) });
3366
+ ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, {}) });
3219
3367
  } else {
3220
3368
  return renderInModel3D(props, ref, usdzSourceURL, placeHolder);
3221
3369
  }
3222
3370
  }
3223
3371
  var Model = (0, import_react31.forwardRef)(ModelBase);
3224
3372
  Model.displayName = "Model";
3225
-
3226
- // src/XRApp.ts
3227
- var defaultSceneConfig = {
3228
- defaultSize: {
3229
- width: 900,
3230
- height: 700
3231
- },
3232
- resizability: "automatic"
3233
- };
3234
- var CONTEXT_WINDOW_URL = "webspatial://createWindowContext";
3235
- var originalOpen = window.open;
3236
- var XRApp = class _XRApp {
3237
- static instance;
3238
- static getInstance() {
3239
- if (!_XRApp.instance) {
3240
- _XRApp.instance = new _XRApp();
3241
- }
3242
- return _XRApp.instance;
3243
- }
3244
- handleATag(event) {
3245
- const targetElement = event.target;
3246
- if (targetElement.tagName === "A") {
3247
- const link = targetElement;
3248
- const target = link.target;
3249
- const url = link.href;
3250
- if (target && target !== "_self") {
3251
- event.preventDefault();
3252
- window.open(url, target);
3253
- }
3254
- }
3255
- }
3256
- init() {
3257
- ;
3258
- window.open = this.open;
3259
- document.addEventListener("click", this.handleATag);
3260
- }
3261
- deinit() {
3262
- ;
3263
- window.open = originalOpen;
3264
- document.removeEventListener("click", this.handleATag);
3265
- }
3266
- configMap = {};
3267
- // name=>config
3268
- getConfig(name) {
3269
- if (name === void 0 || !this.configMap[name]) return void 0;
3270
- return this.configMap[name];
3271
- }
3272
- async show(window2, cfg) {
3273
- try {
3274
- let session = getSession();
3275
- await session._createScene(
3276
- "Plain",
3277
- // only support Plain for now
3278
- {
3279
- sceneData: {
3280
- method: "showRoot",
3281
- sceneConfig: cfg,
3282
- // url: url,
3283
- window: window2
3284
- }
3285
- }
3286
- );
3287
- } catch (error) {
3288
- console.error(error);
3289
- }
3290
- }
3291
- open = (url, target, features) => {
3292
- const newWindow = originalOpen(url, target, features);
3293
- if (url === CONTEXT_WINDOW_URL) return newWindow;
3294
- if (target === "_self" || target === "_parent" || target === "_top") {
3295
- return newWindow;
3296
- }
3297
- let cnt = 2;
3298
- let timer = setInterval(async () => {
3299
- cnt -= 1;
3300
- if (cnt < 0) {
3301
- clearInterval(timer);
3302
- return;
3303
- }
3304
- if (newWindow._webSpatialID) {
3305
- clearInterval(timer);
3306
- let session = getSession();
3307
- if (!session) {
3308
- console.error("no session");
3309
- } else {
3310
- const cfg = this.getConfig(target);
3311
- try {
3312
- await session._createScene(
3313
- "Plain",
3314
- // only support Plain for now
3315
- {
3316
- sceneData: {
3317
- method: "createRoot",
3318
- sceneConfig: cfg,
3319
- url,
3320
- window: newWindow
3321
- // windowID: (newWindow as any)._webSpatialID,
3322
- // windowContainerID: (newWindow as any)._webSpatialGroupID,
3323
- }
3324
- }
3325
- );
3326
- if (typeof target === "string" && this.configMap[target]) {
3327
- delete this.configMap[target];
3328
- }
3329
- } catch (error) {
3330
- console.error(error);
3331
- }
3332
- }
3333
- }
3334
- }, 0);
3335
- return newWindow;
3336
- };
3337
- initScene(name, callback) {
3338
- this.configMap[name] = callback({ ...defaultSceneConfig });
3339
- }
3340
- };
3341
- function initScene(name, callback) {
3342
- return XRApp.getInstance().initScene(name, callback);
3343
- }
3344
3373
  // Annotate the CommonJS export names for ESM import in node:
3345
3374
  0 && (module.exports = {
3346
3375
  CSSSpatialDiv,