@weasel-js/labkit 1.3.0-pre.0 → 1.3.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 (110) hide show
  1. package/dist/_dts/{index-DgcNdEdh.d.ts → types-BttTIent.d.ts} +2 -2
  2. package/dist/_dts/{types-AHlQxBNN.d.ts → types-DCGEcMO_.d.ts} +1 -1
  3. package/dist/canvas/index.d.ts +2 -2
  4. package/dist/canvas/index.js +3 -2
  5. package/dist/chrome/index.d.ts +3 -3
  6. package/dist/chrome/index.js +6 -5
  7. package/dist/chunk-3XXPU73K.js +138 -0
  8. package/dist/chunk-3XXPU73K.js.map +1 -0
  9. package/dist/{chunk-PO6L3NSH.js → chunk-6X5RBC6G.js} +17 -17
  10. package/dist/chunk-6X5RBC6G.js.map +1 -0
  11. package/dist/{chunk-NS54R52R.js → chunk-BDJXIBRZ.js} +5 -17
  12. package/dist/chunk-BDJXIBRZ.js.map +1 -0
  13. package/dist/{chunk-V7PRSIRQ.js → chunk-BMW4TDP5.js} +4 -4
  14. package/dist/chunk-BMW4TDP5.js.map +1 -0
  15. package/dist/{chunk-O7NVSCLN.js → chunk-JDROYQM3.js} +8 -8
  16. package/dist/chunk-JDROYQM3.js.map +1 -0
  17. package/dist/{chunk-HFDVGF4X.js → chunk-LGKRIUSW.js} +3 -3
  18. package/dist/{chunk-HFDVGF4X.js.map → chunk-LGKRIUSW.js.map} +1 -1
  19. package/dist/{chunk-Z6HJ5FEM.js → chunk-QCICIHEO.js} +19 -7
  20. package/dist/{chunk-Z6HJ5FEM.js.map → chunk-QCICIHEO.js.map} +1 -1
  21. package/dist/{chunk-RVNN4CHQ.js → chunk-QRYPXSGP.js} +5 -5
  22. package/dist/{chunk-RVNN4CHQ.js.map → chunk-QRYPXSGP.js.map} +1 -1
  23. package/dist/chunk-RGT4EJIB.js +6961 -0
  24. package/dist/chunk-RGT4EJIB.js.map +1 -0
  25. package/dist/chunk-SBXNQW4G.js +3 -0
  26. package/dist/chunk-SBXNQW4G.js.map +1 -0
  27. package/dist/chunk-T66HU3HX.js +17 -0
  28. package/dist/chunk-T66HU3HX.js.map +1 -0
  29. package/dist/chunk-WTI26YTM.js +266 -0
  30. package/dist/chunk-WTI26YTM.js.map +1 -0
  31. package/dist/controls/index.d.ts +2 -2
  32. package/dist/controls/index.js +3 -3
  33. package/dist/dragdrop/index.d.ts +44 -3
  34. package/dist/dragdrop/index.js +3 -1
  35. package/dist/index.d.ts +571 -541
  36. package/dist/index.js +69 -541
  37. package/dist/index.js.map +1 -1
  38. package/dist/layers/index.d.ts +3 -3
  39. package/dist/layers/index.js +4 -2
  40. package/dist/passthrough/weasel-canvas.js +1 -1
  41. package/dist/passthrough/weasel-ui.d.ts +15 -2
  42. package/dist/passthrough/weasel-ui.js +3 -2
  43. package/dist/primitives/index.js +5 -4
  44. package/dist/styles.css +1 -703
  45. package/dist/surface/index.js +2 -2
  46. package/dist/ui/layers/index.d.ts +8 -2
  47. package/dist/ui/layers/index.js +2 -4
  48. package/dist/undo/index.d.ts +2 -2
  49. package/package.json +5 -5
  50. package/src/config/builder.test.ts +7 -1
  51. package/src/config/builder.ts +1 -5
  52. package/src/config/resolve.test.ts +1 -2
  53. package/src/controls/ControlPanel.stories.tsx +41 -2
  54. package/src/controls/ControlPanel.test.tsx +31 -9
  55. package/src/controls/ControlPanel.tsx +56 -22
  56. package/src/dragdrop/index.ts +11 -0
  57. package/src/index.ts +49 -2
  58. package/src/lab/index.ts +1 -1
  59. package/src/layers/AGENTS.md +1 -1
  60. package/src/layers/LayerList.tsx +1 -1
  61. package/src/passthrough/weasel-ui.ts +22 -17
  62. package/src/styles.less +0 -4
  63. package/src/theme/Interstellar.stories.tsx +1 -1
  64. package/src/trial/Trial.config.test.tsx +3 -8
  65. package/src/ui/layers/index.ts +5 -1
  66. package/dist/chunk-NS54R52R.js.map +0 -1
  67. package/dist/chunk-O2BULFHX.js +0 -152
  68. package/dist/chunk-O2BULFHX.js.map +0 -1
  69. package/dist/chunk-O7NVSCLN.js.map +0 -1
  70. package/dist/chunk-PO6L3NSH.js.map +0 -1
  71. package/dist/chunk-PQJ5B2U2.js +0 -27
  72. package/dist/chunk-PQJ5B2U2.js.map +0 -1
  73. package/dist/chunk-TLGRYALP.js +0 -6151
  74. package/dist/chunk-TLGRYALP.js.map +0 -1
  75. package/dist/chunk-V7PRSIRQ.js.map +0 -1
  76. package/dist/chunk-ZZAYVX4X.js +0 -505
  77. package/dist/chunk-ZZAYVX4X.js.map +0 -1
  78. package/src/primitives/DragHandleGlyph.tsx +0 -29
  79. package/src/ui/format.test.ts +0 -33
  80. package/src/ui/format.ts +0 -30
  81. package/src/ui/layers/LayerStack.less +0 -143
  82. package/src/ui/layers/LayerStack.stories.tsx +0 -45
  83. package/src/ui/layers/LayerStack.test.tsx +0 -170
  84. package/src/ui/layers/LayerStack.tsx +0 -208
  85. package/src/ui/properties/CheckboxRow.stories.tsx +0 -27
  86. package/src/ui/properties/ColorRow.stories.tsx +0 -106
  87. package/src/ui/properties/CurveField.less +0 -48
  88. package/src/ui/properties/CurveField.stories.tsx +0 -20
  89. package/src/ui/properties/CurveField.test.tsx +0 -127
  90. package/src/ui/properties/CurveField.tsx +0 -184
  91. package/src/ui/properties/EffectCard.tsx +0 -324
  92. package/src/ui/properties/Gallery.stories.tsx +0 -178
  93. package/src/ui/properties/NumberRow.stories.tsx +0 -65
  94. package/src/ui/properties/PropertyGroup.less +0 -50
  95. package/src/ui/properties/PropertyGroup.stories.tsx +0 -34
  96. package/src/ui/properties/PropertyGroup.test.tsx +0 -33
  97. package/src/ui/properties/PropertyGroup.tsx +0 -45
  98. package/src/ui/properties/PropertyList.stories.tsx +0 -83
  99. package/src/ui/properties/PropertyPanel.less +0 -606
  100. package/src/ui/properties/PropertyPanel.stories.tsx +0 -190
  101. package/src/ui/properties/PropertyPanel.test.tsx +0 -193
  102. package/src/ui/properties/PropertyPanel.tsx +0 -469
  103. package/src/ui/properties/PropertyRow.stories.tsx +0 -53
  104. package/src/ui/properties/SelectRow.stories.tsx +0 -58
  105. package/src/ui/properties/SliderRow.stories.tsx +0 -74
  106. package/src/ui/properties/SpeechBalloonPanels.stories.tsx +0 -398
  107. package/src/ui/properties/TextRow.stories.tsx +0 -62
  108. package/src/ui/properties/ToggleRow.stories.tsx +0 -57
  109. package/src/ui/properties/index.ts +0 -39
  110. package/src/ui/properties/storyLayouts.tsx +0 -36
package/dist/index.d.ts CHANGED
@@ -1,174 +1,481 @@
1
- export { CanvasLayerDescriptor, CanvasStack, CanvasStackContext, CanvasStackContextValue, CanvasStackProps, screenToWorld, worldToScreen } from './canvas/index.js';
1
+ export { LayerStack, LayerStackItem, LayerStackProps } from './ui/layers/index.js';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
3
  import * as react from 'react';
3
- import { WheelEvent, PointerEvent, ReactNode } from 'react';
4
+ import { ReactNode, WheelEvent, PointerEvent } from 'react';
5
+ export { CanvasLayerDescriptor, CanvasStack, CanvasStackContext, CanvasStackContextValue, CanvasStackProps, screenToWorld, worldToScreen } from './canvas/index.js';
4
6
  export { PaletteRegion, PaletteRegionProps, SidebarRegion, SidebarRegionProps, StatusRegion, StatusRegionProps, TitleBarRegion, TitleBarRegionProps, ToolbarRegion, ToolbarRegionProps, ViewportRegion, ViewportRegionProps, builtinContributions, mergeContributions, suppressContributions } from './chrome/index.js';
5
- import { I as Instrument, a as InstrumentList, T as TrialContribution, b as TrialTool, V as ViewTransform } from './_dts/index-DgcNdEdh.js';
6
- export { C as CanvasCapability, c as CanvasLayer, D as DragDropCapability, d as DragFeedback, H as HitResult, e as IconComponent, L as LayerCapability, f as LayerDescriptor, P as PaletteItem, g as Point, R as RenderContext, S as SidebarSection, h as StatusReadout, i as SystemEvent, j as ToolCapability, k as ToolItem, l as ToolbarItem, m as TrialChromeContext, n as TrialRegion, U as UndoCapability, o as ViewportControl } from './_dts/index-DgcNdEdh.js';
7
+ import { I as Instrument, c as InstrumentList, T as TrialContribution, d as TrialTool, V as ViewTransform } from './_dts/types-BttTIent.js';
8
+ export { C as CanvasCapability, e as CanvasLayer, b as DragDropCapability, D as DragFeedback, H as HitResult, f as IconComponent, L as LayerCapability, g as LayerDescriptor, P as PaletteItem, a as Point, R as RenderContext, S as SidebarSection, h as StatusReadout, i as SystemEvent, j as ToolCapability, k as ToolItem, l as ToolbarItem, m as TrialChromeContext, n as TrialRegion, U as UndoCapability, o as ViewportControl } from './_dts/types-BttTIent.js';
7
9
  import { T as ToolPrefLeaf } from './_dts/PrefsForm-BYa6cWnO.js';
8
- import { C as ConfigNode, A as Annotations, N as NodeOptions, a as ControlRenderer, b as ConfigOption, c as ConfigSchema, I as InferConfig, d as ConfigField, R as ResolvedConfig, e as ConfigRule, L as LeafPatch, f as ConfigRuleContext } from './_dts/types-AHlQxBNN.js';
9
- export { g as CheckboxField, h as ColorField, i as ConfigFieldBase, j as ConfigFieldType, k as ConfigOf, l as NodeValue, m as NumberField, S as SectionSpec, n as SelectField, o as SelectOption, p as SliderField, T as TextField } from './_dts/types-AHlQxBNN.js';
10
+ import { b as ConfigNode, A as Annotations, N as NodeOptions, c as ControlRenderer, d as ConfigOption, a as ConfigSchema, I as InferConfig, C as ConfigField, R as ResolvedConfig, e as ConfigRule, L as LeafPatch, f as ConfigRuleContext } from './_dts/types-DCGEcMO_.js';
11
+ export { g as CheckboxField, h as ColorField, i as ConfigFieldBase, j as ConfigFieldType, k as ConfigOf, l as NodeValue, m as NumberField, S as SectionSpec, n as SelectField, o as SelectOption, p as SliderField, T as TextField } from './_dts/types-DCGEcMO_.js';
10
12
  export { ControlPanel } from './controls/index.js';
11
13
  import { J as JobHandle } from './_dts/types-DJ79Tg5J.js';
12
14
  export { a as JobCapability, b as JobEvent, c as JobFailure, d as JobStatus } from './_dts/types-DJ79Tg5J.js';
13
15
  export { UseJobOptions, useJob } from './job/index.js';
14
- import * as react_jsx_runtime from 'react/jsx-runtime';
15
16
  import { a as StorageAdapter, e as LabMode, T as TrialRecord, c as SavedSnapshot } from './_dts/types-1Sdxy_Pv.js';
16
17
  export { C as CreateLabStoreOptions, L as LabDocument, b as LabStoreState, S as SerializedTrial, d as TrialStateHandle, U as UndoStack } from './_dts/types-1Sdxy_Pv.js';
17
18
  export { LayerList, LayerListProps } from './layers/index.js';
18
19
  export { FloatingPanel, FloatingPanelProps, FpsMeter, JobProgress, JobProgressProps, Legend, LegendEntry, LegendMark, LegendProps, ScaleIndicator, ScaleIndicatorProps, Sidebar, SidebarProps, StatusBar, StatusBarProps, StatusBarSectionProps, Toolbar, ToolbarButtonProps, ToolbarGroupProps, ToolbarProps, ZoomControl, ZoomControlProps } from './primitives/index.js';
19
20
  export { C as CURRENT_DOCUMENT_VERSION, b as LabStoreContext, c as LabStoreProvider, T as TrialIdContext, d as TrialIdProvider, f as createMemoryAdapter, l as labDocumentKey, g as localStorageAdapter, n as noneAdapter, q as quarantineKey, s as sessionStorageAdapter, u as urlHashAdapter, h as useLabStore, i as useTrialId, j as useTrialState } from './_dts/useTrialState-CsGMjhu9.js';
20
21
  export { Box, Rect, SurfaceContext, SurfaceFrame, SurfaceHandle, UseTiledSurfaceOptions, composeRects, rectsEqual, toDeviceRect, useSurface, useSurfaceOptional, useSurfaceTile, useTiledSurface } from './surface/index.js';
21
- export { LayerStack, LayerStackItem, LayerStackProps } from './ui/layers/index.js';
22
22
  export { EventBus, EventListener, clearUndo, createEventBus, emptyStack, pushSnapshot, redo, undo } from './undo/index.js';
23
23
  import 'windease';
24
24
  import 'zustand/vanilla';
25
25
 
26
- /** A point in the space the instrument works in. */
27
- interface Vec3 {
26
+ /** An annotation drawn over a curve plot: a shaded band across a range of x,
27
+ * or a vertical line at one x. */
28
+ type CurveMark = {
29
+ kind: 'band';
30
+ x: [number, number];
31
+ color?: string;
32
+ } | {
33
+ kind: 'line';
28
34
  x: number;
29
- y: number;
30
- z: number;
31
- }
32
- /** An orbit camera as a trial view: where it looks from, and what it looks at.
33
- * labkit does not turn this into a matrix — the host's renderer does. */
34
- interface OrbitView {
35
- yaw: number;
36
- pitch: number;
37
- distance: number;
38
- target: Vec3;
39
- }
40
- /** Just short of the pole. At exactly ±PI/2 the azimuth is undefined and the
41
- * camera rolls, which reads as the model jumping rather than as a limit. */
42
- declare const PITCH_LIMIT: number;
43
- declare function clampPitch(pitch: number): number;
44
- declare function wrapYaw(yaw: number): number;
45
- /** The view a drag of (dx, dy) from `start` produces. Absolute against the drag
46
- * start, so it can be re-applied any number of times without compounding. */
47
- declare function orbitAfterDrag(start: OrbitView, dx: number, dy: number): OrbitView;
48
- /** Multiplicative, so one notch covers the same proportion of the distance
49
- * whether the camera is near or far. */
50
- declare function orbitAfterWheel(view: OrbitView, deltaY: number, minDistance: number, maxDistance: number): OrbitView;
51
- interface UseOrbitOptions {
52
- view: OrbitView;
53
- onViewChange: (v: OrbitView) => void;
54
- /** Restored on double-click. Defaults to the view the hook first saw. */
55
- home?: OrbitView;
56
- minDistance?: number;
57
- maxDistance?: number;
58
- }
59
- interface OrbitHandlers {
60
- onWheel: (e: WheelEvent<HTMLElement>) => void;
61
- onPointerDown: (e: PointerEvent<HTMLElement>) => void;
62
- onPointerMove: (e: PointerEvent<HTMLElement>) => void;
63
- onPointerUp: (e: PointerEvent<HTMLElement>) => void;
64
- onDoubleClick: () => void;
65
- isDragging: () => boolean;
35
+ color?: string;
36
+ };
37
+ /** Props for `<CurveField>`. */
38
+ interface CurveFieldProps {
39
+ /** Flat [x0, y0, x1, y1, …] — matches how curve-as-array configs
40
+ * serialize in JSON snapshots. */
41
+ values: number[];
42
+ min: number;
43
+ max: number;
44
+ step: number;
45
+ /** Plot width in CSS px. Caller sizes (typically uses a ResizeObserver). */
46
+ width: number;
47
+ /** Plot height in CSS px. Default 110. */
48
+ height?: number;
49
+ /** Flat default curve. When provided, a Reset button restores it. */
50
+ defaults?: readonly number[];
51
+ onChange: (next: number[]) => void;
52
+ /** Optional vertical marks overlaid on the plot (e.g. landmarks). */
53
+ marks?: readonly CurveMark[];
66
54
  }
67
- /** Pointer gestures over an orbit view: drag to turn, wheel or pinch to dolly,
68
- * double-click to go home. The 3D peer of `usePanZoom`. */
69
- declare function useOrbit({ view, onViewChange, home, minDistance, maxDistance, }: UseOrbitOptions): OrbitHandlers;
55
+ /**
56
+ * A function-domain (y = f(x), x ∈ [0,1]) curve editor with per-stop
57
+ * numeric readouts and flip buttons. Wraps weasel-ui's
58
+ * `CurveEditor`; consumers wanting the raw editor (2D paths,
59
+ * custom anchors) should import that instead.
60
+ */
61
+ declare function CurveField({ values, min, max, step, width, height, defaults, onChange, marks, }: CurveFieldProps): react_jsx_runtime.JSX.Element;
70
62
 
71
- /** Shared chaining surface. Every method clones, so a node can be reused as a
72
- * base for several leaves without one bleeding into the next. */
73
- declare abstract class BaseNode<T> implements ConfigNode<T> {
74
- readonly annotations: Readonly<Annotations>;
75
- readonly options: Readonly<NodeOptions>;
76
- abstract readonly kind: string | null;
77
- readonly default: T;
78
- constructor(defaultValue: T, annotations?: Readonly<Annotations>, options?: Readonly<NodeOptions>);
79
- /** Clone into the same subclass. Subclasses with extra constructor
80
- * arguments override this. */
81
- protected with(annotations: Annotations, options: NodeOptions): this;
82
- protected ann(patch: Annotations): this;
83
- protected opt(patch: NodeOptions): this;
84
- /** Human-readable label. Defaults to the key, title-cased. */
85
- label(name: string): this;
86
- /** Longer help text, surfaced as a tooltip on the row label. */
87
- describe(description: string): this;
88
- /** Omit from the panel unless it is asked to show hidden leaves. */
89
- hidden(): this;
90
- /** Pair with a sibling sharing this id, side-by-side on one row. */
91
- pair(pair: string): this;
92
- /** Render under a named section heading. */
93
- section(section: string): this;
94
- /** Show this row only while the predicate holds. Presentational — the value
95
- * stays in config and the instrument still reads it. */
96
- showIf(predicate: (config: Record<string, unknown>) => boolean): this;
97
- /** Draw this one row yourself, keeping the kind, default and validation. */
98
- render(renderer: ControlRenderer): this;
99
- }
100
- declare class NumberNode extends BaseNode<number> {
101
- readonly kind = "number";
102
- /** Bound the value. A number with both bounds renders as a slider. */
103
- range(min: number, max: number): this;
104
- step(step: number): this;
105
- /** Force a slider even without both bounds. */
106
- slider(): this;
107
- /** Force a typed input even when both bounds are set. */
108
- input(): this;
109
- }
110
- declare class BooleanNode extends BaseNode<boolean> {
111
- readonly kind = "boolean";
112
- /** Ask for a switch. `ControlPanel` still draws a checkbox; weasel-ui's
113
- * `PrefsForm` honors the distinction. */
114
- toggle(): this;
115
- }
116
- declare class StringNode extends BaseNode<string> {
117
- readonly kind = "string";
118
- placeholder(placeholder: string): this;
119
- maxLength(maxLength: number): this;
120
- /** Milliseconds to debounce live writes. 0 commits every keystroke. */
121
- debounce(debounceMs: number): this;
63
+ /** Props for `<Subpanel>`. */
64
+ interface SubpanelProps {
65
+ title: ReactNode;
66
+ children: ReactNode;
67
+ className?: string;
122
68
  }
123
- declare class ColorNode extends BaseNode<string> {
124
- readonly kind = "color";
69
+ /** A typographic divider inside a property list: a small title flanked by a
70
+ * rule. Purely a heading — use `<PropertyGroup>` for a bordered section. */
71
+ declare function Subpanel({ title, children, className }: SubpanelProps): react_jsx_runtime.JSX.Element;
72
+ /** Props for `<EffectCard>`. */
73
+ interface EffectCardProps {
74
+ /** Card title rendered in the title bar (e.g. effect kind label or a select). */
75
+ title: ReactNode;
76
+ /** Optional badge/chip displayed before the remove button (e.g. primary value summary). */
77
+ primary?: ReactNode;
78
+ /** Optional accent color in any CSS color form. Sets --wzl-effect-card-accent on the card. */
79
+ accent?: string;
80
+ /** Optional ordinal badge that doubles as the drag handle (used by tail cards in SB). */
81
+ index?: number;
82
+ expanded?: boolean;
83
+ onToggleExpanded?: () => void;
84
+ onRemove?: () => void;
85
+ /**
86
+ * Drag-handle wiring. When provided, an inline handle (⋮⋮ icon or `index`)
87
+ * activates HTML5 drag on press. Consumer owns the drag/drop coordination —
88
+ * see EffectCardList for the batteries-included wrapper.
89
+ */
90
+ draggable?: boolean;
91
+ onPressHandle?: () => void;
92
+ onReleaseHandle?: () => void;
93
+ onDragStart?: (e: React.DragEvent<HTMLDivElement>) => void;
94
+ onDragEnd?: (e: React.DragEvent<HTMLDivElement>) => void;
95
+ onDragOver?: (e: React.DragEvent<HTMLDivElement>) => void;
96
+ onDragLeave?: (e: React.DragEvent<HTMLDivElement>) => void;
97
+ onDrop?: (e: React.DragEvent<HTMLDivElement>) => void;
98
+ dragging?: boolean;
99
+ children?: ReactNode;
100
+ className?: string;
125
101
  }
126
- declare class EnumNode<T extends string> extends BaseNode<T> {
127
- readonly kind = "enum";
128
- /** Render as a segmented control rather than a select. */
129
- radio(): this;
130
- /** Relabel the choices. Named `labels` rather than `options` because
131
- * `options` is the node's own extras bag. */
132
- labels(options: readonly ConfigOption[]): this;
102
+ /** An accented, collapsible card for one item in a list of like things —
103
+ * effects, layers, tails. The accent color rebinds the theme accent token
104
+ * within the card, so its controls pick it up too. */
105
+ declare function EffectCard({ title, primary, accent, index, expanded, onToggleExpanded, onRemove, draggable, onPressHandle, onReleaseHandle, onDragStart, onDragEnd, onDragOver, onDragLeave, onDrop, dragging, children, className, }: EffectCardProps): react_jsx_runtime.JSX.Element;
106
+ /** The minimum an item must carry to appear in an `<EffectCardList>`. */
107
+ interface EffectCardListItem {
108
+ id: string | number;
133
109
  }
134
- /** A leaf whose kind the rule chain decides. */
135
- declare class ValueNode<T> extends BaseNode<T> {
136
- readonly kind: null;
110
+ /** Props for `<EffectCardList>`. */
111
+ interface EffectCardListProps<T extends EffectCardListItem> {
112
+ items: ReadonlyArray<T>;
113
+ renderItem: (item: T, helpers: {
114
+ isExpanded: boolean;
115
+ isDragging: boolean;
116
+ toggleExpanded: () => void;
117
+ cardProps: Pick<EffectCardProps, 'expanded' | 'dragging' | 'draggable' | 'onToggleExpanded' | 'onPressHandle' | 'onReleaseHandle' | 'onDragStart' | 'onDragEnd' | 'onDragOver' | 'onDragLeave' | 'onDrop'>;
118
+ }) => ReactNode;
119
+ onReorder: (sourceId: T['id'], targetId: T['id'], position: 'before' | 'after') => void;
120
+ /** Optional rendered when the list is empty. */
121
+ empty?: ReactNode;
122
+ /** IDs to render expanded on first mount. Defaults to all collapsed. */
123
+ defaultExpandedIds?: ReadonlyArray<T['id']>;
137
124
  }
138
- /** A leaf of a kind labkit does not ship a row for. */
139
- declare class CustomNode<T> extends BaseNode<T> {
140
- readonly kind: string;
141
- constructor(kind: string, defaultValue: T, annotations?: Readonly<Annotations>, options?: Readonly<NodeOptions>);
142
- protected with(annotations: Annotations, options: NodeOptions): this;
125
+ /** A drag-reorderable list of `<EffectCard>`s. Owns the expanded and dragging
126
+ * state and hands it back to `renderItem`, so the caller only supplies each
127
+ * card's contents. */
128
+ declare function EffectCardList<T extends EffectCardListItem>({ items, renderItem, onReorder, empty, defaultExpandedIds, }: EffectCardListProps<T>): react_jsx_runtime.JSX.Element;
129
+
130
+ /** Props for `<PropertyGroup>`. */
131
+ interface PropertyGroupProps {
132
+ /** Title rendered between two rules at the top of the group. */
133
+ title: ReactNode;
134
+ /** When true the group renders nothing — useful for conditional sections. */
135
+ hidden?: boolean;
136
+ children: ReactNode;
137
+ className?: string;
138
+ /**
139
+ * How rows pack into the 2-column grid.
140
+ * - `'auto-color'` (default): only color rows pair side-by-side; everything
141
+ * else spans the full width.
142
+ * - `'pairs'`: every row auto-places into the 2-column grid two-per-row.
143
+ */
144
+ pack?: 'auto-color' | 'pairs';
143
145
  }
144
146
  /**
145
- * Builds an instrument's config: the values, their types, and how each is
146
- * edited, in one declaration.
147
- *
148
- * ```ts
149
- * const config = f.schema({
150
- * showGrid: f.boolean(true),
151
- * cellSize: f.number(20).range(5, 80).step(5).label('Grid spacing'),
152
- * })
153
- * ```
147
+ * Visually-bordered group inside a PropertyList. Use to scope a set of
148
+ * related rows under a heading (e.g. "Aqua", "Bevel", "Dome" sections
149
+ * inside a fill effect's controls).
154
150
  */
155
- declare const f: {
156
- number: (def: number) => NumberNode;
157
- boolean: (def: boolean) => BooleanNode;
158
- string: (def: string) => StringNode;
159
- color: (def: string) => ColorNode;
160
- /** A fixed set of choices. The default's literal type flows into the config
161
- * type, so `f.enum('fast', ['fast', 'accurate'])` gives
162
- * `'fast' | 'accurate'` with no `as const`. */
163
- enum: <const T extends string>(def: T, options: readonly T[] | readonly ConfigOption[]) => EnumNode<T>;
164
- /** A leaf with no declared kind: the rule chain decides, which is how a lab
165
- * states a convention like "every `*Color` key is a color picker". */
166
- value: <T>(def: T) => ValueNode<T>;
167
- /** A leaf of a kind a lab supplies the control for, through `controls`. */
168
- custom: <T>(kind: string, def: T, validate?: (leaf: ToolPrefLeaf) => string[]) => CustomNode<T>;
169
- /** Collect leaves into an instrument's config. */
170
- schema<S extends Record<string, ConfigNode>>(nodes: S): ConfigSchema<InferConfig<S>>;
171
- };
151
+ declare function PropertyGroup({ title, hidden, children, className, pack, }: PropertyGroupProps): react_jsx_runtime.JSX.Element | null;
152
+
153
+ /** Props for `<PropertyPanel>`. */
154
+ interface PropertyPanelProps {
155
+ title?: ReactNode;
156
+ children: ReactNode;
157
+ className?: string;
158
+ }
159
+ /** A titled panel holding property rows — the sidebar container the rest of
160
+ * this module's components fill. */
161
+ declare function PropertyPanel({ title, children, className }: PropertyPanelProps): react_jsx_runtime.JSX.Element;
162
+ /** How a property list packs its rows into two columns. */
163
+ type PropertyListPack = 'auto-color' | 'pairs';
164
+ /** Props for `<PropertyList>`. */
165
+ interface PropertyListProps {
166
+ children: ReactNode;
167
+ className?: string;
168
+ /**
169
+ * How rows pack into the 2-column grid.
170
+ * - `'auto-color'` (default): only color rows pair side-by-side; everything
171
+ * else spans the full width. Right for sparse top-level panels.
172
+ * - `'pairs'`: every row auto-places into the 2-column grid two-per-row.
173
+ * Headers and subpanels still span the full width; wrap any other
174
+ * full-width child in `<PropertySpan>`. Right for dense effect bodies.
175
+ */
176
+ pack?: PropertyListPack;
177
+ }
178
+ /**
179
+ * Grid container for PropertyRows. Use standalone for chrome-less layouts, or
180
+ * nest inside <PropertyPanel/> for the standard glass card.
181
+ */
182
+ declare function PropertyList({ children, className, pack }: PropertyListProps): react_jsx_runtime.JSX.Element;
183
+ /** Props for `<PropertySpan>`. */
184
+ interface PropertySpanProps {
185
+ children: ReactNode;
186
+ className?: string;
187
+ }
188
+ /**
189
+ * Wrapper that makes an arbitrary child span both columns of a
190
+ * `<PropertyList pack="pairs">`, a `<PropertyGroup pack="pairs">` body, or a
191
+ * `<Subpanel>`. `<PropertyRow span>` covers the row case; this covers
192
+ * everything else a consumer puts in the grid.
193
+ */
194
+ declare function PropertySpan({ children, className }: PropertySpanProps): react_jsx_runtime.JSX.Element;
195
+ /** Which control shape a row holds, which decides its intrinsic layout. */
196
+ type PropertyRowVariant = 'default' | 'color' | 'checkbox';
197
+ /** Whether a row's label sits above its control or beside it. */
198
+ type PropertyRowLayout = 'block' | 'inline';
199
+ /** Props for `<PropertyRow>`. */
200
+ interface PropertyRowProps {
201
+ label: ReactNode;
202
+ /** Right-aligned readout shown next to the label (e.g. current value). */
203
+ readout?: ReactNode;
204
+ /**
205
+ * Help text for the row, shown in a tooltip off an ⓘ affordance beside the
206
+ * label. Empty or absent renders no affordance.
207
+ */
208
+ description?: string;
209
+ variant?: PropertyRowVariant;
210
+ /**
211
+ * Label position relative to the control. "block" (default) stacks
212
+ * label above control; "inline" places the label to the left.
213
+ * Color and checkbox variants are always inline by their own nature.
214
+ */
215
+ layout?: PropertyRowLayout;
216
+ /**
217
+ * Take the full width of the enclosing grid. Only has an effect inside a
218
+ * `<PropertyList pack="pairs">` or a `<Subpanel>`; elsewhere rows are already
219
+ * full width.
220
+ */
221
+ span?: boolean;
222
+ children: ReactNode;
223
+ htmlFor?: string;
224
+ className?: string;
225
+ }
226
+ /** The label-plus-control frame every typed row below is built from. Use it
227
+ * directly for a control this module does not cover. */
228
+ declare function PropertyRow({ label, readout, description, variant, layout, span, children, htmlFor, className, }: PropertyRowProps): react_jsx_runtime.JSX.Element;
229
+ /** Props for `<SliderRow>`. */
230
+ interface SliderRowProps {
231
+ label: ReactNode;
232
+ value: number;
233
+ min: number;
234
+ max: number;
235
+ step?: number;
236
+ onChange: (next: number) => void;
237
+ /** Override how the value is rendered next to the label. Defaults to `value.toString()`. */
238
+ format?: (value: number) => ReactNode;
239
+ /**
240
+ * Optional suffix rendered next to the readout. A string becomes a
241
+ * baseline-aligned dim "word" unit (e.g. "px"); pass JSX like `<sup>°</sup>`
242
+ * to get the browser's native super positioning for symbol units.
243
+ */
244
+ unit?: ReactNode;
245
+ layout?: PropertyRowLayout;
246
+ description?: string;
247
+ }
248
+ /** A bounded number edited by dragging, with a live readout whose precision
249
+ * follows `step`. */
250
+ declare function SliderRow({ label, value, min, max, step, onChange, format, unit, layout, description, }: SliderRowProps): react_jsx_runtime.JSX.Element;
251
+ /** Props for `<ColorRow>`. */
252
+ interface ColorRowProps {
253
+ label: ReactNode;
254
+ value: string;
255
+ onChange: (next: string) => void;
256
+ /** 0..1 alpha. When provided, a translucent slider renders beneath the swatch. */
257
+ alpha?: number;
258
+ onAlphaChange?: (next: number) => void;
259
+ /**
260
+ * Render the alpha track as inert (dimmed, no thumb, not-allowed cursor).
261
+ * Use when the color's consumer drops alpha so the affordance reads dead.
262
+ */
263
+ alphaDisabled?: boolean;
264
+ description?: string;
265
+ }
266
+ /** A color swatch, optionally with an alpha slider beneath it. */
267
+ declare function ColorRow({ label, value, onChange, alpha, onAlphaChange, alphaDisabled, description, }: ColorRowProps): react_jsx_runtime.JSX.Element;
268
+ /** Props for `<CheckboxRow>`. */
269
+ interface CheckboxRowProps {
270
+ label: ReactNode;
271
+ value: boolean;
272
+ onChange: (next: boolean) => void;
273
+ description?: string;
274
+ }
275
+ /** A boolean checkbox. */
276
+ declare function CheckboxRow({ label, value, onChange, description }: CheckboxRowProps): react_jsx_runtime.JSX.Element;
277
+ /** Props for `<TextRow>`. */
278
+ interface TextRowProps {
279
+ label: ReactNode;
280
+ value: string;
281
+ onChange: (next: string) => void;
282
+ placeholder?: string;
283
+ maxLength?: number;
284
+ layout?: PropertyRowLayout;
285
+ description?: string;
286
+ }
287
+ /** A single-line text input. */
288
+ declare function TextRow({ label, value, onChange, placeholder, maxLength, layout, description, }: TextRowProps): react_jsx_runtime.JSX.Element;
289
+ /** Props for `<NumberRow>`. */
290
+ interface NumberRowProps {
291
+ label: ReactNode;
292
+ value: number;
293
+ onChange: (next: number) => void;
294
+ min?: number;
295
+ max?: number;
296
+ step?: number;
297
+ placeholder?: string;
298
+ layout?: PropertyRowLayout;
299
+ description?: string;
300
+ }
301
+ /** A number typed directly. Reach for `<SliderRow>` when the range matters
302
+ * more than the exact value. */
303
+ declare function NumberRow({ label, value, onChange, min, max, step, placeholder, layout, description, }: NumberRowProps): react_jsx_runtime.JSX.Element;
304
+ interface PropertyOption<T extends string> {
305
+ value: T;
306
+ label: ReactNode;
307
+ }
308
+ /** Props for `<SelectRow>`. */
309
+ interface SelectRowProps<T extends string> {
310
+ label: ReactNode;
311
+ value: T;
312
+ options: ReadonlyArray<PropertyOption<T>>;
313
+ onChange: (next: T) => void;
314
+ layout?: PropertyRowLayout;
315
+ description?: string;
316
+ }
317
+ /** A dropdown over a fixed set of choices. Prefer `<ToggleRow>` when there
318
+ * are only two or three and they should all stay visible. */
319
+ declare function SelectRow<T extends string>({ label, value, options, onChange, layout, description, }: SelectRowProps<T>): react_jsx_runtime.JSX.Element;
320
+ /** Props for `<ToggleRow>`. */
321
+ interface ToggleRowProps<T extends string> {
322
+ label: ReactNode;
323
+ value: T;
324
+ options: ReadonlyArray<PropertyOption<T>>;
325
+ onChange: (next: T) => void;
326
+ layout?: PropertyRowLayout;
327
+ description?: string;
328
+ }
329
+ /** A segmented control: the same choice as a select, with every option
330
+ * visible at once. */
331
+ declare function ToggleRow<T extends string>({ label, value, options, onChange, layout, description, }: ToggleRowProps<T>): react_jsx_runtime.JSX.Element;
332
+
333
+ /** A point in the space the instrument works in. */
334
+ interface Vec3 {
335
+ x: number;
336
+ y: number;
337
+ z: number;
338
+ }
339
+ /** An orbit camera as a trial view: where it looks from, and what it looks at.
340
+ * labkit does not turn this into a matrix — the host's renderer does. */
341
+ interface OrbitView {
342
+ yaw: number;
343
+ pitch: number;
344
+ distance: number;
345
+ target: Vec3;
346
+ }
347
+ /** Just short of the pole. At exactly ±PI/2 the azimuth is undefined and the
348
+ * camera rolls, which reads as the model jumping rather than as a limit. */
349
+ declare const PITCH_LIMIT: number;
350
+ declare function clampPitch(pitch: number): number;
351
+ declare function wrapYaw(yaw: number): number;
352
+ /** The view a drag of (dx, dy) from `start` produces. Absolute against the drag
353
+ * start, so it can be re-applied any number of times without compounding. */
354
+ declare function orbitAfterDrag(start: OrbitView, dx: number, dy: number): OrbitView;
355
+ /** Multiplicative, so one notch covers the same proportion of the distance
356
+ * whether the camera is near or far. */
357
+ declare function orbitAfterWheel(view: OrbitView, deltaY: number, minDistance: number, maxDistance: number): OrbitView;
358
+ interface UseOrbitOptions {
359
+ view: OrbitView;
360
+ onViewChange: (v: OrbitView) => void;
361
+ /** Restored on double-click. Defaults to the view the hook first saw. */
362
+ home?: OrbitView;
363
+ minDistance?: number;
364
+ maxDistance?: number;
365
+ }
366
+ interface OrbitHandlers {
367
+ onWheel: (e: WheelEvent<HTMLElement>) => void;
368
+ onPointerDown: (e: PointerEvent<HTMLElement>) => void;
369
+ onPointerMove: (e: PointerEvent<HTMLElement>) => void;
370
+ onPointerUp: (e: PointerEvent<HTMLElement>) => void;
371
+ onDoubleClick: () => void;
372
+ isDragging: () => boolean;
373
+ }
374
+ /** Pointer gestures over an orbit view: drag to turn, wheel or pinch to dolly,
375
+ * double-click to go home. The 3D peer of `usePanZoom`. */
376
+ declare function useOrbit({ view, onViewChange, home, minDistance, maxDistance, }: UseOrbitOptions): OrbitHandlers;
377
+
378
+ /** Shared chaining surface. Every method clones, so a node can be reused as a
379
+ * base for several leaves without one bleeding into the next. */
380
+ declare abstract class BaseNode<T> implements ConfigNode<T> {
381
+ readonly annotations: Readonly<Annotations>;
382
+ readonly options: Readonly<NodeOptions>;
383
+ abstract readonly kind: string | null;
384
+ readonly default: T;
385
+ constructor(defaultValue: T, annotations?: Readonly<Annotations>, options?: Readonly<NodeOptions>);
386
+ /** Clone into the same subclass. Subclasses with extra constructor
387
+ * arguments override this. */
388
+ protected with(annotations: Annotations, options: NodeOptions): this;
389
+ protected ann(patch: Annotations): this;
390
+ protected opt(patch: NodeOptions): this;
391
+ /** Human-readable label. Defaults to the key, title-cased. */
392
+ label(name: string): this;
393
+ /** Longer help text, surfaced as a tooltip on the row label. */
394
+ describe(description: string): this;
395
+ /** Omit from the panel unless it is asked to show hidden leaves. */
396
+ hidden(): this;
397
+ /** Pair with a sibling sharing this id, side-by-side on one row. */
398
+ pair(pair: string): this;
399
+ /** Render under a named section heading. */
400
+ section(section: string): this;
401
+ /** Show this row only while the predicate holds. Presentational — the value
402
+ * stays in config and the instrument still reads it. */
403
+ showIf(predicate: (config: Record<string, unknown>) => boolean): this;
404
+ /** Draw this one row yourself, keeping the kind, default and validation. */
405
+ render(renderer: ControlRenderer): this;
406
+ }
407
+ declare class NumberNode extends BaseNode<number> {
408
+ readonly kind = "number";
409
+ /** Bound the value. A number with both bounds renders as a slider. */
410
+ range(min: number, max: number): this;
411
+ step(step: number): this;
412
+ /** Force a slider even without both bounds. */
413
+ slider(): this;
414
+ /** Force a typed input even when both bounds are set. */
415
+ input(): this;
416
+ }
417
+ declare class BooleanNode extends BaseNode<boolean> {
418
+ readonly kind = "boolean";
419
+ /** Ask for a switch. `ControlPanel` still draws a checkbox; weasel-ui's
420
+ * `PrefsForm` honors the distinction. */
421
+ toggle(): this;
422
+ }
423
+ declare class StringNode extends BaseNode<string> {
424
+ readonly kind = "string";
425
+ placeholder(placeholder: string): this;
426
+ maxLength(maxLength: number): this;
427
+ /** Milliseconds to debounce live writes. 0 commits every keystroke. */
428
+ debounce(debounceMs: number): this;
429
+ }
430
+ declare class ColorNode extends BaseNode<string> {
431
+ readonly kind = "color";
432
+ }
433
+ declare class EnumNode<T extends string> extends BaseNode<T> {
434
+ readonly kind = "enum";
435
+ /** Render as a segmented control rather than a select. */
436
+ radio(): this;
437
+ /** Relabel the choices. Named `labels` rather than `options` because
438
+ * `options` is the node's own extras bag. */
439
+ labels(options: readonly ConfigOption[]): this;
440
+ }
441
+ /** A leaf whose kind the rule chain decides. */
442
+ declare class ValueNode<T> extends BaseNode<T> {
443
+ readonly kind: null;
444
+ }
445
+ /** A leaf of a kind labkit does not ship a row for. */
446
+ declare class CustomNode<T> extends BaseNode<T> {
447
+ readonly kind: string;
448
+ constructor(kind: string, defaultValue: T, annotations?: Readonly<Annotations>, options?: Readonly<NodeOptions>);
449
+ protected with(annotations: Annotations, options: NodeOptions): this;
450
+ }
451
+ /**
452
+ * Builds an instrument's config: the values, their types, and how each is
453
+ * edited, in one declaration.
454
+ *
455
+ * ```ts
456
+ * const config = f.schema({
457
+ * showGrid: f.boolean(true),
458
+ * cellSize: f.number(20).range(5, 80).step(5).label('Grid spacing'),
459
+ * })
460
+ * ```
461
+ */
462
+ declare const f: {
463
+ number: (def: number) => NumberNode;
464
+ boolean: (def: boolean) => BooleanNode;
465
+ string: (def: string) => StringNode;
466
+ color: (def: string) => ColorNode;
467
+ /** A fixed set of choices. The default's literal type flows into the config
468
+ * type, so `f.enum('fast', ['fast', 'accurate'])` gives
469
+ * `'fast' | 'accurate'` with no `as const`. */
470
+ enum: <const T extends string>(def: T, options: readonly T[] | readonly ConfigOption[]) => EnumNode<T>;
471
+ /** A leaf with no declared kind: the rule chain decides, which is how a lab
472
+ * states a convention like "every `*Color` key is a color picker". */
473
+ value: <T>(def: T) => ValueNode<T>;
474
+ /** A leaf of a kind a lab supplies the control for, through `controls`. */
475
+ custom: <T>(kind: string, def: T, validate?: (leaf: ToolPrefLeaf) => string[]) => CustomNode<T>;
476
+ /** Collect leaves into an instrument's config. */
477
+ schema<S extends Record<string, ConfigNode>>(nodes: S): ConfigSchema<InferConfig<S>>;
478
+ };
172
479
 
173
480
  /**
174
481
  * Adapt a legacy `configSchema(): ConfigField[]` into the resolved shape, so
@@ -386,414 +693,137 @@ interface WorkspaceProps {
386
693
  /** Fires when a tile's extent changes. Persist it and hand it back as
387
694
  * `layout` to make a resize survive a reload. */
388
695
  onLayoutChange?: (layout: TrialLayout) => void;
389
- gap?: number;
390
- padding?: number;
391
- /**
392
- * Fixed tiling extent. Omit in an app — the grid measures its own box. Supply
393
- * it where nothing measures, notably jsdom: at a zero measurement the grid
394
- * renders no tiles at all.
395
- */
396
- viewport?: {
397
- w: number;
398
- h: number;
399
- };
400
- }
401
- /**
402
- * Auto-balanced tiling of trials, `ceil(sqrt(n))` columns wide.
403
- *
404
- * Tiles are absolutely positioned at the rects `gridStrategy` computes, not
405
- * laid out by CSS — `windease/styles.css` (folded into
406
- * `@weasel-js/labkit/styles.css`) carries the rules that positioning depends on.
407
- */
408
- declare function Workspace({ children, ids, resizable, reorderable, onReorder, layout, onLayoutChange, gap, padding, viewport, }: WorkspaceProps): react_jsx_runtime.JSX.Element;
409
-
410
- /** The 2D view labkit has always shipped, and what a trial gets when it names no
411
- * other. Re-exported under its own name so a consumer can say which it means. */
412
- type ViewTransform2D = ViewTransform;
413
- declare const DEFAULT_VIEW: ViewTransform2D;
414
- /** A trial's view is opaque to labkit, so anything that needs the 2D shape — the
415
- * zoom chrome, `CanvasStack` — asks for it and handles not getting it. */
416
- declare function as2DView(view: unknown): ViewTransform2D | null;
417
-
418
- type TokenValue = string | number | readonly (string | number)[];
419
- /**
420
- * A single design token as authored, before aliases are resolved: a DTCG-shaped
421
- * `{ type, value }` pair where `value` may still be a `{ref}` to another token.
422
- */
423
- interface RawToken {
424
- readonly type: string;
425
- readonly value: TokenValue;
426
- /** Render the referenced color at this alpha, 0–1. */
427
- readonly alpha?: number | undefined;
428
- readonly description?: string | undefined;
429
- }
430
- /** A token graph flattened to one level, keyed by token name (no `--wzl-`
431
- * prefix). Still unresolved — see `ResolvedTokenMap` for the output side. */
432
- type FlatTokens = Record<string, RawToken>;
433
-
434
- /**
435
- * A theme: a named set of design tokens, organized into a mode-invariant layer
436
- * plus one layer per mode (light, dark, …), optionally extending another theme.
437
- * Tokens are held unresolved — aliases between them are collapsed later by
438
- * `resolveTheme`, so an override of a base primitive still reaches everything
439
- * that references it.
440
- */
441
- interface Theme {
442
- readonly name: string;
443
- readonly extends: Theme | null;
444
- readonly defaultMode: string;
445
- readonly tokens: FlatTokens;
446
- readonly modes: Readonly<Record<string, FlatTokens>>;
447
- }
448
-
449
- /**
450
- * labkit's theme: a cosmic dark and a warm parchment light, extending the
451
- * built-in weasel theme. Authored as DTCG and loaded at import time — the
452
- * interchange path a theme exported from a design tool would take.
453
- */
454
- declare const interstellarTheme: Theme;
455
-
456
- /** Props for `<Trial>`. */
457
- interface TrialProps {
458
- id: string;
459
- /** Contributions the lab adds to this trial's chrome, merged after the
460
- * instrument's own. */
461
- chrome?: readonly TrialContribution[];
462
- /** Built-in contribution ids to drop. Throws on an id that is not there. */
463
- suppress?: readonly string[];
464
- }
465
- /** Renders one trial from the lab store: looks up its record and
466
- * instrument, and mounts the instrument inside the trial chrome. */
467
- declare function Trial({ id, chrome, suppress }: TrialProps): react_jsx_runtime.JSX.Element;
468
-
469
- interface UndoBindings {
470
- canUndo: boolean;
471
- canRedo: boolean;
472
- undo: () => void;
473
- redo: () => void;
474
- }
475
- /** Props for `<TrialChrome>`. */
476
- interface TrialChromeProps {
477
- trialId: string;
478
- record: TrialRecord;
479
- instrument: Instrument;
480
- isLastTrial: boolean;
481
- undoBindings?: UndoBindings;
482
- /** Supplied when the instrument declares a `job`. */
483
- job?: JobHandle;
484
- /** Contributions the trial runtime itself adds — the drag palette and the
485
- * layer list, which depend on runtime state the instrument cannot reach. */
486
- trialChrome?: readonly TrialContribution[];
487
- /** Contributions from the lab, merged last. */
488
- chrome?: readonly TrialContribution[];
489
- /** Built-in contribution ids to drop. Throws on an id that is not there. */
490
- suppress?: readonly string[];
491
- /** The trial's resolved tool slot, and the setter that writes whichever
492
- * slot it resolved to. `Trial` owns the resolution. */
493
- activeToolId?: string | null;
494
- setActiveTool?: (id: string) => void;
495
- children: ReactNode;
496
- }
497
- /** The frame around a running instrument. Builds one chrome context, assembles
498
- * the contributions the instrument, the runtime and the lab declare, and hands
499
- * each region its slice. */
500
- declare function TrialChrome({ trialId, record, instrument, isLastTrial, undoBindings, job, trialChrome, chrome, suppress, activeToolId, setActiveTool, children, }: TrialChromeProps): react_jsx_runtime.JSX.Element;
501
-
502
- /** Append a new trial running `instrumentName`, at that instrument's
503
- * default config and initial state. */
504
- declare function addTrial(trials: TrialRecord[], instruments: InstrumentList, instrumentName: string): TrialRecord[];
505
- /** Insert a deep copy of a trial directly after it. The copy starts with
506
- * an empty undo history — the original's is not shared. */
507
- declare function cloneTrial(trials: TrialRecord[], id: string): TrialRecord[];
508
- /** Remove a trial, unless it is the last one — a lab always has at least
509
- * one. */
510
- declare function closeTrial(trials: TrialRecord[], id: string): TrialRecord[];
511
- /** Return a trial to its instrument's defaults, keeping its id and its
512
- * place in the list. */
513
- declare function resetTrial(trials: TrialRecord[], id: string, instruments: InstrumentList): TrialRecord[];
514
- /**
515
- * Reorder to match `ids`. Ids the list doesn't mention keep their relative
516
- * order at the end, and ids it names that no longer exist are dropped — a
517
- * reorder that raced a close should not resurrect the closed trial.
518
- */
519
- declare function reorderTrials(trials: TrialRecord[], ids: readonly string[]): TrialRecord[];
520
-
521
- /** An annotation drawn over a curve plot: a shaded band across a range of x,
522
- * or a vertical line at one x. */
523
- type CurveMark = {
524
- kind: 'band';
525
- x: [number, number];
526
- color?: string;
527
- } | {
528
- kind: 'line';
529
- x: number;
530
- color?: string;
531
- };
532
- /** Props for `<CurveField>`. */
533
- interface CurveFieldProps {
534
- /** Flat [x0, y0, x1, y1, …] — matches how curve-as-array configs
535
- * serialize in JSON snapshots. */
536
- values: number[];
537
- min: number;
538
- max: number;
539
- step: number;
540
- /** Plot width in CSS px. Caller sizes (typically uses a ResizeObserver). */
541
- width: number;
542
- /** Plot height in CSS px. Default 110. */
543
- height?: number;
544
- /** Flat default curve. When provided, a Reset button restores it. */
545
- defaults?: readonly number[];
546
- onChange: (next: number[]) => void;
547
- /** Optional vertical marks overlaid on the plot (e.g. landmarks). */
548
- marks?: readonly CurveMark[];
549
- }
550
- /**
551
- * A function-domain (y = f(x), x ∈ [0,1]) curve editor with per-stop
552
- * numeric readouts and flip buttons. Wraps weasel-ui's
553
- * `CurveEditor`; consumers wanting the raw editor (2D paths,
554
- * custom anchors) should import it from `@weasel-js/labkit/weasel-ui`.
555
- */
556
- declare function CurveField({ values, min, max, step, width, height, defaults, onChange, marks, }: CurveFieldProps): react_jsx_runtime.JSX.Element;
557
-
558
- /** Props for `<Subpanel>`. */
559
- interface SubpanelProps {
560
- title: ReactNode;
561
- children: ReactNode;
562
- className?: string;
563
- }
564
- /** A typographic divider inside a property list: a small title flanked by a
565
- * rule. Purely a heading — use `<PropertyGroup>` for a bordered section. */
566
- declare function Subpanel({ title, children, className }: SubpanelProps): react_jsx_runtime.JSX.Element;
567
- /** Props for `<EffectCard>`. */
568
- interface EffectCardProps {
569
- /** Card title rendered in the title bar (e.g. effect kind label or a select). */
570
- title: ReactNode;
571
- /** Optional badge/chip displayed before the remove button (e.g. primary value summary). */
572
- primary?: ReactNode;
573
- /** Optional accent color in any CSS color form. Sets --lk-panel-accent on the card. */
574
- accent?: string;
575
- /** Optional ordinal badge that doubles as the drag handle (used by tail cards in SB). */
576
- index?: number;
577
- expanded?: boolean;
578
- onToggleExpanded?: () => void;
579
- onRemove?: () => void;
580
- /**
581
- * Drag-handle wiring. When provided, an inline handle (⋮⋮ icon or `index`)
582
- * activates HTML5 drag on press. Consumer owns the drag/drop coordination —
583
- * see EffectCardList for the batteries-included wrapper.
584
- */
585
- draggable?: boolean;
586
- onPressHandle?: () => void;
587
- onReleaseHandle?: () => void;
588
- onDragStart?: (e: React.DragEvent<HTMLDivElement>) => void;
589
- onDragEnd?: (e: React.DragEvent<HTMLDivElement>) => void;
590
- onDragOver?: (e: React.DragEvent<HTMLDivElement>) => void;
591
- onDragLeave?: (e: React.DragEvent<HTMLDivElement>) => void;
592
- onDrop?: (e: React.DragEvent<HTMLDivElement>) => void;
593
- dragging?: boolean;
594
- children?: ReactNode;
595
- className?: string;
596
- }
597
- /** An accented, collapsible card for one item in a list of like things —
598
- * effects, layers, tails. The accent color rebinds the theme accent token
599
- * within the card, so its controls pick it up too. */
600
- declare function EffectCard({ title, primary, accent, index, expanded, onToggleExpanded, onRemove, draggable, onPressHandle, onReleaseHandle, onDragStart, onDragEnd, onDragOver, onDragLeave, onDrop, dragging, children, className, }: EffectCardProps): react_jsx_runtime.JSX.Element;
601
- /** The minimum an item must carry to appear in an `<EffectCardList>`. */
602
- interface EffectCardListItem {
603
- id: string | number;
604
- }
605
- /** Props for `<EffectCardList>`. */
606
- interface EffectCardListProps<T extends EffectCardListItem> {
607
- items: ReadonlyArray<T>;
608
- renderItem: (item: T, helpers: {
609
- isExpanded: boolean;
610
- isDragging: boolean;
611
- toggleExpanded: () => void;
612
- cardProps: Pick<EffectCardProps, 'expanded' | 'dragging' | 'draggable' | 'onToggleExpanded' | 'onPressHandle' | 'onReleaseHandle' | 'onDragStart' | 'onDragEnd' | 'onDragOver' | 'onDragLeave' | 'onDrop'>;
613
- }) => ReactNode;
614
- onReorder: (sourceId: T['id'], targetId: T['id'], position: 'before' | 'after') => void;
615
- /** Optional rendered when the list is empty. */
616
- empty?: ReactNode;
617
- /** IDs to render expanded on first mount. Defaults to all collapsed. */
618
- defaultExpandedIds?: ReadonlyArray<T['id']>;
619
- }
620
- /** A drag-reorderable list of `<EffectCard>`s. Owns the expanded and dragging
621
- * state and hands it back to `renderItem`, so the caller only supplies each
622
- * card's contents. */
623
- declare function EffectCardList<T extends EffectCardListItem>({ items, renderItem, onReorder, empty, defaultExpandedIds, }: EffectCardListProps<T>): react_jsx_runtime.JSX.Element;
624
-
625
- /** Props for `<PropertyGroup>`. */
626
- interface PropertyGroupProps {
627
- /** Title rendered between two rules at the top of the group. */
628
- title: ReactNode;
629
- /** When true the group renders nothing — useful for conditional sections. */
630
- hidden?: boolean;
631
- children: ReactNode;
632
- className?: string;
696
+ gap?: number;
697
+ padding?: number;
633
698
  /**
634
- * How rows pack into the 2-column grid.
635
- * - `'auto-color'` (default): only color rows pair side-by-side; everything
636
- * else spans the full width.
637
- * - `'pairs'`: every row auto-places into the 2-column grid two-per-row.
699
+ * Fixed tiling extent. Omit in an app — the grid measures its own box. Supply
700
+ * it where nothing measures, notably jsdom: at a zero measurement the grid
701
+ * renders no tiles at all.
638
702
  */
639
- pack?: 'auto-color' | 'pairs';
703
+ viewport?: {
704
+ w: number;
705
+ h: number;
706
+ };
640
707
  }
641
708
  /**
642
- * Visually-bordered group inside a PropertyList. Use to scope a set of
643
- * related rows under a heading (e.g. "Aqua", "Bevel", "Dome" sections
644
- * inside a fill effect's controls).
709
+ * Auto-balanced tiling of trials, `ceil(sqrt(n))` columns wide.
710
+ *
711
+ * Tiles are absolutely positioned at the rects `gridStrategy` computes, not
712
+ * laid out by CSS — `windease/styles.css` (folded into
713
+ * `@weasel-js/labkit/styles.css`) carries the rules that positioning depends on.
645
714
  */
646
- declare function PropertyGroup({ title, hidden, children, className, pack, }: PropertyGroupProps): react_jsx_runtime.JSX.Element | null;
715
+ declare function Workspace({ children, ids, resizable, reorderable, onReorder, layout, onLayoutChange, gap, padding, viewport, }: WorkspaceProps): react_jsx_runtime.JSX.Element;
647
716
 
648
- /** Props for `<PropertyPanel>`. */
649
- interface PropertyPanelProps {
650
- title?: ReactNode;
651
- children: ReactNode;
652
- className?: string;
653
- }
654
- /** A titled panel holding property rows — the sidebar container the rest of
655
- * this module's components fill. */
656
- declare function PropertyPanel({ title, children, className }: PropertyPanelProps): react_jsx_runtime.JSX.Element;
657
- /** How a property list packs its rows into two columns. */
658
- type PropertyListPack = 'auto-color' | 'pairs';
659
- /** Props for `<PropertyList>`. */
660
- interface PropertyListProps {
661
- children: ReactNode;
662
- className?: string;
663
- /**
664
- * How rows pack into the 2-column grid.
665
- * - `'auto-color'` (default): only color rows pair side-by-side; everything
666
- * else spans the full width. Right for sparse top-level panels.
667
- * - `'pairs'`: every row auto-places into the 2-column grid two-per-row.
668
- * Headers, subpanels, and full-width children (`<hr>`, curve blocks)
669
- * still span via `lk-property-list__span`. Right for dense effect bodies.
670
- */
671
- pack?: PropertyListPack;
672
- }
717
+ /** The 2D view labkit has always shipped, and what a trial gets when it names no
718
+ * other. Re-exported under its own name so a consumer can say which it means. */
719
+ type ViewTransform2D = ViewTransform;
720
+ declare const DEFAULT_VIEW: ViewTransform2D;
721
+ /** A trial's view is opaque to labkit, so anything that needs the 2D shape — the
722
+ * zoom chrome, `CanvasStack` — asks for it and handles not getting it. */
723
+ declare function as2DView(view: unknown): ViewTransform2D | null;
724
+
725
+ type TokenValue = string | number | readonly (string | number)[];
673
726
  /**
674
- * Grid container for PropertyRows. Use standalone for chrome-less layouts, or
675
- * nest inside <PropertyPanel/> for the standard glass card.
727
+ * A single design token as authored, before aliases are resolved: a DTCG-shaped
728
+ * `{ type, value }` pair where `value` may still be a `{ref}` to another token.
676
729
  */
677
- declare function PropertyList({ children, className, pack }: PropertyListProps): react_jsx_runtime.JSX.Element;
678
- /** Which control shape a row holds, which decides its intrinsic layout. */
679
- type PropertyRowVariant = 'default' | 'color' | 'checkbox';
680
- /** Whether a row's label sits above its control or beside it. */
681
- type PropertyRowLayout = 'block' | 'inline';
682
- /** Props for `<PropertyRow>`. */
683
- interface PropertyRowProps {
684
- label: ReactNode;
685
- /** Right-aligned readout shown next to the label (e.g. current value). */
686
- readout?: ReactNode;
687
- variant?: PropertyRowVariant;
688
- /**
689
- * Label position relative to the control. "block" (default) stacks
690
- * label above control; "inline" places the label to the left.
691
- * Color and checkbox variants are always inline by their own nature.
692
- */
693
- layout?: PropertyRowLayout;
694
- children: ReactNode;
695
- htmlFor?: string;
696
- className?: string;
697
- }
698
- /** The label-plus-control frame every typed row below is built from. Use it
699
- * directly for a control this module does not cover. */
700
- declare function PropertyRow({ label, readout, variant, layout, children, htmlFor, className, }: PropertyRowProps): react_jsx_runtime.JSX.Element;
701
- /** Props for `<SliderRow>`. */
702
- interface SliderRowProps {
703
- label: ReactNode;
704
- value: number;
705
- min: number;
706
- max: number;
707
- step?: number;
708
- onChange: (next: number) => void;
709
- /** Override how the value is rendered next to the label. Defaults to `value.toString()`. */
710
- format?: (value: number) => ReactNode;
711
- /**
712
- * Optional suffix rendered next to the readout. A string becomes a
713
- * baseline-aligned dim "word" unit (e.g. "px"); pass JSX like `<sup>°</sup>`
714
- * to get the browser's native super positioning for symbol units.
715
- */
716
- unit?: ReactNode;
717
- layout?: PropertyRowLayout;
718
- }
719
- /** A bounded number edited by dragging, with a live readout whose precision
720
- * follows `step`. */
721
- declare function SliderRow({ label, value, min, max, step, onChange, format, unit, layout, }: SliderRowProps): react_jsx_runtime.JSX.Element;
722
- /** Props for `<ColorRow>`. */
723
- interface ColorRowProps {
724
- label: ReactNode;
725
- value: string;
726
- onChange: (next: string) => void;
727
- /** 0..1 alpha. When provided, a translucent slider renders beneath the swatch. */
728
- alpha?: number;
729
- onAlphaChange?: (next: number) => void;
730
- /**
731
- * Render the alpha track as inert (dimmed, no thumb, not-allowed cursor).
732
- * Use when the color's consumer drops alpha so the affordance reads dead.
733
- */
734
- alphaDisabled?: boolean;
735
- }
736
- /** A color swatch, optionally with an alpha slider beneath it. */
737
- declare function ColorRow({ label, value, onChange, alpha, onAlphaChange, alphaDisabled, }: ColorRowProps): react_jsx_runtime.JSX.Element;
738
- /** Props for `<CheckboxRow>`. */
739
- interface CheckboxRowProps {
740
- label: ReactNode;
741
- value: boolean;
742
- onChange: (next: boolean) => void;
743
- }
744
- /** A boolean checkbox. */
745
- declare function CheckboxRow({ label, value, onChange }: CheckboxRowProps): react_jsx_runtime.JSX.Element;
746
- /** Props for `<TextRow>`. */
747
- interface TextRowProps {
748
- label: ReactNode;
749
- value: string;
750
- onChange: (next: string) => void;
751
- placeholder?: string;
752
- maxLength?: number;
753
- layout?: PropertyRowLayout;
730
+ interface RawToken {
731
+ readonly type: string;
732
+ readonly value: TokenValue;
733
+ /** Render the referenced color at this alpha, 0–1. */
734
+ readonly alpha?: number | undefined;
735
+ readonly description?: string | undefined;
754
736
  }
755
- /** A single-line text input. */
756
- declare function TextRow({ label, value, onChange, placeholder, maxLength, layout }: TextRowProps): react_jsx_runtime.JSX.Element;
757
- /** Props for `<NumberRow>`. */
758
- interface NumberRowProps {
759
- label: ReactNode;
760
- value: number;
761
- onChange: (next: number) => void;
762
- min?: number;
763
- max?: number;
764
- step?: number;
765
- placeholder?: string;
766
- layout?: PropertyRowLayout;
737
+ /** A token graph flattened to one level, keyed by token name (no `--wzl-`
738
+ * prefix). Still unresolved — see `ResolvedTokenMap` for the output side. */
739
+ type FlatTokens = Record<string, RawToken>;
740
+
741
+ /**
742
+ * A theme: a named set of design tokens, organized into a mode-invariant layer
743
+ * plus one layer per mode (light, dark, …), optionally extending another theme.
744
+ * Tokens are held unresolved — aliases between them are collapsed later by
745
+ * `resolveTheme`, so an override of a base primitive still reaches everything
746
+ * that references it.
747
+ */
748
+ interface Theme {
749
+ readonly name: string;
750
+ readonly extends: Theme | null;
751
+ readonly defaultMode: string;
752
+ readonly tokens: FlatTokens;
753
+ readonly modes: Readonly<Record<string, FlatTokens>>;
767
754
  }
768
- /** A number typed directly. Reach for `<SliderRow>` when the range matters
769
- * more than the exact value. */
770
- declare function NumberRow({ label, value, onChange, min, max, step, placeholder, layout, }: NumberRowProps): react_jsx_runtime.JSX.Element;
771
- interface SelectOption<T extends string> {
772
- value: T;
773
- label: ReactNode;
755
+
756
+ /**
757
+ * labkit's theme: a cosmic dark and a warm parchment light, extending the
758
+ * built-in weasel theme. Authored as DTCG and loaded at import time — the
759
+ * interchange path a theme exported from a design tool would take.
760
+ */
761
+ declare const interstellarTheme: Theme;
762
+
763
+ /** Props for `<Trial>`. */
764
+ interface TrialProps {
765
+ id: string;
766
+ /** Contributions the lab adds to this trial's chrome, merged after the
767
+ * instrument's own. */
768
+ chrome?: readonly TrialContribution[];
769
+ /** Built-in contribution ids to drop. Throws on an id that is not there. */
770
+ suppress?: readonly string[];
774
771
  }
775
- /** Props for `<SelectRow>`. */
776
- interface SelectRowProps<T extends string> {
777
- label: ReactNode;
778
- value: T;
779
- options: ReadonlyArray<SelectOption<T>>;
780
- onChange: (next: T) => void;
781
- layout?: PropertyRowLayout;
772
+ /** Renders one trial from the lab store: looks up its record and
773
+ * instrument, and mounts the instrument inside the trial chrome. */
774
+ declare function Trial({ id, chrome, suppress }: TrialProps): react_jsx_runtime.JSX.Element;
775
+
776
+ interface UndoBindings {
777
+ canUndo: boolean;
778
+ canRedo: boolean;
779
+ undo: () => void;
780
+ redo: () => void;
782
781
  }
783
- /** A dropdown over a fixed set of choices. Prefer `<ToggleRow>` when there
784
- * are only two or three and they should all stay visible. */
785
- declare function SelectRow<T extends string>({ label, value, options, onChange, layout, }: SelectRowProps<T>): react_jsx_runtime.JSX.Element;
786
- /** Props for `<ToggleRow>`. */
787
- interface ToggleRowProps<T extends string> {
788
- label: ReactNode;
789
- value: T;
790
- options: ReadonlyArray<SelectOption<T>>;
791
- onChange: (next: T) => void;
792
- layout?: PropertyRowLayout;
782
+ /** Props for `<TrialChrome>`. */
783
+ interface TrialChromeProps {
784
+ trialId: string;
785
+ record: TrialRecord;
786
+ instrument: Instrument;
787
+ isLastTrial: boolean;
788
+ undoBindings?: UndoBindings;
789
+ /** Supplied when the instrument declares a `job`. */
790
+ job?: JobHandle;
791
+ /** Contributions the trial runtime itself adds — the drag palette and the
792
+ * layer list, which depend on runtime state the instrument cannot reach. */
793
+ trialChrome?: readonly TrialContribution[];
794
+ /** Contributions from the lab, merged last. */
795
+ chrome?: readonly TrialContribution[];
796
+ /** Built-in contribution ids to drop. Throws on an id that is not there. */
797
+ suppress?: readonly string[];
798
+ /** The trial's resolved tool slot, and the setter that writes whichever
799
+ * slot it resolved to. `Trial` owns the resolution. */
800
+ activeToolId?: string | null;
801
+ setActiveTool?: (id: string) => void;
802
+ children: ReactNode;
793
803
  }
794
- /** A segmented control: the same choice as a select, with every option
795
- * visible at once. */
796
- declare function ToggleRow<T extends string>({ label, value, options, onChange, layout, }: ToggleRowProps<T>): react_jsx_runtime.JSX.Element;
804
+ /** The frame around a running instrument. Builds one chrome context, assembles
805
+ * the contributions the instrument, the runtime and the lab declare, and hands
806
+ * each region its slice. */
807
+ declare function TrialChrome({ trialId, record, instrument, isLastTrial, undoBindings, job, trialChrome, chrome, suppress, activeToolId, setActiveTool, children, }: TrialChromeProps): react_jsx_runtime.JSX.Element;
808
+
809
+ /** Append a new trial running `instrumentName`, at that instrument's
810
+ * default config and initial state. */
811
+ declare function addTrial(trials: TrialRecord[], instruments: InstrumentList, instrumentName: string): TrialRecord[];
812
+ /** Insert a deep copy of a trial directly after it. The copy starts with
813
+ * an empty undo history — the original's is not shared. */
814
+ declare function cloneTrial(trials: TrialRecord[], id: string): TrialRecord[];
815
+ /** Remove a trial, unless it is the last one — a lab always has at least
816
+ * one. */
817
+ declare function closeTrial(trials: TrialRecord[], id: string): TrialRecord[];
818
+ /** Return a trial to its instrument's defaults, keeping its id and its
819
+ * place in the list. */
820
+ declare function resetTrial(trials: TrialRecord[], id: string, instruments: InstrumentList): TrialRecord[];
821
+ /**
822
+ * Reorder to match `ids`. Ids the list doesn't mention keep their relative
823
+ * order at the end, and ids it names that no longer exist are dropped — a
824
+ * reorder that raced a close should not resurrect the closed trial.
825
+ */
826
+ declare function reorderTrials(trials: TrialRecord[], ids: readonly string[]): TrialRecord[];
797
827
 
798
- export { Annotations, CheckboxRow, ColorRow, ConfigField, ConfigNode, ConfigOption, ConfigRule, ConfigRuleContext, ConfigSchema, ControlRenderer, CurveField, DEFAULT_VIEW, EffectCard, EffectCardList, InferConfig, Instrument, InstrumentList, JobHandle, Lab, LabContext, LabMode, LabPalette, LabShell, LeafPatch, NodeOptions, NumberRow, PITCH_LIMIT, PropertyGroup, PropertyList, PropertyPanel, PropertyRow, ResolvedConfig, SavedSnapshot, SelectRow, SliderRow, StorageAdapter, Subpanel, TextRow, ToggleRow, Trial, TrialChrome, TrialContribution, TrialRecord, TrialTool, ViewTransform, Workspace, addTrial, applyRules, as2DView, builtinRules, clampPitch, cloneTrial, closeTrial, defineInstrument, f, fromConfigFields, interstellarTheme, isLeafVisible, orbitAfterDrag, orbitAfterWheel, reorderTrials, resetTrial, resolveConfigSchema, titleCase, useConfigSchema, useLabContext, useOrbit, validateConfigSchema, wrapYaw };
799
- export type { CheckboxRowProps, ColorRowProps, CurveFieldProps, CurveMark, EffectCardListItem, EffectCardListProps, EffectCardProps, InstrumentSpec, LabContextValue, LabPaletteProps, LabProps, LabShellProps, NumberRowProps, OrbitHandlers, OrbitView, PropertyGroupProps, PropertyListPack, PropertyListProps, PropertyPanelProps, PropertyRowLayout, PropertyRowProps, PropertyRowVariant, SelectRowProps, SliderRowProps, SubpanelProps, TextRowProps, ToggleRowProps, TrialChromeProps, TrialProps, UndoBindings, UseOrbitOptions, ValidationResult, Vec3, ViewTransform2D, WorkspaceProps };
828
+ export { Annotations, CheckboxRow, ColorRow, ConfigField, ConfigNode, ConfigOption, ConfigRule, ConfigRuleContext, ConfigSchema, ControlRenderer, CurveField, DEFAULT_VIEW, EffectCard, EffectCardList, InferConfig, Instrument, InstrumentList, JobHandle, Lab, LabContext, LabMode, LabPalette, LabShell, LeafPatch, NodeOptions, NumberRow, PITCH_LIMIT, PropertyGroup, PropertyList, PropertyPanel, PropertyRow, PropertySpan, ResolvedConfig, SavedSnapshot, SelectRow, SliderRow, StorageAdapter, Subpanel, TextRow, ToggleRow, Trial, TrialChrome, TrialContribution, TrialRecord, TrialTool, ViewTransform, Workspace, addTrial, applyRules, as2DView, builtinRules, clampPitch, cloneTrial, closeTrial, defineInstrument, f, fromConfigFields, interstellarTheme, isLeafVisible, orbitAfterDrag, orbitAfterWheel, reorderTrials, resetTrial, resolveConfigSchema, titleCase, useConfigSchema, useLabContext, useOrbit, validateConfigSchema, wrapYaw };
829
+ export type { CheckboxRowProps, ColorRowProps, CurveFieldProps, CurveMark, EffectCardListItem, EffectCardListProps, EffectCardProps, InstrumentSpec, LabContextValue, LabPaletteProps, LabProps, LabShellProps, NumberRowProps, OrbitHandlers, OrbitView, PropertyGroupProps, PropertyListPack, PropertyListProps, PropertyOption, PropertyPanelProps, PropertyRowLayout, PropertyRowProps, PropertyRowVariant, PropertySpanProps, SelectRowProps, SliderRowProps, SubpanelProps, TextRowProps, ToggleRowProps, TrialChromeProps, TrialLayout, TrialProps, UndoBindings, UseOrbitOptions, ValidationResult, Vec3, ViewTransform2D, WorkspaceProps };