@weasel-js/labkit 1.3.0 → 1.4.0-pre.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/dist/_dts/CanvasStackContext-DtAn_3O-.d.ts +42 -0
- package/dist/_dts/DrawCommand-B3bskUsC.d.ts +564 -0
- package/dist/_dts/{PrefsForm-BYa6cWnO.d.ts → PrefsForm-BkUJZx0A.d.ts} +4 -1
- package/dist/_dts/fitViewToBounds-dZ2UDB6e.d.ts +21 -0
- package/dist/_dts/frac-Cp3NivlC.d.ts +728 -0
- package/dist/_dts/index-BDVzvRzQ.d.ts +236 -0
- package/dist/_dts/shapeKinds-Cx_rxwsa.d.ts +87 -0
- package/dist/_dts/{DrawCommand-DBB45NfN.d.ts → types-C-gh9Ap-.d.ts} +1 -582
- package/dist/_dts/{types-DCGEcMO_.d.ts → types-D6s4b7if.d.ts} +1 -1
- package/dist/_dts/{types-1Sdxy_Pv.d.ts → types-DYMaEvM5.d.ts} +26 -1
- package/dist/_dts/{useTrialState-CsGMjhu9.d.ts → useTrialState-gmMvZqPc.d.ts} +7 -2
- package/dist/canvas/index.d.ts +43 -25
- package/dist/canvas/index.js +5 -4
- package/dist/chrome/index.d.ts +9 -6
- package/dist/chrome/index.js +6 -6
- package/dist/chunk-2AYGEN57.js +32 -0
- package/dist/chunk-2AYGEN57.js.map +1 -0
- package/dist/{chunk-QRYPXSGP.js → chunk-3P5TTTA7.js} +16 -8
- package/dist/chunk-3P5TTTA7.js.map +1 -0
- package/dist/{chunk-BDJXIBRZ.js → chunk-3ZELRRBV.js} +44 -27
- package/dist/chunk-3ZELRRBV.js.map +1 -0
- package/dist/{chunk-LGKRIUSW.js → chunk-4EY67BKJ.js} +32 -7
- package/dist/chunk-4EY67BKJ.js.map +1 -0
- package/dist/{chunk-3XXPU73K.js → chunk-5TCEVMPI.js} +9 -7
- package/dist/chunk-5TCEVMPI.js.map +1 -0
- package/dist/{chunk-JDROYQM3.js → chunk-6JMU56CU.js} +130 -131
- package/dist/chunk-6JMU56CU.js.map +1 -0
- package/dist/{chunk-CPUJ3QXL.js → chunk-CQLQPQ4P.js} +2 -2
- package/dist/chunk-CQLQPQ4P.js.map +1 -0
- package/dist/chunk-CTRKTLYZ.js +33 -0
- package/dist/chunk-CTRKTLYZ.js.map +1 -0
- package/dist/chunk-EQIB2PGC.js +458 -0
- package/dist/chunk-EQIB2PGC.js.map +1 -0
- package/dist/chunk-HEORBLVT.js +7128 -0
- package/dist/chunk-HEORBLVT.js.map +1 -0
- package/dist/{chunk-BMW4TDP5.js → chunk-JDDIZSLL.js} +3 -3
- package/dist/{chunk-BMW4TDP5.js.map → chunk-JDDIZSLL.js.map} +1 -1
- package/dist/chunk-LITE5YFB.js +669 -0
- package/dist/chunk-LITE5YFB.js.map +1 -0
- package/dist/{chunk-QCICIHEO.js → chunk-ROQDRXKW.js} +716 -311
- package/dist/chunk-ROQDRXKW.js.map +1 -0
- package/dist/{chunk-4TMMVIDM.js → chunk-XJ6N32QP.js} +50 -6
- package/dist/chunk-XJ6N32QP.js.map +1 -0
- package/dist/{chunk-WTI26YTM.js → chunk-YQJNT4XQ.js} +40 -13
- package/dist/chunk-YQJNT4XQ.js.map +1 -0
- package/dist/controls/index.d.ts +4 -28
- package/dist/controls/index.js +3 -3
- package/dist/dragdrop/index.d.ts +9 -5
- package/dist/dragdrop/index.js +3 -3
- package/dist/index.d.ts +518 -190
- package/dist/index.js +1753 -75
- package/dist/index.js.map +1 -1
- package/dist/layers/index.d.ts +6 -5
- package/dist/layers/index.js +3 -3
- package/dist/loupe/index.d.ts +187 -0
- package/dist/loupe/index.js +7 -0
- package/dist/loupe/index.js.map +1 -0
- package/dist/passthrough/weasel-canvas.d.ts +3 -1
- package/dist/passthrough/weasel-canvas.js +1 -1
- package/dist/passthrough/weasel-ui.d.ts +138 -91
- package/dist/passthrough/weasel-ui.js +2 -2
- package/dist/primitives/index.d.ts +3 -1
- package/dist/primitives/index.js +5 -5
- package/dist/state/index.d.ts +3 -3
- package/dist/state/index.js +2 -2
- package/dist/styles.css +229 -1
- package/dist/surface/index.d.ts +18 -2
- package/dist/surface/index.js +2 -2
- package/dist/ui/layers/index.js +2 -2
- package/dist/undo/index.d.ts +5 -4
- package/package.json +14 -7
- package/src/annotations/AnnotationOverlay.tsx +205 -0
- package/src/annotations/AnnotationTargets.tsx +37 -0
- package/src/annotations/Annotations.less +129 -0
- package/src/annotations/Annotations.meaning.test.tsx +111 -0
- package/src/annotations/Annotations.overlay.test.tsx +142 -0
- package/src/annotations/AnnotationsContext.ts +49 -0
- package/src/annotations/ExportMenu.test.tsx +86 -0
- package/src/annotations/ExportMenu.tsx +182 -0
- package/src/annotations/MarkList.tsx +75 -0
- package/src/annotations/capture.test.ts +140 -0
- package/src/annotations/capture.ts +237 -0
- package/src/annotations/drawOne.test.ts +56 -0
- package/src/annotations/drawOne.ts +47 -0
- package/src/annotations/frac.test.ts +59 -0
- package/src/annotations/frac.ts +66 -0
- package/src/annotations/history.test.ts +82 -0
- package/src/annotations/history.ts +118 -0
- package/src/annotations/index.ts +37 -0
- package/src/annotations/paint.test.ts +125 -0
- package/src/annotations/paint.ts +130 -0
- package/src/annotations/staleness.test.ts +56 -0
- package/src/annotations/staleness.ts +41 -0
- package/src/annotations/store.test.ts +175 -0
- package/src/annotations/store.ts +317 -0
- package/src/annotations/svgNodes.test.ts +77 -0
- package/src/annotations/svgNodes.ts +74 -0
- package/src/annotations/toolMap.test.ts +36 -0
- package/src/annotations/toolMap.ts +54 -0
- package/src/annotations/types.ts +222 -0
- package/src/annotations/view.test.ts +37 -0
- package/src/annotations/view.ts +40 -0
- package/src/canvas/AGENTS.md +55 -5
- package/src/canvas/CanvasStack.test.tsx +27 -1
- package/src/canvas/CanvasStack.tsx +29 -4
- package/src/canvas/CanvasStackContext.ts +23 -4
- package/src/canvas/camera.test.ts +78 -0
- package/src/canvas/camera.ts +62 -0
- package/src/canvas/canvasCoords.test.ts +26 -0
- package/src/canvas/canvasCoords.ts +20 -7
- package/src/canvas/index.ts +5 -1
- package/src/canvas/useLayerScheduler.ts +7 -3
- package/src/canvas/usePanZoom.test.ts +36 -5
- package/src/canvas/usePanZoom.ts +20 -15
- package/src/canvas/worldSpec.test.ts +63 -0
- package/src/canvas/worldSpec.ts +48 -0
- package/src/chrome/builtins.test.ts +31 -1
- package/src/chrome/builtins.tsx +63 -19
- package/src/chrome/regions/PaletteRegion.test.tsx +22 -1
- package/src/chrome/regions/PaletteRegion.tsx +4 -0
- package/src/chrome/regions/SidebarRegion.tsx +37 -13
- package/src/chrome/regions/ToolbarRegion.tsx +2 -1
- package/src/chrome/regions/ViewportRegion.tsx +9 -1
- package/src/chrome/regions/regions.test.tsx +6 -1
- package/src/chrome/types.ts +20 -0
- package/src/controls/ControlPanel.test.tsx +38 -0
- package/src/controls/ControlPanel.tsx +50 -3
- package/src/dragdrop/DragDropRuntime.tsx +8 -2
- package/src/dragdrop/dragDrop.test.tsx +29 -2
- package/src/index.test.ts +22 -0
- package/src/index.ts +87 -2
- package/src/instrument/SineWave.smoke.test.tsx +1 -0
- package/src/instrument/types.ts +24 -1
- package/src/lab/Lab.surface.test.tsx +162 -0
- package/src/lab/Lab.tsx +102 -17
- package/src/lab/Lab.undock.test.tsx +85 -0
- package/src/lab/LabFullChrome.stories.tsx +20 -0
- package/src/lab/LabShell.less +11 -0
- package/src/lab/Workspace.less +73 -0
- package/src/lab/Workspace.surface.test.tsx +2 -0
- package/src/lab/Workspace.tsx +97 -8
- package/src/lab/index.ts +1 -1
- package/src/lab/panelHost.ts +37 -0
- package/src/loupe/AGENTS.md +49 -0
- package/src/loupe/CanvasLoupe.tsx +83 -0
- package/src/loupe/DomLoupe.tsx +62 -0
- package/src/loupe/Loupe.less +38 -0
- package/src/loupe/LoupeBubble.tsx +32 -0
- package/src/loupe/TrialLoupe.tsx +93 -0
- package/src/loupe/canvasLens.test.ts +205 -0
- package/src/loupe/canvasLens.ts +141 -0
- package/src/loupe/index.ts +19 -0
- package/src/loupe/types.test.ts +29 -0
- package/src/loupe/types.ts +90 -0
- package/src/loupe/useHostSize.ts +30 -0
- package/src/loupe/useLoupe.test.tsx +197 -0
- package/src/loupe/useLoupe.ts +189 -0
- package/src/passthrough/weasel-ui.ts +3 -0
- package/src/primitives/FloatingPanel.test.tsx +76 -1
- package/src/primitives/FloatingPanel.tsx +19 -3
- package/src/primitives/ScaleIndicator.test.tsx +7 -2
- package/src/primitives/Sidebar.less +18 -0
- package/src/primitives/Toolbar.less +8 -0
- package/src/primitives/Toolbar.tsx +5 -0
- package/src/primitives/useRovingTabIndex.test.ts +21 -0
- package/src/primitives/useRovingTabIndex.ts +26 -17
- package/src/state/document.test.ts +23 -0
- package/src/state/document.ts +14 -2
- package/src/state/index.ts +2 -0
- package/src/state/store.test.ts +24 -0
- package/src/state/store.ts +35 -1
- package/src/state/types.ts +11 -0
- package/src/state/undock.test.ts +40 -0
- package/src/state/undock.ts +39 -0
- package/src/styles.less +2 -0
- package/src/surface/SurfaceContext.ts +4 -0
- package/src/surface/index.ts +8 -3
- package/src/surface/useSurfaceTile.test.tsx +2 -0
- package/src/surface/useSurfaceTile.ts +7 -1
- package/src/surface/useTiledSurface.test.tsx +58 -0
- package/src/surface/useTiledSurface.ts +38 -3
- package/src/trial/Trial.annotations.persist.test.tsx +166 -0
- package/src/trial/Trial.annotations.test.tsx +121 -0
- package/src/trial/Trial.canvas.test.tsx +76 -1
- package/src/trial/Trial.less +19 -0
- package/src/trial/Trial.loupe.test.tsx +128 -0
- package/src/trial/Trial.stories.tsx +1 -0
- package/src/trial/Trial.test.tsx +12 -0
- package/src/trial/Trial.trialId.test.tsx +36 -0
- package/src/trial/Trial.tsx +215 -40
- package/src/trial/TrialChrome.tsx +35 -0
- package/src/trial/UndockedSections.tsx +65 -0
- package/src/trial/trialOps.test.ts +21 -0
- package/src/trial/trialOps.ts +5 -3
- package/dist/_dts/types-BttTIent.d.ts +0 -314
- package/dist/chunk-3XXPU73K.js.map +0 -1
- package/dist/chunk-4TMMVIDM.js.map +0 -1
- package/dist/chunk-6X5RBC6G.js +0 -366
- package/dist/chunk-6X5RBC6G.js.map +0 -1
- package/dist/chunk-BDJXIBRZ.js.map +0 -1
- package/dist/chunk-CPUJ3QXL.js.map +0 -1
- package/dist/chunk-JDROYQM3.js.map +0 -1
- package/dist/chunk-LGKRIUSW.js.map +0 -1
- package/dist/chunk-QCICIHEO.js.map +0 -1
- package/dist/chunk-QRYPXSGP.js.map +0 -1
- package/dist/chunk-RGT4EJIB.js +0 -6961
- package/dist/chunk-RGT4EJIB.js.map +0 -1
- package/dist/chunk-T66HU3HX.js +0 -17
- package/dist/chunk-T66HU3HX.js.map +0 -1
- package/dist/chunk-WTI26YTM.js.map +0 -1
|
@@ -692,585 +692,4 @@ interface Scene<TData, TLayer extends string, TPose = RectPose> {
|
|
|
692
692
|
getVersion(): number;
|
|
693
693
|
}
|
|
694
694
|
|
|
695
|
-
|
|
696
|
-
* Viewport state. `(view.x, view.y)` is the **world point currently
|
|
697
|
-
* rendered at the canvas top-left**; `view.scale.x` / `view.scale.y` is
|
|
698
|
-
* pixels per world unit on each axis (default `{ x: 1, y: 1 }`). So:
|
|
699
|
-
*
|
|
700
|
-
* screenX = (worldX - view.x) * view.scale.x
|
|
701
|
-
* screenY = (worldY - view.y) * view.scale.y
|
|
702
|
-
* worldX = screenX / view.scale.x + view.x
|
|
703
|
-
* worldY = screenY / view.scale.y + view.y
|
|
704
|
-
*
|
|
705
|
-
* `scale` is always a 2-vector. Input convenience types
|
|
706
|
-
* {@link ZoomFactor} and {@link ZoomBound} let callers pass a scalar
|
|
707
|
-
* when they want both axes treated the same.
|
|
708
|
-
*/
|
|
709
|
-
interface View {
|
|
710
|
-
x: number;
|
|
711
|
-
y: number;
|
|
712
|
-
scale: {
|
|
713
|
-
x: number;
|
|
714
|
-
y: number;
|
|
715
|
-
};
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
/**
|
|
719
|
-
* Axis-aligned rectangle in world space. Kit-wide `Bounds` shape used by
|
|
720
|
-
* selection, group, and viewport helpers. The optional `rotation` field
|
|
721
|
-
* (radians, around the AABB center) lets selection chrome attach a rotated
|
|
722
|
-
* orientation to an otherwise axis-aligned rect without needing a parallel
|
|
723
|
-
* type.
|
|
724
|
-
*/
|
|
725
|
-
interface Bounds {
|
|
726
|
-
x: number;
|
|
727
|
-
y: number;
|
|
728
|
-
width: number;
|
|
729
|
-
height: number;
|
|
730
|
-
rotation?: number;
|
|
731
|
-
}
|
|
732
|
-
/** Pixel dimensions of the canvas viewport. */
|
|
733
|
-
interface ViewportDims {
|
|
734
|
-
width: number;
|
|
735
|
-
height: number;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
/**
|
|
739
|
-
* A registered texture, named by the registry that holds it.
|
|
740
|
-
*
|
|
741
|
-
* The handle is here rather than beside the registry because `FillStyle`'s
|
|
742
|
-
* pattern variant names it, and paint is a leaf: the registry lives in the
|
|
743
|
-
* renderer and imports this back.
|
|
744
|
-
*/
|
|
745
|
-
interface TextureHandle {
|
|
746
|
-
readonly id: string;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
/**
|
|
750
|
-
* FillStyle and Stroke types — the unified shape for "what color or texture
|
|
751
|
-
* paints these pixels," modeled on SVG's paint-server concept.
|
|
752
|
-
*
|
|
753
|
-
* - `FillStyle` is a tagged union: solid color, pattern, or gradient. Used
|
|
754
|
-
* wherever a kit option previously took `fillStyle: string`.
|
|
755
|
-
* - `Stroke` pairs a `FillStyle` with structural stroke parameters (width, dash,
|
|
756
|
-
* line cap/join, alignment).
|
|
757
|
-
* - These types are consumed by the GL renderer's DrawCommand path fills
|
|
758
|
-
* and strokes.
|
|
759
|
-
*
|
|
760
|
-
* The 2D `applyPaint` / `applyStroke` / `renderFilledRegion` helpers that
|
|
761
|
-
* formerly lived alongside these types were deleted with the 2D backend in
|
|
762
|
-
* Step 10. `alignedStrokeRect` survives as a pure geometry helper used by
|
|
763
|
-
* path tessellation and the selection overlay.
|
|
764
|
-
*/
|
|
765
|
-
|
|
766
|
-
/**
|
|
767
|
-
* Color/texture strategy for fills (and, via `Stroke.paint`, strokes).
|
|
768
|
-
*
|
|
769
|
-
* `fill` is optional and defaults to `'solid'` — `{ color: '#abc' }` is
|
|
770
|
-
* equivalent to `{ fill: 'solid', color: '#abc' }`. Pattern paints must set
|
|
771
|
-
* `fill: 'pattern'` explicitly.
|
|
772
|
-
*
|
|
773
|
-
* The `'pattern'` variant's payload is either a `TilePatternSpec` — plain
|
|
774
|
-
* data naming one of the built-in tiles, which survives serialization — or a
|
|
775
|
-
* `TextureHandle` for a tile the consumer built itself via
|
|
776
|
-
* `createTilePattern()`. A handle is a session-scoped registry key, so a
|
|
777
|
-
* paint carrying one cannot be persisted or exported; prefer the spec.
|
|
778
|
-
*
|
|
779
|
-
* `units` on a pattern names the space the tile's origin and scale live in,
|
|
780
|
-
* not the space of any geometry (a pattern has none). Under `'bounds'` the
|
|
781
|
-
* tile anchors to the painted node's box, so the pattern travels with the
|
|
782
|
-
* node and a resize reveals more tiles rather than stretching them;
|
|
783
|
-
* `fillInPoseFrame` resolves that to a `'local'` paint with an explicit
|
|
784
|
-
* `origin` before the renderer sees it.
|
|
785
|
-
*/
|
|
786
|
-
type FillStyle = {
|
|
787
|
-
fill?: 'solid';
|
|
788
|
-
color: string;
|
|
789
|
-
opacity?: number;
|
|
790
|
-
} | {
|
|
791
|
-
fill: 'pattern';
|
|
792
|
-
pattern: TextureHandle | TilePatternSpec;
|
|
793
|
-
units?: GradientUnits;
|
|
794
|
-
origin?: {
|
|
795
|
-
x: number;
|
|
796
|
-
y: number;
|
|
797
|
-
};
|
|
798
|
-
opacity?: number;
|
|
799
|
-
} | {
|
|
800
|
-
fill: 'linear-gradient';
|
|
801
|
-
from: {
|
|
802
|
-
x: number;
|
|
803
|
-
y: number;
|
|
804
|
-
};
|
|
805
|
-
to: {
|
|
806
|
-
x: number;
|
|
807
|
-
y: number;
|
|
808
|
-
};
|
|
809
|
-
stops: GradStop[];
|
|
810
|
-
units?: GradientUnits;
|
|
811
|
-
opacity?: number;
|
|
812
|
-
} | {
|
|
813
|
-
fill: 'radial-gradient';
|
|
814
|
-
center: {
|
|
815
|
-
x: number;
|
|
816
|
-
y: number;
|
|
817
|
-
};
|
|
818
|
-
radius: number;
|
|
819
|
-
stops: GradStop[];
|
|
820
|
-
units?: GradientUnits;
|
|
821
|
-
opacity?: number;
|
|
822
|
-
} | {
|
|
823
|
-
fill: 'conic-gradient';
|
|
824
|
-
center: {
|
|
825
|
-
x: number;
|
|
826
|
-
y: number;
|
|
827
|
-
};
|
|
828
|
-
angle: number;
|
|
829
|
-
stops: GradStop[];
|
|
830
|
-
units?: GradientUnits;
|
|
831
|
-
opacity?: number;
|
|
832
|
-
};
|
|
833
|
-
/**
|
|
834
|
-
* Which coordinate space a gradient's geometry (`from`/`to`, `center`,
|
|
835
|
-
* `radius`) is expressed in. SVG's `gradientUnits`, plus an option for
|
|
836
|
-
* paints that are themselves viewport furniture.
|
|
837
|
-
*
|
|
838
|
-
* - `'bounds'`: fractions of the painted node's bounding box, `0..1` on each
|
|
839
|
-
* axis — SVG `objectBoundingBox`. Resolved by the node painter, before the
|
|
840
|
-
* renderer sees it, so the paint follows the node through moves, resizes
|
|
841
|
-
* and rotation. What a gradient on a scene node wants.
|
|
842
|
-
* - `'local'`: the coordinate space the geometry was handed to the renderer
|
|
843
|
-
* in — the enclosing group's frame. For draw commands a consumer builds
|
|
844
|
-
* itself, where "the coordinates I just wrote" is the useful frame.
|
|
845
|
-
* - `'world'`: scene coordinates. The paint stays put under pan and zoom
|
|
846
|
-
* while the geometry moves through it. SVG `userSpaceOnUse`. Requires the
|
|
847
|
-
* renderer to have been handed a view matrix; falls back to `'screen'`
|
|
848
|
-
* when it has not.
|
|
849
|
-
* - `'screen'`: CSS pixels of the drawing surface. For overlays and
|
|
850
|
-
* viewport-fixed washes that should not move with the content at all.
|
|
851
|
-
*
|
|
852
|
-
* Defaults to `'screen'`, which is the behavior every gradient had before
|
|
853
|
-
* this field existed.
|
|
854
|
-
*/
|
|
855
|
-
type GradientUnits = 'bounds' | 'local' | 'world' | 'screen';
|
|
856
|
-
/**
|
|
857
|
-
* A built-in tile, described as plain data. The serializable half of the
|
|
858
|
-
* pattern paint: `resolvePatternSpec()` turns one into a `TextureHandle`
|
|
859
|
-
* at paint time, memoized so identical specs share a texture.
|
|
860
|
-
*
|
|
861
|
-
* `size` is the tile's edge length, and doubles as its extent in paint
|
|
862
|
-
* space — a bigger `size` rasterizes a bigger tile rather than magnifying
|
|
863
|
-
* a small one, which is why there is no separate scale field.
|
|
864
|
-
*/
|
|
865
|
-
interface TilePatternSpec {
|
|
866
|
-
tile: 'hatch' | 'crosshatch' | 'dots' | 'chunks';
|
|
867
|
-
color: string;
|
|
868
|
-
/** `chunks` only — omit for a transparent tile background. */
|
|
869
|
-
bg?: string;
|
|
870
|
-
size?: number;
|
|
871
|
-
/** `hatch` / `crosshatch`. */
|
|
872
|
-
lineWidth?: number;
|
|
873
|
-
/** `dots`. */
|
|
874
|
-
radius?: number;
|
|
875
|
-
/** `chunks`. */
|
|
876
|
-
density?: number;
|
|
877
|
-
chunkSize?: number;
|
|
878
|
-
seed?: number;
|
|
879
|
-
}
|
|
880
|
-
/** A single color stop within a gradient. `offset` is in 0..1. */
|
|
881
|
-
interface GradStop {
|
|
882
|
-
offset: number;
|
|
883
|
-
color: string;
|
|
884
|
-
}
|
|
885
|
-
/**
|
|
886
|
-
* Where a stroke sits relative to the geometric edge it strokes.
|
|
887
|
-
*
|
|
888
|
-
* - `'center'` (default): canvas-native — half the stroke width sits inside
|
|
889
|
-
* the geometry, half outside.
|
|
890
|
-
* - `'inner'`: the entire stroke lies inside the geometry. The outer edge of
|
|
891
|
-
* the stroke coincides with the geometric edge.
|
|
892
|
-
* - `'outer'`: the entire stroke lies outside the geometry. The inner edge
|
|
893
|
-
* of the stroke coincides with the geometric edge.
|
|
894
|
-
*
|
|
895
|
-
* Mirrors the (proposed) SVG `stroke-alignment` property. Honoring `inner`
|
|
896
|
-
* or `outer` is the renderer's responsibility — for axis-aligned rects, the
|
|
897
|
-
* kit shifts coordinates by `width / 2`. For arbitrary paths, renderers
|
|
898
|
-
* typically use a stencil mask of the stroked path against the geometry.
|
|
899
|
-
*/
|
|
900
|
-
type StrokeAlign = 'center' | 'inner' | 'outer';
|
|
901
|
-
/**
|
|
902
|
-
* The kit's built-in marker vocabulary, open on the string the way
|
|
903
|
-
* `PaintKind` is so a consumer's registered key typechecks.
|
|
904
|
-
*/
|
|
905
|
-
type KitMarkerKey = 'arrow' | 'arrow-open' | 'arrow-concave' | 'diamond' | 'diamond-hollow' | 'circle' | 'square' | 'bar';
|
|
906
|
-
type MarkerKey = KitMarkerKey | (string & {});
|
|
907
|
-
/**
|
|
908
|
-
* A marker on one end (or every interior vertex) of a stroke.
|
|
909
|
-
*
|
|
910
|
-
* `size` reuses `Stroke.width`'s unit system: a bare number scales with the
|
|
911
|
-
* resolved stroke width, `{ px }` pins screen pixels. That is SVG's
|
|
912
|
-
* `markerUnits` in the idiom this codebase already resolves at draw time.
|
|
913
|
-
* Omitted, the marker is one stroke width per unit.
|
|
914
|
-
*/
|
|
915
|
-
type MarkerRef = MarkerKey | {
|
|
916
|
-
key: MarkerKey;
|
|
917
|
-
size?: number | {
|
|
918
|
-
px: number;
|
|
919
|
-
};
|
|
920
|
-
};
|
|
921
|
-
/** Stroke style: a FillStyle plus structural line parameters. */
|
|
922
|
-
interface Stroke {
|
|
923
|
-
paint: FillStyle;
|
|
924
|
-
/** World units, or `{ px }` for screen pixels — resolved against the
|
|
925
|
-
* accumulated transform scale at draw time, so it holds its on-screen
|
|
926
|
-
* thickness as the view zooms. */
|
|
927
|
-
width?: number | {
|
|
928
|
-
px: number;
|
|
929
|
-
};
|
|
930
|
-
/** Per `CanvasRenderingContext2D.setLineDash` — empty/omitted = solid. */
|
|
931
|
-
dash?: number[];
|
|
932
|
-
/** Marker at the first vertex of each open subpath, rotated to point back
|
|
933
|
-
* along the line (SVG's `auto-start-reverse`, as the only behavior). */
|
|
934
|
-
markerStart?: MarkerRef;
|
|
935
|
-
/** Marker at every interior authored vertex, on the bisector of the
|
|
936
|
-
* incoming and outgoing directions. Never insets the stroke. */
|
|
937
|
-
markerMid?: MarkerRef;
|
|
938
|
-
/** Marker at the last vertex of each open subpath. */
|
|
939
|
-
markerEnd?: MarkerRef;
|
|
940
|
-
cap?: 'butt' | 'round' | 'square';
|
|
941
|
-
join?: 'miter' | 'round' | 'bevel';
|
|
942
|
-
/**
|
|
943
|
-
* Miter join fallback threshold. When the miter length exceeds
|
|
944
|
-
* `miterLimit * width / 2`, the join falls back to a bevel. Default 4,
|
|
945
|
-
* matching SVG — which is also what the kit's own serializer implies when
|
|
946
|
-
* it omits the attribute for an unset field. Canvas2D's 10 lets an acute
|
|
947
|
-
* corner throw a spike four times the half-width.
|
|
948
|
-
*/
|
|
949
|
-
miterLimit?: number;
|
|
950
|
-
/** Where the stroke sits relative to the geometric edge. Default `'center'`. */
|
|
951
|
-
align?: StrokeAlign;
|
|
952
|
-
/**
|
|
953
|
-
* Per-anchor RGBA, flat (length = 4 × countPathAnchors(path)). Each
|
|
954
|
-
* value in 0..1. Arc-length interpolated across the tessellated ribbon
|
|
955
|
-
* between consecutive anchors. When set, `paint` is still required —
|
|
956
|
-
* its `opacity` (and color, as a placeholder) flow through the shader.
|
|
957
|
-
*/
|
|
958
|
-
vertexColors?: number[];
|
|
959
|
-
/**
|
|
960
|
-
* Per-anchor stroke width (length = `countPathAnchors(path)`). When set,
|
|
961
|
-
* the tessellator interpolates half-widths along each segment to produce
|
|
962
|
-
* a tapered ribbon. `width` is used as the fallback for any anchor whose
|
|
963
|
-
* entry is missing or non-finite. Pressure-driven pencil strokes use
|
|
964
|
-
* this; pair with `pressureToWidth` to derive widths from stylus input.
|
|
965
|
-
*
|
|
966
|
-
* Joins between adjacent segments whose widths differ by more than
|
|
967
|
-
* `varyingWidthJoinThreshold` (default 1.5×) are forced to bevel
|
|
968
|
-
* regardless of the `join` setting — miter math is unstable when widths
|
|
969
|
-
* vary across the corner; smooth round joins with mismatched widths
|
|
970
|
-
* are a future enhancement.
|
|
971
|
-
*/
|
|
972
|
-
vertexWidths?: number[];
|
|
973
|
-
/**
|
|
974
|
-
* Max width ratio (greater / lesser) at which a non-bevel join is
|
|
975
|
-
* preserved when `vertexWidths` causes adjacent segments to differ.
|
|
976
|
-
* Beyond this ratio the join falls back to bevel. Default 1.5. Ignored
|
|
977
|
-
* when `vertexWidths` is absent.
|
|
978
|
-
*/
|
|
979
|
-
varyingWidthJoinThreshold?: number;
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
/**
|
|
983
|
-
* 2D affine matrix utilities. Column-major 9-element Float32Array, matching
|
|
984
|
-
* `WebGL2RenderingContext.uniformMatrix3fv` byte order so we can pass the
|
|
985
|
-
* array directly without a transpose flag.
|
|
986
|
-
*
|
|
987
|
-
* Layout (column-major):
|
|
988
|
-
* [m00, m10, 0,
|
|
989
|
-
* m01, m11, 0,
|
|
990
|
-
* tx, ty, 1]
|
|
991
|
-
*
|
|
992
|
-
* `apply(m, x, y)` returns `[m * (x, y, 1)] = [m00*x + m01*y + tx,
|
|
993
|
-
* m10*x + m11*y + ty]`.
|
|
994
|
-
*/
|
|
995
|
-
type Mat3 = Float32Array;
|
|
996
|
-
|
|
997
|
-
/**
|
|
998
|
-
* Typography for `TextPose` and friends. Every field is optional; consumers
|
|
999
|
-
* pass `{}` or override the few they care about. Defaults live in
|
|
1000
|
-
* `DEFAULT_TEXT_STYLE` and are applied at render/measure time, never written
|
|
1001
|
-
* back to the pose.
|
|
1002
|
-
*
|
|
1003
|
-
* Paint is not typography and does not live here. A text node carries its
|
|
1004
|
-
* fill and stroke in `data.fill` / `data.stroke`, the slots every other node
|
|
1005
|
-
* kind uses; `resolveTextStyle` takes them as its second argument and
|
|
1006
|
-
* `StyledRun.fill` / `.stroke` override them per range.
|
|
1007
|
-
*/
|
|
1008
|
-
|
|
1009
|
-
/**
|
|
1010
|
-
* Horizontal alignment. `start` / `end` resolve against the reading direction;
|
|
1011
|
-
* `left` / `right` are absolute. Same five values as CSS `text-align`, with
|
|
1012
|
-
* the same split between the relative pair and the absolute pair.
|
|
1013
|
-
*/
|
|
1014
|
-
type TextAlign = 'left' | 'center' | 'right' | 'start' | 'end';
|
|
1015
|
-
/** Reading direction, which is what gives `start` / `end` their meaning. */
|
|
1016
|
-
type TextDirection = 'ltr' | 'rtl';
|
|
1017
|
-
/** User-facing text style. All fields optional; defaults applied at render time via `resolveTextStyle`. */
|
|
1018
|
-
interface TextStyle {
|
|
1019
|
-
/** Font size in world units. Default 16. */
|
|
1020
|
-
fontSize?: number;
|
|
1021
|
-
/** Default `'sans-serif'`. */
|
|
1022
|
-
fontFamily?: string;
|
|
1023
|
-
/** Default 400. */
|
|
1024
|
-
fontWeight?: number | string;
|
|
1025
|
-
/** Default `'normal'`. */
|
|
1026
|
-
fontStyle?: 'normal' | 'italic';
|
|
1027
|
-
/** Default `'left'`. Pass `'start'` to align by reading order instead. */
|
|
1028
|
-
align?: TextAlign;
|
|
1029
|
-
/** Reading direction, resolving `align: 'start' | 'end'`. Default `'ltr'`. */
|
|
1030
|
-
direction?: TextDirection;
|
|
1031
|
-
/** Multiplier applied to `fontSize`. Default 1.2. */
|
|
1032
|
-
lineHeight?: number;
|
|
1033
|
-
/**
|
|
1034
|
-
* Caret color used by the edit overlay. Defaults to the node's fill when
|
|
1035
|
-
* that fill is solid; falls back to `#000` for non-solid paints.
|
|
1036
|
-
*/
|
|
1037
|
-
caretColor?: string;
|
|
1038
|
-
/**
|
|
1039
|
-
* Selection background color used by the edit overlay's `::selection`
|
|
1040
|
-
* pseudo-element. Defaults to a 25%-opacity tint of `caretColor` via CSS
|
|
1041
|
-
* `color-mix`. Pass `'none'` to fall back to the browser-native highlight.
|
|
1042
|
-
*/
|
|
1043
|
-
selectionBackground?: string;
|
|
1044
|
-
/** Selection text color paired with `selectionBackground`. Default: inherits text color. */
|
|
1045
|
-
selectionColor?: string;
|
|
1046
|
-
/** Extra advance added after each glyph, in world units. Default 0. */
|
|
1047
|
-
letterSpacing?: number;
|
|
1048
|
-
/** Default `false`. */
|
|
1049
|
-
underline?: boolean;
|
|
1050
|
-
/** Default `false`. */
|
|
1051
|
-
strikethrough?: boolean;
|
|
1052
|
-
/** Default `false`. */
|
|
1053
|
-
overline?: boolean;
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
/**
|
|
1057
|
-
* Apply node-level `ResolvedTextStyle` defaults to each `StyledRun`,
|
|
1058
|
-
* producing a fully-resolved run with every styling field set. Downstream
|
|
1059
|
-
* layout and draw never re-resolve defaults — `ResolvedRun` is the
|
|
1060
|
-
* canonical shape the renderer consumes.
|
|
1061
|
-
*
|
|
1062
|
-
* `bold`/`italic` toggles on a run are folded into `fontWeight`/`fontStyle`:
|
|
1063
|
-
* `bold: true` → fontWeight 700, `italic: true` → fontStyle 'italic'.
|
|
1064
|
-
* Explicit `fontFamily` / `fontSize` / `fill` / `letterSpacing` on the run
|
|
1065
|
-
* override the node-level value (`letterSpacing: 0` on a run is an override,
|
|
1066
|
-
* not an absence — it zeroes inherited tracking).
|
|
1067
|
-
*
|
|
1068
|
-
* `underline` / `strikethrough` / `overline` are *additive*, like
|
|
1069
|
-
* `bold`/`italic`: a run can turn a decoration on but never off, so they
|
|
1070
|
-
* resolve as `run.x || style.x` and not `run.x ?? style.x`. See the header of
|
|
1071
|
-
* `runs/rangeStyle.ts` for why the model collapses the tri-state.
|
|
1072
|
-
*
|
|
1073
|
-
* `script` is folded the same way the toggles are, into the two primitives it
|
|
1074
|
-
* is a preset over: `baselineShift` and `fontScale`. Both come out as one
|
|
1075
|
-
* world-unit `baselineShift` and a final `fontSize`, so layout never learns
|
|
1076
|
-
* that superscripts exist — it places a run against a baseline and an offset.
|
|
1077
|
-
*/
|
|
1078
|
-
|
|
1079
|
-
/** A run with every style resolved against the node's text style — no
|
|
1080
|
-
* optional inheritance left. This is what layout and painting consume. */
|
|
1081
|
-
interface ResolvedRun {
|
|
1082
|
-
text: string;
|
|
1083
|
-
fontFamily: string;
|
|
1084
|
-
fontSize: number;
|
|
1085
|
-
fontWeight: number;
|
|
1086
|
-
fontStyle: 'normal' | 'italic';
|
|
1087
|
-
fill: FillStyle;
|
|
1088
|
-
/** Outline over this run's glyphs, or absent for none. Painted only on the
|
|
1089
|
-
* outline tier — a distance field has no geometry to stroke. */
|
|
1090
|
-
stroke?: Stroke;
|
|
1091
|
-
/** Extra advance added after each glyph of this run, in world units. */
|
|
1092
|
-
letterSpacing: number;
|
|
1093
|
-
/** Draw a rule below this run's baseline. Additive over the node style. */
|
|
1094
|
-
underline: boolean;
|
|
1095
|
-
/** Draw a rule through this run's x-height. Additive over the node style. */
|
|
1096
|
-
strikethrough: boolean;
|
|
1097
|
-
/** Draw a rule above this run's ascent. Additive over the node style. */
|
|
1098
|
-
overline: boolean;
|
|
1099
|
-
/**
|
|
1100
|
-
* How far this run sits off the line's shared baseline, in world units;
|
|
1101
|
-
* positive raises. 0 for ordinary text.
|
|
1102
|
-
*
|
|
1103
|
-
* Already multiplied out against the inherited font size, and already
|
|
1104
|
-
* carrying whatever `script` asked for — layout adds it to a baseline and
|
|
1105
|
-
* asks nothing about where it came from.
|
|
1106
|
-
*/
|
|
1107
|
-
baselineShift: number;
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
/**
|
|
1111
|
-
* Box vertical alignment for text draw commands. Given the command's box
|
|
1112
|
-
* `height` and the laid-out text block's height, returns the Y offset to
|
|
1113
|
-
* apply to every quad. `'top'` (or an undefined `align`, or a missing box
|
|
1114
|
-
* `height`) is the legacy behavior: offset 0.
|
|
1115
|
-
*/
|
|
1116
|
-
type TextVerticalAlign = 'top' | 'center' | 'bottom';
|
|
1117
|
-
|
|
1118
|
-
/**
|
|
1119
|
-
* registerProgram — public API for registering custom shader programs.
|
|
1120
|
-
*
|
|
1121
|
-
* Stores raw GLSL source strings in a module-level registry. GL compilation
|
|
1122
|
-
* happens on each WeaselRenderer via WeaselRenderer.registerProgram(), which
|
|
1123
|
-
* calls getProgramSource() and compiles the result. This keeps registerProgram
|
|
1124
|
-
* GL-context-agnostic — identical pattern to registerFont storing ImageBitmap.
|
|
1125
|
-
*
|
|
1126
|
-
* Module-level state = source strings only; compiled GL
|
|
1127
|
-
* programs live on each renderer's programRegistry (Map<id, ShaderProgram>).
|
|
1128
|
-
*
|
|
1129
|
-
* Lifecycle: program sources live for the module lifetime. No unregister in v1.
|
|
1130
|
-
*/
|
|
1131
|
-
|
|
1132
|
-
/** Opaque handle to a compiled custom shader program. */
|
|
1133
|
-
interface ShaderProgramHandle {
|
|
1134
|
-
readonly id: string;
|
|
1135
|
-
}
|
|
1136
|
-
/**
|
|
1137
|
-
* Scalar and vector uniform types accepted by the custom shader uniform binder.
|
|
1138
|
-
*
|
|
1139
|
-
* | TS type | GL call |
|
|
1140
|
-
* |-------------------------|--------------------------------------|
|
|
1141
|
-
* | number | uniform1f |
|
|
1142
|
-
* | [n, n] | uniform2fv |
|
|
1143
|
-
* | [n, n, n] | uniform3fv |
|
|
1144
|
-
* | [n, n, n, n] | uniform4fv |
|
|
1145
|
-
* | Float32Array length 9 | uniformMatrix3fv (column-major) |
|
|
1146
|
-
* | Float32Array length 16 | uniformMatrix4fv (column-major) |
|
|
1147
|
-
* | TextureHandle | bind to next tex unit + uniform1i |
|
|
1148
|
-
*/
|
|
1149
|
-
type ShaderUniform = number | [number, number] | [number, number, number] | [number, number, number, number] | Float32Array | TextureHandle;
|
|
1150
|
-
|
|
1151
|
-
/** DrawCommand variants implemented through step 6. */
|
|
1152
|
-
type DrawCommand = PathDrawCommand | GroupDrawCommand | TextDrawCommand | ImageDrawCommand | ShaderDrawCommand;
|
|
1153
|
-
/** Draw a path, filled and/or stroked. The workhorse command: every shape the
|
|
1154
|
-
* kit draws that is not text, an image, or a custom shader is one of these. */
|
|
1155
|
-
interface PathDrawCommand {
|
|
1156
|
-
kind: 'path';
|
|
1157
|
-
path: Path;
|
|
1158
|
-
/** Any `FillStyle` variant: solid, pattern, or gradient (linear/radial/conic). */
|
|
1159
|
-
fill?: FillStyle;
|
|
1160
|
-
/** Stroke spec. Only solid `paint` supported through step 4. */
|
|
1161
|
-
stroke?: Stroke;
|
|
1162
|
-
/**
|
|
1163
|
-
* Optional flat RGBA-per-path-anchor color array (length =
|
|
1164
|
-
* `4 × countPathAnchors(path)`, floats in 0..1). The renderer
|
|
1165
|
-
* arc-length-interpolates these per-anchor colors across the
|
|
1166
|
-
* flattened/triangulated mesh between consecutive anchors using the
|
|
1167
|
-
* mesh's `anchorA` / `anchorB` / `anchorT` parameterization.
|
|
1168
|
-
*
|
|
1169
|
-
* **`fill` must also be set when using `vertexColors`.** The renderer
|
|
1170
|
-
* only enters the per-vertex shader path when the command has a fill
|
|
1171
|
-
* (the fill provides the opacity uniform; the vertex colors override
|
|
1172
|
-
* the fill's color). Pass any solid `fill` (e.g. `{ color: '#fff' }`)
|
|
1173
|
-
* as the placeholder; the per-vertex colors win in the shader.
|
|
1174
|
-
*/
|
|
1175
|
-
vertexColors?: number[];
|
|
1176
|
-
}
|
|
1177
|
-
/** Draw a list of commands under a shared transform, opacity, color matrix
|
|
1178
|
-
* and clip. Groups nest, and their effects accumulate down the stack — this
|
|
1179
|
-
* is how a container node's transform reaches its descendants. */
|
|
1180
|
-
interface GroupDrawCommand {
|
|
1181
|
-
kind: 'group';
|
|
1182
|
-
transform?: Mat3;
|
|
1183
|
-
alpha?: number;
|
|
1184
|
-
/**
|
|
1185
|
-
* Optional 4×5 color matrix (row-major, 20 numbers) — `out = M₄ₓ₄ * in + bias`.
|
|
1186
|
-
* Accumulated multiplicatively down the group stack. Defaults to identity.
|
|
1187
|
-
*/
|
|
1188
|
-
colorMatrix?: number[];
|
|
1189
|
-
/** Optional clip path. When set, the renderer rasterizes this path into
|
|
1190
|
-
* the stencil buffer before drawing `children`; the children paint only
|
|
1191
|
-
* where the clip covers. Nested groups with clips intersect — a child
|
|
1192
|
-
* cannot escape an ancestor's clip. Max 7 nesting levels; the renderer
|
|
1193
|
-
* throws if exceeded. */
|
|
1194
|
-
clip?: Path;
|
|
1195
|
-
children: DrawCommand[];
|
|
1196
|
-
}
|
|
1197
|
-
/**
|
|
1198
|
-
* Text draw command. Renders one or more runs at (`x`, `y`) in screen
|
|
1199
|
-
* space, optionally word-wrapping at `maxWidth`. The renderer resolves
|
|
1200
|
-
* each run's `(fontFamily, fontWeight, fontStyle)` to an MSDF atlas via
|
|
1201
|
-
* `resolveFontVariant` and bucket-draws by atlas + color group.
|
|
1202
|
-
*
|
|
1203
|
-
* `style` carries node-level defaults (`lineHeight`, anti-alias width)
|
|
1204
|
-
* that don't belong on individual runs.
|
|
1205
|
-
*/
|
|
1206
|
-
interface TextDrawCommand {
|
|
1207
|
-
kind: 'text';
|
|
1208
|
-
x: number;
|
|
1209
|
-
y: number;
|
|
1210
|
-
runs: ResolvedRun[];
|
|
1211
|
-
maxWidth?: number;
|
|
1212
|
-
align?: 'left' | 'center' | 'right';
|
|
1213
|
-
style: TextStyle;
|
|
1214
|
-
/** Box height for vertical alignment. When set with `verticalAlign`,
|
|
1215
|
-
* the laid-out block shifts within `[y, y+height]`. */
|
|
1216
|
-
height?: number;
|
|
1217
|
-
/** Default 'top' — the legacy top-anchored behavior. */
|
|
1218
|
-
verticalAlign?: TextVerticalAlign;
|
|
1219
|
-
}
|
|
1220
|
-
/**
|
|
1221
|
-
* Image draw command — renders `image` at screen-space rect (x, y, w, h).
|
|
1222
|
-
* The image is stretched to fit; no tiling. Use a pattern FillStyle on a path
|
|
1223
|
-
* for tiling.
|
|
1224
|
-
*/
|
|
1225
|
-
interface ImageDrawCommand {
|
|
1226
|
-
kind: 'image';
|
|
1227
|
-
image: ImageBitmap;
|
|
1228
|
-
x: number;
|
|
1229
|
-
y: number;
|
|
1230
|
-
w: number;
|
|
1231
|
-
h: number;
|
|
1232
|
-
opacity?: number;
|
|
1233
|
-
/** Magnification filter. `'linear'` (default) smooths; `'nearest'` shows
|
|
1234
|
-
* device pixels as hard squares — required by anything magnifying a
|
|
1235
|
-
* framebuffer readback, where blur destroys the point of the readback. */
|
|
1236
|
-
sampling?: 'linear' | 'nearest';
|
|
1237
|
-
/** Sub-rectangle of `image` to draw, in bitmap pixels from the top-left.
|
|
1238
|
-
* Omitted draws the whole bitmap. Not range-checked: a rect past the edge
|
|
1239
|
-
* samples outside [0..1], which CLAMP_TO_EDGE smears. With
|
|
1240
|
-
* `sampling: 'linear'` the filter reaches half a texel beyond `source`, so
|
|
1241
|
-
* atlas frames need a gutter (see `SpriteSheet.spacing`) or `'nearest'`. */
|
|
1242
|
-
source?: {
|
|
1243
|
-
x: number;
|
|
1244
|
-
y: number;
|
|
1245
|
-
w: number;
|
|
1246
|
-
h: number;
|
|
1247
|
-
};
|
|
1248
|
-
/** Mirror the sampled region within the destination rect. The quad does not
|
|
1249
|
-
* move — a flipped draw covers exactly the pixels an unflipped one does. */
|
|
1250
|
-
flipX?: boolean;
|
|
1251
|
-
flipY?: boolean;
|
|
1252
|
-
}
|
|
1253
|
-
/**
|
|
1254
|
-
* Custom shader draw command. The renderer generates a quad over `bounds`
|
|
1255
|
-
* and dispatches the consumer's fragment shader with the kit's vertex prelude.
|
|
1256
|
-
*
|
|
1257
|
-
* `uniforms` keys must match names declared in the consumer's fragment shader.
|
|
1258
|
-
* The kit automatically sets `u_bounds`, `u_view`, and `u_proj` — do not
|
|
1259
|
-
* declare those in `uniforms`.
|
|
1260
|
-
*
|
|
1261
|
-
* @experimental API may change before v2.
|
|
1262
|
-
*/
|
|
1263
|
-
interface ShaderDrawCommand {
|
|
1264
|
-
kind: 'shader';
|
|
1265
|
-
program: ShaderProgramHandle;
|
|
1266
|
-
uniforms: Record<string, ShaderUniform>;
|
|
1267
|
-
/** Screen-space bounding rect in CSS pixels. */
|
|
1268
|
-
bounds: {
|
|
1269
|
-
x: number;
|
|
1270
|
-
y: number;
|
|
1271
|
-
w: number;
|
|
1272
|
-
h: number;
|
|
1273
|
-
};
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
export type { Bounds as B, DrawCommand as D, History as H, Node as N, Op as O, Path as P, Scene as S, View as V, ViewportDims as a, PathDrawCommand as b, NodeId as c };
|
|
695
|
+
export type { History as H, Node as N, Op as O, Path as P, Scene as S, NodeId as a };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as PrefRenderer, T as ToolPrefLeaf, a as ToolPrefGroup } from './PrefsForm-
|
|
1
|
+
import { P as PrefRenderer, T as ToolPrefLeaf, a as ToolPrefGroup } from './PrefsForm-BkUJZx0A.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Renders the control cell for one config leaf. Identical to weasel-ui's
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/** A sidebar section torn out of its trial, and where it went. */
|
|
2
|
+
interface UndockedPanel {
|
|
3
|
+
trialId: string;
|
|
4
|
+
sectionId: string;
|
|
5
|
+
as: 'tile' | 'floating';
|
|
6
|
+
}
|
|
7
|
+
/** Undocked panels, keyed by {@link panelKey}. */
|
|
8
|
+
type UndockedPanels = Record<string, UndockedPanel>;
|
|
9
|
+
declare function panelKey(trialId: string, sectionId: string): string;
|
|
10
|
+
declare function undockPanel(panels: UndockedPanels, trialId: string, sectionId: string, as?: UndockedPanel['as']): UndockedPanels;
|
|
11
|
+
/** Dock one section back, or — with no `sectionId` — every panel the trial
|
|
12
|
+
* owns, which is what closing a trial wants. */
|
|
13
|
+
declare function dockPanel(panels: UndockedPanels, trialId: string, sectionId?: string): UndockedPanels;
|
|
14
|
+
|
|
1
15
|
/** A trial's undo history, as snapshots of its state either side of the
|
|
2
16
|
* present. */
|
|
3
17
|
interface UndoStack {
|
|
@@ -16,6 +30,11 @@ interface TrialRecord<TS = unknown, TC = unknown, TV = unknown> {
|
|
|
16
30
|
view: TV;
|
|
17
31
|
/** This trial's own tool slot. Undefined means it reads the lab's. */
|
|
18
32
|
activeToolId?: string | null;
|
|
33
|
+
/** The marks on this trial's annotation targets, as `AnnotationsApi.toJSON`
|
|
34
|
+
* wrote them. Opaque here, and absent for a trial whose instrument declares
|
|
35
|
+
* no `annotations` — or declares its own `storage`. Not in `state`, which
|
|
36
|
+
* belongs to the instrument and is typed as such. */
|
|
37
|
+
annotations?: unknown;
|
|
19
38
|
undoStack: UndoStack;
|
|
20
39
|
}
|
|
21
40
|
/** A named, saved copy of a trial's config and state, restorable into any
|
|
@@ -42,6 +61,9 @@ interface LabStoreState {
|
|
|
42
61
|
/** Per-trial tile extents, keyed by trial id. Opaque here — the
|
|
43
62
|
* shape belongs to whatever lays the trials out. */
|
|
44
63
|
layout: Record<string, unknown>;
|
|
64
|
+
/** Sidebar sections torn out of their trial. A panel here is not rendered in
|
|
65
|
+
* its trial's sidebar; the workspace renders it instead. */
|
|
66
|
+
undockedPanels: UndockedPanels;
|
|
45
67
|
}
|
|
46
68
|
/** Where a lab persists itself. Implementations are keyed string storage and
|
|
47
69
|
* nothing more, so the same store works against localStorage, the URL hash,
|
|
@@ -81,10 +103,13 @@ interface LabDocument {
|
|
|
81
103
|
trials: SerializedTrial[];
|
|
82
104
|
saves: SavedSnapshot[];
|
|
83
105
|
layout: Record<string, unknown>;
|
|
106
|
+
/** Sidebar sections torn out of their trial, keyed by trial and section. */
|
|
107
|
+
undockedPanels: UndockedPanels;
|
|
84
108
|
mode: LabMode;
|
|
85
109
|
}
|
|
86
110
|
/** Migrates a document one version forward. Index `i` in the chain takes a
|
|
87
111
|
* version-`i` document to version `i + 1`. */
|
|
88
112
|
type Migration = (doc: Record<string, unknown>) => Record<string, unknown>;
|
|
89
113
|
|
|
90
|
-
export
|
|
114
|
+
export { dockPanel as g, panelKey as p, undockPanel as u };
|
|
115
|
+
export type { CreateLabStoreOptions as C, InstrumentSerializers as I, LabDocument as L, Migration as M, SerializedTrial as S, TrialRecord as T, UndoStack as U, StorageAdapter as a, LabStoreState as b, SavedSnapshot as c, TrialStateHandle as d, UndockedPanel as e, UndockedPanels as f, LabMode as h };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as StorageAdapter, b as LabStoreState, T as TrialRecord, c as SavedSnapshot,
|
|
1
|
+
import { a as StorageAdapter, b as LabStoreState, T as TrialRecord, c as SavedSnapshot, h as LabMode, e as UndockedPanel, I as InstrumentSerializers, C as CreateLabStoreOptions, d as TrialStateHandle } from './types-DYMaEvM5.js';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode, ReactElement } from 'react';
|
|
4
4
|
import { StoreApi } from 'zustand/vanilla';
|
|
@@ -25,6 +25,7 @@ interface LabStoreActions {
|
|
|
25
25
|
updateTrialState: <TS>(id: string, next: TS | ((prev: TS) => TS)) => void;
|
|
26
26
|
updateTrialConfig: <TC>(id: string, key: keyof TC, value: TC[keyof TC]) => void;
|
|
27
27
|
updateTrialView: (id: string, view: unknown) => void;
|
|
28
|
+
updateTrialAnnotations: (id: string, doc: unknown) => void;
|
|
28
29
|
updateTrialUndoStack: (id: string, next: TrialRecord['undoStack'] | ((prev: TrialRecord['undoStack']) => TrialRecord['undoStack'])) => void;
|
|
29
30
|
setTrialInstrument: (id: string, instrumentName: string) => void;
|
|
30
31
|
saveSnapshot: (trialId: string, name: string) => void;
|
|
@@ -35,6 +36,10 @@ interface LabStoreActions {
|
|
|
35
36
|
setLabTool: (id: string | null) => void;
|
|
36
37
|
setTrialTool: (trialId: string, id: string | null) => void;
|
|
37
38
|
setLayout: (layout: Record<string, unknown>) => void;
|
|
39
|
+
/** Tear a sidebar section out of its trial. Default target is a workspace tile. */
|
|
40
|
+
undockPanel: (trialId: string, sectionId: string, as?: UndockedPanel['as']) => void;
|
|
41
|
+
/** Put one section back, or — with no `sectionId` — every panel the trial owns. */
|
|
42
|
+
dockPanel: (trialId: string, sectionId?: string) => void;
|
|
38
43
|
}
|
|
39
44
|
/** A lab's store: its state and actions, plus the hook instruments use to
|
|
40
45
|
* register how their state is serialized. */
|
|
@@ -71,7 +76,7 @@ declare function TrialIdProvider({ trialId, children, }: {
|
|
|
71
76
|
declare function useTrialId(): string;
|
|
72
77
|
|
|
73
78
|
/** Bumped whenever the persisted shape changes; every bump needs a migration. */
|
|
74
|
-
declare const CURRENT_DOCUMENT_VERSION =
|
|
79
|
+
declare const CURRENT_DOCUMENT_VERSION = 3;
|
|
75
80
|
/** The one key a lab persists under. The `:doc` suffix keeps it out of the
|
|
76
81
|
* legacy bucket namespace, where a lab named `a:saves` would otherwise write
|
|
77
82
|
* its document over lab `a`'s saves bucket. */
|