@weasel-js/labkit 1.4.3 → 1.5.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 (229) hide show
  1. package/README.md +13 -2
  2. package/dist/_dts/{CanvasStackContext-Dde8_1my.d.ts → CanvasStackContext-CqkxkFJW.d.ts} +1 -1
  3. package/dist/_dts/ToggleBar.d-DbHoWKIA.d.ts +116 -0
  4. package/dist/_dts/{frac-B5mB8LsJ.d.ts → frac-8R6UmlvN.d.ts} +256 -33
  5. package/dist/_dts/index-B8uu2ba7.d.ts +237 -0
  6. package/dist/_dts/{index-DelFfeV0.d.ts → index-retnAut7.d.ts} +45 -12
  7. package/dist/_dts/{types-B9_zrHmb.d.ts → types-Ca2LCnPq.d.ts} +65 -2
  8. package/dist/_dts/usePanZoom-nS798rOF.d.ts +160 -0
  9. package/dist/_dts/useTrialState-jcx_TdU6.d.ts +212 -0
  10. package/dist/canvas/index.d.ts +17 -128
  11. package/dist/canvas/index.js +4 -2
  12. package/dist/chrome/index.d.ts +4 -92
  13. package/dist/chrome/index.js +9 -5
  14. package/dist/chunk-67SJLMC7.js +704 -0
  15. package/dist/chunk-67SJLMC7.js.map +1 -0
  16. package/dist/chunk-6ZDGOZQV.js +310 -0
  17. package/dist/chunk-6ZDGOZQV.js.map +1 -0
  18. package/dist/{chunk-QAGAHJKZ.js → chunk-EKIICY6X.js} +111 -25
  19. package/dist/chunk-EKIICY6X.js.map +1 -0
  20. package/dist/{chunk-CTRKTLYZ.js → chunk-H6ZAOWNE.js} +11 -11
  21. package/dist/chunk-H6ZAOWNE.js.map +1 -0
  22. package/dist/{chunk-2RQPGOQF.js → chunk-KJALCDWE.js} +9 -7
  23. package/dist/chunk-KJALCDWE.js.map +1 -0
  24. package/dist/{chunk-ISCOFAUO.js → chunk-MUKOW3TC.js} +3 -3
  25. package/dist/{chunk-ISCOFAUO.js.map → chunk-MUKOW3TC.js.map} +1 -1
  26. package/dist/chunk-NDRYLVOW.js +15 -0
  27. package/dist/chunk-NDRYLVOW.js.map +1 -0
  28. package/dist/{chunk-C42T6DJT.js → chunk-NS64DXMN.js} +226 -159
  29. package/dist/chunk-NS64DXMN.js.map +1 -0
  30. package/dist/{chunk-I6JCVE24.js → chunk-PGETSEDK.js} +135 -13
  31. package/dist/chunk-PGETSEDK.js.map +1 -0
  32. package/dist/{chunk-FQMJUVHJ.js → chunk-QLSV2N3G.js} +32 -37
  33. package/dist/chunk-QLSV2N3G.js.map +1 -0
  34. package/dist/chunk-RWNDDKOH.js +682 -0
  35. package/dist/chunk-RWNDDKOH.js.map +1 -0
  36. package/dist/chunk-S2SHZRD7.js +7681 -0
  37. package/dist/chunk-S2SHZRD7.js.map +1 -0
  38. package/dist/{chunk-ASWKLRKJ.js → chunk-TQBBYTAF.js} +19 -82
  39. package/dist/chunk-TQBBYTAF.js.map +1 -0
  40. package/dist/chunk-UU3NJO6N.js +72 -0
  41. package/dist/chunk-UU3NJO6N.js.map +1 -0
  42. package/dist/chunk-WIG6XHJ7.js +35 -0
  43. package/dist/chunk-WIG6XHJ7.js.map +1 -0
  44. package/dist/{chunk-TJ7QY3OC.js → chunk-ZPH5WTWF.js} +21 -15
  45. package/dist/chunk-ZPH5WTWF.js.map +1 -0
  46. package/dist/config/index.d.ts +232 -0
  47. package/dist/config/index.js +6 -0
  48. package/dist/config/index.js.map +1 -0
  49. package/dist/controls/index.d.ts +2 -3
  50. package/dist/controls/index.js +3 -2
  51. package/dist/dragdrop/index.d.ts +2 -4
  52. package/dist/index.d.ts +123 -348
  53. package/dist/index.js +794 -837
  54. package/dist/index.js.map +1 -1
  55. package/dist/layers/index.d.ts +3 -5
  56. package/dist/layers/index.js +2 -2
  57. package/dist/loupe/index.d.ts +6 -8
  58. package/dist/loupe/index.js +2 -2
  59. package/dist/passthrough/weasel-ui.d.ts +169 -117
  60. package/dist/passthrough/weasel-ui.js +1 -1
  61. package/dist/primitives/index.d.ts +53 -6
  62. package/dist/primitives/index.js +6 -4
  63. package/dist/state/index.d.ts +12 -7
  64. package/dist/state/index.js +16 -13
  65. package/dist/state/index.js.map +1 -1
  66. package/dist/styles.css +163 -62
  67. package/dist/surface/index.d.ts +44 -7
  68. package/dist/surface/index.js +2 -1
  69. package/dist/ui/layers/index.js +1 -1
  70. package/dist/undo/index.d.ts +2 -4
  71. package/package.json +15 -8
  72. package/src/annotations/AnnotationOverlay.tsx +53 -5
  73. package/src/annotations/Annotations.overlay.test.tsx +85 -6
  74. package/src/annotations/drawOne.test.ts +1 -1
  75. package/src/annotations/drawOne.ts +2 -2
  76. package/src/annotations/frac.test.ts +4 -4
  77. package/src/annotations/frac.ts +3 -2
  78. package/src/annotations/index.ts +1 -1
  79. package/src/annotations/paint.test.ts +2 -2
  80. package/src/annotations/paint.ts +1 -1
  81. package/src/annotations/preload.ts +6 -0
  82. package/src/annotations/store.test.ts +18 -0
  83. package/src/annotations/store.ts +7 -6
  84. package/src/annotations/svgNodes.test.ts +2 -2
  85. package/src/annotations/svgNodes.ts +1 -2
  86. package/src/annotations/toolMap.ts +3 -3
  87. package/src/annotations/types.ts +6 -3
  88. package/src/canvas/CameraWheelContext.ts +12 -0
  89. package/src/canvas/CanvasStack.test.tsx +25 -0
  90. package/src/canvas/CanvasStack.tsx +31 -4
  91. package/src/canvas/Stage.less +18 -0
  92. package/src/canvas/Stage.test.tsx +186 -0
  93. package/src/canvas/Stage.tsx +134 -0
  94. package/src/canvas/camera.test.ts +17 -2
  95. package/src/canvas/camera.ts +9 -9
  96. package/src/canvas/index.ts +4 -0
  97. package/src/canvas/usePanZoom.ts +10 -5
  98. package/src/chrome/ChromeRegions.stories.tsx +0 -3
  99. package/src/chrome/LabChrome.tsx +114 -0
  100. package/src/chrome/builtins.tsx +20 -31
  101. package/src/chrome/index.ts +15 -0
  102. package/src/chrome/labRegions.test.tsx +208 -0
  103. package/src/chrome/labTypes.ts +50 -0
  104. package/src/chrome/merge.ts +7 -9
  105. package/src/chrome/regions/PaletteRegion.test.tsx +6 -4
  106. package/src/chrome/regions/PaletteRegion.tsx +21 -9
  107. package/src/chrome/regions/SidebarRegion.tsx +25 -13
  108. package/src/chrome/regions/StatusRegion.tsx +15 -8
  109. package/src/chrome/regions/ToolbarRegion.tsx +30 -16
  110. package/src/chrome/types.ts +47 -20
  111. package/src/config/builder.test.ts +4 -0
  112. package/src/config/builder.ts +16 -10
  113. package/src/config/declarationEmit.fixture.ts +11 -0
  114. package/src/config/declarationEmit.test.ts +51 -0
  115. package/src/config/entry.test.ts +46 -0
  116. package/src/config/index.ts +13 -1
  117. package/src/config/nodeClasses.test.ts +18 -0
  118. package/src/config/types.ts +3 -1
  119. package/src/controls/ControlPanel.test.tsx +16 -0
  120. package/src/controls/ControlPanel.tsx +5 -2
  121. package/src/fake-indexeddb-auto.d.ts +5 -0
  122. package/src/index.test.ts +7 -0
  123. package/src/index.ts +39 -6
  124. package/src/instrument/serializers.test.ts +22 -0
  125. package/src/instrument/serializers.ts +11 -0
  126. package/src/instrument/types.ts +25 -1
  127. package/src/lab/Lab.less +4 -13
  128. package/src/lab/Lab.persist.test.tsx +147 -0
  129. package/src/lab/Lab.stories.tsx +0 -2
  130. package/src/lab/Lab.surface.test.tsx +66 -3
  131. package/src/lab/Lab.test.tsx +91 -17
  132. package/src/lab/Lab.tsx +337 -124
  133. package/src/lab/LabFit.stories.less +18 -0
  134. package/src/lab/LabFit.stories.tsx +219 -0
  135. package/src/lab/LabFullChrome.stories.tsx +0 -3
  136. package/src/lab/LabHeader.test.tsx +40 -9
  137. package/src/lab/LabHeader.tsx +7 -13
  138. package/src/lab/LabPalette.tsx +13 -26
  139. package/src/lab/LabShell.less +49 -12
  140. package/src/lab/LabShell.tsx +14 -2
  141. package/src/lab/LabSwitcher.less +92 -0
  142. package/src/lab/LabSwitcher.test.tsx +96 -0
  143. package/src/lab/LabSwitcher.tsx +112 -0
  144. package/src/lab/Workspace.surface.test.tsx +2 -1
  145. package/src/lab/fitCheck.test.ts +57 -0
  146. package/src/lab/fitCheck.ts +125 -0
  147. package/src/lab/index.ts +2 -0
  148. package/src/loupe/AGENTS.md +1 -1
  149. package/src/loupe/Loupe.less +1 -1
  150. package/src/loupe/canvasLens.ts +1 -1
  151. package/src/loupe/types.ts +1 -1
  152. package/src/loupe/useLoupe.test.tsx +1 -1
  153. package/src/loupe/useLoupe.ts +1 -1
  154. package/src/passthrough/weasel-ui.ts +9 -0
  155. package/src/primitives/FloatingPanel.stories.tsx +13 -1
  156. package/src/primitives/FloatingPanel.test.tsx +47 -16
  157. package/src/primitives/FloatingPanel.tsx +11 -25
  158. package/src/primitives/Split.less +14 -0
  159. package/src/primitives/Split.test.tsx +108 -0
  160. package/src/primitives/Split.tsx +159 -0
  161. package/src/primitives/ZoomControl.tsx +5 -2
  162. package/src/primitives/index.ts +2 -0
  163. package/src/state/Persistence.stories.tsx +75 -0
  164. package/src/state/Persistence.tsx +33 -0
  165. package/src/state/SingletonExperiment.test.tsx +47 -53
  166. package/src/state/SingletonExperiment.tsx +24 -13
  167. package/src/state/adapterContract.ts +116 -0
  168. package/src/state/adapters.test.ts +113 -61
  169. package/src/state/adapters.ts +328 -69
  170. package/src/state/document.test.ts +71 -96
  171. package/src/state/document.ts +66 -52
  172. package/src/state/helpers.test.ts +20 -0
  173. package/src/state/helpers.ts +16 -0
  174. package/src/state/index.ts +8 -0
  175. package/src/state/labRecords.test.ts +105 -0
  176. package/src/state/labRecords.ts +160 -0
  177. package/src/state/openLabStore.test.ts +658 -0
  178. package/src/state/openLabStore.ts +403 -0
  179. package/src/state/records.test.ts +234 -0
  180. package/src/state/records.ts +219 -0
  181. package/src/state/store.test.ts +104 -635
  182. package/src/state/store.ts +117 -158
  183. package/src/state/toolSlot.test.ts +1 -1
  184. package/src/state/types.ts +39 -15
  185. package/src/state/useOpenOnce.ts +68 -0
  186. package/src/state/usePersistedState.test.tsx +125 -0
  187. package/src/state/usePersistedState.ts +66 -0
  188. package/src/state/useTrialState.test.tsx +2 -3
  189. package/src/state/view.test.ts +49 -15
  190. package/src/state/view.ts +18 -1
  191. package/src/styles.less +3 -0
  192. package/src/surface/AGENTS.md +39 -7
  193. package/src/surface/SurfaceContext.ts +26 -3
  194. package/src/surface/index.ts +2 -0
  195. package/src/surface/useSurfaceTile.test.tsx +2 -1
  196. package/src/surface/useSurfaceTile.ts +6 -5
  197. package/src/surface/useTiledSurface.test.tsx +175 -0
  198. package/src/surface/useTiledSurface.ts +54 -5
  199. package/src/theme/Interstellar.stories.tsx +7 -7
  200. package/src/theme/base.less +4 -4
  201. package/src/theme/interstellar.test.ts +1 -1
  202. package/src/theme/interstellar.tokens.json +2 -2
  203. package/src/tools/labTool.ts +11 -0
  204. package/src/trial/Trial.annotations.persist.test.tsx +100 -58
  205. package/src/trial/Trial.annotations.test.tsx +47 -4
  206. package/src/trial/Trial.job.test.tsx +3 -3
  207. package/src/trial/Trial.less +1 -26
  208. package/src/trial/Trial.stories.tsx +1 -2
  209. package/src/trial/Trial.test.tsx +28 -4
  210. package/src/trial/Trial.trialId.test.tsx +23 -1
  211. package/src/trial/Trial.tsx +118 -38
  212. package/src/trial/TrialBody.tsx +17 -141
  213. package/src/trial/TrialChrome.tsx +7 -4
  214. package/src/trial/trialOps.ts +7 -4
  215. package/dist/_dts/types-BP2OCcpg.d.ts +0 -155
  216. package/dist/_dts/types-x92Kfeme.d.ts +0 -62
  217. package/dist/_dts/useTrialState-D6Vb3T-g.d.ts +0 -99
  218. package/dist/chunk-2RQPGOQF.js.map +0 -1
  219. package/dist/chunk-5TROQVQ2.js +0 -547
  220. package/dist/chunk-5TROQVQ2.js.map +0 -1
  221. package/dist/chunk-ASWKLRKJ.js.map +0 -1
  222. package/dist/chunk-C42T6DJT.js.map +0 -1
  223. package/dist/chunk-CTRKTLYZ.js.map +0 -1
  224. package/dist/chunk-FQMJUVHJ.js.map +0 -1
  225. package/dist/chunk-I6JCVE24.js.map +0 -1
  226. package/dist/chunk-MHAGC6VD.js +0 -7320
  227. package/dist/chunk-MHAGC6VD.js.map +0 -1
  228. package/dist/chunk-QAGAHJKZ.js.map +0 -1
  229. package/dist/chunk-TJ7QY3OC.js.map +0 -1
@@ -1,8 +1,12 @@
1
- import { Toolbar, ZoomControl, ScaleIndicator, FpsMeter, useRovingTabIndex, StatusBar } from './chunk-2RQPGOQF.js';
2
- import { ControlPanel } from './chunk-ASWKLRKJ.js';
3
- import { p, u, c, n, f, r2, h, b, g3, u2, A, j, U, M, x, N, g, _, v, P, y, n6, o3 } from './chunk-MHAGC6VD.js';
4
- import { createContext, useContext, useState, useId, useRef, useSyncExternalStore, useCallback } from 'react';
1
+ import { Toolbar, ZoomControl, ScaleIndicator, FpsMeter, StatusBar, useRovingTabIndex } from './chunk-KJALCDWE.js';
2
+ import { usePersistedState } from './chunk-RWNDDKOH.js';
3
+ import { ControlPanel } from './chunk-TQBBYTAF.js';
4
+ import { useLabContext } from './chunk-NDRYLVOW.js';
5
+ import { LabStoreContext } from './chunk-2YILQ7Y5.js';
6
+ import { b, g3, u2, A, j, U, M, x, N, l5, _, v, P, y, n6, o3 } from './chunk-S2SHZRD7.js';
7
+ import { createContext, useContext, useState, useId, useMemo, useRef, useSyncExternalStore, useCallback } from 'react';
5
8
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
9
+ import { useStore } from 'zustand/react';
6
10
 
7
11
  var AnnotationsContext = createContext(null);
8
12
  function useMarkVersion(api) {
@@ -121,18 +125,18 @@ function ExportMenu() {
121
125
  ] }),
122
126
  /* @__PURE__ */ jsxs("div", { className: "lk-export__row", children: [
123
127
  /* @__PURE__ */ jsx("span", { children: "Format" }),
124
- /* @__PURE__ */ jsx("span", { className: "lk-export__choices", role: "radiogroup", "aria-label": "Format", children: FORMATS.map((f2) => /* @__PURE__ */ jsxs("label", { children: [
128
+ /* @__PURE__ */ jsx("span", { className: "lk-export__choices", role: "radiogroup", "aria-label": "Format", children: FORMATS.map((f) => /* @__PURE__ */ jsxs("label", { children: [
125
129
  /* @__PURE__ */ jsx(
126
130
  "input",
127
131
  {
128
132
  type: "radio",
129
133
  name: "lk-export-format",
130
- checked: format === f2.id,
131
- onChange: () => setFormat(f2.id)
134
+ checked: format === f.id,
135
+ onChange: () => setFormat(f.id)
132
136
  }
133
137
  ),
134
- f2.label
135
- ] }, f2.id)) })
138
+ f.label
139
+ ] }, f.id)) })
136
140
  ] }),
137
141
  /* @__PURE__ */ jsxs("div", { className: "lk-export__row", children: [
138
142
  /* @__PURE__ */ jsx("span", { children: "Scale" }),
@@ -215,32 +219,6 @@ function MarkList({ meaning, config }) {
215
219
  ] }, a.id);
216
220
  }) });
217
221
  }
218
-
219
- // src/annotations/toolMap.ts
220
- var TOOLS = {
221
- select: { weaselTool: "select" },
222
- stroke: { weaselTool: "pencil", kind: "stroke" },
223
- line: { weaselTool: "line", kind: "line" },
224
- arrow: { weaselTool: "line", kind: "arrow" },
225
- rect: { weaselTool: "rect", kind: "rect" },
226
- ellipse: { weaselTool: "ellipse", kind: "ellipse" },
227
- text: { weaselTool: "text", kind: "text" }
228
- };
229
- var ANNOTATION_TOOLS = [
230
- { id: "select", label: "Select", icon: p, group: "annotate" },
231
- { id: "stroke", label: "Freehand", icon: u, group: "annotate" },
232
- { id: "line", label: "Line", icon: c, group: "annotate" },
233
- { id: "arrow", label: "Arrow", icon: n, group: "annotate" },
234
- { id: "rect", label: "Rectangle", icon: f, group: "annotate" },
235
- { id: "ellipse", label: "Ellipse", icon: r2, group: "annotate" },
236
- { id: "text", label: "Text", icon: h, group: "annotate" }
237
- ];
238
- function annotationToolInfo(id) {
239
- return id === null ? void 0 : TOOLS[id];
240
- }
241
- var ANNOTATION_WEASEL_TOOLS = [
242
- ...new Set(Object.values(TOOLS).map((t) => t.weaselTool))
243
- ];
244
222
  var ZOOM_STEP = 1.25;
245
223
  function groupFolds(collapsedSections, id) {
246
224
  const prefix = `${id}/`;
@@ -279,11 +257,7 @@ function builtinContributions(instrument, ctx, controls) {
279
257
  }
280
258
  });
281
259
  }
282
- const tools = [
283
- ...instrument.annotations ? ANNOTATION_TOOLS : [],
284
- ...instrument.tools?.tools ?? []
285
- ];
286
- for (const t of tools) {
260
+ for (const t of instrument.tools?.tools ?? []) {
287
261
  out.push({
288
262
  id: t.id,
289
263
  region: "palette",
@@ -304,7 +278,7 @@ function builtinContributions(instrument, ctx, controls) {
304
278
  }
305
279
  });
306
280
  }
307
- if (instrument.canvas != null && zoom !== null) {
281
+ if ((instrument.canvas != null || instrument.stage != null) && zoom !== null) {
308
282
  out.push({
309
283
  id: "zoom-out",
310
284
  region: "viewport",
@@ -335,21 +309,23 @@ function builtinContributions(instrument, ctx, controls) {
335
309
  id: "zoom-control",
336
310
  region: "viewport",
337
311
  group: "zoom",
338
- render: (c2) => /* @__PURE__ */ jsx(ZoomControl, { zoom: c2.zoom ?? 1, onZoomChange: c2.setZoom })
312
+ render: (c) => /* @__PURE__ */ jsx(ZoomControl, { zoom: c.zoom ?? 1, onZoomChange: c.setZoom })
339
313
  });
340
314
  out.push({
341
315
  id: "scale",
342
316
  region: "status",
343
317
  group: "view",
344
- render: () => /* @__PURE__ */ jsx(ScaleIndicator, {})
345
- });
346
- out.push({
347
- id: "fps",
348
- region: "status",
349
- group: "view",
350
- end: true,
351
- render: () => /* @__PURE__ */ jsx(FpsMeter, {})
318
+ render: (c) => /* @__PURE__ */ jsx(ScaleIndicator, { zoom: c.zoom ?? 1 })
352
319
  });
320
+ if (instrument.canvas != null) {
321
+ out.push({
322
+ id: "fps",
323
+ region: "status",
324
+ group: "view",
325
+ end: true,
326
+ render: () => /* @__PURE__ */ jsx(FpsMeter, {})
327
+ });
328
+ }
353
329
  }
354
330
  if (instrument.annotations != null) {
355
331
  out.push({
@@ -394,17 +370,13 @@ function builtinContributions(instrument, ctx, controls) {
394
370
  region: "toolbar",
395
371
  group: "trial",
396
372
  end: true,
397
- render: (c2) => /* @__PURE__ */ jsx(
398
- g,
373
+ render: (c) => /* @__PURE__ */ jsx(
374
+ l5,
399
375
  {
400
- className: "lk-toolbar__load-select",
401
376
  "aria-label": "Load snapshot",
402
- placeholder: "Load\u2026",
403
- selectedKey: null,
404
- options: c2.savedSnapshots.map((sn) => ({ value: sn.id, label: sn.name })),
405
- onSelectionChange: (id) => {
406
- if (id != null) c2.loadSnapshot(String(id));
407
- }
377
+ label: "Load\u2026",
378
+ items: c.savedSnapshots.map((sn) => ({ value: sn.id, label: sn.name })),
379
+ onAction: (id) => c.loadSnapshot(id)
408
380
  }
409
381
  )
410
382
  });
@@ -447,6 +419,12 @@ function builtinContributions(instrument, ctx, controls) {
447
419
  return out;
448
420
  }
449
421
 
422
+ // src/tools/labTool.ts
423
+ function resolveLabTool(slot, instruments) {
424
+ if (slot !== null) return slot;
425
+ return instruments.some((i) => i.annotations != null) ? "select" : null;
426
+ }
427
+
450
428
  // src/chrome/merge.ts
451
429
  function mergeContributions(...bundles) {
452
430
  const out = [];
@@ -465,7 +443,7 @@ function mergeContributions(...bundles) {
465
443
  return out;
466
444
  }
467
445
  function suppressContributions(bundle, ids) {
468
- const present = new Set(bundle.map((c2) => c2.id));
446
+ const present = new Set(bundle.map((c) => c.id));
469
447
  for (const id of ids) {
470
448
  if (!present.has(id)) {
471
449
  throw new Error(
@@ -474,39 +452,7 @@ function suppressContributions(bundle, ids) {
474
452
  }
475
453
  }
476
454
  const drop = new Set(ids);
477
- return bundle.filter((c2) => !drop.has(c2.id));
478
- }
479
- function PaletteRegion({ contributions, ctx }) {
480
- const { ref, onKeyDown } = useRovingTabIndex("vertical");
481
- if (contributions.length === 0) return null;
482
- return /* @__PURE__ */ jsx(
483
- "div",
484
- {
485
- ref,
486
- className: "lk-palette-region",
487
- role: "toolbar",
488
- "aria-label": "Tools",
489
- "aria-orientation": "vertical",
490
- onKeyDown,
491
- children: /* @__PURE__ */ jsx(n6, { orientation: "vertical", children: contributions.map((c2) => {
492
- if (c2.render) return /* @__PURE__ */ jsx("span", { children: c2.render(ctx) }, c2.id);
493
- if (c2.region !== "palette" || !c2.item) return null;
494
- const { icon: Icon, label, shortcut, disabled } = c2.item;
495
- return /* @__PURE__ */ jsx(
496
- o3,
497
- {
498
- icon: /* @__PURE__ */ jsx(Icon, { size: 16 }),
499
- label,
500
- shortcut,
501
- active: ctx.activeToolId === c2.id,
502
- disabled,
503
- onClick: () => ctx.setActiveTool(c2.id)
504
- },
505
- c2.id
506
- );
507
- }) })
508
- }
509
- );
455
+ return bundle.filter((c) => !drop.has(c.id));
510
456
  }
511
457
  function Section({
512
458
  title,
@@ -542,83 +488,66 @@ function Section({
542
488
  collapsed ? null : /* @__PURE__ */ jsx("div", { className: "lk-sidebar-section__body", children })
543
489
  ] });
544
490
  }
545
- function SidebarRegion({ contributions, ctx }) {
491
+ function SidebarRegion({
492
+ contributions,
493
+ ctx,
494
+ region = "sidebar"
495
+ }) {
546
496
  if (contributions.length === 0) return null;
547
- return /* @__PURE__ */ jsx(Fragment, { children: contributions.map((c2) => {
548
- if (c2.render) return /* @__PURE__ */ jsx("div", { children: c2.render(ctx) }, c2.id);
549
- if (c2.region !== "sidebar" || !c2.item) return null;
550
- if (ctx.undockedPanels.includes(c2.id)) return null;
551
- const item = c2.item;
497
+ return /* @__PURE__ */ jsx(Fragment, { children: contributions.map((c) => {
498
+ if (c.render) return /* @__PURE__ */ jsx("div", { children: c.render(ctx) }, c.id);
499
+ if (c.region !== region || !c.item) return null;
500
+ if (ctx.undockedPanels?.includes(c.id)) return null;
501
+ const item = c.item;
552
502
  return /* @__PURE__ */ jsx(
553
503
  Section,
554
504
  {
555
505
  title: item.title,
556
- collapsed: ctx.collapsedSections[c2.id] ?? item.defaultCollapsed ?? false,
557
- onCollapsedChange: (next) => ctx.setSectionCollapsed(c2.id, next),
558
- onUndock: item.undockable === false ? void 0 : () => ctx.undockPanel(c2.id, item.undockAs ?? "tile"),
506
+ collapsed: ctx.collapsedSections[c.id] ?? item.defaultCollapsed ?? false,
507
+ onCollapsedChange: (next) => ctx.setSectionCollapsed(c.id, next),
508
+ onUndock: ctx.undockPanel && item.undockable !== false ? () => ctx.undockPanel?.(c.id, item.undockAs ?? "tile") : void 0,
559
509
  children: item.body
560
510
  },
561
- c2.id
511
+ c.id
562
512
  );
563
513
  }) });
564
514
  }
565
- function StatusRegion({ contributions, ctx }) {
515
+ function StatusRegion({
516
+ contributions,
517
+ ctx,
518
+ region = "status"
519
+ }) {
566
520
  if (contributions.length === 0) return null;
567
- return /* @__PURE__ */ jsx(StatusBar, { children: contributions.map((c2) => {
568
- if (c2.render)
569
- return /* @__PURE__ */ jsx(StatusBar.Section, { end: c2.end, children: c2.render(ctx) }, c2.id);
570
- if (c2.region !== "status" || !c2.item) return null;
571
- return /* @__PURE__ */ jsx(StatusBar.Section, { end: c2.end, children: /* @__PURE__ */ jsx("span", { title: c2.item.title, children: c2.item.text }) }, c2.id);
521
+ return /* @__PURE__ */ jsx(StatusBar, { children: contributions.map((c) => {
522
+ if (c.render)
523
+ return /* @__PURE__ */ jsx(StatusBar.Section, { end: c.end, children: c.render(ctx) }, c.id);
524
+ if (c.region !== region || !c.item) return null;
525
+ const item = c.item;
526
+ return /* @__PURE__ */ jsx(StatusBar.Section, { end: c.end, children: /* @__PURE__ */ jsx("span", { title: item.title, children: item.text }) }, c.id);
572
527
  }) });
573
528
  }
574
- function renderEntry(c2, ctx) {
575
- if (c2.render) return /* @__PURE__ */ jsx("span", { children: c2.render(ctx) }, c2.id);
576
- if (c2.region !== "titlebar" || !c2.item) return null;
577
- const { icon: Icon, label, shortcut, disabled, danger, onActivate } = c2.item;
578
- return /* @__PURE__ */ jsx(
579
- "button",
580
- {
581
- type: "button",
582
- className: `lk-titlebar-button${danger ? " lk-titlebar-button--danger" : ""}`,
583
- disabled,
584
- "aria-label": label,
585
- title: shortcut ? `${label} (${shortcut})` : label,
586
- onClick: () => onActivate(ctx),
587
- onPointerDown: (e) => e.stopPropagation(),
588
- onMouseDown: (e) => e.stopPropagation(),
589
- children: /* @__PURE__ */ jsx(Icon, { size: 14 })
590
- },
591
- c2.id
592
- );
593
- }
594
- function TitleBarRegion({ contributions, ctx, placement = "actions" }) {
595
- const wanted = placement === "actions";
596
- const mine = contributions.filter((c2) => (c2.end ?? false) === wanted);
597
- if (mine.length === 0) return null;
598
- return /* @__PURE__ */ jsx("span", { className: wanted ? "lk-trial__titlebar-actions" : "lk-trial__titlebar-lead", children: mine.map((c2) => renderEntry(c2, ctx)) });
599
- }
600
529
  function groupsOf(contributions) {
601
530
  const groups = [];
602
531
  const byKey = /* @__PURE__ */ new Map();
603
- for (const c2 of contributions) {
604
- if (c2.group == null) {
605
- groups.push({ key: c2.id, end: c2.end ?? false, entries: [c2] });
532
+ for (const c of contributions) {
533
+ if (c.group == null) {
534
+ groups.push({ key: c.id, end: c.end ?? false, entries: [c] });
606
535
  continue;
607
536
  }
608
- let g3 = byKey.get(c2.group);
609
- if (!g3) {
610
- g3 = { key: c2.group, end: c2.end ?? false, entries: [] };
611
- byKey.set(c2.group, g3);
612
- groups.push(g3);
537
+ let g2 = byKey.get(c.group);
538
+ if (!g2) {
539
+ g2 = { key: c.group, end: c.end ?? false, entries: [] };
540
+ byKey.set(c.group, g2);
541
+ groups.push(g2);
613
542
  }
614
- g3.entries.push(c2);
543
+ g2.entries.push(c);
615
544
  }
616
545
  return groups;
617
546
  }
618
- function renderEntry2(c2, ctx) {
619
- if (c2.render) return /* @__PURE__ */ jsx("span", { children: c2.render(ctx) }, c2.id);
620
- if (c2.region !== "toolbar" || !c2.item) return null;
621
- const { icon: Icon, label, shortcut, disabled, danger, showLabel, pressed, onActivate } = c2.item;
547
+ function renderEntry(c, ctx, region) {
548
+ if (c.render) return /* @__PURE__ */ jsx("span", { children: c.render(ctx) }, c.id);
549
+ if (c.region !== region || !c.item) return null;
550
+ const { icon: Icon, label, shortcut, disabled, danger, showLabel, pressed, onActivate } = c.item;
622
551
  return /* @__PURE__ */ jsxs(
623
552
  Toolbar.Button,
624
553
  {
@@ -634,13 +563,151 @@ function renderEntry2(c2, ctx) {
634
563
  showLabel ? /* @__PURE__ */ jsx("span", { children: label }) : null
635
564
  ]
636
565
  },
637
- c2.id
566
+ c.id
638
567
  );
639
568
  }
640
- function ToolbarRegion({ contributions, ctx }) {
569
+ function ToolbarRegion({
570
+ contributions,
571
+ ctx,
572
+ region = "toolbar",
573
+ label = "Trial actions"
574
+ }) {
641
575
  if (contributions.length === 0) return null;
642
576
  const groups = groupsOf(contributions);
643
- return /* @__PURE__ */ jsx(Toolbar, { "aria-label": "Trial actions", children: groups.map((g3) => /* @__PURE__ */ jsx(Toolbar.Group, { end: g3.end, "aria-label": g3.key, children: g3.entries.map((c2) => renderEntry2(c2, ctx)) }, g3.key)) });
577
+ return /* @__PURE__ */ jsx(Toolbar, { "aria-label": label, children: groups.map((g2) => /* @__PURE__ */ jsx(Toolbar.Group, { end: g2.end, "aria-label": g2.key, children: g2.entries.map((c) => renderEntry(c, ctx, region)) }, g2.key)) });
578
+ }
579
+ function useLabChromeContext() {
580
+ const lab = useLabContext();
581
+ const storeCtx = useContext(LabStoreContext);
582
+ if (!storeCtx) throw new Error("[labkit] lab chrome requires <LabStoreProvider>");
583
+ const slot = useStore(storeCtx.store, (s) => s.activeToolId);
584
+ const storeInstruments = useStore(storeCtx.store, (s) => s.instruments);
585
+ const activeToolId = resolveLabTool(slot, storeInstruments ?? lab.instruments);
586
+ const setLabTool = useStore(storeCtx.store, (s) => s.setLabTool);
587
+ return useMemo(
588
+ () => ({ ...lab, activeToolId, setActiveTool: setLabTool }),
589
+ [lab, activeToolId, setLabTool]
590
+ );
591
+ }
592
+ function contributionsIn(contributions, region) {
593
+ return contributions.filter((c) => c.region === region);
594
+ }
595
+ function toolContributions(tools) {
596
+ return tools.map((t) => ({
597
+ id: t.id,
598
+ region: "palette",
599
+ ...t.group === void 0 ? {} : { group: t.group },
600
+ item: {
601
+ icon: t.icon,
602
+ label: t.label,
603
+ ...t.shortcut === void 0 ? {} : { shortcut: t.shortcut }
604
+ }
605
+ }));
606
+ }
607
+ function labContributions(tools, chrome) {
608
+ return mergeContributions(toolContributions(tools ?? []), [...chrome ?? []]);
609
+ }
610
+ function LabHeaderRegion({ contributions }) {
611
+ const ctx = useLabChromeContext();
612
+ return /* @__PURE__ */ jsx(
613
+ ToolbarRegion,
614
+ {
615
+ region: "header",
616
+ label: "Lab actions",
617
+ contributions: contributionsIn(contributions, "header"),
618
+ ctx
619
+ }
620
+ );
621
+ }
622
+ function LabSidebarRegion({ contributions }) {
623
+ const lab = useLabChromeContext();
624
+ const [collapsedSections, setFolds] = usePersistedState(
625
+ "lk-lab-sidebar-folds",
626
+ {},
627
+ { scope: "lab" }
628
+ );
629
+ const ctx = useMemo(
630
+ () => ({
631
+ ...lab,
632
+ collapsedSections,
633
+ setSectionCollapsed: (key, collapsed) => setFolds((f) => ({ ...f, [key]: collapsed }))
634
+ }),
635
+ [lab, collapsedSections, setFolds]
636
+ );
637
+ return /* @__PURE__ */ jsx(SidebarRegion, { contributions: contributionsIn(contributions, "sidebar"), ctx });
638
+ }
639
+ function LabFooterRegion({ contributions }) {
640
+ const ctx = useLabChromeContext();
641
+ return /* @__PURE__ */ jsx(
642
+ StatusRegion,
643
+ {
644
+ region: "footer",
645
+ contributions: contributionsIn(contributions, "footer"),
646
+ ctx
647
+ }
648
+ );
649
+ }
650
+ function PaletteRegion({
651
+ contributions,
652
+ ctx,
653
+ region = "palette"
654
+ }) {
655
+ const { ref, onKeyDown } = useRovingTabIndex("vertical");
656
+ if (contributions.length === 0) return null;
657
+ return /* @__PURE__ */ jsx(
658
+ "div",
659
+ {
660
+ ref,
661
+ className: "lk-palette-region",
662
+ role: "toolbar",
663
+ "aria-label": "Tools",
664
+ "aria-orientation": "vertical",
665
+ onKeyDown,
666
+ children: /* @__PURE__ */ jsx(n6, { orientation: "vertical", children: contributions.map((c) => {
667
+ if (c.render) return /* @__PURE__ */ jsx("span", { children: c.render(ctx) }, c.id);
668
+ if (c.region !== region || !c.item) return null;
669
+ const { icon: Icon, label, shortcut, disabled } = c.item;
670
+ return /* @__PURE__ */ jsx(
671
+ o3,
672
+ {
673
+ icon: /* @__PURE__ */ jsx(Icon, { size: 16 }),
674
+ label,
675
+ shortcut,
676
+ active: ctx.activeToolId === c.id,
677
+ disabled,
678
+ onClick: () => ctx.setActiveTool(c.id)
679
+ },
680
+ c.id
681
+ );
682
+ }) })
683
+ }
684
+ );
685
+ }
686
+ function renderEntry2(c, ctx) {
687
+ if (c.render) return /* @__PURE__ */ jsx("span", { children: c.render(ctx) }, c.id);
688
+ if (c.region !== "titlebar" || !c.item) return null;
689
+ const { icon: Icon, label, shortcut, disabled, danger, onActivate } = c.item;
690
+ return /* @__PURE__ */ jsx(
691
+ "button",
692
+ {
693
+ type: "button",
694
+ className: `lk-titlebar-button${danger ? " lk-titlebar-button--danger" : ""}`,
695
+ disabled,
696
+ "aria-label": label,
697
+ title: shortcut ? `${label} (${shortcut})` : label,
698
+ onClick: () => onActivate(ctx),
699
+ onPointerDown: (e) => e.stopPropagation(),
700
+ onMouseDown: (e) => e.stopPropagation(),
701
+ children: /* @__PURE__ */ jsx(Icon, { size: 14 })
702
+ },
703
+ c.id
704
+ );
705
+ }
706
+ function TitleBarRegion({ contributions, ctx, placement = "actions" }) {
707
+ const wanted = placement === "actions";
708
+ const mine = contributions.filter((c) => (c.end ?? false) === wanted);
709
+ if (mine.length === 0) return null;
710
+ return /* @__PURE__ */ jsx("span", { className: wanted ? "lk-trial__titlebar-actions" : "lk-trial__titlebar-lead", children: mine.map((c) => renderEntry2(c, ctx)) });
644
711
  }
645
712
  function ViewportRegion({ contributions, ctx }) {
646
713
  const { ref, onKeyDown } = useRovingTabIndex();
@@ -653,10 +720,10 @@ function ViewportRegion({ contributions, ctx }) {
653
720
  role: "toolbar",
654
721
  "aria-label": "View",
655
722
  onKeyDown,
656
- children: contributions.map((c2) => {
657
- if (c2.render) return /* @__PURE__ */ jsx("span", { children: c2.render(ctx) }, c2.id);
658
- if (c2.region !== "viewport" || !c2.item) return null;
659
- const { icon: Icon, label, disabled, onActivate } = c2.item;
723
+ children: contributions.map((c) => {
724
+ if (c.render) return /* @__PURE__ */ jsx("span", { children: c.render(ctx) }, c.id);
725
+ if (c.region !== "viewport" || !c.item) return null;
726
+ const { icon: Icon, label, disabled, onActivate } = c.item;
660
727
  return /* @__PURE__ */ jsx(
661
728
  "button",
662
729
  {
@@ -668,13 +735,13 @@ function ViewportRegion({ contributions, ctx }) {
668
735
  onClick: () => onActivate(ctx),
669
736
  children: /* @__PURE__ */ jsx(Icon, { size: 16 })
670
737
  },
671
- c2.id
738
+ c.id
672
739
  );
673
740
  })
674
741
  }
675
742
  );
676
743
  }
677
744
 
678
- export { ANNOTATION_TOOLS, ANNOTATION_WEASEL_TOOLS, AnnotationsContext, ExportMenu, MarkList, PaletteRegion, SidebarRegion, StatusRegion, TitleBarRegion, ToolbarRegion, ViewportRegion, annotationToolInfo, builtinContributions, mergeContributions, suppressContributions, useAnnotations, useAnnotationsOptional };
679
- //# sourceMappingURL=chunk-C42T6DJT.js.map
680
- //# sourceMappingURL=chunk-C42T6DJT.js.map
745
+ export { AnnotationsContext, ExportMenu, LabFooterRegion, LabHeaderRegion, LabSidebarRegion, MarkList, PaletteRegion, SidebarRegion, StatusRegion, TitleBarRegion, ToolbarRegion, ViewportRegion, builtinContributions, contributionsIn, labContributions, mergeContributions, resolveLabTool, suppressContributions, toolContributions, useAnnotations, useAnnotationsOptional, useLabChromeContext };
746
+ //# sourceMappingURL=chunk-NS64DXMN.js.map
747
+ //# sourceMappingURL=chunk-NS64DXMN.js.map