@neurodyn/react-model-viewer 0.0.7 → 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.
package/dist/index.d.ts CHANGED
@@ -21,7 +21,7 @@ declare type DialogProps = React_3.ComponentProps<typeof DialogPrimitive.Root>
21
21
  */
22
22
  export declare type LaunchArOverride = (target: ArLaunchTarget) => boolean | Promise<boolean>;
23
23
 
24
- export declare function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, launchAr, sizeType, dimensionAxes, layout, background, viewerSurface, className, ...props }: ModelViewerProps & React_2.ComponentProps<'div'>): JSX.Element;
24
+ export declare function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, lang, handoffUrl, launchAr, sizeType, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, layout, background, viewerSurface, className, ...props }: ModelViewerProps & React_2.ComponentProps<'div'>): JSX.Element;
25
25
 
26
26
  export declare type ModelViewerArExperience = 'advanced' | 'standard';
27
27
 
@@ -32,6 +32,8 @@ export declare function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, legacyA
32
32
  declare interface ModelViewerDialogProps extends Pick<ModelViewerRootProps, 'apiBaseUrl' | 'apiKey' | 'dimensionAxes' | 'handoffUrl' | 'hid' | 'initialWidgetSessionToken' | 'legacyApiBaseUrl' | 'sizeType' | 'tinuuid'>, Omit<DialogProps, 'children'> {
33
33
  }
34
34
 
35
+ export declare type ModelViewerLanguage = 'en' | 'ru';
36
+
35
37
  declare type ModelViewerLayout = 'default' | 'model';
36
38
 
37
39
  export declare interface ModelViewerProps extends Omit<ModelViewerRootProps, 'showDialogCloseButton'> {
@@ -56,6 +58,8 @@ declare interface ModelViewerRootProps {
56
58
  mode?: ModelViewerWidgetMode;
57
59
  /** Existing token used to preserve the same widget session across a handoff. */
58
60
  initialWidgetSessionToken?: string;
61
+ /** UI language. Defaults to English. */
62
+ lang?: ModelViewerLanguage;
59
63
  /** Hosted viewer URL encoded into the desktop-to-mobile QR handoff. */
60
64
  handoffUrl?: string;
61
65
  /** Lets the host open its own AR experience instead of the native handoff. */
package/dist/index.js CHANGED
@@ -6148,7 +6148,10 @@ function QRCode({ data, foreground, background, robustness = 'M', className, ...
6148
6148
  });
6149
6149
  }
6150
6150
  const MODEL_VIEWER_URL = "https://integrations.vizbl.com/model-viewer";
6151
- const AR_DEVICE_REQUIREMENTS_DISCLAIMER = '*Requires AR-supported device and browser. We recommend iOS 12 or later with Safari, or Android 7.0 or later with Chrome.';
6151
+ const AR_DEVICE_REQUIREMENTS_DISCLAIMER = {
6152
+ en: '*Requires AR-supported device and browser. We recommend iOS 12 or later with Safari, or Android 7.0 or later with Chrome.',
6153
+ ru: '*Требуется устройство и браузер с поддержкой AR. Рекомендуем iOS 12 или новее с Safari либо Android 7.0 или новее с Chrome.'
6154
+ };
6152
6155
  const DEFAULT_API_TIMEOUT = 30000;
6153
6156
  function createDefaultClient(defaultBaseURL) {
6154
6157
  return axios.create({
@@ -6842,7 +6845,7 @@ function isCanvasBlank(modelViewerEl) {
6842
6845
  return true;
6843
6846
  }
6844
6847
  const ModelViewerContext = /*#__PURE__*/ createContext(null);
6845
- function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExperience, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, hid, launchAr, layout, background, sizeType, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, viewerSurface }) {
6848
+ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExperience, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, lang, handoffUrl, hid, launchAr, layout, background, sizeType, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, viewerSurface }) {
6846
6849
  const { object, material, error, isLoading, setMaterialHid: setObjectMaterialHid, widgetSession } = useObjectData(tinuuid, hid, {
6847
6850
  apiBaseUrl,
6848
6851
  apiKey,
@@ -6967,6 +6970,7 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
6967
6970
  layout,
6968
6971
  background,
6969
6972
  mode,
6973
+ lang,
6970
6974
  sizeType,
6971
6975
  dimensionAxes,
6972
6976
  cameraOrbit,
@@ -6997,6 +7001,7 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
6997
7001
  layout,
6998
7002
  background,
6999
7003
  mode,
7004
+ lang,
7000
7005
  sizeType,
7001
7006
  dimensionAxes,
7002
7007
  cameraOrbit,
@@ -7120,7 +7125,7 @@ async function flushWidgetEvent(eventRequest) {
7120
7125
  });
7121
7126
  }
7122
7127
  function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7123
- const { apiKey, appClipBundleId, arExperience, containerEl, handoffUrl, isLoading, isModelLoading, launchAr, material, mode, modelViewerEl, object, tinuuid, trackEvent, widgetSession } = useModelViewer();
7128
+ const { apiKey, appClipBundleId, arExperience, containerEl, handoffUrl, isLoading, isModelLoading, lang, launchAr, material, mode, modelViewerEl, object, tinuuid, trackEvent, widgetSession } = useModelViewer();
7124
7129
  const [handoffSession, setHandoffSession] = useState(null);
7125
7130
  const [open, setOpen] = useState(false);
7126
7131
  const autoLaunchKeyRef = useRef(null);
@@ -7247,7 +7252,7 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7247
7252
  size: size,
7248
7253
  disabled: disabled || isDisabled,
7249
7254
  onClick: handleButtonClick,
7250
- children: "View in place"
7255
+ children: 'ru' === lang ? 'Смотреть в интерьере' : 'View in place'
7251
7256
  }),
7252
7257
  url && /*#__PURE__*/ jsx(Dialog, {
7253
7258
  open: open,
@@ -7266,17 +7271,17 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7266
7271
  }),
7267
7272
  /*#__PURE__*/ jsx("p", {
7268
7273
  className: "text-center text-lg font-medium text-text-sub",
7269
- children: "Scan the QR code with your phone or tablet to view the object in your interior."
7274
+ children: 'ru' === lang ? 'Отсканируйте QR-код телефоном или планшетом, чтобы посмотреть объект в своём интерьере.' : 'Scan the QR code with your phone or tablet to view the object in your interior.'
7270
7275
  }),
7271
7276
  /*#__PURE__*/ jsx("p", {
7272
7277
  className: "text-center text-xs text-text-light",
7273
- children: AR_DEVICE_REQUIREMENTS_DISCLAIMER
7278
+ children: AR_DEVICE_REQUIREMENTS_DISCLAIMER[lang]
7274
7279
  }),
7275
7280
  /*#__PURE__*/ jsx(DialogClose, {
7276
7281
  asChild: true,
7277
7282
  children: /*#__PURE__*/ jsx(button_Button, {
7278
7283
  size: "lg",
7279
- children: "Close"
7284
+ children: 'ru' === lang ? 'Закрыть' : 'Close'
7280
7285
  })
7281
7286
  })
7282
7287
  ]
@@ -7478,6 +7483,7 @@ const Hotspots = /*#__PURE__*/ memo(({ hiddenHotspots, isVisible, labels })=>{
7478
7483
  });
7479
7484
  });
7480
7485
  function LogoSign({ className, ...props }) {
7486
+ const { lang } = useModelViewer();
7481
7487
  return /*#__PURE__*/ jsxs("div", {
7482
7488
  className: utils_cn('group inline-flex gap-2 text-sm text-muted-foreground transition-colors duration-200 ease-in-out hover:text-text-dark', className),
7483
7489
  ...props,
@@ -7488,7 +7494,7 @@ function LogoSign({ className, ...props }) {
7488
7494
  className: "size-4.25 text-icons-white"
7489
7495
  })
7490
7496
  }),
7491
- "Powered by Vizbl"
7497
+ `Powered by ${'ru' === lang ? 'Arizo' : 'Vizbl'}`
7492
7498
  ]
7493
7499
  });
7494
7500
  }
@@ -7620,7 +7626,7 @@ function RadioGroupItem({ className, variant = 'default', ...props }) {
7620
7626
  });
7621
7627
  }
7622
7628
  function MaterialVariants() {
7623
- const { object, material, setMaterialHid } = useModelViewer();
7629
+ const { object, material, lang, setMaterialHid } = useModelViewer();
7624
7630
  const materials = object?.materials ?? [];
7625
7631
  if (!object || materials.length < 2) return null;
7626
7632
  return /*#__PURE__*/ jsx(Card, {
@@ -7643,7 +7649,7 @@ function MaterialVariants() {
7643
7649
  src: option.previews?.[0]?.subRes?.small ?? option.previews?.[0]?.url,
7644
7650
  width: 80,
7645
7651
  height: 80,
7646
- alt: option.name ?? object.name ?? 'Material preview',
7652
+ alt: option.name ?? object.name ?? ('ru' === lang ? 'Превью материала' : 'Material preview'),
7647
7653
  className: "size-20 object-cover @max-xl:size-12"
7648
7654
  })
7649
7655
  }),
@@ -7660,12 +7666,21 @@ function MaterialVariants() {
7660
7666
  });
7661
7667
  }
7662
7668
  const viewerErrorTitle = {
7663
- forbidden: 'Viewer unavailable for this domain',
7664
- 'not-found': 'Object not found',
7665
- unauthorized: 'Invalid API key',
7666
- 'payment-required': 'Viewer temporarily unavailable'
7669
+ en: {
7670
+ forbidden: 'Viewer unavailable for this domain',
7671
+ 'not-found': 'Object not found',
7672
+ unauthorized: 'Invalid API key',
7673
+ 'payment-required': 'Viewer temporarily unavailable'
7674
+ },
7675
+ ru: {
7676
+ forbidden: 'Просмотр недоступен для этого домена',
7677
+ 'not-found': 'Объект не найден',
7678
+ unauthorized: 'Неверный API-ключ',
7679
+ 'payment-required': 'Просмотр временно недоступен'
7680
+ }
7667
7681
  };
7668
7682
  function ViewerErrorState({ variant, showDialogCloseButton = false }) {
7683
+ const { lang } = useModelViewer();
7669
7684
  return /*#__PURE__*/ jsxs("div", {
7670
7685
  className: "relative z-30 flex size-full flex-col items-center justify-center gap-4 bg-radial from-background-containers to-background-base-2 p-4 text-center",
7671
7686
  children: [
@@ -7674,13 +7689,13 @@ function ViewerErrorState({ variant, showDialogCloseButton = false }) {
7674
7689
  }),
7675
7690
  /*#__PURE__*/ jsx("h2", {
7676
7691
  className: "typo-base-16 font-medium text-text-dark",
7677
- children: viewerErrorTitle[variant]
7692
+ children: viewerErrorTitle[lang][variant]
7678
7693
  }),
7679
7694
  showDialogCloseButton && /*#__PURE__*/ jsx(DialogClose, {
7680
7695
  asChild: true,
7681
7696
  children: /*#__PURE__*/ jsx(button_Button, {
7682
7697
  variant: "secondary",
7683
- children: "Close"
7698
+ children: 'ru' === lang ? 'Закрыть' : 'Close'
7684
7699
  })
7685
7700
  })
7686
7701
  ]
@@ -7851,7 +7866,7 @@ function useDimensions({ isVisible, axes }) {
7851
7866
  };
7852
7867
  }
7853
7868
  function ModelViewerContainer({ showDialogCloseButton = false }) {
7854
- const { glbUrl, isModelLoading, object, previewUrl, state, setContainerEl, setModelViewerEl, usdzUrl, layout, background, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, trackEvent } = useModelViewer();
7869
+ const { glbUrl, isModelLoading, object, previewUrl, state, setContainerEl, setModelViewerEl, usdzUrl, layout, background, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, lang, trackEvent } = useModelViewer();
7855
7870
  const [isDimensionsVisible, setDimensionsVisible] = useState(false);
7856
7871
  const isModelLayout = 'model' === layout;
7857
7872
  const showViewerLoader = 'loading' === state || 'ready' === state && isModelLoading;
@@ -7938,7 +7953,7 @@ function ModelViewerContainer({ showDialogCloseButton = false }) {
7938
7953
  size: "lg",
7939
7954
  variant: "secondary",
7940
7955
  disabled: !canToggleDimensions,
7941
- "aria-label": "Toggle dimensions",
7956
+ "aria-label": 'ru' === lang ? 'Показать размеры' : 'Toggle dimensions',
7942
7957
  "aria-pressed": isDimensionsVisible,
7943
7958
  onClick: ()=>{
7944
7959
  setDimensionsVisible((current)=>!current);
@@ -7951,7 +7966,7 @@ function ModelViewerContainer({ showDialogCloseButton = false }) {
7951
7966
  className: "size-6"
7952
7967
  }),
7953
7968
  /*#__PURE__*/ jsx("span", {
7954
- children: "Dimensions"
7969
+ children: 'ru' === lang ? 'Размеры' : 'Dimensions'
7955
7970
  })
7956
7971
  ]
7957
7972
  }),
@@ -7990,7 +8005,7 @@ const root_queryClient = new QueryClient({
7990
8005
  }
7991
8006
  }
7992
8007
  });
7993
- function ModelViewerRoot({ tinuuid, apiKey, appClipBundleId = 'com.us.vizbl.Clip', arExperience, hid, apiBaseUrl = "https://api.vizbl.com", legacyApiBaseUrl = "https://api.vizbl.com/v1", mode = 'embedded-3d-viewer', initialWidgetSessionToken, handoffUrl = "https://integrations.vizbl.com/model-viewer", launchAr, sizeType = 'cm', dimensionAxes = ALL_DIMENSION_AXES, cameraOrbit, minCameraOrbit, maxCameraOrbit, layout = 'default', background = 'default', showDialogCloseButton = false, viewerSurface = 'inline' }) {
8008
+ function ModelViewerRoot({ tinuuid, apiKey, appClipBundleId = 'com.us.vizbl.Clip', arExperience, hid, apiBaseUrl = "https://api.vizbl.com", legacyApiBaseUrl = "https://api.vizbl.com/v1", mode = 'embedded-3d-viewer', initialWidgetSessionToken, lang = 'en', handoffUrl = "https://integrations.vizbl.com/model-viewer", launchAr, sizeType = 'cm', dimensionAxes = ALL_DIMENSION_AXES, cameraOrbit, minCameraOrbit, maxCameraOrbit, layout = 'default', background = 'default', showDialogCloseButton = false, viewerSurface = 'inline' }) {
7994
8009
  const normalizedApiKey = normalizeApiKey(apiKey);
7995
8010
  return /*#__PURE__*/ jsx(QueryClientProvider, {
7996
8011
  client: root_queryClient,
@@ -8003,6 +8018,7 @@ function ModelViewerRoot({ tinuuid, apiKey, appClipBundleId = 'com.us.vizbl.Clip
8003
8018
  legacyApiBaseUrl: legacyApiBaseUrl,
8004
8019
  mode: mode,
8005
8020
  initialWidgetSessionToken: initialWidgetSessionToken,
8021
+ lang: lang,
8006
8022
  handoffUrl: handoffUrl,
8007
8023
  hid: hid,
8008
8024
  launchAr: launchAr,
@@ -8087,7 +8103,7 @@ function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, legacyApiBaseUrl, init
8087
8103
  ]
8088
8104
  });
8089
8105
  }
8090
- function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, launchAr, sizeType, dimensionAxes, layout, background, viewerSurface, className, ...props }) {
8106
+ function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, lang, handoffUrl, launchAr, sizeType, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, layout, background, viewerSurface, className, ...props }) {
8091
8107
  const [container, setContainer] = useState(null);
8092
8108
  return /*#__PURE__*/ jsxs(Fragment, {
8093
8109
  children: [
@@ -8124,11 +8140,15 @@ function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiB
8124
8140
  legacyApiBaseUrl: legacyApiBaseUrl,
8125
8141
  mode: mode,
8126
8142
  initialWidgetSessionToken: initialWidgetSessionToken,
8143
+ lang: lang,
8127
8144
  handoffUrl: handoffUrl,
8128
8145
  hid: hid,
8129
8146
  launchAr: launchAr,
8130
8147
  sizeType: sizeType,
8131
8148
  dimensionAxes: dimensionAxes,
8149
+ cameraOrbit: cameraOrbit,
8150
+ minCameraOrbit: minCameraOrbit,
8151
+ maxCameraOrbit: maxCameraOrbit,
8132
8152
  layout: layout,
8133
8153
  background: background,
8134
8154
  viewerSurface: viewerSurface
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neurodyn/react-model-viewer",
3
3
  "type": "module",
4
- "version": "0.0.7",
4
+ "version": "0.0.9",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },