@weasel-js/labkit 1.4.0 → 1.4.2

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.
Files changed (133) hide show
  1. package/README.md +8 -0
  2. package/dist/_dts/{CanvasStackContext-D6M0o8cQ.d.ts → CanvasStackContext-kjILVnPj.d.ts} +1 -1
  3. package/dist/_dts/PrefsForm.d-CgxUequc.d.ts +20 -0
  4. package/dist/_dts/{frac-QS7XzvpG.d.ts → frac-A4R6v4ld.d.ts} +36 -13
  5. package/dist/_dts/{index-B2X21G1c.d.ts → index-CsU9WhjM.d.ts} +90 -30
  6. package/dist/_dts/{types-ChVJJHvk.d.ts → types-BbXpvQa8.d.ts} +20 -1
  7. package/dist/_dts/{types-C1Zw7s5P.d.ts → types-lg4TSCb2.d.ts} +2 -1
  8. package/dist/_dts/{useTrialState-Cdm13fvl.d.ts → useTrialState-DKjqpv20.d.ts} +5 -1
  9. package/dist/_dts/weasel-canvas-FJTFi3ZZ.d.ts +5041 -0
  10. package/dist/canvas/index.d.ts +16 -16
  11. package/dist/canvas/index.js +2 -2
  12. package/dist/chrome/index.d.ts +15 -9
  13. package/dist/chrome/index.js +5 -5
  14. package/dist/{chunk-7VW3S44V.js → chunk-54ZWZ5FQ.js} +908 -301
  15. package/dist/chunk-54ZWZ5FQ.js.map +1 -0
  16. package/dist/{chunk-Y2HK44TG.js → chunk-D5KQ5OY6.js} +3 -3
  17. package/dist/{chunk-Y2HK44TG.js.map → chunk-D5KQ5OY6.js.map} +1 -1
  18. package/dist/{chunk-VHFQKAUL.js → chunk-FJG4PHTL.js} +83 -75
  19. package/dist/chunk-FJG4PHTL.js.map +1 -0
  20. package/dist/{chunk-LN6JDUGB.js → chunk-HXXTULDN.js} +2 -2
  21. package/dist/{chunk-LN6JDUGB.js.map → chunk-HXXTULDN.js.map} +1 -1
  22. package/dist/{chunk-L5WBGUVR.js → chunk-ISSVF5PT.js} +2753 -2654
  23. package/dist/chunk-ISSVF5PT.js.map +1 -0
  24. package/dist/chunk-NSOVI3AZ.js +170 -0
  25. package/dist/chunk-NSOVI3AZ.js.map +1 -0
  26. package/dist/{chunk-YQGQUBKA.js → chunk-TN7YSJVU.js} +62 -60
  27. package/dist/chunk-TN7YSJVU.js.map +1 -0
  28. package/dist/{chunk-4AMN4MMB.js → chunk-UDXOYZEC.js} +53 -39
  29. package/dist/chunk-UDXOYZEC.js.map +1 -0
  30. package/dist/{chunk-LJSIUFYD.js → chunk-ULDW42CR.js} +23 -2
  31. package/dist/chunk-ULDW42CR.js.map +1 -0
  32. package/dist/{chunk-QR5V3AFG.js → chunk-UTOEDPNU.js} +5 -5
  33. package/dist/{chunk-QR5V3AFG.js.map → chunk-UTOEDPNU.js.map} +1 -1
  34. package/dist/{chunk-UD7TEHZT.js → chunk-W2FJR5FF.js} +35 -22
  35. package/dist/chunk-W2FJR5FF.js.map +1 -0
  36. package/dist/{chunk-B5VWJBWM.js → chunk-WS6ZRV75.js} +3 -3
  37. package/dist/{chunk-B5VWJBWM.js.map → chunk-WS6ZRV75.js.map} +1 -1
  38. package/dist/{chunk-W3KSUXXR.js → chunk-XKENZTNE.js} +45 -14
  39. package/dist/chunk-XKENZTNE.js.map +1 -0
  40. package/dist/controls/index.d.ts +4 -3
  41. package/dist/controls/index.js +3 -3
  42. package/dist/dragdrop/index.d.ts +8 -8
  43. package/dist/dragdrop/index.js +2 -2
  44. package/dist/index.d.ts +75 -110
  45. package/dist/index.js +148 -115
  46. package/dist/index.js.map +1 -1
  47. package/dist/job/index.js +1 -1
  48. package/dist/layers/index.d.ts +26 -11
  49. package/dist/layers/index.js +3 -3
  50. package/dist/loupe/index.d.ts +7 -13
  51. package/dist/loupe/index.js +2 -2
  52. package/dist/passthrough/weasel-canvas.d.ts +3 -343
  53. package/dist/passthrough/weasel-canvas.js +1 -1
  54. package/dist/passthrough/weasel-ui.d.ts +123 -3088
  55. package/dist/passthrough/weasel-ui.js +2 -2
  56. package/dist/primitives/index.js +4 -4
  57. package/dist/state/index.d.ts +3 -3
  58. package/dist/state/index.js +2 -2
  59. package/dist/styles.css +30 -3
  60. package/dist/surface/index.js +2 -2
  61. package/dist/ui/layers/index.d.ts +22 -9
  62. package/dist/ui/layers/index.js +2 -2
  63. package/dist/undo/index.d.ts +6 -5
  64. package/package.json +8 -8
  65. package/src/annotations/AnnotationTargets.tsx +6 -1
  66. package/src/annotations/Annotations.overlay.test.tsx +2 -0
  67. package/src/annotations/types.ts +4 -1
  68. package/src/canvas/CanvasStack.tsx +8 -13
  69. package/src/canvas/useOrbit.test.ts +97 -1
  70. package/src/canvas/useOrbit.ts +41 -34
  71. package/src/canvas/usePanZoom.test.ts +106 -1
  72. package/src/canvas/usePanZoom.ts +54 -36
  73. package/src/chrome/ChromeRegions.stories.tsx +42 -1
  74. package/src/chrome/builtins.test.ts +4 -0
  75. package/src/chrome/builtins.tsx +18 -0
  76. package/src/chrome/index.ts +1 -1
  77. package/src/chrome/regions/SidebarRegion.tsx +7 -6
  78. package/src/chrome/regions/TitleBarRegion.test.tsx +64 -0
  79. package/src/chrome/regions/TitleBarRegion.tsx +16 -7
  80. package/src/chrome/regions/ToolbarRegion.test.tsx +14 -0
  81. package/src/chrome/regions/ToolbarRegion.tsx +2 -2
  82. package/src/chrome/regions/ViewportRegion.tsx +2 -2
  83. package/src/chrome/regions/regions.test.tsx +45 -1
  84. package/src/chrome/types.ts +21 -3
  85. package/src/controls/ControlPanel.test.tsx +38 -0
  86. package/src/controls/ControlPanel.tsx +51 -6
  87. package/src/dragdrop/DragDropRuntime.tsx +74 -61
  88. package/src/dragdrop/Palette.tsx +4 -3
  89. package/src/dragdrop/dragDrop.test.tsx +35 -12
  90. package/src/index.ts +2 -1
  91. package/src/instrument/types.ts +4 -5
  92. package/src/job/useJob.ts +1 -1
  93. package/src/lab/Lab.test.tsx +7 -0
  94. package/src/lab/Lab.tsx +2 -2
  95. package/src/lab/LabContext.ts +5 -1
  96. package/src/lab/LabShell.less +17 -2
  97. package/src/lab/Workspace.tsx +1 -1
  98. package/src/layers/AGENTS.md +29 -7
  99. package/src/layers/LayerList.less +16 -0
  100. package/src/layers/LayerList.stories.tsx +66 -0
  101. package/src/layers/LayerList.test.tsx +185 -2
  102. package/src/layers/LayerList.tsx +221 -74
  103. package/src/layers/index.ts +1 -1
  104. package/src/passthrough/weasel-ui.ts +5 -0
  105. package/src/primitives/FloatingPanel.test.tsx +87 -0
  106. package/src/primitives/FloatingPanel.tsx +59 -41
  107. package/src/state/store.test.ts +78 -0
  108. package/src/state/store.ts +27 -0
  109. package/src/state/types.ts +20 -0
  110. package/src/trial/Trial.less +4 -0
  111. package/src/trial/Trial.targets.test.tsx +96 -0
  112. package/src/trial/Trial.test.tsx +171 -14
  113. package/src/trial/Trial.tsx +4 -1
  114. package/src/trial/TrialChrome.tsx +22 -2
  115. package/src/trial/TrialTitleBar.tsx +7 -3
  116. package/src/trial/index.ts +1 -0
  117. package/src/trial/trialOps.test.ts +49 -1
  118. package/src/trial/trialOps.ts +28 -6
  119. package/dist/_dts/DrawCommand-B3bskUsC.d.ts +0 -564
  120. package/dist/_dts/PrefsForm-BkUJZx0A.d.ts +0 -204
  121. package/dist/_dts/fitViewToBounds-dZ2UDB6e.d.ts +0 -21
  122. package/dist/_dts/shapeKinds-Cx_rxwsa.d.ts +0 -87
  123. package/dist/_dts/types-C-gh9Ap-.d.ts +0 -695
  124. package/dist/chunk-4AMN4MMB.js.map +0 -1
  125. package/dist/chunk-7VW3S44V.js.map +0 -1
  126. package/dist/chunk-L5WBGUVR.js.map +0 -1
  127. package/dist/chunk-LJSIUFYD.js.map +0 -1
  128. package/dist/chunk-UD7TEHZT.js.map +0 -1
  129. package/dist/chunk-VHFQKAUL.js.map +0 -1
  130. package/dist/chunk-W3KSUXXR.js.map +0 -1
  131. package/dist/chunk-XCBCZEBO.js +0 -94
  132. package/dist/chunk-XCBCZEBO.js.map +0 -1
  133. package/dist/chunk-YQGQUBKA.js.map +0 -1
package/dist/job/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { useJob } from '../chunk-LN6JDUGB.js';
1
+ export { useJob } from '../chunk-HXXTULDN.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1,24 +1,39 @@
1
- import { E as LayerDescriptor } from '../_dts/frac-QS7XzvpG.js';
2
- export { B as LayerCapability } from '../_dts/frac-QS7XzvpG.js';
1
+ import { E as LayerDescriptor } from '../_dts/frac-A4R6v4ld.js';
2
+ export { B as LayerCapability } from '../_dts/frac-A4R6v4ld.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import 'react';
5
- import '../_dts/types-C1Zw7s5P.js';
6
- import '../_dts/PrefsForm-BkUJZx0A.js';
7
- import '../_dts/types-ChVJJHvk.js';
5
+ import '../_dts/types-lg4TSCb2.js';
6
+ import '../_dts/weasel-canvas-FJTFi3ZZ.js';
7
+ import '../_dts/PrefsForm.d-CgxUequc.js';
8
+ import '../_dts/types-BbXpvQa8.js';
8
9
  import '../_dts/types-DJ79Tg5J.js';
9
- import '../_dts/types-C-gh9Ap-.js';
10
10
 
11
+ /** A layer that may itself contain layers. A plain `LayerDescriptor` is one
12
+ * of these with no children, so a flat list needs no change. */
13
+ interface LayerTreeNode extends LayerDescriptor {
14
+ children?: LayerTreeNode[];
15
+ /** Render this node's children hidden on first paint. Ignored once
16
+ * `collapsedIds` is supplied. */
17
+ defaultCollapsed?: boolean;
18
+ }
11
19
  /** Props for `<LayerList>`. */
12
20
  interface LayerListProps {
13
- layers: LayerDescriptor[];
21
+ layers: LayerTreeNode[];
14
22
  visibility: Record<string, boolean>;
15
- onReorder: (newOrder: LayerDescriptor[]) => void;
23
+ /** The whole tree, with the dragged node moved. Reordering is scoped to a
24
+ * node's siblings: a drag never changes which parent a layer sits under. */
25
+ onReorder: (newOrder: LayerTreeNode[]) => void;
16
26
  onToggle: (id: string, visible: boolean) => void;
27
+ /** Ids whose children are hidden. Supplying it makes collapse controlled;
28
+ * without it the list keeps its own, seeded from `defaultCollapsed`. */
29
+ collapsedIds?: readonly string[];
30
+ onCollapsedChange?: (ids: string[]) => void;
17
31
  className?: string;
18
32
  }
19
33
  /** A reorderable list of layers with per-layer visibility toggles. Layers
20
- * marked `alwaysOn` are pinned and cannot be reordered or hidden. */
21
- declare function LayerList({ layers, visibility, onReorder, onToggle, className }: LayerListProps): react_jsx_runtime.JSX.Element;
34
+ * marked `alwaysOn` are pinned and cannot be reordered or hidden. Layers with
35
+ * `children` render as an expandable subtree. */
36
+ declare function LayerList({ layers, visibility, onReorder, onToggle, collapsedIds, onCollapsedChange, className, }: LayerListProps): react_jsx_runtime.JSX.Element;
22
37
 
23
38
  export { LayerDescriptor, LayerList };
24
- export type { LayerListProps };
39
+ export type { LayerListProps, LayerTreeNode };
@@ -1,6 +1,6 @@
1
- export { LayerList } from '../chunk-XCBCZEBO.js';
1
+ export { LayerList } from '../chunk-NSOVI3AZ.js';
2
2
  import '../chunk-SBXNQW4G.js';
3
- import '../chunk-L5WBGUVR.js';
4
- import '../chunk-7VW3S44V.js';
3
+ import '../chunk-ISSVF5PT.js';
4
+ import '../chunk-54ZWZ5FQ.js';
5
5
  //# sourceMappingURL=index.js.map
6
6
  //# sourceMappingURL=index.js.map
@@ -1,19 +1,13 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ae as LoupeMode, V as ViewTransform, W as WorldFrame, c as WorldSpec, a2 as ViewportSize, K as LoupeRenderArgs, N as ResolvedLoupe } from '../_dts/frac-QS7XzvpG.js';
3
- export { L as LOUPE_DEFAULTS, G as LoupeCapability, J as LoupeDeclaration, ab as resolveLoupe } from '../_dts/frac-QS7XzvpG.js';
4
- import { c as CanvasStackSurface, C as CanvasLayerDescriptor } from '../_dts/CanvasStackContext-D6M0o8cQ.js';
2
+ import { ae as LoupePoint, af as LoupeMode, V as ViewTransform, W as WorldFrame, c as WorldSpec, a2 as ViewportSize, K as LoupeRenderArgs, N as ResolvedLoupe } from '../_dts/frac-A4R6v4ld.js';
3
+ export { L as LOUPE_DEFAULTS, G as LoupeCapability, J as LoupeDeclaration, ab as resolveLoupe } from '../_dts/frac-A4R6v4ld.js';
4
+ import { c as CanvasStackSurface, C as CanvasLayerDescriptor } from '../_dts/CanvasStackContext-kjILVnPj.js';
5
5
  import { RefObject, ReactNode } from 'react';
6
- import '../_dts/types-C1Zw7s5P.js';
7
- import '../_dts/PrefsForm-BkUJZx0A.js';
8
- import '../_dts/types-ChVJJHvk.js';
6
+ import '../_dts/types-lg4TSCb2.js';
7
+ import '../_dts/weasel-canvas-FJTFi3ZZ.js';
8
+ import '../_dts/PrefsForm.d-CgxUequc.js';
9
+ import '../_dts/types-BbXpvQa8.js';
9
10
  import '../_dts/types-DJ79Tg5J.js';
10
- import '../_dts/types-C-gh9Ap-.js';
11
-
12
- /** A point on the magnified surface, in its own CSS pixels. */
13
- interface LoupePoint {
14
- x: number;
15
- y: number;
16
- }
17
11
 
18
12
  /** Props for `<CanvasLoupe>`. */
19
13
  interface CanvasLoupeProps {
@@ -1,7 +1,7 @@
1
- export { CanvasLoupe, DomLoupe, LOUPE_DEFAULTS, LoupeBubble, TrialLoupe, drawCanvasLens, lensCamera, lensSourceRect, resolveLoupe, sampleStack, useLoupe } from '../chunk-Y2HK44TG.js';
1
+ export { CanvasLoupe, DomLoupe, LOUPE_DEFAULTS, LoupeBubble, TrialLoupe, drawCanvasLens, lensCamera, lensSourceRect, resolveLoupe, sampleStack, useLoupe } from '../chunk-D5KQ5OY6.js';
2
2
  import '../chunk-CTRKTLYZ.js';
3
3
  import '../chunk-2AYGEN57.js';
4
4
  import '../chunk-CQLQPQ4P.js';
5
- import '../chunk-7VW3S44V.js';
5
+ import '../chunk-54ZWZ5FQ.js';
6
6
  //# sourceMappingURL=index.js.map
7
7
  //# sourceMappingURL=index.js.map
@@ -1,343 +1,3 @@
1
- import { N as Node, P as Path, S as Scene } from '../_dts/types-C-gh9Ap-.js';
2
- import { V as View, D as DrawCommand, P as PathDrawCommand } from '../_dts/DrawCommand-B3bskUsC.js';
3
- import * as react_jsx_runtime from 'react/jsx-runtime';
4
- import { Ref } from 'react';
5
- import { B as Bounds, V as ViewportDims } from '../_dts/fitViewToBounds-dZ2UDB6e.js';
6
-
7
- /**
8
- * NodeShape — the **shape trait's** registry. Each trait of a node
9
- * (shape, routing, label, icon, affordances, …) is its own registry;
10
- * this one holds the per-kind `paint` + `silhouette` (and future
11
- * fields) used by `defaultDrawOne`, clipping, non-rect hit-testing,
12
- * and lasso/area-select.
13
- *
14
- * Teaching the kit about a new kind of shape goes through this registry
15
- * rather than by overriding `drawOne`. Overrides are still possible but
16
- * shouldn't be the default seam: most consumers want the same dispatch
17
- * logic, just extended with their own shape kinds (images, custom paths,
18
- * SVG fragments, etc.).
19
- *
20
- * Built-in entries (`kit:text`, `kit:path`, `kit:rect-fallback`) are
21
- * registered at module load. Consumer entries added via
22
- * `registerNodeShape` join the chain; the first entry whose
23
- * `matches` predicate returns true paints the node.
24
- *
25
- * Two priority tiers:
26
- * - `'high'` — checked before all `'normal'` entries. Use this to
27
- * override a kit built-in for a specific data shape (e.g. a custom
28
- * text renderer that wins over `kit:text`).
29
- * - `'normal'` (default) — appended after the built-ins.
30
- *
31
- * Within a tier, entries run in registration order. Each
32
- * `registerNodeShape` call returns a disposer that removes the
33
- * entry — useful for tests, for plugin lifecycles, and for swapping
34
- * implementations at runtime.
35
- *
36
- * See `docs/superpowers/specs/2026-05-24-node-traits-reframe-design.md`
37
- * for the trait taxonomy.
38
- */
39
-
40
- /** Optional per-call paint context, threaded through `defaultDrawOne`'s third
41
- * argument. Lets a rendering entry point override ambient environment reads
42
- * — the headless `renderSceneToPixels` path supplies its own bitmap resolver
43
- * here so consumers reuse their own decode caches. Custom painters may
44
- * ignore it entirely. */
45
- interface NodePaintCtx {
46
- /** Override bitmap resolution for image nodes. When set it is authoritative:
47
- * the global `imageCache` is not consulted, and an `undefined` result
48
- * paints the deterministic grey placeholder outline (never the ambient
49
- * load-status error variant). */
50
- resolveImage?: (node: Node<unknown, string, unknown>) => ImageBitmap | undefined;
51
- /** The node's derived path, resolved by the scene-aware `drawOne` wrapper
52
- * before painting: `paint` has no scene handle, and deriving needs the
53
- * dependencies' poses. **Absent** for a node that derives from nothing —
54
- * the wrapper hands such a node the caller's own ctx untouched. `null`
55
- * means the node derives but has nothing to draw. */
56
- derivedPath?: Path | null;
57
- }
58
- /**
59
- * Per-node draw function — the scene-slot `drawOne` signature shared by
60
- * `<SceneCanvas>`, `renderSceneToCanvas` and `renderSceneToPixels`, so a
61
- * consumer can reuse one callback across a main canvas and a detached view.
62
- *
63
- * Called once per node in the walk. Returned commands are world-space; the
64
- * caller applies the view transform at the group level. `ctx` is supplied by
65
- * the scene-aware wrappers — see {@link NodePaintCtx}.
66
- */
67
- type SceneViewDrawOne<TData, TLayer extends string, TPose> = (node: Node<TData, TLayer, TPose>, pose: TPose, view: View, ctx?: NodePaintCtx) => DrawCommand[];
68
-
69
- /**
70
- * `renderSceneToCanvas` — substrate for detached, read-only scene views
71
- * (`<SceneViewCanvas>` / `<MinimapCanvas>`). Given a `<canvas>`, a `Scene`,
72
- * a `View`, and a per-node `drawOne`, render one frame.
73
- *
74
- * Step 1 of the detached-minimap spec
75
- * (`docs/superpowers/specs/2026-05-31-detached-minimap-design.md`). The full
76
- * `<SceneCanvas>` render pipeline does much more than this (slots, layer
77
- * ordering, debug sinks, tool overlays). The helper deliberately re-implements
78
- * the small subset needed for a non-interactive scene view rather than
79
- * refactoring `<SceneCanvas>` to share code — the spec calls for that
80
- * dedupe as a follow-up.
81
- *
82
- * Note: this duplicates `<SceneCanvas>`'s GL setup + view-wrap pattern in
83
- * miniature. When `<SceneCanvas>` is eventually migrated onto this helper,
84
- * the duplication collapses; until then, keep the two render paths
85
- * in sync by hand where it matters (DPR handling, viewToMat3 wrap).
86
- */
87
-
88
- /** What to draw into an existing canvas: the scene, the view, and the same
89
- * painting hooks `<SceneCanvas>` takes. */
90
- interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {
91
- /** The DOM canvas to paint into. The helper owns its WebGL2 context: the
92
- * first call on a given canvas creates a renderer and stashes it; subsequent
93
- * calls reuse the same renderer (and resize the drawing buffer on dim
94
- * changes). */
95
- canvas: HTMLCanvasElement;
96
- /** Scene to walk. `scene.renderOrder()` provides the per-node order. */
97
- scene: Scene<TData, TLayer, TPose>;
98
- /** Camera view applied to scene + extras (both ride the same world→screen
99
- * transform; extras living in screen space should be supplied via a
100
- * separately-prepared `extraCommands` group or rendered outside this
101
- * helper). */
102
- view: View;
103
- /** CSS-pixel size. The drawing buffer is set to `width × dpr` and
104
- * `height × dpr`; CSS size to `width` / `height`. */
105
- width: number;
106
- height: number;
107
- /** Per-node draw callback. */
108
- drawOne: SceneViewDrawOne<TData, TLayer, TPose>;
109
- /** Optional commands appended after the scene-node output. Used for the
110
- * minimap's visible-window indicator. Wrapped in the same view transform
111
- * as scene commands. */
112
- extraCommands?: DrawCommand[];
113
- /** Optional per-id alpha multiplier, mirroring `<SceneCanvas>`'s scene-slot
114
- * `alphaFor`. Pass the same function the main canvas uses to keep a
115
- * scoping-dim treatment consistent across both. Defaults to `() => 1`. */
116
- alphaFor?: (id: string) => number;
117
- /** Optional device-pixel ratio. Defaults to `window.devicePixelRatio || 1`
118
- * when available, otherwise 1. Tests typically pin this to 1 or 2. */
119
- dpr?: number;
120
- }
121
- /**
122
- * Build the DrawCommand list that `renderSceneToCanvas` would dispatch.
123
- *
124
- * Pure — no GL, no DOM, no side effects. Walks the scene through
125
- * `buildSceneTree` — the same walk `<SceneCanvas>`'s `buildSceneLayer` uses —
126
- * appends any `extraCommands`, and wraps the result in a single
127
- * `{ kind: 'group', transform: viewToMat3(view) }` so the output is in screen
128
- * space. Sharing the walk is what keeps hidden layers unpainted and container
129
- * clips applied here; a hand-rolled `renderOrder()` loop silently dropped both.
130
- *
131
- * Each node's commands additionally go through `wrapNodeOutput` — pose
132
- * rotation, then the `alphaFor` multiplier — exactly as `buildSceneLayer`
133
- * does, so a `drawOne` shared between the two paints the same thing in both.
134
- * A `drawOne` that rotates its own output will therefore rotate twice here;
135
- * emit unrotated geometry and let the pose drive it.
136
- *
137
- * Output shape follows `buildSceneTree`: one group per **visible** layer, in
138
- * scene-layer order, each holding one group per node on that layer.
139
- *
140
- * Exported for tests and for callers that want to render into something
141
- * other than a real `<canvas>` (e.g. an offscreen renderer or a
142
- * snapshot fixture).
143
- */
144
- declare function buildSceneViewCommands<TData, TLayer extends string, TPose>(scene: Scene<TData, TLayer, TPose>, view: View, drawOne: SceneViewDrawOne<TData, TLayer, TPose>, extraCommands?: ReadonlyArray<DrawCommand>, alphaFor?: (id: string) => number): DrawCommand[];
145
- /**
146
- * Render one frame of `scene` at `view` into `canvas`. See module docstring
147
- * for the design context.
148
- *
149
- * Idempotent at the GL-context level: on first call a `WeaselRenderer` is
150
- * constructed against the canvas's WebGL2 context and cached in a
151
- * module-level WeakMap keyed by the canvas element. Subsequent calls reuse
152
- * that renderer. When `width` / `height` / `dpr` change between calls, the
153
- * renderer's `resize` is invoked (which also updates the canvas's `width` /
154
- * `height` attributes and CSS `style.width` / `style.height`).
155
- *
156
- * Returns `void`. If the underlying environment can't supply a WebGL2 context
157
- * (e.g. jsdom in tests), the call is a silent no-op — mirroring `<Canvas>`'s
158
- * `getContext` bail-out (`Canvas.tsx` line ~1445).
159
- */
160
- declare function renderSceneToCanvas<TData, TLayer extends string, TPose>(args: RenderSceneToCanvasArgs<TData, TLayer, TPose>): void;
161
-
162
- /** Props for `<SceneViewCanvas>`. */
163
- interface SceneViewCanvasProps<TData, TLayer extends string, TPose> {
164
- /** Scene to render. Must be the same `Scene` instance passed to whoever
165
- * is mutating it; the component subscribes to its version stream and
166
- * repaints when the version advances. */
167
- scene: Scene<TData, TLayer, TPose>;
168
- /** Camera. Applied to scene + `extraCommands` via the renderer's group
169
- * transform. */
170
- view: View;
171
- /** CSS-pixel width. Drives both layout (via the rendered drawing-buffer
172
- * size) and the renderer's coordinate space. */
173
- width: number;
174
- /** CSS-pixel height. */
175
- height: number;
176
- /** Per-node draw callback. See `SceneViewDrawOne`. The consumer is
177
- * responsible for what gets painted — there is no AABB-fill default. */
178
- drawOne: SceneViewDrawOne<TData, TLayer, TPose>;
179
- /** Optional extra commands appended after scene commands, inside the same
180
- * view transform. Used by `<MinimapCanvas>` for its visible-window
181
- * indicator; available to other consumers that want to overlay a
182
- * world-space annotation. */
183
- extraCommands?: ReadonlyArray<DrawCommand>;
184
- /** Optional per-id alpha multiplier, mirroring `<SceneCanvas>`'s scene-slot
185
- * `alphaFor`. Pass the same function the main canvas uses to keep a
186
- * scoping-dim treatment consistent across both. Defaults to `() => 1`. */
187
- alphaFor?: (id: string) => number;
188
- /** Optional CSS class for sizing / positioning the `<canvas>`. The kit
189
- * does not emit inline styles for layout — use a class. */
190
- className?: string;
191
- /** Forwarded ref to the underlying `<canvas>`. Consumers attach their own
192
- * pointer listeners or call `toBlob` for snapshots through this. */
193
- canvasRef?: Ref<HTMLCanvasElement>;
194
- }
195
- declare function SceneViewCanvasInner<TData, TLayer extends string, TPose>(props: SceneViewCanvasProps<TData, TLayer, TPose>): react_jsx_runtime.JSX.Element;
196
- /**
197
- * Pointer-inert read-only scene view. See `SceneViewCanvasProps` for the
198
- * full surface and the module docstring for the rendering model.
199
- *
200
- * `forwardRef` is not used because the component is generic over `<TData,
201
- * TLayer, TPose>` and React's `forwardRef` erases generics. The
202
- * `canvasRef` prop is the plain-prop equivalent (the spec calls it out as
203
- * the public surface).
204
- */
205
- declare const SceneViewCanvas: typeof SceneViewCanvasInner;
206
-
207
- /**
208
- * Pure math helpers for `<MinimapCanvas>`.
209
- *
210
- * `computeFitView` derives a `View` that fits a chosen world rect into a
211
- * minimap canvas of given pixel dims. `computeIndicatorCommand` builds the
212
- * dashed "visible window" rect — the main canvas's screen window projected
213
- * into the minimap's own screen coordinates.
214
- *
215
- * Neither helper touches GL, the DOM, or the renderer; they're pure
216
- * functions, unit-testable with `expect`.
217
- *
218
- * See `docs/superpowers/specs/2026-05-31-detached-minimap-design.md`.
219
- */
220
-
221
- /**
222
- * Fallback view returned when there is nothing to fit (empty scene, etc.).
223
- * Identity view at the origin — produces a 1:1 mapping centered on (0, 0).
224
- */
225
- declare const FALLBACK_FIT_VIEW: View;
226
- /**
227
- * Fit policy for `<MinimapCanvas>` / `computeFitView`.
228
- *
229
- * - `"scene"` — union of leaf-node pose AABBs (via `poseBounds`).
230
- * - `{ kind: "world", rect }` — caller-supplied world rect.
231
- * - `(scene, dims) => View` — caller derives the view directly.
232
- */
233
- type MinimapFit<TData, TLayer extends string, TPose> = 'scene' | {
234
- kind: 'world';
235
- rect: Bounds;
236
- } | ((scene: Scene<TData, TLayer, TPose>, dims: ViewportDims) => View);
237
- /** Style for the visible-window indicator rect drawn over the minimap. */
238
- interface IndicatorStyle {
239
- /** Stroke color (any CSS color). Defaults to `'#ffffff'`. */
240
- stroke?: string;
241
- /** Stroke width in CSS px. Defaults to `1`. */
242
- width?: number;
243
- /** Dash pattern in CSS px. Defaults to `[2, 3]`. */
244
- dash?: number[];
245
- }
246
- /** Options for {@link computeFitView}. */
247
- interface ComputeFitViewOptions {
248
- /** Inset (CSS px) around the fit rect on each side. Defaults to `8`. */
249
- padding?: number;
250
- }
251
- /**
252
- * Derive a `View` that fits the chosen world rect into a minimap of
253
- * `dims.width × dims.height` CSS px. Uniform scale on both axes; the rect
254
- * is centered with `padding` (default 8) on each side. The smaller-axis
255
- * fit ratio wins, so the whole rect is visible.
256
- *
257
- * - `fit === "scene"`: union AABB of leaf-node poses via `poseBounds`.
258
- * Empty scene → {@link FALLBACK_FIT_VIEW}.
259
- * - `fit` is `{ kind: "world", rect }`: fit `rect`. A degenerate rect
260
- * (zero or negative area) falls back to identity scale centered on the
261
- * rect's top-left — we don't divide by zero.
262
- * - `fit` is a function: called with `(scene, dims)`; its return is
263
- * passed through unchanged.
264
- */
265
- declare function computeFitView<TData, TLayer extends string, TPose>(scene: Scene<TData, TLayer, TPose>, dims: ViewportDims, fit: MinimapFit<TData, TLayer, TPose>, poseBounds: (pose: TPose) => Bounds, opts?: ComputeFitViewOptions): View;
266
- /**
267
- * Build the visible-window indicator `DrawCommand` for the minimap.
268
- *
269
- * The main canvas's visible world rect is:
270
- * ```
271
- * worldX = mainView.x
272
- * worldY = mainView.y
273
- * worldW = mainViewDims.width / mainView.scale.x
274
- * worldH = mainViewDims.height / mainView.scale.y
275
- * ```
276
- * That world rect is then transformed into the minimap's screen
277
- * coordinates through `minimapView`.
278
- *
279
- * The returned command is a dashed-stroke `path` rect with no fill —
280
- * matching the `ViewportLayerDemo` indicator math.
281
- */
282
- declare function computeIndicatorCommand(mainView: View, mainViewDims: ViewportDims, style?: IndicatorStyle): PathDrawCommand;
283
-
284
- /** Props for `<MinimapCanvas>`. */
285
- interface MinimapCanvasProps<TData, TLayer extends string, TPose> {
286
- /** Same scene the main canvas is rendering. */
287
- scene: Scene<TData, TLayer, TPose>;
288
- /** Main canvas's view — used to position the visible-window indicator and
289
- * to preserve `scale` when the minimap recenters. */
290
- mainView: View;
291
- /** Main canvas's CSS-pixel dims. Used to compute the visible-window rect
292
- * and the recenter offset. */
293
- mainViewDims: {
294
- width: number;
295
- height: number;
296
- };
297
- /** Setter called on click (single recenter) and during drag (continuous
298
- * recenter). Receives a `View` with the same `scale` as `mainView` and
299
- * `(x, y)` shifted so the pointer's world point lands at the main
300
- * canvas's center. */
301
- onMainViewChange: (next: View) => void;
302
- /** Minimap's own CSS-pixel dims. */
303
- width: number;
304
- height: number;
305
- /** Consumer's draw callback. Applied through the derived fit view; same
306
- * signature as `<SceneCanvas>`'s scene-slot `drawOne` so the consumer
307
- * can reuse it (typically simplified — just colored AABBs). */
308
- drawOne: SceneViewDrawOne<TData, TLayer, TPose>;
309
- /** Fit policy. Defaults to `"scene"` (AABB union of leaf poses). See
310
- * `MinimapFit` for the full shape.
311
- *
312
- * Framing is derived from **document** poses, not `scene.overrides` — a
313
- * node moved by an override paints where the override puts it, outside the
314
- * frame if it goes there, rather than making the whole minimap rescale on
315
- * every frame of a drag or a settle. */
316
- fit?: MinimapFit<TData, TLayer, TPose>;
317
- /** Pose → AABB. Defaults to identity (`pose as Bounds`), matching
318
- * `sceneAdapter` / `useSelectTool`. */
319
- poseBounds?: (pose: TPose) => Bounds;
320
- /** Optional per-id alpha multiplier, mirroring `<SceneCanvas>`'s scene-slot
321
- * `alphaFor`. Pass the same function the main canvas uses so a
322
- * scoping-dim treatment shows up in the minimap too. */
323
- alphaFor?: (id: string) => number;
324
- /** Visual tuning of the indicator stroke. */
325
- indicatorStyle?: IndicatorStyle;
326
- /** CSS class for sizing / positioning the canvas. */
327
- className?: string;
328
- /** Forwarded ref to the underlying `<canvas>`. */
329
- canvasRef?: Ref<HTMLCanvasElement>;
330
- }
331
- declare function MinimapCanvasInner<TData, TLayer extends string, TPose>(props: MinimapCanvasProps<TData, TLayer, TPose>): react_jsx_runtime.JSX.Element;
332
- /**
333
- * Opinionated minimap. See `MinimapCanvasProps` for the full surface and
334
- * the module docstring for the rendering / pointer model.
335
- *
336
- * `forwardRef` is not used because the component is generic over
337
- * `<TData, TLayer, TPose>` and React's `forwardRef` erases generics. The
338
- * `canvasRef` prop is the plain-prop equivalent.
339
- */
340
- declare const MinimapCanvas: typeof MinimapCanvasInner;
341
-
342
- export { FALLBACK_FIT_VIEW, MinimapCanvas, SceneViewCanvas, buildSceneViewCommands, computeFitView, computeIndicatorCommand, renderSceneToCanvas };
343
- export type { ComputeFitViewOptions, IndicatorStyle, MinimapCanvasProps, MinimapFit, SceneViewCanvasProps, SceneViewDrawOne };
1
+ export { C as ComputeFitViewOptions, v as FALLBACK_FIT_VIEW, I as IndicatorStyle, w as MinimapCanvas, x as MinimapCanvasProps, y as MinimapFit, z as SceneViewCanvas, A as SceneViewCanvasProps, E as SceneViewDrawOne, G as buildSceneViewCommands, H as computeFitView, J as computeIndicatorCommand, K as renderSceneToCanvas } from '../_dts/weasel-canvas-FJTFi3ZZ.js';
2
+ import 'react';
3
+ import 'react/jsx-runtime';
@@ -1,3 +1,3 @@
1
- export { FALLBACK_FIT_VIEW, MinimapCanvas, SceneViewCanvas, buildSceneViewCommands, computeFitView, computeIndicatorCommand, renderSceneToCanvas } from '../chunk-7VW3S44V.js';
1
+ export { FALLBACK_FIT_VIEW, MinimapCanvas, SceneViewCanvas, buildSceneViewCommands, computeFitView, computeIndicatorCommand, renderSceneToCanvas } from '../chunk-54ZWZ5FQ.js';
2
2
  //# sourceMappingURL=weasel-canvas.js.map
3
3
  //# sourceMappingURL=weasel-canvas.js.map