@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
@@ -0,0 +1,276 @@
1
+ import { $ as Auto, K as Instrument } from '../_dts/frac-B4okC2lX.js';
2
+ export { aw as auto, aC as isAuto } from '../_dts/frac-B4okC2lX.js';
3
+ import { R as ResolvedConfig, l as ConfigNode, A as Annotations, N as NodeOptions, v as SectionOption, d as ControlRenderer, n as ConfigOption, p as ConfigShape, h as ConfigBranch, B as BranchAnnotations, e as BranchOptions, b as ConfigSchema, I as InferConfig, i as ConfigEntry, a as ConfigField, c as ConfigRule, L as LeafPatch, o as ConfigRuleContext } from '../_dts/types-DzoNY1pO.js';
4
+ export { m as ConfigOf, C as ConfigPath, E as EntryValue, q as NodeValue, S as SectionSpec, V as ValueAtPath } from '../_dts/types-DzoNY1pO.js';
5
+ import { ToolPrefNumberFormat, ToolPrefNumberUnit, ToolPrefLeaf, ToolPrefGroup } from '@weasel-js/core';
6
+ import 'react';
7
+ import '../_dts/types-DJ79Tg5J.js';
8
+ import '../_dts/PrefsForm.d-DPy9I8It.js';
9
+
10
+ /** The dotted paths a schema declares as starting auto — every leaf that said
11
+ * `.initial(auto)`. This is what seeds a new trial's unpinned set. */
12
+ declare function autoPathsOf(resolved: ResolvedConfig): string[];
13
+ /**
14
+ * The config an instrument reads: the stored one, with every unpinned path
15
+ * either computed by its resolver or removed.
16
+ *
17
+ * Resolution is demand-driven — a resolver reading another unpinned path
18
+ * forces that one first, whatever order the schema declared them in — so a
19
+ * cycle is a real cycle and not an ordering accident.
20
+ */
21
+ declare function resolveAutoConfig<TC>(resolved: ResolvedConfig, config: TC, autoPaths: ReadonlySet<string>): TC;
22
+
23
+ /** Whether a schema entry is a branch rather than a leaf. */
24
+ declare function isConfigBranch(entry: ConfigEntry): entry is ConfigBranch;
25
+ /** Shared chaining surface. Every method clones, so a node can be reused as a
26
+ * base for several leaves without one bleeding into the next. */
27
+ declare abstract class BaseNode<T> implements ConfigNode<T> {
28
+ readonly annotations: Readonly<Annotations>;
29
+ readonly options: Readonly<NodeOptions>;
30
+ abstract readonly kind: string | null;
31
+ readonly default: T;
32
+ constructor(defaultValue: T, annotations?: Readonly<Annotations>, options?: Readonly<NodeOptions>);
33
+ /** Clone into the same subclass. Subclasses with extra constructor
34
+ * arguments override this. */
35
+ protected with(annotations: Annotations, options: NodeOptions): this;
36
+ protected ann(patch: Annotations): this;
37
+ protected opt(patch: NodeOptions): this;
38
+ /** Human-readable label. Defaults to the key, title-cased. */
39
+ label(name: string): this;
40
+ /** Longer help text, surfaced as a tooltip on the row label. */
41
+ describe(description: string): this;
42
+ /** Omit from the panel unless it is asked to show hidden leaves. */
43
+ hidden(): this;
44
+ /** Pair with a sibling sharing this id, side-by-side on one row. */
45
+ pair(pair: string): this;
46
+ /** Render under a named section heading. `collapsed` opens the section
47
+ * folded, and `layout` and `pack` lay out its rows — say each on any one of
48
+ * the section's leaves. */
49
+ section(label: string, opts?: Omit<SectionOption, 'label'>): this;
50
+ /** Show this row only while the predicate holds. Presentational — the value
51
+ * stays in config and the instrument still reads it. */
52
+ showIf(predicate: (config: Record<string, unknown>) => boolean): this;
53
+ /** Draw this one row yourself, keeping the kind, default and validation. */
54
+ render(renderer: ControlRenderer): this;
55
+ /**
56
+ * Compute this leaf's value while it is auto, instead of leaving it
57
+ * `undefined`. The resolver is given the config with every other auto path
58
+ * already resolved.
59
+ */
60
+ auto(resolve: (config: Record<string, unknown>) => T): this;
61
+ /**
62
+ * Start this leaf auto rather than pinned at its default. Takes `auto` and
63
+ * nothing else — the constructor argument already declares the value, and a
64
+ * second way to say it would fight with the first.
65
+ */
66
+ initial(value: Auto): this;
67
+ /** Never auto. The row takes no pin dot and ignores the gesture. */
68
+ manual(): this;
69
+ }
70
+ declare class NumberNode extends BaseNode<number> {
71
+ readonly kind = "number";
72
+ /** Bound the value. A number with both bounds renders as a slider. */
73
+ range(min: number, max: number): this;
74
+ step(step: number): this;
75
+ /** A display suffix for the value — `'px'`, `'ms'`, `'°'`. Presentation only:
76
+ * it is never parsed, and the stored value stays a plain number. */
77
+ suffix(suffix: string): this;
78
+ /** Show the value in a named format — `'compact'` reads `2.0M`. Presentation
79
+ * only: the stored value stays a plain number, and a typed `2.5m` reads back. */
80
+ format(format: ToolPrefNumberFormat): this;
81
+ /**
82
+ * Store the value in one unit and edit it in another — radians stored,
83
+ * degrees typed. `min`, `max` and `step` are declared in the stored unit
84
+ * alongside the value, and convert with it. `prefUnit` builds one from a
85
+ * `UnitSystem`.
86
+ */
87
+ unit(unit: ToolPrefNumberUnit): this;
88
+ /** Force a slider even without both bounds. */
89
+ slider(): this;
90
+ /** Force a typed input even when both bounds are set. */
91
+ input(): this;
92
+ }
93
+ declare class BooleanNode extends BaseNode<boolean> {
94
+ readonly kind = "boolean";
95
+ /** Ask for a switch rather than a checkbox. */
96
+ toggle(): this;
97
+ }
98
+ declare class StringNode extends BaseNode<string> {
99
+ readonly kind = "string";
100
+ placeholder(placeholder: string): this;
101
+ maxLength(maxLength: number): this;
102
+ /** Milliseconds to debounce live writes. 0 commits every keystroke. */
103
+ debounce(debounceMs: number): this;
104
+ }
105
+ declare class ColorNode extends BaseNode<string> {
106
+ readonly kind = "color";
107
+ /** The value carries alpha as `#rrggbbaa`, and the row gets an opacity
108
+ * track beside the swatch. */
109
+ alpha(): this;
110
+ }
111
+ declare class EnumNode<T extends string> extends BaseNode<T> {
112
+ readonly kind = "enum";
113
+ /** Render as a segmented control rather than a select. */
114
+ radio(): this;
115
+ /** Relabel the choices. Named `labels` rather than `options` because
116
+ * `options` is the node's own extras bag. */
117
+ labels(options: readonly ConfigOption[]): this;
118
+ }
119
+ /** A leaf whose kind the rule chain decides. */
120
+ declare class ValueNode<T> extends BaseNode<T> {
121
+ readonly kind: null;
122
+ }
123
+ /** A leaf of a kind labkit does not ship a row for. */
124
+ declare class CustomNode<T> extends BaseNode<T> {
125
+ readonly kind: string;
126
+ constructor(kind: string, defaultValue: T, annotations?: Readonly<Annotations>, options?: Readonly<NodeOptions>);
127
+ protected with(annotations: Annotations, options: NodeOptions): this;
128
+ }
129
+ /**
130
+ * A branch of the schema: its children nest under its key, so a leaf inside
131
+ * one is read and written at a dotted path. Distinct from `.section()`, which
132
+ * puts a heading over sibling leaves and leaves their paths alone.
133
+ */
134
+ declare class GroupNode<S extends ConfigShape> implements ConfigBranch<S> {
135
+ readonly children: S;
136
+ readonly annotations: Readonly<BranchAnnotations>;
137
+ readonly options: Readonly<BranchOptions>;
138
+ constructor(children: S, annotations?: Readonly<BranchAnnotations>, options?: Readonly<BranchOptions>);
139
+ private with;
140
+ /** Heading for the group's rows. Defaults to the key, title-cased. */
141
+ label(name: string): GroupNode<S>;
142
+ /** Longer help text. Carried on the resolved `PrefGroup`, where weasel-ui's
143
+ * `PrefsForm` draws it under the heading; `ControlPanel` has no place for
144
+ * it yet and shows the heading alone. */
145
+ describe(description: string): GroupNode<S>;
146
+ /** Render this whole group under a named section heading. */
147
+ section(label: string, opts?: Omit<SectionOption, 'label'>): GroupNode<S>;
148
+ /** Show this group only while the predicate holds. Presentational — every
149
+ * value beneath it stays in config and the instrument still reads it. */
150
+ showIf(predicate: (config: Record<string, unknown>) => boolean): GroupNode<S>;
151
+ }
152
+ /**
153
+ * Builds an instrument's config: the values, their types, and how each is
154
+ * edited, in one declaration.
155
+ *
156
+ * ```ts
157
+ * const config = f.schema({
158
+ * showGrid: f.boolean(true),
159
+ * cellSize: f.number(20).range(5, 80).step(5).label('Grid spacing'),
160
+ * // Nested: read and written at `grid.color`.
161
+ * grid: f.group({ color: f.color('#ffffff') }),
162
+ * })
163
+ * ```
164
+ */
165
+ declare const f: {
166
+ number: (def: number) => NumberNode;
167
+ boolean: (def: boolean) => BooleanNode;
168
+ string: (def: string) => StringNode;
169
+ color: (def: string) => ColorNode;
170
+ /** A fixed set of choices. The default's literal type flows into the config
171
+ * type, so `f.enum('fast', ['fast', 'accurate'])` gives
172
+ * `'fast' | 'accurate'` with no `as const`. */
173
+ enum: <const T extends string>(def: T, options: readonly T[] | readonly ConfigOption[]) => EnumNode<T>;
174
+ /** A leaf with no declared kind: the rule chain decides, which is how a lab
175
+ * states a convention like "every `*Color` key is a color picker". */
176
+ value: <T>(def: T) => ValueNode<T>;
177
+ /** A branch: its children nest under this key, so `grid: f.group({ size })`
178
+ * puts the value at `config.grid.size` and addresses it as `'grid.size'`.
179
+ * Groups nest as deeply as the schema wants. */
180
+ group: <const S extends ConfigShape>(children: S) => GroupNode<S>;
181
+ /** A leaf of a kind a lab supplies the control for, through `controls`. */
182
+ custom: <T>(kind: string, def: T, validate?: (leaf: ToolPrefLeaf, config: Record<string, unknown>) => string[]) => CustomNode<T>;
183
+ /** Collect leaves and groups into an instrument's config. */
184
+ schema<S extends ConfigShape>(nodes: S): ConfigSchema<InferConfig<S>>;
185
+ };
186
+
187
+ /**
188
+ * Adapt a legacy `configSchema(): ConfigField[]` into the resolved shape, so
189
+ * both instrument paths reach one renderer.
190
+ *
191
+ * Rules do not run here: a hand-written `ConfigField` already states its label
192
+ * and control, which is everything the rule chain would have inferred.
193
+ */
194
+ declare function fromConfigFields(fields: readonly ConfigField[]): ResolvedConfig;
195
+
196
+ /** The value at a dotted path. `undefined` when a segment is missing or the
197
+ * walk hits something that is not a record. */
198
+ declare function valueAtPath(config: unknown, path: string): unknown;
199
+ /** Whether a dotted path is actually present, which a `undefined` value is
200
+ * not enough to tell you. */
201
+ declare function hasConfigPath(config: unknown, path: string): boolean;
202
+ /** A copy of `config` with `value` written at a dotted path. Every record on
203
+ * the way down is copied and the input is left alone; a missing — or
204
+ * non-record — intermediate is replaced with the branch the path implies. */
205
+ declare function withValueAtPath<T>(config: T, path: string, value: unknown): T;
206
+ /**
207
+ * `stored` with every gap filled from `defaults`, down the whole tree.
208
+ *
209
+ * This is how a config written before its schema grew a branch still loads:
210
+ * the branch arrives at its defaults instead of `undefined`, and a key the
211
+ * defaults no longer mention is kept rather than dropped, so nothing is lost
212
+ * to a schema change the author has not finished making.
213
+ */
214
+ declare function fillConfigDefaults<T>(stored: unknown, defaults: T): T;
215
+ /** A node in a resolved schema tree, by dotted path. Structural rather than
216
+ * `isPrefLeaf` so this stays free of a runtime import. */
217
+ declare function schemaNodeAtPath(group: ToolPrefGroup, path: string): ToolPrefLeaf | ToolPrefGroup | undefined;
218
+
219
+ /**
220
+ * Resolve a schema into the vocabulary weasel-ui renders, running each leaf
221
+ * through the consumer's rules and then labkit's own.
222
+ *
223
+ * The group mirrors the schema's own nesting: an `f.group` becomes a nested
224
+ * `PrefGroup`, so a leaf's dotted path within the tree is the path its value
225
+ * is written at, and both `ControlPanel` and `PrefsForm` address it
226
+ * identically.
227
+ */
228
+ declare function resolveConfigSchema<TC>(schema: ConfigSchema<TC>, rules?: readonly ConfigRule[]): ResolvedConfig;
229
+
230
+ /** `cellSize` -> `Cell size`. Splits camelCase without shattering acronyms. */
231
+ declare function titleCase(key: string): string;
232
+ /**
233
+ * labkit's own inference, expressed in the same vocabulary a consumer
234
+ * extends. Runs after the consumer's rules, so a lab always wins.
235
+ *
236
+ * If one of these ever needs something a `ConfigRule` cannot express, the
237
+ * seam is too weak — that is the point of writing them this way.
238
+ */
239
+ declare const builtinRules: readonly ConfigRule[];
240
+ /**
241
+ * Fold a rule chain into one leaf patch. Gap-filling: a property already
242
+ * settled is never overwritten, so the accumulator seeded with the author's
243
+ * annotations beats every rule, and earlier rules beat later ones.
244
+ */
245
+ declare function applyRules(seed: LeafPatch, ctx: Omit<ConfigRuleContext, 'leaf'>, rules: readonly ConfigRule[]): LeafPatch;
246
+
247
+ /**
248
+ * An instrument's controls, resolved against the surrounding lab's rules.
249
+ *
250
+ * Resolution cannot happen in `defineInstrument` — rules are lab-scoped and
251
+ * that runs at module load — so it happens here, at render. Both instrument
252
+ * paths land in the same shape, so callers never branch on which was used.
253
+ */
254
+ declare function useConfigSchema(instrument: Instrument<any, any, any>): ResolvedConfig;
255
+
256
+ /**
257
+ * The config an instrument reads: the stored one with every unpinned path
258
+ * resolved. The single place resolution happens, so `Trial` and
259
+ * `useTrialState` cannot disagree about what an instrument is looking at.
260
+ */
261
+ declare function useResolvedConfig<TC>(schema: ResolvedConfig | undefined, config: TC, autoPaths: readonly string[] | undefined): {
262
+ config: TC;
263
+ auto: ReadonlySet<string>;
264
+ };
265
+
266
+ /**
267
+ * Whether the row at a dotted path should be drawn right now. A group answers
268
+ * for its whole subtree — hiding one hides everything under it.
269
+ *
270
+ * `hidden` is the node's own static flag; `showIf` is the schema's predicate
271
+ * over the live config. Both are presentational — a hidden leaf keeps its
272
+ * value and the instrument still reads it.
273
+ */
274
+ declare function isLeafVisible(resolved: ResolvedConfig, path: string, config: Record<string, unknown>, showHidden?: boolean): boolean;
275
+
276
+ export { Annotations, Auto, BaseNode, BooleanNode, BranchAnnotations, BranchOptions, ColorNode, ConfigBranch, ConfigEntry, ConfigNode, ConfigOption, ConfigRule, ConfigRuleContext, ConfigSchema, ConfigShape, ControlRenderer, CustomNode, EnumNode, GroupNode, InferConfig, LeafPatch, NodeOptions, NumberNode, ResolvedConfig, StringNode, ValueNode, applyRules, autoPathsOf, builtinRules, f, fillConfigDefaults, fromConfigFields, hasConfigPath, isConfigBranch, isLeafVisible, resolveAutoConfig, resolveConfigSchema, schemaNodeAtPath, titleCase, useConfigSchema, useResolvedConfig, valueAtPath, withValueAtPath };
@@ -0,0 +1,8 @@
1
+ export { useConfigSchema } from '../chunk-PJ7WEQBJ.js';
2
+ import '../chunk-Z76KEZAX.js';
3
+ export { BaseNode, BooleanNode, ColorNode, CustomNode, EnumNode, GroupNode, NumberNode, StringNode, ValueNode, applyRules, builtinRules, f, isConfigBranch, resolveConfigSchema, titleCase, useResolvedConfig } from '../chunk-ZDHY47EV.js';
4
+ export { fromConfigFields, isLeafVisible } from '../chunk-PHK4W562.js';
5
+ export { auto, autoPathsOf, fillConfigDefaults, hasConfigPath, isAuto, resolveAutoConfig, schemaNodeAtPath, valueAtPath, withValueAtPath } from '../chunk-7PFH3CNM.js';
6
+ import '../chunk-T3EC2DXD.js';
7
+ //# sourceMappingURL=index.js.map
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,7 +1,6 @@
1
- export { e as ControlPanel } from '../_dts/index-Blv9uQzu.js';
2
- export { a as CheckboxField, b as ColorField, C as ConfigField, d as ConfigFieldType, N as NumberField, S as SelectField, e as SelectOption, f as SliderField, T as TextField } from '../_dts/types-x92Kfeme.js';
1
+ export { e as ControlPanel } from '../_dts/index-BNdz-tNd.js';
2
+ export { f as CheckboxField, g as ColorField, a as ConfigField, k as ConfigFieldType, r as NumberField, s as SelectField, t as SelectOption, u as SliderField, T as TextField } from '../_dts/types-DzoNY1pO.js';
3
3
  import 'react/jsx-runtime';
4
4
  import 'react';
5
- import '../_dts/types-B9_zrHmb.js';
6
5
  import '@weasel-js/core';
7
- import '../_dts/PrefsForm.d-DDHFANkc.js';
6
+ import '../_dts/PrefsForm.d-DPy9I8It.js';
@@ -1,5 +1,6 @@
1
- export { ControlPanel } from '../chunk-U3IYHIAE.js';
2
- import '../chunk-E44SU6XS.js';
3
- import '../chunk-W3ECWC2K.js';
1
+ export { ControlPanel } from '../chunk-EH7UEQV7.js';
2
+ import '../chunk-PHK4W562.js';
3
+ import '../chunk-7PFH3CNM.js';
4
+ import '../chunk-T3EC2DXD.js';
4
5
  //# sourceMappingURL=index.js.map
5
6
  //# sourceMappingURL=index.js.map
@@ -1,11 +1,9 @@
1
- import { P as PaletteItem, a as Point, D as DragFeedback, b as DragDropCapability, V as ViewTransform, c as WorldSpec } from '../_dts/frac-z7ker2Vx.js';
1
+ import { P as PaletteItem, l as Point, m as DragFeedback, n as DragDropCapability, k as ViewTransform, a as WorldSpec } from '../_dts/frac-B4okC2lX.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { RefObject, PointerEvent, ReactPortal } from 'react';
4
- import '../_dts/types-B9_zrHmb.js';
4
+ import '../_dts/types-DzoNY1pO.js';
5
5
  import '@weasel-js/core';
6
- import '../_dts/PrefsForm.d-DDHFANkc.js';
7
- import '../_dts/types-x92Kfeme.js';
8
- import '../_dts/types-BP2OCcpg.js';
6
+ import '../_dts/PrefsForm.d-DPy9I8It.js';
9
7
  import '../_dts/types-DJ79Tg5J.js';
10
8
 
11
9
  interface DragState {