@weasel-js/core 1.13.0 → 1.14.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 +300 -0
- package/README.md +8 -12
- package/dist/affordances/hitAffordanceRegions.js +1 -1
- package/dist/affordances/hitAffordanceRegions.js.map +1 -1
- package/dist/affordances/pathAnchors.js.map +1 -1
- package/dist/animation/clipTargets.js +1 -1
- package/dist/animation/clipTargets.js.map +1 -1
- package/dist/animation/poseTarget.js +5 -32
- package/dist/animation/poseTarget.js.map +1 -1
- package/dist/{autoPoseDescriptor-CZ1eXbzY.d.ts → autoPoseDescriptor-C25QVb0W.d.ts} +1 -1
- package/dist/barrel/canvas.js +8 -8
- package/dist/barrel/chrome.js +9 -9
- package/dist/barrel/input.js +1 -1
- package/dist/barrel/interactions.js +3 -3
- package/dist/barrel/paint.js +2 -2
- package/dist/barrel/paths.js +19 -17
- package/dist/barrel/renderer.js +11 -7
- package/dist/barrel/routing.js +4 -1
- package/dist/barrel/scene.js +16 -12
- package/dist/barrel/text.js +5 -5
- package/dist/barrel/viewport.js +8 -8
- package/dist/canvas/Canvas.js +2 -2
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +20 -14
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/GestureReason.js +64 -0
- package/dist/canvas/GestureReason.js.map +1 -0
- package/dist/canvas/GestureReason.module.js +7 -0
- package/dist/canvas/GestureReason.module.js.map +1 -0
- package/dist/canvas/LeanSceneCanvas.js +3 -1
- package/dist/canvas/LeanSceneCanvas.js.map +1 -1
- package/dist/canvas/NodeShape.js +2 -0
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/PickHud.js +7 -3
- package/dist/canvas/PickHud.js.map +1 -1
- package/dist/canvas/SceneCanvas/CanvasKitProviders.js +1 -1
- package/dist/canvas/SceneCanvas/CanvasKitProviders.js.map +1 -1
- package/dist/canvas/SceneCanvas/DevHuds.js +2 -2
- package/dist/canvas/SceneCanvas/DevHuds.js.map +1 -1
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +4 -2
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
- package/dist/canvas/SceneCanvas/SceneCanvasInput.js +3 -1
- package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -1
- package/dist/canvas/SceneCanvas/brushOverlay.js.map +1 -1
- package/dist/canvas/SceneCanvas/builtinToolSets.js +17 -9
- package/dist/canvas/SceneCanvas/builtinToolSets.js.map +1 -1
- package/dist/canvas/SceneCanvas/canvasPassThrough.js +2 -1
- package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +75 -19
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +7 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultTextEditor.js +108 -0
- package/dist/canvas/SceneCanvas/defaultTextEditor.js.map +1 -0
- package/dist/canvas/SceneCanvas/describePresets.js +47 -0
- package/dist/canvas/SceneCanvas/describePresets.js.map +1 -0
- package/dist/canvas/SceneCanvas/features.js +57 -16
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/mergeLayers.js +10 -1
- package/dist/canvas/SceneCanvas/mergeLayers.js.map +1 -1
- package/dist/canvas/SceneCanvas/namedPresets.js +52 -24
- package/dist/canvas/SceneCanvas/namedPresets.js.map +1 -1
- package/dist/canvas/SceneCanvas/presets/arrange.js +35 -10
- package/dist/canvas/SceneCanvas/presets/arrange.js.map +1 -1
- package/dist/canvas/SceneCanvas/presets/baseline.js +9 -0
- package/dist/canvas/SceneCanvas/presets/baseline.js.map +1 -0
- package/dist/canvas/SceneCanvas/presets/chrome.js.map +1 -1
- package/dist/canvas/SceneCanvas/presets/composites.js +43 -0
- package/dist/canvas/SceneCanvas/presets/composites.js.map +1 -0
- package/dist/canvas/SceneCanvas/presets/edit.js +79 -26
- package/dist/canvas/SceneCanvas/presets/edit.js.map +1 -1
- package/dist/canvas/SceneCanvas/presets/ingest.js +1 -0
- package/dist/canvas/SceneCanvas/presets/ingest.js.map +1 -1
- package/dist/canvas/SceneCanvas/presets/paths.js +58 -16
- package/dist/canvas/SceneCanvas/presets/paths.js.map +1 -1
- package/dist/canvas/SceneCanvas/presets/select.js +4 -2
- package/dist/canvas/SceneCanvas/presets/select.js.map +1 -1
- package/dist/canvas/SceneCanvas/presets/tools.js +24 -0
- package/dist/canvas/SceneCanvas/presets/tools.js.map +1 -0
- package/dist/canvas/SceneCanvas/presets/transform.js +4 -0
- package/dist/canvas/SceneCanvas/presets/transform.js.map +1 -1
- package/dist/canvas/SceneCanvas/presets/view.js +3 -1
- package/dist/canvas/SceneCanvas/presets/view.js.map +1 -1
- package/dist/canvas/SceneCanvas/props.js.map +1 -1
- package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js +1 -1
- package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/toolRegistry.js +5 -4
- package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -1
- package/dist/canvas/SceneCanvas/useCanvasTools.js +26 -10
- package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useContributionRoles.js +15 -2
- package/dist/canvas/SceneCanvas/useContributionRoles.js.map +1 -1
- package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js +5 -4
- package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +1 -1
- package/dist/canvas/SceneCanvas/useNodeAtPoint.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +9 -8
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js +2 -2
- package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +4 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneChrome.js +7 -4
- package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +9 -9
- package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js.map +1 -1
- package/dist/canvas/SceneCanvas/useScenePicking.js +4 -7
- package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +2 -1
- package/dist/canvas/SceneCanvas/useSceneRedrawSources.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +6 -6
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js +2 -2
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +1 -1
- package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSurfaceViewInputs.js.map +1 -1
- package/dist/canvas/SceneCanvas/useToolKeybindings.js +2 -2
- package/dist/canvas/SceneCanvas/useToolKeybindings.js.map +1 -1
- package/dist/canvas/SceneCanvas/useViewportActions.js +5 -2
- package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -1
- package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -1
- package/dist/canvas/SceneCanvas.js +22 -11
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +1 -0
- package/dist/canvas/SceneViewCanvas.js.map +1 -1
- package/dist/canvas/ViewMarker.js.map +1 -1
- package/dist/canvas/accentColor.js +14 -1
- package/dist/canvas/accentColor.js.map +1 -1
- package/dist/canvas/affordanceAt.js +2 -2
- package/dist/canvas/affordanceAt.js.map +1 -1
- package/dist/canvas/buildSceneTree.js +5 -3
- package/dist/canvas/buildSceneTree.js.map +1 -1
- package/dist/canvas/deps/editAnchors.js +4 -4
- package/dist/canvas/deps/editAnchors.js.map +1 -1
- package/dist/canvas/deps/enteredGroup.js +14 -5
- package/dist/canvas/deps/enteredGroup.js.map +1 -1
- package/dist/canvas/deps/ingestion.js +5 -1
- package/dist/canvas/deps/ingestion.js.map +1 -1
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/insertSite.js +5 -3
- package/dist/canvas/deps/insertSite.js.map +1 -1
- package/dist/canvas/deps/nodeAtPoint.js +1 -12
- package/dist/canvas/deps/nodeAtPoint.js.map +1 -1
- package/dist/canvas/deps/pathEditCommits.js +3 -3
- package/dist/canvas/deps/pathEditCommits.js.map +1 -1
- package/dist/canvas/deps/slice.js +16 -2
- package/dist/canvas/deps/slice.js.map +1 -1
- package/dist/canvas/deps/snap.js +5 -5
- package/dist/canvas/deps/snap.js.map +1 -1
- package/dist/canvas/deps/textEdit.js +5 -6
- package/dist/canvas/deps/textEdit.js.map +1 -1
- package/dist/canvas/derivedPath.js +8 -3
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/getNodeAtPoint.js +2 -2
- package/dist/canvas/getNodeAtPoint.js.map +1 -1
- package/dist/canvas/insertPreviewExtent.js.map +1 -1
- package/dist/canvas/layerSlots.js.map +1 -1
- package/dist/canvas/nodeShapes/measurePainter.js +1 -1
- package/dist/canvas/nodeShapes/measurePainter.js.map +1 -1
- package/dist/canvas/nodeShapes/strokedBounds.js +5 -3
- package/dist/canvas/nodeShapes/strokedBounds.js.map +1 -1
- package/dist/canvas/overlayRoleStrokes.js +6 -0
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/pickIndex/scenePickIndex.js +10 -12
- package/dist/canvas/pickIndex/scenePickIndex.js.map +1 -1
- package/dist/canvas/sceneAdapter.js +10 -19
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +17 -4
- package/dist/canvas/sceneClipboard.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +3 -2
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/surfaceContribution.js.map +1 -1
- package/dist/canvas/useCanvasPaint.js +10 -4
- package/dist/canvas/useCanvasPaint.js.map +1 -1
- package/dist/canvas/useHitObserver.js +1 -1
- package/dist/canvas/useHitObserver.js.map +1 -1
- package/dist/canvas/useViewAim.js +1 -1
- package/dist/canvas/useViewAim.js.map +1 -1
- package/dist/canvas/useViewHelpers.js +8 -5
- package/dist/canvas/useViewHelpers.js.map +1 -1
- package/dist/canvas/useViewNesting.js +39 -12
- package/dist/canvas/useViewNesting.js.map +1 -1
- package/dist/canvas/viewInputs.js.map +1 -1
- package/dist/canvas/viewMarkers.js +2 -2
- package/dist/canvas/viewMarkers.js.map +1 -1
- package/dist/canvas/viewRegistry.js +2 -2
- package/dist/canvas/viewRegistry.js.map +1 -1
- package/dist/canvas/viewSnap.js +67 -0
- package/dist/canvas/viewSnap.js.map +1 -0
- package/dist/clipboard.d.ts +6 -12
- package/dist/{clone-qb2e1F5p.d.ts → clone-Bz4iqGfE.d.ts} +10 -5
- package/dist/clone.d.ts +5 -5
- package/dist/core/geometry/booleanOfPaths.js +23 -0
- package/dist/core/geometry/booleanOfPaths.js.map +1 -0
- package/dist/core/geometry/pathPoseDescriptor.js +12 -9
- package/dist/core/geometry/pathPoseDescriptor.js.map +1 -1
- package/dist/core/geometry/poseDescriptor.js +12 -3
- package/dist/core/geometry/poseDescriptor.js.map +1 -1
- package/dist/core/geometry/targetFrame.js +2 -13
- package/dist/core/geometry/targetFrame.js.map +1 -1
- package/dist/core/layers/render.js +2 -1
- package/dist/core/layers/render.js.map +1 -1
- package/dist/core/layers/retain.js +5 -3
- package/dist/core/layers/retain.js.map +1 -1
- package/dist/core/ops/setPath.js +3 -0
- package/dist/core/ops/setPath.js.map +1 -1
- package/dist/core/paint/meshKindLazy.js.map +1 -1
- package/dist/core/paint/paintKindEntry.js.map +1 -1
- package/dist/core/paint/paintKinds.js +8 -1
- package/dist/core/paint/paintKinds.js.map +1 -1
- package/dist/core/scene/NodeProperties.js.map +1 -1
- package/dist/core/scene/NodeRouting.js.map +1 -1
- package/dist/core/scene/booleanGroup.js +33 -0
- package/dist/core/scene/booleanGroup.js.map +1 -0
- package/dist/core/scene/booleanOfChildren.js +53 -0
- package/dist/core/scene/booleanOfChildren.js.map +1 -0
- package/dist/core/scene/carryDescendants.js +18 -6
- package/dist/core/scene/carryDescendants.js.map +1 -1
- package/dist/core/scene/composeFrame.js +42 -5
- package/dist/core/scene/composeFrame.js.map +1 -1
- package/dist/core/scene/composePose.js +35 -16
- package/dist/core/scene/composePose.js.map +1 -1
- package/dist/core/scene/depMemo.js +36 -18
- package/dist/core/scene/depMemo.js.map +1 -1
- package/dist/core/scene/derivedParts.js +2 -23
- package/dist/core/scene/derivedParts.js.map +1 -1
- package/dist/core/scene/effectivePose.js +10 -0
- package/dist/core/scene/effectivePose.js.map +1 -1
- package/dist/core/scene/historyForm.js +5 -4
- package/dist/core/scene/historyForm.js.map +1 -1
- package/dist/core/scene/kitOps.js +5 -71
- package/dist/core/scene/kitOps.js.map +1 -1
- package/dist/core/scene/kitRegistry.js +5 -0
- package/dist/core/scene/kitRegistry.js.map +1 -1
- package/dist/core/scene/layerOps.js +82 -0
- package/dist/core/scene/layerOps.js.map +1 -0
- package/dist/core/scene/layoutPass.js +14 -12
- package/dist/core/scene/layoutPass.js.map +1 -1
- package/dist/core/scene/lockGuard.js +9 -3
- package/dist/core/scene/lockGuard.js.map +1 -1
- package/dist/core/scene/nestedHit.js +5 -5
- package/dist/core/scene/nestedHit.js.map +1 -1
- package/dist/core/scene/nodeFlags.js +8 -2
- package/dist/core/scene/nodeFlags.js.map +1 -1
- package/dist/core/scene/nodeGates.js +31 -2
- package/dist/core/scene/nodeGates.js.map +1 -1
- package/dist/core/scene/pathEffects/effects.js +22 -3
- package/dist/core/scene/pathEffects/effects.js.map +1 -1
- package/dist/core/scene/pathEffects/textAlong.js +16 -3
- package/dist/core/scene/pathEffects/textAlong.js.map +1 -1
- package/dist/core/scene/pathEffects/textAlongBands.js +65 -0
- package/dist/core/scene/pathEffects/textAlongBands.js.map +1 -0
- package/dist/core/scene/reconcileSpecs.js +1 -1
- package/dist/core/scene/reconcileSpecs.js.map +1 -1
- package/dist/core/scene/scene.js +11 -5
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/sceneEdits.js +5 -2
- package/dist/core/scene/sceneEdits.js.map +1 -1
- package/dist/core/scene/scenePoseAdapter.js +10 -1
- package/dist/core/scene/scenePoseAdapter.js.map +1 -1
- package/dist/core/scene/scrollOffsets.js +93 -0
- package/dist/core/scene/scrollOffsets.js.map +1 -0
- package/dist/core/scene/serialization.js +15 -5
- package/dist/core/scene/serialization.js.map +1 -1
- package/dist/core/scene/statedFields.js +2 -1
- package/dist/core/scene/statedFields.js.map +1 -1
- package/dist/core/scene/strategyView.js +35 -0
- package/dist/core/scene/strategyView.js.map +1 -0
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/scene/useScene.js +2 -0
- package/dist/core/scene/useScene.js.map +1 -1
- package/dist/core/scene/worldSave.js +87 -0
- package/dist/core/scene/worldSave.js.map +1 -0
- package/dist/core/selection/selectionTarget.js +1 -1
- package/dist/core/selection/selectionTarget.js.map +1 -1
- package/dist/{cornerHandles-CNCb7aTY.d.ts → cornerHandles-DpmQM_z5.d.ts} +1 -1
- package/dist/{depSchema-CpIQzKWQ.d.ts → depSchema-C3BwxitB.d.ts} +119 -99
- package/dist/devtools-protocol.d.ts +2 -2
- package/dist/devtools.d.ts +2 -2
- package/dist/{features → domains}/chrome-caps/buildChromeCtx.js +1 -1
- package/dist/domains/chrome-caps/buildChromeCtx.js.map +1 -0
- package/dist/{features → domains}/chrome-caps/conditions.js +1 -1
- package/dist/domains/chrome-caps/conditions.js.map +1 -0
- package/dist/{features → domains}/chrome-caps/defaults.js +1 -1
- package/dist/domains/chrome-caps/defaults.js.map +1 -0
- package/dist/{features → domains}/chrome-caps/resolve.js +1 -1
- package/dist/domains/chrome-caps/resolve.js.map +1 -0
- package/dist/{features → domains}/chrome-caps/useChromeCaps.js +1 -1
- package/dist/domains/chrome-caps/useChromeCaps.js.map +1 -0
- package/dist/{features → domains}/chrome-caps/useHoverTracking.js +1 -1
- package/dist/domains/chrome-caps/useHoverTracking.js.map +1 -0
- package/dist/{features → domains}/ingestion/contentHandlers.js +20 -3
- package/dist/domains/ingestion/contentHandlers.js.map +1 -0
- package/dist/domains/ingestion/ghost.js +56 -0
- package/dist/domains/ingestion/ghost.js.map +1 -0
- package/dist/{features → domains}/ingestion/imageHandler.js +1 -1
- package/dist/domains/ingestion/imageHandler.js.map +1 -0
- package/dist/domains/ingestion/kitHandlers.js +22 -0
- package/dist/domains/ingestion/kitHandlers.js.map +1 -0
- package/dist/{features → domains}/ingestion/openFilePicker.js +1 -1
- package/dist/domains/ingestion/openFilePicker.js.map +1 -0
- package/dist/{features → domains}/ingestion/placement.js +1 -1
- package/dist/domains/ingestion/placement.js.map +1 -0
- package/dist/{features → domains}/ingestion/svgHandler.js +1 -1
- package/dist/domains/ingestion/svgHandler.js.map +1 -0
- package/dist/{features → domains}/ingestion/textHandler.js +9 -7
- package/dist/domains/ingestion/textHandler.js.map +1 -0
- package/dist/{features → domains}/ingestion/useCanvasIngestion.js +13 -15
- package/dist/domains/ingestion/useCanvasIngestion.js.map +1 -0
- package/dist/{features → domains}/ingestion/weaselJsonHandler.js +1 -1
- package/dist/domains/ingestion/weaselJsonHandler.js.map +1 -0
- package/dist/{features → domains}/longPress/longPressFeedback.js +1 -1
- package/dist/domains/longPress/longPressFeedback.js.map +1 -0
- package/dist/{features → domains}/measure/actionIds.js +1 -1
- package/dist/domains/measure/actionIds.js.map +1 -0
- package/dist/{features → domains}/measure/measureCommands.js +1 -1
- package/dist/domains/measure/measureCommands.js.map +1 -0
- package/dist/{features → domains}/measure/measureContribution.js +1 -1
- package/dist/domains/measure/measureContribution.js.map +1 -0
- package/dist/{features → domains}/measure/measureEdits.js +1 -1
- package/dist/domains/measure/measureEdits.js.map +1 -0
- package/dist/{features → domains}/measure/measureGestures.js +4 -7
- package/dist/domains/measure/measureGestures.js.map +1 -0
- package/dist/{features → domains}/measure/measureHit.js +1 -1
- package/dist/domains/measure/measureHit.js.map +1 -0
- package/dist/{features → domains}/measure/measureLayer.js +1 -1
- package/dist/domains/measure/measureLayer.js.map +1 -0
- package/dist/{features → domains}/measure/measurement.js +1 -1
- package/dist/domains/measure/measurement.js.map +1 -0
- package/dist/{features → domains}/measure/measurements.js +2 -2
- package/dist/domains/measure/measurements.js.map +1 -0
- package/dist/{features → domains}/modes/modeLayers.js +1 -1
- package/dist/domains/modes/modeLayers.js.map +1 -0
- package/dist/{features → domains}/modes/modeTriggers.js +3 -6
- package/dist/domains/modes/modeTriggers.js.map +1 -0
- package/dist/{features → domains}/pathEffects/effectSources.js +1 -1
- package/dist/domains/pathEffects/effectSources.js.map +1 -0
- package/dist/{features → domains}/pathEffects/index.js +1 -1
- package/dist/domains/pathEffects/index.js.map +1 -0
- package/dist/{features → domains}/pathEffects/readSource.js +1 -1
- package/dist/domains/pathEffects/readSource.js.map +1 -0
- package/dist/{features → domains}/pathEffects/textItems.js +11 -2
- package/dist/domains/pathEffects/textItems.js.map +1 -0
- package/dist/{features → domains}/pathEffects/useEffectSourcesLayer.js +1 -1
- package/dist/domains/pathEffects/useEffectSourcesLayer.js.map +1 -0
- package/dist/{features → domains}/paths/anchorData.js +1 -1
- package/dist/domains/paths/anchorData.js.map +1 -0
- package/dist/{features → domains}/paths/anchorMarkers.js +9 -7
- package/dist/domains/paths/anchorMarkers.js.map +1 -0
- package/dist/{features → domains}/paths/editablePath.js +1 -1
- package/dist/domains/paths/editablePath.js.map +1 -0
- package/dist/{features → domains}/paths/index.js +3 -3
- package/dist/{features → domains}/paths/originProjection.js +1 -1
- package/dist/domains/paths/originProjection.js.map +1 -0
- package/dist/{features → domains}/paths/pathEditExtension.js +1 -1
- package/dist/domains/paths/pathEditExtension.js.map +1 -0
- package/dist/{features → domains}/paths/pathEditState.js +1 -1
- package/dist/domains/paths/pathEditState.js.map +1 -0
- package/dist/{features → domains}/paths/pathEditingOverlayLayer.js +1 -1
- package/dist/domains/paths/pathEditingOverlayLayer.js.map +1 -0
- package/dist/{features → domains}/paths/pathLayer.js +1 -1
- package/dist/domains/paths/pathLayer.js.map +1 -0
- package/dist/{features → domains}/paths/pathRepresentation.js +1 -1
- package/dist/domains/paths/pathRepresentation.js.map +1 -0
- package/dist/{features → domains}/paths/pathSnap/glyphs.js +1 -1
- package/dist/domains/paths/pathSnap/glyphs.js.map +1 -0
- package/dist/{features → domains}/paths/pathSnap/pathSnapSource.js +1 -1
- package/dist/domains/paths/pathSnap/pathSnapSource.js.map +1 -0
- package/dist/{features → domains}/paths/pathSnap/sceneIndex.js +1 -1
- package/dist/domains/paths/pathSnap/sceneIndex.js.map +1 -0
- package/dist/{features → domains}/paths/pathSnap/snapGeometry.js +3 -2
- package/dist/domains/paths/pathSnap/snapGeometry.js.map +1 -0
- package/dist/{features → domains}/paths/penPreviewLayer.js +1 -1
- package/dist/domains/paths/penPreviewLayer.js.map +1 -0
- package/dist/{features → domains}/paths/shapeGenerator.js +6 -4
- package/dist/domains/paths/shapeGenerator.js.map +1 -0
- package/dist/{features → domains}/paths/strokeOutline.js +1 -1
- package/dist/domains/paths/strokeOutline.js.map +1 -0
- package/dist/{features → domains}/paths/useAnchorFields.js +1 -1
- package/dist/domains/paths/useAnchorFields.js.map +1 -0
- package/dist/{features → domains}/paths/usePathEdit.js +1 -1
- package/dist/domains/paths/usePathEdit.js.map +1 -0
- package/dist/{features → domains}/poseRun/usePoseRun.js +1 -1
- package/dist/domains/poseRun/usePoseRun.js.map +1 -0
- package/dist/{features → domains}/selection/enteredGroupFrame.js +49 -10
- package/dist/domains/selection/enteredGroupFrame.js.map +1 -0
- package/dist/{features → domains}/selection/enteredGroupScope.js +1 -1
- package/dist/domains/selection/enteredGroupScope.js.map +1 -0
- package/dist/domains/selection/enteredOperands.js +29 -0
- package/dist/domains/selection/enteredOperands.js.map +1 -0
- package/dist/{features → domains}/selection/handleCommands.js +1 -1
- package/dist/domains/selection/handleCommands.js.map +1 -0
- package/dist/{features → domains}/selection/overlay.js +1 -1
- package/dist/domains/selection/overlay.js.map +1 -0
- package/dist/{features → domains}/selection/selectionPose.js +1 -1
- package/dist/domains/selection/selectionPose.js.map +1 -0
- package/dist/{features → domains}/snap/angle2d.js +1 -1
- package/dist/domains/snap/angle2d.js.map +1 -0
- package/dist/{features → domains}/snap/debugCandidates.js +1 -1
- package/dist/domains/snap/debugCandidates.js.map +1 -0
- package/dist/{features → domains}/snap/gather.js +1 -1
- package/dist/domains/snap/gather.js.map +1 -0
- package/dist/{features → domains}/snap/inputSubspace.js +1 -1
- package/dist/domains/snap/inputSubspace.js.map +1 -0
- package/dist/{features → domains}/snap/lazySession.js +1 -1
- package/dist/domains/snap/lazySession.js.map +1 -0
- package/dist/{features → domains}/snap/marks.js +1 -1
- package/dist/domains/snap/marks.js.map +1 -0
- package/dist/{features → domains}/snap/outcomeStore.js +1 -1
- package/dist/domains/snap/outcomeStore.js.map +1 -0
- package/dist/{features → domains}/snap/pointSnap.js +1 -1
- package/dist/domains/snap/pointSnap.js.map +1 -0
- package/dist/{features → domains}/snap/probes2d.js +1 -1
- package/dist/domains/snap/probes2d.js.map +1 -0
- package/dist/{features → domains}/snap/readoutDraw.js +1 -1
- package/dist/domains/snap/readoutDraw.js.map +1 -0
- package/dist/{features → domains}/snap/readoutLayer.js +1 -1
- package/dist/domains/snap/readoutLayer.js.map +1 -0
- package/dist/{features → domains}/snap/registry.js +1 -1
- package/dist/domains/snap/registry.js.map +1 -0
- package/dist/{features → domains}/snap/resizeBox.js +1 -1
- package/dist/domains/snap/resizeBox.js.map +1 -0
- package/dist/{features → domains}/snap/roles.js +1 -1
- package/dist/domains/snap/roles.js.map +1 -0
- package/dist/{features → domains}/snap/rotationSource.js +1 -1
- package/dist/domains/snap/rotationSource.js.map +1 -0
- package/dist/{features → domains}/snap/sceneReads.js +24 -3
- package/dist/domains/snap/sceneReads.js.map +1 -0
- package/dist/{features → domains}/snap/sceneSession2d.js +3 -2
- package/dist/domains/snap/sceneSession2d.js.map +1 -0
- package/dist/{features → domains}/snap/screen.js +1 -1
- package/dist/domains/snap/screen.js.map +1 -0
- package/dist/{features → domains}/snap/session2d.js +3 -2
- package/dist/domains/snap/session2d.js.map +1 -0
- package/dist/{features → domains}/snap/spanSnap.js +1 -1
- package/dist/domains/snap/spanSnap.js.map +1 -0
- package/dist/{features → domains}/snap/stepAngles.js +1 -1
- package/dist/domains/snap/stepAngles.js.map +1 -0
- package/dist/{features → domains}/text/editingDrawOne.js +4 -4
- package/dist/domains/text/editingDrawOne.js.map +1 -0
- package/dist/domains/text/hostTextEditors.js +24 -0
- package/dist/domains/text/hostTextEditors.js.map +1 -0
- package/dist/{features → domains}/text/index.js +1 -1
- package/dist/{features → domains}/text/sceneTextDrafts.js +1 -1
- package/dist/domains/text/sceneTextDrafts.js.map +1 -0
- package/dist/{features → domains}/text/textHitAt.js +18 -2
- package/dist/domains/text/textHitAt.js.map +1 -0
- package/dist/{features → domains}/text/textLayer.js +1 -1
- package/dist/domains/text/textLayer.js.map +1 -0
- package/dist/{features → domains}/text/useSceneTextEdit.js +11 -3
- package/dist/domains/text/useSceneTextEdit.js.map +1 -0
- package/dist/{features → domains}/viewports/aim.js +1 -1
- package/dist/domains/viewports/aim.js.map +1 -0
- package/dist/{features → domains}/viewports/viewMarker.js +23 -5
- package/dist/domains/viewports/viewMarker.js.map +1 -0
- package/dist/{features → domains}/viewports/viewMarkerDrag.js +3 -3
- package/dist/domains/viewports/viewMarkerDrag.js.map +1 -0
- package/dist/{features → domains}/viewports/viewResolver.js +1 -1
- package/dist/domains/viewports/viewResolver.js.map +1 -0
- package/dist/{features → domains}/viewports/viewportLayer.js +1 -1
- package/dist/domains/viewports/viewportLayer.js.map +1 -0
- package/dist/icons.table.js +1 -1
- package/dist/icons.table.js.map +1 -1
- package/dist/icons.table.json +106 -6
- package/dist/index.d.ts +1441 -1050
- package/dist/index.js +90 -77
- package/dist/interactions/actions/admitsChild.js +6 -2
- package/dist/interactions/actions/admitsChild.js.map +1 -1
- package/dist/interactions/actions/align/align.js +1 -4
- package/dist/interactions/actions/align/align.js.map +1 -1
- package/dist/interactions/actions/booleans/booleanGroupAction.js +66 -0
- package/dist/interactions/actions/booleans/booleanGroupAction.js.map +1 -0
- package/dist/interactions/actions/booleans/keymap.js +52 -0
- package/dist/interactions/actions/booleans/keymap.js.map +1 -0
- package/dist/interactions/actions/booleans/operands.js +1 -1
- package/dist/interactions/actions/booleans/pieces.js +4 -11
- package/dist/interactions/actions/booleans/pieces.js.map +1 -1
- package/dist/interactions/actions/clipboard/action.js +3 -7
- package/dist/interactions/actions/clipboard/action.js.map +1 -1
- package/dist/interactions/actions/clipboard/clipboardOps.js +1 -1
- package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
- package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +6 -6
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/bendSegment.js +1 -1
- package/dist/interactions/actions/defaults/bendSegment.js.map +1 -1
- package/dist/interactions/actions/defaults/containerScroll.js +170 -0
- package/dist/interactions/actions/defaults/containerScroll.js.map +1 -0
- package/dist/interactions/actions/defaults/contextMenu.js +2 -5
- package/dist/interactions/actions/defaults/contextMenu.js.map +1 -1
- package/dist/interactions/actions/defaults/delete.js +1 -1
- package/dist/interactions/actions/defaults/delete.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +1 -3
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/enterGroup.js +7 -12
- package/dist/interactions/actions/defaults/enterGroup.js.map +1 -1
- package/dist/interactions/actions/defaults/enterPathEdit.js +4 -8
- package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +12 -24
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +18 -10
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +3 -3
- package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
- package/dist/interactions/actions/defaults/nudgeSteps.js +3 -21
- package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -1
- package/dist/interactions/actions/defaults/pathEditMarks.js.map +1 -1
- package/dist/interactions/actions/defaults/selectDeep.js +2 -2
- package/dist/interactions/actions/defaults/selectDeep.js.map +1 -1
- package/dist/interactions/actions/distribute/distribute.js.map +1 -1
- package/dist/interactions/actions/dropVerdict.js +9 -0
- package/dist/interactions/actions/dropVerdict.js.map +1 -0
- package/dist/interactions/actions/edit-anchors/action.js +2 -2
- package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/extensionDrags.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/geometry.js +8 -6
- package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/handleDrag.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/preview.js +1 -1
- package/dist/interactions/actions/edit-anchors/preview.js.map +1 -1
- package/dist/interactions/actions/flip/action.js +3 -2
- package/dist/interactions/actions/flip/action.js.map +1 -1
- package/dist/interactions/actions/geometryProjection.js +8 -3
- package/dist/interactions/actions/geometryProjection.js.map +1 -1
- package/dist/interactions/actions/gestureFrames.js +1 -0
- package/dist/interactions/actions/gestureFrames.js.map +1 -1
- package/dist/interactions/actions/insert/action.js +6 -2
- package/dist/interactions/actions/insert/action.js.map +1 -1
- package/dist/interactions/actions/insert/frame.js +1 -1
- package/dist/interactions/actions/insert/frame.js.map +1 -1
- package/dist/interactions/actions/insert/placeAction.js +6 -8
- package/dist/interactions/actions/insert/placeAction.js.map +1 -1
- package/dist/interactions/actions/insert/session.js +2 -2
- package/dist/interactions/actions/insert/session.js.map +1 -1
- package/dist/interactions/actions/move/action.js +6 -15
- package/dist/interactions/actions/move/action.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/layoutDrop.js +12 -2
- package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +29 -10
- package/dist/interactions/actions/move/behaviors/reparentOnDrop.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +42 -6
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
- package/dist/interactions/actions/move/capture.js +4 -8
- package/dist/interactions/actions/move/capture.js.map +1 -1
- package/dist/interactions/actions/move/commit/index.js.map +1 -1
- package/dist/interactions/actions/move/commit/layoutDrop.js +4 -3
- package/dist/interactions/actions/move/commit/layoutDrop.js.map +1 -1
- package/dist/interactions/actions/move/commit/layoutRelease.js +15 -9
- package/dist/interactions/actions/move/commit/layoutRelease.js.map +1 -1
- package/dist/interactions/actions/move/commit/reparent.js +19 -13
- package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
- package/dist/interactions/actions/move/delta.js +51 -5
- package/dist/interactions/actions/move/delta.js.map +1 -1
- package/dist/interactions/actions/move/frame.js +8 -4
- package/dist/interactions/actions/move/frame.js.map +1 -1
- package/dist/interactions/actions/move/layout/container.js +19 -9
- package/dist/interactions/actions/move/layout/container.js.map +1 -1
- package/dist/interactions/actions/move/layout/dragged.js +2 -2
- package/dist/interactions/actions/move/layout/dragged.js.map +1 -1
- package/dist/interactions/actions/move/layout/dropPass.js +36 -18
- package/dist/interactions/actions/move/layout/dropPass.js.map +1 -1
- package/dist/interactions/actions/move/layout/exits.js +2 -2
- package/dist/interactions/actions/move/layout/exits.js.map +1 -1
- package/dist/interactions/actions/move/layout/glide.js +5 -5
- package/dist/interactions/actions/move/layout/glide.js.map +1 -1
- package/dist/interactions/actions/move/layout/view.js +55 -0
- package/dist/interactions/actions/move/layout/view.js.map +1 -0
- package/dist/interactions/actions/move/refusal.js +52 -0
- package/dist/interactions/actions/move/refusal.js.map +1 -0
- package/dist/interactions/actions/move/session.js +9 -8
- package/dist/interactions/actions/move/session.js.map +1 -1
- package/dist/interactions/actions/move/translate.js +10 -4
- package/dist/interactions/actions/move/translate.js.map +1 -1
- package/dist/interactions/actions/moveNodes.js +21 -5
- package/dist/interactions/actions/moveNodes.js.map +1 -1
- package/dist/interactions/actions/pathCommands/pathNodes.js +3 -3
- package/dist/interactions/actions/pathCommands/pathNodes.js.map +1 -1
- package/dist/interactions/actions/planeInput.js +14 -13
- package/dist/interactions/actions/planeInput.js.map +1 -1
- package/dist/interactions/actions/poseFrame.js +21 -8
- package/dist/interactions/actions/poseFrame.js.map +1 -1
- package/dist/interactions/actions/resize/action.js +1 -1
- package/dist/interactions/actions/resize/action.js.map +1 -1
- package/dist/interactions/actions/resize/aspect.js +1 -1
- package/dist/interactions/actions/resize/aspect.js.map +1 -1
- package/dist/interactions/actions/resize/commit.js +10 -1
- package/dist/interactions/actions/resize/commit.js.map +1 -1
- package/dist/interactions/actions/resize/frame.js +3 -2
- package/dist/interactions/actions/resize/frame.js.map +1 -1
- package/dist/interactions/actions/resize/held.js +44 -0
- package/dist/interactions/actions/resize/held.js.map +1 -0
- package/dist/interactions/actions/resize/session.js +3 -1
- package/dist/interactions/actions/resize/session.js.map +1 -1
- package/dist/interactions/actions/resolveOverlays.js +9 -0
- package/dist/interactions/actions/resolveOverlays.js.map +1 -1
- package/dist/interactions/actions/resolvePreviews.js +23 -7
- package/dist/interactions/actions/resolvePreviews.js.map +1 -1
- package/dist/interactions/actions/rotate/action.js +1 -1
- package/dist/interactions/actions/rotate/action.js.map +1 -1
- package/dist/interactions/actions/rotate/frame.js +1 -1
- package/dist/interactions/actions/rotate/frame.js.map +1 -1
- package/dist/interactions/actions/rotate/session.js +2 -2
- package/dist/interactions/actions/rotate/session.js.map +1 -1
- package/dist/interactions/actions/selectionSubtree.js +2 -4
- package/dist/interactions/actions/selectionSubtree.js.map +1 -1
- package/dist/interactions/actions/spatialReference.js +4 -9
- package/dist/interactions/actions/spatialReference.js.map +1 -1
- package/dist/interactions/gestures/dragRadial/dragRadial.js.map +1 -1
- package/dist/interactions/gestures/dragRect/dragRect.js.map +1 -1
- package/dist/kitSettingsSchema.js +2 -2
- package/dist/kitSettingsSchema.js.map +1 -1
- package/dist/{math-C_elShP_.d.ts → math-B_unOnF4.d.ts} +2 -2
- package/dist/math.d.ts +3 -3
- package/dist/move.d.ts +6 -6
- package/dist/{options-ClEm3SEl.d.ts → options-DAjkhbcs.d.ts} +5 -5
- package/dist/{poseDescriptor-DN2yfnq_.d.ts → poseDescriptor-CvSxVhCd.d.ts} +17 -4
- package/dist/resize.d.ts +6 -6
- package/dist/style.css +14 -0
- package/dist/test-seams.d.ts +11 -15
- package/dist/test-seams.js +1 -1
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js +3 -6
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
- package/dist/tools/builtin/line/useLineTool.js.map +1 -1
- package/dist/tools/builtin/measure/useMeasureTool.js +2 -2
- package/dist/tools/builtin/measure/useMeasureTool.js.map +1 -1
- package/dist/tools/builtin/pen/penHandle.js +2 -2
- package/dist/tools/builtin/pen/penHandle.js.map +1 -1
- package/dist/tools/builtin/pen/usePenTool.js +13 -19
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
- package/dist/tools/builtin/select/groupEntry.js +1 -1
- package/dist/tools/builtin/select/groupEntry.js.map +1 -1
- package/dist/tools/builtin/select/selectionContributions.js +1 -1
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +7 -7
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/slice/useSliceTool.js +5 -8
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js +1 -1
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/index.js +2 -1
- package/dist/{types-49uYJN3j.d.ts → types-A_sNJYRd.d.ts} +8 -0
- package/dist/{types-BEdRIhNc.d.ts → types-DW14eu9B.d.ts} +131 -36
- package/dist/{types-p2alu-R1.d.ts → types-VCtfchp-.d.ts} +4 -6
- package/dist/util/color.js +12 -14
- package/dist/util/color.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +25 -24
- package/dist/canvas/poseCascade.js +0 -65
- package/dist/canvas/poseCascade.js.map +0 -1
- package/dist/features/chrome-caps/buildChromeCtx.js.map +0 -1
- package/dist/features/chrome-caps/conditions.js.map +0 -1
- package/dist/features/chrome-caps/defaults.js.map +0 -1
- package/dist/features/chrome-caps/resolve.js.map +0 -1
- package/dist/features/chrome-caps/useChromeCaps.js.map +0 -1
- package/dist/features/chrome-caps/useHoverTracking.js.map +0 -1
- package/dist/features/ingestion/contentHandlers.js.map +0 -1
- package/dist/features/ingestion/imageHandler.js.map +0 -1
- package/dist/features/ingestion/openFilePicker.js.map +0 -1
- package/dist/features/ingestion/placement.js.map +0 -1
- package/dist/features/ingestion/registerKitHandlers.js +0 -43
- package/dist/features/ingestion/registerKitHandlers.js.map +0 -1
- package/dist/features/ingestion/svgHandler.js.map +0 -1
- package/dist/features/ingestion/textHandler.js.map +0 -1
- package/dist/features/ingestion/useCanvasIngestion.js.map +0 -1
- package/dist/features/ingestion/weaselJsonHandler.js.map +0 -1
- package/dist/features/longPress/longPressFeedback.js.map +0 -1
- package/dist/features/measure/actionIds.js.map +0 -1
- package/dist/features/measure/measureCommands.js.map +0 -1
- package/dist/features/measure/measureContribution.js.map +0 -1
- package/dist/features/measure/measureEdits.js.map +0 -1
- package/dist/features/measure/measureGestures.js.map +0 -1
- package/dist/features/measure/measureHit.js.map +0 -1
- package/dist/features/measure/measureLayer.js.map +0 -1
- package/dist/features/measure/measurement.js.map +0 -1
- package/dist/features/measure/measurements.js.map +0 -1
- package/dist/features/modes/modeLayers.js.map +0 -1
- package/dist/features/modes/modeTriggers.js.map +0 -1
- package/dist/features/pathEffects/effectSources.js.map +0 -1
- package/dist/features/pathEffects/index.js.map +0 -1
- package/dist/features/pathEffects/readSource.js.map +0 -1
- package/dist/features/pathEffects/textItems.js.map +0 -1
- package/dist/features/pathEffects/useEffectSourcesLayer.js.map +0 -1
- package/dist/features/paths/anchorData.js.map +0 -1
- package/dist/features/paths/anchorMarkers.js.map +0 -1
- package/dist/features/paths/editablePath.js.map +0 -1
- package/dist/features/paths/originProjection.js.map +0 -1
- package/dist/features/paths/pathEditExtension.js.map +0 -1
- package/dist/features/paths/pathEditState.js.map +0 -1
- package/dist/features/paths/pathEditingOverlayLayer.js.map +0 -1
- package/dist/features/paths/pathLayer.js.map +0 -1
- package/dist/features/paths/pathRepresentation.js.map +0 -1
- package/dist/features/paths/pathSnap/glyphs.js.map +0 -1
- package/dist/features/paths/pathSnap/pathSnapSource.js.map +0 -1
- package/dist/features/paths/pathSnap/sceneIndex.js.map +0 -1
- package/dist/features/paths/pathSnap/snapGeometry.js.map +0 -1
- package/dist/features/paths/penPreviewLayer.js.map +0 -1
- package/dist/features/paths/shapeGenerator.js.map +0 -1
- package/dist/features/paths/strokeOutline.js.map +0 -1
- package/dist/features/paths/useAnchorFields.js.map +0 -1
- package/dist/features/paths/usePathEdit.js.map +0 -1
- package/dist/features/poseRun/usePoseRun.js.map +0 -1
- package/dist/features/selection/enteredGroupFrame.js.map +0 -1
- package/dist/features/selection/enteredGroupScope.js.map +0 -1
- package/dist/features/selection/handleCommands.js.map +0 -1
- package/dist/features/selection/overlay.js.map +0 -1
- package/dist/features/selection/selectionPose.js.map +0 -1
- package/dist/features/snap/angle2d.js.map +0 -1
- package/dist/features/snap/debugCandidates.js.map +0 -1
- package/dist/features/snap/gather.js.map +0 -1
- package/dist/features/snap/inputSubspace.js.map +0 -1
- package/dist/features/snap/lazySession.js.map +0 -1
- package/dist/features/snap/marks.js.map +0 -1
- package/dist/features/snap/outcomeStore.js.map +0 -1
- package/dist/features/snap/pointSnap.js.map +0 -1
- package/dist/features/snap/probes2d.js.map +0 -1
- package/dist/features/snap/readoutDraw.js.map +0 -1
- package/dist/features/snap/readoutLayer.js.map +0 -1
- package/dist/features/snap/registry.js.map +0 -1
- package/dist/features/snap/resizeBox.js.map +0 -1
- package/dist/features/snap/roles.js.map +0 -1
- package/dist/features/snap/rotationSource.js.map +0 -1
- package/dist/features/snap/sceneReads.js.map +0 -1
- package/dist/features/snap/sceneSession2d.js.map +0 -1
- package/dist/features/snap/screen.js.map +0 -1
- package/dist/features/snap/session2d.js.map +0 -1
- package/dist/features/snap/spanSnap.js.map +0 -1
- package/dist/features/snap/stepAngles.js.map +0 -1
- package/dist/features/text/editingDrawOne.js.map +0 -1
- package/dist/features/text/sceneTextDrafts.js.map +0 -1
- package/dist/features/text/textHitAt.js.map +0 -1
- package/dist/features/text/textLayer.js.map +0 -1
- package/dist/features/text/useSceneTextEdit.js.map +0 -1
- package/dist/features/viewports/aim.js.map +0 -1
- package/dist/features/viewports/viewMarker.js.map +0 -1
- package/dist/features/viewports/viewMarkerDrag.js.map +0 -1
- package/dist/features/viewports/viewResolver.js.map +0 -1
- package/dist/features/viewports/viewportLayer.js.map +0 -1
- /package/dist/{features → domains}/chrome-caps/index.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"props.js","names":[],"sources":["../../../src/canvas/SceneCanvas/props.ts"],"sourcesContent":["import type { ModeRegistry } from '@weasel-js/modes';\nimport type { PathEditHost, PathEditOpening } from './pathEditHost';\nimport type { SceneCanvasGeometry } from './geometryProps';\nimport type { SceneCanvasHit, SceneCanvasPointerProps } from './pointerProps';\nimport type { Paint } from '@weasel-js/paint';\nimport type { SceneCanvasActionProps } from './actionProps';\nimport { Yoke } from '@weasel-js/routing/react';\nimport type { PasteOmission } from 'core/adapters/types';\nimport type { Op } from 'core/ops/types';\nimport type { Node, Scene, SerializedScene } from 'core/scene/types';\nimport type { SelectionApi, UseSelectionOptions } from 'core/selection/useSelection';\nimport type { ContentHandlerEntry } from 'features/ingestion';\nimport type { SceneCanvasSnap } from 'features/snap/types';\nimport type { SvgIngestOptions } from 'interactions/actions/depSchema';\nimport type { GeometryProjection } from 'interactions/actions/geometryProjection';\nimport type { UseMoveOptions } from 'interactions/actions/move/options';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport type { UseResizeOptions } from 'interactions/actions/resize/options';\nimport type { UseRotateOptions } from 'interactions/actions/rotate/options';\nimport type { ReactNode } from 'react';\nimport type { Animator } from '@weasel-js/animator';\nimport type { PoseTransitionSeat } from '../../animation/poseTransition';\nimport { HANDLE_BASE_PX } from '../../core/device/targets';\nimport type { DeviceProfile } from '../../core/device/types';\nimport type { NodeRoutingEntry } from '../../core/scene/NodeRouting';\nimport type { DebugConfig } from '../../debug/types';\nimport type { LayoutDropTargetMode, ReflowTransition } from '../../layout/types';\nimport type { FlattenTolerance, ShaderProgramHandle } from '@weasel-js/renderer';\nimport type { Tool, ToolsApi } from '../../tools/overlayBinding';\nimport type { SceneSlotConfig } from '../buildSceneLayer';\nimport type { CanvasProps } from '../Canvas';\nimport type { LayersMap } from '../layerSlots';\nimport type { CanvasViewProps } from '../CanvasView';\nimport type { InsertNodeFactory, InsertPaint } from '../deps';\nimport type { SurfaceContribution } from '../surfaceContribution';\nimport type { CameraProps } from '../useCanvasView';\nimport type { FeatureEntry } from './features';\nimport type { BuiltinToolOptions } from './useBuiltinShapeTools';\nimport type { VersionCheck } from './useContributionRoles';\nimport type { SceneCanvasViewport } from './viewportProp';\n\n/** The adapter surface delete / duplicate / group / ungroup need, narrowed from\n * `SceneCanvasAdapter` because `useSceneStandardActions` is non-generic. */\nexport interface BridgeAdapter {\n applyOps(ops: Op[], label?: string): void;\n insertNode(node: { id: string; [k: string]: unknown }): void;\n removeNode(id: string): void;\n setSelection(ids: string[]): void;\n}\n\n/** Default size in CSS pixels for selection corner-handles AND their\n * hit-test radius, at `targetScale = 1`. Deliberately unscaled; kit-internal\n * use sites multiply by `DeviceProfile.targetScale`. */\nexport const DEFAULT_HANDLE_SIZE = HANDLE_BASE_PX;\n\n/** `<SceneCanvas longPress>`. */\nexport interface SceneCanvasLongPress {\n /**\n * Shown while a long-press is held and some binding would fire on it.\n * Default: a ring that fills around the press point\n * (`createLongPressFeedbackContribution()`), static under\n * `prefers-reduced-motion`. `false` shows nothing; a contribution replaces\n * it, reading the `longPress` dep. Installed beside `ambient`, so under a\n * `tools` takeover add it to your own `useTools` call instead.\n */\n feedback?: boolean | SurfaceContribution;\n /** Default true. A long-press some binding handled pulses\n * `navigator.vibrate` briefly, for touch and pen, where the API exists. */\n haptics?: boolean;\n /** Hold time in ms. Default `LONG_PRESS_MS` (500). */\n duration?: number;\n}\n\n/** `<SceneCanvas layers>`: a {@link LayersMap} whose scene slot may be partial,\n * since the defaults fill in whatever it leaves out. */\nexport type SceneCanvasLayers<TNode extends { id: string }, TPose> = LayersMap<\n TNode,\n TPose,\n Partial<SceneSlotConfig<TNode, TPose>>\n>;\n\nimport type { BuiltinToolId } from './builtinToolSets';\nimport type { ToolEntry } from '@weasel-js/routing';\nexport { BUILTIN_TOOL_IDS, type BuiltinToolId } from './builtinToolSets';\n\nexport type { SceneCanvasHit };\n\n/** Props for `<SceneCanvas>`. A scene is the only thing it needs. With nothing\n * else it renders that scene and keeps a selection no input sets; `features`\n * turns behavior on by preset, and the rest configures what those turn on. */\nexport type SceneCanvasProps<TData, TLayer extends string, TPose> =\n Omit<\n CanvasProps<TPose>,\n | 'adapter' | 'boundsOf' | 'selection' | 'tools'\n | 'viewState' // SceneCanvas makes the camera from the view props below\n | 'layers' // stripped so we can re-add as optional below\n | 'getIsVisible' // SceneCanvas synthesizes this from chromeVisibility\n | 'contentVersion' // SceneCanvas wires this to the scene's own version\n | 'layerVisibility' | 'layerOrder' // re-declared below: they gate picking here too\n | 'debug' // re-declared below with SceneCanvas's own `slops`\n > & CameraProps\n & {\n /** A `Scene` (typically from `useScene`) — or a `SerializedScene` JSON\n * object, which SceneCanvas bakes into a Scene on first render. The\n * serialized form is read once; pass a `key` on `<SceneCanvas>` to force\n * a fresh canvas from updated JSON.\n *\n * The JSON shape is relaxed (`version: number` rather than the `1`\n * literal) so an `import json from './x.json'` result satisfies the type\n * without an `as` cast. */\n scene:\n | Scene<TData, TLayer, TPose>\n | SerializedScene<TData, TLayer, TPose>\n | { version: number; systemLayers?: ReadonlyArray<{ id: string }>; nodes: ReadonlyArray<unknown> };\n\n /** Layer configuration. When omitted, SceneCanvas applies kit defaults\n * (a scene slot that paints `node.data.fill` rects + a default\n * selection overlay). A partial scene or selection-overlay config is\n * spread over that slot's defaults; pass `slot: null` to suppress a\n * default explicitly. */\n layers?: SceneCanvasLayers<Node<TData, TLayer, TPose>, TPose>;\n\n /** Which layout container a drag lands in when several contain the drop\n * point — the innermost (default), the topmost in paint order, or only\n * containers whose strategy declares a `dropRegion`. Decides both the\n * drag-time reflow preview and the commit. */\n layoutDropTarget?: LayoutDropTargetMode;\n\n /** Carries the siblings a layout reflow displaces to their slots over time\n * instead of snapping them — `useAnimatedReflow` builds one. Covers a\n * drag's reflow and every one the scene records (an insert, delete,\n * reorder or resize inside a laid-out container). Absent or `null`,\n * they snap. */\n reflowTransition?: ReflowTransition<TPose> | null;\n\n /** Glides what is shown when the scene writes a pose — a `scene.setPose`, an undo — and sees\n * removed nodes off with `exit`. Absent or `null`, writes snap. See {@link PoseTransitionSeat}. */\n poseTransition?: PoseTransitionSeat<TPose> | null;\n\n /**\n * Lets pose-transform actions (move, resize, nudge, flip — NOT rotate) also rewrite a\n * node's data-held geometry. Given a node and the affine `m` applied to its pose,\n * `transform(node, m)` returns updated `data`, or `null` for nodes with no data-held\n * geometry. When absent, the kit emits only the pose op and leaves `data` untouched.\n *\n * @see GeometryProjection\n */\n geometryProjection?: GeometryProjection;\n\n /**\n * Routing-trait classifiers. The kit builds a `NodeRouting` registry per `<SceneCanvas>`\n * from this prop and uses it to derive each hit's `kind`, which tool routing tables\n * (e.g. `{ target: 'rect', actionId: 'move' }`) match against. Pass `defaultNodeRouting`\n * for the kit's built-in shape kinds; spread additional entries for consumer-defined\n * kinds.\n *\n * **Memoize the `routing` value.** The registry is memoized on the prop's reference\n * identity: a fresh array each render rebuilds it and cascades into a new adapter,\n * churning gesture state.\n */\n routing?: readonly NodeRoutingEntry[];\n\n /** How to read and rewrite this scene's poses. Every built-in action,\n * the selection chrome and picking read it. Default `AUTO_POSE_DESCRIPTOR`\n * (rect poses and `Path` poses). */\n poseDescriptor?: PoseDescriptor<TPose>;\n\n // --- Geometry: hit-test + bounds overrides consumed by the internal\n // `useSelectTool`. Ignored if the consumer passes their own `tools`. ---\n geometry?: SceneCanvasGeometry;\n\n // --- Selection options. `pickBest` and `handleHitRadius` configure the\n // internal select tool, and are ignored under a `tools` takeover;\n // `move`, `resize` and `rotate` configure the `move`,\n // `resize` and `rotate` presets, and apply either way. ---\n selectTool?: {\n move?: UseMoveOptions<TPose>;\n resize?: UseResizeOptions<TPose>;\n /** Rotation options, or `false` to hide the rotation handle and bind it to\n * nothing; the `rotate` action stays, for other tools and `actions.rotate`. */\n rotate?: UseRotateOptions<TPose> | false;\n handleHitRadius?: number;\n /** Override the body-pick used on click/pointerdown. Alt-aware: receives\n * the live alt state + current selection so consumers can implement\n * alt-cycling through an overlapping stack. Default: top-most hit\n * (alt ignored). */\n pickBest?: (worldX: number, worldY: number, alt: boolean, sel: readonly string[]) => string | null;\n };\n\n /** Consumer node factories for the `insert` action, keyed by tool `kind`.\n * Each factory receives the drag AABB + tool `extras` and returns the\n * node's `data` (in this canvas's own data shape) plus an optional `pose`.\n * A factory for a kit kind (`rect`, `line`, …) replaces the kit's default\n * `{ path, fill }` node for that kind; a factory for a novel kind (e.g.\n * `text`) adds insert support the kit doesn't ship. The dep supplies id,\n * layer, and the undoable op. Return `null` to reject an insert. */\n insertNodeFactories?: Record<string, InsertNodeFactory>;\n\n /** The fill, stroke, and fill rule a kit-built shape is inserted with, by\n * tool `kind` and insert count; the kit keeps the geometry. Default\n * `paletteInsertPaint`, the kit palette in turn. A kind with a factory in\n * `insertNodeFactories` is not asked. */\n insertPaint?: InsertPaint;\n\n /** External-content ingestion (OS drop / clipboard paste / picker).\n *\n * - `handlers` — consumer content handlers registered for this canvas's\n * lifetime (priority 0 by default — they beat the kit's `image/*` /\n * `image/svg+xml` handlers at -100/-90).\n * - `resolveSrc` — overrides the image handler's `data:`-URI embed (e.g.\n * upload to an asset store, return the URL).\n * - `svg.unpack` — makes the kit SVG handler parse dropped SVG files into\n * native scene nodes instead of one embedded-image node each.\n * - `clipboard` — the kit weasel-JSON paste handler, enabled by default.\n * `reviver` restores JSON-unfriendly values the copying side encoded via\n * `jsonReplacer`. `enabled: false` opts the canvas out, but the kit\n * handler still consumes weasel-matching items and declines them inert\n * rather than letting them fall through. Also governs Cmd/Ctrl+V under\n * the `edit` preset; the rest takes the `ingest` preset.\n *\n * Memoize `handlers` and `clipboard.reviver`: an inline array literal\n * re-registers the handlers on every render. */\n ingestion?: {\n handlers?: ContentHandlerEntry[];\n resolveSrc?: (file: File) => Promise<string>;\n svg?: SvgIngestOptions;\n clipboard?: {\n reviver?: (key: string, value: unknown) => unknown;\n enabled?: boolean;\n /** Called when a paste left copied nodes out, with each one and the\n * reason. `useClipboardOps` takes the same callback as\n * `onPasteOmitted` for a paste from its own in-memory copy. */\n onOmitted?: (omitted: PasteOmission[]) => void;\n };\n };\n\n selection?: SelectionApi;\n selectionOptions?: UseSelectionOptions;\n\n /**\n * `false` stops the canvas writing the selection: no click, marquee,\n * lasso, action or tool, and no op committed through the adapter it hands\n * its tools. The consumer's own `SelectionApi` — the `selection` prop, or\n * `useSelection({ scene })` — still writes, and the canvas draws what it\n * holds. Undo and redo still restore the selection each history entry\n * recorded. Default `true`.\n *\n * Click policy (whether shift-click extends) is the selection's `mode`:\n * `useSelection({ mode: 'multi' })`, or `selectionOptions={{ mode: 'multi' }}`\n * for the selection the canvas builds itself.\n */\n selectable?: boolean;\n\n /**\n * Behavior presets to turn on, composable in any combination. A canvas\n * with none renders its scene and keeps a selection (the `selection` API\n * works) that no input sets: no tools, no standard actions or their keys,\n * no clipboard, no drop or paste, and no selection chrome. The dispatcher\n * is still mounted, so bindings a consumer adds work.\n *\n * - `view` — wheel pan and zoom, pinch, the zoom keys, and the hand tool\n * (H, or hold Space). Passing `viewport` implies it.\n * - `select` — the select tool, as the initial active tool and Escape's\n * return target: click to pick, drag on empty to marquee, click on empty\n * to clear.\n * - `outline` — the selection outline, whichever tool sets the selection.\n * - `pick` — `select` and `outline`.\n * - `move` — drag a body to move it, Alt-drag to clone it. Ambient, so it\n * runs under any tool that does not claim the drag.\n * - `resize` — resize handles, drawn and bound.\n * - `rotate` — the rotation handle, drawn and bound.\n * - `transform` — `resize` and `rotate`.\n * - `edit` — undo/redo, delete, duplicate, group/ungroup, nudge,\n * select-all, Escape, cancel-gesture, cut/copy/paste, fill and stroke,\n * and their keys. Cmd/Ctrl+V pastes nodes a kit canvas copied, from\n * this tab or another, and nothing else.\n * - `arrange` — align, distribute, reorder, flip.\n * - `paths` — pathfinder operations, path-edit entry and anchor editing.\n * - `ingest` — dropped and pasted content: images, SVG, files, and\n * whatever `ingestion.handlers` accept, on Cmd/Ctrl+V or an OS drop.\n * - `draw` — all of the above.\n *\n * Any `FeaturePreset` object goes beside the names: core's own\n * (`pathsPreset`), or one a package ships.\n * Tools add the actions they bind — a shape tool brings `insert` — so\n * `defaultTools` composes with any preset. `actions` then adds, overrides\n * or removes on top of what the presets registered.\n */\n features?: readonly FeatureEntry[];\n\n /** Extra tools or overrides keyed by id, or a full `ToolsApi` takeover.\n *\n * **Patch form** (`Record<string, Tool | true | false>`): merged\n * into the built-in registry on top of whatever `defaultTools` and\n * `features` already selected.\n * - `true` pulls in the built-in for this id (`'pen'`, `'lasso'`,\n * `'hand'`, …), the same as listing it in `defaultTools`. Unknown\n * built-in ids warn in dev and are ignored.\n * - `Tool` adds a new id or replaces an existing one in place\n * (dev-only warning if `defaultTools` also names that id).\n * - `false` omits a bundled tool entirely.\n * Auto-wiring (keybindings, dispatcher, action registry) still runs.\n *\n * **Takeover form** (`ToolsApi`): the internal registry is bypassed and\n * this `tools` value is forwarded to Canvas as-is — the consumer owns\n * active-slot management, and `pick`'s select tool is theirs to supply.\n * Every other preset still applies. Keybindings are still auto-wired\n * against the supplied registry; pass `enableKeybindings={false}` to opt\n * out. */\n tools?: ToolsApi | Record<string, Tool | true | false>;\n\n /**\n * Auto-wire keyboard shortcuts. Default `true`. When `false`, SceneCanvas still mounts\n * its tools but routes no keyboard input to them — neither tool hotkeys nor\n * keyboard-bound actions like delete / escape / nudge. Pointer, wheel, and contextmenu\n * interactions are unaffected.\n */\n enableKeybindings?: boolean;\n\n /**\n * Take the keyboard on mount, as a press in the canvas would. A key that\n * reaches the page goes to the canvas the user last pressed or scrolled\n * in, and to no canvas before the first such interaction, so a canvas in a\n * side panel does not take Space from a page that wants it. An app whose\n * canvas is the page sets this so its shortcuts work before the first\n * click. Default `false`.\n */\n claimKeys?: boolean;\n\n /**\n * Auto-mount the gesture dispatcher (`useGestureDispatcher`). Default `true`. `false` is\n * for tests or demos that drive actions another way, or that call\n * `useGestureDispatcher` themselves.\n */\n enableGestureDispatcher?: boolean;\n\n /** Called with the `ToolsApi` SceneCanvas constructs or receives, whenever its identity\n * changes. For introspection. */\n onToolsCreated?: (tools: ToolsApi) => void;\n\n /**\n * Built-in tools SceneCanvas registers in its internal `useTools`, on top\n * of the ones presets bring (`select` from `pick`, `hand` from `view`):\n * ids, or sets of them such as `SHAPE_TOOLS`, or `withoutTools(...)` of one.\n * Default: none. Each tool also registers the kit actions it binds, so\n * `['rect']` brings `insert`. Ignored when the consumer supplies their own\n * `tools` prop.\n */\n defaultTools?: readonly ToolEntry<BuiltinToolId>[];\n\n /** Per-tool option overrides for the built-in tools. Each entry is a\n * narrow subset of the underlying hook's options surface — `lasso.mode`,\n * `rig.state`, etc. */\n toolOptions?: BuiltinToolOptions;\n /** What gestures snap to, and how near it pulls. */\n snap?: SceneCanvasSnap;\n\n /** Initial active-slot tool id. Default: `'select'` when it is\n * registered, otherwise none — a canvas can run on ambient bindings\n * alone. Must be one of the registered tools. Ignored when the consumer\n * supplies their own `tools` prop. */\n initialActiveTool?: string;\n\n /** Always-on entries to register alongside the internal tools — every one\n * a `SurfaceContribution`, whose views, deps, overlay, bindings, actions\n * and `attach` all install from this one list, and uninstall when the\n * entry leaves it. A tool is a contribution too, so one can go here. If\n * you supply your own `tools` prop, this is ignored — wire `ambient`\n * through your own `useTools` call instead. */\n ambient?: readonly SurfaceContribution[];\n\n /** What an entry's `requires` does when the running kit does not meet\n * it: `'warn'` (the default) logs in development, `'strict'` throws,\n * `'off'` skips the check. */\n versionCheck?: VersionCheck;\n\n /** Touch and pen long-press: its hold time, its haptic, and the\n * feedback shown while it is held. */\n longPress?: SceneCanvasLongPress;\n\n /** Configures the `view` preset, and implies it. See {@link SceneCanvasViewport}. */\n viewport?: SceneCanvasViewport;\n\n /**\n * Given a scene node, return a short human-readable \"kind\" label (e.g. `'rectangle'`,\n * `'sticky note'`), which the kit publishes per id into any surrounding\n * `<SelectionContextProvider>`. Return `undefined` to skip an entry. When omitted,\n * each node reports its routing kind (see `routing`), and a node that routes as\n * `'unknown'` is left unlabeled.\n */\n describeKind?: (node: Node<TData, TLayer, TPose>) => string | undefined;\n\n /**\n * Animator to bind for per-frame redraws. SceneCanvas requests a redraw on every active\n * animation frame and paints `animator.colorOverrides` onto the scene's nodes: the\n * kit's path and shape painters apply them, and a custom `drawOne` receives them as\n * `ctx.vertexColors`.\n */\n animator?: Animator;\n\n /**\n * Extra views on this canvas: each is a camera over a rect of the same\n * surface, drawn through one GL context, with input routed to it. The flat\n * `view` / `onViewChange` props above stay the canvas's own camera — view\n * zero — and are unaffected by anything declared here.\n *\n * Order is paint and hit order, low to high. Each entry is a\n * `<CanvasView>`; mounting one as a child is the same declaration, and\n * children land after every entry here.\n */\n views?: readonly CanvasViewProps[];\n\n /**\n * Children rendered alongside the canvas, inside its input scope (e.g.\n * shortcuts overlays, probes).\n */\n children?: ReactNode;\n\n /** A yoke to join, from `useYoke()`: canvases on one yoke share the active tool, the gesture\n * in flight and history. Omitted, this canvas keeps its own. */\n yoke?: Yoke;\n\n /**\n * Chrome-caps visibility overrides, keyed by chrome id (`selection.outline`,\n * `selection.rotation-handle`, `gesture.marquee`, …). Each entry is a composable\n * {@link Condition} built from the `cond()` builder, merged on top of the kit's\n * `defaultVisibilityRules`. Set an id to `never` to suppress a chrome element\n * entirely (also unhittable), or to `always` to force-show.\n */\n chromeVisibility?: import('features/chrome-caps').VisibilityRules;\n\n /**\n * The app's mode registry (`createModeRegistry` in `@weasel-js/modes`).\n * The canvas reads the active mode from it to gate chrome, tool\n * activation and the dispatcher's eligibility filter, repaints when it\n * switches, and hands every registered mode to the dev-time route-conflict\n * check. Omitted, the canvas behaves as the kit's normal mode and nothing\n * revokes anchor editing.\n */\n modes?: ModeRegistry;\n\n /** Hands which path is being anchor-edited to the host. See {@link PathEditHost}. */\n pathEdit?: PathEditHost;\n /** A path to open in anchor edit as the canvas mounts, with anchors selected. Read once. */\n defaultPathEdit?: PathEditOpening;\n\n /**\n * Override detected device facts. Merged over what `matchMedia` reports;\n * `targetScale` is re-derived from the merged `coarsePointer` unless you\n * override it explicitly.\n */\n device?: Partial<DeviceProfile>;\n\n /**\n * Live focus getter for chrome-caps' `focused` ctx field, for visibility rules that\n * read the `focused` atom (the kit's default `selection.rotation-handle` rule does).\n * Omit to default `focused` to `true`.\n */\n getFocused?: () => boolean;\n\n /** Custom shader programs to compile on the renderer. See `CanvasProps.shaders`. */\n shaders?: ShaderProgramHandle[];\n\n /** Flatness tolerance for curve tessellation. See `CanvasProps.flattenTolerance`. */\n flattenTolerance?: FlattenTolerance;\n\n /** Fill for the full canvas behind the scene, drawn as a screen-space layer slotted\n * before `'scene'` — independent of pan / zoom. */\n backgroundFill?: Paint;\n /** Dev HUD: a fixed-position widget showing live cursor coords in both viewport\n * (client) and canvas (world) frames. */\n cursorCoordsHud?: boolean;\n /** Dev HUD: a fixed-position widget listing the ids `pickEvery(world)` returns under\n * the cursor. */\n pickHud?: boolean;\n /**\n * The debug overlay: `<Canvas debug>`'s config, plus `slops: true` for\n * translucent halos at every affordance hit zone. `false` turns it off;\n * absent reads `?debug=…` from the URL, as `<Canvas>` does.\n */\n debug?: (DebugConfig & { slops?: boolean }) | false;\n /**\n * Dev HUD: when true (or object), mounts a fixed-position widget below\n * the pick HUD showing the active modality mode, active-slot tool, and\n * hotkey stack. Pass `{ modeId }` to populate the mode line.\n */\n modalityHud?: boolean | { modeId?: string };\n\n /**\n * Per-id alpha multiplier for the scene-render slot: each node's draw output is wrapped\n * in a group with the returned alpha, and 1 emits no wrapper. Typical use: dimming\n * non-active nodes during a mode transition.\n */\n alphaFor?: (id: string) => number;\n\n /**\n * Show or hide render layers in this canvas's own view, by id — the map\n * `<Canvas>` takes. Each scene layer paints as its own render layer, keyed\n * `scene:<layerId>`, so `{ 'scene:guides': false }` hides one scene layer\n * here and nowhere else.\n *\n * A layer hidden this way is gone from this view: it does not paint, and a\n * click, a marquee or Cmd+A here passes over it. Another view of the same\n * scene — a `<CanvasView>`, a second canvas, a minimap — still shows it and\n * can still take it. It applies on top of the scene's own\n * `LayerRecord.visible` and cannot show a layer the scene hides.\n */\n layerVisibility?: Record<string, boolean>;\n\n /**\n * Draw order for this view, by render-layer id, bottom first. A listed\n * order is the whole list: a scene layer left out of it is neither painted\n * nor picked here. See `CanvasProps.layerOrder`.\n */\n layerOrder?: string[];\n } & SceneCanvasPointerProps & SceneCanvasActionProps;\n"],"mappings":";;;;;;;;AAqDA,IAAa,sBAAsB"}
|
|
1
|
+
{"version":3,"file":"props.js","names":[],"sources":["../../../src/canvas/SceneCanvas/props.ts"],"sourcesContent":["import type { ModeRegistry } from '@weasel-js/modes';\nimport type { PathEditHost, PathEditOpening } from './pathEditHost';\nimport type { SceneCanvasGeometry } from './geometryProps';\nimport type { SceneCanvasHit, SceneCanvasPointerProps } from './pointerProps';\nimport type { Paint } from '@weasel-js/paint';\nimport type { SceneCanvasActionProps } from './actionProps';\nimport { Yoke } from '@weasel-js/routing/react';\nimport type { PasteOmission } from 'core/adapters/types';\nimport type { Op } from 'core/ops/types';\nimport type { Node, Scene, SerializedScene } from 'core/scene/types';\nimport type { SelectionApi, UseSelectionOptions } from 'core/selection/useSelection';\nimport type { ContentHandlerEntry, KitHandlersOption } from 'domains/ingestion';\nimport type { SceneCanvasSnap } from 'domains/snap/types';\nimport type { SvgIngestOptions } from 'interactions/actions/depSchema';\nimport type { GeometryProjection } from 'interactions/actions/geometryProjection';\nimport type { UseMoveOptions } from 'interactions/actions/move/options';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport type { UseResizeOptions } from 'interactions/actions/resize/options';\nimport type { UseRotateOptions } from 'interactions/actions/rotate/options';\nimport type { ReactNode } from 'react';\nimport type { Animator } from '@weasel-js/animator';\nimport type { PoseTransitionSeat } from '../../animation/poseTransition';\nimport { HANDLE_BASE_PX } from '../../core/device/targets';\nimport type { DeviceProfile } from '../../core/device/types';\nimport type { NodeRoutingEntry } from '../../core/scene/NodeRouting';\nimport type { DebugConfig } from '../../debug/types';\nimport type { LayoutDropTargetMode, ReflowTransition } from '../../layout/types';\nimport type { FlattenTolerance, ShaderProgramHandle } from '@weasel-js/renderer';\nimport type { Tool, ToolsApi } from '../../tools/overlayBinding';\nimport type { SceneSlotConfig } from '../buildSceneLayer';\nimport type { CanvasProps } from '../Canvas';\nimport type { LayersMap } from '../layerSlots';\nimport type { CanvasViewProps } from '../CanvasView';\nimport type { InsertNodeFactory, InsertPaint } from '../deps';\nimport type { SurfaceContribution } from '../surfaceContribution';\nimport type { CameraProps } from '../useCanvasView';\nimport type { FeatureEntry } from './features';\nimport type { BuiltinToolOptions } from './useBuiltinShapeTools';\nimport type { VersionCheck } from './useContributionRoles';\nimport type { SceneCanvasViewport } from './viewportProp';\n\n/** The adapter surface delete / duplicate / group / ungroup need, narrowed from\n * `SceneCanvasAdapter` because `useSceneStandardActions` is non-generic. */\nexport interface BridgeAdapter {\n applyOps(ops: Op[], label?: string): void;\n insertNode(node: { id: string; [k: string]: unknown }): void;\n removeNode(id: string): void;\n setSelection(ids: string[]): void;\n}\n\n/** Default size in CSS pixels for selection corner-handles AND their\n * hit-test radius, at `targetScale = 1`. Deliberately unscaled; kit-internal\n * use sites multiply by `DeviceProfile.targetScale`. */\nexport const DEFAULT_HANDLE_SIZE = HANDLE_BASE_PX;\n\n/** `<SceneCanvas longPress>`. */\nexport interface SceneCanvasLongPress {\n /**\n * Shown while a long-press is held and some binding would fire on it.\n * Default: a ring that fills around the press point\n * (`createLongPressFeedbackContribution()`), static under\n * `prefers-reduced-motion`. `false` shows nothing; a contribution replaces\n * it, reading the `longPress` dep. Installed beside `ambient` and beside a `tools`\n * takeover, unless the takeover's ambient holds an entry of the same id.\n */\n feedback?: boolean | SurfaceContribution;\n /** Default true. A long-press some binding handled pulses\n * `navigator.vibrate` briefly, for touch and pen, where the API exists. */\n haptics?: boolean;\n /** Hold time in ms. Default `LONG_PRESS_MS` (500). */\n duration?: number;\n}\n\n/** `<SceneCanvas layers>`: a {@link LayersMap} whose scene slot may be partial,\n * since the defaults fill in whatever it leaves out. */\nexport type SceneCanvasLayers<TNode extends { id: string }, TPose> = LayersMap<\n TNode,\n TPose,\n Partial<SceneSlotConfig<TNode, TPose>>\n>;\n\nimport type { BuiltinToolId } from './builtinToolSets';\nimport type { ToolEntry } from '@weasel-js/routing';\nexport { BUILTIN_TOOL_IDS, type BuiltinToolId } from './builtinToolSets';\n\nexport type { SceneCanvasHit };\n\n/** Props for `<SceneCanvas>`. A scene is the only thing it needs. With nothing\n * else it renders that scene and keeps a selection no input sets; `features`\n * turns behavior on by preset, and the rest configures what those turn on. */\nexport type SceneCanvasProps<TData, TLayer extends string, TPose> =\n Omit<\n CanvasProps<TPose>,\n | 'adapter' | 'boundsOf' | 'selection' | 'tools'\n | 'viewState' // SceneCanvas makes the camera from the view props below\n | 'layers' // stripped so we can re-add as optional below\n | 'getIsVisible' // SceneCanvas synthesizes this from chromeVisibility\n | 'contentVersion' // SceneCanvas wires this to the scene's own version\n | 'layerVisibility' | 'layerOrder' // re-declared below: they gate picking here too\n | 'debug' // re-declared below with SceneCanvas's own `slops`\n > & CameraProps\n & {\n /** A `Scene` (typically from `useScene`) — or a `SerializedScene` JSON\n * object, which SceneCanvas bakes into a Scene on first render. The\n * serialized form is read once; pass a `key` on `<SceneCanvas>` to force\n * a fresh canvas from updated JSON.\n *\n * The JSON shape is relaxed (`version: number` rather than the `1`\n * literal) so an `import json from './x.json'` result satisfies the type\n * without an `as` cast. */\n scene:\n | Scene<TData, TLayer, TPose>\n | SerializedScene<TData, TLayer, TPose>\n | { version: number; systemLayers?: ReadonlyArray<{ id: string }>; nodes: ReadonlyArray<unknown> };\n\n /** Layer configuration. When omitted, SceneCanvas applies kit defaults\n * (a scene slot that paints `node.data.fill` rects + a default\n * selection overlay). A partial scene or selection-overlay config is\n * spread over that slot's defaults; pass `slot: null` to suppress a\n * default explicitly. */\n layers?: SceneCanvasLayers<Node<TData, TLayer, TPose>, TPose>;\n\n /** Which layout container a drag lands in when several contain the drop\n * point — the innermost (default), the topmost in paint order, or only\n * containers whose strategy declares a `dropRegion`. Decides both the\n * drag-time reflow preview and the commit. */\n layoutDropTarget?: LayoutDropTargetMode;\n\n /** Carries the siblings a layout reflow displaces to their slots over time\n * instead of snapping them — `useAnimatedReflow` builds one. Covers a\n * drag's reflow and every one the scene records (an insert, delete,\n * reorder or resize inside a laid-out container). Absent or `null`,\n * they snap. */\n reflowTransition?: ReflowTransition<TPose> | null;\n\n /** Glides what is shown when the scene writes a pose — a `scene.setPose`, an undo — and sees\n * removed nodes off with `exit`. Absent or `null`, writes snap. See {@link PoseTransitionSeat}. */\n poseTransition?: PoseTransitionSeat<TPose> | null;\n\n /**\n * Lets pose-transform actions (move, resize, nudge, flip — NOT rotate) also rewrite a\n * node's data-held geometry: `transform(node, m, change)` returns updated `data`, or\n * `null` for nodes with no data-held geometry. When absent, the kit emits only the pose\n * op and leaves `data` untouched.\n *\n * @see GeometryProjection\n */\n geometryProjection?: GeometryProjection;\n\n /**\n * Routing-trait classifiers. The kit builds a `NodeRouting` registry per `<SceneCanvas>`\n * from this prop and uses it to derive each hit's `kind`, which tool routing tables\n * (e.g. `{ target: 'rect', actionId: 'move' }`) match against. Pass `defaultNodeRouting`\n * for the kit's built-in shape kinds; spread additional entries for consumer-defined\n * kinds.\n *\n * **Memoize the `routing` value.** The registry is memoized on the prop's reference\n * identity: a fresh array each render rebuilds it and cascades into a new adapter,\n * churning gesture state.\n */\n routing?: readonly NodeRoutingEntry[];\n\n /** How to read and rewrite this scene's poses. Every built-in action,\n * the selection chrome and picking read it. Default `AUTO_POSE_DESCRIPTOR`\n * (rect poses and `Path` poses). */\n poseDescriptor?: PoseDescriptor<TPose>;\n\n // --- Geometry: hit-test + bounds overrides consumed by the internal\n // `useSelectTool`. Ignored if the consumer passes their own `tools`. ---\n geometry?: SceneCanvasGeometry;\n\n // --- Selection options. `pickBest` and `handleHitRadius` configure the\n // internal select tool, and are ignored under a `tools` takeover;\n // `move`, `resize` and `rotate` configure the `move`,\n // `resize` and `rotate` presets, and apply either way. ---\n selectTool?: {\n move?: UseMoveOptions<TPose>;\n resize?: UseResizeOptions<TPose>;\n /** Rotation options, or `false` to hide the rotation handle and bind it to\n * nothing; the `rotate` action stays, for other tools and `actions.rotate`. */\n rotate?: UseRotateOptions<TPose> | false;\n handleHitRadius?: number;\n /** Override the body-pick used on click/pointerdown. Alt-aware: receives\n * the live alt state + current selection so consumers can implement\n * alt-cycling through an overlapping stack. Default: top-most hit\n * (alt ignored). */\n pickBest?: (world: import('@weasel-js/routing').WorldPoint, alt: boolean, sel: readonly string[]) => string | null;\n };\n\n /** Consumer node factories for the `insert` action, keyed by tool `kind`.\n * Each factory receives the drag AABB + tool `extras` and returns the\n * node's `data` (in this canvas's own data shape) plus an optional `pose`.\n * A factory for a kit kind (`rect`, `line`, …) replaces the kit's default\n * `{ path, fill }` node for that kind; a factory for a novel kind (e.g.\n * `text`) adds insert support the kit doesn't ship. The dep supplies id,\n * layer, and the undoable op. Return `null` to reject an insert. */\n insertNodeFactories?: Record<string, InsertNodeFactory>;\n\n /** The fill, stroke, and fill rule a kit-built shape is inserted with, by\n * tool `kind` and insert count; the kit keeps the geometry. Default\n * `paletteInsertPaint`, the kit palette in turn. A kind with a factory in\n * `insertNodeFactories` is not asked. */\n insertPaint?: InsertPaint;\n\n /** External-content ingestion (OS drop / clipboard paste / picker).\n *\n * - `handlers` — content handlers for this canvas alone, priority 0 by default, above\n * the kit's. One for every canvas on the page goes through `registerContentHandler`.\n * - `kitHandlers` — which kit handlers it keeps (`KitHandlersOption`); default all.\n * - `resolveSrc` — overrides the image handler's `data:`-URI embed (e.g.\n * upload to an asset store, return the URL).\n * - `svg.unpack` — makes the kit SVG handler parse dropped SVG files into\n * native scene nodes instead of one embedded-image node each.\n * - `clipboard` — the kit weasel-JSON paste handler, enabled by default.\n * `reviver` restores JSON-unfriendly values the copying side encoded via\n * `jsonReplacer`. `enabled: false` opts the canvas out, but the kit\n * handler still consumes weasel-matching items and declines them inert\n * rather than letting them fall through. Also governs Cmd/Ctrl+V under\n * the `edit` preset; the rest takes the `ingest` preset.\n *\n * Memoize `handlers` and `clipboard.reviver`: inline literals rebuild them every render. */\n ingestion?: {\n handlers?: ContentHandlerEntry[];\n kitHandlers?: KitHandlersOption;\n resolveSrc?: (file: File) => Promise<string>;\n svg?: SvgIngestOptions;\n clipboard?: {\n reviver?: (key: string, value: unknown) => unknown;\n enabled?: boolean;\n /** Called when a paste left copied nodes out, with each one and the\n * reason. `useClipboardOps` takes the same callback as\n * `onPasteOmitted` for a paste from its own in-memory copy. */\n onOmitted?: (omitted: PasteOmission[]) => void;\n };\n };\n\n selection?: SelectionApi;\n selectionOptions?: UseSelectionOptions;\n\n /**\n * `false` stops the canvas writing the selection: no click, marquee,\n * lasso, action or tool, and no op committed through the adapter it hands\n * its tools. The consumer's own `SelectionApi` — the `selection` prop, or\n * `useSelection({ scene })` — still writes, and the canvas draws what it\n * holds. Undo and redo still restore the selection each history entry\n * recorded. Default `true`.\n *\n * Click policy (whether shift-click extends) is the selection's `mode`:\n * `useSelection({ mode: 'multi' })`, or `selectionOptions={{ mode: 'multi' }}`\n * for the selection the canvas builds itself.\n */\n selectable?: boolean;\n\n /**\n * Behavior presets to turn on, composable in any combination. A canvas\n * with none renders its scene and keeps a selection (the `selection` API\n * works) that no input sets: no tools, no standard actions or their keys,\n * no clipboard, no drop or paste, and no selection chrome. The dispatcher\n * is still mounted, so bindings a consumer adds work.\n *\n * - `view` — wheel pan and zoom, pinch, the zoom keys, and the hand tool\n * (H, or hold Space). Passing `viewport` implies it.\n * - `select` — the select tool, as the initial active tool and Escape's\n * return target: click to pick, drag on empty to marquee, click on empty\n * to clear.\n * - `outline` — the selection outline, whichever tool sets the selection.\n * - `pick` — `select` and `outline`.\n * - `move` — drag a body to move it, Alt-drag to clone it. Ambient, so it\n * runs under any tool that does not claim the drag.\n * - `resize` — resize handles, drawn and bound.\n * - `rotate` — the rotation handle, drawn and bound.\n * - `transform` — `resize` and `rotate`.\n * - `edit` — undo/redo, delete, duplicate, group/ungroup, nudge,\n * select-all, Escape, cancel-gesture, cut/copy/paste, fill and stroke,\n * and their keys. Cmd/Ctrl+V pastes nodes a kit canvas copied, from\n * this tab or another, and nothing else.\n * - `arrange` — align, distribute, reorder, flip.\n * - `paths` — pathfinder operations, path-edit entry and anchor editing.\n * - `ingest` — dropped and pasted content: images, SVG, files, and\n * whatever `ingestion.handlers` accept, on Cmd/Ctrl+V or an OS drop.\n * - `draw` — all of the above.\n *\n * Any `FeaturePreset` object goes beside the names: core's own\n * (`pathsPreset`), or one a package ships.\n * Tools add the actions they bind — a shape tool brings `insert` — so\n * `defaultTools` composes with any preset. `actions` then adds, overrides\n * or removes on top of what the presets registered.\n */\n features?: readonly FeatureEntry[];\n\n /** Extra tools or overrides keyed by id, or a full `ToolsApi` takeover.\n *\n * **Patch form** (`Record<string, Tool | true | false>`): merged\n * into the built-in registry on top of whatever `defaultTools` and\n * `features` already selected.\n * - `true` pulls in the built-in for this id (`'pen'`, `'lasso'`,\n * `'hand'`, …), the same as listing it in `defaultTools`. Unknown\n * built-in ids warn in dev and are ignored.\n * - `Tool` adds a new id or replaces an existing one in place\n * (dev-only warning if `defaultTools` also names that id).\n * - `false` omits a bundled tool entirely.\n * Auto-wiring (keybindings, dispatcher, action registry) still runs.\n *\n * **Takeover form** (`ToolsApi`): the internal registry is bypassed and\n * this `tools` value is forwarded to Canvas as-is — the consumer owns\n * active-slot management, and `pick`'s select tool is theirs to supply.\n * Every other preset still applies. Keybindings are still auto-wired\n * against the supplied registry; pass `enableKeybindings={false}` to opt\n * out. */\n tools?: ToolsApi | Record<string, Tool | true | false>;\n\n /**\n * Auto-wire keyboard shortcuts. Default `true`. When `false`, SceneCanvas still mounts\n * its tools but routes no keyboard input to them — neither tool hotkeys nor\n * keyboard-bound actions like delete / escape / nudge. Pointer, wheel, and contextmenu\n * interactions are unaffected.\n */\n enableKeybindings?: boolean;\n\n /**\n * Take the keyboard on mount, as a press in the canvas would. A key that\n * reaches the page goes to the canvas the user last pressed or scrolled\n * in, and to no canvas before the first such interaction, so a canvas in a\n * side panel does not take Space from a page that wants it. An app whose\n * canvas is the page sets this so its shortcuts work before the first\n * click. Default `false`.\n */\n claimKeys?: boolean;\n\n /**\n * Auto-mount the gesture dispatcher (`useGestureDispatcher`). Default `true`. `false` is\n * for tests or demos that drive actions another way, or that call\n * `useGestureDispatcher` themselves.\n */\n enableGestureDispatcher?: boolean;\n\n /** Called with the `ToolsApi` SceneCanvas constructs or receives, whenever its identity\n * changes. For introspection. */\n onToolsCreated?: (tools: ToolsApi) => void;\n\n /**\n * Built-in tools SceneCanvas registers in its internal `useTools`, on top\n * of the ones presets bring (`select` from `pick`, `hand` from `view`):\n * ids, or sets of them such as `SHAPE_TOOLS`, or `withoutTools(...)` of one.\n * Default: none. Each tool also registers the kit actions it binds, so\n * `['rect']` brings `insert`. Ignored when the consumer supplies their own\n * `tools` prop.\n */\n defaultTools?: readonly ToolEntry<BuiltinToolId>[];\n\n /** Per-tool option overrides for the built-in tools. Each entry is a\n * narrow subset of the underlying hook's options surface — `lasso.mode`,\n * `rig.state`, etc. */\n toolOptions?: BuiltinToolOptions;\n /** What gestures snap to, and how near it pulls. */\n snap?: SceneCanvasSnap;\n\n /** Initial active-slot tool id. Default: `'select'` when it is\n * registered, otherwise none — a canvas can run on ambient bindings\n * alone. Must be one of the registered tools. Ignored when the consumer\n * supplies their own `tools` prop. */\n initialActiveTool?: string;\n\n /** Always-on entries to register alongside the internal tools — every one\n * a `SurfaceContribution`, whose views, deps, overlay, bindings, actions\n * and `attach` all install from this one list, and uninstall when the\n * entry leaves it. A tool is a contribution too, so one can go here. If\n * you supply your own `tools` prop, this is ignored — wire `ambient`\n * through your own `useTools` call instead. */\n ambient?: readonly SurfaceContribution[];\n\n /** What an entry's `requires` does when the running kit does not meet\n * it: `'warn'` (the default) logs in development, `'strict'` throws,\n * `'off'` skips the check. */\n versionCheck?: VersionCheck;\n\n /** Touch and pen long-press: its hold time, its haptic, and the\n * feedback shown while it is held. */\n longPress?: SceneCanvasLongPress;\n\n /** Configures the `view` preset, and implies it. See {@link SceneCanvasViewport}. */\n viewport?: SceneCanvasViewport;\n\n /**\n * Given a scene node, return a short human-readable \"kind\" label (e.g. `'rectangle'`,\n * `'sticky note'`), which the kit publishes per id into any surrounding\n * `<SelectionContextProvider>`. Return `undefined` to skip an entry. When omitted,\n * each node reports its routing kind (see `routing`), and a node that routes as\n * `'unknown'` is left unlabeled.\n */\n describeKind?: (node: Node<TData, TLayer, TPose>) => string | undefined;\n\n /**\n * Animator to bind for per-frame redraws. SceneCanvas requests a redraw on every active\n * animation frame and paints `animator.colorOverrides` onto the scene's nodes: the\n * kit's path and shape painters apply them, and a custom `drawOne` receives them as\n * `ctx.vertexColors`.\n */\n animator?: Animator;\n\n /**\n * Extra views on this canvas: each is a camera over a rect of the same\n * surface, drawn through one GL context, with input routed to it. The flat\n * `view` / `onViewChange` props above stay the canvas's own camera — view\n * zero — and are unaffected by anything declared here.\n *\n * Order is paint and hit order, low to high. Each entry is a\n * `<CanvasView>`; mounting one as a child is the same declaration, and\n * children land after every entry here.\n */\n views?: readonly CanvasViewProps[];\n\n /**\n * Children rendered alongside the canvas, inside its input scope (e.g.\n * shortcuts overlays, probes).\n */\n children?: ReactNode;\n\n /** A yoke to join, from `useYoke()`: canvases on one yoke share the active tool, the gesture\n * in flight and history. Omitted, this canvas keeps its own. */\n yoke?: Yoke;\n\n /**\n * Chrome-caps visibility overrides, keyed by chrome id (`selection.outline`,\n * `selection.rotation-handle`, `gesture.marquee`, …). Each entry is a composable\n * {@link Condition} built from the `cond()` builder, merged on top of the kit's\n * `defaultVisibilityRules`. Set an id to `never` to suppress a chrome element\n * entirely (also unhittable), or to `always` to force-show.\n */\n chromeVisibility?: import('domains/chrome-caps').VisibilityRules;\n\n /**\n * The app's mode registry (`createModeRegistry` in `@weasel-js/modes`).\n * The canvas reads the active mode from it to gate chrome, tool\n * activation and the dispatcher's eligibility filter, repaints when it\n * switches, and hands every registered mode to the dev-time route-conflict\n * check. Omitted, the canvas behaves as the kit's normal mode and nothing\n * revokes anchor editing.\n */\n modes?: ModeRegistry;\n\n /** Hands which path is being anchor-edited to the host. See {@link PathEditHost}. */\n pathEdit?: PathEditHost;\n /** A path to open in anchor edit as the canvas mounts, with anchors selected. Read once. */\n defaultPathEdit?: PathEditOpening;\n\n /**\n * Override detected device facts. Merged over what `matchMedia` reports;\n * `targetScale` is re-derived from the merged `coarsePointer` unless you\n * override it explicitly.\n */\n device?: Partial<DeviceProfile>;\n\n /**\n * Live focus getter for chrome-caps' `focused` ctx field, for visibility rules that\n * read the `focused` atom (the kit's default `selection.rotation-handle` rule does).\n * Omit to default `focused` to `true`.\n */\n getFocused?: () => boolean;\n\n /** Custom shader programs to compile on the renderer. See `CanvasProps.shaders`. */\n shaders?: ShaderProgramHandle[];\n\n /** Flatness tolerance for curve tessellation. See `CanvasProps.flattenTolerance`. */\n flattenTolerance?: FlattenTolerance;\n\n /** Fill for the full canvas behind the scene, drawn as a screen-space layer slotted\n * before `'scene'` — independent of pan / zoom. */\n backgroundFill?: Paint;\n /** Dev HUD: a fixed-position widget showing live cursor coords in both viewport\n * (client) and canvas (world) frames. */\n cursorCoordsHud?: boolean;\n /** Dev HUD: a fixed-position widget listing the ids `pickEvery(world)` returns under\n * the cursor. */\n pickHud?: boolean;\n /**\n * The debug overlay: `<Canvas debug>`'s config, plus `slops: true` for\n * translucent halos at every affordance hit zone. `false` turns it off;\n * absent reads `?debug=…` from the URL, as `<Canvas>` does.\n */\n debug?: (DebugConfig & { slops?: boolean }) | false;\n /**\n * Dev HUD: when true (or object), mounts a fixed-position widget below\n * the pick HUD showing the active modality mode, active-slot tool, and\n * hotkey stack. Pass `{ modeId }` to populate the mode line.\n */\n modalityHud?: boolean | { modeId?: string };\n\n /**\n * Per-id alpha multiplier for the scene-render slot: each node's draw output is wrapped\n * in a group with the returned alpha, and 1 emits no wrapper. Typical use: dimming\n * non-active nodes during a mode transition.\n */\n alphaFor?: (id: string) => number;\n\n /**\n * Show or hide render layers in this canvas's own view, by id — the map\n * `<Canvas>` takes. Each scene layer paints as its own render layer, keyed\n * `scene:<layerId>`, so `{ 'scene:guides': false }` hides one scene layer\n * here and nowhere else.\n *\n * A layer hidden this way is gone from this view: it does not paint, and a\n * click, a marquee or Cmd+A here passes over it. Another view of the same\n * scene — a `<CanvasView>`, a second canvas, a minimap — still shows it and\n * can still take it. It applies on top of the scene's own\n * `LayerRecord.visible` and cannot show a layer the scene hides.\n */\n layerVisibility?: Record<string, boolean>;\n\n /**\n * Draw order for this view, by render-layer id, bottom first. A listed\n * order is the whole list: a scene layer left out of it is neither painted\n * nor picked here. See `CanvasProps.layerOrder`.\n */\n layerOrder?: string[];\n } & SceneCanvasPointerProps<TData> & SceneCanvasActionProps;\n"],"mappings":";;;;;;;;AAqDA,IAAa,sBAAsB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SHAPE_COUNT_RANGE, STAR_RATIO_RANGE } from "../../
|
|
1
|
+
import { SHAPE_COUNT_RANGE, STAR_RATIO_RANGE } from "../../domains/paths/shapeGenerator.js";
|
|
2
2
|
import { decimal } from "@weasel-js/quantity";
|
|
3
3
|
|
|
4
4
|
//#region src/canvas/SceneCanvas/shapeGeneratorProperties.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shapeGeneratorProperties.js","names":[],"sources":["../../../src/canvas/SceneCanvas/shapeGeneratorProperties.ts"],"sourcesContent":["import type { PrefSection } from '@weasel-js/prefs';\nimport { decimal } from '@weasel-js/quantity';\nimport { SHAPE_COUNT_RANGE, STAR_RATIO_RANGE } from '
|
|
1
|
+
{"version":3,"file":"shapeGeneratorProperties.js","names":[],"sources":["../../../src/canvas/SceneCanvas/shapeGeneratorProperties.ts"],"sourcesContent":["import type { PrefSection } from '@weasel-js/prefs';\nimport { decimal } from '@weasel-js/quantity';\nimport { SHAPE_COUNT_RANGE, STAR_RATIO_RANGE } from 'domains/paths/shapeGenerator';\n\nconst WHOLE = decimal({ maxPlaces: 2, grouping: false });\n\n/**\n * The rows that edit a polygon's or a star's `data.generator`, each shown only\n * on a node holding that kind's generator. A write to one regenerates the\n * shape through the entry's `settle` (`settleShapeGenerator`).\n */\nexport const SHAPE_GENERATOR_SECTIONS: Record<string, PrefSection> = {\n polygon: {\n name: 'Polygon',\n showIf: { path: 'data.generator.sides' },\n members: {\n 'data.generator.sides': {\n kind: 'number', display: WHOLE, name: 'Sides', description: 'Number of sides.',\n default: 6, min: SHAPE_COUNT_RANGE.min, max: SHAPE_COUNT_RANGE.max, step: 1,\n },\n },\n },\n star: {\n name: 'Star',\n showIf: { path: 'data.generator.points' },\n members: {\n 'data.generator.points': {\n kind: 'number', display: WHOLE, name: 'Points', description: 'Number of points.',\n default: 5, min: SHAPE_COUNT_RANGE.min, max: SHAPE_COUNT_RANGE.max, step: 1,\n },\n 'data.generator.innerRadiusRatio': {\n kind: 'number', name: 'Inner', description: 'Inner radius as a fraction of the outer one.',\n default: 0.5, min: STAR_RATIO_RANGE.min, max: STAR_RATIO_RANGE.max, step: 0.01, control: 'slider',\n },\n },\n },\n};\n"],"mappings":";;;;AAIA,IAAM,QAAQ,QAAQ;CAAE,WAAW;CAAG,UAAU;AAAM,CAAC;;;;;;AAOvD,IAAa,2BAAwD;CACnE,SAAS;EACP,MAAM;EACN,QAAQ,EAAE,MAAM,uBAAuB;EACvC,SAAS,EACP,wBAAwB;GACtB,MAAM;GAAU,SAAS;GAAO,MAAM;GAAS,aAAa;GAC5D,SAAS;GAAG,KAAK,kBAAkB;GAAK,KAAK,kBAAkB;GAAK,MAAM;EAC5E,EACF;CACF;CACA,MAAM;EACJ,MAAM;EACN,QAAQ,EAAE,MAAM,wBAAwB;EACxC,SAAS;GACP,yBAAyB;IACvB,MAAM;IAAU,SAAS;IAAO,MAAM;IAAU,aAAa;IAC7D,SAAS;IAAG,KAAK,kBAAkB;IAAK,KAAK,kBAAkB;IAAK,MAAM;GAC5E;GACA,mCAAmC;IACjC,MAAM;IAAU,MAAM;IAAS,aAAa;IAC5C,SAAS;IAAK,KAAK,iBAAiB;IAAK,KAAK,iBAAiB;IAAK,MAAM;IAAM,SAAS;GAC3F;EACF;CACF;AACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { presetBuiltinTools, presetOwnTools } from "./features.js";
|
|
2
1
|
import { BUILTIN_TOOL_IDS } from "./builtinToolSets.js";
|
|
2
|
+
import { presetBuiltinTools, presetOwnTools } from "./features.js";
|
|
3
3
|
import { isDev } from "@weasel-js/react";
|
|
4
4
|
import { toolIdsOf } from "@weasel-js/routing";
|
|
5
5
|
|
|
@@ -10,9 +10,10 @@ import { toolIdsOf } from "@weasel-js/routing";
|
|
|
10
10
|
* Built-ins come first, in `BUILTIN_TOOL_IDS` order whatever order they were
|
|
11
11
|
* asked for in, then the presets' own tools in preset order; a patch tool
|
|
12
12
|
* replaces a mounted one where it stands, and any other is appended in patch
|
|
13
|
-
* order.
|
|
14
|
-
*
|
|
15
|
-
* patch tool for an id `defaultTools`
|
|
13
|
+
* order. A palette keeps that order for tools its own order does not name.
|
|
14
|
+
* Replacing a tool that is mounted only because a preset implies it is the
|
|
15
|
+
* documented way to restyle it, so only a patch tool for an id `defaultTools`
|
|
16
|
+
* also names is warned about.
|
|
16
17
|
*/
|
|
17
18
|
function resolveToolRegistry(args) {
|
|
18
19
|
const { builtins, enabled, patch, dev = isDev() } = args;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolRegistry.js","names":[],"sources":["../../../src/canvas/SceneCanvas/toolRegistry.ts"],"sourcesContent":["import type { Tool } from 'tools/overlayBinding';\nimport { presetBuiltinTools, presetOwnTools, type EnabledPresets } from './features';\nimport { isDev } from '@weasel-js/react';\nimport { toolIdsOf, type ToolEntry } from '@weasel-js/routing';\nimport { BUILTIN_TOOL_IDS, type BuiltinToolId } from './props';\n\n/** The patch form of `<SceneCanvas tools>`: per id, `true` mounts that\n * built-in, `false` leaves it out, and a tool adds or replaces one. */\nexport type ToolsPatch = Record<string, Tool | true | false>;\n\n/** One tool per built-in id, mounted or not. */\nexport type BuiltinTools = Record<BuiltinToolId, Tool>;\n\nexport interface ResolveToolRegistryArgs {\n builtins: BuiltinTools;\n /** Built-ins asked for, by id or by set. */\n defaultTools?: readonly ToolEntry<BuiltinToolId>[];\n /** The presets the canvas runs with, each bringing the tools it names. */\n enabled: EnabledPresets;\n patch: ToolsPatch | null;\n /** Whether to warn about a patch entry that is probably a mistake. */\n dev?: boolean;\n}\n\n/**\n * The tool registry a canvas mounts when it is not handed a whole `ToolsApi`.\n *\n * Built-ins come first, in `BUILTIN_TOOL_IDS` order whatever order they were\n * asked for in, then the presets' own tools in preset order; a patch tool\n * replaces a mounted one where it stands, and any other is appended in patch\n * order.
|
|
1
|
+
{"version":3,"file":"toolRegistry.js","names":[],"sources":["../../../src/canvas/SceneCanvas/toolRegistry.ts"],"sourcesContent":["import type { Tool } from 'tools/overlayBinding';\nimport { presetBuiltinTools, presetOwnTools, type EnabledPresets } from './features';\nimport { isDev } from '@weasel-js/react';\nimport { toolIdsOf, type ToolEntry } from '@weasel-js/routing';\nimport { BUILTIN_TOOL_IDS, type BuiltinToolId } from './props';\n\n/** The patch form of `<SceneCanvas tools>`: per id, `true` mounts that\n * built-in, `false` leaves it out, and a tool adds or replaces one. */\nexport type ToolsPatch = Record<string, Tool | true | false>;\n\n/** One tool per built-in id, mounted or not. */\nexport type BuiltinTools = Record<BuiltinToolId, Tool>;\n\nexport interface ResolveToolRegistryArgs {\n builtins: BuiltinTools;\n /** Built-ins asked for, by id or by set. */\n defaultTools?: readonly ToolEntry<BuiltinToolId>[];\n /** The presets the canvas runs with, each bringing the tools it names. */\n enabled: EnabledPresets;\n patch: ToolsPatch | null;\n /** Whether to warn about a patch entry that is probably a mistake. */\n dev?: boolean;\n}\n\n/**\n * The tool registry a canvas mounts when it is not handed a whole `ToolsApi`.\n *\n * Built-ins come first, in `BUILTIN_TOOL_IDS` order whatever order they were\n * asked for in, then the presets' own tools in preset order; a patch tool\n * replaces a mounted one where it stands, and any other is appended in patch\n * order. A palette keeps that order for tools its own order does not name.\n * Replacing a tool that is mounted only because a preset implies it is the\n * documented way to restyle it, so only a patch tool for an id `defaultTools`\n * also names is warned about.\n */\nexport function resolveToolRegistry(args: ResolveToolRegistryArgs): Record<string, Tool> {\n const { builtins, enabled, patch, dev = isDev() } = args;\n const defaultTools = toolIdsOf(args.defaultTools ?? []);\n const registry: Record<string, Tool> = {};\n const preset = presetBuiltinTools(enabled);\n for (const id of BUILTIN_TOOL_IDS) {\n const patched = patch?.[id];\n if (patched === false) continue;\n const asked = patched === true || defaultTools.includes(id) || preset.has(id);\n if (asked) registry[id] = builtins[id];\n }\n for (const [id, tool] of Object.entries(presetOwnTools(enabled))) {\n if (patch?.[id] !== false) registry[id] = tool;\n }\n for (const [id, value] of Object.entries(patch ?? {})) {\n if (value === false) continue;\n if (value === true) {\n if (dev && !(BUILTIN_TOOL_IDS as readonly string[]).includes(id)) {\n console.warn(`[SceneCanvas] tools.${id}=true is not a known built-in id; ignoring`);\n }\n continue;\n }\n if (dev && id in registry && (defaultTools as string[]).includes(id)) {\n console.warn(`[SceneCanvas] tools prop overrides bundled \"${id}\" tool`);\n }\n registry[id] = value;\n }\n return registry;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAmCA,SAAgB,oBAAoB,MAAqD;CACvF,MAAM,EAAE,UAAU,SAAS,OAAO,MAAM,MAAM,MAAM;CACpD,MAAM,eAAe,UAAU,KAAK,gBAAgB,CAAC,CAAC;CACtD,MAAM,WAAiC,CAAC;CACxC,MAAM,SAAS,mBAAmB,OAAO;CACzC,KAAK,MAAM,MAAM,kBAAkB;EACjC,MAAM,UAAU,QAAQ;EACxB,IAAI,YAAY,OAAO;EAEvB,IADc,YAAY,QAAQ,aAAa,SAAS,EAAE,KAAK,OAAO,IAAI,EAAE,GACjE,SAAS,MAAM,SAAS;CACrC;CACA,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,QAAQ,eAAe,OAAO,CAAC,GAC7D,IAAI,QAAQ,QAAQ,OAAO,SAAS,MAAM;CAE5C,KAAK,MAAM,CAAC,IAAI,UAAU,OAAO,QAAQ,SAAS,CAAC,CAAC,GAAG;EACrD,IAAI,UAAU,OAAO;EACrB,IAAI,UAAU,MAAM;GAClB,IAAI,OAAO,CAAE,iBAAuC,SAAS,EAAE,GAC7D,QAAQ,KAAK,uBAAuB,GAAG,2CAA2C;GAEpF;EACF;EACA,IAAI,OAAO,MAAM,YAAa,aAA0B,SAAS,EAAE,GACjE,QAAQ,KAAK,+CAA+C,GAAG,OAAO;EAExE,SAAS,MAAM;CACjB;CACA,OAAO;AACT"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createViewMarkerContribution } from "../../
|
|
2
|
-
import { createLongPressFeedbackContribution } from "../../
|
|
1
|
+
import { createViewMarkerContribution } from "../../domains/viewports/viewMarkerDrag.js";
|
|
2
|
+
import { createLongPressFeedbackContribution } from "../../domains/longPress/longPressFeedback.js";
|
|
3
3
|
import { useTools } from "../../tools/overlayBinding.js";
|
|
4
4
|
import { presetActions, presetAmbient, presetContributions, resolveFeatures } from "./features.js";
|
|
5
5
|
import { useBuiltinTools } from "./useBuiltinTools.js";
|
|
@@ -76,6 +76,16 @@ function useCanvasTools(args) {
|
|
|
76
76
|
...modes ? { modes } : {}
|
|
77
77
|
});
|
|
78
78
|
const tools = takeover ?? internal;
|
|
79
|
+
const takeoverAmbient = takeover?.ambient;
|
|
80
|
+
const surface = useMemo(() => {
|
|
81
|
+
if (!takeoverAmbient) return [];
|
|
82
|
+
const missing = (e) => e !== null && !takeoverAmbient.some((t) => t.id === e.id);
|
|
83
|
+
return [markerDrag, pressFeedback].filter(missing);
|
|
84
|
+
}, [
|
|
85
|
+
takeoverAmbient,
|
|
86
|
+
markerDrag,
|
|
87
|
+
pressFeedback
|
|
88
|
+
]);
|
|
79
89
|
const onToolsCreatedRef = useLatest(onToolsCreated);
|
|
80
90
|
useEffect(() => {
|
|
81
91
|
onToolsCreatedRef.current?.(tools);
|
|
@@ -83,31 +93,35 @@ function useCanvasTools(args) {
|
|
|
83
93
|
return {
|
|
84
94
|
tools,
|
|
85
95
|
internal,
|
|
86
|
-
takeover
|
|
96
|
+
takeover,
|
|
97
|
+
surface
|
|
87
98
|
};
|
|
88
99
|
}
|
|
89
100
|
/**
|
|
90
101
|
* The presets' ambient bindings, and the standard actions the canvas
|
|
91
102
|
* registers. The bindings are not tools and sit outside `tools`, so they apply
|
|
92
|
-
* under a takeover too. An action is registered when an enabled preset brings
|
|
103
|
+
* under a takeover too. An action is registered when it is in `baseline`, when an enabled preset brings
|
|
93
104
|
* it, or when it is in `pool` and a tool or contribution on this canvas binds
|
|
94
105
|
* it: a tool brings the actions it routes to, so `defaultTools={['rect']}`
|
|
95
106
|
* works under any preset.
|
|
96
107
|
*/
|
|
97
108
|
function useFeatureBindings(args) {
|
|
98
|
-
const { enabled, pool, tools, move, rotate } = args;
|
|
99
|
-
const contributions = useMemo(() => presetAmbient(enabled, {
|
|
109
|
+
const { enabled, pool, baseline, tools, move, rotate, surface } = args;
|
|
110
|
+
const contributions = useMemo(() => [...presetAmbient(enabled, {
|
|
100
111
|
move,
|
|
101
112
|
rotate
|
|
102
|
-
}), [
|
|
113
|
+
}), ...surface ?? []], [
|
|
103
114
|
enabled,
|
|
104
115
|
move,
|
|
105
|
-
rotate
|
|
116
|
+
rotate,
|
|
117
|
+
surface
|
|
106
118
|
]);
|
|
107
119
|
return {
|
|
108
120
|
contributions,
|
|
109
121
|
standardActions: useMemo(() => {
|
|
110
|
-
const
|
|
122
|
+
const own = [...presetActions(enabled), ...(surface ?? []).flatMap((e) => e.actions ?? [])];
|
|
123
|
+
const ownIds = new Set(own.map((a) => a.id));
|
|
124
|
+
const out = [...(baseline ?? []).filter((a) => !ownIds.has(a.id)), ...own];
|
|
111
125
|
const have = new Set(out.map((a) => a.id));
|
|
112
126
|
const bound = /* @__PURE__ */ new Set();
|
|
113
127
|
for (const entry of [
|
|
@@ -123,8 +137,10 @@ function useFeatureBindings(args) {
|
|
|
123
137
|
}, [
|
|
124
138
|
enabled,
|
|
125
139
|
pool,
|
|
140
|
+
baseline,
|
|
126
141
|
tools,
|
|
127
|
-
contributions
|
|
142
|
+
contributions,
|
|
143
|
+
surface
|
|
128
144
|
])
|
|
129
145
|
};
|
|
130
146
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCanvasTools.js","names":[],"sources":["../../../src/canvas/SceneCanvas/useCanvasTools.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { Action } from '@weasel-js/routing';\nimport { createLongPressFeedbackContribution } from '../../features/longPress/longPressFeedback';\nimport { createViewMarkerContribution } from '../../features/viewports/viewMarkerDrag';\nimport { useTools, type Contribution, type Tool, type ToolsApi } from '../../tools/overlayBinding';\nimport {\n presetActions,\n presetAmbient,\n presetContributions,\n resolveFeatures,\n type EnabledPresets,\n type FeatureBindingOptions,\n type FeatureEntry,\n type NamedPresets,\n} from './features';\nimport type { SceneCanvasProps } from './props';\nimport type { ToolsPatch } from './toolRegistry';\nimport { useBuiltinTools } from './useBuiltinTools';\n\ntype Props = SceneCanvasProps<unknown, string, unknown>;\n\n/** Discriminate the polymorphic `tools` prop: `ToolsApi` has `setActive`\n * / `active` / `registry`; the patch record shape has none of those. */\nfunction isToolsApi(tools: ToolsApi | ToolsPatch): tools is ToolsApi {\n return typeof (tools as ToolsApi).setActive === 'function';\n}\n\nconst presetSerials = new WeakMap<object, number>();\nlet nextSerial = 0;\nconst entryKey = (e: FeatureEntry): string => {\n if (typeof e === 'string') return e;\n let n = presetSerials.get(e);\n if (n === undefined) presetSerials.set(e, (n = nextSerial++));\n return `#${n}`;\n};\n\n/** The presets a canvas runs with. Keyed on the entries, not the array, so\n * an inline `features={['draw', pathTools]}` does not re-derive every render. */\nexport function useEnabledFeatures(\n features: readonly FeatureEntry[] | undefined,\n named: NamedPresets | null,\n hasViewport: boolean,\n selectRotates: boolean,\n): EnabledPresets {\n const featuresKey = (features ?? []).map(entryKey).join('|');\n return useMemo(\n () => resolveFeatures(features, named, { viewport: hasViewport, selectRotates }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [featuresKey, named, hasViewport, selectRotates],\n );\n}\n\n/**\n * The canvas's tools: a caller's own `ToolsApi` when the `tools` prop is one\n * (the takeover form), and otherwise the built-ins the presets and\n * `defaultTools` name, patched by a `tools` record.\n */\nexport function useCanvasTools(args: {\n /** The canvas's select tool, which is built from its scene and pickers. */\n select: Tool;\n /** The canvas's group entry and leave, or null where the select preset is off. */\n groupEntry: Contribution | null;\n enabled: EnabledPresets;\n tools: Props['tools'];\n defaultTools: Props['defaultTools'];\n toolOptions: Props['toolOptions'];\n /** `viewport.inertia`, which is the hand tool's. */\n inertia: NonNullable<Props['viewport']>['inertia'];\n ambient: Props['ambient'];\n /** `null` leaves out the kit's default actions, the marker drag among them. */\n actions: Props['actions'];\n /** `longPress.feedback`. Default true, which installs the kit's own. */\n pressFeedback: NonNullable<Props['longPress']>['feedback'];\n initialActiveTool: Props['initialActiveTool'];\n modes: Props['modes'];\n onToolsCreated: Props['onToolsCreated'];\n}): {\n /** What the canvas routes input through: the takeover, or `internal`. */\n tools: ToolsApi;\n /** The canvas's own api, built whether or not a takeover replaces it. */\n internal: ToolsApi;\n takeover: ToolsApi | null;\n} {\n const { select, enabled, tools: toolsProp, defaultTools, toolOptions, inertia, ambient, initialActiveTool, modes, onToolsCreated } = args;\n\n const takeover = toolsProp && isToolsApi(toolsProp) ? toolsProp : null;\n const registry = useBuiltinTools({\n select,\n enabled,\n defaultTools,\n patch: toolsProp && !isToolsApi(toolsProp) ? toolsProp : null,\n toolOptions,\n inertia,\n });\n\n const defaultPressFeedback = useMemo(() => createLongPressFeedbackContribution(), []);\n const feedbackOpt = args.pressFeedback ?? true;\n const pressFeedback = feedbackOpt === true ? defaultPressFeedback : feedbackOpt || null;\n const defaultMarkerDrag = useMemo(() => createViewMarkerContribution(), []);\n const markerDrag = args.actions === null ? null : defaultMarkerDrag;\n const groupEntry = args.actions === null ? null : args.groupEntry;\n const mergedAmbient = useMemo(\n () => [\n ...presetContributions(enabled), ...(groupEntry ? [groupEntry] : []), ...(ambient ?? []),\n ...(pressFeedback ? [pressFeedback] : []), ...(markerDrag ? [markerDrag] : []),\n ],\n [enabled, groupEntry, ambient, pressFeedback, markerDrag],\n );\n\n const internal = useTools({\n active: initialActiveTool ?? ('select' in registry ? 'select' : null),\n registry,\n ...(mergedAmbient.length ? { ambient: mergedAmbient } : {}),\n ...(modes ? { modes } : {}),\n });\n const tools = takeover ?? internal;\n\n const onToolsCreatedRef = useLatest(onToolsCreated);\n useEffect(() => { onToolsCreatedRef.current?.(tools); }, [tools, onToolsCreatedRef]);\n\n return { tools, internal, takeover };\n}\n\n/**\n * The presets' ambient bindings, and the standard actions the canvas\n * registers. The bindings are not tools and sit outside `tools`, so they apply\n * under a takeover too. An action is registered when an enabled preset brings\n * it, or when it is in `pool` and a tool or contribution on this canvas binds\n * it: a tool brings the actions it routes to, so `defaultTools={['rect']}`\n * works under any preset.\n */\nexport function useFeatureBindings(args: {\n enabled: EnabledPresets;\n /** Actions registered only when something binds them. */\n pool: readonly Action[];\n tools: Pick<ToolsApi, 'registry' | 'ambient'>;\n move: FeatureBindingOptions['move'];\n rotate: FeatureBindingOptions['rotate'];\n}): { contributions: Contribution[]; standardActions: Action[] } {\n const { enabled, pool, tools, move, rotate } = args;\n const contributions = useMemo<Contribution[]>(\n () => presetAmbient(enabled, { move, rotate }),\n [enabled, move, rotate],\n );\n const standardActions = useMemo(() => {\n const out = presetActions(enabled);\n const have = new Set(out.map((a) => a.id));\n const bound = new Set<string>();\n for (const entry of [...Object.values(tools.registry), ...tools.ambient, ...contributions]) {\n for (const b of entry.bindings ?? []) bound.add(b.actionId);\n }\n for (const a of pool) {\n if (bound.has(a.id) && !have.has(a.id)) {\n have.add(a.id);\n out.push(a);\n }\n }\n return out;\n }, [enabled, pool, tools, contributions]);\n return { contributions, standardActions };\n}\n\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useCanvasTools.js","names":[],"sources":["../../../src/canvas/SceneCanvas/useCanvasTools.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { Action } from '@weasel-js/routing';\nimport { createLongPressFeedbackContribution } from '../../domains/longPress/longPressFeedback';\nimport { createViewMarkerContribution } from '../../domains/viewports/viewMarkerDrag';\nimport { useTools, type Contribution, type Tool, type ToolsApi } from '../../tools/overlayBinding';\nimport type { SurfaceContribution } from '../surfaceContribution';\nimport {\n presetActions,\n presetAmbient,\n presetContributions,\n resolveFeatures,\n type EnabledPresets,\n type FeatureBindingOptions,\n type FeatureEntry,\n type NamedPresets,\n} from './features';\nimport type { SceneCanvasProps } from './props';\nimport type { ToolsPatch } from './toolRegistry';\nimport { useBuiltinTools } from './useBuiltinTools';\n\ntype Props = SceneCanvasProps<unknown, string, unknown>;\n\n/** Discriminate the polymorphic `tools` prop: `ToolsApi` has `setActive`\n * / `active` / `registry`; the patch record shape has none of those. */\nfunction isToolsApi(tools: ToolsApi | ToolsPatch): tools is ToolsApi {\n return typeof (tools as ToolsApi).setActive === 'function';\n}\n\nconst presetSerials = new WeakMap<object, number>();\nlet nextSerial = 0;\nconst entryKey = (e: FeatureEntry): string => {\n if (typeof e === 'string') return e;\n let n = presetSerials.get(e);\n if (n === undefined) presetSerials.set(e, (n = nextSerial++));\n return `#${n}`;\n};\n\n/** The presets a canvas runs with. Keyed on the entries, not the array, so\n * an inline `features={['draw', pathTools]}` does not re-derive every render. */\nexport function useEnabledFeatures(\n features: readonly FeatureEntry[] | undefined,\n named: NamedPresets | null,\n hasViewport: boolean,\n selectRotates: boolean,\n): EnabledPresets {\n const featuresKey = (features ?? []).map(entryKey).join('|');\n return useMemo(\n () => resolveFeatures(features, named, { viewport: hasViewport, selectRotates }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [featuresKey, named, hasViewport, selectRotates],\n );\n}\n\n/**\n * The canvas's tools: a caller's own `ToolsApi` when the `tools` prop is one\n * (the takeover form), and otherwise the built-ins the presets and\n * `defaultTools` name, patched by a `tools` record.\n */\nexport function useCanvasTools(args: {\n /** The canvas's select tool, which is built from its scene and pickers. */\n select: Tool;\n /** The canvas's group entry and leave, or null where the select preset is off. */\n groupEntry: Contribution | null;\n enabled: EnabledPresets;\n tools: Props['tools'];\n defaultTools: Props['defaultTools'];\n toolOptions: Props['toolOptions'];\n /** `viewport.inertia`, which is the hand tool's. */\n inertia: NonNullable<Props['viewport']>['inertia'];\n ambient: Props['ambient'];\n /** `null` leaves out the kit's default actions, the marker drag among them. */\n actions: Props['actions'];\n /** `longPress.feedback`. Default true, which installs the kit's own. */\n pressFeedback: NonNullable<Props['longPress']>['feedback'];\n initialActiveTool: Props['initialActiveTool'];\n modes: Props['modes'];\n onToolsCreated: Props['onToolsCreated'];\n}): {\n /** What the canvas routes input through: the takeover, or `internal`. */\n tools: ToolsApi;\n /** The canvas's own api, built whether or not a takeover replaces it. */\n internal: ToolsApi;\n takeover: ToolsApi | null;\n /** The surface's own always-on entries a takeover's ambient leaves out: they apply under it too. */\n surface: readonly SurfaceContribution[];\n} {\n const { select, enabled, tools: toolsProp, defaultTools, toolOptions, inertia, ambient, initialActiveTool, modes, onToolsCreated } = args;\n\n const takeover = toolsProp && isToolsApi(toolsProp) ? toolsProp : null;\n const registry = useBuiltinTools({\n select,\n enabled,\n defaultTools,\n patch: toolsProp && !isToolsApi(toolsProp) ? toolsProp : null,\n toolOptions,\n inertia,\n });\n\n const defaultPressFeedback = useMemo(() => createLongPressFeedbackContribution(), []);\n const feedbackOpt = args.pressFeedback ?? true;\n const pressFeedback = feedbackOpt === true ? defaultPressFeedback : feedbackOpt || null;\n const defaultMarkerDrag = useMemo(() => createViewMarkerContribution(), []);\n const markerDrag = args.actions === null ? null : defaultMarkerDrag;\n const groupEntry = args.actions === null ? null : args.groupEntry;\n const mergedAmbient = useMemo(\n () => [\n ...presetContributions(enabled), ...(groupEntry ? [groupEntry] : []), ...(ambient ?? []),\n ...(pressFeedback ? [pressFeedback] : []), ...(markerDrag ? [markerDrag] : []),\n ],\n [enabled, groupEntry, ambient, pressFeedback, markerDrag],\n );\n\n const internal = useTools({\n active: initialActiveTool ?? ('select' in registry ? 'select' : null),\n registry,\n ...(mergedAmbient.length ? { ambient: mergedAmbient } : {}),\n ...(modes ? { modes } : {}),\n });\n const tools = takeover ?? internal;\n const takeoverAmbient = takeover?.ambient;\n const surface = useMemo(() => {\n if (!takeoverAmbient) return [];\n const missing = (e: SurfaceContribution | null): e is SurfaceContribution =>\n e !== null && !takeoverAmbient.some((t) => t.id === e.id);\n return [markerDrag, pressFeedback].filter(missing);\n }, [takeoverAmbient, markerDrag, pressFeedback]);\n\n const onToolsCreatedRef = useLatest(onToolsCreated);\n useEffect(() => { onToolsCreatedRef.current?.(tools); }, [tools, onToolsCreatedRef]);\n\n return { tools, internal, takeover, surface };\n}\n\n/**\n * The presets' ambient bindings, and the standard actions the canvas\n * registers. The bindings are not tools and sit outside `tools`, so they apply\n * under a takeover too. An action is registered when it is in `baseline`, when an enabled preset brings\n * it, or when it is in `pool` and a tool or contribution on this canvas binds\n * it: a tool brings the actions it routes to, so `defaultTools={['rect']}`\n * works under any preset.\n */\nexport function useFeatureBindings(args: {\n enabled: EnabledPresets;\n /** Actions registered only when something binds them. */\n pool: readonly Action[];\n /** Actions registered whatever is on. */\n baseline?: readonly Action[];\n tools: Pick<ToolsApi, 'registry' | 'ambient'>;\n move: FeatureBindingOptions['move'];\n rotate: FeatureBindingOptions['rotate'];\n /** Entries the surface installs beside a takeover, with the actions they bring. */\n surface?: readonly SurfaceContribution[];\n}): { contributions: Contribution[]; standardActions: Action[] } {\n const { enabled, pool, baseline, tools, move, rotate, surface } = args;\n const contributions = useMemo<Contribution[]>(\n () => [...presetAmbient(enabled, { move, rotate }), ...(surface ?? [])],\n [enabled, move, rotate, surface],\n );\n const standardActions = useMemo(() => {\n const own = [...presetActions(enabled), ...(surface ?? []).flatMap((e) => e.actions ?? [])];\n const ownIds = new Set(own.map((a) => a.id));\n const out = [...(baseline ?? []).filter((a) => !ownIds.has(a.id)), ...own];\n const have = new Set(out.map((a) => a.id));\n const bound = new Set<string>();\n for (const entry of [...Object.values(tools.registry), ...tools.ambient, ...contributions]) {\n for (const b of entry.bindings ?? []) bound.add(b.actionId);\n }\n for (const a of pool) {\n if (bound.has(a.id) && !have.has(a.id)) {\n have.add(a.id);\n out.push(a);\n }\n }\n return out;\n }, [enabled, pool, baseline, tools, contributions, surface]);\n return { contributions, standardActions };\n}\n\n"],"mappings":"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"}
|
|
@@ -67,7 +67,15 @@ function useKeyedInstall(items) {
|
|
|
67
67
|
live.current.clear();
|
|
68
68
|
}, []);
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
var NO_SURFACE = [];
|
|
71
|
+
/**
|
|
72
|
+
* `surface` is the canvas's own entries installed beside a takeover, which the
|
|
73
|
+
* takeover's `ToolsApi` does not hold: their deps, `watch`, `attach`, frame
|
|
74
|
+
* hooks and overlay install here, the overlay as a registered layer since no
|
|
75
|
+
* tool set lists it. Their actions are the canvas's standard actions, so they
|
|
76
|
+
* are not registered again.
|
|
77
|
+
*/
|
|
78
|
+
function useContributionRoles(tools, api, versionCheck = "warn", surface = NO_SURFACE) {
|
|
71
79
|
const registry = useActionsRegistry();
|
|
72
80
|
const depRegistry = useOptionalDepRegistry();
|
|
73
81
|
const { registry: toolRegistry, ambient } = tools;
|
|
@@ -100,7 +108,7 @@ function useContributionRoles(tools, api, versionCheck = "warn") {
|
|
|
100
108
|
toolRegistry,
|
|
101
109
|
ambient
|
|
102
110
|
]);
|
|
103
|
-
const entries = contributionEntries(tools);
|
|
111
|
+
const entries = [...contributionEntries(tools), ...surface];
|
|
104
112
|
if (versionCheck === "strict" || versionCheck === "warn" && isDev()) checkEntryRequirements(entries, versionCheck);
|
|
105
113
|
const reader = depRegistry ?? NO_DEPS;
|
|
106
114
|
const installs = /* @__PURE__ */ new Map();
|
|
@@ -112,6 +120,11 @@ function useContributionRoles(tools, api, versionCheck = "warn") {
|
|
|
112
120
|
const attach = entry.attach;
|
|
113
121
|
if (attach && api) installs.set(attach, () => attach(api, reader));
|
|
114
122
|
}
|
|
123
|
+
for (const entry of surface) {
|
|
124
|
+
const overlay = entry.overlay;
|
|
125
|
+
if (!overlay || !api) continue;
|
|
126
|
+
for (const layer of Array.isArray(overlay) ? overlay : [overlay]) installs.set(layer, () => api.registerLayer(layer));
|
|
127
|
+
}
|
|
115
128
|
useKeyedInstall(installs);
|
|
116
129
|
useContributionFrameHooks(entries, api, reader);
|
|
117
130
|
useOffhandAction(contributionEntries(tools));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useContributionRoles.js","names":[],"sources":["../../../src/canvas/SceneCanvas/useContributionRoles.ts"],"sourcesContent":["/**\n * `useContributionRoles` — installs the roles of every entry in the tools\n * registry that a surface owns rather than the dispatcher: its actions into the\n * `<ActionsProvider>`, its deps into the dep registry, and its `attach` against\n * the mounted canvas. Views are the fourth such role; `<SceneCanvas>` renders\n * those itself, because a view is a component.\n *\n * Tool hooks run wherever the consumer calls them, which may be outside any\n * registry. Declaring roles on the entry and installing them from in here keeps\n * the tool hook callable from anywhere.\n */\nimport { useEffect, useRef } from 'react';\nimport { useActionsRegistry, useMenuHost, useOffhandAction, useOptionalDepRegistry } from '@weasel-js/routing/react';\nimport type { DepRegistry } from '@weasel-js/routing/react';\nimport type { DepName } from 'interactions/actions/depSchema';\nimport type { ToolsApi } from '../../tools/overlayBinding';\nimport type { CanvasExtensionApi } from '../canvasExtension';\nimport type { SurfaceContribution } from '../surfaceContribution';\nimport { checkRequirements, type RequirementMismatch } from '../kitRequirements';\nimport { useContributionFrameHooks } from './contributionFrameHooks';\nimport { isDev } from '@weasel-js/react';\n\n/** How a surface treats an entry whose `requires` the running kit does not\n * meet: warn in development (the default), throw, or not check. */\nexport type VersionCheck = 'warn' | 'strict' | 'off';\n\nconst NO_DEPS = { get: () => undefined };\nconst warnedRequirements = new WeakSet<object>();\n\nfunction describeMismatch(m: RequirementMismatch): string {\n switch (m.reason) {\n case 'unsatisfied': return `${m.package} ${m.range} (running ${m.running})`;\n case 'invalid-range': return `${m.package} \"${m.range}\", which is not a range this check reads`;\n case 'unknown-package': return `${m.package} ${m.range}, but ${m.package} reports no version`;\n }\n}\n\nfunction checkEntryRequirements(entries: readonly SurfaceContribution[], mode: VersionCheck): void {\n if (mode === 'off') return;\n for (const entry of entries) {\n const requires = entry.requires;\n if (!requires) continue;\n if (mode === 'warn' && warnedRequirements.has(requires)) continue;\n const mismatches = checkRequirements(requires);\n if (mismatches.length === 0) continue;\n const message = `[weasel] contribution \"${entry.id}\" requires ${mismatches.map(describeMismatch).join('; ')}.`;\n if (mode === 'strict') throw new Error(message);\n warnedRequirements.add(requires);\n console.warn(message);\n }\n}\n\n/** Every entry the registry holds, registry and ambient alike. */\nexport function contributionEntries(tools: Pick<ToolsApi, 'registry' | 'ambient'>): SurfaceContribution[] {\n return [...Object.values(tools.registry), ...tools.ambient] as SurfaceContribution[];\n}\n\n/**\n * Keep one installation per key alive: install keys that appeared, tear down\n * keys that went. Keys are role objects the consumer owns, so an entry the\n * host re-wraps every render — `useTools` restates eligibility on a copy —\n * still installs once.\n */\nfunction useKeyedInstall(\n items: ReadonlyMap<object, () => () => void>,\n): void {\n const live = useRef(new Map<object, () => void>());\n useEffect(() => {\n for (const [key, teardown] of live.current) {\n if (items.has(key)) continue;\n teardown();\n live.current.delete(key);\n }\n for (const [key, install] of items) {\n if (live.current.has(key)) continue;\n live.current.set(key, install());\n }\n });\n useEffect(() => () => {\n for (const teardown of live.current.values()) teardown();\n live.current.clear();\n }, []);\n}\n\nexport function useContributionRoles(\n tools: ToolsApi,\n api: CanvasExtensionApi | null,\n versionCheck: VersionCheck = 'warn',\n): void {\n const registry = useActionsRegistry();\n const depRegistry = useOptionalDepRegistry();\n const { registry: toolRegistry, ambient } = tools;\n\n useEffect(() => {\n if (!registry) return;\n const unregisters: Array<() => void> = [];\n // Ambient entries included: an always-on entry owns actions its own\n // bindings reference exactly as a registry tool does, and leaving them out\n // gives the same silent failure this hook exists to prevent — a binding\n // pointing at an id nothing registered.\n for (const entry of contributionEntries({ registry: toolRegistry, ambient })) {\n for (const action of entry.actions ?? []) {\n unregisters.push(registry.register(action));\n }\n }\n return () => { for (const u of unregisters) u(); };\n }, [registry, toolRegistry, ambient]);\n\n const menuHost = useMenuHost();\n useEffect(() => {\n if (!menuHost) return;\n const releases: Array<() => void> = [];\n for (const [id, entry] of Object.entries(toolRegistry)) {\n for (const def of (entry as SurfaceContribution).menus ?? []) releases.push(menuHost.define(def, id));\n }\n for (const entry of ambient) {\n for (const def of (entry as SurfaceContribution).menus ?? []) releases.push(menuHost.define(def, null));\n }\n return () => { for (const r of releases) r(); };\n }, [menuHost, toolRegistry, ambient]);\n\n const entries = contributionEntries(tools);\n // Development only for a warning; a strict surface asked to be stopped, so\n // it throws in every build.\n if (versionCheck === 'strict' || (versionCheck === 'warn' && isDev())) {\n checkEntryRequirements(entries, versionCheck);\n }\n\n const reader = depRegistry ?? NO_DEPS;\n const installs = new Map<object, () => () => void>();\n for (const entry of entries) {\n const deps = entry.deps;\n if (deps && depRegistry) installs.set(deps, () => registerDeps(depRegistry, deps));\n const watch = entry.watch;\n if (watch && depRegistry) installs.set(watch, () => watch(() => depRegistry.changed?.()));\n const attach = entry.attach;\n if (attach && api) installs.set(attach, () => attach(api, reader));\n }\n useKeyedInstall(installs);\n useContributionFrameHooks(entries, api, reader);\n\n // Tool assembly runs above the provider too, so its own registration of\n // held-key engagement finds no registry unless the consumer mounted one.\n useOffhandAction(contributionEntries(tools));\n}\n\nfunction registerDeps(\n depRegistry: DepRegistry,\n deps: NonNullable<SurfaceContribution['deps']>,\n): () => void {\n const unregisters = (Object.keys(deps) as DepName[]).map((name) =>\n depRegistry.register(name, deps[name] as never));\n return () => { for (const u of unregisters) u(); };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useContributionRoles.js","names":[],"sources":["../../../src/canvas/SceneCanvas/useContributionRoles.ts"],"sourcesContent":["/**\n * `useContributionRoles` — installs the roles of every entry in the tools\n * registry that a surface owns rather than the dispatcher: its actions into the\n * `<ActionsProvider>`, its deps into the dep registry, and its `attach` against\n * the mounted canvas. Views are the fourth such role; `<SceneCanvas>` renders\n * those itself, because a view is a component.\n *\n * Tool hooks run wherever the consumer calls them, which may be outside any\n * registry. Declaring roles on the entry and installing them from in here keeps\n * the tool hook callable from anywhere.\n */\nimport { useEffect, useRef } from 'react';\nimport { useActionsRegistry, useMenuHost, useOffhandAction, useOptionalDepRegistry } from '@weasel-js/routing/react';\nimport type { DepRegistry } from '@weasel-js/routing/react';\nimport type { DepName } from 'interactions/actions/depSchema';\nimport type { ToolsApi } from '../../tools/overlayBinding';\nimport type { CanvasExtensionApi } from '../canvasExtension';\nimport type { SurfaceContribution } from '../surfaceContribution';\nimport { checkRequirements, type RequirementMismatch } from '../kitRequirements';\nimport { useContributionFrameHooks } from './contributionFrameHooks';\nimport { isDev } from '@weasel-js/react';\n\n/** How a surface treats an entry whose `requires` the running kit does not\n * meet: warn in development (the default), throw, or not check. */\nexport type VersionCheck = 'warn' | 'strict' | 'off';\n\nconst NO_DEPS = { get: () => undefined };\nconst warnedRequirements = new WeakSet<object>();\n\nfunction describeMismatch(m: RequirementMismatch): string {\n switch (m.reason) {\n case 'unsatisfied': return `${m.package} ${m.range} (running ${m.running})`;\n case 'invalid-range': return `${m.package} \"${m.range}\", which is not a range this check reads`;\n case 'unknown-package': return `${m.package} ${m.range}, but ${m.package} reports no version`;\n }\n}\n\nfunction checkEntryRequirements(entries: readonly SurfaceContribution[], mode: VersionCheck): void {\n if (mode === 'off') return;\n for (const entry of entries) {\n const requires = entry.requires;\n if (!requires) continue;\n if (mode === 'warn' && warnedRequirements.has(requires)) continue;\n const mismatches = checkRequirements(requires);\n if (mismatches.length === 0) continue;\n const message = `[weasel] contribution \"${entry.id}\" requires ${mismatches.map(describeMismatch).join('; ')}.`;\n if (mode === 'strict') throw new Error(message);\n warnedRequirements.add(requires);\n console.warn(message);\n }\n}\n\n/** Every entry the registry holds, registry and ambient alike. */\nexport function contributionEntries(tools: Pick<ToolsApi, 'registry' | 'ambient'>): SurfaceContribution[] {\n return [...Object.values(tools.registry), ...tools.ambient] as SurfaceContribution[];\n}\n\n/**\n * Keep one installation per key alive: install keys that appeared, tear down\n * keys that went. Keys are role objects the consumer owns, so an entry the\n * host re-wraps every render — `useTools` restates eligibility on a copy —\n * still installs once.\n */\nfunction useKeyedInstall(\n items: ReadonlyMap<object, () => () => void>,\n): void {\n const live = useRef(new Map<object, () => void>());\n useEffect(() => {\n for (const [key, teardown] of live.current) {\n if (items.has(key)) continue;\n teardown();\n live.current.delete(key);\n }\n for (const [key, install] of items) {\n if (live.current.has(key)) continue;\n live.current.set(key, install());\n }\n });\n useEffect(() => () => {\n for (const teardown of live.current.values()) teardown();\n live.current.clear();\n }, []);\n}\n\nconst NO_SURFACE: readonly SurfaceContribution[] = [];\n\n/**\n * `surface` is the canvas's own entries installed beside a takeover, which the\n * takeover's `ToolsApi` does not hold: their deps, `watch`, `attach`, frame\n * hooks and overlay install here, the overlay as a registered layer since no\n * tool set lists it. Their actions are the canvas's standard actions, so they\n * are not registered again.\n */\nexport function useContributionRoles(\n tools: ToolsApi,\n api: CanvasExtensionApi | null,\n versionCheck: VersionCheck = 'warn',\n surface: readonly SurfaceContribution[] = NO_SURFACE,\n): void {\n const registry = useActionsRegistry();\n const depRegistry = useOptionalDepRegistry();\n const { registry: toolRegistry, ambient } = tools;\n\n useEffect(() => {\n if (!registry) return;\n const unregisters: Array<() => void> = [];\n // Ambient entries included: an always-on entry owns actions its own\n // bindings reference exactly as a registry tool does, and leaving them out\n // gives the same silent failure this hook exists to prevent — a binding\n // pointing at an id nothing registered.\n for (const entry of contributionEntries({ registry: toolRegistry, ambient })) {\n for (const action of entry.actions ?? []) {\n unregisters.push(registry.register(action));\n }\n }\n return () => { for (const u of unregisters) u(); };\n }, [registry, toolRegistry, ambient]);\n\n const menuHost = useMenuHost();\n useEffect(() => {\n if (!menuHost) return;\n const releases: Array<() => void> = [];\n for (const [id, entry] of Object.entries(toolRegistry)) {\n for (const def of (entry as SurfaceContribution).menus ?? []) releases.push(menuHost.define(def, id));\n }\n for (const entry of ambient) {\n for (const def of (entry as SurfaceContribution).menus ?? []) releases.push(menuHost.define(def, null));\n }\n return () => { for (const r of releases) r(); };\n }, [menuHost, toolRegistry, ambient]);\n\n const entries = [...contributionEntries(tools), ...surface];\n // Development only for a warning; a strict surface asked to be stopped, so\n // it throws in every build.\n if (versionCheck === 'strict' || (versionCheck === 'warn' && isDev())) {\n checkEntryRequirements(entries, versionCheck);\n }\n\n const reader = depRegistry ?? NO_DEPS;\n const installs = new Map<object, () => () => void>();\n for (const entry of entries) {\n const deps = entry.deps;\n if (deps && depRegistry) installs.set(deps, () => registerDeps(depRegistry, deps));\n const watch = entry.watch;\n if (watch && depRegistry) installs.set(watch, () => watch(() => depRegistry.changed?.()));\n const attach = entry.attach;\n if (attach && api) installs.set(attach, () => attach(api, reader));\n }\n for (const entry of surface) {\n const overlay = entry.overlay;\n if (!overlay || !api) continue;\n for (const layer of Array.isArray(overlay) ? overlay : [overlay]) installs.set(layer, () => api.registerLayer(layer));\n }\n useKeyedInstall(installs);\n useContributionFrameHooks(entries, api, reader);\n\n // Tool assembly runs above the provider too, so its own registration of\n // held-key engagement finds no registry unless the consumer mounted one.\n useOffhandAction(contributionEntries(tools));\n}\n\nfunction registerDeps(\n depRegistry: DepRegistry,\n deps: NonNullable<SurfaceContribution['deps']>,\n): () => void {\n const unregisters = (Object.keys(deps) as DepName[]).map((name) =>\n depRegistry.register(name, deps[name] as never));\n return () => { for (const u of unregisters) u(); };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0BA,IAAM,UAAU,EAAE,WAAW,OAAU;AACvC,IAAM,qCAAqB,IAAI,QAAgB;AAE/C,SAAS,iBAAiB,GAAgC;CACxD,QAAQ,EAAE,QAAV;EACE,KAAK,eAAe,OAAO,GAAG,EAAE,QAAQ,GAAG,EAAE,MAAM,YAAY,EAAE,QAAQ;EACzE,KAAK,iBAAiB,OAAO,GAAG,EAAE,QAAQ,IAAI,EAAE,MAAM;EACtD,KAAK,mBAAmB,OAAO,GAAG,EAAE,QAAQ,GAAG,EAAE,MAAM,QAAQ,EAAE,QAAQ;CAC3E;AACF;AAEA,SAAS,uBAAuB,SAAyC,MAA0B;CACjG,IAAI,SAAS,OAAO;CACpB,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,WAAW,MAAM;EACvB,IAAI,CAAC,UAAU;EACf,IAAI,SAAS,UAAU,mBAAmB,IAAI,QAAQ,GAAG;EACzD,MAAM,aAAa,kBAAkB,QAAQ;EAC7C,IAAI,WAAW,WAAW,GAAG;EAC7B,MAAM,UAAU,0BAA0B,MAAM,GAAG,aAAa,WAAW,IAAI,gBAAgB,CAAC,CAAC,KAAK,IAAI,EAAE;EAC5G,IAAI,SAAS,UAAU,MAAM,IAAI,MAAM,OAAO;EAC9C,mBAAmB,IAAI,QAAQ;EAC/B,QAAQ,KAAK,OAAO;CACtB;AACF;;AAGA,SAAgB,oBAAoB,OAAsE;CACxG,OAAO,CAAC,GAAG,OAAO,OAAO,MAAM,QAAQ,GAAG,GAAG,MAAM,OAAO;AAC5D;;;;;;;AAQA,SAAS,gBACP,OACM;CACN,MAAM,OAAO,uBAAO,IAAI,IAAwB,CAAC;CACjD,gBAAgB;EACd,KAAK,MAAM,CAAC,KAAK,aAAa,KAAK,SAAS;GAC1C,IAAI,MAAM,IAAI,GAAG,GAAG;GACpB,SAAS;GACT,KAAK,QAAQ,OAAO,GAAG;EACzB;EACA,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO;GAClC,IAAI,KAAK,QAAQ,IAAI,GAAG,GAAG;GAC3B,KAAK,QAAQ,IAAI,KAAK,QAAQ,CAAC;EACjC;CACF,CAAC;CACD,sBAAsB;EACpB,KAAK,MAAM,YAAY,KAAK,QAAQ,OAAO,GAAG,SAAS;EACvD,KAAK,QAAQ,MAAM;CACrB,GAAG,CAAC,CAAC;AACP;AAEA,IAAM,aAA6C,CAAC;;;;;;;;AASpD,SAAgB,qBACd,OACA,KACA,eAA6B,QAC7B,UAA0C,YACpC;CACN,MAAM,WAAW,mBAAmB;CACpC,MAAM,cAAc,uBAAuB;CAC3C,MAAM,EAAE,UAAU,cAAc,YAAY;CAE5C,gBAAgB;EACd,IAAI,CAAC,UAAU;EACf,MAAM,cAAiC,CAAC;EAKxC,KAAK,MAAM,SAAS,oBAAoB;GAAE,UAAU;GAAc;EAAQ,CAAC,GACzE,KAAK,MAAM,UAAU,MAAM,WAAW,CAAC,GACrC,YAAY,KAAK,SAAS,SAAS,MAAM,CAAC;EAG9C,aAAa;GAAE,KAAK,MAAM,KAAK,aAAa,EAAE;EAAG;CACnD,GAAG;EAAC;EAAU;EAAc;CAAO,CAAC;CAEpC,MAAM,WAAW,YAAY;CAC7B,gBAAgB;EACd,IAAI,CAAC,UAAU;EACf,MAAM,WAA8B,CAAC;EACrC,KAAK,MAAM,CAAC,IAAI,UAAU,OAAO,QAAQ,YAAY,GACnD,KAAK,MAAM,OAAQ,MAA8B,SAAS,CAAC,GAAG,SAAS,KAAK,SAAS,OAAO,KAAK,EAAE,CAAC;EAEtG,KAAK,MAAM,SAAS,SAClB,KAAK,MAAM,OAAQ,MAA8B,SAAS,CAAC,GAAG,SAAS,KAAK,SAAS,OAAO,KAAK,IAAI,CAAC;EAExG,aAAa;GAAE,KAAK,MAAM,KAAK,UAAU,EAAE;EAAG;CAChD,GAAG;EAAC;EAAU;EAAc;CAAO,CAAC;CAEpC,MAAM,UAAU,CAAC,GAAG,oBAAoB,KAAK,GAAG,GAAG,OAAO;CAG1D,IAAI,iBAAiB,YAAa,iBAAiB,UAAU,MAAM,GACjE,uBAAuB,SAAS,YAAY;CAG9C,MAAM,SAAS,eAAe;CAC9B,MAAM,2BAAW,IAAI,IAA8B;CACnD,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,OAAO,MAAM;EACnB,IAAI,QAAQ,aAAa,SAAS,IAAI,YAAY,aAAa,aAAa,IAAI,CAAC;EACjF,MAAM,QAAQ,MAAM;EACpB,IAAI,SAAS,aAAa,SAAS,IAAI,aAAa,YAAY,YAAY,UAAU,CAAC,CAAC;EACxF,MAAM,SAAS,MAAM;EACrB,IAAI,UAAU,KAAK,SAAS,IAAI,cAAc,OAAO,KAAK,MAAM,CAAC;CACnE;CACA,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,UAAU,MAAM;EACtB,IAAI,CAAC,WAAW,CAAC,KAAK;EACtB,KAAK,MAAM,SAAS,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO,GAAG,SAAS,IAAI,aAAa,IAAI,cAAc,KAAK,CAAC;CACtH;CACA,gBAAgB,QAAQ;CACxB,0BAA0B,SAAS,KAAK,MAAM;CAI9C,iBAAiB,oBAAoB,KAAK,CAAC;AAC7C;AAEA,SAAS,aACP,aACA,MACY;CACZ,MAAM,cAAe,OAAO,KAAK,IAAI,CAAC,CAAe,KAAK,SACxD,YAAY,SAAS,MAAM,KAAK,KAAc,CAAC;CACjD,aAAa;EAAE,KAAK,MAAM,KAAK,aAAa,EAAE;CAAG;AACnD"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { deriveParallaxView } from "../../core/viewport/parallax.js";
|
|
2
|
-
import {
|
|
2
|
+
import { composeChildFrame, composesFrames } from "../../core/scene/composeFrame.js";
|
|
3
3
|
import { definesFrame, effectivePose } from "../../core/scene/effectivePose.js";
|
|
4
|
+
import { viewPoseAdapter } from "../../core/scene/scrollOffsets.js";
|
|
4
5
|
import { wrapWithPoseRotation } from "../poseRotation.js";
|
|
5
6
|
import { isCustomEntry } from "../layerSlots.js";
|
|
6
7
|
import { useMemo } from "react";
|
|
@@ -27,11 +28,11 @@ function useDepartureGhostLayer(args) {
|
|
|
27
28
|
const sc = sceneRef.current;
|
|
28
29
|
const { compose } = sc.composition;
|
|
29
30
|
const composes = composesFrames(sc.composition);
|
|
30
|
-
const frames = {
|
|
31
|
+
const frames = viewPoseAdapter(sc, {
|
|
31
32
|
getParent: (id) => sc.get(id)?.parent ?? null,
|
|
32
33
|
getPose: (id) => effectivePose(sc, sc.get(id)),
|
|
33
34
|
definesFrame: (id) => definesFrame(sc.get(id))
|
|
34
|
-
};
|
|
35
|
+
});
|
|
35
36
|
const viewOf = (layer) => {
|
|
36
37
|
const parallax = sc.layers.find((l) => l.id === layer)?.parallax;
|
|
37
38
|
return parallax ? deriveParallaxView(view, parallax) : view;
|
|
@@ -42,7 +43,7 @@ function useDepartureGhostLayer(args) {
|
|
|
42
43
|
};
|
|
43
44
|
return leaving.map(({ removal, pose, alpha }) => {
|
|
44
45
|
const parent = removal.parent !== null && sc.get(removal.parent) ? removal.parent : null;
|
|
45
|
-
const world = composes && parent !== null ? compose(
|
|
46
|
+
const world = composes && parent !== null ? compose(composeChildFrame(frames, parent, compose), pose) : pose;
|
|
46
47
|
const children = [];
|
|
47
48
|
draw(removal, world, children);
|
|
48
49
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDepartureGhostLayer.js","names":[],"sources":["../../../src/canvas/SceneCanvas/useDepartureGhostLayer.ts"],"sourcesContent":["/**\n * The layer `<SceneCanvas poseTransition exit>` draws removed nodes leaving\n * on: each ghost through the scene slot's `drawOne`, at the pose and opacity\n * its glide shows, inside the frame of a parent still in the scene.\n */\nimport { useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport type { RenderLayer } from 'core/layers/render';\nimport { composesFrames,
|
|
1
|
+
{"version":3,"file":"useDepartureGhostLayer.js","names":[],"sources":["../../../src/canvas/SceneCanvas/useDepartureGhostLayer.ts"],"sourcesContent":["/**\n * The layer `<SceneCanvas poseTransition exit>` draws removed nodes leaving\n * on: each ghost through the scene slot's `drawOne`, at the pose and opacity\n * its glide shows, inside the frame of a parent still in the scene.\n */\nimport { useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport type { RenderLayer } from 'core/layers/render';\nimport { composeChildFrame, composesFrames, type PoseAdapter } from 'core/scene/composePose';\nimport { viewPoseAdapter } from 'core/scene/scrollOffsets';\nimport { definesFrame, effectivePose } from 'core/scene/effectivePose';\nimport type { RemovedNode } from 'core/scene/poseWrites';\nimport type { Node, NodeId, Scene } from 'core/scene/types';\nimport { deriveParallaxView } from 'core/viewport/parallax';\nimport type { View } from 'core/viewport/view';\nimport type { Departures } from '../../animation/departures';\nimport { isCustomEntry, type LayersMap } from '../layerSlots';\nimport { wrapWithPoseRotation } from '../poseRotation';\n\nexport function useDepartureGhostLayer<TData, TLayer extends string, TPose>(args: {\n scene: Scene<TData, TLayer, TPose>;\n sceneSlot: LayersMap<Node<TData, TLayer, TPose>, TPose>['scene'];\n departures: Departures<TPose, Node<TData, TLayer, TPose>>;\n}): RenderLayer<unknown> {\n const sceneRef = useLatest(args.scene);\n const slotRef = useLatest(args.sceneSlot);\n const { departures } = args;\n\n return useMemo<RenderLayer<unknown>>(() => ({\n id: 'departure-ghost',\n label: 'Departing nodes',\n draw: (_data, view) => {\n const slot = slotRef.current;\n const leaving = departures.shown();\n if (leaving.length === 0 || !slot || isCustomEntry(slot) || !slot.drawOne) return [];\n const drawOne = slot.drawOne;\n const sc = sceneRef.current;\n const { compose } = sc.composition;\n const composes = composesFrames(sc.composition);\n const frames = viewPoseAdapter(sc, {\n getParent: (id: string) => sc.get(id as NodeId)?.parent ?? null,\n getPose: (id: string) => effectivePose(sc, sc.get(id as NodeId)!),\n definesFrame: (id: string) => definesFrame(sc.get(id as NodeId)!),\n } as PoseAdapter<TPose>);\n const viewOf = (layer: string): View => {\n const parallax = sc.layers.find((l) => l.id === layer)?.parallax;\n return parallax ? deriveParallaxView(view, parallax) : view;\n };\n const draw = (r: RemovedNode<TPose, Node<TData, TLayer, TPose>>, pose: TPose, out: DrawCommand[]): void => {\n out.push(...wrapWithPoseRotation(drawOne(r.node, pose, viewOf(r.node.layer)), pose));\n for (const c of r.children) draw(c, composes ? compose(pose, c.pose) : c.pose, out);\n };\n return leaving.map(({ removal, pose, alpha }): DrawCommand => {\n const parent = removal.parent !== null && sc.get(removal.parent) ? removal.parent : null;\n const world = composes && parent !== null ? compose(composeChildFrame(frames, parent, compose), pose) : pose;\n const children: DrawCommand[] = [];\n draw(removal, world, children);\n return { kind: 'group', alpha: Math.max(0, Math.min(1, alpha)), children };\n });\n },\n }), [departures, sceneRef, slotRef]);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,SAAgB,uBAA4D,MAInD;CACvB,MAAM,WAAW,UAAU,KAAK,KAAK;CACrC,MAAM,UAAU,UAAU,KAAK,SAAS;CACxC,MAAM,EAAE,eAAe;CAEvB,OAAO,eAAqC;EAC1C,IAAI;EACJ,OAAO;EACP,OAAO,OAAO,SAAS;GACrB,MAAM,OAAO,QAAQ;GACrB,MAAM,UAAU,WAAW,MAAM;GACjC,IAAI,QAAQ,WAAW,KAAK,CAAC,QAAQ,cAAc,IAAI,KAAK,CAAC,KAAK,SAAS,OAAO,CAAC;GACnF,MAAM,UAAU,KAAK;GACrB,MAAM,KAAK,SAAS;GACpB,MAAM,EAAE,YAAY,GAAG;GACvB,MAAM,WAAW,eAAe,GAAG,WAAW;GAC9C,MAAM,SAAS,gBAAgB,IAAI;IACjC,YAAY,OAAe,GAAG,IAAI,EAAY,CAAC,EAAE,UAAU;IAC3D,UAAU,OAAe,cAAc,IAAI,GAAG,IAAI,EAAY,CAAE;IAChE,eAAe,OAAe,aAAa,GAAG,IAAI,EAAY,CAAE;GAClE,CAAuB;GACvB,MAAM,UAAU,UAAwB;IACtC,MAAM,WAAW,GAAG,OAAO,MAAM,MAAM,EAAE,OAAO,KAAK,CAAC,EAAE;IACxD,OAAO,WAAW,mBAAmB,MAAM,QAAQ,IAAI;GACzD;GACA,MAAM,QAAQ,GAAmD,MAAa,QAA6B;IACzG,IAAI,KAAK,GAAG,qBAAqB,QAAQ,EAAE,MAAM,MAAM,OAAO,EAAE,KAAK,KAAK,CAAC,GAAG,IAAI,CAAC;IACnF,KAAK,MAAM,KAAK,EAAE,UAAU,KAAK,GAAG,WAAW,QAAQ,MAAM,EAAE,IAAI,IAAI,EAAE,MAAM,GAAG;GACpF;GACA,OAAO,QAAQ,KAAK,EAAE,SAAS,MAAM,YAAyB;IAC5D,MAAM,SAAS,QAAQ,WAAW,QAAQ,GAAG,IAAI,QAAQ,MAAM,IAAI,QAAQ,SAAS;IACpF,MAAM,QAAQ,YAAY,WAAW,OAAO,QAAQ,kBAAkB,QAAQ,QAAQ,OAAO,GAAG,IAAI,IAAI;IACxG,MAAM,WAA0B,CAAC;IACjC,KAAK,SAAS,OAAO,QAAQ;IAC7B,OAAO;KAAE,MAAM;KAAS,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;KAAG;IAAS;GAC3E,CAAC;EACH;CACF,IAAI;EAAC;EAAY;EAAU;CAAO,CAAC;AACrC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { viewToTransform } from "../../core/viewport/view.js";
|
|
2
2
|
import { worldToScreen } from "../../core/viewport/viewTransform.js";
|
|
3
3
|
import { OVERLAY_ROLE_STROKES } from "../overlayRoleStrokes.js";
|
|
4
|
-
import { gestureOverlaysFrom, isVisibleFrom } from "../drawEnvelope.js";
|
|
5
4
|
import { resolveOverlays } from "../../interactions/actions/resolveOverlays.js";
|
|
5
|
+
import { gestureOverlaysFrom, isVisibleFrom } from "../drawEnvelope.js";
|
|
6
6
|
import { insertPreviewCommands } from "./insertPreviewCommands.js";
|
|
7
7
|
import { brushOverlayCommands } from "./brushOverlay.js";
|
|
8
8
|
import { polygonFromPoints, polylineFromPoints } from "@weasel-js/geom";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNodeAtPoint.js","names":[],"sources":["../../../src/canvas/SceneCanvas/useNodeAtPoint.ts"],"sourcesContent":["import { useMemo } from 'react';\nimport { makeGetNodeAtPoint, type NodeAtPointHit } from '../getNodeAtPoint';\nimport type { PickView } from './useSceneSelectTool';\n\nexport type NodeAtPoint = (
|
|
1
|
+
{"version":3,"file":"useNodeAtPoint.js","names":[],"sources":["../../../src/canvas/SceneCanvas/useNodeAtPoint.ts"],"sourcesContent":["import { useMemo } from 'react';\nimport { makeGetNodeAtPoint, type NodeAtPointHit } from '../getNodeAtPoint';\nimport type { PickView } from './useSceneSelectTool';\nimport type { WorldPoint } from '@weasel-js/routing';\n\nexport type NodeAtPoint = (world: WorldPoint, view?: PickView | null) => NodeAtPointHit | null;\n\n/**\n * The node under a world point with its routing kind, resolved through the\n * select tool's own single-hit picker, so `onClick`, `onDoubleClick`, hover,\n * and tool routing all name the node a click selects.\n */\nexport function useNodeAtPoint<TData>(args: {\n pickBest: ((world: WorldPoint, view?: PickView | null) => string | null) | undefined;\n /** A caller's `geometry.pickEvery` can answer an id the scene does not hold. */\n nodes: { getNode(id: string): { kind: string; data: TData } | null | undefined };\n kindOf: ((node: { kind: string; data: TData }) => string) | undefined;\n}): NodeAtPoint | undefined {\n const { pickBest, nodes, kindOf } = args;\n return useMemo(() => {\n if (!pickBest) return undefined;\n return makeGetNodeAtPoint(pickBest, (id) => {\n const node = nodes.getNode(id);\n if (!node) return null;\n return { kind: kindOf ? kindOf(node) : 'unknown' };\n });\n }, [nodes, pickBest, kindOf]);\n}\n"],"mappings":";;;;;;;;;AAYA,SAAgB,eAAsB,MAKV;CAC1B,MAAM,EAAE,UAAU,OAAO,WAAW;CACpC,OAAO,cAAc;EACnB,IAAI,CAAC,UAAU,OAAO;EACtB,OAAO,mBAAmB,WAAW,OAAO;GAC1C,MAAM,OAAO,MAAM,QAAQ,EAAE;GAC7B,IAAI,CAAC,MAAM,OAAO;GAClB,OAAO,EAAE,MAAM,SAAS,OAAO,IAAI,IAAI,UAAU;EACnD,CAAC;CACH,GAAG;EAAC;EAAO;EAAU;CAAM,CAAC;AAC9B"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { targetSizesPx } from "../../core/device/targets.js";
|
|
2
2
|
import { drawnBoundsScene } from "../derivedPath.js";
|
|
3
|
-
import { createSnapOutcomeStore } from "../../
|
|
3
|
+
import { createSnapOutcomeStore } from "../../domains/snap/outcomeStore.js";
|
|
4
4
|
import { builtLayersOf, isCustomEntry } from "../layerSlots.js";
|
|
5
5
|
import { useTargetBasePx } from "../../core/device/useTargetBasePx.js";
|
|
6
|
-
import { usePathEditOverlayLayer } from "../../
|
|
6
|
+
import { usePathEditOverlayLayer } from "../../domains/paths/usePathEdit.js";
|
|
7
7
|
import { createSlopsDebugLayer } from "../slopsDebugLayer.js";
|
|
8
|
-
import { mergeLayersWithDefaults } from "./mergeLayers.js";
|
|
8
|
+
import { layersOverPresets, mergeLayersWithDefaults } from "./mergeLayers.js";
|
|
9
9
|
import { useDispatcherOverlayLayer } from "./useDispatcherOverlayLayer.js";
|
|
10
10
|
import { usePreviewGhostLayer } from "./usePreviewGhostLayer.js";
|
|
11
11
|
import { useDepartureGhostLayer } from "./useDepartureGhostLayer.js";
|
|
12
|
-
import { useEffectSourcesLayer } from "../../
|
|
12
|
+
import { useEffectSourcesLayer } from "../../domains/pathEffects/useEffectSourcesLayer.js";
|
|
13
13
|
import { usePoseTransition } from "../../animation/poseTransition.js";
|
|
14
14
|
import { useSceneSlotLayers } from "./useSceneSlotLayers.js";
|
|
15
15
|
import { useSelectionOverlayLayer } from "./useSelectionOverlayLayer.js";
|
|
16
|
-
import { useEnteredGroupFrameLayer } from "../../
|
|
17
|
-
import { createSnapReadoutLayer } from "../../
|
|
16
|
+
import { useEnteredGroupFrameLayer } from "../../domains/selection/enteredGroupFrame.js";
|
|
17
|
+
import { createSnapReadoutLayer } from "../../domains/snap/readoutLayer.js";
|
|
18
18
|
import { useMemo, useRef, useState } from "react";
|
|
19
19
|
|
|
20
20
|
//#region src/canvas/SceneCanvas/useSceneCanvasLayers.ts
|
|
@@ -29,8 +29,9 @@ import { useMemo, useRef, useState } from "react";
|
|
|
29
29
|
function useSceneCanvasLayers(args) {
|
|
30
30
|
const { scene, adapter, poseDescriptor, alphaFor, dispatcher, pathEditState, slops, targetScale } = args;
|
|
31
31
|
const baseSizes = useTargetBasePx();
|
|
32
|
-
const merged = useMemo(() => mergeLayersWithDefaults(args.layers, targetScale, baseSizes), [
|
|
32
|
+
const merged = useMemo(() => mergeLayersWithDefaults(layersOverPresets(args.presetLayers, args.layers), targetScale, baseSizes), [
|
|
33
33
|
args.layers,
|
|
34
|
+
args.presetLayers,
|
|
34
35
|
targetScale,
|
|
35
36
|
baseSizes
|
|
36
37
|
]);
|
|
@@ -84,7 +85,7 @@ function useSceneCanvasLayers(args) {
|
|
|
84
85
|
planeOfNode: args.planeOfNode
|
|
85
86
|
}, overlayConfig);
|
|
86
87
|
const { layer: selectionOverlayLayer, rotationBadge } = useSelectionOverlayLayer(merged.selectionOverlay, pathEditState.getEditingIds, poseDescriptor, args.boundsIncludeStroke ? drawnBoundsScene(scene) : void 0, resizeHandles);
|
|
87
|
-
const enteredFrameLayer = useEnteredGroupFrameLayer(args.enteredGroup, args.boundsOf, args.frameColor);
|
|
88
|
+
const enteredFrameLayer = useEnteredGroupFrameLayer(args.enteredGroup, args.boundsOf, args.frameColor, scene);
|
|
88
89
|
return {
|
|
89
90
|
layers: useMemo(() => ({
|
|
90
91
|
...builtLayersOf(merged),
|