@weasel-js/labkit 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/dist/_dts/{CanvasStackContext-DQgcH1ny.d.ts → CanvasStackContext-D2jnIwfk.d.ts} +1 -1
  2. package/dist/_dts/FloatingPanel-7j0IcXwz.d.ts +30 -0
  3. package/dist/_dts/{LayerList.d-2c9yup5Y.d.ts → LayerList.d-DiuEArKq.d.ts} +4 -4
  4. package/dist/_dts/PrefsRow.d-TOZ7BgD9.d.ts +79 -0
  5. package/dist/_dts/PropertyPanel.d-D-1paCbE.d.ts +141 -0
  6. package/dist/_dts/{Select.d-BchGMC2Y.d.ts → Select.d-Bensr_MT.d.ts} +15 -6
  7. package/dist/_dts/Stage-CCWfQQWM.d.ts +202 -0
  8. package/dist/_dts/index-B2Yj5aA0.d.ts +274 -0
  9. package/dist/_dts/{index-B0--8PEM.d.ts → index-CsYqUHD3.d.ts} +12 -13
  10. package/dist/_dts/{types-B7y8hX1D.d.ts → types-CRPSGFAp.d.ts} +33 -5
  11. package/dist/_dts/{frac-DTRq7Xpb.d.ts → types-CSm9jgol.d.ts} +700 -650
  12. package/dist/_dts/{useTrialState-CP4jfuKl.d.ts → useTrialState-CTZPgeZ7.d.ts} +2 -3
  13. package/dist/canvas/index.d.ts +40 -8
  14. package/dist/canvas/index.js +5 -3
  15. package/dist/chrome/index.d.ts +5 -6
  16. package/dist/chrome/index.js +9 -7
  17. package/dist/chunk-24W5VEJW.js +18 -0
  18. package/dist/chunk-24W5VEJW.js.map +1 -0
  19. package/dist/chunk-275JRRVD.js +728 -0
  20. package/dist/chunk-275JRRVD.js.map +1 -0
  21. package/dist/chunk-3RY6WL5T.js +38 -0
  22. package/dist/chunk-3RY6WL5T.js.map +1 -0
  23. package/dist/chunk-4LJSC7MB.js +143 -0
  24. package/dist/chunk-4LJSC7MB.js.map +1 -0
  25. package/dist/{chunk-3FI7Y4R4.js → chunk-7BO7HNGF.js} +5 -5
  26. package/dist/{chunk-3FI7Y4R4.js.map → chunk-7BO7HNGF.js.map} +1 -1
  27. package/dist/chunk-AWQG7FCC.js +19 -0
  28. package/dist/chunk-AWQG7FCC.js.map +1 -0
  29. package/dist/chunk-CZZPXUOU.js +3 -0
  30. package/dist/{chunk-SBXNQW4G.js.map → chunk-CZZPXUOU.js.map} +1 -1
  31. package/dist/{chunk-ZORVNOKX.js → chunk-FMK7UQ6V.js} +24 -145
  32. package/dist/chunk-FMK7UQ6V.js.map +1 -0
  33. package/dist/{chunk-BVL7Y574.js → chunk-FZ7YFQN7.js} +26 -10
  34. package/dist/chunk-FZ7YFQN7.js.map +1 -0
  35. package/dist/{chunk-USO6TERP.js → chunk-GOZLNM4L.js} +11 -9
  36. package/dist/chunk-GOZLNM4L.js.map +1 -0
  37. package/dist/{chunk-H5VIV7MQ.js → chunk-I5DUQ5HM.js} +88 -82
  38. package/dist/chunk-I5DUQ5HM.js.map +1 -0
  39. package/dist/chunk-J7OWWTCW.js +143 -0
  40. package/dist/chunk-J7OWWTCW.js.map +1 -0
  41. package/dist/{chunk-H6ZAOWNE.js → chunk-JVBYV6TL.js} +3 -3
  42. package/dist/{chunk-H6ZAOWNE.js.map → chunk-JVBYV6TL.js.map} +1 -1
  43. package/dist/{chunk-VQ47KWD5.js → chunk-KMJ7RWD3.js} +18 -7
  44. package/dist/chunk-KMJ7RWD3.js.map +1 -0
  45. package/dist/{chunk-ERFMC6WU.js → chunk-M7HP3FTK.js} +20 -11
  46. package/dist/chunk-M7HP3FTK.js.map +1 -0
  47. package/dist/chunk-MIM5R4ZT.js +14972 -0
  48. package/dist/chunk-MIM5R4ZT.js.map +1 -0
  49. package/dist/{chunk-HFRE4QQV.js → chunk-T5IBSPAM.js} +96 -32
  50. package/dist/chunk-T5IBSPAM.js.map +1 -0
  51. package/dist/chunk-UNAZSLWE.js +294 -0
  52. package/dist/chunk-UNAZSLWE.js.map +1 -0
  53. package/dist/{chunk-RS3HRQWU.js → chunk-WPLAANH4.js} +4 -3
  54. package/dist/chunk-WPLAANH4.js.map +1 -0
  55. package/dist/{chunk-AWH3SRPW.js → chunk-Y23G2VZL.js} +5 -37
  56. package/dist/chunk-Y23G2VZL.js.map +1 -0
  57. package/dist/{chunk-MOLIUNVH.js → chunk-YT75VYRD.js} +4 -4
  58. package/dist/{chunk-MOLIUNVH.js.map → chunk-YT75VYRD.js.map} +1 -1
  59. package/dist/chunk-ZIFPHIWZ.js +302 -0
  60. package/dist/chunk-ZIFPHIWZ.js.map +1 -0
  61. package/dist/config/index.d.ts +48 -40
  62. package/dist/config/index.js +4 -5
  63. package/dist/controls/index.d.ts +91 -7
  64. package/dist/controls/index.js +5 -4
  65. package/dist/dragdrop/index.d.ts +9 -7
  66. package/dist/dragdrop/index.js +3 -2
  67. package/dist/index.d.ts +294 -82
  68. package/dist/index.js +425 -402
  69. package/dist/index.js.map +1 -1
  70. package/dist/layers/index.d.ts +4 -5
  71. package/dist/layers/index.js +2 -1
  72. package/dist/loupe/index.d.ts +20 -17
  73. package/dist/loupe/index.js +5 -3
  74. package/dist/overview/index.d.ts +56 -0
  75. package/dist/overview/index.js +289 -0
  76. package/dist/overview/index.js.map +1 -0
  77. package/dist/passthrough/weasel-ui.d.ts +239 -69
  78. package/dist/passthrough/weasel-ui.js +3 -2
  79. package/dist/primitives/index.d.ts +5 -204
  80. package/dist/primitives/index.js +6 -4
  81. package/dist/state/index.d.ts +8 -8
  82. package/dist/state/index.js +4 -5
  83. package/dist/state/index.js.map +1 -1
  84. package/dist/styles.css +152 -82
  85. package/dist/undo/index.d.ts +4 -4
  86. package/package.json +17 -12
  87. package/src/annotations/AnnotationOverlay.tsx +2 -2
  88. package/src/annotations/Annotations.less +0 -10
  89. package/src/annotations/MarkList.tsx +4 -8
  90. package/src/annotations/index.ts +1 -0
  91. package/src/annotations/paint.test.ts +3 -14
  92. package/src/annotations/paint.ts +3 -19
  93. package/src/annotations/store.test.ts +26 -0
  94. package/src/annotations/store.ts +25 -6
  95. package/src/annotations/svgNodes.test.ts +6 -9
  96. package/src/annotations/svgNodes.ts +3 -3
  97. package/src/annotations/toolMap.test.ts +37 -2
  98. package/src/annotations/toolMap.ts +13 -0
  99. package/src/annotations/types.ts +27 -0
  100. package/src/canvas/AGENTS.md +9 -10
  101. package/src/canvas/CameraInput.test.tsx +136 -0
  102. package/src/canvas/CameraInput.tsx +322 -0
  103. package/src/canvas/CanvasStack.tsx +47 -58
  104. package/src/canvas/LinkedCursor.less +16 -0
  105. package/src/canvas/LinkedCursor.tsx +54 -0
  106. package/src/canvas/Stage.test.tsx +33 -4
  107. package/src/canvas/Stage.tsx +47 -37
  108. package/src/canvas/cameraRegistry.test.ts +55 -0
  109. package/src/canvas/cameraRegistry.ts +86 -0
  110. package/src/canvas/cameraView.test.ts +60 -0
  111. package/src/canvas/cameraView.ts +61 -0
  112. package/src/canvas/cameraZoom.test.ts +46 -0
  113. package/src/canvas/cameraZoom.ts +24 -0
  114. package/src/canvas/index.ts +23 -2
  115. package/src/canvas/sharedScope.test.tsx +94 -0
  116. package/src/chrome/ChromeRegions.stories.tsx +1 -0
  117. package/src/chrome/regions/PaletteRegion.less +0 -7
  118. package/src/chrome/regions/SidebarRegion.less +12 -2
  119. package/src/chrome/regions/SidebarRegion.test.tsx +9 -2
  120. package/src/config/builder.test.ts +2 -1
  121. package/src/config/builder.ts +15 -8
  122. package/src/config/entry.test.ts +3 -1
  123. package/src/config/fromConfigField.test.ts +14 -0
  124. package/src/config/fromConfigField.ts +19 -4
  125. package/src/config/index.ts +4 -1
  126. package/src/config/path.ts +2 -5
  127. package/src/config/resolve.ts +15 -1
  128. package/src/config/sectionTree.test.ts +12 -6
  129. package/src/config/sectionTree.ts +15 -5
  130. package/src/config/types.ts +34 -9
  131. package/src/controls/ControlPanel.less +1 -1
  132. package/src/controls/ControlPanel.stories.tsx +3 -2
  133. package/src/controls/ControlPanel.test.tsx +76 -13
  134. package/src/controls/ControlPanel.tsx +80 -11
  135. package/src/controls/inDialog.test.tsx +18 -0
  136. package/src/controls/inDialog.tsx +2 -10
  137. package/src/index.test.ts +1 -1
  138. package/src/index.ts +23 -5
  139. package/src/instrument/SineWave.smoke.test.tsx +2 -0
  140. package/src/instrument/types.ts +10 -1
  141. package/src/lab/Lab.nebula.test.tsx +11 -2
  142. package/src/lab/Lab.test.tsx +3 -1
  143. package/src/lab/Lab.tsx +87 -76
  144. package/src/lab/{LabFit.stories.less → LabFit.browser.test.less} +1 -1
  145. package/src/lab/{LabFit.stories.tsx → LabFit.browser.test.tsx} +41 -63
  146. package/src/lab/LabFullChrome.stories.tsx +1 -0
  147. package/src/lab/LabHeader.test.tsx +24 -14
  148. package/src/lab/LabHeader.tsx +11 -12
  149. package/src/lab/LabShell.less +8 -17
  150. package/src/lab/LabSwitcher.less +6 -6
  151. package/src/lab/LabZoom.test.tsx +223 -0
  152. package/src/lab/LabZoom.tsx +170 -0
  153. package/src/lab/index.ts +1 -0
  154. package/src/loupe/AGENTS.md +7 -6
  155. package/src/loupe/LoupeGestures.tsx +15 -10
  156. package/src/loupe/TrialLoupe.tsx +5 -5
  157. package/src/loupe/index.ts +1 -0
  158. package/src/loupe/loupeActions.ts +6 -2
  159. package/src/overview/AGENTS.md +38 -0
  160. package/src/overview/OverviewMarks.test.tsx +100 -0
  161. package/src/overview/OverviewMarks.tsx +93 -0
  162. package/src/overview/TrialOverview.less +53 -0
  163. package/src/overview/TrialOverview.stories.tsx +50 -0
  164. package/src/overview/TrialOverview.test.tsx +116 -0
  165. package/src/overview/TrialOverview.tsx +376 -0
  166. package/src/overview/index.ts +2 -0
  167. package/src/passthrough/weasel-ui.test.ts +2 -0
  168. package/src/passthrough/weasel-ui.ts +23 -4
  169. package/src/primitives/FloatingPanel.test.tsx +11 -0
  170. package/src/primitives/FloatingPanel.tsx +2 -5
  171. package/src/primitives/JobProgress.less +1 -1
  172. package/src/primitives/Legend.stories.tsx +1 -0
  173. package/src/primitives/Readout.browser.test.tsx +137 -0
  174. package/src/primitives/Readout.less +12 -0
  175. package/src/primitives/Readout.stories.tsx +58 -0
  176. package/src/primitives/Readout.test.tsx +93 -0
  177. package/src/primitives/Readout.tsx +56 -0
  178. package/src/primitives/index.ts +2 -0
  179. package/src/specimen/Specimen.stories.tsx +1 -0
  180. package/src/specimen/Specimen.tsx +21 -4
  181. package/src/state/Persistence.browser.test.tsx +47 -0
  182. package/src/state/labRecords.test.ts +4 -1
  183. package/src/state/store.test.ts +9 -5
  184. package/src/state/usePersistedState.test.tsx +1 -1
  185. package/src/state/useTrialState.test.tsx +1 -1
  186. package/src/styles.less +3 -0
  187. package/src/theme/Interstellar.stories.tsx +4 -6
  188. package/src/theme/base.less +21 -47
  189. package/src/theme/interstellar.test.ts +1 -1
  190. package/src/theme/interstellar.theme.json +10 -3
  191. package/src/tools/labTool.ts +6 -2
  192. package/src/trial/Trial.annotations.test.tsx +16 -0
  193. package/src/trial/Trial.less +0 -13
  194. package/src/trial/Trial.loupe.test.tsx +73 -1
  195. package/src/trial/Trial.stories.tsx +2 -0
  196. package/src/trial/Trial.tsx +23 -1
  197. package/src/trial/TrialChrome.tsx +21 -3
  198. package/src/trial/trialOps.test.ts +4 -4
  199. package/dist/_dts/PrefsRow.d-DFpPIeIC.d.ts +0 -39
  200. package/dist/_dts/inDialog-D5ZKGjiD.d.ts +0 -23
  201. package/dist/_dts/index-DINmCuLA.d.ts +0 -453
  202. package/dist/_dts/number.d-OeQYQoUO.d.ts +0 -28
  203. package/dist/_dts/usePanZoom-Bq73pwFe.d.ts +0 -117
  204. package/dist/chunk-2AYGEN57.js +0 -32
  205. package/dist/chunk-2AYGEN57.js.map +0 -1
  206. package/dist/chunk-AWH3SRPW.js.map +0 -1
  207. package/dist/chunk-BVL7Y574.js.map +0 -1
  208. package/dist/chunk-ERFMC6WU.js.map +0 -1
  209. package/dist/chunk-H5VIV7MQ.js.map +0 -1
  210. package/dist/chunk-HFRE4QQV.js.map +0 -1
  211. package/dist/chunk-RS3HRQWU.js.map +0 -1
  212. package/dist/chunk-SBXNQW4G.js +0 -3
  213. package/dist/chunk-TT5C5S6R.js +0 -368
  214. package/dist/chunk-TT5C5S6R.js.map +0 -1
  215. package/dist/chunk-USO6TERP.js.map +0 -1
  216. package/dist/chunk-VQ47KWD5.js.map +0 -1
  217. package/dist/chunk-WUJXJC5O.js +0 -14568
  218. package/dist/chunk-WUJXJC5O.js.map +0 -1
  219. package/dist/chunk-ZORVNOKX.js.map +0 -1
  220. package/src/canvas/usePanZoom.test.ts +0 -244
  221. package/src/canvas/usePanZoom.ts +0 -147
  222. package/src/state/Persistence.stories.tsx +0 -75
@@ -0,0 +1,274 @@
1
+ import './FloatingPanel-7j0IcXwz.js';
2
+ import * as react from 'react';
3
+ import { ReactNode, MouseEventHandler } from 'react';
4
+ import { J as JobHandle } from './types-DJ79Tg5J.js';
5
+
6
+ /** Whether a row's label sits beside its value or above it. */
7
+ type DetailListLayout = 'inline' | 'block';
8
+ /**
9
+ * How a list sets its values. `text` starts each value at the column's edge
10
+ * and wraps it; `figures` right-aligns it in a column at least
11
+ * `--wzl-detail-figure-min-width` (default `8ch`) wide, in the mono face,
12
+ * with spaces kept, so figure-space padding lines a column up on its decimal
13
+ * point.
14
+ */
15
+ type DetailListValues = 'text' | 'figures';
16
+ /** The state a row's status dot reports, painted from `--wzl-success`,
17
+ * `--wzl-warning` or `--wzl-danger`. */
18
+ type DetailRowStatus = 'success' | 'warn' | 'danger';
19
+ /** Props for {@link DetailList}. */
20
+ interface DetailListProps {
21
+ /** {@link DetailRow}s. */
22
+ children: ReactNode;
23
+ /** Heading drawn above the list, which also names it. */
24
+ title?: ReactNode;
25
+ /**
26
+ * `inline` puts every label in one rail beside the values; `block` stacks
27
+ * each label over its value, for a column too narrow to hold both.
28
+ */
29
+ layout?: DetailListLayout;
30
+ /** `text` by default. See {@link DetailListValues}. */
31
+ values?: DetailListValues;
32
+ /** Class on the outermost element: the `<dl>`, or the `<section>` holding
33
+ * the heading and the list when there is a `title`. */
34
+ className?: string;
35
+ }
36
+ /** Props for {@link DetailRow}. */
37
+ interface DetailRowProps {
38
+ label: ReactNode;
39
+ /** The value: text, or any run of elements — code chips, badges, keycaps,
40
+ * links. Several children wrap as a line of items. `null` or `undefined`
41
+ * keeps the row in place showing `placeholder`, so a list whose values
42
+ * come and go holds its height. */
43
+ children?: ReactNode;
44
+ /** Shown while there is no value. An en dash by default. */
45
+ placeholder?: ReactNode;
46
+ /**
47
+ * Draws a dot in the status color before the value. The dot is hidden from
48
+ * assistive technology and color is never the only signal, so the value
49
+ * itself has to say the same thing — "locked", not just a green dot.
50
+ */
51
+ status?: DetailRowStatus;
52
+ /** Sets this row's value as `text` or `figures`, whatever the list's
53
+ * `values` says — a sentence among figures, or one figure among text. */
54
+ values?: DetailListValues;
55
+ className?: string;
56
+ }
57
+ /**
58
+ * A read-only list of labeled values — the `<dl>` a property panel would be
59
+ * if its rows held facts instead of controls. Labels take the params label
60
+ * recipe and rail: `--wzl-params-label-width` sets the rail, so a detail list
61
+ * and a property panel beside it line their labels up from one declaration.
62
+ */
63
+ declare function DetailList({ children, title, layout, values, className }: DetailListProps): react.JSX.Element;
64
+ /** One label and its value in a {@link DetailList}. */
65
+ declare function DetailRow({ label, children, placeholder, status, values, className }: DetailRowProps): react.JSX.Element;
66
+
67
+ /** A live frame-rate readout, averaged over the last 30 frames. */
68
+ declare function FpsMeter(): react.JSX.Element;
69
+
70
+ /** Props for `<JobProgress>`. */
71
+ interface JobProgressProps {
72
+ job: JobHandle;
73
+ className?: string;
74
+ }
75
+ /** A running job's progress, failures and outcome. Determinate once the job
76
+ * reports a total; a job that cannot count up front never sends one, so the
77
+ * bar stays indeterminate rather than inventing a denominator. */
78
+ declare function JobProgress({ job, className }: JobProgressProps): react.JSX.Element | null;
79
+
80
+ /** How a legend entry's swatch is drawn, matching how the thing looks on canvas. */
81
+ type LegendMark = 'line' | 'dash' | 'dot' | 'band';
82
+ /** One row of a legend: a swatch and what it means. */
83
+ interface LegendEntry {
84
+ key: string;
85
+ label: string;
86
+ color: string;
87
+ /** Defaults to `'line'`. */
88
+ mark?: LegendMark;
89
+ }
90
+ /** Props for `<Legend>`. */
91
+ interface LegendProps {
92
+ entries: readonly LegendEntry[];
93
+ className?: string;
94
+ }
95
+ /** A color key. Presentational only — no handlers, no state, no hover behavior. */
96
+ declare function Legend({ entries, className }: LegendProps): react.JSX.Element;
97
+
98
+ /** One measurement in a {@link Readout}. */
99
+ interface ReadoutRow {
100
+ /** React key. Defaults to `label` when that is a string, else the row's index. */
101
+ key?: string;
102
+ label: ReactNode;
103
+ /** `null` or `undefined` keeps the row in place showing an en dash, so the
104
+ * readout holds its height while a measurement comes and goes. */
105
+ value?: ReactNode;
106
+ /** A dot in the status color before the value. Color is never the only
107
+ * signal: the value has to say the same thing in words. */
108
+ status?: DetailRowStatus;
109
+ /** `text` sets this row's value as wrapping prose instead of a figure. */
110
+ values?: DetailListValues;
111
+ }
112
+ /** Props for {@link Readout}. */
113
+ interface ReadoutProps {
114
+ rows: readonly ReadoutRow[];
115
+ /** Heading above the rows, which also names the list. */
116
+ title?: ReactNode;
117
+ /** Drawn below the rows — a small table, a note. */
118
+ children?: ReactNode;
119
+ className?: string;
120
+ }
121
+ /**
122
+ * Values a lab only reads — measurements shown beside its picture, such as
123
+ * "Lock margin +47.9°". A {@link DetailList} set as figures: labels take the
124
+ * params label recipe and `--wzl-params-label-width` rail, so a readout lines
125
+ * up with a `ControlPanel` beside it, and values sit right-aligned in the mono
126
+ * face with spaces kept, so figure-space padding aligns a column on its
127
+ * decimal point. Rows compose by hand as `DetailRow`s inside a `DetailList`
128
+ * with `values="figures"`.
129
+ */
130
+ declare function Readout({ rows, title, children, className }: ReadoutProps): react.JSX.Element;
131
+
132
+ /** Props for `<ScaleIndicator>`. */
133
+ interface ScaleIndicatorProps {
134
+ /** Current view zoom factor. If omitted, reads from CanvasStackContext. Defaults to 1. */
135
+ zoom?: number;
136
+ /** World pixels per unit at zoom=1. Default: 1. */
137
+ pixelsPerUnit?: number;
138
+ /** Unit label. Default: 'px'. */
139
+ unit?: string;
140
+ /** Target bar width in display pixels. Default: 100. */
141
+ targetWidth?: number;
142
+ }
143
+ /** A scale bar: a labeled rule showing how far a round number of world units
144
+ * is at the current zoom. Reads the zoom from the surrounding canvas stack
145
+ * unless one is passed. */
146
+ declare function ScaleIndicator({ zoom, pixelsPerUnit, unit, targetWidth, }: ScaleIndicatorProps): react.JSX.Element;
147
+
148
+ /** Props for `<Split>`. */
149
+ interface SplitProps {
150
+ /** The sidebar pane's contents. */
151
+ sidebar: ReactNode;
152
+ /** The edge the sidebar sits on. Read once, when the strip mounts. Default `'start'`. */
153
+ side?: 'start' | 'end';
154
+ /** The content pane's contents. */
155
+ children: ReactNode;
156
+ /** Names the sidebar pane, and through it the seam. Default `'Sidebar'`. */
157
+ label?: string;
158
+ /** Extra classes on the strip, which always has `lk-split`. */
159
+ className?: string;
160
+ /** The class on the sidebar pane. */
161
+ sidebarClassName?: string;
162
+ /** The class on the content pane. */
163
+ contentClassName?: string;
164
+ /** The sidebar's current extent in pixels. Omit to leave it unpersisted: the
165
+ * seam still works, its result just does not outlive the mount. */
166
+ width?: number;
167
+ /** Where the sidebar starts before anyone drags it. */
168
+ defaultWidth?: number;
169
+ minWidth?: number;
170
+ maxWidth?: number;
171
+ /** How little the content pane may be squeezed to. Reported as the seam's
172
+ * reachable maximum, so the drag stops there rather than clamping silently. */
173
+ contentMinWidth?: number;
174
+ /** Fires through the drag, not on release: the pane is already there. */
175
+ onWidthChange?: (width: number) => void;
176
+ /**
177
+ * Fixed extent. Omit in an app — the strip measures its own box. Supply it
178
+ * where nothing measures, notably jsdom, or both panes lay out at zero.
179
+ */
180
+ viewport?: {
181
+ w: number;
182
+ h: number;
183
+ };
184
+ }
185
+ /**
186
+ * A sidebar and a content pane as a two-pane strip with a draggable seam.
187
+ *
188
+ * The seam is `stripStrategy`'s own resize affordance, so it arrives as a
189
+ * `role="separator"` carrying the reachable range, operable by pointer and by
190
+ * arrows / Home / End, and clamped against the content pane's floor rather
191
+ * than against the sidebar's alone.
192
+ */
193
+ declare function Split({ sidebar, children, side, label, className, sidebarClassName, contentClassName, width, defaultWidth, minWidth, maxWidth, contentMinWidth, onWidthChange, viewport, }: SplitProps): react.JSX.Element;
194
+
195
+ /** Props for `<StatusBar>`. */
196
+ interface StatusBarProps {
197
+ children: ReactNode;
198
+ }
199
+ /** A footer strip for readouts. Fill it with `<StatusBar.Section>`. */
200
+ declare function StatusBar({ children }: StatusBarProps): react.JSX.Element;
201
+ declare namespace StatusBar {
202
+ var Section: ({ children, end }: StatusBarSectionProps) => react.JSX.Element;
203
+ }
204
+ /** Props for `<StatusBar.Section>`. */
205
+ interface StatusBarSectionProps {
206
+ children: ReactNode;
207
+ /** Pushes this section, and everything after it, to the far end. */
208
+ end?: boolean;
209
+ }
210
+
211
+ /** Props for `<Toolbar>`. */
212
+ interface ToolbarProps {
213
+ children: ReactNode;
214
+ /** Names the toolbar for assistive tech. Required by the APG pattern when a
215
+ * view holds more than one. */
216
+ 'aria-label'?: string;
217
+ }
218
+ /** A horizontal bar of controls. Fill it with `<Toolbar.Title>`,
219
+ * `<Toolbar.Group>`, `<Toolbar.Button>` and `<Toolbar.Spacer>`. */
220
+ declare function Toolbar({ children, 'aria-label': ariaLabel }: ToolbarProps): react.JSX.Element;
221
+ declare namespace Toolbar {
222
+ var Title: ({ children }: TitleProps) => react.JSX.Element;
223
+ var Group: ({ children, end, "aria-label": ariaLabel }: ToolbarGroupProps) => react.JSX.Element;
224
+ var Button: ({ children, onClick, disabled, title, "aria-label": ariaLabel, variant, iconOnly, pressed, }: ToolbarButtonProps) => react.JSX.Element;
225
+ var Spacer: () => react.JSX.Element;
226
+ }
227
+ interface TitleProps {
228
+ children: ReactNode;
229
+ }
230
+ /** Props for `<Toolbar.Group>`. */
231
+ interface ToolbarGroupProps {
232
+ children: ReactNode;
233
+ /** Pushes this group, and everything after it, to the far end. */
234
+ end?: boolean;
235
+ 'aria-label'?: string;
236
+ }
237
+ /** Props for `<Toolbar.Button>`. */
238
+ interface ToolbarButtonProps {
239
+ children: ReactNode;
240
+ onClick: MouseEventHandler<HTMLButtonElement>;
241
+ disabled?: boolean;
242
+ title?: string;
243
+ /** Required when `children` is an icon with no text of its own. */
244
+ 'aria-label'?: string;
245
+ /** `danger` reddens on hover — for actions that discard work. */
246
+ variant?: 'default' | 'danger';
247
+ /** Square, for a button whose whole content is one glyph. */
248
+ iconOnly?: boolean;
249
+ /** Makes this a toggle: `aria-pressed`, and held down while true. */
250
+ pressed?: boolean;
251
+ }
252
+
253
+ /** Props for `<ZoomControl>`. */
254
+ interface ZoomControlProps {
255
+ /** Current zoom as a scale factor: 1 is actual size. */
256
+ zoom: number;
257
+ /** Fired continuously while the slider drags. */
258
+ onZoomChange: (zoom: number) => void;
259
+ /** Fired when a drag settles or the field is committed. Defaults to
260
+ * `onZoomChange`. */
261
+ onZoomCommit?: (zoom: number) => void;
262
+ /** Smallest selectable zoom. Defaults to 0.1 (10%). */
263
+ min?: number;
264
+ /** Largest selectable zoom. Defaults to 8 (800%). */
265
+ max?: number;
266
+ className?: string;
267
+ }
268
+ /** Zoom as a log-scaled slider with an editable percentage beside it. Pair it
269
+ * with zoom-in / zoom-out buttons in a `<Toolbar.Group>`; this component owns
270
+ * only the continuous part. */
271
+ declare function ZoomControl({ zoom, onZoomChange, onZoomCommit, min: minProp, max: maxProp, className, }: ZoomControlProps): react.JSX.Element;
272
+
273
+ export { DetailList as D, FpsMeter as F, JobProgress as J, Legend as L, Readout as R, Toolbar as T, ZoomControl as Z, DetailRow as d, ScaleIndicator as m, Split as o, StatusBar as p };
274
+ export type { SplitProps as S, DetailListLayout as a, DetailListProps as b, DetailListValues as c, DetailRowProps as e, DetailRowStatus as f, JobProgressProps as g, LegendEntry as h, LegendMark as i, LegendProps as j, ReadoutProps as k, ReadoutRow as l, ScaleIndicatorProps as n, StatusBarProps as q, StatusBarSectionProps as r, ToolbarButtonProps as s, ToolbarGroupProps as t, ToolbarProps as u, ZoomControlProps as v };
@@ -1,6 +1,5 @@
1
- import { C as ControlRenderer, d as ConfigRule } from './types-B7y8hX1D.js';
2
- import { O as Instrument, as as TrialChromeContext, R as TrialContribution, T as TrialRecord, t as InstrumentList, g as SavedSnapshot, s as LabMode, aq as ToolSlotContext, a6 as ContributionBase, ar as ToolbarItem, ap as ToolItem, aj as SidebarSection, am as StatusReadout, K as TrialTool, af as RegionContribution, ak as SidebarSlotContext } from './frac-DTRq7Xpb.js';
3
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import { d as ControlRenderer, c as ConfigRule } from './types-CRPSGFAp.js';
2
+ import { R as Instrument, ax as TrialChromeContext, Y as TrialContribution, T as TrialRecord, t as InstrumentList, f as SavedSnapshot, s as LabMode, av as ToolSlotContext, a9 as ContributionBase, aw as ToolbarItem, au as ToolItem, ao as SidebarSection, ar as StatusReadout, O as TrialTool, ak as RegionContribution, ap as SidebarSlotContext } from './types-CSm9jgol.js';
4
3
  import * as react from 'react';
5
4
  import { ReactNode } from 'react';
6
5
 
@@ -142,15 +141,15 @@ interface LabRegionProps {
142
141
  contributions: readonly LabContribution[];
143
142
  }
144
143
  /** The lab's action bar, in the shell header beside the title. */
145
- declare function LabHeaderRegion({ contributions }: LabRegionProps): react_jsx_runtime.JSX.Element;
144
+ declare function LabHeaderRegion({ contributions }: LabRegionProps): react.JSX.Element;
146
145
  /** The lab's sidebar sections. Fold state is a lab-scoped persisted value, so it
147
146
  * survives a reload in a stored lab and lasts the session in an unstored one. */
148
- declare function LabSidebarRegion({ contributions }: LabRegionProps): react_jsx_runtime.JSX.Element;
147
+ declare function LabSidebarRegion({ contributions }: LabRegionProps): react.JSX.Element;
149
148
  /** The lab's aside sections, on the far side of the workspace from the sidebar.
150
149
  * Fold state persists the way the sidebar's does. */
151
- declare function LabAsideRegion({ contributions }: LabRegionProps): react_jsx_runtime.JSX.Element;
150
+ declare function LabAsideRegion({ contributions }: LabRegionProps): react.JSX.Element;
152
151
  /** The lab's readouts, in the shell footer below the workspace. */
153
- declare function LabFooterRegion({ contributions }: LabRegionProps): react_jsx_runtime.JSX.Element;
152
+ declare function LabFooterRegion({ contributions }: LabRegionProps): react.JSX.Element;
154
153
 
155
154
  /**
156
155
  * Concatenate contribution bundles into one list, preserving order — order
@@ -183,7 +182,7 @@ interface PaletteRegionProps<TCtx extends ToolSlotContext = TrialChromeContext>
183
182
  /** A tool strip: a trial's, or the lab's. Selection lives in whichever tool
184
183
  * slot the context carries; this region only reflects it. An item carrying
185
184
  * `onActivate` is a command instead — it presses, and never latches. */
186
- declare function PaletteRegion<TCtx extends ToolSlotContext = TrialChromeContext>({ contributions, ctx, region, }: PaletteRegionProps<TCtx>): react_jsx_runtime.JSX.Element | null;
185
+ declare function PaletteRegion<TCtx extends ToolSlotContext = TrialChromeContext>({ contributions, ctx, region, }: PaletteRegionProps<TCtx>): react.JSX.Element | null;
187
186
 
188
187
  /** Props for `<SidebarRegion>`. */
189
188
  interface SidebarRegionProps<TCtx extends SidebarSlotContext = TrialChromeContext> {
@@ -196,7 +195,7 @@ interface SidebarRegionProps<TCtx extends SidebarSlotContext = TrialChromeContex
196
195
  * trial's, or the lab's. A section the trial has torn out is not rendered
197
196
  * here — `Trial` portals its body into the workspace instead. A context with
198
197
  * no `undockPanel` offers no tear-out. */
199
- declare function SidebarRegion<TCtx extends SidebarSlotContext = TrialChromeContext>({ contributions, ctx, region, }: SidebarRegionProps<TCtx>): react_jsx_runtime.JSX.Element | null;
198
+ declare function SidebarRegion<TCtx extends SidebarSlotContext = TrialChromeContext>({ contributions, ctx, region, }: SidebarRegionProps<TCtx>): react.JSX.Element | null;
200
199
 
201
200
  /** Props for `<StatusRegion>`. */
202
201
  interface StatusRegionProps<TCtx = TrialChromeContext> {
@@ -206,7 +205,7 @@ interface StatusRegionProps<TCtx = TrialChromeContext> {
206
205
  region?: string;
207
206
  }
208
207
  /** Lays a bar's readouts out. */
209
- declare function StatusRegion<TCtx = TrialChromeContext>({ contributions, ctx, region, }: StatusRegionProps<TCtx>): react_jsx_runtime.JSX.Element | null;
208
+ declare function StatusRegion<TCtx = TrialChromeContext>({ contributions, ctx, region, }: StatusRegionProps<TCtx>): react.JSX.Element | null;
210
209
 
211
210
  /** Which end of the title bar a `<TitleBarRegion>` lays out: `'lead'` renders
212
211
  * the contributions that leave `end` unset, before the title; `'actions'`
@@ -220,7 +219,7 @@ interface TitleBarRegionProps {
220
219
  placement?: TitleBarPlacement;
221
220
  }
222
221
  /** Lays a trial's `titlebar` contributions out at one end of the bar. */
223
- declare function TitleBarRegion({ contributions, ctx, placement }: TitleBarRegionProps): react_jsx_runtime.JSX.Element | null;
222
+ declare function TitleBarRegion({ contributions, ctx, placement }: TitleBarRegionProps): react.JSX.Element | null;
224
223
 
225
224
  /** Props for `<ToolbarRegion>`. */
226
225
  interface ToolbarRegionProps<TCtx = TrialChromeContext> {
@@ -232,7 +231,7 @@ interface ToolbarRegionProps<TCtx = TrialChromeContext> {
232
231
  label?: string;
233
232
  }
234
233
  /** Lays a bar's contributions out, grouped by their `group`. */
235
- declare function ToolbarRegion<TCtx = TrialChromeContext>({ contributions, ctx, region, label, }: ToolbarRegionProps<TCtx>): react_jsx_runtime.JSX.Element | null;
234
+ declare function ToolbarRegion<TCtx = TrialChromeContext>({ contributions, ctx, region, label, }: ToolbarRegionProps<TCtx>): react.JSX.Element | null;
236
235
 
237
236
  /** Props for `<ViewportRegion>`. */
238
237
  interface ViewportRegionProps {
@@ -243,7 +242,7 @@ interface ViewportRegionProps {
243
242
  * Controls acting on the view of a trial. Anchored inside the content well
244
243
  * rather than in the toolbar, which acts on the trial itself.
245
244
  */
246
- declare function ViewportRegion({ contributions, ctx }: ViewportRegionProps): react_jsx_runtime.JSX.Element | null;
245
+ declare function ViewportRegion({ contributions, ctx }: ViewportRegionProps): react.JSX.Element | null;
247
246
 
248
247
  export { resetTrial as B, suppressContributions as C, toolContributions as D, useLabChromeContext as E, useLabContext as F, PaletteRegion as P, SidebarRegion as S, ViewportRegion as V, LabAsideRegion as a, LabContext as c, LabFooterRegion as e, LabHeaderRegion as f, LabSidebarRegion as i, StatusRegion as l, TitleBarRegion as n, ToolbarRegion as p, addTrial as s, builtinContributions as t, cloneTrial as u, closeTrial as v, contributionsIn as w, labContributions as x, mergeContributions as y, reorderTrials as z };
249
248
  export type { AddTrialOptions as A, LabContribution as L, TitleBarPlacement as T, LabChromeContext as b, LabContextValue as d, LabRegion as g, LabRegionProps as h, PaletteRegionProps as j, SidebarRegionProps as k, StatusRegionProps as m, TitleBarRegionProps as o, ToolbarRegionProps as q, ViewportRegionProps as r };
@@ -1,5 +1,6 @@
1
- import { ToolPrefNumberFormat, ToolPrefNumberUnit, ToolPrefLeaf, ToolPrefGroup } from '@weasel-js/core';
2
- import { P as PrefRenderer } from './PrefsRow.d-DFpPIeIC.js';
1
+ import { D as Display, P as PrefRenderer } from './PrefsRow.d-TOZ7BgD9.js';
2
+ import { ReactNode } from 'react';
3
+ import { ToolPrefNumberUnit, ToolPrefLeaf, ToolPrefGroup } from '@weasel-js/core';
3
4
 
4
5
  /**
5
6
  * Renders the control cell for one config leaf. Identical to weasel-ui's
@@ -11,6 +12,9 @@ type ControlRenderer = PrefRenderer;
11
12
  interface ConfigOption {
12
13
  value: string;
13
14
  label: string;
15
+ /** A glyph in weasel-ui's icon set (`IconName`). A segmented row draws it in
16
+ * place of `label`, which stays the accessible name and becomes the tooltip. */
17
+ icon?: string;
14
18
  }
15
19
  /** Everything a leaf can carry beyond its kind and default. A flat union of
16
20
  * every `Pref*` leaf's extras, plus labkit's own `debounceMs`. */
@@ -24,8 +28,8 @@ interface Annotations {
24
28
  max?: number;
25
29
  step?: number;
26
30
  suffix?: string;
27
- /** How a number's value is shown. `compact` abbreviates from a thousand up. */
28
- format?: ToolPrefNumberFormat;
31
+ /** How a number's value shows, speaks and reads back — `compact()` reads `2.00M`. */
32
+ display?: Display;
29
33
  /** Display-unit conversion for a number stored in a canonical unit — the
30
34
  * value, its bounds and its step all convert at the control's edge. */
31
35
  unit?: ToolPrefNumberUnit;
@@ -94,6 +98,24 @@ interface ResolvedConfig {
94
98
  showIf: ReadonlyMap<string, (config: Record<string, unknown>) => boolean>;
95
99
  /** Node-level `.render` overrides, keyed by path. */
96
100
  renderers: Readonly<Record<string, ControlRenderer>>;
101
+ /** Node-level `.dialog` rows, keyed by path. */
102
+ dialogs: Readonly<Record<string, DialogSpec>>;
103
+ /** Paths of the groups marked `.resettable()`, whose heading carries a
104
+ * button that puts every value beneath it back to its default. */
105
+ resettable?: ReadonlySet<string>;
106
+ }
107
+ /** Options for a row drawn as a button that opens a dialog. */
108
+ interface InDialogOptions {
109
+ /** What the row's button shows of the value. Defaults to a list joined with
110
+ * commas, or the value itself. */
111
+ summary?: (value: unknown) => ReactNode;
112
+ /** The dialog's heading. Defaults to the row's label. */
113
+ title?: ReactNode;
114
+ }
115
+ /** A `.dialog` row: `body` is the dialog's content, handed the context a row
116
+ * renderer gets. */
117
+ interface DialogSpec extends InDialogOptions {
118
+ body: ControlRenderer;
97
119
  }
98
120
  /** How a node names the section it belongs to: the heading, and how that
99
121
  * section opens. Every node in one section repeats the heading; only one of
@@ -109,6 +131,9 @@ interface SectionOption {
109
131
  /** Per-node extras that do not belong on a `PrefLeaf`. */
110
132
  interface NodeOptions extends BranchOptions {
111
133
  render?: ControlRenderer;
134
+ /** Draw the row as a button that opens a dialog. Set by `.dialog`; the
135
+ * config entry records it, and `ControlPanel` draws it. */
136
+ dialog?: DialogSpec;
112
137
  /** Errors for this leaf under `config`, the instrument's whole config. */
113
138
  validate?: (leaf: ToolPrefLeaf, config: Record<string, unknown>) => string[];
114
139
  /** Computes this leaf's value while it is auto. Attaching one is what gives
@@ -128,6 +153,9 @@ interface BranchOptions {
128
153
  /** Show this node only while the predicate holds. On a group it hides the
129
154
  * whole subtree; the values stay in config either way. */
130
155
  showIf?: (config: Record<string, unknown>) => boolean;
156
+ /** Put a button on this group's heading that returns every value beneath it
157
+ * to its default. Groups only. */
158
+ resettable?: boolean;
131
159
  }
132
160
  /** A group's own annotations: what it is called and, optionally, why. */
133
161
  interface BranchAnnotations {
@@ -250,4 +278,4 @@ interface ColorField extends ConfigFieldBase {
250
278
  * panel renders, and what `validateConfigSchema` checks. */
251
279
  type ConfigField = SliderField | CheckboxField | SelectField | NumberField | TextField | ColorField;
252
280
 
253
- export type { Annotations as A, BranchAnnotations as B, ControlRenderer as C, EntryValue as E, InferConfig as I, LeafPatch as L, NodeOptions as N, ResolvedConfig as R, SectionSpec as S, TextField as T, ValueAtPath as V, ConfigPath as a, ConfigField as b, ConfigSchema as c, ConfigRule as d, BranchOptions as e, CheckboxField as f, ColorField as g, ConfigBranch as h, ConfigEntry as i, ConfigFieldBase as j, ConfigFieldType as k, ConfigNode as l, ConfigOf as m, ConfigOption as n, ConfigRuleContext as o, ConfigShape as p, NodeValue as q, NumberField as r, SelectField as s, SelectOption as t, SliderField as u, SectionOption as v };
281
+ export type { Annotations as A, BranchAnnotations as B, ConfigPath as C, DialogSpec as D, EntryValue as E, InDialogOptions as I, LeafPatch as L, NodeOptions as N, ResolvedConfig as R, SectionOption as S, TextField as T, ValueAtPath as V, ConfigField as a, ConfigSchema as b, ConfigRule as c, ControlRenderer as d, BranchOptions as e, CheckboxField as f, ColorField as g, ConfigBranch as h, ConfigEntry as i, ConfigFieldBase as j, ConfigFieldType as k, ConfigNode as l, ConfigOf as m, ConfigOption as n, ConfigRuleContext as o, ConfigShape as p, InferConfig as q, NodeValue as r, NumberField as s, SectionSpec as t, SelectField as u, SelectOption as v, SliderField as w };