@cavegiant/cave-world-r3f 1.0.0
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 +25 -0
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/dist/core/connector-label/readiness.d.ts +11 -0
- package/dist/core/connector-label/readiness.d.ts.map +1 -0
- package/dist/core/connector-label/readiness.js +31 -0
- package/dist/core/connector-label/readiness.js.map +1 -0
- package/dist/core/connector-label/types.d.ts +64 -0
- package/dist/core/connector-label/types.d.ts.map +1 -0
- package/dist/core/connector-label/types.js +47 -0
- package/dist/core/connector-label/types.js.map +1 -0
- package/dist/core/context/cave-world-context.d.ts +96 -0
- package/dist/core/context/cave-world-context.d.ts.map +1 -0
- package/dist/core/context/cave-world-context.js +100 -0
- package/dist/core/context/cave-world-context.js.map +1 -0
- package/dist/core/errors.d.ts +34 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +17 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events/event-bus.d.ts +122 -0
- package/dist/core/events/event-bus.d.ts.map +1 -0
- package/dist/core/events/event-bus.js +62 -0
- package/dist/core/events/event-bus.js.map +1 -0
- package/dist/core/hooks/use-cave-event.d.ts +13 -0
- package/dist/core/hooks/use-cave-event.d.ts.map +1 -0
- package/dist/core/hooks/use-cave-event.js +12 -0
- package/dist/core/hooks/use-cave-event.js.map +1 -0
- package/dist/core/i18n/messages.d.ts +82 -0
- package/dist/core/i18n/messages.d.ts.map +1 -0
- package/dist/core/i18n/messages.js +131 -0
- package/dist/core/i18n/messages.js.map +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +47 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logging/logger.d.ts +29 -0
- package/dist/core/logging/logger.d.ts.map +1 -0
- package/dist/core/logging/logger.js +47 -0
- package/dist/core/logging/logger.js.map +1 -0
- package/dist/core/registry/component-registry.d.ts +41 -0
- package/dist/core/registry/component-registry.d.ts.map +1 -0
- package/dist/core/registry/component-registry.js +34 -0
- package/dist/core/registry/component-registry.js.map +1 -0
- package/dist/core/registry/object-registry.d.ts +38 -0
- package/dist/core/registry/object-registry.d.ts.map +1 -0
- package/dist/core/registry/object-registry.js +32 -0
- package/dist/core/registry/object-registry.js.map +1 -0
- package/dist/explore/cave-explore.d.ts +85 -0
- package/dist/explore/cave-explore.d.ts.map +1 -0
- package/dist/explore/cave-explore.js +204 -0
- package/dist/explore/cave-explore.js.map +1 -0
- package/dist/explore/cave-orbit-viewer.d.ts +76 -0
- package/dist/explore/cave-orbit-viewer.d.ts.map +1 -0
- package/dist/explore/cave-orbit-viewer.js +123 -0
- package/dist/explore/cave-orbit-viewer.js.map +1 -0
- package/dist/explore/characters/character-configs.d.ts +38 -0
- package/dist/explore/characters/character-configs.d.ts.map +1 -0
- package/dist/explore/characters/character-configs.js +45 -0
- package/dist/explore/characters/character-configs.js.map +1 -0
- package/dist/explore/characters/character-controls.d.ts +44 -0
- package/dist/explore/characters/character-controls.d.ts.map +1 -0
- package/dist/explore/characters/character-pose.d.ts +19 -0
- package/dist/explore/characters/character-pose.d.ts.map +1 -0
- package/dist/explore/characters/character-pose.js +13 -0
- package/dist/explore/characters/character-pose.js.map +1 -0
- package/dist/explore/characters/local-character-model.d.ts +53 -0
- package/dist/explore/characters/local-character-model.d.ts.map +1 -0
- package/dist/explore/characters/local-character-model.js +36 -0
- package/dist/explore/characters/local-character-model.js.map +1 -0
- package/dist/explore/characters/mixamo-style-bone-map.d.ts +9 -0
- package/dist/explore/characters/mixamo-style-bone-map.d.ts.map +1 -0
- package/dist/explore/characters/mixamo-style-bone-map.js +28 -0
- package/dist/explore/characters/mixamo-style-bone-map.js.map +1 -0
- package/dist/explore/characters/remote-character-controller.d.ts +38 -0
- package/dist/explore/characters/remote-character-controller.d.ts.map +1 -0
- package/dist/explore/characters/remote-character-controller.js +135 -0
- package/dist/explore/characters/remote-character-controller.js.map +1 -0
- package/dist/explore/characters/remote-character.d.ts +19 -0
- package/dist/explore/characters/remote-character.d.ts.map +1 -0
- package/dist/explore/characters/remote-character.js +63 -0
- package/dist/explore/characters/remote-character.js.map +1 -0
- package/dist/explore/connected-spaces-renderer.d.ts +16 -0
- package/dist/explore/connected-spaces-renderer.d.ts.map +1 -0
- package/dist/explore/connected-spaces-renderer.js +103 -0
- package/dist/explore/connected-spaces-renderer.js.map +1 -0
- package/dist/explore/hooks/use-action-shortcuts.d.ts +16 -0
- package/dist/explore/hooks/use-action-shortcuts.d.ts.map +1 -0
- package/dist/explore/hooks/use-action-shortcuts.js +23 -0
- package/dist/explore/hooks/use-action-shortcuts.js.map +1 -0
- package/dist/explore/hooks/use-active-space-notify.d.ts +11 -0
- package/dist/explore/hooks/use-active-space-notify.d.ts.map +1 -0
- package/dist/explore/hooks/use-active-space-notify.js +17 -0
- package/dist/explore/hooks/use-active-space-notify.js.map +1 -0
- package/dist/explore/hooks/use-character-sync.d.ts +46 -0
- package/dist/explore/hooks/use-character-sync.d.ts.map +1 -0
- package/dist/explore/hooks/use-character-sync.js +72 -0
- package/dist/explore/hooks/use-character-sync.js.map +1 -0
- package/dist/explore/hooks/use-connector-preloader.d.ts +20 -0
- package/dist/explore/hooks/use-connector-preloader.d.ts.map +1 -0
- package/dist/explore/hooks/use-connector-preloader.js +78 -0
- package/dist/explore/hooks/use-connector-preloader.js.map +1 -0
- package/dist/explore/hooks/use-connector-transitions.d.ts +31 -0
- package/dist/explore/hooks/use-connector-transitions.d.ts.map +1 -0
- package/dist/explore/hooks/use-connector-transitions.js +63 -0
- package/dist/explore/hooks/use-connector-transitions.js.map +1 -0
- package/dist/explore/hooks/use-explore-actions.d.ts +17 -0
- package/dist/explore/hooks/use-explore-actions.d.ts.map +1 -0
- package/dist/explore/hooks/use-explore-actions.js +134 -0
- package/dist/explore/hooks/use-explore-actions.js.map +1 -0
- package/dist/explore/hooks/use-load-error-notify.d.ts +11 -0
- package/dist/explore/hooks/use-load-error-notify.d.ts.map +1 -0
- package/dist/explore/hooks/use-load-error-notify.js +18 -0
- package/dist/explore/hooks/use-load-error-notify.js.map +1 -0
- package/dist/explore/hooks/use-primary-space-loader.d.ts +24 -0
- package/dist/explore/hooks/use-primary-space-loader.d.ts.map +1 -0
- package/dist/explore/hooks/use-primary-space-loader.js +29 -0
- package/dist/explore/hooks/use-primary-space-loader.js.map +1 -0
- package/dist/explore/index.d.ts +37 -0
- package/dist/explore/index.d.ts.map +1 -0
- package/dist/explore/index.js +107 -0
- package/dist/explore/index.js.map +1 -0
- package/dist/explore/loaders/cave-loader.d.ts +58 -0
- package/dist/explore/loaders/cave-loader.d.ts.map +1 -0
- package/dist/explore/loaders/cave-loader.js +79 -0
- package/dist/explore/loaders/cave-loader.js.map +1 -0
- package/dist/explore/math/space-transforms.d.ts +49 -0
- package/dist/explore/math/space-transforms.d.ts.map +1 -0
- package/dist/explore/math/space-transforms.js +54 -0
- package/dist/explore/math/space-transforms.js.map +1 -0
- package/dist/explore/overlays/action-bubble.d.ts +8 -0
- package/dist/explore/overlays/action-bubble.d.ts.map +1 -0
- package/dist/explore/overlays/action-bubble.js +18 -0
- package/dist/explore/overlays/action-bubble.js.map +1 -0
- package/dist/explore/overlays/action-panel.d.ts +12 -0
- package/dist/explore/overlays/action-panel.d.ts.map +1 -0
- package/dist/explore/overlays/action-panel.js +69 -0
- package/dist/explore/overlays/action-panel.js.map +1 -0
- package/dist/explore/overlays/connector-label-beacon.d.ts +11 -0
- package/dist/explore/overlays/connector-label-beacon.d.ts.map +1 -0
- package/dist/explore/overlays/connector-label-beacon.js +38 -0
- package/dist/explore/overlays/connector-label-beacon.js.map +1 -0
- package/dist/explore/overlays/connector-label-tag-shell.d.ts +16 -0
- package/dist/explore/overlays/connector-label-tag-shell.d.ts.map +1 -0
- package/dist/explore/overlays/connector-label-tag-shell.js +18 -0
- package/dist/explore/overlays/connector-label-tag-shell.js.map +1 -0
- package/dist/explore/overlays/detail-window.d.ts +9 -0
- package/dist/explore/overlays/detail-window.d.ts.map +1 -0
- package/dist/explore/overlays/detail-window.js +92 -0
- package/dist/explore/overlays/detail-window.js.map +1 -0
- package/dist/explore/overlays/explore-helper.d.ts +44 -0
- package/dist/explore/overlays/explore-helper.d.ts.map +1 -0
- package/dist/explore/overlays/explore-helper.js +57 -0
- package/dist/explore/overlays/explore-helper.js.map +1 -0
- package/dist/explore/overlays/icons.d.ts +16 -0
- package/dist/explore/overlays/icons.d.ts.map +1 -0
- package/dist/explore/overlays/icons.js +34 -0
- package/dist/explore/overlays/icons.js.map +1 -0
- package/dist/explore/overlays/space-load-error-overlay.d.ts +27 -0
- package/dist/explore/overlays/space-load-error-overlay.d.ts.map +1 -0
- package/dist/explore/overlays/space-load-error-overlay.js +24 -0
- package/dist/explore/overlays/space-load-error-overlay.js.map +1 -0
- package/dist/explore/services/websocket.service.d.ts +180 -0
- package/dist/explore/services/websocket.service.d.ts.map +1 -0
- package/dist/explore/services/websocket.service.js +187 -0
- package/dist/explore/services/websocket.service.js.map +1 -0
- package/dist/explore/simple-character.d.ts +46 -0
- package/dist/explore/simple-character.d.ts.map +1 -0
- package/dist/explore/simple-character.js +119 -0
- package/dist/explore/simple-character.js.map +1 -0
- package/dist/explore/stores/action-prompt.store.d.ts +27 -0
- package/dist/explore/stores/action-prompt.store.d.ts.map +1 -0
- package/dist/explore/stores/action-prompt.store.js +14 -0
- package/dist/explore/stores/action-prompt.store.js.map +1 -0
- package/dist/explore/stores/cave-explore.store.d.ts +77 -0
- package/dist/explore/stores/cave-explore.store.d.ts.map +1 -0
- package/dist/explore/stores/cave-explore.store.js +66 -0
- package/dist/explore/stores/cave-explore.store.js.map +1 -0
- package/dist/explore/stores/explore-context.d.ts +35 -0
- package/dist/explore/stores/explore-context.d.ts.map +1 -0
- package/dist/explore/stores/explore-context.js +43 -0
- package/dist/explore/stores/explore-context.js.map +1 -0
- package/dist/explore/styles/cave-world-css.d.ts +10 -0
- package/dist/explore/styles/cave-world-css.d.ts.map +1 -0
- package/dist/explore/styles/cave-world-css.js +935 -0
- package/dist/explore/styles/cave-world-css.js.map +1 -0
- package/dist/explore/styles/inject.d.ts +32 -0
- package/dist/explore/styles/inject.d.ts.map +1 -0
- package/dist/explore/styles/inject.js +40 -0
- package/dist/explore/styles/inject.js.map +1 -0
- package/dist/explore/utils/schedule-idle.d.ts +12 -0
- package/dist/explore/utils/schedule-idle.d.ts.map +1 -0
- package/dist/explore/utils/schedule-idle.js +16 -0
- package/dist/explore/utils/schedule-idle.js.map +1 -0
- package/dist/explore/viewer-shared.d.ts +56 -0
- package/dist/explore/viewer-shared.d.ts.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/space/cave-base-layer.d.ts +42 -0
- package/dist/space/cave-base-layer.d.ts.map +1 -0
- package/dist/space/cave-base-layer.js +221 -0
- package/dist/space/cave-base-layer.js.map +1 -0
- package/dist/space/cave-custom-layer.d.ts +12 -0
- package/dist/space/cave-custom-layer.d.ts.map +1 -0
- package/dist/space/cave-custom-layer.js +17 -0
- package/dist/space/cave-custom-layer.js.map +1 -0
- package/dist/space/cave-env.d.ts +6 -0
- package/dist/space/cave-env.d.ts.map +1 -0
- package/dist/space/cave-env.js +23 -0
- package/dist/space/cave-env.js.map +1 -0
- package/dist/space/cave-space.d.ts +46 -0
- package/dist/space/cave-space.d.ts.map +1 -0
- package/dist/space/cave-space.js +37 -0
- package/dist/space/cave-space.js.map +1 -0
- package/dist/space/connector-label-host.d.ts +21 -0
- package/dist/space/connector-label-host.d.ts.map +1 -0
- package/dist/space/connector-label-host.js +65 -0
- package/dist/space/connector-label-host.js.map +1 -0
- package/dist/space/index.d.ts +18 -0
- package/dist/space/index.d.ts.map +1 -0
- package/dist/space/index.js +47 -0
- package/dist/space/index.js.map +1 -0
- package/dist/space/objects/builtin-registrar.d.ts +17 -0
- package/dist/space/objects/builtin-registrar.d.ts.map +1 -0
- package/dist/space/objects/builtin-registrar.js +19 -0
- package/dist/space/objects/builtin-registrar.js.map +1 -0
- package/dist/space/objects/custom-object.d.ts +9 -0
- package/dist/space/objects/custom-object.d.ts.map +1 -0
- package/dist/space/objects/custom-object.js +56 -0
- package/dist/space/objects/custom-object.js.map +1 -0
- package/dist/space/objects/image-object.d.ts +7 -0
- package/dist/space/objects/image-object.d.ts.map +1 -0
- package/dist/space/objects/image-object.js +14 -0
- package/dist/space/objects/image-object.js.map +1 -0
- package/dist/space/objects/model-object/fbx-object.d.ts +8 -0
- package/dist/space/objects/model-object/fbx-object.d.ts.map +1 -0
- package/dist/space/objects/model-object/fbx-object.js +26 -0
- package/dist/space/objects/model-object/fbx-object.js.map +1 -0
- package/dist/space/objects/model-object/gltf-object.d.ts +9 -0
- package/dist/space/objects/model-object/gltf-object.d.ts.map +1 -0
- package/dist/space/objects/model-object/gltf-object.js +66 -0
- package/dist/space/objects/model-object/gltf-object.js.map +1 -0
- package/dist/space/objects/model-object/index.d.ts +9 -0
- package/dist/space/objects/model-object/index.d.ts.map +1 -0
- package/dist/space/objects/model-object/index.js +12 -0
- package/dist/space/objects/model-object/index.js.map +1 -0
- package/dist/space/objects/model-object/splat-object.d.ts +9 -0
- package/dist/space/objects/model-object/splat-object.d.ts.map +1 -0
- package/dist/space/objects/model-object/splat-object.js +19 -0
- package/dist/space/objects/model-object/splat-object.js.map +1 -0
- package/dist/space/objects/object-components/windows/index.d.ts +5 -0
- package/dist/space/objects/object-components/windows/index.d.ts.map +1 -0
- package/dist/space/objects/object-components/windows/index.js +20 -0
- package/dist/space/objects/object-components/windows/index.js.map +1 -0
- package/dist/space/objects/placeholder-object.d.ts +7 -0
- package/dist/space/objects/placeholder-object.d.ts.map +1 -0
- package/dist/space/objects/placeholder-object.js +12 -0
- package/dist/space/objects/placeholder-object.js.map +1 -0
- package/dist/space/objects/poi-object.d.ts +7 -0
- package/dist/space/objects/poi-object.d.ts.map +1 -0
- package/dist/space/objects/poi-object.js +38 -0
- package/dist/space/objects/poi-object.js.map +1 -0
- package/dist/space/objects/portal-object.d.ts +7 -0
- package/dist/space/objects/portal-object.d.ts.map +1 -0
- package/dist/space/objects/portal-object.js +84 -0
- package/dist/space/objects/portal-object.js.map +1 -0
- package/dist/space/objects/video-object.d.ts +7 -0
- package/dist/space/objects/video-object.d.ts.map +1 -0
- package/dist/space/objects/video-object.js +32 -0
- package/dist/space/objects/video-object.js.map +1 -0
- package/dist/space/polygon-boundary.d.ts +10 -0
- package/dist/space/polygon-boundary.d.ts.map +1 -0
- package/dist/space/polygon-boundary.js +205 -0
- package/dist/space/polygon-boundary.js.map +1 -0
- package/dist/space/splats/spark/robust-splat-mesh.d.ts +59 -0
- package/dist/space/splats/spark/robust-splat-mesh.d.ts.map +1 -0
- package/dist/space/splats/spark/robust-splat-mesh.js +105 -0
- package/dist/space/splats/spark/robust-splat-mesh.js.map +1 -0
- package/dist/space/splats/spark/splat-mesh.d.ts +5 -0
- package/dist/space/splats/spark/splat-mesh.d.ts.map +1 -0
- package/dist/space/splats/spark/splat-mesh.js +7 -0
- package/dist/space/splats/spark/splat-mesh.js.map +1 -0
- package/dist/space/splats/spark/splat-spread-reveal.d.ts +14 -0
- package/dist/space/splats/spark/splat-spread-reveal.d.ts.map +1 -0
- package/dist/space/splats/spark/splat-spread-reveal.js +45 -0
- package/dist/space/splats/spark/splat-spread-reveal.js.map +1 -0
- package/dist/space/utils/cave-world-player.d.ts +3 -0
- package/dist/space/utils/cave-world-player.d.ts.map +1 -0
- package/dist/space/utils/cave-world-player.js +5 -0
- package/dist/space/utils/cave-world-player.js.map +1 -0
- package/dist/space/utils/configure-canvas.d.ts +20 -0
- package/dist/space/utils/configure-canvas.d.ts.map +1 -0
- package/dist/space/utils/configure-canvas.js +12 -0
- package/dist/space/utils/configure-canvas.js.map +1 -0
- package/dist/space/utils/polygon-boundary-geometry.d.ts +8 -0
- package/dist/space/utils/polygon-boundary-geometry.d.ts.map +1 -0
- package/dist/space/utils/polygon-boundary-geometry.js +20 -0
- package/dist/space/utils/polygon-boundary-geometry.js.map +1 -0
- package/dist/space/utils/polygon-boundary-segments.d.ts +50 -0
- package/dist/space/utils/polygon-boundary-segments.d.ts.map +1 -0
- package/dist/space/utils/polygon-boundary-segments.js +64 -0
- package/dist/space/utils/polygon-boundary-segments.js.map +1 -0
- package/dist/space/utils/rotation-compat.d.ts +4 -0
- package/dist/space/utils/rotation-compat.d.ts.map +1 -0
- package/dist/space/utils/rotation-compat.js +9 -0
- package/dist/space/utils/rotation-compat.js.map +1 -0
- package/dist/space/utils/select-splat-level.d.ts +52 -0
- package/dist/space/utils/select-splat-level.d.ts.map +1 -0
- package/dist/space/utils/select-splat-level.js +43 -0
- package/dist/space/utils/select-splat-level.js.map +1 -0
- package/dist/space/utils/spark-performance.d.ts +10 -0
- package/dist/space/utils/spark-performance.d.ts.map +1 -0
- package/dist/space/utils/spark-performance.js +10 -0
- package/dist/space/utils/spark-performance.js.map +1 -0
- package/dist/space/utils/splat-collider-helper.d.ts +5 -0
- package/dist/space/utils/splat-collider-helper.d.ts.map +1 -0
- package/dist/space/utils/splat-collider-helper.js +162 -0
- package/dist/space/utils/splat-collider-helper.js.map +1 -0
- package/dist/space/utils/touch-primary-device.d.ts +16 -0
- package/dist/space/utils/touch-primary-device.d.ts.map +1 -0
- package/dist/space/utils/touch-primary-device.js +52 -0
- package/dist/space/utils/touch-primary-device.js.map +1 -0
- package/dist/space/utils/use-visibility-frameloop.d.ts +20 -0
- package/dist/space/utils/use-visibility-frameloop.d.ts.map +1 -0
- package/dist/space/utils/use-visibility-frameloop.js +18 -0
- package/dist/space/utils/use-visibility-frameloop.js.map +1 -0
- package/dist/styles.css +930 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/space-types.d.ts +404 -0
- package/dist/types/space-types.d.ts.map +1 -0
- package/doc/API.md +617 -0
- package/doc/ARCHITECTURE.md +264 -0
- package/doc/multiplayer-protocol.md +757 -0
- package/doc/scene-json-structure.md +567 -0
- package/package.json +131 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as e, jsxs as r } from "react/jsx-runtime";
|
|
2
|
+
import { useCaveWorldMessages as d } from "../../core/context/cave-world-context.js";
|
|
3
|
+
import { useTouchPrimaryDevice as m } from "../../space/utils/touch-primary-device.js";
|
|
4
|
+
import { useActionPrompt as t } from "../stores/explore-context.js";
|
|
5
|
+
import { ArrowRightIcon as _, ChevronRightIcon as p } from "./icons.js";
|
|
6
|
+
function h(l, c, i) {
|
|
7
|
+
const { actionPanel: n } = i;
|
|
8
|
+
return l.every((a) => a.disabled) ? n.footerAllLoading : l.some((a) => a.shortcut) ? c ? l.length === 1 ? n.footerTapToConfirm : n.footerTapToSelect : l.length === 1 ? n.footerKeyToConfirm : n.footerKeysOrTap : n.footerTapToSelect;
|
|
9
|
+
}
|
|
10
|
+
function y() {
|
|
11
|
+
const l = t((a) => a.actions), c = t((a) => a.style), i = m(), n = d();
|
|
12
|
+
return c !== "panel" || l.length === 0 ? null : /* @__PURE__ */ e("div", { className: "cw-overlay-root cw-panel-layer", children: /* @__PURE__ */ r("div", { className: "cw-panel", role: "dialog", "aria-label": n.actionPanel.title, children: [
|
|
13
|
+
/* @__PURE__ */ e("div", { className: "cw-panel__rim", "aria-hidden": !0 }),
|
|
14
|
+
/* @__PURE__ */ e("div", { className: "cw-panel__frame", children: /* @__PURE__ */ r("div", { className: "cw-panel__body", children: [
|
|
15
|
+
/* @__PURE__ */ e("div", { className: "cw-panel__grain", "aria-hidden": !0 }),
|
|
16
|
+
/* @__PURE__ */ e("div", { className: "cw-panel__hairline", "aria-hidden": !0 }),
|
|
17
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__mark cw-panel__mark--tl", "aria-hidden": !0 }),
|
|
18
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__mark cw-panel__mark--tr", "aria-hidden": !0 }),
|
|
19
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__mark cw-panel__mark--bl", "aria-hidden": !0 }),
|
|
20
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__mark cw-panel__mark--br", "aria-hidden": !0 }),
|
|
21
|
+
/* @__PURE__ */ r("header", { className: "cw-panel__header", children: [
|
|
22
|
+
/* @__PURE__ */ r("div", { className: "cw-panel__eyebrow-row", children: [
|
|
23
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__dot", "aria-hidden": !0 }),
|
|
24
|
+
/* @__PURE__ */ e("p", { className: "cw-panel__eyebrow", children: n.actionPanel.eyebrow })
|
|
25
|
+
] }),
|
|
26
|
+
/* @__PURE__ */ e("h3", { className: "cw-panel__title", children: n.actionPanel.title }),
|
|
27
|
+
/* @__PURE__ */ e("div", { className: "cw-panel__divider", "aria-hidden": !0 })
|
|
28
|
+
] }),
|
|
29
|
+
/* @__PURE__ */ e("ul", { className: "cw-panel__list", children: l.map((a, o) => {
|
|
30
|
+
const s = a.disabled === !0;
|
|
31
|
+
return /* @__PURE__ */ e(
|
|
32
|
+
"li",
|
|
33
|
+
{
|
|
34
|
+
className: "cw-panel__row",
|
|
35
|
+
style: { animationDelay: `${40 + o * 40}ms` },
|
|
36
|
+
children: /* @__PURE__ */ r(
|
|
37
|
+
"button",
|
|
38
|
+
{
|
|
39
|
+
type: "button",
|
|
40
|
+
className: "cw-panel__item",
|
|
41
|
+
disabled: s,
|
|
42
|
+
onClick: s ? void 0 : a.onAction,
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__item-bar", "aria-hidden": !0 }),
|
|
45
|
+
a.shortcut && !i ? /* @__PURE__ */ e("span", { className: "cw-key", "aria-hidden": !0, children: a.shortcut }) : /* @__PURE__ */ e("span", { className: "cw-panel__item-icon", "aria-hidden": !0, children: /* @__PURE__ */ e(_, { size: 12 }) }),
|
|
46
|
+
/* @__PURE__ */ r("span", { className: "cw-panel__item-text", children: [
|
|
47
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__item-label", children: a.label }),
|
|
48
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__item-hint", children: s ? n.actionPanel.itemLoading : n.actionPanel.itemEnter })
|
|
49
|
+
] }),
|
|
50
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__item-chevron", "aria-hidden": !0, children: /* @__PURE__ */ e(p, { size: 14 }) })
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
},
|
|
55
|
+
a.id
|
|
56
|
+
);
|
|
57
|
+
}) }),
|
|
58
|
+
/* @__PURE__ */ r("div", { className: "cw-panel__footer", children: [
|
|
59
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__footer-rule", "aria-hidden": !0 }),
|
|
60
|
+
/* @__PURE__ */ e("p", { className: "cw-panel__footer-text", children: h(l, i, n) }),
|
|
61
|
+
/* @__PURE__ */ e("span", { className: "cw-panel__footer-rule cw-panel__footer-rule--end", "aria-hidden": !0 })
|
|
62
|
+
] })
|
|
63
|
+
] }) })
|
|
64
|
+
] }) });
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
y as default
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=action-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-panel.js","sources":["../../../explore/overlays/action-panel.tsx"],"sourcesContent":["import { useCaveWorldMessages, type CaveWorldMessages } from '../../core'\nimport { useTouchPrimaryDevice } from '../../space'\nimport type { ActionDef } from '../stores/action-prompt.store'\nimport { useActionPrompt } from '../stores/explore-context'\nimport { ArrowRightIcon, ChevronRightIcon } from './icons'\n\n/**\n * Footer copy depends on how the player can actually pick a destination: touch\n * devices have no keyboard shortcuts, and a single option needs no list.\n */\nfunction resolveFooterHint(\n actions: ActionDef[],\n isTouchDevice: boolean,\n messages: CaveWorldMessages\n): string {\n const { actionPanel } = messages\n if (actions.every((action) => action.disabled)) return actionPanel.footerAllLoading\n if (!actions.some((action) => action.shortcut)) return actionPanel.footerTapToSelect\n if (isTouchDevice) {\n return actions.length === 1 ? actionPanel.footerTapToConfirm : actionPanel.footerTapToSelect\n }\n return actions.length === 1 ? actionPanel.footerKeyToConfirm : actionPanel.footerKeysOrTap\n}\n\n/**\n * Screen-space list of the currently available actions — used for multi-choice\n * interactions such as picking a portal destination.\n *\n * Intentionally low-intrusion: a compact chamfered card with no full-screen\n * scrim, so the scene stays visible when the player just brushes past a\n * connector. The decorative nodes (rim, grain, hairline, corner marks) are\n * `aria-hidden` siblings rather than pseudo-elements because several of them\n * need their own stacking and blend context.\n */\nexport default function ActionPanel() {\n const actions = useActionPrompt((s) => s.actions)\n const style = useActionPrompt((s) => s.style)\n const isTouchDevice = useTouchPrimaryDevice()\n const messages = useCaveWorldMessages()\n\n if (style !== 'panel' || actions.length === 0) return null\n\n return (\n <div className=\"cw-overlay-root cw-panel-layer\">\n <div className=\"cw-panel\" role=\"dialog\" aria-label={messages.actionPanel.title}>\n <div className=\"cw-panel__rim\" aria-hidden />\n\n <div className=\"cw-panel__frame\">\n <div className=\"cw-panel__body\">\n <div className=\"cw-panel__grain\" aria-hidden />\n <div className=\"cw-panel__hairline\" aria-hidden />\n <span className=\"cw-panel__mark cw-panel__mark--tl\" aria-hidden />\n <span className=\"cw-panel__mark cw-panel__mark--tr\" aria-hidden />\n <span className=\"cw-panel__mark cw-panel__mark--bl\" aria-hidden />\n <span className=\"cw-panel__mark cw-panel__mark--br\" aria-hidden />\n\n <header className=\"cw-panel__header\">\n <div className=\"cw-panel__eyebrow-row\">\n <span className=\"cw-panel__dot\" aria-hidden />\n <p className=\"cw-panel__eyebrow\">{messages.actionPanel.eyebrow}</p>\n </div>\n <h3 className=\"cw-panel__title\">{messages.actionPanel.title}</h3>\n <div className=\"cw-panel__divider\" aria-hidden />\n </header>\n\n <ul className=\"cw-panel__list\">\n {actions.map((action, index) => {\n const disabled = action.disabled === true\n return (\n <li\n key={action.id}\n className=\"cw-panel__row\"\n // Staggered entrance, so a multi-destination list reads as a\n // sequence instead of appearing all at once.\n style={{ animationDelay: `${40 + index * 40}ms` }}\n >\n <button\n type=\"button\"\n className=\"cw-panel__item\"\n disabled={disabled}\n onClick={disabled ? undefined : action.onAction}\n >\n <span className=\"cw-panel__item-bar\" aria-hidden />\n\n {action.shortcut && !isTouchDevice ? (\n <span className=\"cw-key\" aria-hidden>\n {action.shortcut}\n </span>\n ) : (\n <span className=\"cw-panel__item-icon\" aria-hidden>\n <ArrowRightIcon size={12} />\n </span>\n )}\n\n <span className=\"cw-panel__item-text\">\n <span className=\"cw-panel__item-label\">{action.label}</span>\n <span className=\"cw-panel__item-hint\">\n {disabled\n ? messages.actionPanel.itemLoading\n : messages.actionPanel.itemEnter}\n </span>\n </span>\n\n <span className=\"cw-panel__item-chevron\" aria-hidden>\n <ChevronRightIcon size={14} />\n </span>\n </button>\n </li>\n )\n })}\n </ul>\n\n <div className=\"cw-panel__footer\">\n <span className=\"cw-panel__footer-rule\" aria-hidden />\n <p className=\"cw-panel__footer-text\">\n {resolveFooterHint(actions, isTouchDevice, messages)}\n </p>\n <span className=\"cw-panel__footer-rule cw-panel__footer-rule--end\" aria-hidden />\n </div>\n </div>\n </div>\n </div>\n </div>\n )\n}\n"],"names":["resolveFooterHint","actions","isTouchDevice","messages","actionPanel","action","ActionPanel","useActionPrompt","s","style","useTouchPrimaryDevice","useCaveWorldMessages","jsx","jsxs","index","disabled","ArrowRightIcon","ChevronRightIcon"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ConnectorLabelRendererProps } from '../../core/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Default always-on wayfinding label for portal connectors.
|
|
4
|
+
*
|
|
5
|
+
* Shows the destination name at mid range, collapses to an arrow badge at long
|
|
6
|
+
* range, and greys out while the target scene is still preloading (a click then
|
|
7
|
+
* would have nowhere to go). Pass `renderConnectorLabel` to replace it — the SDK
|
|
8
|
+
* keeps owning distance fade and visibility gating either way.
|
|
9
|
+
*/
|
|
10
|
+
export default function ConnectorLabelBeacon({ label, opacity, displayMode, isPlayerInside, transferStatus, onClick }: ConnectorLabelRendererProps): import("react").JSX.Element | null;
|
|
11
|
+
//# sourceMappingURL=connector-label-beacon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-label-beacon.d.ts","sourceRoot":"","sources":["../../../explore/overlays/connector-label-beacon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,2BAA2B,EAAE,MAAM,YAAY,CAAA;AAInF;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,EAC3C,KAAK,EACL,OAAO,EACP,WAAW,EACX,cAAc,EACd,cAAc,EACd,OAAO,EACR,EAAE,2BAA2B,sCAmC7B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as t, jsxs as g } from "react/jsx-runtime";
|
|
2
|
+
import { useCaveWorldMessages as p } from "../../core/context/cave-world-context.js";
|
|
3
|
+
import u from "./connector-label-tag-shell.js";
|
|
4
|
+
import { ArrowRightIcon as b } from "./icons.js";
|
|
5
|
+
function h({
|
|
6
|
+
label: r,
|
|
7
|
+
opacity: a,
|
|
8
|
+
displayMode: l,
|
|
9
|
+
isPlayerInside: s,
|
|
10
|
+
transferStatus: i,
|
|
11
|
+
onClick: c
|
|
12
|
+
}) {
|
|
13
|
+
const m = p();
|
|
14
|
+
if (s || a <= 0 || l === "hidden") return null;
|
|
15
|
+
const e = i === "loading", n = !!c && !e, o = l === "compact", d = [
|
|
16
|
+
"cw-label__tag",
|
|
17
|
+
o ? "cw-label__tag--compact" : "",
|
|
18
|
+
e ? "cw-label__tag--pending" : n ? "cw-label__tag--interactive" : ""
|
|
19
|
+
].filter(Boolean).join(" ");
|
|
20
|
+
return /* @__PURE__ */ t(u, { opacity: a, children: /* @__PURE__ */ g(
|
|
21
|
+
"div",
|
|
22
|
+
{
|
|
23
|
+
className: d,
|
|
24
|
+
onClick: n ? c : void 0,
|
|
25
|
+
role: n ? "button" : void 0,
|
|
26
|
+
"aria-busy": e || void 0,
|
|
27
|
+
style: { pointerEvents: n ? "auto" : "none" },
|
|
28
|
+
children: [
|
|
29
|
+
e ? /* @__PURE__ */ t("span", { className: "cw-spinner" }) : o ? /* @__PURE__ */ t(b, {}) : null,
|
|
30
|
+
o ? null : /* @__PURE__ */ t("span", { className: "cw-label__text", children: e ? m.connector.labelPending : r.text })
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
) });
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
h as default
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=connector-label-beacon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-label-beacon.js","sources":["../../../explore/overlays/connector-label-beacon.tsx"],"sourcesContent":["import { useCaveWorldMessages, type ConnectorLabelRendererProps } from '../../core'\nimport ConnectorLabelTagShell from './connector-label-tag-shell'\nimport { ArrowRightIcon } from './icons'\n\n/**\n * Default always-on wayfinding label for portal connectors.\n *\n * Shows the destination name at mid range, collapses to an arrow badge at long\n * range, and greys out while the target scene is still preloading (a click then\n * would have nowhere to go). Pass `renderConnectorLabel` to replace it — the SDK\n * keeps owning distance fade and visibility gating either way.\n */\nexport default function ConnectorLabelBeacon({\n label,\n opacity,\n displayMode,\n isPlayerInside,\n transferStatus,\n onClick\n}: ConnectorLabelRendererProps) {\n const messages = useCaveWorldMessages()\n\n if (isPlayerInside || opacity <= 0 || displayMode === 'hidden') return null\n\n const pending = transferStatus === 'loading'\n const interactive = !!onClick && !pending\n const compact = displayMode === 'compact'\n\n const className = [\n 'cw-label__tag',\n compact ? 'cw-label__tag--compact' : '',\n pending ? 'cw-label__tag--pending' : interactive ? 'cw-label__tag--interactive' : ''\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <ConnectorLabelTagShell opacity={opacity}>\n <div\n className={className}\n onClick={interactive ? onClick : undefined}\n role={interactive ? 'button' : undefined}\n aria-busy={pending || undefined}\n style={{ pointerEvents: interactive ? 'auto' : 'none' }}\n >\n {pending ? <span className=\"cw-spinner\" /> : compact ? <ArrowRightIcon /> : null}\n {compact ? null : (\n <span className=\"cw-label__text\">\n {pending ? messages.connector.labelPending : label.text}\n </span>\n )}\n </div>\n </ConnectorLabelTagShell>\n )\n}\n"],"names":["ConnectorLabelBeacon","label","opacity","displayMode","isPlayerInside","transferStatus","onClick","messages","useCaveWorldMessages","pending","interactive","compact","className","jsx","ConnectorLabelTagShell","jsxs","ArrowRightIcon"],"mappings":";;;;AAYA,SAAwBA,EAAqB;AAAA,EAC3C,OAAAC;AAAA,EACA,SAAAC;AAAA,EACA,aAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,SAAAC;AACF,GAAgC;AAC9B,QAAMC,IAAWC,EAAA;AAEjB,MAAIJ,KAAkBF,KAAW,KAAKC,MAAgB,SAAU,QAAO;AAEvE,QAAMM,IAAUJ,MAAmB,WAC7BK,IAAc,CAAC,CAACJ,KAAW,CAACG,GAC5BE,IAAUR,MAAgB,WAE1BS,IAAY;AAAA,IAChB;AAAA,IACAD,IAAU,2BAA2B;AAAA,IACrCF,IAAU,2BAA2BC,IAAc,+BAA+B;AAAA,EAAA,EAEjF,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SACE,gBAAAG,EAACC,KAAuB,SAAAZ,GACtB,UAAA,gBAAAa;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAAH;AAAA,MACA,SAASF,IAAcJ,IAAU;AAAA,MACjC,MAAMI,IAAc,WAAW;AAAA,MAC/B,aAAWD,KAAW;AAAA,MACtB,OAAO,EAAE,eAAeC,IAAc,SAAS,OAAA;AAAA,MAE9C,UAAA;AAAA,QAAAD,IAAU,gBAAAI,EAAC,UAAK,WAAU,aAAA,CAAa,IAAKF,IAAU,gBAAAE,EAACG,KAAe,IAAK;AAAA,QAC3EL,IAAU,OACT,gBAAAE,EAAC,QAAA,EAAK,WAAU,kBACb,UAAAJ,IAAUF,EAAS,UAAU,eAAeN,EAAM,KAAA,CACrD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAGN;AAEJ;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Billboard + `Html` shell shared by every connector-label renderer.
|
|
4
|
+
*
|
|
5
|
+
* Reuse it in a custom `renderConnectorLabel` so your label gets the same
|
|
6
|
+
* camera-facing behavior, opacity fade, and pointer handling as the built-in
|
|
7
|
+
* one, and you only supply the visuals.
|
|
8
|
+
*
|
|
9
|
+
* Pointer events are stopped here so clicking a label never reaches the canvas
|
|
10
|
+
* underneath (which would otherwise grab pointer lock and start a look-around).
|
|
11
|
+
*/
|
|
12
|
+
export default function ConnectorLabelTagShell({ opacity, children }: {
|
|
13
|
+
opacity: number;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=connector-label-tag-shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-label-tag-shell.d.ts","sourceRoot":"","sources":["../../../explore/overlays/connector-label-tag-shell.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAGnD;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAC7C,OAAO,EACP,QAAQ,EACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,SAAS,CAAA;CACpB,+BAwBA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback as e } from "react";
|
|
3
|
+
import { Billboard as c, Html as i } from "@react-three/drei";
|
|
4
|
+
function u({
|
|
5
|
+
opacity: l,
|
|
6
|
+
children: r
|
|
7
|
+
}) {
|
|
8
|
+
const n = e((o) => {
|
|
9
|
+
o.stopPropagation();
|
|
10
|
+
}, []), a = e((o) => {
|
|
11
|
+
o.stopPropagation();
|
|
12
|
+
}, []);
|
|
13
|
+
return /* @__PURE__ */ t(c, { follow: !0, lockX: !0, lockY: !0, lockZ: !0, children: /* @__PURE__ */ t(i, { center: !0, className: "cw-overlay-root cw-label", style: { opacity: l }, zIndexRange: [50, 0], children: /* @__PURE__ */ t("div", { className: "cw-label__hit", onClick: a, onPointerDown: n, children: r }) }) });
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
u as default
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=connector-label-tag-shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-label-tag-shell.js","sources":["../../../explore/overlays/connector-label-tag-shell.tsx"],"sourcesContent":["import { useCallback, type ReactNode } from 'react'\nimport { Billboard, Html } from '@react-three/drei'\n\n/**\n * Billboard + `Html` shell shared by every connector-label renderer.\n *\n * Reuse it in a custom `renderConnectorLabel` so your label gets the same\n * camera-facing behavior, opacity fade, and pointer handling as the built-in\n * one, and you only supply the visuals.\n *\n * Pointer events are stopped here so clicking a label never reaches the canvas\n * underneath (which would otherwise grab pointer lock and start a look-around).\n */\nexport default function ConnectorLabelTagShell({\n opacity,\n children\n}: {\n opacity: number\n children: ReactNode\n}) {\n const stopPointerDown = useCallback((event: React.PointerEvent) => {\n event.stopPropagation()\n }, [])\n\n const stopClick = useCallback((event: React.MouseEvent) => {\n event.stopPropagation()\n }, [])\n\n return (\n <Billboard follow lockX lockY lockZ>\n {/*\n * `cw-label` must not set a size: drei positions this wrapper with inline\n * styles and centers it with `translate(-50%, -50%)`, so a width/height\n * here would stretch it to the canvas and offset the tag by half a\n * viewport.\n */}\n <Html center className=\"cw-overlay-root cw-label\" style={{ opacity }} zIndexRange={[50, 0]}>\n <div className=\"cw-label__hit\" onClick={stopClick} onPointerDown={stopPointerDown}>\n {children}\n </div>\n </Html>\n </Billboard>\n )\n}\n"],"names":["ConnectorLabelTagShell","opacity","children","stopPointerDown","useCallback","event","stopClick","jsx","Billboard","Html"],"mappings":";;;AAaA,SAAwBA,EAAuB;AAAA,EAC7C,SAAAC;AAAA,EACA,UAAAC;AACF,GAGG;AACD,QAAMC,IAAkBC,EAAY,CAACC,MAA8B;AACjE,IAAAA,EAAM,gBAAA;AAAA,EACR,GAAG,CAAA,CAAE,GAECC,IAAYF,EAAY,CAACC,MAA4B;AACzD,IAAAA,EAAM,gBAAA;AAAA,EACR,GAAG,CAAA,CAAE;AAEL,SACE,gBAAAE,EAACC,GAAA,EAAU,QAAM,IAAC,OAAK,IAAC,OAAK,IAAC,OAAK,IAOjC,UAAA,gBAAAD,EAACE,GAAA,EAAK,QAAM,IAAC,WAAU,4BAA2B,OAAO,EAAE,SAAAR,EAAA,GAAW,aAAa,CAAC,IAAI,CAAC,GACvF,UAAA,gBAAAM,EAAC,OAAA,EAAI,WAAU,iBAAgB,SAASD,GAAW,eAAeH,GAC/D,UAAAD,EAAA,CACH,GACF,GACF;AAEJ;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in detail panel for objects carrying a `Window` component.
|
|
3
|
+
*
|
|
4
|
+
* Replace it wholesale with `renderDetailWindow` when you need product-specific
|
|
5
|
+
* layout; the event and store contract stays the same
|
|
6
|
+
* (`detail:open` / `detail:close`, `activeObject`, `detailVisible`).
|
|
7
|
+
*/
|
|
8
|
+
export default function DetailWindow(): import("react").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=detail-window.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detail-window.d.ts","sourceRoot":"","sources":["../../../explore/overlays/detail-window.tsx"],"names":[],"mappings":"AAsCA;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,uCA2FnC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { jsxs as i, jsx as t, Fragment as b } from "react/jsx-runtime";
|
|
2
|
+
import { useState as v, useCallback as x } from "react";
|
|
3
|
+
import { useCaveWorldStore as d, useCaveEventBus as j, useCaveWorldMessages as I } from "../../core/context/cave-world-context.js";
|
|
4
|
+
import { useCaveEvent as $ } from "../../core/hooks/use-cave-event.js";
|
|
5
|
+
import { CloseIcon as O } from "./icons.js";
|
|
6
|
+
const _ = 12;
|
|
7
|
+
function D({ block: e }) {
|
|
8
|
+
switch (e.type) {
|
|
9
|
+
case "text":
|
|
10
|
+
return /* @__PURE__ */ t("div", { className: "cw-detail__text", children: e.text });
|
|
11
|
+
case "image":
|
|
12
|
+
return e.url ? /* @__PURE__ */ t("img", { src: e.url, alt: "" }) : null;
|
|
13
|
+
case "video":
|
|
14
|
+
return e.url ? /* @__PURE__ */ t("video", { controls: !0, loop: !0, muted: !0, playsInline: !0, children: /* @__PURE__ */ t("source", { src: e.url, type: "video/mp4" }) }) : null;
|
|
15
|
+
case "portal":
|
|
16
|
+
return e.url ? /* @__PURE__ */ t("iframe", { src: e.url, title: e.url }) : null;
|
|
17
|
+
default:
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function f(e) {
|
|
22
|
+
return !e || e < 1 ? _ : Math.min(e, _);
|
|
23
|
+
}
|
|
24
|
+
function S(e) {
|
|
25
|
+
const s = e?.components?.Window?.contents;
|
|
26
|
+
return Array.isArray(s) ? s : [];
|
|
27
|
+
}
|
|
28
|
+
function E() {
|
|
29
|
+
const e = d((l) => l.activeObject), s = d((l) => l.detailVisible), r = d((l) => l.setDetailVisible), u = j(), m = I(), [c, p] = v(0), [w, g] = v(e);
|
|
30
|
+
w !== e && (g(e), p(0));
|
|
31
|
+
const n = S(e), y = n[c] ?? null;
|
|
32
|
+
$("detail:open", () => r(!0));
|
|
33
|
+
const C = x(() => {
|
|
34
|
+
r(!1), u.emit("detail:close", {});
|
|
35
|
+
}, [r, u]);
|
|
36
|
+
if (!s || n.length === 0) return null;
|
|
37
|
+
const h = e?.name || e?.text?.content || m.detail.untitled;
|
|
38
|
+
return /* @__PURE__ */ i("div", { className: "cw-overlay-root cw-detail", role: "dialog", "aria-label": h, children: [
|
|
39
|
+
/* @__PURE__ */ i("header", { className: "cw-detail__header", children: [
|
|
40
|
+
/* @__PURE__ */ t("span", { children: h }),
|
|
41
|
+
/* @__PURE__ */ t(
|
|
42
|
+
"button",
|
|
43
|
+
{
|
|
44
|
+
type: "button",
|
|
45
|
+
className: "cw-icon-button",
|
|
46
|
+
onClick: C,
|
|
47
|
+
"aria-label": m.detail.close,
|
|
48
|
+
children: /* @__PURE__ */ t(O, { size: 16 })
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
] }),
|
|
52
|
+
/* @__PURE__ */ t("div", { className: "cw-detail__body", children: /* @__PURE__ */ t("div", { className: "cw-detail__grid", children: y?.blocks?.map((l, a) => /* @__PURE__ */ t(
|
|
53
|
+
"div",
|
|
54
|
+
{
|
|
55
|
+
className: "cw-detail__cell",
|
|
56
|
+
style: { gridColumn: `span ${f(l.col)}` },
|
|
57
|
+
children: /* @__PURE__ */ t(D, { block: l })
|
|
58
|
+
},
|
|
59
|
+
`${l.type}-${a}`
|
|
60
|
+
)) }) }),
|
|
61
|
+
n.length > 1 ? /* @__PURE__ */ i(b, { children: [
|
|
62
|
+
/* @__PURE__ */ i("div", { className: "cw-detail__counter", children: [
|
|
63
|
+
c + 1,
|
|
64
|
+
" / ",
|
|
65
|
+
n.length
|
|
66
|
+
] }),
|
|
67
|
+
/* @__PURE__ */ t("div", { className: "cw-detail__thumbs", children: n.map((l, a) => /* @__PURE__ */ t(
|
|
68
|
+
"button",
|
|
69
|
+
{
|
|
70
|
+
type: "button",
|
|
71
|
+
className: "cw-detail__thumb",
|
|
72
|
+
"aria-current": a === c,
|
|
73
|
+
onClick: () => p(a),
|
|
74
|
+
children: l.blocks?.map((o, N) => /* @__PURE__ */ t(
|
|
75
|
+
"span",
|
|
76
|
+
{
|
|
77
|
+
className: "cw-detail__thumb-cell",
|
|
78
|
+
style: { gridColumn: `span ${f(o.col)}` },
|
|
79
|
+
children: o.type
|
|
80
|
+
},
|
|
81
|
+
`${o.type}-${N}`
|
|
82
|
+
))
|
|
83
|
+
},
|
|
84
|
+
l.id ?? a
|
|
85
|
+
)) })
|
|
86
|
+
] }) : null
|
|
87
|
+
] });
|
|
88
|
+
}
|
|
89
|
+
export {
|
|
90
|
+
E as default
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=detail-window.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detail-window.js","sources":["../../../explore/overlays/detail-window.tsx"],"sourcesContent":["import { useCallback, useState } from 'react'\nimport { useCaveEvent, useCaveEventBus, useCaveWorldMessages, useCaveWorldStore } from '../../core'\nimport type { Block, Content, CustomObject } from '../../types'\nimport { CloseIcon } from './icons'\n\n/** Blocks declare a 12-column span in the scene JSON. */\nconst GRID_COLUMNS = 12\n\nfunction BlockItem({ block }: { block: Block }) {\n switch (block.type) {\n case 'text':\n return <div className=\"cw-detail__text\">{block.text}</div>\n case 'image':\n return block.url ? <img src={block.url} alt=\"\" /> : null\n case 'video':\n return block.url ? (\n <video controls loop muted playsInline>\n <source src={block.url} type=\"video/mp4\" />\n </video>\n ) : null\n case 'portal':\n return block.url ? <iframe src={block.url} title={block.url} /> : null\n default:\n return null\n }\n}\n\nfunction clampSpan(col: number | undefined): number {\n if (!col || col < 1) return GRID_COLUMNS\n return Math.min(col, GRID_COLUMNS)\n}\n\n/** `Window.contents` is typed `unknown[]` in the schema; narrow it here. */\nfunction resolveContents(object: CustomObject | undefined): Content[] {\n const contents = object?.components?.Window?.contents\n return Array.isArray(contents) ? (contents as Content[]) : []\n}\n\n/**\n * Built-in detail panel for objects carrying a `Window` component.\n *\n * Replace it wholesale with `renderDetailWindow` when you need product-specific\n * layout; the event and store contract stays the same\n * (`detail:open` / `detail:close`, `activeObject`, `detailVisible`).\n */\nexport default function DetailWindow() {\n const activeObject = useCaveWorldStore((s) => s.activeObject)\n const detailVisible = useCaveWorldStore((s) => s.detailVisible)\n const setDetailVisible = useCaveWorldStore((s) => s.setDetailVisible)\n const eventBus = useCaveEventBus()\n const messages = useCaveWorldMessages()\n\n const [activeIndex, setActiveIndex] = useState(0)\n const [pagedObject, setPagedObject] = useState(activeObject)\n\n // Reset paging when the target object changes. Adjusted during render (the\n // pattern React recommends over a reset effect) so the first paint of a new\n // object already shows page 1 instead of flashing the previous page index.\n if (pagedObject !== activeObject) {\n setPagedObject(activeObject)\n setActiveIndex(0)\n }\n\n const contents = resolveContents(activeObject)\n const activeContent = contents[activeIndex] ?? null\n\n useCaveEvent('detail:open', () => setDetailVisible(true))\n\n const handleClose = useCallback(() => {\n setDetailVisible(false)\n eventBus.emit('detail:close', {})\n }, [setDetailVisible, eventBus])\n\n if (!detailVisible || contents.length === 0) return null\n\n const title = activeObject?.name || activeObject?.text?.content || messages.detail.untitled\n\n return (\n <div className=\"cw-overlay-root cw-detail\" role=\"dialog\" aria-label={title}>\n <header className=\"cw-detail__header\">\n <span>{title}</span>\n <button\n type=\"button\"\n className=\"cw-icon-button\"\n onClick={handleClose}\n aria-label={messages.detail.close}\n >\n <CloseIcon size={16} />\n </button>\n </header>\n\n <div className=\"cw-detail__body\">\n <div className=\"cw-detail__grid\">\n {activeContent?.blocks?.map((block, index) => (\n <div\n key={`${block.type}-${index}`}\n className=\"cw-detail__cell\"\n style={{ gridColumn: `span ${clampSpan(block.col)}` }}\n >\n <BlockItem block={block} />\n </div>\n ))}\n </div>\n </div>\n\n {contents.length > 1 ? (\n <>\n <div className=\"cw-detail__counter\">\n {activeIndex + 1} / {contents.length}\n </div>\n\n <div className=\"cw-detail__thumbs\">\n {contents.map((content, index) => (\n <button\n key={content.id ?? index}\n type=\"button\"\n className=\"cw-detail__thumb\"\n aria-current={index === activeIndex}\n onClick={() => setActiveIndex(index)}\n >\n {content.blocks?.map((block, blockIndex) => (\n <span\n key={`${block.type}-${blockIndex}`}\n className=\"cw-detail__thumb-cell\"\n style={{ gridColumn: `span ${clampSpan(block.col)}` }}\n >\n {block.type}\n </span>\n ))}\n </button>\n ))}\n </div>\n </>\n ) : null}\n </div>\n )\n}\n"],"names":["GRID_COLUMNS","BlockItem","block","jsx","clampSpan","col","resolveContents","object","contents","DetailWindow","activeObject","useCaveWorldStore","s","detailVisible","setDetailVisible","eventBus","useCaveEventBus","messages","useCaveWorldMessages","activeIndex","setActiveIndex","useState","pagedObject","setPagedObject","activeContent","useCaveEvent","handleClose","useCallback","title","jsxs","CloseIcon","index","Fragment","content","blockIndex"],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/** One row in the default hint card. */
|
|
3
|
+
export interface ExploreHelperHint {
|
|
4
|
+
/** Key cap or gesture name, e.g. `'W A S D'`. */
|
|
5
|
+
keys: string;
|
|
6
|
+
/** What it does. */
|
|
7
|
+
desc: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ExploreHelperConfig {
|
|
10
|
+
/**
|
|
11
|
+
* `localStorage` key used to remember that the player dismissed the hints.
|
|
12
|
+
* Set it to something app-specific so two SDK embeds don't share state; pass
|
|
13
|
+
* `false` to show the hints on every visit.
|
|
14
|
+
*/
|
|
15
|
+
storageKey?: string | false;
|
|
16
|
+
/** Replace the default hint rows. */
|
|
17
|
+
hints?: ExploreHelperHint[];
|
|
18
|
+
/** Hint rows used on touch devices. */
|
|
19
|
+
touchHints?: ExploreHelperHint[];
|
|
20
|
+
}
|
|
21
|
+
export interface ExploreHelperRenderProps {
|
|
22
|
+
/** Whether the current device uses on-screen touch controls. */
|
|
23
|
+
isTouchDevice: boolean;
|
|
24
|
+
/** Hints resolved for the current device. */
|
|
25
|
+
hints: ExploreHelperHint[];
|
|
26
|
+
/** Hide the helper and persist the dismissal. */
|
|
27
|
+
dismiss: () => void;
|
|
28
|
+
}
|
|
29
|
+
/** Fully replace the built-in onboarding card. */
|
|
30
|
+
export type ExploreHelperRenderer = (props: ExploreHelperRenderProps) => ReactNode;
|
|
31
|
+
export declare const DEFAULT_EXPLORE_HELPER_STORAGE_KEY = "cave-world:explore-helper-seen:v1";
|
|
32
|
+
export interface ExploreHelperProps {
|
|
33
|
+
config?: ExploreHelperConfig;
|
|
34
|
+
render?: ExploreHelperRenderer;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* First-run controls hint.
|
|
38
|
+
*
|
|
39
|
+
* Shown once per browser (keyed by `config.storageKey`) and dismissible. Pass
|
|
40
|
+
* `render` to substitute your own onboarding UI while keeping the SDK's
|
|
41
|
+
* show-once logic and device detection.
|
|
42
|
+
*/
|
|
43
|
+
export default function ExploreHelper({ config, render }: ExploreHelperProps): import("react").JSX.Element | null;
|
|
44
|
+
//# sourceMappingURL=explore-helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore-helper.d.ts","sourceRoot":"","sources":["../../../explore/overlays/explore-helper.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAMvE,wCAAwC;AACxC,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IAC3B,qCAAqC;IACrC,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC3B,uCAAuC;IACvC,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,aAAa,EAAE,OAAO,CAAA;IACtB,6CAA6C;IAC7C,KAAK,EAAE,iBAAiB,EAAE,CAAA;IAC1B,iDAAiD;IACjD,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,kDAAkD;AAClD,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,wBAAwB,KAAK,SAAS,CAAA;AAElF,eAAO,MAAM,kCAAkC,sCAAsC,CAAA;AAuBrF,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,mBAAmB,CAAA;IAC5B,MAAM,CAAC,EAAE,qBAAqB,CAAA;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,kBAAkB,sCAiE3E"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as r, Fragment as u, jsxs as n } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo as m, useEffect as y, useCallback as k } from "react";
|
|
3
|
+
import { useCaveWorldMessages as f } from "../../core/context/cave-world-context.js";
|
|
4
|
+
import { useTouchPrimaryDevice as w } from "../../space/utils/touch-primary-device.js";
|
|
5
|
+
import { useCaveExplore as v, useCaveExploreStore as _ } from "../stores/explore-context.js";
|
|
6
|
+
import { CloseIcon as E } from "./icons.js";
|
|
7
|
+
const p = "cave-world:explore-helper-seen:v1";
|
|
8
|
+
function S(e) {
|
|
9
|
+
if (e === !1) return !1;
|
|
10
|
+
const t = e ?? p;
|
|
11
|
+
try {
|
|
12
|
+
return localStorage.getItem(t) === "true";
|
|
13
|
+
} catch {
|
|
14
|
+
return !1;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function N(e) {
|
|
18
|
+
if (e === !1) return;
|
|
19
|
+
const t = e ?? p;
|
|
20
|
+
try {
|
|
21
|
+
localStorage.setItem(t, "true");
|
|
22
|
+
} catch {
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function T({ config: e, render: t }) {
|
|
26
|
+
const a = w(), s = f(), d = v((c) => c.showHelper), o = _(), l = e?.storageKey, i = m(() => a ? e?.touchHints ?? [
|
|
27
|
+
{ keys: "◎", desc: s.helper.touch.move },
|
|
28
|
+
{ keys: "☰", desc: s.helper.touch.look },
|
|
29
|
+
{ keys: "◉", desc: s.helper.touch.interact }
|
|
30
|
+
] : e?.hints ?? [
|
|
31
|
+
{ keys: "W A S D", desc: s.helper.keyboard.move },
|
|
32
|
+
{ keys: "🖱", desc: s.helper.keyboard.look },
|
|
33
|
+
{ keys: "Space", desc: s.helper.keyboard.jump },
|
|
34
|
+
{ keys: "F", desc: s.helper.keyboard.interact }
|
|
35
|
+
], [a, e?.hints, e?.touchHints, s]);
|
|
36
|
+
y(() => {
|
|
37
|
+
o.getState().setShowHelper(!S(l));
|
|
38
|
+
}, [o, l]);
|
|
39
|
+
const h = k(() => {
|
|
40
|
+
N(l), o.getState().setShowHelper(!1);
|
|
41
|
+
}, [o, l]);
|
|
42
|
+
return d ? t ? /* @__PURE__ */ r(u, { children: t({ isTouchDevice: a, hints: i, dismiss: h }) }) : /* @__PURE__ */ r("div", { className: "cw-overlay-root cw-helper", children: /* @__PURE__ */ r("div", { className: "cw-helper__card", children: /* @__PURE__ */ n("div", { className: "cw-helper__inner cw-surface", children: [
|
|
43
|
+
/* @__PURE__ */ r("div", { className: "cw-helper__hints", children: i.map((c) => /* @__PURE__ */ n("div", { className: "cw-helper__hint", children: [
|
|
44
|
+
/* @__PURE__ */ r("span", { className: "cw-key", children: c.keys }),
|
|
45
|
+
/* @__PURE__ */ r("span", { className: "cw-helper__hint-desc", children: c.desc })
|
|
46
|
+
] }, c.keys)) }),
|
|
47
|
+
/* @__PURE__ */ r("div", { className: "cw-helper__actions", children: /* @__PURE__ */ n("button", { type: "button", className: "cw-button", onClick: h, children: [
|
|
48
|
+
/* @__PURE__ */ r(E, { size: 12 }),
|
|
49
|
+
s.helper.close
|
|
50
|
+
] }) })
|
|
51
|
+
] }) }) }) : null;
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
p as DEFAULT_EXPLORE_HELPER_STORAGE_KEY,
|
|
55
|
+
T as default
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=explore-helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore-helper.js","sources":["../../../explore/overlays/explore-helper.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, type ReactNode } from 'react'\nimport { useCaveWorldMessages } from '../../core'\nimport { useTouchPrimaryDevice } from '../../space'\nimport { useCaveExplore, useCaveExploreStore } from '../stores/explore-context'\nimport { CloseIcon } from './icons'\n\n/** One row in the default hint card. */\nexport interface ExploreHelperHint {\n /** Key cap or gesture name, e.g. `'W A S D'`. */\n keys: string\n /** What it does. */\n desc: string\n}\n\nexport interface ExploreHelperConfig {\n /**\n * `localStorage` key used to remember that the player dismissed the hints.\n * Set it to something app-specific so two SDK embeds don't share state; pass\n * `false` to show the hints on every visit.\n */\n storageKey?: string | false\n /** Replace the default hint rows. */\n hints?: ExploreHelperHint[]\n /** Hint rows used on touch devices. */\n touchHints?: ExploreHelperHint[]\n}\n\nexport interface ExploreHelperRenderProps {\n /** Whether the current device uses on-screen touch controls. */\n isTouchDevice: boolean\n /** Hints resolved for the current device. */\n hints: ExploreHelperHint[]\n /** Hide the helper and persist the dismissal. */\n dismiss: () => void\n}\n\n/** Fully replace the built-in onboarding card. */\nexport type ExploreHelperRenderer = (props: ExploreHelperRenderProps) => ReactNode\n\nexport const DEFAULT_EXPLORE_HELPER_STORAGE_KEY = 'cave-world:explore-helper-seen:v1'\n\nfunction readDismissed(storageKey: string | false | undefined): boolean {\n if (storageKey === false) return false\n const key = storageKey ?? DEFAULT_EXPLORE_HELPER_STORAGE_KEY\n try {\n return localStorage.getItem(key) === 'true'\n } catch {\n // Private browsing / disabled storage: fall back to showing the hints.\n return false\n }\n}\n\nfunction writeDismissed(storageKey: string | false | undefined): void {\n if (storageKey === false) return\n const key = storageKey ?? DEFAULT_EXPLORE_HELPER_STORAGE_KEY\n try {\n localStorage.setItem(key, 'true')\n } catch {\n // Nothing to do — the helper just reappears next session.\n }\n}\n\nexport interface ExploreHelperProps {\n config?: ExploreHelperConfig\n render?: ExploreHelperRenderer\n}\n\n/**\n * First-run controls hint.\n *\n * Shown once per browser (keyed by `config.storageKey`) and dismissible. Pass\n * `render` to substitute your own onboarding UI while keeping the SDK's\n * show-once logic and device detection.\n */\nexport default function ExploreHelper({ config, render }: ExploreHelperProps) {\n const isTouchDevice = useTouchPrimaryDevice()\n const messages = useCaveWorldMessages()\n const showHelper = useCaveExplore((s) => s.showHelper)\n const store = useCaveExploreStore()\n const storageKey = config?.storageKey\n\n const hints = useMemo<ExploreHelperHint[]>(() => {\n if (isTouchDevice) {\n return (\n config?.touchHints ?? [\n { keys: '◎', desc: messages.helper.touch.move },\n { keys: '☰', desc: messages.helper.touch.look },\n { keys: '◉', desc: messages.helper.touch.interact }\n ]\n )\n }\n return (\n config?.hints ?? [\n { keys: 'W A S D', desc: messages.helper.keyboard.move },\n { keys: '🖱', desc: messages.helper.keyboard.look },\n { keys: 'Space', desc: messages.helper.keyboard.jump },\n { keys: 'F', desc: messages.helper.keyboard.interact }\n ]\n )\n }, [isTouchDevice, config?.hints, config?.touchHints, messages])\n\n useEffect(() => {\n store.getState().setShowHelper(!readDismissed(storageKey))\n }, [store, storageKey])\n\n const dismiss = useCallback(() => {\n writeDismissed(storageKey)\n store.getState().setShowHelper(false)\n }, [store, storageKey])\n\n if (!showHelper) return null\n\n if (render) {\n return <>{render({ isTouchDevice, hints, dismiss })}</>\n }\n\n return (\n <div className=\"cw-overlay-root cw-helper\">\n <div className=\"cw-helper__card\">\n <div className=\"cw-helper__inner cw-surface\">\n <div className=\"cw-helper__hints\">\n {hints.map((hint) => (\n <div key={hint.keys} className=\"cw-helper__hint\">\n <span className=\"cw-key\">{hint.keys}</span>\n <span className=\"cw-helper__hint-desc\">{hint.desc}</span>\n </div>\n ))}\n </div>\n\n <div className=\"cw-helper__actions\">\n <button type=\"button\" className=\"cw-button\" onClick={dismiss}>\n <CloseIcon size={12} />\n {messages.helper.close}\n </button>\n </div>\n </div>\n </div>\n </div>\n )\n}\n"],"names":["DEFAULT_EXPLORE_HELPER_STORAGE_KEY","readDismissed","storageKey","key","writeDismissed","ExploreHelper","config","render","isTouchDevice","useTouchPrimaryDevice","messages","useCaveWorldMessages","showHelper","useCaveExplore","s","store","useCaveExploreStore","hints","useMemo","useEffect","dismiss","useCallback","jsx","jsxs","hint","CloseIcon"],"mappings":";;;;;;AAuCO,MAAMA,IAAqC;AAElD,SAASC,EAAcC,GAAiD;AACtE,MAAIA,MAAe,GAAO,QAAO;AACjC,QAAMC,IAAMD,KAAcF;AAC1B,MAAI;AACF,WAAO,aAAa,QAAQG,CAAG,MAAM;AAAA,EACvC,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,EAAeF,GAA8C;AACpE,MAAIA,MAAe,GAAO;AAC1B,QAAMC,IAAMD,KAAcF;AAC1B,MAAI;AACF,iBAAa,QAAQG,GAAK,MAAM;AAAA,EAClC,QAAQ;AAAA,EAER;AACF;AAcA,SAAwBE,EAAc,EAAE,QAAAC,GAAQ,QAAAC,KAA8B;AAC5E,QAAMC,IAAgBC,EAAA,GAChBC,IAAWC,EAAA,GACXC,IAAaC,EAAe,CAACC,MAAMA,EAAE,UAAU,GAC/CC,IAAQC,EAAA,GACRd,IAAaI,GAAQ,YAErBW,IAAQC,EAA6B,MACrCV,IAEAF,GAAQ,cAAc;AAAA,IACpB,EAAE,MAAM,KAAK,MAAMI,EAAS,OAAO,MAAM,KAAA;AAAA,IACzC,EAAE,MAAM,KAAK,MAAMA,EAAS,OAAO,MAAM,KAAA;AAAA,IACzC,EAAE,MAAM,KAAK,MAAMA,EAAS,OAAO,MAAM,SAAA;AAAA,EAAS,IAKtDJ,GAAQ,SAAS;AAAA,IACf,EAAE,MAAM,WAAW,MAAMI,EAAS,OAAO,SAAS,KAAA;AAAA,IAClD,EAAE,MAAM,MAAM,MAAMA,EAAS,OAAO,SAAS,KAAA;AAAA,IAC7C,EAAE,MAAM,SAAS,MAAMA,EAAS,OAAO,SAAS,KAAA;AAAA,IAChD,EAAE,MAAM,KAAK,MAAMA,EAAS,OAAO,SAAS,SAAA;AAAA,EAAS,GAGxD,CAACF,GAAeF,GAAQ,OAAOA,GAAQ,YAAYI,CAAQ,CAAC;AAE/D,EAAAS,EAAU,MAAM;AACd,IAAAJ,EAAM,WAAW,cAAc,CAACd,EAAcC,CAAU,CAAC;AAAA,EAC3D,GAAG,CAACa,GAAOb,CAAU,CAAC;AAEtB,QAAMkB,IAAUC,EAAY,MAAM;AAChC,IAAAjB,EAAeF,CAAU,GACzBa,EAAM,SAAA,EAAW,cAAc,EAAK;AAAA,EACtC,GAAG,CAACA,GAAOb,CAAU,CAAC;AAEtB,SAAKU,IAEDL,2BACQ,UAAAA,EAAO,EAAE,eAAAC,GAAe,OAAAS,GAAO,SAAAG,EAAA,CAAS,GAAE,IAIpD,gBAAAE,EAAC,OAAA,EAAI,WAAU,6BACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,IAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,oBACZ,UAAAL,EAAM,IAAI,CAACO,MACV,gBAAAD,EAAC,OAAA,EAAoB,WAAU,mBAC7B,UAAA;AAAA,MAAA,gBAAAD,EAAC,QAAA,EAAK,WAAU,UAAU,UAAAE,EAAK,MAAK;AAAA,MACpC,gBAAAF,EAAC,QAAA,EAAK,WAAU,wBAAwB,YAAK,KAAA,CAAK;AAAA,IAAA,EAAA,GAF1CE,EAAK,IAGf,CACD,GACH;AAAA,IAEA,gBAAAF,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA,gBAAAC,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,aAAY,SAASH,GACnD,UAAA;AAAA,MAAA,gBAAAE,EAACG,GAAA,EAAU,MAAM,GAAA,CAAI;AAAA,MACpBf,EAAS,OAAO;AAAA,IAAA,EAAA,CACnB,EAAA,CACF;AAAA,EAAA,EAAA,CACF,GACF,GACF,IA3BsB;AA6B1B;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline icons for the built-in overlays.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately hand-written rather than pulled from an icon package: an SDK
|
|
5
|
+
* should not force an icon dependency (or its bundle cost) on every consumer.
|
|
6
|
+
*/
|
|
7
|
+
export declare function CloseIcon({ size }: {
|
|
8
|
+
size?: number;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
export declare function ArrowRightIcon({ size }: {
|
|
11
|
+
size?: number;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
export declare function ChevronRightIcon({ size }: {
|
|
14
|
+
size?: number;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../explore/overlays/icons.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,SAAS,CAAC,EAAE,IAAS,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,+BAMzD;AAED,wBAAgB,cAAc,CAAC,EAAE,IAAS,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,+BAY9D;AAED,wBAAgB,gBAAgB,CAAC,EAAE,IAAS,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,+BAYhE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as o } from "react/jsx-runtime";
|
|
2
|
+
function n({ size: r = 14 }) {
|
|
3
|
+
return /* @__PURE__ */ o("svg", { width: r, height: r, viewBox: "0 0 24 24", fill: "none", "aria-hidden": !0, children: /* @__PURE__ */ o("path", { d: "M6 6l12 12M18 6L6 18", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) });
|
|
4
|
+
}
|
|
5
|
+
function t({ size: r = 14 }) {
|
|
6
|
+
return /* @__PURE__ */ o("svg", { width: r, height: r, viewBox: "0 0 24 24", fill: "none", "aria-hidden": !0, children: /* @__PURE__ */ o(
|
|
7
|
+
"path",
|
|
8
|
+
{
|
|
9
|
+
d: "M5 12h12M13 7l5 5-5 5",
|
|
10
|
+
stroke: "currentColor",
|
|
11
|
+
strokeWidth: "1.75",
|
|
12
|
+
strokeLinecap: "round",
|
|
13
|
+
strokeLinejoin: "round"
|
|
14
|
+
}
|
|
15
|
+
) });
|
|
16
|
+
}
|
|
17
|
+
function i({ size: r = 14 }) {
|
|
18
|
+
return /* @__PURE__ */ o("svg", { width: r, height: r, viewBox: "0 0 24 24", fill: "none", "aria-hidden": !0, children: /* @__PURE__ */ o(
|
|
19
|
+
"path",
|
|
20
|
+
{
|
|
21
|
+
d: "M9 6l6 6-6 6",
|
|
22
|
+
stroke: "currentColor",
|
|
23
|
+
strokeWidth: "2",
|
|
24
|
+
strokeLinecap: "round",
|
|
25
|
+
strokeLinejoin: "round"
|
|
26
|
+
}
|
|
27
|
+
) });
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
t as ArrowRightIcon,
|
|
31
|
+
i as ChevronRightIcon,
|
|
32
|
+
n as CloseIcon
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.js","sources":["../../../explore/overlays/icons.tsx"],"sourcesContent":["/**\n * Inline icons for the built-in overlays.\n *\n * Deliberately hand-written rather than pulled from an icon package: an SDK\n * should not force an icon dependency (or its bundle cost) on every consumer.\n */\n\nexport function CloseIcon({ size = 14 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden>\n <path d=\"M6 6l12 12M18 6L6 18\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport function ArrowRightIcon({ size = 14 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden>\n <path\n d=\"M5 12h12M13 7l5 5-5 5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nexport function ChevronRightIcon({ size = 14 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden>\n <path\n d=\"M9 6l6 6-6 6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n"],"names":["CloseIcon","size","jsx","ArrowRightIcon","ChevronRightIcon"],"mappings":";AAOO,SAASA,EAAU,EAAE,MAAAC,IAAO,MAAyB;AAC1D,SACE,gBAAAC,EAAC,SAAI,OAAOD,GAAM,QAAQA,GAAM,SAAQ,aAAY,MAAK,QAAO,eAAW,IACzE,UAAA,gBAAAC,EAAC,QAAA,EAAK,GAAE,wBAAuB,QAAO,gBAAe,aAAY,KAAI,eAAc,QAAA,CAAQ,EAAA,CAC7F;AAEJ;AAEO,SAASC,EAAe,EAAE,MAAAF,IAAO,MAAyB;AAC/D,SACE,gBAAAC,EAAC,OAAA,EAAI,OAAOD,GAAM,QAAQA,GAAM,SAAQ,aAAY,MAAK,QAAO,eAAW,IACzE,UAAA,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,GAAE;AAAA,MACF,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,IAAA;AAAA,EAAA,GAEnB;AAEJ;AAEO,SAASE,EAAiB,EAAE,MAAAH,IAAO,MAAyB;AACjE,SACE,gBAAAC,EAAC,OAAA,EAAI,OAAOD,GAAM,QAAQA,GAAM,SAAQ,aAAY,MAAK,QAAO,eAAW,IACzE,UAAA,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,GAAE;AAAA,MACF,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,IAAA;AAAA,EAAA,GAEnB;AAEJ;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type SpaceLoadError } from '../../core/index.js';
|
|
3
|
+
export interface LoadErrorRenderProps {
|
|
4
|
+
/** The terminal load failure. */
|
|
5
|
+
error: SpaceLoadError;
|
|
6
|
+
/** Retry the failed load (re-fetch config / re-download splat). */
|
|
7
|
+
retry: () => void;
|
|
8
|
+
/** Go back, when the host wired an `onLoadErrorExit` handler. */
|
|
9
|
+
exit?: () => void;
|
|
10
|
+
}
|
|
11
|
+
/** Fully replace the built-in load-error prompt. */
|
|
12
|
+
export type LoadErrorRenderer = (props: LoadErrorRenderProps) => ReactNode;
|
|
13
|
+
export interface SpaceLoadErrorOverlayProps {
|
|
14
|
+
onExit?: () => void;
|
|
15
|
+
render?: LoadErrorRenderer;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Prompt shown when a space fails to load after automatic retries are
|
|
19
|
+
* exhausted, so the page cannot hang on an infinite loading screen.
|
|
20
|
+
*
|
|
21
|
+
* Rendered through a portal to `document.body` at a very high z-index: the
|
|
22
|
+
* host's own loading UI is usually a `fixed` sibling *outside* the viewer
|
|
23
|
+
* subtree, and would otherwise cover this prompt — leaving the user staring at
|
|
24
|
+
* a spinner that never resolves.
|
|
25
|
+
*/
|
|
26
|
+
export default function SpaceLoadErrorOverlay({ onExit, render }: SpaceLoadErrorOverlayProps): import("react").ReactPortal | null;
|
|
27
|
+
//# sourceMappingURL=space-load-error-overlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space-load-error-overlay.d.ts","sourceRoot":"","sources":["../../../explore/overlays/space-load-error-overlay.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAEnD,OAAO,EAA2C,KAAK,cAAc,EAAE,MAAM,YAAY,CAAA;AAEzF,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,KAAK,EAAE,cAAc,CAAA;IACrB,mEAAmE;IACnE,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,oDAAoD;AACpD,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,oBAAoB,KAAK,SAAS,CAAA;AAE1E,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,sCA0C3F"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as r, jsxs as c } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback as m } from "react";
|
|
3
|
+
import { createPortal as p } from "react-dom";
|
|
4
|
+
import { useCaveWorldStore as d, useCaveWorldMessages as f } from "../../core/context/cave-world-context.js";
|
|
5
|
+
function v({ onExit: o, render: l }) {
|
|
6
|
+
const a = d((t) => t.spaceLoadError), s = d((t) => t.retrySpaceLoad), e = f(), n = m(() => s(), [s]);
|
|
7
|
+
if (!a || typeof document > "u") return null;
|
|
8
|
+
const i = a.stage === "config" ? e.loadError.configTitle : e.loadError.splatTitle, u = l ? l({ error: a, retry: n, exit: o }) : /* @__PURE__ */ r("div", { className: "cw-overlay-root cw-error-layer", role: "alertdialog", "aria-label": i, children: /* @__PURE__ */ c("div", { className: "cw-error", children: [
|
|
9
|
+
/* @__PURE__ */ r("div", { className: "cw-error__badge", "aria-hidden": !0, children: "!" }),
|
|
10
|
+
/* @__PURE__ */ c("div", { children: [
|
|
11
|
+
/* @__PURE__ */ r("p", { className: "cw-error__title", children: i }),
|
|
12
|
+
/* @__PURE__ */ r("p", { className: "cw-error__message", children: e.loadError.description })
|
|
13
|
+
] }),
|
|
14
|
+
/* @__PURE__ */ c("div", { className: "cw-error__actions", children: [
|
|
15
|
+
/* @__PURE__ */ r("button", { type: "button", className: "cw-button cw-button--primary", onClick: n, children: e.loadError.retry }),
|
|
16
|
+
o ? /* @__PURE__ */ r("button", { type: "button", className: "cw-button", onClick: o, children: e.loadError.exit }) : null
|
|
17
|
+
] })
|
|
18
|
+
] }) });
|
|
19
|
+
return p(u, document.body);
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
v as default
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=space-load-error-overlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space-load-error-overlay.js","sources":["../../../explore/overlays/space-load-error-overlay.tsx"],"sourcesContent":["import { useCallback, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\nimport { useCaveWorldMessages, useCaveWorldStore, type SpaceLoadError } from '../../core'\n\nexport interface LoadErrorRenderProps {\n /** The terminal load failure. */\n error: SpaceLoadError\n /** Retry the failed load (re-fetch config / re-download splat). */\n retry: () => void\n /** Go back, when the host wired an `onLoadErrorExit` handler. */\n exit?: () => void\n}\n\n/** Fully replace the built-in load-error prompt. */\nexport type LoadErrorRenderer = (props: LoadErrorRenderProps) => ReactNode\n\nexport interface SpaceLoadErrorOverlayProps {\n onExit?: () => void\n render?: LoadErrorRenderer\n}\n\n/**\n * Prompt shown when a space fails to load after automatic retries are\n * exhausted, so the page cannot hang on an infinite loading screen.\n *\n * Rendered through a portal to `document.body` at a very high z-index: the\n * host's own loading UI is usually a `fixed` sibling *outside* the viewer\n * subtree, and would otherwise cover this prompt — leaving the user staring at\n * a spinner that never resolves.\n */\nexport default function SpaceLoadErrorOverlay({ onExit, render }: SpaceLoadErrorOverlayProps) {\n const spaceLoadError = useCaveWorldStore((s) => s.spaceLoadError)\n const retrySpaceLoad = useCaveWorldStore((s) => s.retrySpaceLoad)\n const messages = useCaveWorldMessages()\n\n const retry = useCallback(() => retrySpaceLoad(), [retrySpaceLoad])\n\n if (!spaceLoadError) return null\n if (typeof document === 'undefined') return null\n\n const title =\n spaceLoadError.stage === 'config'\n ? messages.loadError.configTitle\n : messages.loadError.splatTitle\n\n const content = render ? (\n render({ error: spaceLoadError, retry, exit: onExit })\n ) : (\n <div className=\"cw-overlay-root cw-error-layer\" role=\"alertdialog\" aria-label={title}>\n <div className=\"cw-error\">\n <div className=\"cw-error__badge\" aria-hidden>\n !\n </div>\n <div>\n <p className=\"cw-error__title\">{title}</p>\n <p className=\"cw-error__message\">{messages.loadError.description}</p>\n </div>\n <div className=\"cw-error__actions\">\n <button type=\"button\" className=\"cw-button cw-button--primary\" onClick={retry}>\n {messages.loadError.retry}\n </button>\n {onExit ? (\n <button type=\"button\" className=\"cw-button\" onClick={onExit}>\n {messages.loadError.exit}\n </button>\n ) : null}\n </div>\n </div>\n </div>\n )\n\n return createPortal(content, document.body)\n}\n"],"names":["SpaceLoadErrorOverlay","onExit","render","spaceLoadError","useCaveWorldStore","s","retrySpaceLoad","messages","useCaveWorldMessages","retry","useCallback","title","content","jsxs","jsx","createPortal"],"mappings":";;;;AA8BA,SAAwBA,EAAsB,EAAE,QAAAC,GAAQ,QAAAC,KAAsC;AAC5F,QAAMC,IAAiBC,EAAkB,CAACC,MAAMA,EAAE,cAAc,GAC1DC,IAAiBF,EAAkB,CAACC,MAAMA,EAAE,cAAc,GAC1DE,IAAWC,EAAA,GAEXC,IAAQC,EAAY,MAAMJ,KAAkB,CAACA,CAAc,CAAC;AAGlE,MADI,CAACH,KACD,OAAO,WAAa,IAAa,QAAO;AAE5C,QAAMQ,IACJR,EAAe,UAAU,WACrBI,EAAS,UAAU,cACnBA,EAAS,UAAU,YAEnBK,IAAUV,IACdA,EAAO,EAAE,OAAOC,GAAgB,OAAAM,GAAO,MAAMR,GAAQ,sBAEpD,OAAA,EAAI,WAAU,kCAAiC,MAAK,eAAc,cAAYU,GAC7E,UAAA,gBAAAE,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,mBAAkB,eAAW,IAAC,UAAA,KAE7C;AAAA,sBACC,OAAA,EACC,UAAA;AAAA,MAAA,gBAAAA,EAAC,KAAA,EAAE,WAAU,mBAAmB,UAAAH,GAAM;AAAA,wBACrC,KAAA,EAAE,WAAU,qBAAqB,UAAAJ,EAAS,UAAU,YAAA,CAAY;AAAA,IAAA,GACnE;AAAA,IACA,gBAAAM,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,gCAA+B,SAASL,GACrE,UAAAF,EAAS,UAAU,MAAA,CACtB;AAAA,MACCN,IACC,gBAAAa,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,aAAY,SAASb,GAClD,UAAAM,EAAS,UAAU,KAAA,CACtB,IACE;AAAA,IAAA,EAAA,CACN;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAGF,SAAOQ,EAAaH,GAAS,SAAS,IAAI;AAC5C;"}
|