@weasel-js/labkit 1.5.1 → 1.6.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 (160) hide show
  1. package/README.md +3 -7
  2. package/dist/_dts/{CanvasStackContext-CJNMS6mz.d.ts → CanvasStackContext-DQgcH1ny.d.ts} +1 -1
  3. package/dist/_dts/LayerList.d-2c9yup5Y.d.ts +83 -0
  4. package/dist/_dts/{PrefsForm.d-DPy9I8It.d.ts → PrefsRow.d-DFpPIeIC.d.ts} +16 -1
  5. package/dist/_dts/{Select.d-Gwr8fLpK.d.ts → Select.d-BchGMC2Y.d.ts} +129 -12
  6. package/dist/_dts/{frac-B4okC2lX.d.ts → frac-DTRq7Xpb.d.ts} +31 -13
  7. package/dist/_dts/inDialog-D5ZKGjiD.d.ts +23 -0
  8. package/dist/_dts/{index-CSJoj4LC.d.ts → index-B0--8PEM.d.ts} +5 -4
  9. package/dist/_dts/index-DINmCuLA.d.ts +453 -0
  10. package/dist/_dts/number.d-OeQYQoUO.d.ts +28 -0
  11. package/dist/_dts/{types-DzoNY1pO.d.ts → types-B7y8hX1D.d.ts} +6 -6
  12. package/dist/_dts/{usePanZoom-Pzf9f2jh.d.ts → usePanZoom-Bq73pwFe.d.ts} +4 -47
  13. package/dist/_dts/{useTrialState-uLlmaccn.d.ts → useTrialState-CP4jfuKl.d.ts} +1 -1
  14. package/dist/canvas/index.d.ts +6 -5
  15. package/dist/canvas/index.js +1 -1
  16. package/dist/chrome/index.d.ts +5 -4
  17. package/dist/chrome/index.js +7 -7
  18. package/dist/chunk-2RVCB2PT.js +3 -0
  19. package/dist/chunk-2RVCB2PT.js.map +1 -0
  20. package/dist/{chunk-UN4U4P63.js → chunk-3FI7Y4R4.js} +9 -9
  21. package/dist/chunk-3FI7Y4R4.js.map +1 -0
  22. package/dist/{chunk-7PFH3CNM.js → chunk-AWH3SRPW.js} +31 -5
  23. package/dist/chunk-AWH3SRPW.js.map +1 -0
  24. package/dist/{chunk-ZDHY47EV.js → chunk-BVL7Y574.js} +25 -9
  25. package/dist/chunk-BVL7Y574.js.map +1 -0
  26. package/dist/{chunk-IHUVQ3TX.js → chunk-H5VIV7MQ.js} +31 -27
  27. package/dist/chunk-H5VIV7MQ.js.map +1 -0
  28. package/dist/chunk-HFRE4QQV.js +400 -0
  29. package/dist/chunk-HFRE4QQV.js.map +1 -0
  30. package/dist/{chunk-IXTQI7JX.js → chunk-MOLIUNVH.js} +4 -4
  31. package/dist/{chunk-IXTQI7JX.js.map → chunk-MOLIUNVH.js.map} +1 -1
  32. package/dist/{chunk-CEIUBPPW.js → chunk-TT5C5S6R.js} +3 -86
  33. package/dist/chunk-TT5C5S6R.js.map +1 -0
  34. package/dist/chunk-USO6TERP.js +90 -0
  35. package/dist/chunk-USO6TERP.js.map +1 -0
  36. package/dist/{chunk-PHK4W562.js → chunk-VQ47KWD5.js} +3 -3
  37. package/dist/{chunk-PHK4W562.js.map → chunk-VQ47KWD5.js.map} +1 -1
  38. package/dist/chunk-WUJXJC5O.js +14568 -0
  39. package/dist/chunk-WUJXJC5O.js.map +1 -0
  40. package/dist/{chunk-EHGVROVV.js → chunk-ZORVNOKX.js} +6 -25
  41. package/dist/chunk-ZORVNOKX.js.map +1 -0
  42. package/dist/config/index.d.ts +53 -11
  43. package/dist/config/index.js +5 -5
  44. package/dist/controls/index.d.ts +6 -3
  45. package/dist/controls/index.js +4 -4
  46. package/dist/dragdrop/index.d.ts +4 -3
  47. package/dist/index.d.ts +139 -114
  48. package/dist/index.js +470 -479
  49. package/dist/index.js.map +1 -1
  50. package/dist/layers/index.d.ts +6 -35
  51. package/dist/layers/index.js +2 -3
  52. package/dist/loupe/index.d.ts +6 -5
  53. package/dist/passthrough/weasel-ui.d.ts +421 -215
  54. package/dist/passthrough/weasel-ui.js +1 -1
  55. package/dist/primitives/index.d.ts +2 -13
  56. package/dist/primitives/index.js +4 -4
  57. package/dist/state/index.d.ts +6 -5
  58. package/dist/state/index.js +5 -5
  59. package/dist/styles.css +410 -190
  60. package/dist/undo/index.d.ts +4 -3
  61. package/package.json +9 -13
  62. package/src/annotations/frac.test.ts +7 -0
  63. package/src/annotations/paint.test.ts +21 -0
  64. package/src/annotations/paint.ts +12 -0
  65. package/src/annotations/store.test.ts +31 -0
  66. package/src/annotations/types.ts +3 -2
  67. package/src/canvas/Stage.test.tsx +18 -0
  68. package/src/canvas/index.ts +0 -9
  69. package/src/chrome/labTypes.ts +1 -1
  70. package/src/chrome/regions/PaletteRegion.test.tsx +18 -0
  71. package/src/chrome/regions/PaletteRegion.tsx +5 -4
  72. package/src/chrome/regions/SidebarRegion.less +197 -0
  73. package/src/chrome/regions/SidebarRegion.test.tsx +20 -0
  74. package/src/chrome/regions/SidebarRegion.tsx +7 -2
  75. package/src/chrome/regions/TitleBarRegion.tsx +1 -1
  76. package/src/chrome/types.ts +13 -4
  77. package/src/config/autoConfig.ts +2 -2
  78. package/src/config/builder.ts +23 -5
  79. package/src/config/entry.test.ts +8 -0
  80. package/src/config/index.ts +2 -0
  81. package/src/config/rules.ts +2 -0
  82. package/src/config/sectionTree.test.ts +146 -0
  83. package/src/config/sectionTree.ts +124 -0
  84. package/src/config/types.ts +4 -4
  85. package/src/controls/AutoControls.stories.tsx +6 -6
  86. package/src/controls/ControlPanel.less +27 -0
  87. package/src/controls/ControlPanel.stories.tsx +95 -1
  88. package/src/controls/ControlPanel.test.tsx +82 -112
  89. package/src/controls/ControlPanel.tsx +159 -396
  90. package/src/controls/inDialog.test.tsx +82 -0
  91. package/src/controls/inDialog.tsx +46 -0
  92. package/src/controls/index.ts +1 -0
  93. package/src/index.test.ts +0 -2
  94. package/src/index.ts +14 -35
  95. package/src/instrument/types.ts +5 -2
  96. package/src/lab/Lab.nebula.test.tsx +31 -0
  97. package/src/lab/Lab.tsx +57 -18
  98. package/src/lab/LabBoundary.test.tsx +66 -0
  99. package/src/lab/LabBoundary.tsx +56 -0
  100. package/src/lab/LabHeader.tsx +4 -23
  101. package/src/lab/LabRoot.tsx +2 -3
  102. package/src/lab/LabShell.less +0 -1
  103. package/src/lab/LabShell.stories.tsx +15 -0
  104. package/src/lab/LabShell.test.tsx +18 -0
  105. package/src/lab/LabShell.tsx +14 -1
  106. package/src/lab/LabSwitcher.less +1 -1
  107. package/src/lab/LabSwitcher.test.tsx +41 -0
  108. package/src/lab/LabSwitcher.tsx +30 -8
  109. package/src/lab/index.ts +1 -0
  110. package/src/layers/AGENTS.md +18 -74
  111. package/src/layers/index.ts +4 -2
  112. package/src/passthrough/weasel-ui.ts +25 -10
  113. package/src/primitives/FpsMeter.less +6 -1
  114. package/src/primitives/FpsMeter.test.tsx +12 -4
  115. package/src/primitives/FpsMeter.tsx +6 -1
  116. package/src/primitives/JobProgress.stories.tsx +1 -1
  117. package/src/primitives/StatusBar.less +6 -0
  118. package/src/primitives/index.ts +0 -2
  119. package/src/specimen/Specimen.tsx +42 -56
  120. package/src/state/types.ts +8 -2
  121. package/src/state/view.test.ts +4 -4
  122. package/src/styles.less +4 -2
  123. package/src/theme/Interstellar.stories.tsx +8 -9
  124. package/src/theme/base.less +3 -20
  125. package/src/theme/interstellar.test.ts +6 -3
  126. package/src/theme/interstellar.theme.json +0 -56
  127. package/src/theme/interstellar.ts +2 -2
  128. package/src/trial/Trial.canvas.test.tsx +9 -5
  129. package/src/trial/Trial.config.test.tsx +1 -1
  130. package/src/trial/Trial.tsx +30 -8
  131. package/dist/_dts/index-BNdz-tNd.d.ts +0 -423
  132. package/dist/chunk-7PFH3CNM.js.map +0 -1
  133. package/dist/chunk-CEIUBPPW.js.map +0 -1
  134. package/dist/chunk-EH7UEQV7.js +0 -590
  135. package/dist/chunk-EH7UEQV7.js.map +0 -1
  136. package/dist/chunk-EHGVROVV.js.map +0 -1
  137. package/dist/chunk-IHUVQ3TX.js.map +0 -1
  138. package/dist/chunk-MDVTK5U3.js +0 -170
  139. package/dist/chunk-MDVTK5U3.js.map +0 -1
  140. package/dist/chunk-PJ7WEQBJ.js +0 -18
  141. package/dist/chunk-PJ7WEQBJ.js.map +0 -1
  142. package/dist/chunk-T3EC2DXD.js +0 -12628
  143. package/dist/chunk-T3EC2DXD.js.map +0 -1
  144. package/dist/chunk-UN4U4P63.js.map +0 -1
  145. package/dist/chunk-ZDHY47EV.js.map +0 -1
  146. package/dist/ui/layers/index.d.ts +0 -66
  147. package/dist/ui/layers/index.js +0 -3
  148. package/dist/ui/layers/index.js.map +0 -1
  149. package/src/canvas/useOrbit.test.ts +0 -167
  150. package/src/canvas/useOrbit.ts +0 -156
  151. package/src/lab/useSystemMode.ts +0 -30
  152. package/src/layers/LayerList.less +0 -93
  153. package/src/layers/LayerList.stories.tsx +0 -66
  154. package/src/layers/LayerList.test.tsx +0 -232
  155. package/src/layers/LayerList.tsx +0 -268
  156. package/src/primitives/Sidebar.less +0 -112
  157. package/src/primitives/Sidebar.stories.tsx +0 -38
  158. package/src/primitives/Sidebar.test.tsx +0 -74
  159. package/src/primitives/Sidebar.tsx +0 -35
  160. package/src/ui/layers/index.ts +0 -5
package/README.md CHANGED
@@ -30,9 +30,6 @@ the `@weasel-js/ui` components it passes through:
30
30
  import '@weasel-js/labkit/styles.css';
31
31
  ```
32
32
 
33
- Annotations are on the `pre` tag until the next stable release:
34
- `npm i @weasel-js/labkit@pre`.
35
-
36
33
  ## A lab
37
34
 
38
35
  ```tsx
@@ -250,8 +247,8 @@ it. `SidebarSection.undockable` and `undockAs` control the offer;
250
247
 
251
248
  ## Theming
252
249
 
253
- labkit ships one theme, `interstellar` — a cosmic dark and a warm parchment
254
- light — as a value, not a stylesheet. `<Lab>` and `<LabShell>` apply it for you;
250
+ labkit ships one theme, `interstellar` — a cosmic dark over weasel's own light
251
+ mode — as a value, not a stylesheet. `<Lab>` and `<LabShell>` apply it for you;
255
252
  `mode` is `"auto"` (follow the OS), `"light"` or `"dark"`. Only `styles.css`
256
253
  needs importing, and the token values arrive through the provider:
257
254
 
@@ -316,14 +313,13 @@ directly. Several expose more than the root does, `/state` most of all.
316
313
  | `/chrome` | Regions, contribution types, built-in contributions |
317
314
  | `/controls` | `<ControlPanel>` and the config field types |
318
315
  | `/canvas` | `<CanvasStack>`, coordinate helpers, `usePanZoom`, `useOrbit` |
319
- | `/layers` | `<LayerList>` |
316
+ | `/layers` | `<LayerList>` from `@weasel-js/ui`, and the layers capability types |
320
317
  | `/loupe` | Magnifier components and `useLoupe` |
321
318
  | `/surface` | Tiled surface hooks for your own renderer |
322
319
  | `/job` | `useJob` and the job capability types |
323
320
  | `/state` | The lab store, storage adapters, `useTrialState`, serialization helpers |
324
321
  | `/undo` | Undo stack and event bus |
325
322
  | `/dragdrop` | `<Palette>`, `<DragGhost>`, `useDragDrop` |
326
- | `/ui/layers` | `<LayerStack>`, the expandable layer-card list |
327
323
  | `/weasel-ui`, `/weasel-canvas` | Passthroughs to `@weasel-js/ui` and `@weasel-js/core` |
328
324
 
329
325
  ## Development
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { RefObject } from 'react';
3
- import { k as ViewTransform, W as WorldFrame } from './frac-B4okC2lX.js';
3
+ import { m as ViewTransform, W as WorldFrame } from './frac-DTRq7Xpb.js';
4
4
 
5
5
  /** One layer of a canvas stack: its id, whether it is currently shown, and how
6
6
  * it paints itself. */
@@ -0,0 +1,83 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { S as StanceProps } from './PrefsRow.d-DFpPIeIC.js';
4
+
5
+ /** One layer. With a body (see `renderBody`) it draws as a card that folds its
6
+ * body away; without one, as a one-line row. Either can hold child layers. */
7
+ interface LayerListItem {
8
+ id: string;
9
+ /** The layer's name. Also what its controls are labeled by. */
10
+ label: string;
11
+ /** Shown in the header in place of `label` — a select that switches the
12
+ * layer's kind, say. */
13
+ title?: ReactNode;
14
+ /** Fixed-size content before the label: a color swatch, a kind icon. */
15
+ leading?: ReactNode;
16
+ /** Drawn in the drag handle in place of the grip — an ordinal. */
17
+ badge?: ReactNode;
18
+ /** Which of its list this layer is: an index into the theme's tone list, or
19
+ * a color. A card draws its edge and handle in it and recolors its controls. */
20
+ tone?: StanceProps['tone'];
21
+ /** Cannot be dragged, hidden or removed, walls off drops on either side, and
22
+ * selects alone rather than joining a multi-selection. */
23
+ locked?: boolean;
24
+ /** Shown or not, when the list has `onVisibilityChange`. Default true. */
25
+ visible?: boolean;
26
+ children?: LayerListItem[];
27
+ /** Folds the body and children away until the user opens them.
28
+ * `collapsedIds` overrides it. */
29
+ defaultCollapsed?: boolean;
30
+ }
31
+ /**
32
+ * A reorder: `ids`, siblings under `parentId` (`null` at the top level), now
33
+ * sit as one block in list order starting at `index` of the parent's children.
34
+ * A drag never moves a layer to another parent.
35
+ */
36
+ interface LayerMove {
37
+ ids: string[];
38
+ parentId: string | null;
39
+ index: number;
40
+ }
41
+ /** Props for `<LayerList>`. */
42
+ interface LayerListProps {
43
+ items: LayerListItem[];
44
+ /** Omit for a list the user cannot reorder. */
45
+ onReorder?: (move: LayerMove) => void;
46
+ /** Giving both makes rows selectable: a click selects one, shift-click adds
47
+ * or removes one, and dragging a selected row drags its selected siblings. */
48
+ selectedIds?: readonly string[];
49
+ onSelect?: (ids: string[]) => void;
50
+ /** Adds a visibility checkbox to every unlocked layer. */
51
+ onVisibilityChange?: (id: string, visible: boolean) => void;
52
+ /** Adds a ✕ to every unlocked layer. */
53
+ onRemove?: (id: string) => void;
54
+ /** A layer's controls. Returning `null` leaves that layer a one-line row. */
55
+ renderBody?: (item: LayerListItem) => ReactNode;
56
+ /** Ids whose body and children are folded away. Giving it makes folding
57
+ * controlled; `onCollapsedChange` fires either way. */
58
+ collapsedIds?: readonly string[];
59
+ onCollapsedChange?: (ids: string[]) => void;
60
+ /** Heading above the list. */
61
+ title?: string;
62
+ /** Names the list for assistive tech when it has no `title`. */
63
+ label?: string;
64
+ /** Kinds the user can add, as buttons beside the title. Shown only with `onAdd`. */
65
+ addKinds?: string[];
66
+ onAdd?: (kind: string) => void;
67
+ /** Shown in place of the list when `items` is empty. */
68
+ empty?: ReactNode;
69
+ /** Appended to the root's class list — the module's own names are hashed. */
70
+ className?: string;
71
+ }
72
+ /** Returns `items` with `move` applied, for a consumer that holds the tree as state. */
73
+ declare function moveLayers(items: LayerListItem[], move: LayerMove): LayerListItem[];
74
+ /**
75
+ * An ordered, drag-reorderable list of layers — a document's objects, a lab's
76
+ * canvases, a fill's effects. Each layer is a one-line row or, with a body, a
77
+ * card whose controls fold away; either can nest child layers. Selection,
78
+ * visibility, removal and an add palette are each on when their handler is given.
79
+ */
80
+ declare function LayerList(props: LayerListProps): react_jsx_runtime.JSX.Element;
81
+
82
+ export { LayerList as L, moveLayers as m };
83
+ export type { LayerListItem as a, LayerListProps as b, LayerMove as c };
@@ -1,6 +1,21 @@
1
+ import { Stance } from '@weasel-js/theme';
1
2
  import { ReactNode } from 'react';
2
3
  import { ToolPrefLeaf } from '@weasel-js/core';
3
4
 
5
+ /**
6
+ * What a surface holds, and which of its peers it is. Every surface that takes
7
+ * these takes both, and the theme decides how each looks.
8
+ */
9
+ interface StanceProps {
10
+ /** The class of content the surface holds. Omitted, it draws as it always has. */
11
+ stance?: Stance;
12
+ /**
13
+ * Which of its peers this is: an index into the theme's tone list, wrapping,
14
+ * or a color given directly. Independent of `stance`, and allowed without one.
15
+ */
16
+ tone?: number | string;
17
+ }
18
+
4
19
  /** What a {@link PrefRenderer} is given for the leaf it is rendering. */
5
20
  interface PrefRenderContext {
6
21
  /** Dotted path of the leaf within the schema root. */
@@ -21,4 +36,4 @@ interface PrefRenderContext {
21
36
  */
22
37
  type PrefRenderer = (ctx: PrefRenderContext) => ReactNode;
23
38
 
24
- export type { PrefRenderer as P, PrefRenderContext as a };
39
+ export type { PrefRenderer as P, StanceProps as S, PrefRenderContext as a };
@@ -1,12 +1,13 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, ButtonHTMLAttributes, ReactElement } from 'react';
4
+ import { S as StanceProps } from './PrefsRow.d-DFpPIeIC.js';
4
5
  import { TextFieldProps, ValidationResult, SelectProps as SelectProps$1, ListBoxItemProps } from 'react-aria-components';
5
6
 
6
7
  declare const ICON_PATHS: {
7
8
  readonly clone: "<path d=\"M7 7.4V4.6A1.6 1.6 0 0 1 8.6 3h6.8A1.6 1.6 0 0 1 17 4.6v6.8a1.6 1.6 0 0 1-1.6 1.6H12.6\" stroke-linecap=\"butt\"/><rect x=\"3\" y=\"7\" width=\"10\" height=\"10\" rx=\"1.6\"/><path d=\"M5.7 10.8h4.6M5.7 13.4h3\" stroke-width=\"1\"/>";
8
9
  readonly reset: "<path d=\"M7.28 4.88A5.8 5.8 0 1 0 12.72 4.88\"/><path d=\"M13.81 7.57 12.72 4.88 15.56 4.28\"/>";
9
- readonly close: "<path d=\"M5 5 15 15M15 5 5 15\" stroke-width=\"1.75\"/>";
10
+ readonly close: "<path d=\"M4.5 4.5 15.5 15.5M15.5 4.5 4.5 15.5\" stroke-width=\"1.75\"/>";
10
11
  readonly export: "<path d=\"M4 12.6v2.9A1.5 1.5 0 0 0 5.5 17h9a1.5 1.5 0 0 0 1.5-1.5v-2.9\"/><path d=\"M10 3.2v8.5\"/><path d=\"M11.7 9.35 10 11.7 8.3 9.35\"/><path d=\"M6.8 14.7h6.4\" stroke-width=\"1\"/>";
11
12
  readonly zoomIn: "<circle cx=\"9\" cy=\"9\" r=\"5.4\"/><path d=\"M12.82 12.82 16.9 16.9\"/><path d=\"M9 6.7v4.6M6.7 9h4.6\"/>";
12
13
  readonly zoomOut: "<circle cx=\"9\" cy=\"9\" r=\"5.4\"/><path d=\"M12.82 12.82 16.9 16.9\"/><path d=\"M6.7 9h4.6\"/>";
@@ -20,6 +21,14 @@ declare const ICON_PATHS: {
20
21
  readonly undo: "<path d=\"M4.4 8.4h6.8a3.6 3.6 0 0 1 0 7.2H8.6\"/><path d=\"M6.47 10.14 4.4 8.4 6.47 6.66\"/>";
21
22
  readonly redo: "<path d=\"M15.6 8.4H8.8a3.6 3.6 0 0 0 0 7.2H11.4\"/><path d=\"M13.53 6.66 15.6 8.4 13.53 10.14\"/>";
22
23
  readonly snapshot: "<path d=\"M3.8 8.3A1.4 1.4 0 0 1 5.2 6.9h1.9L8 5.1h4l.9 1.8h1.9A1.4 1.4 0 0 1 16.2 8.3v6A1.4 1.4 0 0 1 14.8 15.7H5.2A1.4 1.4 0 0 1 3.8 14.3z\"/><circle cx=\"10\" cy=\"11\" r=\"2.75\"/>";
24
+ readonly bold: "<path d=\"M6 3.5h4.6a3.1 3.1 0 0 1 0 6.2H6zM6 9.7h5.4a3.4 3.4 0 0 1 0 6.8H6z\" stroke-width=\"2.1\"/>";
25
+ readonly italic: "<path d=\"M9 3.5h6M5 16.5h6M12.5 3.5 7.5 16.5\"/>";
26
+ readonly underline: "<path d=\"M6 3.4v5.6a4 4 0 0 0 8 0V3.4\"/><path d=\"M4.6 17h10.8\"/>";
27
+ readonly strikethrough: "<path d=\"M14.4 5.8c-.9-1.6-2.4-2.4-4.4-2.4-2.5 0-4.2 1.3-4.2 3.1 0 .9.4 1.6 1.2 2.2\"/><path d=\"M5.6 14.2c.9 1.6 2.4 2.4 4.4 2.4 2.5 0 4.2-1.3 4.2-3.1 0-.9-.4-1.6-1.2-2.2\"/><path d=\"M3.4 10h13.2\"/>";
28
+ readonly overline: "<path d=\"M4.6 3h10.8\"/><ellipse cx=\"10\" cy=\"11.4\" rx=\"4.4\" ry=\"4.8\"/>";
29
+ readonly superscript: "<path d=\"M3.6 8.6 10.4 16.4M10.4 8.6 3.6 16.4\"/><path d=\"M11.9 5.3a2.2 2.2 0 1 1 4.3.8c0 1.4-4.3 2.2-4.3 3.5h4.5\"/>";
30
+ readonly subscript: "<path d=\"M3.6 3.6 10.4 11.4M10.4 3.6 3.6 11.4\"/><path d=\"M11.9 11.5a2.2 2.2 0 1 1 4.3.8c0 1.4-4.3 2.2-4.3 3.5h4.5\"/>";
31
+ readonly code: "<path d=\"M7 6.2 3.2 10 7 13.8M13 6.2 16.8 10 13 13.8\"/><path d=\"M11.2 4.8 8.8 15.2\"/>";
23
32
  readonly play: "<path d=\"M7.6 5.2 15.6 10 7.6 14.8Z\"/>";
24
33
  readonly pause: "<path d=\"M7.8 5.2v9.6M12.2 5.2v9.6\"/>";
25
34
  readonly stop: "<rect x=\"5.6\" y=\"5.6\" width=\"8.8\" height=\"8.8\" rx=\"1.4\"/>";
@@ -34,6 +43,7 @@ declare const ICON_PATHS: {
34
43
  readonly warning: "<path d=\"M10 3.4 17.4 16.2H2.6z\"/><path d=\"M10 8.4v3.4\"/><path d=\"M10 14h0\"/>";
35
44
  readonly error: "<circle cx=\"10\" cy=\"10\" r=\"7\"/><path d=\"M7.6 7.6 12.4 12.4M12.4 7.6 7.6 12.4\"/>";
36
45
  readonly busy: "<path d=\"M10 3.2A6.8 6.8 0 1 1 3.2 10\"/>";
46
+ readonly check: "<path d=\"M4.35 10.56 8.03 14.24 15.66 5.77\"/>";
37
47
  readonly modeLight: "<circle cx=\"10\" cy=\"10\" r=\"3.5\"/><path d=\"M15.3 10L17.7 10M13.75 6.25L15.44 4.56M10 4.7L10 2.3M6.25 6.25L4.56 4.56M4.7 10L2.3 10M6.25 13.75L4.56 15.44M10 15.3L10 17.7M13.75 13.75L15.44 15.44\"/>";
38
48
  readonly modeDark: "<path d=\"M8.19 3.55A6.7 6.7 0 1 0 16.45 11.81A5.9 5.9 0 0 1 8.19 3.55Z\"/>";
39
49
  readonly modeAuto: "<path d=\"M10 2.6Q10 10 17.4 10Q10 10 10 17.4Q10 10 2.6 10Q10 10 10 2.6Z\"/>";
@@ -43,6 +53,7 @@ declare const ICON_PATHS: {
43
53
  readonly search: "<circle cx=\"9\" cy=\"9\" r=\"5.4\"/><path d=\"M12.82 12.82 16.9 16.9\"/>";
44
54
  readonly loupe: "<circle cx=\"9\" cy=\"9\" r=\"5.6\"/><path d=\"M12.96 12.96 17 17\"/><rect x=\"6\" y=\"6\" width=\"6\" height=\"6\" stroke-width=\"1\"/><path d=\"M9 6v6M6 9h6\" stroke-width=\"1\"/>";
45
55
  readonly layers: "<path d=\"M10 2.8 17.2 6.6 10 10.4 2.8 6.6z\"/><path d=\"M2.8 10 10 13.8 17.2 10\" stroke-width=\"1\"/><path d=\"M2.8 13.4 10 17.2 17.2 13.4\" stroke-width=\"1\"/>";
56
+ readonly page: "<path d=\"M4.6 2.8H11.6L15.4 6.6V17.2H4.6z\"/><path d=\"M11.6 2.8V6.6H15.4\"/>";
46
57
  readonly link: "<path d=\"M8.6 11.4a3.4 3.4 0 0 1 0-4.8l2.2-2.2a3.4 3.4 0 0 1 4.8 4.8l-1.1 1.1\"/><path d=\"M11.4 8.6a3.4 3.4 0 0 1 0 4.8l-2.2 2.2a3.4 3.4 0 0 1-4.8-4.8l1.1-1.1\"/>";
47
58
  readonly collapse: "<path d=\"M14.16 4.05 10 7.8 5.84 4.05M5.84 15.95 10 12.2 14.16 15.95\"/>";
48
59
  readonly expand: "<path d=\"M5.84 8.15 10 4.4 14.16 8.15M14.16 11.85 10 15.6 5.84 11.85\"/>";
@@ -230,13 +241,31 @@ declare function Icon({ name, className, size, label, filled, fillOpacity, }: Ic
230
241
  name: IconName;
231
242
  }): react_jsx_runtime.JSX.Element;
232
243
 
233
- /** Visual weight of a button. Defaults to `secondary`. */
234
- type ButtonVariant = 'primary' | 'secondary' | 'ghost';
244
+ /** The tooltip fields a segmented bar's item carries. */
245
+ interface SegmentTooltipFields {
246
+ /** Tooltip content. Overrides the name-plus-`shortcut` default. */
247
+ tooltip?: ReactNode;
248
+ /** Shortcut hint shown in the tooltip as `Name (⌘Z)`, the way `ToolButton`
249
+ * and `ActionBar` show theirs. The name is `ariaLabel`, else a string
250
+ * `label`. */
251
+ shortcut?: string;
252
+ }
253
+
254
+ /** Visual weight of a button. Defaults to `secondary`. `link` drops the
255
+ * control box entirely and reads as a hyperlink in running text -- for an
256
+ * in-page navigation that is still a button, not an `<a href>`. */
257
+ type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'link';
258
+ /** Text color of a `link` button — the same set as `Code`'s statuses. */
259
+ type ButtonStatus = 'neutral' | 'muted' | 'accent' | 'success' | 'warn' | 'danger';
235
260
  /** Button height and type scale. */
236
261
  type ButtonSize = 'sm' | 'md';
237
262
  type ButtonBase = {
238
263
  variant?: ButtonVariant;
239
264
  size?: ButtonSize;
265
+ /** Text color of the `link` variant, which is `accent` unless told
266
+ * otherwise. The boxed variants carry their weight in their fill and
267
+ * ignore it. A peer `tone`, or a stance's accent, paints over it. */
268
+ status?: ButtonStatus;
240
269
  /** A button that stays down: renders `aria-pressed` and holds the active
241
270
  * treatment while it is on. For a control that reports a state rather than
242
271
  * firing an action -- a panel toggle, a mode switch. Left off, the button
@@ -252,7 +281,7 @@ type ButtonBase = {
252
281
  style?: ButtonHTMLAttributes<HTMLButtonElement>['style'];
253
282
  children?: ReactNode;
254
283
  onClick?: ButtonHTMLAttributes<HTMLButtonElement>['onClick'];
255
- };
284
+ } & StanceProps & SegmentTooltipFields;
256
285
  type ButtonRegular = ButtonBase & {
257
286
  iconOnly?: false;
258
287
  ariaLabel?: string;
@@ -271,6 +300,10 @@ type ButtonProps = ButtonRegular | ButtonIconOnly;
271
300
  * button `aria-busy`, and leaves the label in place; it does not disable the
272
301
  * button, so pass `disabled` too if the click should be blocked.
273
302
  *
303
+ * `shortcut` adds a kit tooltip reading `Name (⌘S)`, named by `ariaLabel` or
304
+ * string children, the way `ToolButton` and `ButtonBar` items show theirs;
305
+ * `tooltip` replaces that text with any content.
306
+ *
274
307
  * `ref` forwards to the underlying `<button>`.
275
308
  */
276
309
  declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
@@ -281,7 +314,7 @@ type ToggleBarItem<V extends string | number = string> = {
281
314
  label?: ReactNode;
282
315
  ariaLabel?: string;
283
316
  disabled?: boolean;
284
- };
317
+ } & SegmentTooltipFields;
285
318
  /** Segment height and type scale for a {@link ToggleBar}. */
286
319
  type ToggleBarSize = 'sm' | 'md';
287
320
  /** Visual treatment of a {@link ToggleBar}. */
@@ -354,9 +387,48 @@ interface OverlayPortalProps {
354
387
  /** React Aria props minus the portal key a weasel overlay owns. */
355
388
  type WithoutPortalTarget<T> = Omit<T, 'UNSTABLE_portalContainer'>;
356
389
 
390
+ /**
391
+ * Whether a {@link Field} stacks its label above the control or sits them
392
+ * side by side.
393
+ */
394
+ type FieldOrientation = 'stacked' | 'row';
395
+ /** Props for {@link Field}. */
396
+ type FieldProps = {
397
+ orientation?: FieldOrientation;
398
+ className?: string;
399
+ children?: ReactNode;
400
+ };
401
+ /**
402
+ * Layout primitive that arranges a label, control, hint, and error in the
403
+ * canonical weasel-ui form-row shape. The control itself owns its semantics
404
+ * (RAC `TextField`, `Checkbox`, etc.); this just paints the layout.
405
+ *
406
+ * Most users will instead reach for `Input` / `Checkbox` / `Switch`, which
407
+ * compose Field internally. Use Field directly when you need a custom
408
+ * control to sit in the same visual rhythm.
409
+ */
410
+ declare function Field({ orientation, className, children }: FieldProps): react_jsx_runtime.JSX.Element;
411
+ /**
412
+ * The class names {@link Field} paints its slots with, so a control composing
413
+ * its own layout can match the same form-row rhythm.
414
+ */
415
+ declare const fieldClasses: {
416
+ root: string;
417
+ row: string;
418
+ label: string;
419
+ hint: string;
420
+ error: string;
421
+ };
422
+
357
423
  /** Props for {@link Input}, on top of React Aria's `TextField` props. */
358
424
  type InputProps = Omit<TextFieldProps, 'children' | 'className'> & {
359
425
  label?: ReactNode;
426
+ /**
427
+ * `'stacked'` (the default) puts the label above the field; `'row'` sets it
428
+ * beside the field at its own width, with any description or error on a
429
+ * line below. Same vocabulary as {@link Field}'s `orientation`.
430
+ */
431
+ orientation?: FieldOrientation;
360
432
  description?: ReactNode;
361
433
  errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);
362
434
  placeholder?: string;
@@ -373,6 +445,12 @@ type InputProps = Omit<TextFieldProps, 'children' | 'className'> & {
373
445
  */
374
446
  declare const Input: react.ForwardRefExoticComponent<Omit<TextFieldProps, "className" | "children"> & {
375
447
  label?: ReactNode;
448
+ /**
449
+ * `'stacked'` (the default) puts the label above the field; `'row'` sets it
450
+ * beside the field at its own width, with any description or error on a
451
+ * line below. Same vocabulary as {@link Field}'s `orientation`.
452
+ */
453
+ orientation?: FieldOrientation;
376
454
  description?: ReactNode;
377
455
  errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);
378
456
  placeholder?: string;
@@ -394,20 +472,40 @@ type SelectOption = {
394
472
  */
395
473
  textValue?: string;
396
474
  };
475
+ /** A titled group of options in a {@link Select}'s `options` list. */
476
+ type SelectOptionGroup<T extends Key = string> = {
477
+ title: ReactNode;
478
+ options: ReadonlyArray<SelectOption & {
479
+ value: T;
480
+ }>;
481
+ };
397
482
  type Key = string | number;
483
+ /** How a {@link Select} trigger signals that it opens a list. */
484
+ type SelectIndicator = 'chevron' | 'underline' | 'none';
485
+ /** Where a {@link Select}'s list opens relative to its trigger. */
486
+ type SelectPopup = 'over' | 'below';
398
487
  /**
399
488
  * Props for {@link Select}, on top of React Aria's `Select` props, with the
400
489
  * selection key narrowed to the option value type.
401
490
  */
402
491
  type SelectProps<T extends Key = string> = Omit<SelectProps$1<object>, 'children' | 'className' | 'selectedKey' | 'defaultSelectedKey' | 'onSelectionChange'> & {
403
492
  label?: ReactNode;
493
+ /**
494
+ * `'stacked'` (the default) puts the label above the trigger; `'row'` sets it
495
+ * beside the trigger at its own width, with any description or error on a
496
+ * line below. Same vocabulary as {@link Field}'s `orientation`.
497
+ */
498
+ orientation?: FieldOrientation;
404
499
  description?: ReactNode;
405
500
  errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);
406
501
  placeholder?: string;
407
- /** Either pass `options` for a quick render, or `children` for full control. */
408
- options?: ReadonlyArray<SelectOption & {
502
+ /**
503
+ * Either pass `options` for a quick render, or `children` for full control.
504
+ * An entry with `title` and `options` of its own is a titled section.
505
+ */
506
+ options?: ReadonlyArray<(SelectOption & {
409
507
  value: T;
410
- }>;
508
+ }) | SelectOptionGroup<T>>;
411
509
  children?: ReactNode;
412
510
  selectedKey?: T | null;
413
511
  defaultSelectedKey?: T;
@@ -420,6 +518,20 @@ type SelectProps<T extends Key = string> = Omit<SelectProps$1<object>, 'children
420
518
  width?: 'fill' | 'fit';
421
519
  /** `'bare'` drops the box, for a select set in a row of other chrome such as a property row. */
422
520
  variant?: 'field' | 'bare';
521
+ /**
522
+ * How the trigger says it opens a list. `'chevron'` draws the caret beside
523
+ * the value; `'underline'` marks the value itself, dotted at rest and solid
524
+ * while it is pointed at or open; `'none'` says nothing. Unset takes the
525
+ * variant's own: a boxed select shows the caret, a bare one — set in a row
526
+ * where 10px of caret is a tenth of the value's width — underlines.
527
+ */
528
+ indicator?: SelectIndicator;
529
+ /**
530
+ * Where the list opens. `'over'` (the default) puts the selected row on the
531
+ * trigger, its label in the trigger's own text column, so choosing what is
532
+ * already chosen moves nothing; `'below'` hangs it under the trigger.
533
+ */
534
+ popup?: SelectPopup;
423
535
  /**
424
536
  * Id for the trigger button. React Aria puts a plain `id` on the wrapper,
425
537
  * which is not labelable, so an outer `<label for>` needs this to reach a
@@ -427,14 +539,19 @@ type SelectProps<T extends Key = string> = Omit<SelectProps$1<object>, 'children
427
539
  */
428
540
  triggerId?: string;
429
541
  className?: string;
430
- } & OverlayPortalProps;
542
+ } & SegmentTooltipFields & OverlayPortalProps;
431
543
  /**
432
544
  * Form select wrapping React Aria's Select. Pass either `options` for a
433
545
  * quick declarative render or `children` of `<SelectItem>` for control over
434
- * each row.
546
+ * each row; `<SelectSection>` (or an `options` entry with a `title`) groups
547
+ * rows under a heading.
435
548
  *
436
549
  * The selection key type is parameterized so consumers with a string-literal
437
550
  * union for `value` (e.g. `'r' | 'g' | 'b'`) get a typed `onSelectionChange`.
551
+ *
552
+ * `shortcut` puts a kit tooltip on the trigger reading `Name (⌘K)`, named by
553
+ * `aria-label` or a string `label`, as `Button` does; `tooltip` replaces that
554
+ * text.
438
555
  */
439
556
  declare function Select<T extends Key = string>(props: SelectProps<T>): react_jsx_runtime.JSX.Element;
440
557
  /** Props for {@link SelectItem}, on top of React Aria's `ListBoxItem` props. */
@@ -449,5 +566,5 @@ type SelectItemProps = Omit<ListBoxItemProps, 'className' | 'children'> & {
449
566
  */
450
567
  declare function SelectItem({ children, className, textValue, ...rest }: SelectItemProps): react_jsx_runtime.JSX.Element;
451
568
 
452
- export { Button as B, Select as S, ToggleBar as T, Icon as d, Input as e, ICON_PATHS as l, SelectItem as n };
453
- export type { IconProps as I, OverlayPortalProps as O, WithoutPortalTarget as W, ButtonProps as a, ButtonSize as b, ButtonVariant as c, InputProps as f, SelectProps as g, ToggleBarItem as h, ToggleBarProps as i, ToggleBarSize as j, ToggleBarVariant as k, IconName as m, SelectItemProps as o, SelectOption as p };
569
+ export { Button as B, Select as S, ToggleBar as T, Icon as d, Input as e, Field as m, ICON_PATHS as o, SelectItem as q, fieldClasses as t };
570
+ export type { FieldOrientation as F, IconProps as I, OverlayPortalProps as O, WithoutPortalTarget as W, ButtonProps as a, ButtonSize as b, ButtonVariant as c, InputProps as f, SelectProps as g, ToggleBarItem as h, ToggleBarProps as i, ToggleBarSize as j, ToggleBarVariant as k, SegmentTooltipFields as l, FieldProps as n, IconName as p, SelectItemProps as r, SelectOption as s };
@@ -1,5 +1,7 @@
1
1
  import { ComponentType, ReactNode, RefObject } from 'react';
2
- import { R as ResolvedConfig, C as ConfigPath, V as ValueAtPath, a as ConfigField, b as ConfigSchema } from './types-DzoNY1pO.js';
2
+ import { S as StanceProps } from './PrefsRow.d-DFpPIeIC.js';
3
+ import { R as ResolvedConfig, a as ConfigPath, V as ValueAtPath, b as ConfigField, c as ConfigSchema } from './types-B7y8hX1D.js';
4
+ import { ColorModePreference } from '@weasel-js/theme';
3
5
  import { J as JobHandle, a as JobCapability } from './types-DJ79Tg5J.js';
4
6
  import { Scene } from '@weasel-js/core';
5
7
 
@@ -129,7 +131,11 @@ interface SavedSnapshot {
129
131
  savedAt: number;
130
132
  }
131
133
  /** `auto` follows the OS; the other two are an explicit choice. */
132
- type LabMode = 'auto' | 'light' | 'dark';
134
+ type LabMode = ColorModePreference;
135
+ /** How much room the lab's own chrome takes — the theme's density axis, named
136
+ * the way the theme names it. A lab's instruments are unaffected: this sizes
137
+ * the shell around them. */
138
+ type LabDensity = 'compact' | 'comfortable' | 'roomy';
133
139
  /** Everything a lab persists: its trials, its saved snapshots, and the
134
140
  * chosen color mode. */
135
141
  interface LabStoreState {
@@ -173,7 +179,7 @@ interface TrialStateHandle<TS, TC> {
173
179
  setState: (next: TS | ((prev: TS) => TS)) => void;
174
180
  config: TC;
175
181
  /** The config as stored, before any auto path is resolved. What the control
176
- * panel renders, so a ghosted control sits at the value it pins back to. */
182
+ * panel renders, so an auto row pins back to the value it was holding. */
177
183
  raw: TC;
178
184
  /** Dotted paths this trial has unpinned. */
179
185
  auto: ReadonlySet<string>;
@@ -265,15 +271,23 @@ interface ToolbarItem<TCtx = TrialChromeContext> {
265
271
  * zero-argument handler stays valid. */
266
272
  onActivate: (ctx: TCtx) => void;
267
273
  }
268
- /** A selectable tool in the palette region. */
269
- interface ToolItem {
274
+ /** A tool in the palette region: a mode by default, a command when it carries
275
+ * an `onActivate`. `TCtx` is the chrome context that handler is handed — a
276
+ * trial's, or the lab's for a lab-level rail. */
277
+ interface ToolItem<TCtx = TrialChromeContext> {
270
278
  icon: IconComponent;
271
279
  label: string;
280
+ /** Shown in the tooltip. Not bound here — the trial owns its keymap. */
272
281
  shortcut?: string;
273
282
  disabled?: boolean;
283
+ /** Runs on press instead of selecting. An item with one is a command: it
284
+ * never writes the tool slot, and never reads as the current tool. */
285
+ onActivate?: (ctx: TCtx) => void;
274
286
  }
275
- /** A titled block in the sidebar. */
276
- interface SidebarSection {
287
+ /** A titled block in the sidebar. `stance` and `tone` work as on a
288
+ * `<PropertyPanel>`: what kind of content the section holds, and which of its
289
+ * peers it is. */
290
+ interface SidebarSection extends StanceProps {
277
291
  title: string;
278
292
  /** Starts collapsed, until the trial remembers a fold of its own. */
279
293
  defaultCollapsed?: boolean;
@@ -589,7 +603,7 @@ interface CanvasCapability<TS = unknown, TC = unknown> {
589
603
  /** Declares that an instrument's DOM is content of a fixed size, which the
590
604
  * trial pans and zooms the way it does a canvas's layers. Not combined with
591
605
  * `canvas`: there the DOM is an unzoomed overlay, and `canvas` wins. */
592
- interface StageCapability {
606
+ interface StageCapability<TS = unknown, TC = unknown> {
593
607
  /** The content's own size in CSS pixels, at zoom 1. */
594
608
  size: ViewportSize;
595
609
  /** Where the view starts. Omitted, the content opens centered and shrunk to
@@ -597,6 +611,9 @@ interface StageCapability {
597
611
  initialView?: ViewTransform | ((viewport: ViewportSize) => ViewTransform);
598
612
  minZoom?: number;
599
613
  maxZoom?: number;
614
+ /** Drawn over the content in viewport pixels, outside the camera — a legend,
615
+ * a floating panel, anything that must not zoom with the picture. */
616
+ overlay?: (ctx: RenderContext<TS, TC>) => ReactNode;
600
617
  }
601
618
  /** Declares which of an instrument's layers the trial should offer
602
619
  * show/hide controls for. */
@@ -696,7 +713,7 @@ interface Instrument<TS = unknown, TC = unknown, TItem = unknown> {
696
713
  serialize?: (state: TS) => unknown;
697
714
  deserialize?: (data: unknown, config: TC) => TS;
698
715
  canvas?: CanvasCapability<TS, TC>;
699
- stage?: StageCapability;
716
+ stage?: StageCapability<TS, TC>;
700
717
  layers?: LayerCapability;
701
718
  dragDrop?: DragDropCapability<TS, TC>;
702
719
  undo?: UndoCapability;
@@ -785,8 +802,9 @@ interface FracRect {
785
802
  h: number;
786
803
  }
787
804
  /** What shape a mark is. The kinds map onto weasel's own tools; an arrow is a
788
- * line carrying an end marker, not a separate geometry. */
789
- type AnnotationKind = 'stroke' | 'line' | 'arrow' | 'rect' | 'ellipse' | 'text';
805
+ * line carrying an end marker, not a separate geometry. A point holds one
806
+ * entry in `points` and zero-size bounds at that position. */
807
+ type AnnotationKind = 'stroke' | 'line' | 'arrow' | 'rect' | 'ellipse' | 'text' | 'point';
790
808
  /** One selectable status in an instrument's meaning tier. */
791
809
  interface AnnotationStatus {
792
810
  id: string;
@@ -1018,5 +1036,5 @@ declare function fracContains(box: FracRect, pt: FracPoint, tol?: number): boole
1018
1036
  * answers false for two rects that merely overlap. */
1019
1037
  declare function fracEncloses(outer: FracRect, inner: FracRect): boolean;
1020
1038
 
1021
- export { DEFAULT_FRAME as D, LOUPE_DEFAULTS as a8, fracEncloses as aA, fracToWorld as aB, isAuto as aC, resolveLoupe as aD, roundFrac as aE, worldToFrac as aF, annotationsFromJSON as av, auto as aw, createAnnotationScene as ax, createAnnotationStore as ay, fracContains as az, applyCamera as b, dockPanel as j, panelKey as p, resolveFrame as r, undockPanel as u };
1022
- export type { Auto as $, AnnotationData as A, AnnotationTarget as B, CreateLabStoreOptions as C, AnnotationsApi as E, AnnotationsCapability as F, TrialInfo as G, TrialTool as H, InstrumentSerializers as I, AnnotationKind as J, Instrument as K, LabDocument as L, Migration as M, TrialContribution as N, Annotation as O, PaletteItem as P, AnnotationInit as Q, AnnotationPatch as R, SerializedTrial as S, TrialRecord as T, UndoStack as U, ViewportSize as V, WorldFrame as W, AnnotationQuery as X, AnnotationStatus as Y, AnnotationStoreOptions as Z, AnnotationTargetInfo as _, WorldSpec as a, CanvasCapability as a0, CanvasLayer as a1, CaptureDeps as a2, ContributionBase as a3, FracPoint as a4, FracRect as a5, HitResult as a6, IconComponent as a7, LayerCapability as a9, LoupePoint as aG, LoupeMode as aH, LayerDescriptor as aa, LoupeCapability as ab, LoupeDeclaration as ac, LoupeRenderArgs as ad, RegionContribution as ae, RenderContext as af, ResolvedLoupe as ag, SerializedAnnotations as ah, SidebarSection as ai, SidebarSlotContext as aj, StageCapability as ak, StatusReadout as al, SystemEvent as am, ToolCapability as an, ToolItem as ao, ToolSlotContext as ap, ToolbarItem as aq, TrialChromeContext as ar, TrialRegion as as, UndoCapability as at, ViewportControl as au, StorageAdapter as c, LabStoreState as d, SavedSnapshot as e, StorageChange as f, TrialStateHandle as g, UndockedPanel as h, UndockedPanels as i, ViewTransform as k, Point as l, DragFeedback as m, DragDropCapability as n, LabMode as o, InstrumentList as q, InstrumentHooks as s, WorldRect as t, AnnotationMeaning as v, MarkScene as w, CaptureSource as x, CaptureOptions as y, CaptureResult as z };
1039
+ export { DEFAULT_FRAME as D, fracContains as aA, fracEncloses as aB, fracToWorld as aC, isAuto as aD, resolveLoupe as aE, roundFrac as aF, worldToFrac as aG, LOUPE_DEFAULTS as ab, annotationsFromJSON as aw, auto as ax, createAnnotationScene as ay, createAnnotationStore as az, applyCamera as c, dockPanel as l, panelKey as p, resolveFrame as r, undockPanel as u };
1040
+ export type { AnnotationStatus as $, AnnotationData as A, CaptureOptions as B, CreateLabStoreOptions as C, CaptureResult as E, AnnotationTarget as F, AnnotationsApi as G, AnnotationsCapability as H, InstrumentSerializers as I, TrialInfo as J, TrialTool as K, LayerCapability as L, Migration as M, AnnotationKind as N, Instrument as O, PaletteItem as P, LabDensity as Q, TrialContribution as R, SerializedTrial as S, TrialRecord as T, UndoStack as U, ViewportSize as V, WorldFrame as W, Annotation as X, AnnotationInit as Y, AnnotationPatch as Z, AnnotationQuery as _, LayerDescriptor as a, AnnotationStoreOptions as a0, AnnotationTargetInfo as a1, Auto as a2, CanvasCapability as a3, CanvasLayer as a4, CaptureDeps as a5, ContributionBase as a6, FracPoint as a7, FracRect as a8, HitResult as a9, LoupePoint as aH, LoupeMode as aI, IconComponent as aa, LoupeCapability as ac, LoupeDeclaration as ad, LoupeRenderArgs as ae, RegionContribution as af, RenderContext as ag, ResolvedLoupe as ah, SerializedAnnotations as ai, SidebarSection as aj, SidebarSlotContext as ak, StageCapability as al, StatusReadout as am, SystemEvent as an, ToolCapability as ao, ToolItem as ap, ToolSlotContext as aq, ToolbarItem as ar, TrialChromeContext as as, TrialRegion as at, UndoCapability as au, ViewportControl as av, WorldSpec as b, StorageAdapter as d, LabDocument as e, LabStoreState as f, SavedSnapshot as g, StorageChange as h, TrialStateHandle as i, UndockedPanel as j, UndockedPanels as k, ViewTransform as m, Point as n, DragFeedback as o, DragDropCapability as q, LabMode as s, InstrumentList as t, InstrumentHooks as v, WorldRect as w, AnnotationMeaning as x, MarkScene as y, CaptureSource as z };
@@ -0,0 +1,23 @@
1
+ import { ReactNode } from 'react';
2
+ import { C as ControlRenderer } from './types-B7y8hX1D.js';
3
+
4
+ /** Options for {@link inDialog}. */
5
+ interface InDialogOptions {
6
+ /** What the row's button shows of the value. Defaults to a list joined with
7
+ * commas, or the value itself. */
8
+ summary?: (value: unknown) => ReactNode;
9
+ /** The dialog's heading. Defaults to the row's label. */
10
+ title?: ReactNode;
11
+ }
12
+ /** The one-line summary a dialog row shows when it is given none. */
13
+ declare function summarizeValue(value: unknown): string;
14
+ /**
15
+ * Moves a control into a modal: the row becomes a button showing a summary of
16
+ * the value, and the button opens a dialog whose body is `body`, handed the
17
+ * same context a row renderer gets. For a leaf whose editor will never fit a
18
+ * sidebar row.
19
+ */
20
+ declare function inDialog(body: ControlRenderer, opts?: InDialogOptions): ControlRenderer;
21
+
22
+ export { inDialog as i, summarizeValue as s };
23
+ export type { InDialogOptions as I };
@@ -1,5 +1,5 @@
1
- import { d as ControlRenderer, c as ConfigRule } from './types-DzoNY1pO.js';
2
- import { K as Instrument, ar as TrialChromeContext, N as TrialContribution, T as TrialRecord, q as InstrumentList, e as SavedSnapshot, o as LabMode, ap as ToolSlotContext, a3 as ContributionBase, aq as ToolbarItem, ao as ToolItem, ai as SidebarSection, al as StatusReadout, H as TrialTool, ae as RegionContribution, aj as SidebarSlotContext } from './frac-B4okC2lX.js';
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
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
@@ -107,7 +107,7 @@ type LabContribution<TCtx = LabChromeContext> = (ContributionBase & {
107
107
  render?: never;
108
108
  }) | (ContributionBase & {
109
109
  region: 'palette';
110
- item: ToolItem;
110
+ item: ToolItem<TCtx>;
111
111
  render?: never;
112
112
  }) | (ContributionBase & {
113
113
  region: 'sidebar' | 'aside';
@@ -181,7 +181,8 @@ interface PaletteRegionProps<TCtx extends ToolSlotContext = TrialChromeContext>
181
181
  region?: string;
182
182
  }
183
183
  /** A tool strip: a trial's, or the lab's. Selection lives in whichever tool
184
- * slot the context carries; this region only reflects it. */
184
+ * slot the context carries; this region only reflects it. An item carrying
185
+ * `onActivate` is a command instead — it presses, and never latches. */
185
186
  declare function PaletteRegion<TCtx extends ToolSlotContext = TrialChromeContext>({ contributions, ctx, region, }: PaletteRegionProps<TCtx>): react_jsx_runtime.JSX.Element | null;
186
187
 
187
188
  /** Props for `<SidebarRegion>`. */