@thunderclap-engine/engine 0.0.0-stage → 1.1.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 +390 -0
- package/LICENSE +21 -0
- package/README.md +333 -2
- package/dist/analytics/analytics.d.ts +80 -0
- package/dist/analytics/analytics.js +129 -0
- package/dist/analytics/index.d.ts +1 -0
- package/dist/analytics/index.js +1 -0
- package/dist/anim/aim.d.ts +43 -0
- package/dist/anim/aim.js +157 -0
- package/dist/anim/clip.d.ts +98 -0
- package/dist/anim/clip.js +282 -0
- package/dist/anim/compress.d.ts +65 -0
- package/dist/anim/compress.js +339 -0
- package/dist/anim/foot-ik.d.ts +74 -0
- package/dist/anim/foot-ik.js +241 -0
- package/dist/anim/graph.d.ts +153 -0
- package/dist/anim/graph.js +532 -0
- package/dist/anim/ik.d.ts +105 -0
- package/dist/anim/ik.js +435 -0
- package/dist/anim/index.d.ts +36 -0
- package/dist/anim/index.js +21 -0
- package/dist/anim/match.d.ts +66 -0
- package/dist/anim/match.js +153 -0
- package/dist/anim/mixer.d.ts +113 -0
- package/dist/anim/mixer.js +314 -0
- package/dist/anim/morph.d.ts +41 -0
- package/dist/anim/morph.js +94 -0
- package/dist/anim/pose.d.ts +74 -0
- package/dist/anim/pose.js +254 -0
- package/dist/anim/quat.d.ts +44 -0
- package/dist/anim/quat.js +187 -0
- package/dist/anim/retarget.d.ts +97 -0
- package/dist/anim/retarget.js +366 -0
- package/dist/anim/root-motion.d.ts +44 -0
- package/dist/anim/root-motion.js +224 -0
- package/dist/anim/skin-pose.d.ts +39 -0
- package/dist/anim/skin-pose.js +53 -0
- package/dist/anim/socket.d.ts +47 -0
- package/dist/anim/socket.js +84 -0
- package/dist/anim/spring-chain.d.ts +73 -0
- package/dist/anim/spring-chain.js +294 -0
- package/dist/assets/atlas.d.ts +90 -0
- package/dist/assets/atlas.js +212 -0
- package/dist/assets/baked.d.ts +33 -0
- package/dist/assets/baked.js +38 -0
- package/dist/assets/bundle.d.ts +88 -0
- package/dist/assets/bundle.js +464 -0
- package/dist/assets/cache.d.ts +56 -0
- package/dist/assets/cache.js +123 -0
- package/dist/assets/gltf-load.d.ts +252 -0
- package/dist/assets/gltf-load.js +661 -0
- package/dist/assets/gltf-skin.d.ts +36 -0
- package/dist/assets/gltf-skin.js +109 -0
- package/dist/assets/gltf.d.ts +706 -0
- package/dist/assets/gltf.js +1376 -0
- package/dist/assets/index.d.ts +20 -0
- package/dist/assets/index.js +10 -0
- package/dist/assets/ktx2.d.ts +71 -0
- package/dist/assets/ktx2.js +213 -0
- package/dist/assets/manifest.d.ts +79 -0
- package/dist/assets/manifest.js +7 -0
- package/dist/assets/meshopt.d.ts +23 -0
- package/dist/assets/meshopt.js +403 -0
- package/dist/audio/audio.d.ts +733 -0
- package/dist/audio/audio.js +2013 -0
- package/dist/audio/dsp.d.ts +61 -0
- package/dist/audio/dsp.js +159 -0
- package/dist/audio/duck.d.ts +44 -0
- package/dist/audio/duck.js +101 -0
- package/dist/audio/envelope.d.ts +53 -0
- package/dist/audio/envelope.js +106 -0
- package/dist/audio/index.d.ts +13 -0
- package/dist/audio/index.js +14 -0
- package/dist/audio/music.d.ts +113 -0
- package/dist/audio/music.js +548 -0
- package/dist/audio/occlusion.d.ts +55 -0
- package/dist/audio/occlusion.js +61 -0
- package/dist/audio/persist.d.ts +23 -0
- package/dist/audio/persist.js +27 -0
- package/dist/audio/recipes.d.ts +55 -0
- package/dist/audio/recipes.js +227 -0
- package/dist/audio/send.d.ts +41 -0
- package/dist/audio/send.js +118 -0
- package/dist/audio/sprites.d.ts +59 -0
- package/dist/audio/sprites.js +43 -0
- package/dist/audio/synth.d.ts +103 -0
- package/dist/audio/synth.js +197 -0
- package/dist/audio/variations.d.ts +25 -0
- package/dist/audio/variations.js +55 -0
- package/dist/audio/zones.d.ts +100 -0
- package/dist/audio/zones.js +167 -0
- package/dist/core/detached-surface.d.ts +44 -0
- package/dist/core/detached-surface.js +104 -0
- package/dist/core/events.d.ts +24 -0
- package/dist/core/events.js +43 -0
- package/dist/core/game.d.ts +409 -0
- package/dist/core/game.js +530 -0
- package/dist/core/hash.d.ts +24 -0
- package/dist/core/hash.js +49 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.js +9 -0
- package/dist/core/loop.d.ts +113 -0
- package/dist/core/loop.js +185 -0
- package/dist/core/math.d.ts +58 -0
- package/dist/core/math.js +210 -0
- package/dist/core/noise.d.ts +40 -0
- package/dist/core/noise.js +247 -0
- package/dist/core/pool.d.ts +42 -0
- package/dist/core/pool.js +85 -0
- package/dist/core/random.d.ts +61 -0
- package/dist/core/random.js +199 -0
- package/dist/core/scene.d.ts +79 -0
- package/dist/core/scene.js +195 -0
- package/dist/core/timer.d.ts +66 -0
- package/dist/core/timer.js +286 -0
- package/dist/fx/billboard-wgsl.d.ts +29 -0
- package/dist/fx/billboard-wgsl.js +158 -0
- package/dist/fx/billboard.d.ts +249 -0
- package/dist/fx/billboard.js +702 -0
- package/dist/fx/debug-draw.d.ts +127 -0
- package/dist/fx/debug-draw.js +523 -0
- package/dist/fx/debug-wgsl.d.ts +7 -0
- package/dist/fx/debug-wgsl.js +32 -0
- package/dist/fx/decals-wgsl.d.ts +15 -0
- package/dist/fx/decals-wgsl.js +173 -0
- package/dist/fx/decals.d.ts +216 -0
- package/dist/fx/decals.js +607 -0
- package/dist/fx/effect.d.ts +129 -0
- package/dist/fx/effect.js +349 -0
- package/dist/fx/effects/hit-spark.json +48 -0
- package/dist/fx/effects/index.d.ts +8 -0
- package/dist/fx/effects/index.js +9 -0
- package/dist/fx/effects/magic-aura.json +47 -0
- package/dist/fx/effects/smoke-puff.json +34 -0
- package/dist/fx/emit-surface.d.ts +40 -0
- package/dist/fx/emit-surface.js +124 -0
- package/dist/fx/flicker.d.ts +30 -0
- package/dist/fx/flicker.js +42 -0
- package/dist/fx/index.d.ts +31 -0
- package/dist/fx/index.js +20 -0
- package/dist/fx/particles-wgsl.d.ts +57 -0
- package/dist/fx/particles-wgsl.js +828 -0
- package/dist/fx/particles.d.ts +566 -0
- package/dist/fx/particles.js +1533 -0
- package/dist/fx/random.d.ts +15 -0
- package/dist/fx/random.js +20 -0
- package/dist/fx/sky-wgsl.d.ts +23 -0
- package/dist/fx/sky-wgsl.js +127 -0
- package/dist/fx/sky.d.ts +96 -0
- package/dist/fx/sky.js +175 -0
- package/dist/fx/text-atlas.d.ts +143 -0
- package/dist/fx/text-atlas.js +327 -0
- package/dist/fx/trail-wgsl.d.ts +11 -0
- package/dist/fx/trail-wgsl.js +42 -0
- package/dist/fx/trail.d.ts +194 -0
- package/dist/fx/trail.js +555 -0
- package/dist/fx/water-wgsl.d.ts +34 -0
- package/dist/fx/water-wgsl.js +197 -0
- package/dist/fx/water.d.ts +176 -0
- package/dist/fx/water.js +371 -0
- package/dist/geom/collide/bvh.d.ts +151 -0
- package/dist/geom/collide/bvh.js +493 -0
- package/dist/geom/collide/debug.d.ts +14 -0
- package/dist/geom/collide/debug.js +74 -0
- package/dist/geom/collide/grid.d.ts +26 -0
- package/dist/geom/collide/grid.js +91 -0
- package/dist/geom/collide/index.d.ts +8 -0
- package/dist/geom/collide/index.js +8 -0
- package/dist/geom/collide/queries.d.ts +70 -0
- package/dist/geom/collide/queries.js +583 -0
- package/dist/geom/collide/serialize.d.ts +14 -0
- package/dist/geom/collide/serialize.js +145 -0
- package/dist/geom/collide/shapes.d.ts +161 -0
- package/dist/geom/collide/shapes.js +686 -0
- package/dist/geom/collide/slide.d.ts +66 -0
- package/dist/geom/collide/slide.js +375 -0
- package/dist/geom/collide/tile-slide.d.ts +88 -0
- package/dist/geom/collide/tile-slide.js +255 -0
- package/dist/geom/geometry.d.ts +95 -0
- package/dist/geom/geometry.js +322 -0
- package/dist/geom/heightfield.d.ts +72 -0
- package/dist/geom/heightfield.js +295 -0
- package/dist/geom/hull.d.ts +27 -0
- package/dist/geom/hull.js +279 -0
- package/dist/geom/index.d.ts +35 -0
- package/dist/geom/index.js +23 -0
- package/dist/geom/iso.d.ts +74 -0
- package/dist/geom/iso.js +89 -0
- package/dist/geom/lod.d.ts +29 -0
- package/dist/geom/lod.js +27 -0
- package/dist/geom/ops.d.ts +47 -0
- package/dist/geom/ops.js +285 -0
- package/dist/geom/primitives.d.ts +97 -0
- package/dist/geom/primitives.js +359 -0
- package/dist/geom/shapes.d.ts +43 -0
- package/dist/geom/shapes.js +88 -0
- package/dist/geom/simplify.d.ts +38 -0
- package/dist/geom/simplify.js +519 -0
- package/dist/geom/split.d.ts +37 -0
- package/dist/geom/split.js +413 -0
- package/dist/geom/sweep.d.ts +83 -0
- package/dist/geom/sweep.js +534 -0
- package/dist/geom/tangents.d.ts +16 -0
- package/dist/geom/tangents.js +124 -0
- package/dist/geom/triangulate.d.ts +19 -0
- package/dist/geom/triangulate.js +147 -0
- package/dist/host/default.d.ts +10 -0
- package/dist/host/default.js +10 -0
- package/dist/host/index.d.ts +4 -0
- package/dist/host/index.js +3 -0
- package/dist/host/types.d.ts +144 -0
- package/dist/host/types.js +1 -0
- package/dist/host/web-links.d.ts +38 -0
- package/dist/host/web-links.js +110 -0
- package/dist/host/web.d.ts +30 -0
- package/dist/host/web.js +216 -0
- package/dist/host/xr.d.ts +24 -0
- package/dist/host/xr.js +59 -0
- package/dist/i18n/i18n.d.ts +59 -0
- package/dist/i18n/i18n.js +241 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/message.d.ts +72 -0
- package/dist/i18n/message.js +369 -0
- package/dist/i18n/negotiate.d.ts +17 -0
- package/dist/i18n/negotiate.js +58 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1 -0
- package/dist/input/bindings.d.ts +31 -0
- package/dist/input/bindings.js +141 -0
- package/dist/input/clock.d.ts +44 -0
- package/dist/input/clock.js +49 -0
- package/dist/input/follow.d.ts +133 -0
- package/dist/input/follow.js +218 -0
- package/dist/input/gestures.d.ts +281 -0
- package/dist/input/gestures.js +662 -0
- package/dist/input/glyphs.d.ts +35 -0
- package/dist/input/glyphs.js +216 -0
- package/dist/input/gyro.d.ts +85 -0
- package/dist/input/gyro.js +140 -0
- package/dist/input/index.d.ts +19 -0
- package/dist/input/index.js +16 -0
- package/dist/input/input.d.ts +543 -0
- package/dist/input/input.js +1492 -0
- package/dist/input/look.d.ts +327 -0
- package/dist/input/look.js +681 -0
- package/dist/input/magnify.d.ts +177 -0
- package/dist/input/magnify.js +131 -0
- package/dist/input/pointer-dispatch.d.ts +138 -0
- package/dist/input/pointer-dispatch.js +180 -0
- package/dist/input/pointer-router.d.ts +204 -0
- package/dist/input/pointer-router.js +533 -0
- package/dist/input/pointer-sources.d.ts +164 -0
- package/dist/input/pointer-sources.js +306 -0
- package/dist/input/rays.d.ts +138 -0
- package/dist/input/rays.js +615 -0
- package/dist/input/record.d.ts +209 -0
- package/dist/input/record.js +601 -0
- package/dist/input/touch-zones.d.ts +147 -0
- package/dist/input/touch-zones.js +300 -0
- package/dist/input/types.d.ts +158 -0
- package/dist/input/types.js +1 -0
- package/dist/input/xr-source.d.ts +53 -0
- package/dist/input/xr-source.js +164 -0
- package/dist/nav/astar.d.ts +45 -0
- package/dist/nav/astar.js +182 -0
- package/dist/nav/corridor.d.ts +40 -0
- package/dist/nav/corridor.js +95 -0
- package/dist/nav/crowd.d.ts +94 -0
- package/dist/nav/crowd.js +624 -0
- package/dist/nav/flow.d.ts +61 -0
- package/dist/nav/flow.js +193 -0
- package/dist/nav/grid.d.ts +108 -0
- package/dist/nav/grid.js +210 -0
- package/dist/nav/heap.d.ts +22 -0
- package/dist/nav/heap.js +92 -0
- package/dist/nav/index.d.ts +37 -0
- package/dist/nav/index.js +19 -0
- package/dist/nav/mesh/areas.d.ts +44 -0
- package/dist/nav/mesh/areas.js +98 -0
- package/dist/nav/mesh/bake-options.d.ts +33 -0
- package/dist/nav/mesh/bake-options.js +76 -0
- package/dist/nav/mesh/contour.d.ts +22 -0
- package/dist/nav/mesh/contour.js +323 -0
- package/dist/nav/mesh/flow3.d.ts +35 -0
- package/dist/nav/mesh/flow3.js +229 -0
- package/dist/nav/mesh/links.d.ts +38 -0
- package/dist/nav/mesh/links.js +72 -0
- package/dist/nav/mesh/mesh-path.d.ts +152 -0
- package/dist/nav/mesh/mesh-path.js +643 -0
- package/dist/nav/mesh/mesh-reach.d.ts +78 -0
- package/dist/nav/mesh/mesh-reach.js +450 -0
- package/dist/nav/mesh/navmesh.d.ts +117 -0
- package/dist/nav/mesh/navmesh.js +647 -0
- package/dist/nav/mesh/polymesh.d.ts +24 -0
- package/dist/nav/mesh/polymesh.js +384 -0
- package/dist/nav/mesh/regions.d.ts +12 -0
- package/dist/nav/mesh/regions.js +367 -0
- package/dist/nav/mesh/serialize.d.ts +13 -0
- package/dist/nav/mesh/serialize.js +197 -0
- package/dist/nav/mesh/voxelize.d.ts +111 -0
- package/dist/nav/mesh/voxelize.js +552 -0
- package/dist/nav/obstacles.d.ts +75 -0
- package/dist/nav/obstacles.js +294 -0
- package/dist/nav/path.d.ts +59 -0
- package/dist/nav/path.js +177 -0
- package/dist/nav/query-queue.d.ts +46 -0
- package/dist/nav/query-queue.js +308 -0
- package/dist/nav/reach.d.ts +53 -0
- package/dist/nav/reach.js +148 -0
- package/dist/nav/steer.d.ts +36 -0
- package/dist/nav/steer.js +78 -0
- package/dist/platform/boot.d.ts +28 -0
- package/dist/platform/boot.js +43 -0
- package/dist/platform/device-mode.d.ts +40 -0
- package/dist/platform/device-mode.js +104 -0
- package/dist/platform/device.d.ts +31 -0
- package/dist/platform/device.js +91 -0
- package/dist/platform/environment.d.ts +42 -0
- package/dist/platform/environment.js +82 -0
- package/dist/platform/gpu.d.ts +40 -0
- package/dist/platform/gpu.js +57 -0
- package/dist/platform/index.d.ts +18 -0
- package/dist/platform/index.js +10 -0
- package/dist/platform/letterbox.d.ts +43 -0
- package/dist/platform/letterbox.js +57 -0
- package/dist/platform/links.d.ts +20 -0
- package/dist/platform/links.js +43 -0
- package/dist/platform/screens.d.ts +36 -0
- package/dist/platform/screens.js +138 -0
- package/dist/platform/surface.d.ts +72 -0
- package/dist/platform/surface.js +157 -0
- package/dist/platform/xr-fake.d.ts +168 -0
- package/dist/platform/xr-fake.js +434 -0
- package/dist/platform/xr-surface.d.ts +120 -0
- package/dist/platform/xr-surface.js +214 -0
- package/dist/platform/xr-types.d.ts +262 -0
- package/dist/post/ao.d.ts +12 -0
- package/dist/post/ao.js +136 -0
- package/dist/post/blend.d.ts +27 -0
- package/dist/post/blend.js +129 -0
- package/dist/post/depth-pass.d.ts +43 -0
- package/dist/post/depth-pass.js +118 -0
- package/dist/post/dof.d.ts +1 -0
- package/dist/post/dof.js +66 -0
- package/dist/post/exposure.d.ts +80 -0
- package/dist/post/exposure.js +322 -0
- package/dist/post/index.d.ts +12 -0
- package/dist/post/index.js +11 -0
- package/dist/post/lens-dirt.d.ts +13 -0
- package/dist/post/lens-dirt.js +91 -0
- package/dist/post/lut.d.ts +19 -0
- package/dist/post/lut.js +50 -0
- package/dist/post/motion-blur.d.ts +9 -0
- package/dist/post/motion-blur.js +78 -0
- package/dist/post/post-stack.d.ts +302 -0
- package/dist/post/post-stack.js +1137 -0
- package/dist/post/settings.d.ts +485 -0
- package/dist/post/settings.js +416 -0
- package/dist/post/shaders.d.ts +25 -0
- package/dist/post/shaders.js +410 -0
- package/dist/post/ssr.d.ts +16 -0
- package/dist/post/ssr.js +155 -0
- package/dist/post/taa.d.ts +74 -0
- package/dist/post/taa.js +235 -0
- package/dist/post/white-balance.d.ts +25 -0
- package/dist/post/white-balance.js +98 -0
- package/dist/render/bindings.d.ts +98 -0
- package/dist/render/bindings.js +281 -0
- package/dist/render/blend.d.ts +13 -0
- package/dist/render/blend.js +26 -0
- package/dist/render/camera-2d.d.ts +72 -0
- package/dist/render/camera-2d.js +92 -0
- package/dist/render/camera.d.ts +302 -0
- package/dist/render/camera.js +671 -0
- package/dist/render/color.d.ts +16 -0
- package/dist/render/color.js +41 -0
- package/dist/render/compressed.d.ts +104 -0
- package/dist/render/compressed.js +248 -0
- package/dist/render/diagnostics.d.ts +15 -0
- package/dist/render/diagnostics.js +43 -0
- package/dist/render/dynamic-resolution.d.ts +70 -0
- package/dist/render/dynamic-resolution.js +126 -0
- package/dist/render/fake-gpu.d.ts +204 -0
- package/dist/render/fake-gpu.js +426 -0
- package/dist/render/flipbook.d.ts +56 -0
- package/dist/render/flipbook.js +87 -0
- package/dist/render/frame.d.ts +278 -0
- package/dist/render/frame.js +174 -0
- package/dist/render/fullscreen.d.ts +54 -0
- package/dist/render/fullscreen.js +91 -0
- package/dist/render/gpu-timer.d.ts +73 -0
- package/dist/render/gpu-timer.js +186 -0
- package/dist/render/index.d.ts +53 -0
- package/dist/render/index.js +29 -0
- package/dist/render/instance-list.d.ts +185 -0
- package/dist/render/instance-list.js +547 -0
- package/dist/render/lights.d.ts +181 -0
- package/dist/render/lights.js +233 -0
- package/dist/render/lod.d.ts +54 -0
- package/dist/render/lod.js +52 -0
- package/dist/render/material.d.ts +165 -0
- package/dist/render/material.js +292 -0
- package/dist/render/mesh.d.ts +284 -0
- package/dist/render/mesh.js +472 -0
- package/dist/render/mipmap.d.ts +16 -0
- package/dist/render/mipmap.js +121 -0
- package/dist/render/parallax.d.ts +50 -0
- package/dist/render/parallax.js +47 -0
- package/dist/render/pbr-wgsl.d.ts +31 -0
- package/dist/render/pbr-wgsl.js +119 -0
- package/dist/render/ping-pong.d.ts +42 -0
- package/dist/render/ping-pong.js +74 -0
- package/dist/render/renderer.d.ts +741 -0
- package/dist/render/renderer.js +2486 -0
- package/dist/render/scene-pipelines.d.ts +44 -0
- package/dist/render/scene-pipelines.js +92 -0
- package/dist/render/scene-target.d.ts +170 -0
- package/dist/render/scene-target.js +450 -0
- package/dist/render/shadow.d.ts +74 -0
- package/dist/render/shadow.js +208 -0
- package/dist/render/skin.d.ts +112 -0
- package/dist/render/skin.js +240 -0
- package/dist/render/snapshot.d.ts +36 -0
- package/dist/render/snapshot.js +34 -0
- package/dist/render/standard.d.ts +162 -0
- package/dist/render/standard.js +263 -0
- package/dist/render/texture.d.ts +142 -0
- package/dist/render/texture.js +228 -0
- package/dist/render/tile-layer.d.ts +110 -0
- package/dist/render/tile-layer.js +304 -0
- package/dist/render/transform.d.ts +115 -0
- package/dist/render/transform.js +318 -0
- package/dist/render/wgsl.d.ts +131 -0
- package/dist/render/wgsl.js +528 -0
- package/dist/save/codec.d.ts +49 -0
- package/dist/save/codec.js +169 -0
- package/dist/save/index.d.ts +8 -0
- package/dist/save/index.js +8 -0
- package/dist/save/journal.d.ts +24 -0
- package/dist/save/journal.js +102 -0
- package/dist/save/migrate.d.ts +15 -0
- package/dist/save/migrate.js +37 -0
- package/dist/save/schema.d.ts +72 -0
- package/dist/save/schema.js +154 -0
- package/dist/save/settings.d.ts +28 -0
- package/dist/save/settings.js +59 -0
- package/dist/save/slots.d.ts +56 -0
- package/dist/save/slots.js +200 -0
- package/dist/save/storage.d.ts +35 -0
- package/dist/save/storage.js +62 -0
- package/dist/save/store.d.ts +114 -0
- package/dist/save/store.js +269 -0
- package/dist/testing/fake-host.d.ts +103 -0
- package/dist/testing/fake-host.js +163 -0
- package/dist/testing/fixed-clock.d.ts +25 -0
- package/dist/testing/fixed-clock.js +30 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/test-game.d.ts +76 -0
- package/dist/testing/test-game.js +92 -0
- package/dist/tween/ease.d.ts +77 -0
- package/dist/tween/ease.js +192 -0
- package/dist/tween/index.d.ts +8 -0
- package/dist/tween/index.js +7 -0
- package/dist/tween/timeline.d.ts +78 -0
- package/dist/tween/timeline.js +269 -0
- package/dist/tween/tween.d.ts +168 -0
- package/dist/tween/tween.js +320 -0
- package/dist/ui/anchor.d.ts +206 -0
- package/dist/ui/anchor.js +307 -0
- package/dist/ui/caption.d.ts +122 -0
- package/dist/ui/caption.js +286 -0
- package/dist/ui/cursor.d.ts +105 -0
- package/dist/ui/cursor.js +261 -0
- package/dist/ui/dom.d.ts +30 -0
- package/dist/ui/dom.js +92 -0
- package/dist/ui/floats.d.ts +86 -0
- package/dist/ui/floats.js +260 -0
- package/dist/ui/hud.d.ts +198 -0
- package/dist/ui/hud.js +431 -0
- package/dist/ui/index.d.ts +37 -0
- package/dist/ui/index.js +34 -0
- package/dist/ui/inventory-card.d.ts +52 -0
- package/dist/ui/inventory-card.js +173 -0
- package/dist/ui/inventory-context.d.ts +29 -0
- package/dist/ui/inventory-context.js +125 -0
- package/dist/ui/inventory-drag.d.ts +63 -0
- package/dist/ui/inventory-drag.js +394 -0
- package/dist/ui/inventory-grid.d.ts +66 -0
- package/dist/ui/inventory-grid.js +625 -0
- package/dist/ui/inventory-radial.d.ts +39 -0
- package/dist/ui/inventory-radial.js +168 -0
- package/dist/ui/inventory.d.ts +128 -0
- package/dist/ui/inventory.js +154 -0
- package/dist/ui/layout.d.ts +356 -0
- package/dist/ui/layout.js +856 -0
- package/dist/ui/link.d.ts +64 -0
- package/dist/ui/link.js +155 -0
- package/dist/ui/loading.d.ts +40 -0
- package/dist/ui/loading.js +157 -0
- package/dist/ui/loupe.d.ts +74 -0
- package/dist/ui/loupe.js +164 -0
- package/dist/ui/menu-nav.d.ts +33 -0
- package/dist/ui/menu-nav.js +28 -0
- package/dist/ui/minimap-canvas.d.ts +145 -0
- package/dist/ui/minimap-canvas.js +460 -0
- package/dist/ui/notify.d.ts +40 -0
- package/dist/ui/notify.js +141 -0
- package/dist/ui/orb.d.ts +53 -0
- package/dist/ui/orb.js +304 -0
- package/dist/ui/overlay.d.ts +213 -0
- package/dist/ui/overlay.js +394 -0
- package/dist/ui/padnav.d.ts +53 -0
- package/dist/ui/padnav.js +146 -0
- package/dist/ui/perf.d.ts +130 -0
- package/dist/ui/perf.js +329 -0
- package/dist/ui/rotate-card.d.ts +54 -0
- package/dist/ui/rotate-card.js +97 -0
- package/dist/ui/stack.d.ts +128 -0
- package/dist/ui/stack.js +312 -0
- package/dist/ui/styles.d.ts +13 -0
- package/dist/ui/styles.js +200 -0
- package/dist/ui/text-scale.d.ts +67 -0
- package/dist/ui/text-scale.js +102 -0
- package/dist/ui/theme.d.ts +70 -0
- package/dist/ui/theme.js +98 -0
- package/dist/ui/toast.d.ts +23 -0
- package/dist/ui/toast.js +46 -0
- package/dist/ui/tooltip.d.ts +89 -0
- package/dist/ui/tooltip.js +333 -0
- package/dist/ui/widgets-2.d.ts +134 -0
- package/dist/ui/widgets-2.js +399 -0
- package/dist/ui/widgets-3.d.ts +91 -0
- package/dist/ui/widgets-3.js +212 -0
- package/dist/ui/widgets.d.ts +34 -0
- package/dist/ui/widgets.js +50 -0
- package/dist/ui/world-panel/index.d.ts +5 -0
- package/dist/ui/world-panel/index.js +5 -0
- package/dist/ui/world-panel/layout.d.ts +38 -0
- package/dist/ui/world-panel/layout.js +68 -0
- package/dist/ui/world-panel/paint.d.ts +96 -0
- package/dist/ui/world-panel/paint.js +136 -0
- package/dist/ui/world-panel/panel.d.ts +235 -0
- package/dist/ui/world-panel/panel.js +762 -0
- package/dist/ui/world-panel/wgsl.d.ts +10 -0
- package/dist/ui/world-panel/wgsl.js +52 -0
- package/dist/ui/world-panel/widgets.d.ts +207 -0
- package/dist/ui/world-panel/widgets.js +569 -0
- package/dist/voxel/chunks.d.ts +77 -0
- package/dist/voxel/chunks.js +149 -0
- package/dist/voxel/grid.d.ts +84 -0
- package/dist/voxel/grid.js +223 -0
- package/dist/voxel/index.d.ts +22 -0
- package/dist/voxel/index.js +7 -0
- package/dist/voxel/mesher-worker.d.ts +14 -0
- package/dist/voxel/mesher-worker.js +47 -0
- package/dist/voxel/mesher.d.ts +73 -0
- package/dist/voxel/mesher.js +306 -0
- package/dist/voxel/ray.d.ts +32 -0
- package/dist/voxel/ray.js +73 -0
- package/dist/voxel/wgsl.d.ts +16 -0
- package/dist/voxel/wgsl.js +28 -0
- package/dist/voxel/worker-client.d.ts +79 -0
- package/dist/voxel/worker-client.js +122 -0
- package/package.json +177 -3
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tooltips (ws/ui-3): one shared `role="tooltip"` element per overlay that follows either a DOM
|
|
3
|
+
* element (hover after a delay and focus show it; pointer leave, blur and Escape hide it) or a
|
|
4
|
+
* world point (an `AnchorHandle` or `[x, y, z]`, riding `Anchors` and hidden with it). The
|
|
5
|
+
* element lives on the `toasts` layer, which is never inert, so a tooltip reads over a modal
|
|
6
|
+
* panel's controls as well as over the HUD. Placement is the pure `placeTooltip`: the asked
|
|
7
|
+
* side, flipped to its opposite when it would leave the layer, centred on the anchor and clamped.
|
|
8
|
+
*/
|
|
9
|
+
import type { AnchorHandle, Anchors } from './anchor.js';
|
|
10
|
+
import type { Rect } from './overlay.js';
|
|
11
|
+
export type TooltipSide = 'top' | 'bottom' | 'left' | 'right';
|
|
12
|
+
export type TooltipPlacement = TooltipSide | 'auto';
|
|
13
|
+
/** What a tooltip follows: an element, an anchored element, or a world point. */
|
|
14
|
+
export type TooltipTarget = HTMLElement | AnchorHandle | ArrayLike<number>;
|
|
15
|
+
export interface TooltipOptions {
|
|
16
|
+
/** ms from pointer enter to show (focus shows at once). Default 400. */
|
|
17
|
+
delay?: number;
|
|
18
|
+
/** The side of the target to sit on; `auto` tries top, bottom, right, left. Default `auto`. */
|
|
19
|
+
placement?: TooltipPlacement;
|
|
20
|
+
/** Draw the arrow. Default true. */
|
|
21
|
+
arrow?: boolean;
|
|
22
|
+
/** Keep it up while the pointer is over the tooltip itself (links, buttons). Default false. */
|
|
23
|
+
interactive?: boolean;
|
|
24
|
+
/** CSS px between the target and the tooltip. Default 8. */
|
|
25
|
+
gap?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface Tooltip {
|
|
28
|
+
/** The overlay's shared tooltip element (`role="tooltip"`). */
|
|
29
|
+
readonly element: HTMLElement;
|
|
30
|
+
readonly target: TooltipTarget;
|
|
31
|
+
/** True while this tooltip owns the shared element and it is shown. */
|
|
32
|
+
readonly visible: boolean;
|
|
33
|
+
/** The side it landed on (`placeTooltip`'s choice), or null while hidden. */
|
|
34
|
+
readonly placement: TooltipSide | null;
|
|
35
|
+
set(content: string | Node): void;
|
|
36
|
+
show(): void;
|
|
37
|
+
hide(): void;
|
|
38
|
+
/** Unhook the target (and drop a world point's anchor). */
|
|
39
|
+
dispose(): void;
|
|
40
|
+
}
|
|
41
|
+
/** What the tooltips need from their overlay (`Overlay` fits). */
|
|
42
|
+
export interface TooltipHost {
|
|
43
|
+
readonly layers: {
|
|
44
|
+
readonly hud: HTMLElement;
|
|
45
|
+
readonly toasts: HTMLElement;
|
|
46
|
+
};
|
|
47
|
+
/** The overlay's box: in `css` units the toasts layer covers it. */
|
|
48
|
+
readonly rect: Readonly<Rect>;
|
|
49
|
+
/** In `frame` units the toasts layer is the frame (`anchors().frame.rect`), else the box. */
|
|
50
|
+
readonly units: 'frame' | 'css';
|
|
51
|
+
/** The overlay's `Anchors`; throws until a camera built it. Needed for world-point targets. */
|
|
52
|
+
anchors(): Anchors;
|
|
53
|
+
}
|
|
54
|
+
/** The overlay's tooltip set: one element, many targets. */
|
|
55
|
+
export interface Tooltips {
|
|
56
|
+
readonly element: HTMLElement;
|
|
57
|
+
/** The tooltip showing now, if any. */
|
|
58
|
+
readonly active: Tooltip | null;
|
|
59
|
+
tooltip(target: TooltipTarget, content: string | Node, opts?: TooltipOptions): Tooltip;
|
|
60
|
+
/** Re-place a shown world tooltip (after `anchors.update()`); `overlay.updateAnchors` calls it. */
|
|
61
|
+
update(): void;
|
|
62
|
+
dispose(): void;
|
|
63
|
+
}
|
|
64
|
+
export interface TooltipPlace {
|
|
65
|
+
x: number;
|
|
66
|
+
y: number;
|
|
67
|
+
side: TooltipSide;
|
|
68
|
+
/** The arrow's distance along the tooltip's near edge, from its left or top. */
|
|
69
|
+
arrow: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Where a tooltip of `size` goes beside `anchor` inside `frame` (same units). `auto` takes the
|
|
73
|
+
* first of top, bottom, right, left that fits, else the side with the most room; a named side
|
|
74
|
+
* flips to its opposite when it does not fit and the opposite does. The box is centred on the
|
|
75
|
+
* anchor along the other axis and clamped into the frame; `arrow` says where the anchor's centre
|
|
76
|
+
* is along the near edge, kept `inset` from the corners.
|
|
77
|
+
*/
|
|
78
|
+
export declare function placeTooltip(anchor: Rect, size: {
|
|
79
|
+
width: number;
|
|
80
|
+
height: number;
|
|
81
|
+
}, frame: Rect, placement?: TooltipPlacement, gap?: number, inset?: number): TooltipPlace;
|
|
82
|
+
/** One shared tooltip element on the host's `toasts` layer. See the module comment. */
|
|
83
|
+
export declare function createTooltips(host: TooltipHost): Tooltips;
|
|
84
|
+
/**
|
|
85
|
+
* Stylesheet for the tooltip (design px, theme tokens).
|
|
86
|
+
*/
|
|
87
|
+
export declare const TOOLTIP_CSS: string;
|
|
88
|
+
/** Add `TOOLTIP_CSS` to `doc` once (the first tooltip does it). */
|
|
89
|
+
export declare function ensureTooltipStyles(doc?: Document): void;
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { h } from './dom.js';
|
|
2
|
+
import { toFrameUnits } from './text-scale.js';
|
|
3
|
+
const OPPOSITE = {
|
|
4
|
+
top: 'bottom',
|
|
5
|
+
bottom: 'top',
|
|
6
|
+
left: 'right',
|
|
7
|
+
right: 'left',
|
|
8
|
+
};
|
|
9
|
+
const ORDER = ['top', 'bottom', 'right', 'left'];
|
|
10
|
+
/**
|
|
11
|
+
* Where a tooltip of `size` goes beside `anchor` inside `frame` (same units). `auto` takes the
|
|
12
|
+
* first of top, bottom, right, left that fits, else the side with the most room; a named side
|
|
13
|
+
* flips to its opposite when it does not fit and the opposite does. The box is centred on the
|
|
14
|
+
* anchor along the other axis and clamped into the frame; `arrow` says where the anchor's centre
|
|
15
|
+
* is along the near edge, kept `inset` from the corners.
|
|
16
|
+
*/
|
|
17
|
+
export function placeTooltip(anchor, size, frame, placement = 'auto', gap = 8, inset = 12) {
|
|
18
|
+
const room = {
|
|
19
|
+
top: anchor.y - frame.y - gap,
|
|
20
|
+
bottom: frame.y + frame.height - (anchor.y + anchor.height) - gap,
|
|
21
|
+
right: frame.x + frame.width - (anchor.x + anchor.width) - gap,
|
|
22
|
+
left: anchor.x - frame.x - gap,
|
|
23
|
+
};
|
|
24
|
+
const fits = (s) => room[s] >= (s === 'left' || s === 'right' ? size.width : size.height);
|
|
25
|
+
let side;
|
|
26
|
+
if (placement === 'auto') {
|
|
27
|
+
side = ORDER.find(fits) ?? ORDER.reduce((a, b) => (room[b] > room[a] ? b : a));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
side = placement;
|
|
31
|
+
if (!fits(side) && fits(OPPOSITE[side]))
|
|
32
|
+
side = OPPOSITE[side];
|
|
33
|
+
}
|
|
34
|
+
const cx = anchor.x + anchor.width / 2;
|
|
35
|
+
const cy = anchor.y + anchor.height / 2;
|
|
36
|
+
let x;
|
|
37
|
+
let y;
|
|
38
|
+
switch (side) {
|
|
39
|
+
case 'top':
|
|
40
|
+
x = cx - size.width / 2;
|
|
41
|
+
y = anchor.y - gap - size.height;
|
|
42
|
+
break;
|
|
43
|
+
case 'bottom':
|
|
44
|
+
x = cx - size.width / 2;
|
|
45
|
+
y = anchor.y + anchor.height + gap;
|
|
46
|
+
break;
|
|
47
|
+
case 'right':
|
|
48
|
+
x = anchor.x + anchor.width + gap;
|
|
49
|
+
y = cy - size.height / 2;
|
|
50
|
+
break;
|
|
51
|
+
case 'left':
|
|
52
|
+
x = anchor.x - gap - size.width;
|
|
53
|
+
y = cy - size.height / 2;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
x = Math.max(frame.x, Math.min(frame.x + frame.width - size.width, x));
|
|
57
|
+
y = Math.max(frame.y, Math.min(frame.y + frame.height - size.height, y));
|
|
58
|
+
const along = side === 'top' || side === 'bottom' ? cx - x : cy - y;
|
|
59
|
+
const span = side === 'top' || side === 'bottom' ? size.width : size.height;
|
|
60
|
+
const arrow = Math.max(inset, Math.min(span - inset, along));
|
|
61
|
+
return { x, y, side, arrow };
|
|
62
|
+
}
|
|
63
|
+
let tooltipCounter = 0;
|
|
64
|
+
const isAnchorHandle = (t) => typeof t === 'object' && t !== null && 'el' in t && typeof t.set === 'function';
|
|
65
|
+
/** One shared tooltip element on the host's `toasts` layer. See the module comment. */
|
|
66
|
+
export function createTooltips(host) {
|
|
67
|
+
const layer = host.layers.toasts;
|
|
68
|
+
const doc = layer.ownerDocument;
|
|
69
|
+
ensureTooltipStyles(doc);
|
|
70
|
+
const id = `tc-tooltip-${++tooltipCounter}`;
|
|
71
|
+
const body = h('div', { class: 'tc-tooltip-body' });
|
|
72
|
+
const arrowEl = h('span', { class: 'tc-tooltip-arrow', 'aria-hidden': 'true' });
|
|
73
|
+
const element = h('div', { class: 'tc-tooltip', role: 'tooltip', id, hidden: true }, body, arrowEl);
|
|
74
|
+
layer.append(element);
|
|
75
|
+
let active = null;
|
|
76
|
+
let hoveringTip = false;
|
|
77
|
+
let hideTimer = null;
|
|
78
|
+
const anchorRect = { x: 0, y: 0, width: 0, height: 0 };
|
|
79
|
+
const frameRect = { x: 0, y: 0, width: 0, height: 0 };
|
|
80
|
+
const size = { width: 0, height: 0 };
|
|
81
|
+
const NO_FRAME = { x: 0, y: 0, width: 0, height: 0 };
|
|
82
|
+
// The overlay's anchors once a world point built them: their frame is the one source for
|
|
83
|
+
// where the frame is (ws/ui-4); before that, an empty frame.
|
|
84
|
+
let anchors = null;
|
|
85
|
+
const frameOf = () => anchors?.frame.rect ?? NO_FRAME;
|
|
86
|
+
function place(entry) {
|
|
87
|
+
const t = entry.target;
|
|
88
|
+
if (t instanceof HTMLElement) {
|
|
89
|
+
const lr = layer.getBoundingClientRect();
|
|
90
|
+
const r = t.getBoundingClientRect();
|
|
91
|
+
anchorRect.x = r.left - lr.left;
|
|
92
|
+
anchorRect.y = r.top - lr.top;
|
|
93
|
+
anchorRect.width = r.width;
|
|
94
|
+
anchorRect.height = r.height;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const handle = entry.handle;
|
|
98
|
+
if (!handle.visible) {
|
|
99
|
+
if (!element.hidden)
|
|
100
|
+
element.hidden = true;
|
|
101
|
+
entry.side = null;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Our proxy rides the tooltip layer; a caller's handle rides the hud layer (the frame),
|
|
105
|
+
// which the toasts layer only matches in frame units (in css units it is the whole root).
|
|
106
|
+
const shift = entry.ownsHandle || host.units === 'frame';
|
|
107
|
+
const fr = frameOf();
|
|
108
|
+
anchorRect.x = handle.x + (shift ? 0 : fr.x);
|
|
109
|
+
anchorRect.y = handle.y + (shift ? 0 : fr.y);
|
|
110
|
+
anchorRect.width = 0;
|
|
111
|
+
anchorRect.height = 0;
|
|
112
|
+
}
|
|
113
|
+
if (element.hidden)
|
|
114
|
+
element.hidden = false;
|
|
115
|
+
size.width = element.offsetWidth;
|
|
116
|
+
size.height = element.offsetHeight;
|
|
117
|
+
const box = host.units === 'frame' ? frameOf() : host.rect;
|
|
118
|
+
frameRect.width = box.width;
|
|
119
|
+
frameRect.height = box.height;
|
|
120
|
+
const p = placeTooltip(anchorRect, size, frameRect, entry.asked, entry.gap);
|
|
121
|
+
if (p.x !== entry.x || p.y !== entry.y) {
|
|
122
|
+
entry.x = p.x;
|
|
123
|
+
entry.y = p.y;
|
|
124
|
+
element.style.transform = `translate(${p.x}px, ${p.y}px)`;
|
|
125
|
+
}
|
|
126
|
+
if (p.side !== entry.side) {
|
|
127
|
+
entry.side = p.side;
|
|
128
|
+
element.dataset.placement = p.side;
|
|
129
|
+
}
|
|
130
|
+
if (p.arrow !== entry.arrowAt) {
|
|
131
|
+
entry.arrowAt = p.arrow;
|
|
132
|
+
element.style.setProperty('--tc-tooltip-arrow', `${p.arrow}px`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const clearShow = (entry) => {
|
|
136
|
+
if (entry.showTimer) {
|
|
137
|
+
clearTimeout(entry.showTimer);
|
|
138
|
+
entry.showTimer = null;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
function activate(entry) {
|
|
142
|
+
clearShow(entry);
|
|
143
|
+
if (active && active !== entry)
|
|
144
|
+
deactivate(active);
|
|
145
|
+
active = entry;
|
|
146
|
+
body.replaceChildren(entry.content);
|
|
147
|
+
element.toggleAttribute('data-interactive', entry.interactive);
|
|
148
|
+
element.toggleAttribute('data-no-arrow', !entry.arrow);
|
|
149
|
+
if (entry.target instanceof HTMLElement)
|
|
150
|
+
entry.target.setAttribute('aria-describedby', id);
|
|
151
|
+
entry.x = entry.y = entry.arrowAt = Number.NaN;
|
|
152
|
+
place(entry);
|
|
153
|
+
}
|
|
154
|
+
function deactivate(entry) {
|
|
155
|
+
clearShow(entry);
|
|
156
|
+
if (entry.target instanceof HTMLElement)
|
|
157
|
+
entry.target.removeAttribute('aria-describedby');
|
|
158
|
+
if (active === entry) {
|
|
159
|
+
active = null;
|
|
160
|
+
element.hidden = true;
|
|
161
|
+
entry.side = null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
element.addEventListener('pointerenter', () => {
|
|
165
|
+
hoveringTip = true;
|
|
166
|
+
if (hideTimer) {
|
|
167
|
+
clearTimeout(hideTimer);
|
|
168
|
+
hideTimer = null;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
element.addEventListener('pointerleave', () => {
|
|
172
|
+
hoveringTip = false;
|
|
173
|
+
if (active?.interactive)
|
|
174
|
+
deactivate(active);
|
|
175
|
+
});
|
|
176
|
+
return {
|
|
177
|
+
element,
|
|
178
|
+
get active() {
|
|
179
|
+
return active ? active.tip : null;
|
|
180
|
+
},
|
|
181
|
+
tooltip(target, content, opts = {}) {
|
|
182
|
+
const isEl = target instanceof HTMLElement;
|
|
183
|
+
let handle = null;
|
|
184
|
+
let ownsHandle = false;
|
|
185
|
+
if (!isEl) {
|
|
186
|
+
if (isAnchorHandle(target))
|
|
187
|
+
handle = target;
|
|
188
|
+
else {
|
|
189
|
+
// A world point: a zero-size proxy on the hud layer rides the anchors.
|
|
190
|
+
const proxy = h('span', { class: 'tc-tooltip-anchor', 'aria-hidden': 'true' });
|
|
191
|
+
anchors = host.anchors();
|
|
192
|
+
handle = anchors.add(proxy, target, { layer: 'toasts' });
|
|
193
|
+
ownsHandle = true;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const delay = opts.delay ?? 400;
|
|
197
|
+
const onEnter = () => {
|
|
198
|
+
if (active === entry)
|
|
199
|
+
return;
|
|
200
|
+
clearShow(entry);
|
|
201
|
+
entry.showTimer = setTimeout(() => {
|
|
202
|
+
entry.showTimer = null;
|
|
203
|
+
activate(entry);
|
|
204
|
+
}, delay);
|
|
205
|
+
};
|
|
206
|
+
const onLeave = () => {
|
|
207
|
+
clearShow(entry);
|
|
208
|
+
if (active !== entry)
|
|
209
|
+
return;
|
|
210
|
+
if (!entry.interactive) {
|
|
211
|
+
deactivate(entry);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (hideTimer)
|
|
215
|
+
clearTimeout(hideTimer);
|
|
216
|
+
hideTimer = setTimeout(() => {
|
|
217
|
+
hideTimer = null;
|
|
218
|
+
if (!hoveringTip && active === entry)
|
|
219
|
+
deactivate(entry);
|
|
220
|
+
}, 120);
|
|
221
|
+
};
|
|
222
|
+
const onFocus = () => activate(entry);
|
|
223
|
+
const onKey = (e) => {
|
|
224
|
+
if (e.key === 'Escape' && active === entry)
|
|
225
|
+
deactivate(entry);
|
|
226
|
+
};
|
|
227
|
+
const tip = {
|
|
228
|
+
element,
|
|
229
|
+
target,
|
|
230
|
+
get visible() {
|
|
231
|
+
return active === entry && !element.hidden;
|
|
232
|
+
},
|
|
233
|
+
get placement() {
|
|
234
|
+
return active === entry ? entry.side : null;
|
|
235
|
+
},
|
|
236
|
+
set(c) {
|
|
237
|
+
entry.content = c;
|
|
238
|
+
if (active === entry) {
|
|
239
|
+
body.replaceChildren(c);
|
|
240
|
+
entry.x = Number.NaN;
|
|
241
|
+
place(entry);
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
show() {
|
|
245
|
+
activate(entry);
|
|
246
|
+
},
|
|
247
|
+
hide() {
|
|
248
|
+
deactivate(entry);
|
|
249
|
+
},
|
|
250
|
+
dispose() {
|
|
251
|
+
deactivate(entry);
|
|
252
|
+
if (isEl) {
|
|
253
|
+
target.removeEventListener('pointerenter', onEnter);
|
|
254
|
+
target.removeEventListener('pointerleave', onLeave);
|
|
255
|
+
target.removeEventListener('focus', onFocus);
|
|
256
|
+
target.removeEventListener('blur', onLeave);
|
|
257
|
+
target.removeEventListener('keydown', onKey);
|
|
258
|
+
}
|
|
259
|
+
if (ownsHandle)
|
|
260
|
+
handle?.remove();
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
const entry = {
|
|
264
|
+
target,
|
|
265
|
+
content,
|
|
266
|
+
handle,
|
|
267
|
+
ownsHandle,
|
|
268
|
+
asked: opts.placement ?? 'auto',
|
|
269
|
+
gap: opts.gap ?? 8,
|
|
270
|
+
arrow: opts.arrow ?? true,
|
|
271
|
+
interactive: opts.interactive ?? false,
|
|
272
|
+
x: Number.NaN,
|
|
273
|
+
y: Number.NaN,
|
|
274
|
+
arrowAt: Number.NaN,
|
|
275
|
+
side: null,
|
|
276
|
+
showTimer: null,
|
|
277
|
+
tip,
|
|
278
|
+
};
|
|
279
|
+
if (isEl) {
|
|
280
|
+
target.addEventListener('pointerenter', onEnter);
|
|
281
|
+
target.addEventListener('pointerleave', onLeave);
|
|
282
|
+
target.addEventListener('focus', onFocus);
|
|
283
|
+
target.addEventListener('blur', onLeave);
|
|
284
|
+
target.addEventListener('keydown', onKey);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
// A world tooltip has no hover: it shows at once and rides the anchor.
|
|
288
|
+
activate(entry);
|
|
289
|
+
}
|
|
290
|
+
return tip;
|
|
291
|
+
},
|
|
292
|
+
update() {
|
|
293
|
+
if (active && !(active.target instanceof HTMLElement))
|
|
294
|
+
place(active);
|
|
295
|
+
},
|
|
296
|
+
dispose() {
|
|
297
|
+
if (active)
|
|
298
|
+
deactivate(active);
|
|
299
|
+
element.remove();
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Stylesheet for the tooltip (design px, theme tokens).
|
|
305
|
+
*/
|
|
306
|
+
export const TOOLTIP_CSS = toFrameUnits(`
|
|
307
|
+
.tc-tooltip { position: absolute; left: 0; top: 0; pointer-events: none; will-change: transform; box-sizing: border-box;
|
|
308
|
+
max-width: 560px; padding: var(--tc-space-2) var(--tc-space-3); font-family: var(--tc-font-ui); font-size: var(--tc-font-size-s);
|
|
309
|
+
line-height: 1.35; color: var(--tc-color-text); background: var(--tc-color-surface);
|
|
310
|
+
border: var(--tc-border-width) solid var(--tc-color-border); border-radius: var(--tc-radius-m); box-shadow: var(--tc-shadow);
|
|
311
|
+
animation: tc-fade var(--tc-duration-fast) var(--tc-easing); }
|
|
312
|
+
.tc-tooltip[hidden] { display: none; }
|
|
313
|
+
.tc-tooltip[data-interactive] { pointer-events: auto; }
|
|
314
|
+
.tc-tooltip-body { overflow-wrap: break-word; }
|
|
315
|
+
.tc-tooltip-arrow { position: absolute; width: 16px; height: 16px; background: var(--tc-color-surface);
|
|
316
|
+
border: var(--tc-border-width) solid var(--tc-color-border); transform: rotate(45deg); }
|
|
317
|
+
.tc-tooltip[data-no-arrow] .tc-tooltip-arrow { display: none; }
|
|
318
|
+
.tc-tooltip[data-placement="top"] .tc-tooltip-arrow { left: var(--tc-tooltip-arrow, 50%); bottom: -9px; margin-left: -8px; border-top: 0; border-left: 0; }
|
|
319
|
+
.tc-tooltip[data-placement="bottom"] .tc-tooltip-arrow { left: var(--tc-tooltip-arrow, 50%); top: -9px; margin-left: -8px; border-bottom: 0; border-right: 0; }
|
|
320
|
+
.tc-tooltip[data-placement="left"] .tc-tooltip-arrow { top: var(--tc-tooltip-arrow, 50%); right: -9px; margin-top: -8px; border-bottom: 0; border-left: 0; }
|
|
321
|
+
.tc-tooltip[data-placement="right"] .tc-tooltip-arrow { top: var(--tc-tooltip-arrow, 50%); left: -9px; margin-top: -8px; border-top: 0; border-right: 0; }
|
|
322
|
+
.tc-tooltip-anchor { width: 0; height: 0; }
|
|
323
|
+
`);
|
|
324
|
+
const STYLE_ID = 'tc-ui-tooltip';
|
|
325
|
+
/** Add `TOOLTIP_CSS` to `doc` once (the first tooltip does it). */
|
|
326
|
+
export function ensureTooltipStyles(doc = document) {
|
|
327
|
+
if (doc.getElementById(STYLE_ID))
|
|
328
|
+
return;
|
|
329
|
+
const style = doc.createElement('style');
|
|
330
|
+
style.id = STYLE_ID;
|
|
331
|
+
style.textContent = TOOLTIP_CSS;
|
|
332
|
+
doc.head.appendChild(style);
|
|
333
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/** A choice for `segmented` and `select`. */
|
|
2
|
+
export interface ChoiceOption<T extends string = string> {
|
|
3
|
+
value: T;
|
|
4
|
+
label: string;
|
|
5
|
+
}
|
|
6
|
+
/** Colour of a `bar`: the accent, or one of the toast tones. */
|
|
7
|
+
export type WidgetTone = 'accent' | 'info' | 'success' | 'warn' | 'danger';
|
|
8
|
+
export interface WidgetReticleOptions {
|
|
9
|
+
/** Box the lines fit in at spread 0, design px. Default 48. */
|
|
10
|
+
size?: number;
|
|
11
|
+
/** Line thickness, design px. Default 2. */
|
|
12
|
+
thickness?: number;
|
|
13
|
+
/** Gap from the centre to each line at spread 0, design px. Default 6. */
|
|
14
|
+
gap?: number;
|
|
15
|
+
/** Centre dot. Default true. */
|
|
16
|
+
dot?: boolean;
|
|
17
|
+
/** Any CSS colour. Default the theme's text colour. */
|
|
18
|
+
color?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface WidgetReticle {
|
|
21
|
+
element: HTMLDivElement;
|
|
22
|
+
/** Open the lines: 0 is the resting gap, 1 is a quarter of the size further out. */
|
|
23
|
+
set(spread: number): void;
|
|
24
|
+
/** Play the hit flash once (restarts if running). */
|
|
25
|
+
hit(): void;
|
|
26
|
+
hide(): void;
|
|
27
|
+
show(): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A four-line reticle with a centre dot, drawn with CSS only and centred in its parent
|
|
31
|
+
* (`position: absolute; left: 50%; top: 50%`), so it goes on the `hud` layer or any positioned
|
|
32
|
+
* box. Decorative: `aria-hidden`. `set(spread)` opens the lines; `hit()` flashes them.
|
|
33
|
+
*/
|
|
34
|
+
export declare function reticle(opts?: WidgetReticleOptions): WidgetReticle;
|
|
35
|
+
export interface BarOptions {
|
|
36
|
+
min?: number;
|
|
37
|
+
max?: number;
|
|
38
|
+
/** Draw the track in this many segments (pips). */
|
|
39
|
+
segments?: number;
|
|
40
|
+
tone?: WidgetTone;
|
|
41
|
+
/** Text for `aria-valuetext` and the visible value. Default a whole percent. */
|
|
42
|
+
format?: (v: number) => string;
|
|
43
|
+
}
|
|
44
|
+
export interface Bar {
|
|
45
|
+
element: HTMLDivElement;
|
|
46
|
+
set(value: number): void;
|
|
47
|
+
tone(t: WidgetTone): void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A labelled progress or health bar: `role=progressbar`, `aria-valuemin/max/now` and
|
|
51
|
+
* `aria-valuetext` (from `format`, else a percent). The fill is a `scaleX` transform driven by
|
|
52
|
+
* `--tc-ui-fill`; `segments` overlays pips; `tone` picks the fill colour.
|
|
53
|
+
*/
|
|
54
|
+
export declare function bar(label: string, value: number, opts?: BarOptions): Bar;
|
|
55
|
+
export interface Segmented<T extends string = string> {
|
|
56
|
+
element: HTMLDivElement;
|
|
57
|
+
/** Select `value` without calling `onChange`. */
|
|
58
|
+
set(value: T): void;
|
|
59
|
+
readonly value: T;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A segmented choice: `role=radiogroup` with one `role=radio` button per option, roving
|
|
63
|
+
* tabindex (only the selected one is in the tab order), ArrowLeft/ArrowRight to move (wrapping)
|
|
64
|
+
* and a click to pick. Consumes only those two arrows, so a panel's ArrowUp/Down walk passes.
|
|
65
|
+
* `onChange` fires on user changes only.
|
|
66
|
+
*/
|
|
67
|
+
export declare function segmented<T extends string>(label: string, options: ChoiceOption<T>[], value: T, onChange: (value: T) => void): Segmented<T>;
|
|
68
|
+
export interface Select<T extends string = string> {
|
|
69
|
+
element: HTMLLabelElement;
|
|
70
|
+
select: HTMLSelectElement;
|
|
71
|
+
/** Select `value` without calling `onChange`. */
|
|
72
|
+
set(value: T): void;
|
|
73
|
+
}
|
|
74
|
+
/** A labelled native `<select>` in the theme (`.tc-field.tc-ui-select`). */
|
|
75
|
+
export declare function select<T extends string>(label: string, options: ChoiceOption<T>[], value: T, onChange: (value: T) => void): Select<T>;
|
|
76
|
+
export interface KeyPromptOptions {
|
|
77
|
+
/** The bound key's text (`'E'`, `'Space'`). */
|
|
78
|
+
key?: string;
|
|
79
|
+
/** The pad button's glyph text (`'Ⓐ'`, `'RT'`). */
|
|
80
|
+
pad?: string;
|
|
81
|
+
}
|
|
82
|
+
export interface KeyPrompt {
|
|
83
|
+
element: HTMLSpanElement;
|
|
84
|
+
/** Show `key` in the key chip and `pad` (or nothing) in the pad chip. */
|
|
85
|
+
set(key: string, pad?: string): void;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* An action with its binding: a key chip (`<kbd>`), a pad chip when a pad glyph is given, and
|
|
89
|
+
* the action's text. Strings in; no icon font. An empty chip hides itself.
|
|
90
|
+
*/
|
|
91
|
+
export declare function keyPrompt(action: string, opts?: KeyPromptOptions): KeyPrompt;
|
|
92
|
+
export interface StepperOptions {
|
|
93
|
+
min: number;
|
|
94
|
+
max: number;
|
|
95
|
+
step: number;
|
|
96
|
+
/** Text for the value and `aria-valuetext`. Default the number. */
|
|
97
|
+
format?: (v: number) => string;
|
|
98
|
+
}
|
|
99
|
+
export interface Stepper {
|
|
100
|
+
element: HTMLDivElement;
|
|
101
|
+
/** Set the value (clamped and snapped to `step`) without calling `onChange`. */
|
|
102
|
+
set(value: number): void;
|
|
103
|
+
readonly value: number;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* A numeric stepper: a `−` button, a focusable `role=spinbutton` value and a `+` button.
|
|
107
|
+
* ArrowUp/ArrowDown step, Home/End jump to the bounds; only those four keys are consumed.
|
|
108
|
+
* Values snap to `step` from `min` and clamp; the buttons disable at the bounds. `onChange`
|
|
109
|
+
* fires on user changes only.
|
|
110
|
+
*/
|
|
111
|
+
export declare function stepper(label: string, value: number, onChange: (value: number) => void, opts: StepperOptions): Stepper;
|
|
112
|
+
export interface WidgetCooldownOptions {
|
|
113
|
+
/** Diameter, design px. Default 64. */
|
|
114
|
+
size?: number;
|
|
115
|
+
}
|
|
116
|
+
export interface WidgetCooldown {
|
|
117
|
+
element: HTMLDivElement;
|
|
118
|
+
/** 0 is just used, 1 is ready; the sweep fills clockwise. */
|
|
119
|
+
set(fraction: number): void;
|
|
120
|
+
/** True once `set` reached 1. */
|
|
121
|
+
readonly ready: boolean;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* A radial cooldown: a disc whose `conic-gradient` sweep follows `--tc-ui-sweep`, lit when
|
|
125
|
+
* ready (`data-ready`). Decorative (`aria-hidden`): the game announces readiness itself.
|
|
126
|
+
*/
|
|
127
|
+
export declare function cooldown(opts?: WidgetCooldownOptions): WidgetCooldown;
|
|
128
|
+
/**
|
|
129
|
+
* Stylesheet for these widgets in design px (`toFrameUnits`: every `px` here is one `--tc-unit`;
|
|
130
|
+
* `--tc-ui-px` carries that unit into the `calc`s on the size custom properties).
|
|
131
|
+
*/
|
|
132
|
+
export declare const WIDGETS2_CSS: string;
|
|
133
|
+
/** Add `WIDGETS2_CSS` to `doc` once (`createOverlay` calls it beside `ensureStyles`). */
|
|
134
|
+
export declare function ensureWidgets2Styles(doc?: Document): void;
|