@weasel-js/labkit 1.5.0 → 1.5.2

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 (206) hide show
  1. package/README.md +41 -4
  2. package/dist/_dts/{CanvasStackContext-CqkxkFJW.d.ts → CanvasStackContext-CMMo180l.d.ts} +1 -1
  3. package/dist/_dts/{PrefsForm.d-DDHFANkc.d.ts → PrefsForm.d-DPy9I8It.d.ts} +4 -0
  4. package/dist/_dts/Select.d-ZTiwzYyT.d.ts +479 -0
  5. package/dist/_dts/{frac-8R6UmlvN.d.ts → frac-B4hFJMiN.d.ts} +54 -6
  6. package/dist/_dts/{index-retnAut7.d.ts → index-8LiKe3A-.d.ts} +77 -10
  7. package/dist/_dts/{index-B8uu2ba7.d.ts → index-DlKolEIZ.d.ts} +20 -8
  8. package/dist/_dts/{types-Ca2LCnPq.d.ts → types-Db-3NNk1.d.ts} +28 -4
  9. package/dist/_dts/{usePanZoom-nS798rOF.d.ts → usePanZoom-SSTZe410.d.ts} +4 -47
  10. package/dist/_dts/{useTrialState-jcx_TdU6.d.ts → useTrialState-pnAE-UBD.d.ts} +1 -1
  11. package/dist/canvas/index.d.ts +5 -5
  12. package/dist/canvas/index.js +1 -1
  13. package/dist/chrome/index.d.ts +4 -4
  14. package/dist/chrome/index.js +7 -7
  15. package/dist/chunk-6BUQ77ZV.js +18 -0
  16. package/dist/chunk-6BUQ77ZV.js.map +1 -0
  17. package/dist/{chunk-KJALCDWE.js → chunk-753Y6HE6.js} +9 -9
  18. package/dist/chunk-753Y6HE6.js.map +1 -0
  19. package/dist/{chunk-6ZDGOZQV.js → chunk-A2ACAGW6.js} +72 -20
  20. package/dist/chunk-A2ACAGW6.js.map +1 -0
  21. package/dist/{chunk-NS64DXMN.js → chunk-CKUKF72R.js} +44 -21
  22. package/dist/chunk-CKUKF72R.js.map +1 -0
  23. package/dist/{chunk-MUKOW3TC.js → chunk-D35PFTS7.js} +4 -4
  24. package/dist/{chunk-MUKOW3TC.js.map → chunk-D35PFTS7.js.map} +1 -1
  25. package/dist/{chunk-UU3NJO6N.js → chunk-EMXAIRUJ.js} +3 -3
  26. package/dist/{chunk-UU3NJO6N.js.map → chunk-EMXAIRUJ.js.map} +1 -1
  27. package/dist/{chunk-ZPH5WTWF.js → chunk-ERFMC6WU.js} +142 -66
  28. package/dist/chunk-ERFMC6WU.js.map +1 -0
  29. package/dist/chunk-FKLT3ITC.js +590 -0
  30. package/dist/chunk-FKLT3ITC.js.map +1 -0
  31. package/dist/{chunk-QLSV2N3G.js → chunk-IJJUK4FU.js} +25 -13
  32. package/dist/chunk-IJJUK4FU.js.map +1 -0
  33. package/dist/{chunk-EKIICY6X.js → chunk-KJCUERQF.js} +37 -25
  34. package/dist/chunk-KJCUERQF.js.map +1 -0
  35. package/dist/chunk-LASCBWW7.js +13456 -0
  36. package/dist/chunk-LASCBWW7.js.map +1 -0
  37. package/dist/{chunk-67SJLMC7.js → chunk-LRI3MBGR.js} +45 -12
  38. package/dist/chunk-LRI3MBGR.js.map +1 -0
  39. package/dist/chunk-REOBGYMC.js +150 -0
  40. package/dist/chunk-REOBGYMC.js.map +1 -0
  41. package/dist/{chunk-PGETSEDK.js → chunk-TT5C5S6R.js} +11 -90
  42. package/dist/chunk-TT5C5S6R.js.map +1 -0
  43. package/dist/{chunk-NDRYLVOW.js → chunk-Z76KEZAX.js} +2 -2
  44. package/dist/chunk-Z76KEZAX.js.map +1 -0
  45. package/dist/config/index.d.ts +62 -19
  46. package/dist/config/index.js +6 -4
  47. package/dist/controls/index.d.ts +3 -3
  48. package/dist/controls/index.js +4 -4
  49. package/dist/dragdrop/index.d.ts +3 -3
  50. package/dist/index.d.ts +230 -62
  51. package/dist/index.js +1367 -1698
  52. package/dist/index.js.map +1 -1
  53. package/dist/layers/index.d.ts +4 -4
  54. package/dist/layers/index.js +2 -2
  55. package/dist/loupe/index.d.ts +67 -16
  56. package/dist/loupe/index.js +1 -1
  57. package/dist/passthrough/weasel-ui.d.ts +57 -230
  58. package/dist/passthrough/weasel-ui.js +1 -1
  59. package/dist/primitives/index.d.ts +3 -1
  60. package/dist/primitives/index.js +3 -3
  61. package/dist/state/index.d.ts +5 -5
  62. package/dist/state/index.js +5 -3
  63. package/dist/state/index.js.map +1 -1
  64. package/dist/styles.css +266 -57
  65. package/dist/surface/index.js +1 -1
  66. package/dist/ui/layers/index.js +1 -1
  67. package/dist/undo/index.d.ts +3 -3
  68. package/package.json +9 -9
  69. package/src/annotations/AnnotationOverlay.tsx +3 -0
  70. package/src/annotations/Annotations.less +4 -0
  71. package/src/annotations/Annotations.overlay.test.tsx +20 -0
  72. package/src/annotations/svgNodes.ts +1 -0
  73. package/src/annotations/toolMap.test.ts +9 -5
  74. package/src/annotations/toolMap.ts +3 -0
  75. package/src/canvas/CanvasStack.stories.tsx +1 -1
  76. package/src/canvas/index.ts +0 -9
  77. package/src/canvas/usePanZoom.test.ts +28 -0
  78. package/src/canvas/usePanZoom.ts +11 -4
  79. package/src/chrome/ChromeRegions.stories.tsx +1 -1
  80. package/src/chrome/LabChrome.tsx +21 -5
  81. package/src/chrome/builtins.test.ts +1 -0
  82. package/src/chrome/builtins.tsx +1 -0
  83. package/src/chrome/index.ts +1 -0
  84. package/src/chrome/labTypes.ts +3 -3
  85. package/src/chrome/regions/PaletteRegion.test.tsx +18 -0
  86. package/src/chrome/regions/PaletteRegion.tsx +6 -10
  87. package/src/chrome/regions/SidebarRegion.stories.tsx +44 -0
  88. package/src/chrome/regions/TitleBarRegion.tsx +1 -1
  89. package/src/chrome/regions/ToolbarRegion.tsx +11 -7
  90. package/src/chrome/types.ts +11 -2
  91. package/src/config/auto.test.ts +12 -0
  92. package/src/config/auto.ts +15 -0
  93. package/src/config/autoConfig.test.ts +107 -0
  94. package/src/config/autoConfig.ts +153 -0
  95. package/src/config/builder.test.ts +38 -0
  96. package/src/config/builder.ts +55 -11
  97. package/src/config/index.ts +3 -0
  98. package/src/config/path.ts +7 -2
  99. package/src/config/resolve.test.ts +25 -0
  100. package/src/config/resolve.ts +17 -1
  101. package/src/config/types.ts +32 -2
  102. package/src/config/useResolvedConfig.ts +26 -0
  103. package/src/controls/AutoControls.stories.tsx +88 -0
  104. package/src/controls/ControlPanel.less +23 -0
  105. package/src/controls/ControlPanel.stories.tsx +83 -1
  106. package/src/controls/ControlPanel.test.tsx +457 -4
  107. package/src/controls/ControlPanel.tsx +534 -73
  108. package/src/index.test.ts +0 -2
  109. package/src/index.ts +33 -11
  110. package/src/instrument/serializers.ts +29 -1
  111. package/src/lab/Lab.chrome.test.tsx +16 -0
  112. package/src/lab/Lab.stories.tsx +1 -1
  113. package/src/lab/Lab.surface.test.tsx +7 -2
  114. package/src/lab/Lab.test.tsx +79 -1
  115. package/src/lab/Lab.tsx +124 -16
  116. package/src/lab/LabContext.ts +8 -0
  117. package/src/lab/LabFit.stories.tsx +4 -4
  118. package/src/lab/LabFullChrome.stories.tsx +1 -1
  119. package/src/lab/LabHeader.tsx +0 -1
  120. package/src/lab/LabRoot.test.tsx +56 -0
  121. package/src/lab/LabRoot.tsx +47 -0
  122. package/src/lab/LabShell.less +24 -3
  123. package/src/lab/LabShell.stories.tsx +50 -1
  124. package/src/lab/LabShell.tsx +18 -27
  125. package/src/lab/LabSwitcher.less +10 -10
  126. package/src/lab/LabSwitcher.test.tsx +14 -9
  127. package/src/lab/LabSwitcher.tsx +8 -4
  128. package/src/lab/Workspace.less +1 -1
  129. package/src/lab/Workspace.stories.tsx +1 -1
  130. package/src/lab/Workspace.surface.test.tsx +1 -1
  131. package/src/lab/index.ts +2 -0
  132. package/src/layers/LayerList.less +1 -1
  133. package/src/layers/LayerList.stories.tsx +2 -2
  134. package/src/loupe/AGENTS.md +16 -4
  135. package/src/loupe/LoupeGestures.tsx +67 -0
  136. package/src/loupe/TrialLoupe.tsx +43 -28
  137. package/src/loupe/index.ts +4 -0
  138. package/src/loupe/loupeActions.ts +98 -0
  139. package/src/loupe/useLoupe.test.tsx +59 -2
  140. package/src/loupe/useLoupe.ts +28 -48
  141. package/src/passthrough/weasel-ui.ts +3 -3
  142. package/src/primitives/FloatingPanel.stories.tsx +1 -1
  143. package/src/primitives/FpsMeter.less +6 -1
  144. package/src/primitives/FpsMeter.stories.tsx +1 -1
  145. package/src/primitives/FpsMeter.test.tsx +12 -4
  146. package/src/primitives/FpsMeter.tsx +6 -1
  147. package/src/primitives/JobProgress.stories.tsx +2 -2
  148. package/src/primitives/Legend.stories.tsx +1 -1
  149. package/src/primitives/ScaleIndicator.stories.tsx +1 -1
  150. package/src/primitives/Sidebar.less +7 -0
  151. package/src/primitives/Sidebar.stories.tsx +1 -1
  152. package/src/primitives/Split.test.tsx +25 -0
  153. package/src/primitives/Split.tsx +36 -20
  154. package/src/primitives/StatusBar.less +6 -0
  155. package/src/primitives/StatusBar.stories.tsx +1 -1
  156. package/src/primitives/Toolbar.stories.tsx +1 -1
  157. package/src/specimen/Specimen.less +95 -0
  158. package/src/specimen/Specimen.stories.tsx +13 -0
  159. package/src/specimen/Specimen.test.tsx +13 -0
  160. package/src/specimen/Specimen.tsx +888 -0
  161. package/src/state/Persistence.stories.tsx +4 -4
  162. package/src/state/store.test.ts +65 -0
  163. package/src/state/store.ts +32 -8
  164. package/src/state/types.ts +31 -2
  165. package/src/state/useTrialState.test.tsx +85 -0
  166. package/src/state/useTrialState.ts +9 -1
  167. package/src/state/view.test.ts +4 -4
  168. package/src/styles.less +1 -0
  169. package/src/surface/index.ts +1 -1
  170. package/src/surface/useSurfaceTile.test.tsx +1 -1
  171. package/src/surface/useTiledSurface.test.tsx +65 -10
  172. package/src/surface/useTiledSurface.ts +23 -11
  173. package/src/theme/Interstellar.stories.tsx +2 -2
  174. package/src/theme/interstellar.test.ts +16 -5
  175. package/src/theme/interstellar.theme.json +180 -0
  176. package/src/theme/interstellar.ts +8 -5
  177. package/src/tools/labTool.ts +3 -3
  178. package/src/trial/Trial.annotations.test.tsx +13 -4
  179. package/src/trial/Trial.canvas.test.tsx +36 -0
  180. package/src/trial/Trial.config.test.tsx +75 -2
  181. package/src/trial/Trial.less +4 -0
  182. package/src/trial/Trial.stories.tsx +4 -1
  183. package/src/trial/Trial.test.tsx +3 -0
  184. package/src/trial/Trial.tsx +21 -14
  185. package/src/trial/TrialChrome.tsx +17 -3
  186. package/src/trial/trialOps.test.ts +101 -1
  187. package/src/trial/trialOps.ts +62 -4
  188. package/dist/_dts/ToggleBar.d-DbHoWKIA.d.ts +0 -116
  189. package/dist/chunk-67SJLMC7.js.map +0 -1
  190. package/dist/chunk-6ZDGOZQV.js.map +0 -1
  191. package/dist/chunk-E44SU6XS.js +0 -50
  192. package/dist/chunk-E44SU6XS.js.map +0 -1
  193. package/dist/chunk-EKIICY6X.js.map +0 -1
  194. package/dist/chunk-KJALCDWE.js.map +0 -1
  195. package/dist/chunk-NDRYLVOW.js.map +0 -1
  196. package/dist/chunk-NS64DXMN.js.map +0 -1
  197. package/dist/chunk-PGETSEDK.js.map +0 -1
  198. package/dist/chunk-QLSV2N3G.js.map +0 -1
  199. package/dist/chunk-S2SHZRD7.js +0 -7681
  200. package/dist/chunk-S2SHZRD7.js.map +0 -1
  201. package/dist/chunk-TQBBYTAF.js +0 -280
  202. package/dist/chunk-TQBBYTAF.js.map +0 -1
  203. package/dist/chunk-ZPH5WTWF.js.map +0 -1
  204. package/src/canvas/useOrbit.test.ts +0 -167
  205. package/src/canvas/useOrbit.ts +0 -156
  206. package/src/theme/interstellar.tokens.json +0 -61
@@ -1,156 +0,0 @@
1
- import { openPointerSession, type PointerSession } from '@weasel-js/core';
2
- import {
3
- type PointerEvent as ReactPointerEvent,
4
- useCallback,
5
- useEffect,
6
- useRef,
7
- type WheelEvent,
8
- } from 'react';
9
-
10
- /** A point in the space the instrument works in. */
11
- export interface Vec3 {
12
- x: number;
13
- y: number;
14
- z: number;
15
- }
16
-
17
- /** An orbit camera as a trial view: where it looks from, and what it looks at.
18
- * labkit does not turn this into a matrix — the host's renderer does. */
19
- export interface OrbitView {
20
- yaw: number;
21
- pitch: number;
22
- distance: number;
23
- target: Vec3;
24
- }
25
-
26
- /** Just short of the pole. At exactly ±PI/2 the azimuth is undefined and the
27
- * camera rolls, which reads as the model jumping rather than as a limit. */
28
- export const PITCH_LIMIT = Math.PI / 2 - 0.01;
29
-
30
- const YAW_PER_PX = 0.008;
31
- const PITCH_PER_PX = 0.008;
32
- const DISTANCE_PER_NOTCH = 0.0015;
33
- const DRAG_THRESHOLD = 3;
34
-
35
- export function clampPitch(pitch: number): number {
36
- return Math.min(PITCH_LIMIT, Math.max(-PITCH_LIMIT, pitch));
37
- }
38
-
39
- export function wrapYaw(yaw: number): number {
40
- const wrapped = ((((yaw + Math.PI) % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI)) - Math.PI;
41
- return wrapped === -Math.PI ? Math.PI : wrapped;
42
- }
43
-
44
- /** The view a drag of (dx, dy) from `start` produces. Absolute against the drag
45
- * start, so it can be re-applied any number of times without compounding. */
46
- export function orbitAfterDrag(start: OrbitView, dx: number, dy: number): OrbitView {
47
- return {
48
- ...start,
49
- yaw: wrapYaw(start.yaw + dx * YAW_PER_PX),
50
- pitch: clampPitch(start.pitch + dy * PITCH_PER_PX),
51
- };
52
- }
53
-
54
- /** Multiplicative, so one notch covers the same proportion of the distance
55
- * whether the camera is near or far. */
56
- export function orbitAfterWheel(
57
- view: OrbitView,
58
- deltaY: number,
59
- minDistance: number,
60
- maxDistance: number,
61
- ): OrbitView {
62
- const factor = Math.exp(deltaY * DISTANCE_PER_NOTCH);
63
- return {
64
- ...view,
65
- distance: Math.min(maxDistance, Math.max(minDistance, view.distance * factor)),
66
- };
67
- }
68
-
69
- export interface UseOrbitOptions {
70
- view: OrbitView;
71
- onViewChange: (v: OrbitView) => void;
72
- /** Restored on double-click. Defaults to the view the hook first saw. */
73
- home?: OrbitView;
74
- minDistance?: number;
75
- maxDistance?: number;
76
- }
77
-
78
- export interface OrbitHandlers {
79
- onWheel: (e: WheelEvent<HTMLElement>) => void;
80
- onPointerDown: (e: ReactPointerEvent<HTMLElement>) => void;
81
- onDoubleClick: () => void;
82
- isDragging: () => boolean;
83
- }
84
-
85
- interface DragState {
86
- startX: number;
87
- startY: number;
88
- startView: OrbitView;
89
- moved: boolean;
90
- }
91
-
92
- /** Pointer gestures over an orbit view: drag to turn, wheel or pinch to dolly,
93
- * double-click to go home. The 3D peer of `usePanZoom`. */
94
- export function useOrbit({
95
- view,
96
- onViewChange,
97
- home,
98
- minDistance = 0.1,
99
- maxDistance = 1000,
100
- }: UseOrbitOptions): OrbitHandlers {
101
- const dragRef = useRef<DragState | null>(null);
102
- const sessionRef = useRef<PointerSession | null>(null);
103
- const viewRef = useRef(view);
104
- viewRef.current = view;
105
- const onViewChangeRef = useRef(onViewChange);
106
- onViewChangeRef.current = onViewChange;
107
- const homeRef = useRef(home ?? view);
108
- if (home) homeRef.current = home;
109
-
110
- const onWheel = useCallback(
111
- (e: WheelEvent<HTMLElement>) => {
112
- e.preventDefault();
113
- onViewChange(orbitAfterWheel(viewRef.current, e.deltaY, minDistance, maxDistance));
114
- },
115
- [onViewChange, minDistance, maxDistance],
116
- );
117
-
118
- const clearDrag = useCallback(() => {
119
- dragRef.current = null;
120
- sessionRef.current = null;
121
- }, []);
122
-
123
- const onPointerDown = useCallback(
124
- (e: ReactPointerEvent<HTMLElement>) => {
125
- if (e.button !== 0) return;
126
- const drag: DragState = {
127
- startX: e.clientX,
128
- startY: e.clientY,
129
- startView: viewRef.current,
130
- moved: false,
131
- };
132
- dragRef.current = drag;
133
- sessionRef.current = openPointerSession(e.currentTarget, e, {
134
- onMove: (ev) => {
135
- const dx = ev.clientX - drag.startX;
136
- const dy = ev.clientY - drag.startY;
137
- if (!drag.moved && Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
138
- drag.moved = true;
139
- onViewChangeRef.current(orbitAfterDrag(drag.startView, dx, dy));
140
- },
141
- onEnd: clearDrag,
142
- // A cancelled turn keeps where it got to: every move was committed as
143
- // it arrived, so there is nothing left to undo.
144
- onCancel: clearDrag,
145
- });
146
- },
147
- [clearDrag],
148
- );
149
-
150
- useEffect(() => () => sessionRef.current?.cancel(), []);
151
-
152
- const onDoubleClick = useCallback(() => onViewChange(homeRef.current), [onViewChange]);
153
- const isDragging = useCallback(() => dragRef.current?.moved === true, []);
154
-
155
- return { onWheel, onPointerDown, onDoubleClick, isDragging };
156
- }
@@ -1,61 +0,0 @@
1
- {
2
- "name": "interstellar",
3
- "defaultMode": "dark",
4
- "primitives": {
5
- "dimension": {
6
- "$type": "dimension",
7
- "radius-md": { "$value": "6px" },
8
- "glass-blur": { "$value": "12px" }
9
- },
10
- "fontWeight": {
11
- "$type": "fontWeight",
12
- "font-weight-light": { "$value": 300 },
13
- "font-weight-medium": { "$value": 500 },
14
- "font-weight-bold": { "$value": 700 }
15
- }
16
- },
17
- "modes": {
18
- "dark": {
19
- "color": {
20
- "$type": "color",
21
- "surface": { "$value": "#0a0a14" },
22
- "surface-raised": { "$value": "rgba(20, 20, 36, 0.55)" },
23
- "surface-sunken": { "$value": "#02020a" },
24
- "border": { "$value": "rgba(255, 255, 255, 0.14)" },
25
- "line-subtle": { "$value": "rgba(255, 255, 255, 0.08)" },
26
- "fg": { "$value": "#e8e8f0" },
27
- "fg-muted": { "$value": "#a8a8c0" },
28
- "fg-subtle": { "$value": "#5a5a78" },
29
- "accent": { "$value": "#b08adb" },
30
- "accent-hover": { "$value": "#c6a3ee" },
31
- "focus-ring": { "$value": "rgba(176, 138, 219, 0.45)" },
32
- "shadow": { "$value": "rgba(0, 0, 0, 0.7)" },
33
- "border-strong": { "$value": "rgba(255, 255, 255, 0.36)" }
34
- },
35
- "gradient": {
36
- "$type": "gradient",
37
- "backdrop": {
38
- "$value": "radial-gradient(ellipse 60% 80% at 18% 30%, rgba(150, 80, 200, 0.22), transparent 70%), radial-gradient(ellipse 55% 90% at 78% 70%, rgba(220, 100, 140, 0.18), transparent 65%), radial-gradient(ellipse 50% 70% at 50% 50%, rgba(60, 110, 200, 0.18), transparent 75%), radial-gradient(ellipse at center, #0a0a18 0%, #02020a 100%)"
39
- }
40
- }
41
- },
42
- "light": {
43
- "color": {
44
- "$type": "color",
45
- "surface": { "$value": "#fafaf7" },
46
- "surface-raised": { "$value": "#ffffff" },
47
- "surface-sunken": { "$value": "#f0ebe2" },
48
- "border": { "$value": "#c9bba5" },
49
- "line-subtle": { "$value": "rgba(0, 0, 0, 0.08)" },
50
- "fg": { "$value": "#2a2018" },
51
- "fg-muted": { "$value": "#6b5c4a" },
52
- "fg-subtle": { "$value": "#a89b85" },
53
- "accent": { "$value": "#a86f3c" },
54
- "accent-hover": { "$value": "#c2854f" },
55
- "focus-ring": { "$value": "rgba(168, 111, 60, 0.35)" },
56
- "shadow": { "$value": "rgba(80, 60, 40, 0.18)" },
57
- "border-strong": { "$value": "#9e8b71" }
58
- }
59
- }
60
- }
61
- }