@weasel-js/labkit 1.6.1 → 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 (162) hide show
  1. package/dist/_dts/{CanvasStackContext-Wo6OwIVM.d.ts → CanvasStackContext-D2jnIwfk.d.ts} +1 -1
  2. package/dist/_dts/{LayerList.d-BoELAMsM.d.ts → LayerList.d-DiuEArKq.d.ts} +2 -2
  3. package/dist/_dts/PrefsRow.d-TOZ7BgD9.d.ts +79 -0
  4. package/dist/_dts/PropertyPanel.d-D-1paCbE.d.ts +141 -0
  5. package/dist/_dts/{Select.d-Cr8-zoup.d.ts → Select.d-Bensr_MT.d.ts} +11 -1
  6. package/dist/_dts/{Stage-DWBBi8IU.d.ts → Stage-CCWfQQWM.d.ts} +58 -18
  7. package/dist/_dts/index-B2Yj5aA0.d.ts +274 -0
  8. package/dist/_dts/{index-CKyX0ME_.d.ts → index-CsYqUHD3.d.ts} +2 -2
  9. package/dist/_dts/{types-DTuViBvc.d.ts → types-CRPSGFAp.d.ts} +13 -4
  10. package/dist/_dts/{types-B7yBTTF9.d.ts → types-CSm9jgol.d.ts} +2 -2
  11. package/dist/_dts/{useTrialState-CMaV6UD4.d.ts → useTrialState-CTZPgeZ7.d.ts} +1 -1
  12. package/dist/canvas/index.d.ts +6 -6
  13. package/dist/canvas/index.js +2 -2
  14. package/dist/chrome/index.d.ts +5 -5
  15. package/dist/chrome/index.js +8 -8
  16. package/dist/{chunk-QGMOA2YE.js → chunk-275JRRVD.js} +67 -70
  17. package/dist/chunk-275JRRVD.js.map +1 -0
  18. package/dist/{chunk-KHK5FGER.js → chunk-4LJSC7MB.js} +8 -10
  19. package/dist/chunk-4LJSC7MB.js.map +1 -0
  20. package/dist/{chunk-SLAQPUI4.js → chunk-7BO7HNGF.js} +5 -5
  21. package/dist/{chunk-SLAQPUI4.js.map → chunk-7BO7HNGF.js.map} +1 -1
  22. package/dist/chunk-CZZPXUOU.js +3 -0
  23. package/dist/{chunk-SBXNQW4G.js.map → chunk-CZZPXUOU.js.map} +1 -1
  24. package/dist/{chunk-6FLXL3I7.js → chunk-FMK7UQ6V.js} +19 -4
  25. package/dist/chunk-FMK7UQ6V.js.map +1 -0
  26. package/dist/{chunk-O6FFFOHS.js → chunk-FZ7YFQN7.js} +16 -8
  27. package/dist/chunk-FZ7YFQN7.js.map +1 -0
  28. package/dist/{chunk-GHGO52SO.js → chunk-GOZLNM4L.js} +5 -5
  29. package/dist/{chunk-GHGO52SO.js.map → chunk-GOZLNM4L.js.map} +1 -1
  30. package/dist/{chunk-4TT3PNPR.js → chunk-I5DUQ5HM.js} +33 -36
  31. package/dist/chunk-I5DUQ5HM.js.map +1 -0
  32. package/dist/{chunk-NEXR37YJ.js → chunk-J7OWWTCW.js} +4 -5
  33. package/dist/chunk-J7OWWTCW.js.map +1 -0
  34. package/dist/{chunk-IRTGUQ5O.js → chunk-KMJ7RWD3.js} +16 -6
  35. package/dist/chunk-KMJ7RWD3.js.map +1 -0
  36. package/dist/{chunk-S4NCI32V.js → chunk-M7HP3FTK.js} +4 -4
  37. package/dist/{chunk-S4NCI32V.js.map → chunk-M7HP3FTK.js.map} +1 -1
  38. package/dist/chunk-MIM5R4ZT.js +14972 -0
  39. package/dist/chunk-MIM5R4ZT.js.map +1 -0
  40. package/dist/{chunk-ASOK76ZH.js → chunk-T5IBSPAM.js} +59 -26
  41. package/dist/chunk-T5IBSPAM.js.map +1 -0
  42. package/dist/{chunk-DWMSB4CA.js → chunk-UNAZSLWE.js} +82 -16
  43. package/dist/chunk-UNAZSLWE.js.map +1 -0
  44. package/dist/{chunk-TJ77A4A3.js → chunk-Y23G2VZL.js} +5 -9
  45. package/dist/chunk-Y23G2VZL.js.map +1 -0
  46. package/dist/{chunk-HKV7LRHY.js → chunk-YT75VYRD.js} +4 -4
  47. package/dist/{chunk-HKV7LRHY.js.map → chunk-YT75VYRD.js.map} +1 -1
  48. package/dist/{chunk-CGHF6RZV.js → chunk-ZIFPHIWZ.js} +9 -7
  49. package/dist/chunk-ZIFPHIWZ.js.map +1 -0
  50. package/dist/config/index.d.ts +16 -9
  51. package/dist/config/index.js +4 -4
  52. package/dist/controls/index.d.ts +2 -2
  53. package/dist/controls/index.js +5 -5
  54. package/dist/dragdrop/index.d.ts +3 -3
  55. package/dist/index.d.ts +263 -24
  56. package/dist/index.js +376 -237
  57. package/dist/index.js.map +1 -1
  58. package/dist/layers/index.d.ts +4 -4
  59. package/dist/layers/index.js +2 -2
  60. package/dist/loupe/index.d.ts +4 -4
  61. package/dist/loupe/index.js +2 -2
  62. package/dist/overview/index.d.ts +2 -2
  63. package/dist/overview/index.js +9 -8
  64. package/dist/overview/index.js.map +1 -1
  65. package/dist/passthrough/weasel-ui.d.ts +208 -38
  66. package/dist/passthrough/weasel-ui.js +3 -3
  67. package/dist/primitives/index.d.ts +3 -178
  68. package/dist/primitives/index.js +6 -6
  69. package/dist/state/index.d.ts +5 -5
  70. package/dist/state/index.js +4 -4
  71. package/dist/styles.css +91 -83
  72. package/dist/undo/index.d.ts +3 -3
  73. package/package.json +13 -12
  74. package/src/annotations/AnnotationOverlay.tsx +2 -2
  75. package/src/annotations/Annotations.less +0 -10
  76. package/src/annotations/MarkList.tsx +4 -8
  77. package/src/annotations/paint.test.ts +3 -14
  78. package/src/annotations/paint.ts +3 -19
  79. package/src/annotations/svgNodes.test.ts +6 -9
  80. package/src/annotations/svgNodes.ts +3 -3
  81. package/src/canvas/AGENTS.md +1 -0
  82. package/src/canvas/CameraInput.tsx +44 -33
  83. package/src/canvas/CanvasStack.tsx +6 -1
  84. package/src/canvas/LinkedCursor.less +1 -1
  85. package/src/canvas/Stage.test.tsx +33 -4
  86. package/src/canvas/Stage.tsx +6 -1
  87. package/src/canvas/cameraRegistry.test.ts +55 -0
  88. package/src/canvas/cameraRegistry.ts +86 -0
  89. package/src/canvas/cameraZoom.test.ts +46 -0
  90. package/src/canvas/cameraZoom.ts +24 -0
  91. package/src/canvas/index.ts +14 -2
  92. package/src/canvas/sharedScope.test.tsx +94 -0
  93. package/src/chrome/ChromeRegions.stories.tsx +1 -0
  94. package/src/chrome/regions/PaletteRegion.less +0 -7
  95. package/src/chrome/regions/SidebarRegion.less +12 -2
  96. package/src/config/builder.test.ts +2 -1
  97. package/src/config/builder.ts +12 -5
  98. package/src/config/fromConfigField.test.ts +14 -0
  99. package/src/config/fromConfigField.ts +18 -4
  100. package/src/config/path.ts +2 -5
  101. package/src/config/resolve.ts +4 -0
  102. package/src/config/types.ts +13 -9
  103. package/src/controls/ControlPanel.less +1 -1
  104. package/src/controls/ControlPanel.stories.tsx +3 -2
  105. package/src/controls/ControlPanel.test.tsx +64 -11
  106. package/src/controls/ControlPanel.tsx +52 -2
  107. package/src/index.ts +15 -1
  108. package/src/lab/Lab.tsx +83 -72
  109. package/src/lab/{LabFit.stories.less → LabFit.browser.test.less} +1 -1
  110. package/src/lab/{LabFit.stories.tsx → LabFit.browser.test.tsx} +41 -63
  111. package/src/lab/LabFullChrome.stories.tsx +1 -0
  112. package/src/lab/LabHeader.test.tsx +24 -14
  113. package/src/lab/LabHeader.tsx +11 -12
  114. package/src/lab/LabShell.less +8 -17
  115. package/src/lab/LabSwitcher.less +6 -6
  116. package/src/lab/LabZoom.test.tsx +223 -0
  117. package/src/lab/LabZoom.tsx +170 -0
  118. package/src/lab/index.ts +1 -0
  119. package/src/loupe/LoupeGestures.tsx +1 -1
  120. package/src/overview/TrialOverview.tsx +7 -5
  121. package/src/passthrough/weasel-ui.test.ts +2 -0
  122. package/src/passthrough/weasel-ui.ts +16 -4
  123. package/src/primitives/FloatingPanel.test.tsx +11 -0
  124. package/src/primitives/FloatingPanel.tsx +2 -5
  125. package/src/primitives/JobProgress.less +1 -1
  126. package/src/primitives/Legend.stories.tsx +1 -0
  127. package/src/primitives/Readout.browser.test.tsx +137 -0
  128. package/src/primitives/Readout.less +12 -0
  129. package/src/primitives/Readout.stories.tsx +58 -0
  130. package/src/primitives/Readout.test.tsx +93 -0
  131. package/src/primitives/Readout.tsx +56 -0
  132. package/src/primitives/index.ts +2 -0
  133. package/src/specimen/Specimen.stories.tsx +1 -0
  134. package/src/specimen/Specimen.tsx +2 -2
  135. package/src/state/Persistence.browser.test.tsx +47 -0
  136. package/src/state/store.test.ts +5 -1
  137. package/src/state/usePersistedState.test.tsx +1 -1
  138. package/src/styles.less +1 -0
  139. package/src/theme/Interstellar.stories.tsx +3 -1
  140. package/src/theme/base.less +21 -47
  141. package/src/theme/interstellar.test.ts +1 -1
  142. package/src/theme/interstellar.theme.json +10 -3
  143. package/src/trial/Trial.less +0 -13
  144. package/src/trial/Trial.tsx +12 -6
  145. package/src/trial/TrialChrome.tsx +21 -3
  146. package/dist/_dts/PrefsRow.d-DFpPIeIC.d.ts +0 -39
  147. package/dist/_dts/PropertyField.d-D0ndfIIt.d.ts +0 -404
  148. package/dist/chunk-4TT3PNPR.js.map +0 -1
  149. package/dist/chunk-6FLXL3I7.js.map +0 -1
  150. package/dist/chunk-ASOK76ZH.js.map +0 -1
  151. package/dist/chunk-CGHF6RZV.js.map +0 -1
  152. package/dist/chunk-DWMSB4CA.js.map +0 -1
  153. package/dist/chunk-IRTGUQ5O.js.map +0 -1
  154. package/dist/chunk-KHK5FGER.js.map +0 -1
  155. package/dist/chunk-NEXR37YJ.js.map +0 -1
  156. package/dist/chunk-O6FFFOHS.js.map +0 -1
  157. package/dist/chunk-QGMOA2YE.js.map +0 -1
  158. package/dist/chunk-SBXNQW4G.js +0 -3
  159. package/dist/chunk-TJ77A4A3.js.map +0 -1
  160. package/dist/chunk-TYN6MLXX.js +0 -13864
  161. package/dist/chunk-TYN6MLXX.js.map +0 -1
  162. 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,5 +1,5 @@
1
- import { d as ControlRenderer, c as ConfigRule } from './types-DTuViBvc.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-B7yBTTF9.js';
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';
3
3
  import * as react from 'react';
4
4
  import { ReactNode } from 'react';
5
5
 
@@ -1,6 +1,6 @@
1
+ import { D as Display, P as PrefRenderer } from './PrefsRow.d-TOZ7BgD9.js';
1
2
  import { ReactNode } from 'react';
2
- import { ToolPrefNumberFormat, ToolPrefNumberUnit, ToolPrefLeaf, ToolPrefGroup } from '@weasel-js/core';
3
- import { P as PrefRenderer } from './PrefsRow.d-DFpPIeIC.js';
3
+ import { ToolPrefNumberUnit, ToolPrefLeaf, ToolPrefGroup } from '@weasel-js/core';
4
4
 
5
5
  /**
6
6
  * Renders the control cell for one config leaf. Identical to weasel-ui's
@@ -12,6 +12,9 @@ type ControlRenderer = PrefRenderer;
12
12
  interface ConfigOption {
13
13
  value: string;
14
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;
15
18
  }
16
19
  /** Everything a leaf can carry beyond its kind and default. A flat union of
17
20
  * every `Pref*` leaf's extras, plus labkit's own `debounceMs`. */
@@ -25,8 +28,8 @@ interface Annotations {
25
28
  max?: number;
26
29
  step?: number;
27
30
  suffix?: string;
28
- /** How a number's value is shown. `compact` abbreviates from a thousand up. */
29
- format?: ToolPrefNumberFormat;
31
+ /** How a number's value shows, speaks and reads back — `compact()` reads `2.00M`. */
32
+ display?: Display;
30
33
  /** Display-unit conversion for a number stored in a canonical unit — the
31
34
  * value, its bounds and its step all convert at the control's edge. */
32
35
  unit?: ToolPrefNumberUnit;
@@ -97,6 +100,9 @@ interface ResolvedConfig {
97
100
  renderers: Readonly<Record<string, ControlRenderer>>;
98
101
  /** Node-level `.dialog` rows, keyed by path. */
99
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>;
100
106
  }
101
107
  /** Options for a row drawn as a button that opens a dialog. */
102
108
  interface InDialogOptions {
@@ -147,6 +153,9 @@ interface BranchOptions {
147
153
  /** Show this node only while the predicate holds. On a group it hides the
148
154
  * whole subtree; the values stay in config either way. */
149
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;
150
159
  }
151
160
  /** A group's own annotations: what it is called and, optionally, why. */
152
161
  interface BranchAnnotations {
@@ -1,7 +1,7 @@
1
1
  import { DrawCommand, Scene, PointerContextValue } from '@weasel-js/core';
2
2
  import { RefObject, ComponentType, ReactNode } from 'react';
3
- import { S as StanceProps } from './PrefsRow.d-DFpPIeIC.js';
4
- import { R as ResolvedConfig, C as ConfigPath, V as ValueAtPath, a as ConfigField, b as ConfigSchema } from './types-DTuViBvc.js';
3
+ import { S as StanceProps } from './PrefsRow.d-TOZ7BgD9.js';
4
+ import { R as ResolvedConfig, C as ConfigPath, V as ValueAtPath, a as ConfigField, b as ConfigSchema } from './types-CRPSGFAp.js';
5
5
  import { ColorModePreference } from '@weasel-js/theme';
6
6
  import { J as JobHandle, a as JobCapability } from './types-DJ79Tg5J.js';
7
7
 
@@ -1,4 +1,4 @@
1
- import { c as StorageAdapter, e as LabStoreState, T as TrialRecord, f as SavedSnapshot, s as LabMode, i as UndockedPanel, t as InstrumentList, v as InstrumentHooks, C as CreateLabStoreOptions, h as TrialStateHandle } from './types-B7yBTTF9.js';
1
+ import { c as StorageAdapter, e as LabStoreState, T as TrialRecord, f as SavedSnapshot, s as LabMode, i as UndockedPanel, t as InstrumentList, v as InstrumentHooks, C as CreateLabStoreOptions, h as TrialStateHandle } from './types-CSm9jgol.js';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, ReactElement, Dispatch, SetStateAction } from 'react';
4
4
  import { StoreApi } from 'zustand/vanilla';
@@ -1,13 +1,13 @@
1
- export { C as CameraContext, a as CameraContextValue, b as CameraInput, c as CameraInputProps, d as CameraScope, e as CameraScopeContext, f as CameraViewOptions, g as CanvasStack, h as CanvasStackProps, S as STAGE_VIEW_ID, i as Stage, j as StageProps, Z as ZoomAtOptions, k as centerOn, l as fitStage, s as screenToWorld, u as useCameraView, w as worldToScreen, z as zoomAt } from '../_dts/Stage-DWBBi8IU.js';
1
+ export { C as CameraContext, a as CameraContextValue, b as CameraInput, c as CameraInputProps, d as CameraPublishContext, e as CameraRegistry, f as CameraRegistryContext, g as CameraScope, h as CameraView, i as CameraViewOptions, j as CanvasStack, k as CanvasStackProps, S as STAGE_VIEW_ID, l as Stage, m as StageProps, Z as ZoomAtOptions, n as ZoomRange, o as centerOn, p as createCameraRegistry, q as fitStage, s as screenToWorld, u as useCameraView, r as usePublishCamera, w as worldToScreen, z as zoomAt } from '../_dts/Stage-CCWfQQWM.js';
2
2
  import * as react from 'react';
3
- export { C as CanvasLayerDescriptor, a as CanvasStackContext, b as CanvasStackContextValue, c as CanvasStackSurface } from '../_dts/CanvasStackContext-Wo6OwIVM.js';
3
+ export { C as CanvasLayerDescriptor, a as CanvasStackContext, b as CanvasStackContextValue, c as CanvasStackSurface } from '../_dts/CanvasStackContext-D2jnIwfk.js';
4
4
  import { View } from '@weasel-js/core';
5
- import { W as WorldFrame } from '../_dts/types-B7yBTTF9.js';
5
+ import { W as WorldFrame } from '../_dts/types-CSm9jgol.js';
6
6
  import { Point, ViewTransform } from '../index.js';
7
- export { D as DEFAULT_FRAME, V as ViewportSize, l as WorldSpec, m as applyCamera, r as resolveFrame } from '../_dts/types-B7yBTTF9.js';
8
- import '../_dts/PrefsRow.d-DFpPIeIC.js';
7
+ export { D as DEFAULT_FRAME, V as ViewportSize, l as WorldSpec, m as applyCamera, r as resolveFrame } from '../_dts/types-CSm9jgol.js';
8
+ import '../_dts/PrefsRow.d-TOZ7BgD9.js';
9
9
  import '@weasel-js/theme';
10
- import '../_dts/types-DTuViBvc.js';
10
+ import '../_dts/types-CRPSGFAp.js';
11
11
  import '../_dts/types-DJ79Tg5J.js';
12
12
 
13
13
  /** Where a trial's camera takes a wheel event from outside its own element. */
@@ -1,8 +1,8 @@
1
- export { CanvasStack, LinkedCursor, Stage, fitStage } from '../chunk-CGHF6RZV.js';
1
+ export { CanvasStack, LinkedCursor, Stage, fitStage } from '../chunk-ZIFPHIWZ.js';
2
2
  export { centerOn, zoomAt } from '../chunk-JVBYV6TL.js';
3
3
  export { screenToWorld, worldToScreen } from '../chunk-AWQG7FCC.js';
4
4
  import '../chunk-WIG6XHJ7.js';
5
- export { CameraContext, CameraInput, CameraScope, CameraScopeContext, CameraWheelContext, STAGE_VIEW_ID, clampZoomAbout, frameLocalToWorld, fromCameraView, toCameraView, useCameraView } from '../chunk-DWMSB4CA.js';
5
+ export { CameraContext, CameraInput, CameraPublishContext, CameraRegistryContext, CameraScope, CameraWheelContext, STAGE_VIEW_ID, clampZoomAbout, createCameraRegistry, frameLocalToWorld, fromCameraView, toCameraView, useCameraView, usePublishCamera } from '../chunk-UNAZSLWE.js';
6
6
  export { DEFAULT_FRAME, applyCamera, resolveFrame } from '../chunk-24W5VEJW.js';
7
7
  export { CanvasStackContext } from '../chunk-CQLQPQ4P.js';
8
8
  import '../chunk-2YILQ7Y5.js';
@@ -1,8 +1,8 @@
1
- export { a as LabAsideRegion, b as LabChromeContext, L as LabContribution, 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, t as builtinContributions, w as contributionsIn, x as labContributions, y as mergeContributions, C as suppressContributions, D as toolContributions, E as useLabChromeContext } from '../_dts/index-CKyX0ME_.js';
2
- export { a9 as ContributionBase, ad as IconComponent, ak as RegionContribution, ao as SidebarSection, ap as SidebarSlotContext, ar as StatusReadout, au as ToolItem, av as ToolSlotContext, aw as ToolbarItem, ax as TrialChromeContext, Y as TrialContribution, ay as TrialRegion, aA as ViewportControl } from '../_dts/types-B7yBTTF9.js';
3
- import '../_dts/types-DTuViBvc.js';
1
+ export { a as LabAsideRegion, b as LabChromeContext, L as LabContribution, 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, t as builtinContributions, w as contributionsIn, x as labContributions, y as mergeContributions, C as suppressContributions, D as toolContributions, E as useLabChromeContext } from '../_dts/index-CsYqUHD3.js';
2
+ export { a9 as ContributionBase, ad as IconComponent, ak as RegionContribution, ao as SidebarSection, ap as SidebarSlotContext, ar as StatusReadout, au as ToolItem, av as ToolSlotContext, aw as ToolbarItem, ax as TrialChromeContext, Y as TrialContribution, ay as TrialRegion, aA as ViewportControl } from '../_dts/types-CSm9jgol.js';
3
+ import '../_dts/types-CRPSGFAp.js';
4
+ import '../_dts/PrefsRow.d-TOZ7BgD9.js';
5
+ import '@weasel-js/theme';
4
6
  import 'react';
5
7
  import '@weasel-js/core';
6
- import '../_dts/PrefsRow.d-DFpPIeIC.js';
7
- import '@weasel-js/theme';
8
8
  import '../_dts/types-DJ79Tg5J.js';
@@ -1,15 +1,15 @@
1
- export { LabAsideRegion, LabFooterRegion, LabHeaderRegion, LabSidebarRegion, PaletteRegion, SidebarRegion, StatusRegion, TitleBarRegion, ToolbarRegion, ViewportRegion, builtinContributions, contributionsIn, labContributions, mergeContributions, suppressContributions, toolContributions, useLabChromeContext } from '../chunk-4TT3PNPR.js';
1
+ export { LabAsideRegion, LabFooterRegion, LabHeaderRegion, LabSidebarRegion, PaletteRegion, SidebarRegion, StatusRegion, TitleBarRegion, ToolbarRegion, ViewportRegion, builtinContributions, contributionsIn, labContributions, mergeContributions, suppressContributions, toolContributions, useLabChromeContext } from '../chunk-I5DUQ5HM.js';
2
2
  import '../chunk-3RY6WL5T.js';
3
- import '../chunk-SLAQPUI4.js';
4
- import '../chunk-SBXNQW4G.js';
3
+ import '../chunk-7BO7HNGF.js';
4
+ import '../chunk-CZZPXUOU.js';
5
5
  import '../chunk-RWNDDKOH.js';
6
- import '../chunk-ASOK76ZH.js';
6
+ import '../chunk-T5IBSPAM.js';
7
7
  import '../chunk-Z76KEZAX.js';
8
- import '../chunk-IRTGUQ5O.js';
9
- import '../chunk-TJ77A4A3.js';
8
+ import '../chunk-KMJ7RWD3.js';
9
+ import '../chunk-Y23G2VZL.js';
10
10
  import '../chunk-CQLQPQ4P.js';
11
11
  import '../chunk-2YILQ7Y5.js';
12
- import '../chunk-TYN6MLXX.js';
13
- import '../chunk-QGMOA2YE.js';
12
+ import '../chunk-MIM5R4ZT.js';
13
+ import '../chunk-275JRRVD.js';
14
14
  //# sourceMappingURL=index.js.map
15
15
  //# sourceMappingURL=index.js.map