@weasel-js/labkit 1.4.4 → 1.5.1

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 (278) hide show
  1. package/README.md +54 -6
  2. package/dist/_dts/{CanvasStackContext-kTEZvEgE.d.ts → CanvasStackContext-CJNMS6mz.d.ts} +1 -1
  3. package/dist/_dts/{PrefsForm.d-DDHFANkc.d.ts → PrefsForm.d-DPy9I8It.d.ts} +4 -0
  4. package/dist/_dts/Select.d-Gwr8fLpK.d.ts +453 -0
  5. package/dist/_dts/{frac-z7ker2Vx.d.ts → frac-B4okC2lX.d.ts} +291 -31
  6. package/dist/_dts/{index-Blv9uQzu.d.ts → index-BNdz-tNd.d.ts} +105 -17
  7. package/dist/_dts/index-CSJoj4LC.d.ts +248 -0
  8. package/dist/_dts/{types-B9_zrHmb.d.ts → types-DzoNY1pO.d.ts} +91 -4
  9. package/dist/_dts/usePanZoom-Pzf9f2jh.d.ts +160 -0
  10. package/dist/_dts/useTrialState-uLlmaccn.d.ts +212 -0
  11. package/dist/canvas/index.d.ts +18 -129
  12. package/dist/canvas/index.js +4 -2
  13. package/dist/chrome/index.d.ts +5 -93
  14. package/dist/chrome/index.js +10 -6
  15. package/dist/chunk-7PFH3CNM.js +150 -0
  16. package/dist/chunk-7PFH3CNM.js.map +1 -0
  17. package/dist/{chunk-I6JCVE24.js → chunk-CEIUBPPW.js} +143 -17
  18. package/dist/chunk-CEIUBPPW.js.map +1 -0
  19. package/dist/chunk-EH7UEQV7.js +590 -0
  20. package/dist/chunk-EH7UEQV7.js.map +1 -0
  21. package/dist/{chunk-MOM3GOVY.js → chunk-EHGVROVV.js} +125 -27
  22. package/dist/chunk-EHGVROVV.js.map +1 -0
  23. package/dist/{chunk-TJ7QY3OC.js → chunk-ERFMC6WU.js} +160 -78
  24. package/dist/chunk-ERFMC6WU.js.map +1 -0
  25. package/dist/{chunk-CTRKTLYZ.js → chunk-H6ZAOWNE.js} +11 -11
  26. package/dist/chunk-H6ZAOWNE.js.map +1 -0
  27. package/dist/{chunk-64ZCN3DA.js → chunk-IHUVQ3TX.js} +250 -160
  28. package/dist/chunk-IHUVQ3TX.js.map +1 -0
  29. package/dist/{chunk-FQMJUVHJ.js → chunk-IJJUK4FU.js} +53 -46
  30. package/dist/chunk-IJJUK4FU.js.map +1 -0
  31. package/dist/chunk-IXTQI7JX.js +737 -0
  32. package/dist/chunk-IXTQI7JX.js.map +1 -0
  33. package/dist/{chunk-BKFVHKJH.js → chunk-MDVTK5U3.js} +4 -4
  34. package/dist/{chunk-BKFVHKJH.js.map → chunk-MDVTK5U3.js.map} +1 -1
  35. package/dist/chunk-PHK4W562.js +72 -0
  36. package/dist/chunk-PHK4W562.js.map +1 -0
  37. package/dist/chunk-PJ7WEQBJ.js +18 -0
  38. package/dist/chunk-PJ7WEQBJ.js.map +1 -0
  39. package/dist/chunk-RWNDDKOH.js +682 -0
  40. package/dist/chunk-RWNDDKOH.js.map +1 -0
  41. package/dist/chunk-T3EC2DXD.js +12628 -0
  42. package/dist/chunk-T3EC2DXD.js.map +1 -0
  43. package/dist/{chunk-SMHP6XZ4.js → chunk-UN4U4P63.js} +10 -8
  44. package/dist/chunk-UN4U4P63.js.map +1 -0
  45. package/dist/chunk-WIG6XHJ7.js +35 -0
  46. package/dist/chunk-WIG6XHJ7.js.map +1 -0
  47. package/dist/chunk-Z76KEZAX.js +15 -0
  48. package/dist/chunk-Z76KEZAX.js.map +1 -0
  49. package/dist/chunk-ZDHY47EV.js +363 -0
  50. package/dist/chunk-ZDHY47EV.js.map +1 -0
  51. package/dist/config/index.d.ts +276 -0
  52. package/dist/config/index.js +8 -0
  53. package/dist/config/index.js.map +1 -0
  54. package/dist/controls/index.d.ts +3 -4
  55. package/dist/controls/index.js +4 -3
  56. package/dist/dragdrop/index.d.ts +3 -5
  57. package/dist/index.d.ts +266 -413
  58. package/dist/index.js +1775 -2251
  59. package/dist/index.js.map +1 -1
  60. package/dist/layers/index.d.ts +4 -6
  61. package/dist/layers/index.js +2 -2
  62. package/dist/loupe/index.d.ts +69 -20
  63. package/dist/loupe/index.js +2 -2
  64. package/dist/passthrough/weasel-ui.d.ts +175 -309
  65. package/dist/passthrough/weasel-ui.js +1 -1
  66. package/dist/primitives/index.d.ts +55 -6
  67. package/dist/primitives/index.js +6 -4
  68. package/dist/state/index.d.ts +13 -8
  69. package/dist/state/index.js +18 -13
  70. package/dist/state/index.js.map +1 -1
  71. package/dist/styles.css +223 -76
  72. package/dist/surface/index.d.ts +44 -7
  73. package/dist/surface/index.js +2 -1
  74. package/dist/ui/layers/index.js +1 -1
  75. package/dist/undo/index.d.ts +3 -5
  76. package/package.json +15 -8
  77. package/src/annotations/AnnotationOverlay.tsx +56 -5
  78. package/src/annotations/Annotations.less +4 -0
  79. package/src/annotations/Annotations.overlay.test.tsx +105 -6
  80. package/src/annotations/drawOne.test.ts +1 -1
  81. package/src/annotations/drawOne.ts +2 -2
  82. package/src/annotations/paint.test.ts +2 -2
  83. package/src/annotations/paint.ts +1 -1
  84. package/src/annotations/preload.ts +6 -0
  85. package/src/annotations/store.test.ts +18 -0
  86. package/src/annotations/store.ts +5 -4
  87. package/src/annotations/svgNodes.test.ts +2 -2
  88. package/src/annotations/svgNodes.ts +1 -0
  89. package/src/annotations/toolMap.test.ts +9 -5
  90. package/src/annotations/toolMap.ts +6 -3
  91. package/src/annotations/types.ts +6 -3
  92. package/src/canvas/CameraWheelContext.ts +12 -0
  93. package/src/canvas/CanvasStack.stories.tsx +1 -1
  94. package/src/canvas/CanvasStack.test.tsx +25 -0
  95. package/src/canvas/CanvasStack.tsx +31 -4
  96. package/src/canvas/Stage.less +18 -0
  97. package/src/canvas/Stage.test.tsx +186 -0
  98. package/src/canvas/Stage.tsx +134 -0
  99. package/src/canvas/camera.test.ts +17 -2
  100. package/src/canvas/camera.ts +9 -9
  101. package/src/canvas/index.ts +4 -0
  102. package/src/canvas/usePanZoom.test.ts +28 -0
  103. package/src/canvas/usePanZoom.ts +21 -9
  104. package/src/chrome/ChromeRegions.stories.tsx +1 -4
  105. package/src/chrome/LabChrome.tsx +130 -0
  106. package/src/chrome/builtins.test.ts +1 -0
  107. package/src/chrome/builtins.tsx +21 -31
  108. package/src/chrome/index.ts +16 -0
  109. package/src/chrome/labRegions.test.tsx +208 -0
  110. package/src/chrome/labTypes.ts +50 -0
  111. package/src/chrome/merge.ts +7 -9
  112. package/src/chrome/regions/PaletteRegion.test.tsx +6 -4
  113. package/src/chrome/regions/PaletteRegion.tsx +16 -9
  114. package/src/chrome/regions/SidebarRegion.stories.tsx +44 -0
  115. package/src/chrome/regions/SidebarRegion.tsx +25 -13
  116. package/src/chrome/regions/StatusRegion.tsx +15 -8
  117. package/src/chrome/regions/ToolbarRegion.tsx +34 -16
  118. package/src/chrome/types.ts +50 -20
  119. package/src/config/auto.test.ts +12 -0
  120. package/src/config/auto.ts +15 -0
  121. package/src/config/autoConfig.test.ts +107 -0
  122. package/src/config/autoConfig.ts +153 -0
  123. package/src/config/builder.test.ts +42 -0
  124. package/src/config/builder.ts +68 -17
  125. package/src/config/declarationEmit.fixture.ts +11 -0
  126. package/src/config/declarationEmit.test.ts +51 -0
  127. package/src/config/entry.test.ts +46 -0
  128. package/src/config/index.ts +16 -1
  129. package/src/config/nodeClasses.test.ts +18 -0
  130. package/src/config/path.ts +7 -2
  131. package/src/config/resolve.test.ts +25 -0
  132. package/src/config/resolve.ts +17 -1
  133. package/src/config/types.ts +34 -2
  134. package/src/config/useResolvedConfig.ts +26 -0
  135. package/src/controls/AutoControls.stories.tsx +88 -0
  136. package/src/controls/ControlPanel.stories.tsx +42 -1
  137. package/src/controls/ControlPanel.test.tsx +530 -4
  138. package/src/controls/ControlPanel.tsx +562 -82
  139. package/src/fake-indexeddb-auto.d.ts +5 -0
  140. package/src/index.test.ts +7 -0
  141. package/src/index.ts +66 -5
  142. package/src/instrument/serializers.test.ts +22 -0
  143. package/src/instrument/serializers.ts +40 -1
  144. package/src/instrument/types.ts +25 -1
  145. package/src/lab/Lab.chrome.test.tsx +16 -0
  146. package/src/lab/Lab.less +4 -13
  147. package/src/lab/Lab.persist.test.tsx +147 -0
  148. package/src/lab/Lab.stories.tsx +1 -3
  149. package/src/lab/Lab.surface.test.tsx +71 -3
  150. package/src/lab/Lab.test.tsx +168 -16
  151. package/src/lab/Lab.tsx +434 -129
  152. package/src/lab/LabContext.ts +8 -0
  153. package/src/lab/LabFit.stories.less +18 -0
  154. package/src/lab/LabFit.stories.tsx +219 -0
  155. package/src/lab/LabFullChrome.stories.tsx +1 -4
  156. package/src/lab/LabHeader.test.tsx +40 -9
  157. package/src/lab/LabHeader.tsx +7 -14
  158. package/src/lab/LabPalette.tsx +13 -26
  159. package/src/lab/LabRoot.test.tsx +56 -0
  160. package/src/lab/LabRoot.tsx +47 -0
  161. package/src/lab/LabShell.less +73 -15
  162. package/src/lab/LabShell.stories.tsx +50 -1
  163. package/src/lab/LabShell.tsx +18 -27
  164. package/src/lab/LabSwitcher.less +18 -11
  165. package/src/lab/LabSwitcher.test.tsx +14 -9
  166. package/src/lab/LabSwitcher.tsx +8 -4
  167. package/src/lab/Workspace.less +1 -1
  168. package/src/lab/Workspace.stories.tsx +1 -1
  169. package/src/lab/Workspace.surface.test.tsx +1 -0
  170. package/src/lab/fitCheck.test.ts +57 -0
  171. package/src/lab/fitCheck.ts +125 -0
  172. package/src/lab/index.ts +2 -0
  173. package/src/layers/LayerList.stories.tsx +1 -1
  174. package/src/loupe/AGENTS.md +17 -5
  175. package/src/loupe/Loupe.less +1 -1
  176. package/src/loupe/LoupeGestures.tsx +67 -0
  177. package/src/loupe/TrialLoupe.tsx +43 -28
  178. package/src/loupe/canvasLens.ts +1 -1
  179. package/src/loupe/index.ts +4 -0
  180. package/src/loupe/loupeActions.ts +98 -0
  181. package/src/loupe/types.ts +1 -1
  182. package/src/loupe/useLoupe.test.tsx +60 -3
  183. package/src/loupe/useLoupe.ts +29 -49
  184. package/src/passthrough/weasel-ui.ts +9 -0
  185. package/src/primitives/FloatingPanel.stories.tsx +14 -2
  186. package/src/primitives/FloatingPanel.test.tsx +47 -16
  187. package/src/primitives/FloatingPanel.tsx +11 -25
  188. package/src/primitives/FpsMeter.stories.tsx +1 -1
  189. package/src/primitives/JobProgress.stories.tsx +1 -1
  190. package/src/primitives/Legend.stories.tsx +1 -1
  191. package/src/primitives/ScaleIndicator.stories.tsx +1 -1
  192. package/src/primitives/Sidebar.less +7 -0
  193. package/src/primitives/Sidebar.stories.tsx +1 -1
  194. package/src/primitives/Split.less +14 -0
  195. package/src/primitives/Split.test.tsx +133 -0
  196. package/src/primitives/Split.tsx +175 -0
  197. package/src/primitives/StatusBar.stories.tsx +1 -1
  198. package/src/primitives/Toolbar.stories.tsx +1 -1
  199. package/src/primitives/ZoomControl.tsx +5 -2
  200. package/src/primitives/index.ts +2 -0
  201. package/src/specimen/Specimen.less +95 -0
  202. package/src/specimen/Specimen.stories.tsx +13 -0
  203. package/src/specimen/Specimen.test.tsx +13 -0
  204. package/src/specimen/Specimen.tsx +888 -0
  205. package/src/state/Persistence.stories.tsx +75 -0
  206. package/src/state/Persistence.tsx +33 -0
  207. package/src/state/SingletonExperiment.test.tsx +47 -53
  208. package/src/state/SingletonExperiment.tsx +24 -13
  209. package/src/state/adapterContract.ts +116 -0
  210. package/src/state/adapters.test.ts +113 -61
  211. package/src/state/adapters.ts +328 -69
  212. package/src/state/document.test.ts +71 -96
  213. package/src/state/document.ts +66 -52
  214. package/src/state/helpers.test.ts +1 -1
  215. package/src/state/index.ts +8 -0
  216. package/src/state/labRecords.test.ts +105 -0
  217. package/src/state/labRecords.ts +160 -0
  218. package/src/state/openLabStore.test.ts +658 -0
  219. package/src/state/openLabStore.ts +403 -0
  220. package/src/state/records.test.ts +234 -0
  221. package/src/state/records.ts +219 -0
  222. package/src/state/store.test.ts +169 -635
  223. package/src/state/store.ts +146 -163
  224. package/src/state/toolSlot.test.ts +1 -1
  225. package/src/state/types.ts +65 -17
  226. package/src/state/useOpenOnce.ts +68 -0
  227. package/src/state/usePersistedState.test.tsx +125 -0
  228. package/src/state/usePersistedState.ts +66 -0
  229. package/src/state/useTrialState.test.tsx +87 -3
  230. package/src/state/useTrialState.ts +9 -1
  231. package/src/state/view.test.ts +49 -15
  232. package/src/state/view.ts +18 -1
  233. package/src/styles.less +3 -0
  234. package/src/surface/AGENTS.md +39 -7
  235. package/src/surface/SurfaceContext.ts +26 -3
  236. package/src/surface/index.ts +2 -0
  237. package/src/surface/useSurfaceTile.test.tsx +1 -0
  238. package/src/surface/useSurfaceTile.ts +6 -5
  239. package/src/surface/useTiledSurface.test.tsx +231 -1
  240. package/src/surface/useTiledSurface.ts +76 -15
  241. package/src/theme/Interstellar.stories.tsx +9 -9
  242. package/src/theme/interstellar.test.ts +17 -6
  243. package/src/theme/interstellar.theme.json +180 -0
  244. package/src/theme/interstellar.ts +8 -5
  245. package/src/tools/labTool.ts +11 -0
  246. package/src/trial/Trial.annotations.persist.test.tsx +100 -58
  247. package/src/trial/Trial.annotations.test.tsx +59 -7
  248. package/src/trial/Trial.canvas.test.tsx +32 -0
  249. package/src/trial/Trial.config.test.tsx +75 -2
  250. package/src/trial/Trial.job.test.tsx +3 -3
  251. package/src/trial/Trial.less +5 -26
  252. package/src/trial/Trial.stories.tsx +5 -3
  253. package/src/trial/Trial.test.tsx +31 -4
  254. package/src/trial/Trial.trialId.test.tsx +23 -1
  255. package/src/trial/Trial.tsx +139 -52
  256. package/src/trial/TrialBody.tsx +17 -141
  257. package/src/trial/TrialChrome.tsx +24 -7
  258. package/src/trial/trialOps.test.ts +101 -1
  259. package/src/trial/trialOps.ts +67 -7
  260. package/dist/_dts/types-BP2OCcpg.d.ts +0 -155
  261. package/dist/_dts/types-x92Kfeme.d.ts +0 -62
  262. package/dist/_dts/useTrialState-D6Vb3T-g.d.ts +0 -99
  263. package/dist/chunk-2P6PP5N4.js +0 -553
  264. package/dist/chunk-2P6PP5N4.js.map +0 -1
  265. package/dist/chunk-64ZCN3DA.js.map +0 -1
  266. package/dist/chunk-CTRKTLYZ.js.map +0 -1
  267. package/dist/chunk-E44SU6XS.js +0 -50
  268. package/dist/chunk-E44SU6XS.js.map +0 -1
  269. package/dist/chunk-FQMJUVHJ.js.map +0 -1
  270. package/dist/chunk-I6JCVE24.js.map +0 -1
  271. package/dist/chunk-MOM3GOVY.js.map +0 -1
  272. package/dist/chunk-SMHP6XZ4.js.map +0 -1
  273. package/dist/chunk-TJ7QY3OC.js.map +0 -1
  274. package/dist/chunk-U3IYHIAE.js +0 -343
  275. package/dist/chunk-U3IYHIAE.js.map +0 -1
  276. package/dist/chunk-W3ECWC2K.js +0 -7335
  277. package/dist/chunk-W3ECWC2K.js.map +0 -1
  278. package/src/theme/interstellar.tokens.json +0 -61
package/dist/index.d.ts CHANGED
@@ -1,34 +1,47 @@
1
- export { LayerStack, LayerStackItem, LayerStackProps } from './ui/layers/index.js';
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { I as IconProps } from './_dts/Select.d-Gwr8fLpK.js';
3
+ export { B as Button, a as ButtonProps, b as ButtonSize, c as ButtonVariant, d as Icon, e as Input, f as InputProps, S as Select, g as SelectProps, T as ToggleBar, h as ToggleBarItem, i as ToggleBarProps, j as ToggleBarSize, k as ToggleBarVariant } from './_dts/Select.d-Gwr8fLpK.js';
4
+ export { LayerStack, LayerStackItem, LayerStackProps } from './ui/layers/index.js';
3
5
  import * as react from 'react';
4
6
  import { ReactNode } from 'react';
5
- import { P as PropertyMetricProps, a as PropertyListPack } from './_dts/index-Blv9uQzu.js';
6
- export { C as CheckboxRow, b as CheckboxRowProps, c as ColorRow, d as ColorRowProps, e as ControlPanel, N as NumberRow, f as NumberRowProps, g as PropertyList, h as PropertyListProps, i as PropertyOption, j as PropertyPanel, k as PropertyPanelProps, l as PropertyRow, m as PropertyRowLayout, n as PropertyRowProps, o as PropertyRowVariant, p as PropertySpan, q as PropertySpanProps, S as SelectRow, r as SelectRowProps, s as SliderRow, t as SliderRowProps, T as TextRow, u as TextRowProps, v as ToggleRow, w as ToggleRowProps } from './_dts/index-Blv9uQzu.js';
7
- import { DrawCommand, SceneNode, View, Path, FillStyle, StyledRun, TextStyle, Stroke, BuiltinToolId, ToolPrefLeaf, ToolPrefGroup } from '@weasel-js/core';
8
- import { d as WorldRect, A as AnnotationData, e as AnnotationMeaning, M as MarkScene, C as CaptureSource, f as CaptureOptions, g as CaptureResult, h as AnnotationTarget, i as AnnotationsApi, j as AnnotationsCapability, T as TrialTool, k as AnnotationKind, V as ViewTransform, I as Instrument, l as InstrumentList, m as TrialContribution } from './_dts/frac-z7ker2Vx.js';
9
- export { n as Annotation, o as AnnotationInit, p as AnnotationPatch, q as AnnotationQuery, r as AnnotationStatus, s as AnnotationStoreOptions, t as AnnotationTargetInfo, u as CanvasCapability, v as CanvasLayer, w as CaptureDeps, x as DEFAULT_FRAME, b as DragDropCapability, D as DragFeedback, F as FracPoint, y as FracRect, H as HitResult, z as IconComponent, L as LOUPE_DEFAULTS, B as LayerCapability, E as LayerDescriptor, G as LoupeCapability, J as LoupeDeclaration, K as LoupeRenderArgs, P as PaletteItem, a as Point, R as RenderContext, N as ResolvedLoupe, S as SerializedAnnotations, O as SidebarSection, Q as StatusReadout, U as SystemEvent, X as ToolCapability, Y as ToolItem, Z as ToolbarItem, _ as TrialChromeContext, $ as TrialRegion, a0 as UndoCapability, a1 as ViewportControl, a2 as ViewportSize, W as WorldFrame, c as WorldSpec, a3 as annotationsFromJSON, a4 as applyCamera, a5 as createAnnotationScene, a6 as createAnnotationStore, a7 as fracContains, a8 as fracEncloses, a9 as fracToWorld, aa as resolveFrame, ab as resolveLoupe, ac as roundFrac, ad as worldToFrac } from './_dts/frac-z7ker2Vx.js';
10
- import { i as TrialInfo, a as StorageAdapter, h as LabMode, T as TrialRecord, c as SavedSnapshot } from './_dts/types-BP2OCcpg.js';
11
- export { C as CreateLabStoreOptions, L as LabDocument, b as LabStoreState, S as SerializedTrial, d as TrialStateHandle, U as UndoStack, e as UndockedPanel, f as UndockedPanels, g as dockPanel, p as panelKey, u as undockPanel } from './_dts/types-BP2OCcpg.js';
12
- export { CanvasStack, CanvasStackProps, OrbitHandlers, OrbitView, PITCH_LIMIT, PanZoomHandlers, UseOrbitOptions, UsePanZoomOptions, Vec3, ZoomAtOptions, centerOn, clampPitch, orbitAfterDrag, orbitAfterWheel, screenToWorld, useOrbit, usePanZoom, worldToScreen, wrapYaw, zoomAt } from './canvas/index.js';
13
- export { C as CanvasLayerDescriptor, a as CanvasStackContext, b as CanvasStackContextValue, c as CanvasStackSurface } from './_dts/CanvasStackContext-kTEZvEgE.js';
14
- export { PaletteRegion, PaletteRegionProps, SidebarRegion, SidebarRegionProps, StatusRegion, StatusRegionProps, TitleBarPlacement, TitleBarRegion, TitleBarRegionProps, ToolbarRegion, ToolbarRegionProps, ViewportRegion, ViewportRegionProps, builtinContributions, mergeContributions, suppressContributions } from './chrome/index.js';
15
- import { b as ConfigNode, A as Annotations, N as NodeOptions, c as ControlRenderer, d as ConfigOption, e as ConfigShape, f as ConfigBranch, B as BranchAnnotations, g as BranchOptions, a as ConfigSchema, I as InferConfig, h as ConfigEntry, R as ResolvedConfig, i as ConfigRule, L as LeafPatch, j as ConfigRuleContext } from './_dts/types-B9_zrHmb.js';
16
- export { k as ConfigOf, C as ConfigPath, E as EntryValue, l as NodeValue, S as SectionSpec, V as ValueAtPath } from './_dts/types-B9_zrHmb.js';
17
- import { C as ConfigField } from './_dts/types-x92Kfeme.js';
18
- export { a as CheckboxField, b as ColorField, c as ConfigFieldBase, d as ConfigFieldType, N as NumberField, S as SelectField, e as SelectOption, f as SliderField, T as TextField } from './_dts/types-x92Kfeme.js';
7
+ import { P as PropertyMetricProps, a as PropertyListPack } from './_dts/index-BNdz-tNd.js';
8
+ export { C as CheckboxRow, b as CheckboxRowProps, c as ColorRow, d as ColorRowProps, e as ControlPanel, N as NumberRow, f as NumberRowProps, g as PropertyList, h as PropertyListProps, i as PropertyOption, j as PropertyPanel, k as PropertyPanelProps, l as PropertyRow, m as PropertyRowLayout, n as PropertyRowProps, o as PropertyRowVariant, p as PropertySpan, q as PropertySpanProps, S as SelectRow, r as SelectRowProps, s as SliderRow, t as SliderRowProps, T as TextRow, u as TextRowProps, v as ToggleRow, w as ToggleRowProps } from './_dts/index-BNdz-tNd.js';
9
+ import { DrawCommand, SceneNode, View, Path, FillStyle, StrokeAlign, StyledRun, TextStyle, TextVerticalAlign, Stroke, BuiltinToolId } from '@weasel-js/core';
10
+ import { t as WorldRect, A as AnnotationData, v as AnnotationMeaning, w as MarkScene, x as CaptureSource, y as CaptureOptions, z as CaptureResult, B as AnnotationTarget, E as AnnotationsApi, F as AnnotationsCapability, G as TrialInfo, H as TrialTool, J as AnnotationKind, k as ViewTransform, K as Instrument, q as InstrumentList, o as LabMode, N as TrialContribution, c as StorageAdapter, T as TrialRecord } from './_dts/frac-B4okC2lX.js';
11
+ export { O as Annotation, Q as AnnotationInit, R as AnnotationPatch, X as AnnotationQuery, Y as AnnotationStatus, Z as AnnotationStoreOptions, _ as AnnotationTargetInfo, $ as Auto, a0 as CanvasCapability, a1 as CanvasLayer, a2 as CaptureDeps, a3 as ContributionBase, C as CreateLabStoreOptions, D as DEFAULT_FRAME, n as DragDropCapability, m as DragFeedback, a4 as FracPoint, a5 as FracRect, a6 as HitResult, a7 as IconComponent, a8 as LOUPE_DEFAULTS, L as LabDocument, d as LabStoreState, a9 as LayerCapability, aa as LayerDescriptor, ab as LoupeCapability, ac as LoupeDeclaration, ad as LoupeRenderArgs, P as PaletteItem, l as Point, ae as RegionContribution, af as RenderContext, ag as ResolvedLoupe, e as SavedSnapshot, ah as SerializedAnnotations, S as SerializedTrial, ai as SidebarSection, aj as SidebarSlotContext, ak as StageCapability, al as StatusReadout, f as StorageChange, am as SystemEvent, an as ToolCapability, ao as ToolItem, ap as ToolSlotContext, aq as ToolbarItem, ar as TrialChromeContext, as as TrialRegion, g as TrialStateHandle, at as UndoCapability, U as UndoStack, h as UndockedPanel, i as UndockedPanels, au as ViewportControl, V as ViewportSize, W as WorldFrame, a as WorldSpec, av as annotationsFromJSON, b as applyCamera, aw as auto, ax as createAnnotationScene, ay as createAnnotationStore, j as dockPanel, az as fracContains, aA as fracEncloses, aB as fracToWorld, aC as isAuto, p as panelKey, r as resolveFrame, aD as resolveLoupe, aE as roundFrac, u as undockPanel, aF as worldToFrac } from './_dts/frac-B4okC2lX.js';
12
+ export { C as CanvasStack, a as CanvasStackProps, O as OrbitHandlers, b as OrbitView, P as PITCH_LIMIT, c as PanZoomHandlers, S as Stage, d as StageProps, U as UseOrbitOptions, e as UsePanZoomOptions, V as Vec3, Z as ZoomAtOptions, f as centerOn, g as clampPitch, h as fitStage, o as orbitAfterDrag, i as orbitAfterWheel, s as screenToWorld, u as useOrbit, j as usePanZoom, w as worldToScreen, k as wrapYaw, z as zoomAt } from './_dts/usePanZoom-Pzf9f2jh.js';
13
+ export { C as CanvasLayerDescriptor, a as CanvasStackContext, b as CanvasStackContextValue, c as CanvasStackSurface } from './_dts/CanvasStackContext-CJNMS6mz.js';
14
+ import { L as LabContribution } from './_dts/index-CSJoj4LC.js';
15
+ export { A as AddTrialOptions, a as LabAsideRegion, b as LabChromeContext, c as LabContext, d as LabContextValue, e as LabFooterRegion, f as LabHeaderRegion, g as LabRegion, h as LabRegionProps, i as LabSidebarRegion, P as PaletteRegion, j as PaletteRegionProps, S as SidebarRegion, k as SidebarRegionProps, l as StatusRegion, m as StatusRegionProps, T as TitleBarPlacement, n as TitleBarRegion, o as TitleBarRegionProps, p as ToolbarRegion, q as ToolbarRegionProps, V as ViewportRegion, r as ViewportRegionProps, s as addTrial, t as builtinContributions, u as cloneTrial, v as closeTrial, w as contributionsIn, x as labContributions, y as mergeContributions, z as reorderTrials, B as resetTrial, C as suppressContributions, D as toolContributions, E as useLabChromeContext, F as useLabContext } from './_dts/index-CSJoj4LC.js';
16
+ export { BaseNode, BooleanNode, ColorNode, CustomNode, EnumNode, GroupNode, NumberNode, StringNode, ValueNode, applyRules, autoPathsOf, builtinRules, f, fillConfigDefaults, fromConfigFields, hasConfigPath, isConfigBranch, isLeafVisible, resolveAutoConfig, resolveConfigSchema, schemaNodeAtPath, titleCase, useConfigSchema, useResolvedConfig, valueAtPath, withValueAtPath } from './config/index.js';
17
+ import { b as ConfigSchema, a as ConfigField, c as ConfigRule, d as ControlRenderer } from './_dts/types-DzoNY1pO.js';
18
+ export { A as Annotations, B as BranchAnnotations, e as BranchOptions, f as CheckboxField, g as ColorField, h as ConfigBranch, i as ConfigEntry, j as ConfigFieldBase, k as ConfigFieldType, l as ConfigNode, m as ConfigOf, n as ConfigOption, C as ConfigPath, o as ConfigRuleContext, p as ConfigShape, E as EntryValue, I as InferConfig, L as LeafPatch, N as NodeOptions, q as NodeValue, r as NumberField, R as ResolvedConfig, S as SectionSpec, s as SelectField, t as SelectOption, u as SliderField, T as TextField, V as ValueAtPath } from './_dts/types-DzoNY1pO.js';
19
19
  import { J as JobHandle } from './_dts/types-DJ79Tg5J.js';
20
20
  export { a as JobCapability, b as JobEvent, c as JobFailure, d as JobStatus } from './_dts/types-DJ79Tg5J.js';
21
21
  export { UseJobOptions, useJob } from './job/index.js';
22
22
  export { LayerList, LayerListProps, LayerTreeNode } from './layers/index.js';
23
- export { CanvasLoupe, CanvasLoupeProps, DomLoupe, DomLoupeProps, LensCamera, LoupeBubble, LoupeBubbleProps, LoupeState, SourceRect, TrialLoupe, TrialLoupeProps, UseLoupeOptions, drawCanvasLens, lensCamera, lensSourceRect, sampleStack, useLoupe } from './loupe/index.js';
24
- export { FloatingPanel, FloatingPanelProps, FpsMeter, JobProgress, JobProgressProps, Legend, LegendEntry, LegendMark, LegendProps, ScaleIndicator, ScaleIndicatorProps, Sidebar, SidebarProps, StatusBar, StatusBarProps, StatusBarSectionProps, Toolbar, ToolbarButtonProps, ToolbarGroupProps, ToolbarProps, ZoomControl, ZoomControlProps } from './primitives/index.js';
25
- export { C as CURRENT_DOCUMENT_VERSION, b as LabStoreContext, c as LabStoreProvider, T as TrialIdContext, d as TrialIdProvider, f as createMemoryAdapter, l as labDocumentKey, g as localStorageAdapter, n as noneAdapter, q as quarantineKey, s as sessionStorageAdapter, u as urlHashAdapter, h as useLabStore, i as useTrialId, j as useTrialState } from './_dts/useTrialState-D6Vb3T-g.js';
26
- export { Box, Rect, SurfaceCanvasContext, SurfaceContext, SurfaceFrame, SurfaceHandle, TilePainter, UseTiledSurfaceOptions, composeRects, rectsEqual, toDeviceRect, useSurface, useSurfaceCanvas, useSurfaceOptional, useSurfaceTile, useTileId, useTiledSurface } from './surface/index.js';
23
+ export { CanvasLoupe, CanvasLoupeProps, DomLoupe, DomLoupeProps, LOUPE_MAGNIFY_ID, LOUPE_PEEK_ID, LensCamera, LoupeBubble, LoupeBubbleProps, LoupeGestures, LoupeGesturesProps, LoupeInputApi, LoupeState, SourceRect, TrialLoupe, TrialLoupeProps, UseLoupeOptions, createLoupeActions, drawCanvasLens, lensCamera, lensSourceRect, sampleStack, useLoupe } from './loupe/index.js';
24
+ import { SplitProps } from './primitives/index.js';
25
+ export { FloatingPanel, FloatingPanelProps, FpsMeter, JobProgress, JobProgressProps, Legend, LegendEntry, LegendMark, LegendProps, ScaleIndicator, ScaleIndicatorProps, Sidebar, SidebarProps, Split, StatusBar, StatusBarProps, StatusBarSectionProps, Toolbar, ToolbarButtonProps, ToolbarGroupProps, ToolbarProps, ZoomControl, ZoomControlProps } from './primitives/index.js';
26
+ export { C as CURRENT_DOCUMENT_VERSION, I as IndexedDbAdapterOptions, b as LabStoreContext, c as LabStoreProvider, O as OpenLabStoreOptions, d as OpenedLabStore, P as PersistedStateOptions, e as Persistence, f as PersistenceProps, R as RecordCache, g as RecordChange, T as TrialIdContext, h as TrialIdProvider, i as createIndexedDbAdapter, k as createMemoryAdapter, l as indexedDbAdapter, m as labDocumentKey, n as localStorageAdapter, o as noneAdapter, p as openLabStore, q as quarantineKey, s as sessionStorageAdapter, u as urlHashAdapter, r as useLabStore, t as usePersistedState, v as useTrialId, w as useTrialState } from './_dts/useTrialState-uLlmaccn.js';
27
+ export { Box, Rect, SurfaceCanvasContext, SurfaceCanvases, SurfaceClear, SurfaceContext, SurfaceFrame, SurfaceHandle, SurfaceLayer, TilePainter, UseTiledSurfaceOptions, composeRects, rectsEqual, toDeviceRect, useSurface, useSurfaceCanvas, useSurfaceOptional, useSurfaceTile, useTileId, useTiledSurface } from './surface/index.js';
28
+ import { Theme } from '@weasel-js/theme';
27
29
  export { EventBus, EventListener, clearUndo, createEventBus, emptyStack, pushSnapshot, redo, undo } from './undo/index.js';
28
- import './_dts/PrefsForm.d-DDHFANkc.js';
30
+ import 'react-aria-components';
31
+ import './_dts/PrefsForm.d-DPy9I8It.js';
29
32
  import 'windease';
30
33
  import 'zustand/vanilla';
31
34
 
35
+ declare const ResetIcon: (p: IconProps) => react_jsx_runtime.JSX.Element;
36
+ declare const CloseIcon: (p: IconProps) => react_jsx_runtime.JSX.Element;
37
+ declare const PlayIcon: (p: IconProps) => react_jsx_runtime.JSX.Element;
38
+ declare const PauseIcon: (p: IconProps) => react_jsx_runtime.JSX.Element;
39
+ declare const StopIcon: (p: IconProps) => react_jsx_runtime.JSX.Element;
40
+ declare const StepBackIcon: (p: IconProps) => react_jsx_runtime.JSX.Element;
41
+ declare const StepForwardIcon: (p: IconProps) => react_jsx_runtime.JSX.Element;
42
+ declare const CollapseIcon: (p: IconProps) => react_jsx_runtime.JSX.Element;
43
+ declare const ExpandIcon: (p: IconProps) => react_jsx_runtime.JSX.Element;
44
+
32
45
  /** An annotation drawn over a curve plot: a shaded band across a range of x,
33
46
  * or a vertical line at one x. */
34
47
  type CurveMark = {
@@ -169,6 +182,81 @@ interface PropertyGroupProps extends PropertyMetricProps {
169
182
  */
170
183
  declare function PropertyGroup({ title, hidden, collapsible, defaultCollapsed, collapsed, onCollapsedChange, children, className, pack, density, align, }: PropertyGroupProps): react_jsx_runtime.JSX.Element | null;
171
184
 
185
+ /** A design token as `TokenPanel` edits it. */
186
+ interface TokenEntry {
187
+ /** The custom property, e.g. `--wzl-gray-50`. */
188
+ name: string;
189
+ /** A DTCG type name. A type the panel has no control for edits as text. */
190
+ type: string;
191
+ /** Tokens sharing a group sit together; a color group large enough draws as one row of swatches. */
192
+ group: string;
193
+ value: string;
194
+ /** Whether `value` overrides the token's own, which offers Reset. */
195
+ overridden?: boolean;
196
+ description?: string;
197
+ }
198
+ type TokenCategory = 'color' | 'type' | 'size' | 'motion' | 'depth' | 'other';
199
+ /** A DTCG type read off the shape of a value, for a token that arrives without one. `'string'` when nothing fits. */
200
+ declare function inferTokenType(value: string): string;
201
+
202
+ type OnChange = (name: string, value: string | null) => void;
203
+ /** Props for `<TokenPanel>`. */
204
+ interface TokenPanelProps {
205
+ tokens: readonly TokenEntry[];
206
+ /** A token's new value, or null to drop its override. Keep it stable: rows re-render only when it or their token changes. */
207
+ onChange: OnChange;
208
+ /** Sections held closed, by category. Omit to let the panel keep that state itself. */
209
+ collapsed?: Readonly<Partial<Record<TokenCategory, boolean>>>;
210
+ onCollapsedChange?: (category: TokenCategory, collapsed: boolean) => void;
211
+ /** Files a token under a section. Defaults to `tokenCategory`. */
212
+ categorize?: (token: TokenEntry) => TokenCategory;
213
+ /** The fewest colors sharing a group that draw as one row of swatches. Default 3. */
214
+ familySize?: number;
215
+ /**
216
+ * Row layout. `tight` puts a token on one line — name, control, Reset — with the
217
+ * names on a fixed rail so the values read down the panel as a column, and caps
218
+ * the field rather than letting it span the panel. Default `normal` stacks the
219
+ * control under its name.
220
+ */
221
+ density?: 'tight' | 'normal';
222
+ className?: string;
223
+ }
224
+ /**
225
+ * Edits a set of design tokens by type: collapsible sections by category, a
226
+ * color group drawn as one row of swatches sized to fit, and a control for each
227
+ * type — a number with its unit for dimensions and durations, the nine weights
228
+ * for a font weight, a curve beside a `cubic-bezier()`, a swatch beside a color,
229
+ * and text for everything else.
230
+ */
231
+ declare function TokenPanel({ tokens, onChange, collapsed, onCollapsedChange, categorize, familySize, density, className, }: TokenPanelProps): react_jsx_runtime.JSX.Element;
232
+
233
+ /** Props for {@link Jog}. */
234
+ interface JogProps {
235
+ /** Which step is showing, 0-based. */
236
+ index: number;
237
+ /** How many steps there are. */
238
+ count: number;
239
+ playing: boolean;
240
+ onPlay: (playing: boolean) => void;
241
+ /** Move one step, back or forward. */
242
+ onStep: (by: -1 | 1) => void;
243
+ /** Jump to a step. Left out, no scrubber is drawn. */
244
+ onScrub?: (index: number) => void;
245
+ /** What one step is called, for the spoken labels. Defaults to `Step`. */
246
+ unit?: string;
247
+ /** Drawn after the readout — a beat's caption, a snapshot's date. */
248
+ caption?: ReactNode;
249
+ className?: string;
250
+ }
251
+ /**
252
+ * Transport for something counted rather than timed: beat 3 of 24, not 4.20s of 12.00s.
253
+ * `<Transport>` is the continuous-time one, and wants a playhead in milliseconds, a rate and
254
+ * a loop, none of which a list of steps has.
255
+ *
256
+ * Named for the jog of jog/shuttle — moving one frame at a time, as against running at speed.
257
+ */
258
+ declare function Jog(props: JogProps): react_jsx_runtime.JSX.Element;
259
+
172
260
  /** The subset of a mark's scene node this needs: where it is, and what it is. */
173
261
  interface PaintableMark {
174
262
  pose: WorldRect;
@@ -177,7 +265,7 @@ interface PaintableMark {
177
265
  /** How a mark is drawn, as opposed to where. Resolved by the overlay from the
178
266
  * instrument's vocabulary and the mark's own staleness. */
179
267
  interface MarkStyle {
180
- /** The status's colour, or the default. */
268
+ /** The status's color, or the default. */
181
269
  color?: string;
182
270
  /** A mark whose stored position no longer describes the picture. Drawn
183
271
  * dashed rather than hidden: it still describes *something*, and dropping
@@ -207,14 +295,14 @@ interface MarkDrawOptions {
207
295
  positionDependsOn?: readonly string[];
208
296
  /** The trial's config at the time of the draw. */
209
297
  config: unknown;
210
- /** The instrument's vocabulary, for a status's colour. */
298
+ /** The instrument's vocabulary, for a status's color. */
211
299
  meaning?: AnnotationMeaning;
212
300
  }
213
301
  /**
214
302
  * How one mark is drawn — shared by the pane on screen and by an export.
215
303
  *
216
304
  * One function rather than two call sites building their own, because an
217
- * export that resolves a status colour or a stale dash differently from the
305
+ * export that resolves a status color or a stale dash differently from the
218
306
  * screen produces a picture nobody was looking at.
219
307
  */
220
308
  declare function createMarkDrawOne(opts: MarkDrawOptions): (node: SceneNode<AnnotationData, 'marks', WorldRect>, pose: WorldRect, view: View) => DrawCommand[];
@@ -396,6 +484,10 @@ interface SvgStroke {
396
484
  * attribute may render with longer miters than the source SVG intended.
397
485
  */
398
486
  miterLimit?: number;
487
+ /** The kit stroke's `align`. SVG has no stroke alignment, so the serializer
488
+ * writes the stroke centered and says so through `onWarn`; the parser
489
+ * never sets it. */
490
+ align?: StrokeAlign;
399
491
  /** `marker-start` / `marker-mid` / `marker-end`, as the bare `url(#id)` key. */
400
492
  markerStart?: string;
401
493
  markerMid?: string;
@@ -431,6 +523,12 @@ interface SvgGroupNode {
431
523
  kind: 'group';
432
524
  children: SvgNode[];
433
525
  transform?: Matrix;
526
+ /** Clips the group's contents. Serializes to a `<clipPath>` def plus
527
+ * `clip-path="url(#id)"`, and lives in the same space as `children` —
528
+ * SVG applies the group's own `transform` to the clip as well.
529
+ * A `<clipPath>` of more than one shape parses back as no clip: SVG
530
+ * unions them and a `Path` holds one outline. */
531
+ clip?: Path;
434
532
  opacity?: number;
435
533
  /** Opaque per-element bag for declared namespaces. See `NamespaceMeta`. */
436
534
  meta?: NamespaceMeta;
@@ -445,9 +543,12 @@ interface SvgGroupNode {
445
543
  * `dominant-baseline="text-before-edge"` so `y` is the top of the text
446
544
  * box, plus `data-weasel-width` / `data-weasel-height` so weasel's
447
545
  * explicit box dimensions round-trip losslessly. External SVG text
448
- * (lacking the data-* attrs) imports with estimated dimensions —
449
- * {@link UNBOUNDED_TEXT_WIDTH} and
546
+ * (lacking the data-* attrs) imports with the width the kit's text layout
547
+ * measures — an em-based estimate when no registered font can — and
450
548
  * `height = fontSize * lineHeight * (lineCount || 1)`.
549
+ *
550
+ * `x` here is always the box's left edge. In the SVG it is the
551
+ * `text-anchor` point, and the parser and serializer convert between them.
451
552
  */
452
553
  interface SvgTextNode {
453
554
  kind: 'text';
@@ -461,6 +562,10 @@ interface SvgTextNode {
461
562
  runs?: StyledRun[];
462
563
  /** Node-wide typography. Defaults applied at render time via `resolveTextStyle`. */
463
564
  style?: TextStyle;
565
+ /** Where the laid-out text sits inside the box — `kit:text`'s
566
+ * `data.verticalAlign`. SVG text has no box to align in, so this rides in
567
+ * `data-weasel-vertical-align` and other readers draw the text top-aligned. */
568
+ verticalAlign?: TextVerticalAlign;
464
569
  /**
465
570
  * Node-wide glyph paint, the `FillStyle` / `Stroke` a kit text node holds
466
571
  * in `data.fill` / `data.stroke`. Not `SvgPaint`, which is the path
@@ -488,6 +593,12 @@ interface SvgTextNode {
488
593
  * a reference and only resolves when something downstream loads it.
489
594
  *
490
595
  * SVG's `preserveAspectRatio` is not modeled; the box is taken literally.
596
+ *
597
+ * With a `source` rect or a flip, the element is written as a `<g
598
+ * data-weasel-image>` holding a nested `<svg>` viewport at the box, whose
599
+ * `viewBox` is the source window over a unit-square `<image>` — plain SVG 1.1,
600
+ * which any reader crops and mirrors the same way, and which `parseSvg` reads
601
+ * back as one image node.
491
602
  */
492
603
  interface SvgImageNode {
493
604
  kind: 'image';
@@ -496,6 +607,20 @@ interface SvgImageNode {
496
607
  y: number;
497
608
  width: number;
498
609
  height: number;
610
+ /** The part of the bitmap drawn into the box, as fractions of the bitmap's
611
+ * width and height from its top-left. Omitted draws the whole bitmap.
612
+ * Fractions rather than bitmap pixels because this package never decodes
613
+ * the image, so it cannot know its size. */
614
+ source?: {
615
+ x: number;
616
+ y: number;
617
+ width: number;
618
+ height: number;
619
+ };
620
+ /** Mirror the drawn region within the box, as `ImageDrawCommand` does. The
621
+ * box does not move. */
622
+ flipX?: boolean;
623
+ flipY?: boolean;
499
624
  /** Element-level opacity (`opacity="..."`), 0..1. */
500
625
  opacity?: number;
501
626
  /** Element-level rotation in **radians**, pivoting around the unrotated
@@ -530,7 +655,7 @@ interface AnnotationOverlayProps {
530
655
  config: unknown;
531
656
  /** The trial's resolved tool slot. */
532
657
  activeToolId: string | null;
533
- /** The instrument's vocabulary, for a status's colour. */
658
+ /** The instrument's vocabulary, for a status's color. */
534
659
  meaning?: AnnotationMeaning;
535
660
  }
536
661
  /**
@@ -575,9 +700,9 @@ interface AnnotationToolInfo {
575
700
  weaselTool: BuiltinToolId;
576
701
  kind?: AnnotationKind;
577
702
  }
578
- /** The palette an instrument gets for declaring `annotations`. Ids share the
579
- * trial's contribution namespace with `instrument.tools`, and one tool slot
580
- * holds whichever is active. */
703
+ /** The tools a lab's rail gets when any instrument declares `annotations`.
704
+ * Ids share the lab's contribution namespace with its own `tools`, and the
705
+ * lab's tool slot holds whichever is active. */
581
706
  declare const ANNOTATION_TOOLS: readonly TrialTool[];
582
707
  /** What `id` drives, or undefined for a tool that is not one of these. */
583
708
  declare function annotationToolInfo(id: string | null): AnnotationToolInfo | undefined;
@@ -610,226 +735,6 @@ declare function fromWeaselView(v: View): ViewTransform;
610
735
  */
611
736
  declare function fitView(content: ContentSize, pane: PaneSize): ViewTransform;
612
737
 
613
- /** Whether a schema entry is a branch rather than a leaf. */
614
- declare function isConfigBranch(entry: ConfigEntry): entry is ConfigBranch;
615
- /** Shared chaining surface. Every method clones, so a node can be reused as a
616
- * base for several leaves without one bleeding into the next. */
617
- declare abstract class BaseNode<T> implements ConfigNode<T> {
618
- readonly annotations: Readonly<Annotations>;
619
- readonly options: Readonly<NodeOptions>;
620
- abstract readonly kind: string | null;
621
- readonly default: T;
622
- constructor(defaultValue: T, annotations?: Readonly<Annotations>, options?: Readonly<NodeOptions>);
623
- /** Clone into the same subclass. Subclasses with extra constructor
624
- * arguments override this. */
625
- protected with(annotations: Annotations, options: NodeOptions): this;
626
- protected ann(patch: Annotations): this;
627
- protected opt(patch: NodeOptions): this;
628
- /** Human-readable label. Defaults to the key, title-cased. */
629
- label(name: string): this;
630
- /** Longer help text, surfaced as a tooltip on the row label. */
631
- describe(description: string): this;
632
- /** Omit from the panel unless it is asked to show hidden leaves. */
633
- hidden(): this;
634
- /** Pair with a sibling sharing this id, side-by-side on one row. */
635
- pair(pair: string): this;
636
- /** Render under a named section heading. `collapsed` opens the section
637
- * folded — say it on any one of the section's leaves. */
638
- section(label: string, opts?: {
639
- collapsed?: boolean;
640
- }): this;
641
- /** Show this row only while the predicate holds. Presentational — the value
642
- * stays in config and the instrument still reads it. */
643
- showIf(predicate: (config: Record<string, unknown>) => boolean): this;
644
- /** Draw this one row yourself, keeping the kind, default and validation. */
645
- render(renderer: ControlRenderer): this;
646
- }
647
- declare class NumberNode extends BaseNode<number> {
648
- readonly kind = "number";
649
- /** Bound the value. A number with both bounds renders as a slider. */
650
- range(min: number, max: number): this;
651
- step(step: number): this;
652
- /** A display suffix for the value — `'px'`, `'ms'`, `'°'`. Presentation only:
653
- * it is never parsed, and the stored value stays a plain number. */
654
- suffix(suffix: string): this;
655
- /** Force a slider even without both bounds. */
656
- slider(): this;
657
- /** Force a typed input even when both bounds are set. */
658
- input(): this;
659
- }
660
- declare class BooleanNode extends BaseNode<boolean> {
661
- readonly kind = "boolean";
662
- /** Ask for a switch. `ControlPanel` still draws a checkbox; weasel-ui's
663
- * `PrefsForm` honors the distinction. */
664
- toggle(): this;
665
- }
666
- declare class StringNode extends BaseNode<string> {
667
- readonly kind = "string";
668
- placeholder(placeholder: string): this;
669
- maxLength(maxLength: number): this;
670
- /** Milliseconds to debounce live writes. 0 commits every keystroke. */
671
- debounce(debounceMs: number): this;
672
- }
673
- declare class ColorNode extends BaseNode<string> {
674
- readonly kind = "color";
675
- }
676
- declare class EnumNode<T extends string> extends BaseNode<T> {
677
- readonly kind = "enum";
678
- /** Render as a segmented control rather than a select. */
679
- radio(): this;
680
- /** Relabel the choices. Named `labels` rather than `options` because
681
- * `options` is the node's own extras bag. */
682
- labels(options: readonly ConfigOption[]): this;
683
- }
684
- /** A leaf whose kind the rule chain decides. */
685
- declare class ValueNode<T> extends BaseNode<T> {
686
- readonly kind: null;
687
- }
688
- /** A leaf of a kind labkit does not ship a row for. */
689
- declare class CustomNode<T> extends BaseNode<T> {
690
- readonly kind: string;
691
- constructor(kind: string, defaultValue: T, annotations?: Readonly<Annotations>, options?: Readonly<NodeOptions>);
692
- protected with(annotations: Annotations, options: NodeOptions): this;
693
- }
694
- /**
695
- * A branch of the schema: its children nest under its key, so a leaf inside
696
- * one is read and written at a dotted path. Distinct from `.section()`, which
697
- * puts a heading over sibling leaves and leaves their paths alone.
698
- */
699
- declare class GroupNode<S extends ConfigShape> implements ConfigBranch<S> {
700
- readonly children: S;
701
- readonly annotations: Readonly<BranchAnnotations>;
702
- readonly options: Readonly<BranchOptions>;
703
- constructor(children: S, annotations?: Readonly<BranchAnnotations>, options?: Readonly<BranchOptions>);
704
- private with;
705
- /** Heading for the group's rows. Defaults to the key, title-cased. */
706
- label(name: string): GroupNode<S>;
707
- /** Longer help text. Carried on the resolved `PrefGroup`, where weasel-ui's
708
- * `PrefsForm` draws it under the heading; `ControlPanel` has no place for
709
- * it yet and shows the heading alone. */
710
- describe(description: string): GroupNode<S>;
711
- /** Render this whole group under a named section heading. */
712
- section(label: string, opts?: {
713
- collapsed?: boolean;
714
- }): GroupNode<S>;
715
- /** Show this group only while the predicate holds. Presentational — every
716
- * value beneath it stays in config and the instrument still reads it. */
717
- showIf(predicate: (config: Record<string, unknown>) => boolean): GroupNode<S>;
718
- }
719
- /**
720
- * Builds an instrument's config: the values, their types, and how each is
721
- * edited, in one declaration.
722
- *
723
- * ```ts
724
- * const config = f.schema({
725
- * showGrid: f.boolean(true),
726
- * cellSize: f.number(20).range(5, 80).step(5).label('Grid spacing'),
727
- * // Nested: read and written at `grid.color`.
728
- * grid: f.group({ color: f.color('#ffffff') }),
729
- * })
730
- * ```
731
- */
732
- declare const f: {
733
- number: (def: number) => NumberNode;
734
- boolean: (def: boolean) => BooleanNode;
735
- string: (def: string) => StringNode;
736
- color: (def: string) => ColorNode;
737
- /** A fixed set of choices. The default's literal type flows into the config
738
- * type, so `f.enum('fast', ['fast', 'accurate'])` gives
739
- * `'fast' | 'accurate'` with no `as const`. */
740
- enum: <const T extends string>(def: T, options: readonly T[] | readonly ConfigOption[]) => EnumNode<T>;
741
- /** A leaf with no declared kind: the rule chain decides, which is how a lab
742
- * states a convention like "every `*Color` key is a color picker". */
743
- value: <T>(def: T) => ValueNode<T>;
744
- /** A branch: its children nest under this key, so `grid: f.group({ size })`
745
- * puts the value at `config.grid.size` and addresses it as `'grid.size'`.
746
- * Groups nest as deeply as the schema wants. */
747
- group: <const S extends ConfigShape>(children: S) => GroupNode<S>;
748
- /** A leaf of a kind a lab supplies the control for, through `controls`. */
749
- custom: <T>(kind: string, def: T, validate?: (leaf: ToolPrefLeaf) => string[]) => CustomNode<T>;
750
- /** Collect leaves and groups into an instrument's config. */
751
- schema<S extends ConfigShape>(nodes: S): ConfigSchema<InferConfig<S>>;
752
- };
753
-
754
- /**
755
- * Adapt a legacy `configSchema(): ConfigField[]` into the resolved shape, so
756
- * both instrument paths reach one renderer.
757
- *
758
- * Rules do not run here: a hand-written `ConfigField` already states its label
759
- * and control, which is everything the rule chain would have inferred.
760
- */
761
- declare function fromConfigFields(fields: readonly ConfigField[]): ResolvedConfig;
762
-
763
- /** The value at a dotted path. `undefined` when a segment is missing or the
764
- * walk hits something that is not a record. */
765
- declare function valueAtPath(config: unknown, path: string): unknown;
766
- /** Whether a dotted path is actually present, which a `undefined` value is
767
- * not enough to tell you. */
768
- declare function hasConfigPath(config: unknown, path: string): boolean;
769
- /** A copy of `config` with `value` written at a dotted path. Every record on
770
- * the way down is copied and the input is left alone; a missing — or
771
- * non-record — intermediate is replaced with the branch the path implies. */
772
- declare function withValueAtPath<T>(config: T, path: string, value: unknown): T;
773
- /**
774
- * `stored` with every gap filled from `defaults`, down the whole tree.
775
- *
776
- * This is how a config written before its schema grew a branch still loads:
777
- * the branch arrives at its defaults instead of `undefined`, and a key the
778
- * defaults no longer mention is kept rather than dropped, so nothing is lost
779
- * to a schema change the author has not finished making.
780
- */
781
- declare function fillConfigDefaults<T>(stored: unknown, defaults: T): T;
782
- /** A node in a resolved schema tree, by dotted path. Structural rather than
783
- * `isPrefLeaf` so this stays free of a runtime import. */
784
- declare function schemaNodeAtPath(group: ToolPrefGroup, path: string): ToolPrefLeaf | ToolPrefGroup | undefined;
785
-
786
- /**
787
- * Resolve a schema into the vocabulary weasel-ui renders, running each leaf
788
- * through the consumer's rules and then labkit's own.
789
- *
790
- * The group mirrors the schema's own nesting: an `f.group` becomes a nested
791
- * `PrefGroup`, so a leaf's dotted path within the tree is the path its value
792
- * is written at, and both `ControlPanel` and `PrefsForm` address it
793
- * identically.
794
- */
795
- declare function resolveConfigSchema<TC>(schema: ConfigSchema<TC>, rules?: readonly ConfigRule[]): ResolvedConfig;
796
-
797
- /** `cellSize` -> `Cell size`. Splits camelCase without shattering acronyms. */
798
- declare function titleCase(key: string): string;
799
- /**
800
- * labkit's own inference, expressed in the same vocabulary a consumer
801
- * extends. Runs after the consumer's rules, so a lab always wins.
802
- *
803
- * If one of these ever needs something a `ConfigRule` cannot express, the
804
- * seam is too weak — that is the point of writing them this way.
805
- */
806
- declare const builtinRules: readonly ConfigRule[];
807
- /**
808
- * Fold a rule chain into one leaf patch. Gap-filling: a property already
809
- * settled is never overwritten, so the accumulator seeded with the author's
810
- * annotations beats every rule, and earlier rules beat later ones.
811
- */
812
- declare function applyRules(seed: LeafPatch, ctx: Omit<ConfigRuleContext, 'leaf'>, rules: readonly ConfigRule[]): LeafPatch;
813
-
814
- /**
815
- * An instrument's controls, resolved against the surrounding lab's rules.
816
- *
817
- * Resolution cannot happen in `defineInstrument` — rules are lab-scoped and
818
- * that runs at module load — so it happens here, at render. Both instrument
819
- * paths land in the same shape, so callers never branch on which was used.
820
- */
821
- declare function useConfigSchema(instrument: Instrument<any, any, any>): ResolvedConfig;
822
-
823
- /**
824
- * Whether the row at a dotted path should be drawn right now. A group answers
825
- * for its whole subtree — hiding one hides everything under it.
826
- *
827
- * `hidden` is the node's own static flag; `showIf` is the schema's predicate
828
- * over the live config. Both are presentational — a hidden leaf keeps its
829
- * value and the instrument still reads it.
830
- */
831
- declare function isLeafVisible(resolved: ResolvedConfig, path: string, config: Record<string, unknown>, showHidden?: boolean): boolean;
832
-
833
738
  /** An instrument as it is written: either the legacy `defaultConfig` (plus an
834
739
  * optional `configSchema`), or a `config` schema that supplies both. */
835
740
  type InstrumentSpec<TS, TC, TItem = unknown> = Instrument<TS, TC, TItem> | (Omit<Instrument<TS, TC, TItem>, 'defaultConfig'> & {
@@ -868,13 +773,50 @@ interface ValidationResult {
868
773
  * a field simply has no constraints to check here. */
869
774
  declare function validateConfigSchema(fields: ConfigField[]): ValidationResult;
870
775
 
871
- /** Props for `<Lab>`. */
872
- interface LabProps {
776
+ /** One page in a project's set of labs. */
777
+ interface LabPage {
778
+ /** The page's own URL, and how the switcher knows which page is open. */
779
+ href: string;
780
+ label: string;
781
+ }
782
+ /** Props for `<LabSwitcher>`. */
783
+ interface LabSwitcherProps {
784
+ /** The open page's title, shown as the control's own label. */
785
+ title: string;
786
+ pages: readonly LabPage[];
787
+ /** Defaults to the current location. Pass it in tests, or to render a
788
+ * switcher for a page other than the one being viewed. */
789
+ path?: string;
790
+ className?: string;
791
+ }
792
+ /** Which of `pages` a path is on, or -1.
793
+ *
794
+ * Matched on the end of the path so a query string, a trailing slash or a
795
+ * leftover `.html` cannot lose it: a project whose dev server maps `/stats`
796
+ * to `stats.html` serves both spellings, and a bookmark from before the URLs
797
+ * lost their extension still resolves to the same page. */
798
+ declare function currentPage(path: string, pages: readonly LabPage[]): number;
799
+ /** A project's lab title, doubling as the way to reach its other labs.
800
+ *
801
+ * The menu holds real anchors, not a `<select>` and not buttons. These are
802
+ * separate documents, so an `href` is what gets middle-click, cmd-click and
803
+ * the back button for free; a select fires a change event and can do none of
804
+ * the three. The trigger is a button because it opens something rather than
805
+ * going anywhere.
806
+ *
807
+ * Pages accumulate -- a project grows a wall, a dashboard, an ingest page, a
808
+ * bench -- and a tab strip is the layout that stops working first. */
809
+ declare function LabSwitcher({ title, pages, path, className }: LabSwitcherProps): react_jsx_runtime.JSX.Element;
810
+
811
+ interface LabBaseProps {
812
+ /** May change while mounted. An instrument that is a different object from
813
+ * the last render counts as replaced and its open trials' configs are
814
+ * refilled, so hoist or memoize the list. */
873
815
  instruments: InstrumentList;
874
816
  defaultInstrument: string;
875
- storage?: StorageAdapter | null;
876
- storageKey?: string;
877
817
  mode?: LabMode;
818
+ /** Rendered while a stored lab loads. Default: the lab's empty shell. */
819
+ fallback?: ReactNode;
878
820
  /**
879
821
  * Optional list of CSS colors used to compose the interstellar theme's
880
822
  * cosmic backdrop. Each color becomes one radial-gradient blob on the
@@ -883,12 +825,27 @@ interface LabProps {
883
825
  */
884
826
  nebula?: readonly string[];
885
827
  title?: string;
828
+ /** The project's other labs. Given two or more, the title becomes the way to
829
+ * reach them — the same switcher `<LabShell>` renders, so a lab reached from
830
+ * one is not a dead end. */
831
+ pages?: readonly LabPage[];
832
+ /** The path the switcher marks as open. Defaults to the current location. */
833
+ path?: string;
886
834
  /** Rendered in the shell's footer, below the workspace. */
887
835
  footer?: ReactNode;
888
836
  /** Contributions added to every trial's chrome, after the instrument's own. */
889
837
  chrome?: readonly TrialContribution[];
838
+ /** Contributions to the lab's own chrome — its header bar, its sidebar, its
839
+ * tool rail and its footer — rather than to every trial's. Rendered after
840
+ * `children` and `footer`, which stay the way a lab drops arbitrary content
841
+ * into those same two boxes. Going from no sidebar contributions to some
842
+ * remounts the workspace and every trial, dropping unpersisted trial state. */
843
+ labChrome?: readonly LabContribution[];
890
844
  /** Built-in contribution ids to drop. Throws on an id that is not there. */
891
845
  suppress?: readonly string[];
846
+ /** Offer the header's add-trial control. Default `true`; a lab that opens
847
+ * trials some other way passes `false`. */
848
+ addTrial?: boolean;
892
849
  /** Tools offered lab-wide. A trial whose instrument declares none of its own
893
850
  * reflects and writes this slot. */
894
851
  tools?: readonly TrialTool[];
@@ -901,110 +858,51 @@ interface LabProps {
901
858
  controls?: Record<string, ControlRenderer>;
902
859
  children?: ReactNode;
903
860
  }
904
- /** The lab runtime: creates the store, provides it, and renders one trial
861
+ /** Props for `<Lab>`. With a `storageKey` the lab persists — to IndexedDB
862
+ * unless `storage` names another substrate — and both are read once, at
863
+ * mount. Without one, nothing persists. */
864
+ type LabProps = LabBaseProps & ({
865
+ storageKey?: undefined;
866
+ storage?: undefined;
867
+ } | {
868
+ storageKey: string;
869
+ storage?: StorageAdapter;
870
+ });
871
+ /** The lab runtime: opens the store, provides it, and renders one trial
905
872
  * per record in a grid. Each trial runs one of `instruments`. */
906
- declare function Lab({ instruments, defaultInstrument, storage, storageKey, mode, nebula, title, footer, chrome, suppress, tools, configRules, controls, children, }: LabProps): react_jsx_runtime.JSX.Element;
907
-
908
- /** What a trial opens on beyond its instrument's own defaults. */
909
- interface AddTrialOptions<TC = Record<string, unknown>> {
910
- /** Overlaid on `defaultConfig()` before `initialState` reads it, so a trial
911
- * opened on a subject is running that subject from its first frame. Keys
912
- * whose value is `undefined` are left to the default. */
913
- config?: Partial<TC>;
914
- }
915
- /** Append a new trial running `instrumentName`, at that instrument's default
916
- * config — with `options.config` written over it — and the initial state
917
- * that config produces. */
918
- declare function addTrial(trials: TrialRecord[], instruments: InstrumentList, instrumentName: string, options?: AddTrialOptions): TrialRecord[];
919
- /** Insert a deep copy of a trial directly after it. The copy starts with
920
- * an empty undo history — the original's is not shared. */
921
- declare function cloneTrial(trials: TrialRecord[], id: string): TrialRecord[];
922
- /** Remove a trial, unless it is the last one — a lab always has at least
923
- * one. */
924
- declare function closeTrial(trials: TrialRecord[], id: string): TrialRecord[];
925
- /** Return a trial to what it opened on — its instrument's defaults under the
926
- * seed `addTrial` was given — keeping its id and its place in the list. */
927
- declare function resetTrial(trials: TrialRecord[], id: string, instruments: InstrumentList): TrialRecord[];
928
- /**
929
- * Reorder to match `ids`. Ids the list doesn't mention keep their relative
930
- * order at the end, and ids it names that no longer exist are dropped — a
931
- * reorder that raced a close should not resurrect the closed trial.
932
- */
933
- declare function reorderTrials(trials: TrialRecord[], ids: readonly string[]): TrialRecord[];
934
-
935
- /** Lab-wide state and commands: the available instruments, the open
936
- * trials and the operations over them, saved snapshots, and the color
937
- * mode. */
938
- interface LabContextValue {
939
- instruments: InstrumentList;
940
- trials: TrialRecord[];
941
- /** Open a trial running `instrumentName`. `options.config` is written over
942
- * that instrument's defaults, which is where a trial opened on a subject
943
- * says which subject. */
944
- addTrial: (instrumentName: string, options?: AddTrialOptions) => void;
945
- cloneTrial: (id: string) => void;
946
- closeTrial: (id: string) => void;
947
- resetTrial: (id: string) => void;
948
- reorderTrials: (ids: readonly string[]) => void;
949
- savedSnapshots: SavedSnapshot[];
950
- saveSnapshot: (trialId: string, name?: string) => void;
951
- loadSnapshot: (trialId: string, snapshotId: string) => void;
952
- deleteSnapshot: (snapshotId: string) => void;
953
- mode: LabMode;
954
- setMode: (m: LabMode) => void;
955
- /** Lab-wide rules run over every instrument's config leaves, before
956
- * labkit's own inference. */
957
- configRules?: readonly ConfigRule[];
958
- /** Lab-wide control overrides, keyed by config path or by leaf kind. */
959
- controls?: Record<string, ControlRenderer>;
960
- }
961
- /** Context carrying the surrounding lab. Prefer `useLabContext`. */
962
- declare const LabContext: react.Context<LabContextValue | null>;
963
- /** The surrounding lab. Throws outside a `<Lab>`. */
964
- declare function useLabContext(): LabContextValue;
873
+ declare function Lab(props: LabProps): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null;
965
874
 
966
875
  /** Props for `<LabPalette>`. */
967
876
  interface LabPaletteProps {
968
- tools: readonly TrialTool[];
877
+ /** Tools offered lab-wide. Shorthand for one `palette` contribution each. */
878
+ tools?: readonly TrialTool[];
879
+ /** The lab's contributions; the `palette` ones are laid out here. */
880
+ contributions?: readonly LabContribution[];
969
881
  }
970
- /** The lab's tool strip. Writes the lab's tool slot, which every trial whose
971
- * instrument declares no tools of its own resolves to. */
972
- declare function LabPalette({ tools }: LabPaletteProps): react_jsx_runtime.JSX.Element;
882
+ /** The lab's tool rail. Writes the lab's tool slot, which every trial whose
883
+ * instrument declares no tools of its own resolves to. Renders nothing when
884
+ * the lab contributes no tool rail. */
885
+ declare function LabPalette({ tools, contributions }: LabPaletteProps): react_jsx_runtime.JSX.Element;
973
886
 
974
- /** One page in a project's set of labs. */
975
- interface LabPage {
976
- /** The page's own URL, and how the switcher knows which page is open. */
977
- href: string;
978
- label: string;
979
- }
980
- /** Props for `<LabSwitcher>`. */
981
- interface LabSwitcherProps {
982
- /** The open page's title, shown as the control's own label. */
983
- title: string;
984
- pages: readonly LabPage[];
985
- /** Defaults to the current location. Pass it in tests, or to render a
986
- * switcher for a page other than the one being viewed. */
987
- path?: string;
887
+ /** Props for `<LabRoot>`. */
888
+ interface LabRootProps {
889
+ children: ReactNode;
890
+ /** Color mode. "auto" (default) follows prefers-color-scheme. */
891
+ mode?: LabMode;
892
+ /** Added after `lk-root` on the same element. */
988
893
  className?: string;
989
894
  }
990
- /** Which of `pages` a path is on, or -1.
895
+ /** The element every labkit component expects above it: `.lk-root`, which
896
+ * carries the design tokens, the font stack, the box-sizing reset and the
897
+ * element defaults a lab's bare markup is styled by, plus a theme when the
898
+ * app has not already applied one.
991
899
  *
992
- * Matched on the end of the path so a query string, a trailing slash or a
993
- * leftover `.html` cannot lose it: a project whose dev server maps `/stats`
994
- * to `stats.html` serves both spellings, and a bookmark from before the URLs
995
- * lost their extension still resolves to the same page. */
996
- declare function currentPage(path: string, pages: readonly LabPage[]): number;
997
- /** A project's lab title, doubling as the way to reach its other labs.
998
- *
999
- * The menu holds real anchors, not a `<select>` and not buttons. These are
1000
- * separate documents, so an `href` is what gets middle-click, cmd-click and
1001
- * the back button for free; a select fires a change event and can do none of
1002
- * the three. The trigger is a button because it opens something rather than
1003
- * going anywhere.
1004
- *
1005
- * Pages accumulate -- a project grows a wall, a dashboard, an ingest page, a
1006
- * bench -- and a tab strip is the layout that stops working first. */
1007
- declare function LabSwitcher({ title, pages, path, className }: LabSwitcherProps): react_jsx_runtime.JSX.Element;
900
+ * `<LabShell>` and `<Lab>` render this themselves. Mount it by hand around a
901
+ * labkit piece used on its own — a bare `<Workspace>` or `<ControlPanel>` —
902
+ * or those components inherit whatever the host page happens to define.
903
+ * Pair it with `import '@weasel-js/labkit/styles.css'`, which is what defines
904
+ * the rules this element scopes. */
905
+ declare function LabRoot({ children, mode, className }: LabRootProps): react_jsx_runtime.JSX.Element;
1008
906
 
1009
907
  /** Props for `<LabShell>`. */
1010
908
  interface LabShellProps {
@@ -1026,7 +924,7 @@ interface LabShellProps {
1026
924
  /** Page frame for a lab: a titled header, a body, and an optional footer,
1027
925
  * themed for the resolved color mode. Presentational only — use `<Lab>` when
1028
926
  * the trial runtime is wanted too. */
1029
- declare function LabShell({ title, children, header, footer, mode, pages, path }: LabShellProps): react_jsx_runtime.JSX.Element;
927
+ declare function LabShell({ title, children, header, footer, mode, pages, path, }: LabShellProps): react_jsx_runtime.JSX.Element;
1030
928
 
1031
929
  /** A tile's persisted extent, keyed by the id its caller gave it. Grid resizes
1032
930
  * write `span`; `size` is here because a strategy swap would write that. */
@@ -1090,6 +988,18 @@ interface PanelDescriptor {
1090
988
  }
1091
989
  declare function Workspace({ children, ids, panels, resizable, reorderable, onReorder, layout, onLayoutChange, gap, padding, viewport, }: WorkspaceProps): react_jsx_runtime.JSX.Element;
1092
990
 
991
+ /** The specimen's sections, in page order. */
992
+ declare const SPECIMEN_SECTIONS: readonly ["Buttons & toggles", "Fields & pickers", "Panels & property rows", "Overlays & feedback", "Lists & data", "Tool chrome", "Editors & plots", "Lab chrome"];
993
+ /**
994
+ * One page of the kit's controls and chrome, each in a small working state: a
995
+ * preview surface for a theme, where every token has something on screen that
996
+ * reads it. Popovers, dialogs and toasts portal into the page itself, so they
997
+ * take whatever theme the page is under.
998
+ */
999
+ declare function Specimen({ className }: {
1000
+ className?: string;
1001
+ }): react_jsx_runtime.JSX.Element;
1002
+
1093
1003
  /** The 2D view labkit has always shipped, and what a trial gets when it names no
1094
1004
  * other. Re-exported under its own name so a consumer can say which it means. */
1095
1005
  type ViewTransform2D = ViewTransform;
@@ -1098,40 +1008,10 @@ declare const DEFAULT_VIEW: ViewTransform2D;
1098
1008
  * zoom chrome, `CanvasStack` — asks for it and handles not getting it. */
1099
1009
  declare function as2DView(view: unknown): ViewTransform2D | null;
1100
1010
 
1101
- type TokenValue = string | number | readonly (string | number)[];
1102
- /**
1103
- * A single design token as authored, before aliases are resolved: a DTCG-shaped
1104
- * `{ type, value }` pair where `value` may still be a `{ref}` to another token.
1105
- */
1106
- interface RawToken {
1107
- readonly type: string;
1108
- readonly value: TokenValue;
1109
- /** Render the referenced color at this alpha, 0–1. */
1110
- readonly alpha?: number | undefined;
1111
- readonly description?: string | undefined;
1112
- }
1113
- /** A token graph flattened to one level, keyed by token name (no `--wzl-`
1114
- * prefix). Still unresolved — see `ResolvedTokenMap` for the output side. */
1115
- type FlatTokens = Record<string, RawToken>;
1116
- /**
1117
- * A theme: a named set of design tokens, organized into a mode-invariant layer
1118
- * plus one layer per mode (light, dark, …), optionally extending another theme.
1119
- * Tokens are held unresolved — aliases between them are collapsed later by
1120
- * `resolveTheme`, so an override of a base primitive still reaches everything
1121
- * that references it.
1122
- */
1123
- interface Theme {
1124
- readonly name: string;
1125
- readonly extends: Theme | null;
1126
- readonly defaultMode: string;
1127
- readonly tokens: FlatTokens;
1128
- readonly modes: Readonly<Record<string, FlatTokens>>;
1129
- }
1130
-
1131
1011
  /**
1132
1012
  * labkit's theme: a cosmic dark and a warm parchment light, extending the
1133
- * built-in weasel theme. Authored as DTCG and loaded at import time — the
1134
- * interchange path a theme exported from a design tool would take.
1013
+ * built-in weasel theme. A pins-only theme definition: nothing in it is
1014
+ * derived, so it loads without the engine.
1135
1015
  */
1136
1016
  declare const interstellarTheme: Theme;
1137
1017
 
@@ -1149,7 +1029,7 @@ interface TrialProps {
1149
1029
  declare function Trial({ id, chrome, suppress }: TrialProps): react_jsx_runtime.JSX.Element;
1150
1030
 
1151
1031
  /** Props for `<TrialBody>`. */
1152
- interface TrialBodyProps {
1032
+ interface TrialBodyProps extends Omit<SplitProps, 'sidebar' | 'children' | 'className' | 'sidebarClassName' | 'label'> {
1153
1033
  /** The sidebar region's sections. */
1154
1034
  sidebar: ReactNode;
1155
1035
  /** The instrument's own output. */
@@ -1157,36 +1037,9 @@ interface TrialBodyProps {
1157
1037
  /** Extra class on the content pane — `Trial` marks a canvas instrument's
1158
1038
  * well flush. */
1159
1039
  contentClassName?: string;
1160
- /** The sidebar's current extent in pixels. Omit for an unpersisted lab: the
1161
- * seam still works, its result just does not outlive the mount. */
1162
- width?: number;
1163
- /** Where the sidebar starts before anyone drags it. */
1164
- defaultWidth?: number;
1165
- minWidth?: number;
1166
- maxWidth?: number;
1167
- /** How little the instrument may be squeezed to. Reported as the seam's
1168
- * reachable maximum, so the drag stops there rather than clamping silently. */
1169
- contentMinWidth?: number;
1170
- /** Fires through the drag, not on release: the pane is already there. */
1171
- onWidthChange?: (width: number) => void;
1172
- /**
1173
- * Fixed extent. Omit in an app — the strip measures its own box. Supply it
1174
- * where nothing measures, notably jsdom, or both panes lay out at zero.
1175
- */
1176
- viewport?: {
1177
- w: number;
1178
- h: number;
1179
- };
1180
1040
  }
1181
- /**
1182
- * A trial's sidebar and content as a two-pane strip with a draggable seam.
1183
- *
1184
- * The seam is `stripStrategy`'s own resize affordance, so it arrives as a
1185
- * `role="separator"` carrying the reachable range, operable by pointer and by
1186
- * arrows / Home / End, and clamped against the content pane's floor rather
1187
- * than against the sidebar's alone.
1188
- */
1189
- declare function TrialBody({ sidebar, children, contentClassName, width, defaultWidth, minWidth, maxWidth, contentMinWidth, onWidthChange, viewport, }: TrialBodyProps): react_jsx_runtime.JSX.Element;
1041
+ /** A trial's sidebar and content as a `Split`, wearing the trial's classes. */
1042
+ declare function TrialBody({ sidebar, children, contentClassName, ...rest }: TrialBodyProps): react_jsx_runtime.JSX.Element;
1190
1043
 
1191
1044
  /** The trial's loupe as its chrome sees it: a switch and its position. */
1192
1045
  interface LoupeBindings {
@@ -1229,5 +1082,5 @@ interface TrialChromeProps {
1229
1082
  * each region its slice. */
1230
1083
  declare function TrialChrome({ trialId, record, instrument, isLastTrial, undoBindings, job, loupe, trialChrome, chrome, suppress, activeToolId, setActiveTool, children, }: TrialChromeProps): react_jsx_runtime.JSX.Element;
1231
1084
 
1232
- export { ANNOTATION_TOOLS, ANNOTATION_WEASEL_TOOLS, AnnotationData, AnnotationKind, AnnotationMeaning, AnnotationOverlay, AnnotationTarget, AnnotationTargets, Annotations, AnnotationsApi, AnnotationsCapability, AnnotationsContext, BranchAnnotations, BranchOptions, CaptureOptions, CaptureResult, CaptureSource, ConfigBranch, ConfigEntry, ConfigField, ConfigNode, ConfigOption, ConfigRule, ConfigRuleContext, ConfigSchema, ConfigShape, ControlRenderer, CurveField, DEFAULT_VIEW, EffectCard, EffectCardList, ExportMenu, InferConfig, Instrument, InstrumentList, JobHandle, Lab, LabContext, LabMode, LabPalette, LabShell, LabSwitcher, LeafPatch, MarkList, MarkScene, NodeOptions, PropertyGroup, PropertyListPack, ResolvedConfig, SavedSnapshot, StorageAdapter, Subpanel, Trial, TrialBody, TrialChrome, TrialContribution, TrialInfo, TrialRecord, TrialTool, ViewTransform, Workspace, WorldRect, addTrial, annotationToolInfo, applyRules, as2DView, builtinRules, capturePlan, captureTarget, cloneTrial, closeTrial, composeCaptureSvg, createMarkDrawOne, currentPage, defineInstrument, f, fillConfigDefaults, fitView, fromConfigFields, fromWeaselView, hasConfigPath, interstellarTheme, isConfigBranch, isLeafVisible, isStale, markCommands, markSvgNodes, reorderTrials, resetTrial, resolveConfigSchema, resolveMarkStyle, schemaNodeAtPath, seenFrom, titleCase, toWeaselView, useAnnotations, useAnnotationsOptional, useConfigSchema, useLabContext, validateConfigSchema, valueAtPath, withValueAtPath };
1233
- export type { AddTrialOptions, AnnotationOverlayProps, AnnotationTargetsProps, AnnotationToolInfo, CaptureArgs, CapturePlan, ComposeSvgArgs, ContentSize, CurveFieldProps, CurveMark, EffectCardListItem, EffectCardListProps, EffectCardProps, InstrumentSpec, LabContextValue, LabPage, LabPaletteProps, LabProps, LabShellProps, LabSwitcherProps, MarkDrawOptions, MarkListProps, MarkStyle, PaintableMark, PaneSize, PanelDescriptor, PropertyGroupProps, SubpanelProps, TrialBodyProps, TrialChromeProps, TrialLayout, TrialProps, UndoBindings, ValidationResult, ViewTransform2D, WorkspaceProps };
1085
+ export { ANNOTATION_TOOLS, ANNOTATION_WEASEL_TOOLS, AnnotationData, AnnotationKind, AnnotationMeaning, AnnotationOverlay, AnnotationTarget, AnnotationTargets, AnnotationsApi, AnnotationsCapability, AnnotationsContext, CaptureOptions, CaptureResult, CaptureSource, CloseIcon, CollapseIcon, ConfigField, ConfigRule, ConfigSchema, ControlRenderer, CurveField, DEFAULT_VIEW, EffectCard, EffectCardList, ExpandIcon, ExportMenu, IconProps, Instrument, InstrumentList, JobHandle, Jog, Lab, LabContribution, LabMode, LabPalette, LabRoot, LabShell, LabSwitcher, MarkList, MarkScene, PauseIcon, PlayIcon, PropertyGroup, PropertyListPack, ResetIcon, SPECIMEN_SECTIONS, Specimen, SplitProps, StepBackIcon, StepForwardIcon, StopIcon, StorageAdapter, Subpanel, TokenPanel, Trial, TrialBody, TrialChrome, TrialContribution, TrialInfo, TrialRecord, TrialTool, ViewTransform, Workspace, WorldRect, annotationToolInfo, as2DView, capturePlan, captureTarget, composeCaptureSvg, createMarkDrawOne, currentPage, defineInstrument, fitView, fromWeaselView, inferTokenType, interstellarTheme, isStale, markCommands, markSvgNodes, resolveMarkStyle, seenFrom, toWeaselView, useAnnotations, useAnnotationsOptional, validateConfigSchema };
1086
+ export type { AnnotationOverlayProps, AnnotationTargetsProps, AnnotationToolInfo, CaptureArgs, CapturePlan, ComposeSvgArgs, ContentSize, CurveFieldProps, CurveMark, EffectCardListItem, EffectCardListProps, EffectCardProps, InstrumentSpec, JogProps, LabPage, LabPaletteProps, LabProps, LabRootProps, LabShellProps, LabSwitcherProps, MarkDrawOptions, MarkListProps, MarkStyle, PaintableMark, PaneSize, PanelDescriptor, PropertyGroupProps, SubpanelProps, TokenCategory, TokenEntry, TokenPanelProps, TrialBodyProps, TrialChromeProps, TrialLayout, TrialProps, UndoBindings, ValidationResult, ViewTransform2D, WorkspaceProps };