@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.
@@ -704,6 +704,127 @@ function parseCornerRadius(computedStyle) {
704
704
  import { createContext as createContext4 } from "react";
705
705
  var SpatialDebugNameContext = createContext4("");
706
706
 
707
+ // src/XRApp.ts
708
+ var defaultSceneConfig = {
709
+ defaultSize: {
710
+ width: 900,
711
+ height: 700
712
+ },
713
+ resizability: "automatic"
714
+ };
715
+ var CONTEXT_WINDOW_URL = "webspatial://createWindowContext";
716
+ var originalOpen = window.open;
717
+ var XRApp = class _XRApp {
718
+ static instance;
719
+ static getInstance() {
720
+ if (!_XRApp.instance) {
721
+ _XRApp.instance = new _XRApp();
722
+ }
723
+ return _XRApp.instance;
724
+ }
725
+ handleATag(event) {
726
+ const targetElement = event.target;
727
+ if (targetElement.tagName === "A") {
728
+ const link = targetElement;
729
+ const target = link.target;
730
+ const url = link.href;
731
+ if (target && target !== "_self") {
732
+ event.preventDefault();
733
+ window.open(url, target);
734
+ } else {
735
+ window.location.href = url;
736
+ }
737
+ }
738
+ }
739
+ init() {
740
+ ;
741
+ window.open = this.open;
742
+ document.addEventListener("click", this.handleATag);
743
+ }
744
+ deinit() {
745
+ ;
746
+ window.open = originalOpen;
747
+ document.removeEventListener("click", this.handleATag);
748
+ }
749
+ configMap = {};
750
+ // name=>config
751
+ getConfig(name) {
752
+ if (name === void 0 || !this.configMap[name]) return void 0;
753
+ return this.configMap[name];
754
+ }
755
+ async show(window2, cfg) {
756
+ try {
757
+ let session = getSession();
758
+ await session._createScene(
759
+ "Plain",
760
+ // only support Plain for now
761
+ {
762
+ sceneData: {
763
+ method: "showRoot",
764
+ sceneConfig: cfg,
765
+ // url: url,
766
+ window: window2
767
+ }
768
+ }
769
+ );
770
+ } catch (error) {
771
+ console.error(error);
772
+ }
773
+ }
774
+ open = (url, target, features) => {
775
+ const newWindow = originalOpen(url, target, features);
776
+ if (url === CONTEXT_WINDOW_URL) return newWindow;
777
+ if (target === "_self" || target === "_parent" || target === "_top") {
778
+ return newWindow;
779
+ }
780
+ let cnt = 2;
781
+ let timer = setInterval(async () => {
782
+ cnt -= 1;
783
+ if (cnt < 0) {
784
+ clearInterval(timer);
785
+ return;
786
+ }
787
+ if (newWindow._webSpatialID) {
788
+ clearInterval(timer);
789
+ let session = getSession();
790
+ if (!session) {
791
+ console.error("no session");
792
+ } else {
793
+ const cfg = this.getConfig(target);
794
+ try {
795
+ await session._createScene(
796
+ "Plain",
797
+ // only support Plain for now
798
+ {
799
+ sceneData: {
800
+ method: "createRoot",
801
+ sceneConfig: cfg,
802
+ url,
803
+ window: newWindow
804
+ // windowID: (newWindow as any)._webSpatialID,
805
+ // windowContainerID: (newWindow as any)._webSpatialGroupID,
806
+ }
807
+ }
808
+ );
809
+ if (typeof target === "string" && this.configMap[target]) {
810
+ delete this.configMap[target];
811
+ }
812
+ } catch (error) {
813
+ console.error(error);
814
+ }
815
+ }
816
+ }
817
+ }, 0);
818
+ return newWindow;
819
+ };
820
+ initScene(name, callback) {
821
+ this.configMap[name] = callback({ ...defaultSceneConfig });
822
+ }
823
+ };
824
+ function initScene(name, callback) {
825
+ return XRApp.getInstance().initScene(name, callback);
826
+ }
827
+
707
828
  // src/spatial-react-components/SpatialReactComponent/PortalInstance.tsx
708
829
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
709
830
  function renderJSXPortalInstance(inProps, elWidth, elHeight, inheritedPortalStyle, className) {
@@ -744,9 +865,7 @@ function handleOpenWindowDocumentClick(openedWindow) {
744
865
  let found = false;
745
866
  while (!found) {
746
867
  if (element && element.tagName == "A") {
747
- if (!element.onclick) {
748
- window.location.href = element.href;
749
- }
868
+ XRApp.getInstance().handleATag(e);
750
869
  return false;
751
870
  }
752
871
  if (element && element.parentElement) {
@@ -792,6 +911,7 @@ async function syncParentHeadToChild(childWindow, debugName) {
792
911
  if (debugName) {
793
912
  childWindow.document.title = debugName;
794
913
  }
914
+ childWindow.document.documentElement.className = document.documentElement.className;
795
915
  return Promise.all(styleLoadedPromises);
796
916
  }
797
917
  async function syncHeaderStyle(openedWindow, debugName) {
@@ -1062,10 +1182,12 @@ function PortalInstance(inProps) {
1062
1182
  "div",
1063
1183
  {
1064
1184
  className,
1185
+ "data-subportal-spatialid": spatialId,
1065
1186
  style: {
1066
1187
  position: "relative",
1067
1188
  width: `${domRect.width}px`,
1068
- height: `${domRect.height}px`
1189
+ height: `${domRect.height}px`,
1190
+ visibility: "hidden"
1069
1191
  }
1070
1192
  }
1071
1193
  ),
@@ -2027,7 +2149,8 @@ import {
2027
2149
  Children,
2028
2150
  useMemo as useMemo8,
2029
2151
  useRef as useRef12,
2030
- useEffect as useEffect16
2152
+ useEffect as useEffect16,
2153
+ useState as useState6
2031
2154
  } from "react";
2032
2155
 
2033
2156
  // src/spatial-react-components/Model3D/Model3D.tsx
@@ -2037,6 +2160,15 @@ import { forwardRef as forwardRef7, useContext as useContext8, useMemo as useMem
2037
2160
  import { useRef as useRef8, useEffect as useEffect9 } from "react";
2038
2161
  function useDetectLayoutDomUpdated(onDomUpdated) {
2039
2162
  const ref = useRef8(null);
2163
+ useEffect9(() => {
2164
+ const handleResize = () => {
2165
+ onDomUpdated();
2166
+ };
2167
+ window.addEventListener("resize", handleResize);
2168
+ return () => {
2169
+ window.removeEventListener("resize", handleResize);
2170
+ };
2171
+ }, []);
2040
2172
  useEffect9(() => {
2041
2173
  if (!ref.current) {
2042
2174
  console.warn("Ref is not attached to the DOM");
@@ -2209,8 +2341,8 @@ var Model3DNative = class {
2209
2341
  if (!this.entity || !this.spatialModel3DComponent) {
2210
2342
  return;
2211
2343
  }
2212
- const targetPosX = rect.x + (rect.width - rect.x) / 2;
2213
- const targetPosY = rect.y + (rect.height - rect.y) / 2 + window.scrollY;
2344
+ const targetPosX = rect.x + rect.width / 2;
2345
+ const targetPosY = rect.y + rect.height / 2 + window.scrollY;
2214
2346
  const { position, rotation, scale } = spatialTransform;
2215
2347
  const entity = this.entity;
2216
2348
  entity.transform.position.x = targetPosX + position.x;
@@ -3082,8 +3214,7 @@ var CSSModel3D = forwardRef8(CSSModel3DBase);
3082
3214
  CSSModel3D.displayName = "CSSModel3D";
3083
3215
 
3084
3216
  // src/spatial-react-components/Model/index.tsx
3085
- import "@google/model-viewer";
3086
- import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
3217
+ import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
3087
3218
  function renderInModel3D(inProps, ref, modelUrl, placeHolder) {
3088
3219
  const { poster, ...props } = inProps;
3089
3220
  return /* @__PURE__ */ jsxs7(CSSModel3D, { modelUrl, ...props, ref, children: [
@@ -3130,7 +3261,25 @@ function ModelBase(inProps, ref) {
3130
3261
  if (isWebEnv) {
3131
3262
  const myModelViewer = useRef12(null);
3132
3263
  const { className, style = {}, ...props2 } = inProps;
3264
+ let [modelViewerExists, setModelViewerExists] = useState6(false);
3133
3265
  useEffect16(() => {
3266
+ customElements.whenDefined("model-viewer").then(function() {
3267
+ setModelViewerExists(true);
3268
+ });
3269
+ }, []);
3270
+ useEffect16(() => {
3271
+ if (!modelViewerExists) {
3272
+ return;
3273
+ }
3274
+ myModelViewer.current.addEventListener("error", (event) => {
3275
+ if (event.detail.type == "loadfailure") {
3276
+ if (props2.onLoad) {
3277
+ props2.onLoad({
3278
+ target: { ready: false, currentSrc: gltfSourceURL }
3279
+ });
3280
+ }
3281
+ }
3282
+ });
3134
3283
  myModelViewer.current.addEventListener("load", (event) => {
3135
3284
  if (props2.onLoad) {
3136
3285
  props2.onLoad({
@@ -3168,7 +3317,7 @@ function ModelBase(inProps, ref) {
3168
3317
  });
3169
3318
  }
3170
3319
  });
3171
- }, []);
3320
+ }, [modelViewerExists]);
3172
3321
  useEffect16(() => {
3173
3322
  if (props2.contentMode !== void 0 && props2.contentMode !== "fit") {
3174
3323
  console.warn(
@@ -3186,7 +3335,7 @@ function ModelBase(inProps, ref) {
3186
3335
  );
3187
3336
  }
3188
3337
  }, [props2.contentMode, props2.resizable, props2.aspectRatio]);
3189
- return /* @__PURE__ */ jsx14("div", { ref, className, style, children: /* @__PURE__ */ jsx14(
3338
+ return /* @__PURE__ */ jsx14("div", { ref, className, style, children: modelViewerExists ? /* @__PURE__ */ jsx14(
3190
3339
  "model-viewer",
3191
3340
  {
3192
3341
  ref: myModelViewer,
@@ -3199,132 +3348,13 @@ function ModelBase(inProps, ref) {
3199
3348
  "touch-action": "pan-y",
3200
3349
  poster: props2.poster
3201
3350
  }
3202
- ) });
3351
+ ) : /* @__PURE__ */ jsx14(Fragment5, {}) });
3203
3352
  } else {
3204
3353
  return renderInModel3D(props, ref, usdzSourceURL, placeHolder);
3205
3354
  }
3206
3355
  }
3207
3356
  var Model = forwardRef9(ModelBase);
3208
3357
  Model.displayName = "Model";
3209
-
3210
- // src/XRApp.ts
3211
- var defaultSceneConfig = {
3212
- defaultSize: {
3213
- width: 900,
3214
- height: 700
3215
- },
3216
- resizability: "automatic"
3217
- };
3218
- var CONTEXT_WINDOW_URL = "webspatial://createWindowContext";
3219
- var originalOpen = window.open;
3220
- var XRApp = class _XRApp {
3221
- static instance;
3222
- static getInstance() {
3223
- if (!_XRApp.instance) {
3224
- _XRApp.instance = new _XRApp();
3225
- }
3226
- return _XRApp.instance;
3227
- }
3228
- handleATag(event) {
3229
- const targetElement = event.target;
3230
- if (targetElement.tagName === "A") {
3231
- const link = targetElement;
3232
- const target = link.target;
3233
- const url = link.href;
3234
- if (target && target !== "_self") {
3235
- event.preventDefault();
3236
- window.open(url, target);
3237
- }
3238
- }
3239
- }
3240
- init() {
3241
- ;
3242
- window.open = this.open;
3243
- document.addEventListener("click", this.handleATag);
3244
- }
3245
- deinit() {
3246
- ;
3247
- window.open = originalOpen;
3248
- document.removeEventListener("click", this.handleATag);
3249
- }
3250
- configMap = {};
3251
- // name=>config
3252
- getConfig(name) {
3253
- if (name === void 0 || !this.configMap[name]) return void 0;
3254
- return this.configMap[name];
3255
- }
3256
- async show(window2, cfg) {
3257
- try {
3258
- let session = getSession();
3259
- await session._createScene(
3260
- "Plain",
3261
- // only support Plain for now
3262
- {
3263
- sceneData: {
3264
- method: "showRoot",
3265
- sceneConfig: cfg,
3266
- // url: url,
3267
- window: window2
3268
- }
3269
- }
3270
- );
3271
- } catch (error) {
3272
- console.error(error);
3273
- }
3274
- }
3275
- open = (url, target, features) => {
3276
- const newWindow = originalOpen(url, target, features);
3277
- if (url === CONTEXT_WINDOW_URL) return newWindow;
3278
- if (target === "_self" || target === "_parent" || target === "_top") {
3279
- return newWindow;
3280
- }
3281
- let cnt = 2;
3282
- let timer = setInterval(async () => {
3283
- cnt -= 1;
3284
- if (cnt < 0) {
3285
- clearInterval(timer);
3286
- return;
3287
- }
3288
- if (newWindow._webSpatialID) {
3289
- clearInterval(timer);
3290
- let session = getSession();
3291
- if (!session) {
3292
- console.error("no session");
3293
- } else {
3294
- const cfg = this.getConfig(target);
3295
- try {
3296
- await session._createScene(
3297
- "Plain",
3298
- // only support Plain for now
3299
- {
3300
- sceneData: {
3301
- method: "createRoot",
3302
- sceneConfig: cfg,
3303
- url,
3304
- window: newWindow
3305
- // windowID: (newWindow as any)._webSpatialID,
3306
- // windowContainerID: (newWindow as any)._webSpatialGroupID,
3307
- }
3308
- }
3309
- );
3310
- if (typeof target === "string" && this.configMap[target]) {
3311
- delete this.configMap[target];
3312
- }
3313
- } catch (error) {
3314
- console.error(error);
3315
- }
3316
- }
3317
- }
3318
- }, 0);
3319
- return newWindow;
3320
- };
3321
- initScene(name, callback) {
3322
- this.configMap[name] = callback({ ...defaultSceneConfig });
3323
- }
3324
- };
3325
- function initScene(name, callback) {
3326
- return XRApp.getInstance().initScene(name, callback);
3327
- }
3328
3358
  export {
3329
3359
  CSSSpatialDiv,
3330
3360
  CSSSpatialPrimitive,