@weasel-js/labkit 1.6.1 → 1.7.1
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.
- package/README.md +3 -3
- package/dist/_dts/{CanvasStackContext-Wo6OwIVM.d.ts → CanvasStackContext-Cjy6I-Iv.d.ts} +4 -1
- package/dist/_dts/{Stage-DWBBi8IU.d.ts → Stage-D6t7o0pF.d.ts} +59 -18
- package/dist/_dts/{index-CKyX0ME_.d.ts → index-BTmaRy6a.d.ts} +10 -6
- package/dist/_dts/{types-B7yBTTF9.d.ts → index-DCMA4Fy1.d.ts} +59 -113
- package/dist/_dts/{types-DTuViBvc.d.ts → types-BUBSIZuV.d.ts} +18 -8
- package/dist/_dts/{useTrialState-CMaV6UD4.d.ts → useTrialState-Bh8bzFgE.d.ts} +1 -1
- package/dist/canvas/index.d.ts +8 -6
- package/dist/canvas/index.js +6 -6
- package/dist/chrome/index.d.ts +6 -4
- package/dist/chrome/index.js +11 -10
- package/dist/chunk-2ES4W47N.js +8 -0
- package/dist/chunk-2ES4W47N.js.map +1 -0
- package/dist/{chunk-WPLAANH4.js → chunk-2N7UBSS2.js} +12 -12
- package/dist/chunk-2N7UBSS2.js.map +1 -0
- package/dist/chunk-4KSC7NXL.js +15491 -0
- package/dist/chunk-4KSC7NXL.js.map +1 -0
- package/dist/{chunk-SLAQPUI4.js → chunk-CEGFXTBD.js} +10 -63
- package/dist/chunk-CEGFXTBD.js.map +1 -0
- package/dist/chunk-CZZPXUOU.js +3 -0
- package/dist/{chunk-SBXNQW4G.js.map → chunk-CZZPXUOU.js.map} +1 -1
- package/dist/{chunk-QGMOA2YE.js → chunk-E23Q6A3Y.js} +296 -104
- package/dist/chunk-E23Q6A3Y.js.map +1 -0
- package/dist/{chunk-GHGO52SO.js → chunk-E6NARGU7.js} +5 -5
- package/dist/{chunk-GHGO52SO.js.map → chunk-E6NARGU7.js.map} +1 -1
- package/dist/{chunk-IJJUK4FU.js → chunk-EESJUSYR.js} +5 -6
- package/dist/chunk-EESJUSYR.js.map +1 -0
- package/dist/{chunk-HXXTULDN.js → chunk-EFXRM6XQ.js} +8 -11
- package/dist/chunk-EFXRM6XQ.js.map +1 -0
- package/dist/chunk-F4ACIK7Z.js +210 -0
- package/dist/chunk-F4ACIK7Z.js.map +1 -0
- package/dist/{chunk-6FLXL3I7.js → chunk-FB4MIZOO.js} +77 -45
- package/dist/chunk-FB4MIZOO.js.map +1 -0
- package/dist/{chunk-AWQG7FCC.js → chunk-FG3EXZDV.js} +3 -3
- package/dist/{chunk-AWQG7FCC.js.map → chunk-FG3EXZDV.js.map} +1 -1
- package/dist/{chunk-4TT3PNPR.js → chunk-GAHELLJT.js} +95 -95
- package/dist/chunk-GAHELLJT.js.map +1 -0
- package/dist/{chunk-HKV7LRHY.js → chunk-IBVRMHW5.js} +5 -5
- package/dist/{chunk-HKV7LRHY.js.map → chunk-IBVRMHW5.js.map} +1 -1
- package/dist/{chunk-ASOK76ZH.js → chunk-JFOJESJF.js} +72 -29
- package/dist/chunk-JFOJESJF.js.map +1 -0
- package/dist/{chunk-RWNDDKOH.js → chunk-PMLZP7RT.js} +18 -15
- package/dist/chunk-PMLZP7RT.js.map +1 -0
- package/dist/{chunk-TJ77A4A3.js → chunk-READTDQX.js} +5 -9
- package/dist/chunk-READTDQX.js.map +1 -0
- package/dist/{chunk-JVBYV6TL.js → chunk-ROGJWDQA.js} +3 -3
- package/dist/{chunk-JVBYV6TL.js.map → chunk-ROGJWDQA.js.map} +1 -1
- package/dist/{chunk-CGHF6RZV.js → chunk-T6DLGEJB.js} +18 -18
- package/dist/chunk-T6DLGEJB.js.map +1 -0
- package/dist/{chunk-24W5VEJW.js → chunk-ULYYNWGP.js} +2 -2
- package/dist/{chunk-24W5VEJW.js.map → chunk-ULYYNWGP.js.map} +1 -1
- package/dist/{chunk-DWMSB4CA.js → chunk-VYVGVBGY.js} +95 -32
- package/dist/chunk-VYVGVBGY.js.map +1 -0
- package/dist/{chunk-IRTGUQ5O.js → chunk-WLMDTI2Q.js} +16 -6
- package/dist/chunk-WLMDTI2Q.js.map +1 -0
- package/dist/{chunk-NEXR37YJ.js → chunk-XE5HJOPL.js} +6 -8
- package/dist/chunk-XE5HJOPL.js.map +1 -0
- package/dist/chunk-XVUKDSYV.js +38 -0
- package/dist/chunk-XVUKDSYV.js.map +1 -0
- package/dist/{chunk-O6FFFOHS.js → chunk-YCFKW5RX.js} +16 -8
- package/dist/chunk-YCFKW5RX.js.map +1 -0
- package/dist/{chunk-CQLQPQ4P.js → chunk-ZQIHJXP4.js} +2 -2
- package/dist/chunk-ZQIHJXP4.js.map +1 -0
- package/dist/config/index.d.ts +28 -13
- package/dist/config/index.js +4 -4
- package/dist/controls/index.d.ts +4 -7
- package/dist/controls/index.js +6 -5
- package/dist/dragdrop/index.d.ts +23 -3
- package/dist/dragdrop/index.js +4 -3
- package/dist/fonts/oswald-tabular-digits.woff2 +0 -0
- package/dist/index.d.ts +72 -487
- package/dist/index.js +603 -441
- package/dist/index.js.map +1 -1
- package/dist/job/index.d.ts +8 -0
- package/dist/job/index.js +1 -1
- package/dist/layers/index.d.ts +6 -5
- package/dist/layers/index.js +3 -2
- package/dist/loupe/index.d.ts +100 -30
- package/dist/loupe/index.js +585 -6
- package/dist/loupe/index.js.map +1 -1
- package/dist/overview/index.d.ts +4 -2
- package/dist/overview/index.js +20 -18
- package/dist/overview/index.js.map +1 -1
- package/dist/passthrough/weasel-canvas.d.ts +2 -0
- package/dist/passthrough/weasel-ui.d.ts +2 -2701
- package/dist/passthrough/weasel-ui.js +4 -3
- package/dist/primitives/index.d.ts +37 -2
- package/dist/primitives/index.js +9 -8
- package/dist/state/index.d.ts +7 -5
- package/dist/state/index.js +6 -6
- package/dist/styles.css +150 -126
- package/dist/surface/index.d.ts +10 -2
- package/dist/surface/index.js +1 -1
- package/dist/undo/index.d.ts +5 -3
- package/package.json +14 -13
- package/src/annotations/AnnotationOverlay.abandon.test.tsx +143 -0
- package/src/annotations/AnnotationOverlay.tsx +52 -33
- package/src/annotations/Annotations.less +0 -10
- package/src/annotations/Annotations.overlay.test.tsx +31 -0
- package/src/annotations/MarkList.tsx +4 -8
- package/src/annotations/capture.browser.test.ts +41 -0
- package/src/annotations/capture.ts +14 -7
- package/src/annotations/drawOne.ts +2 -2
- package/src/annotations/frac.test.ts +44 -1
- package/src/annotations/frac.ts +46 -18
- package/src/annotations/index.ts +1 -0
- package/src/annotations/paint.test.ts +76 -46
- package/src/annotations/paint.ts +65 -43
- package/src/annotations/store.test.ts +212 -2
- package/src/annotations/store.ts +130 -27
- package/src/annotations/svgNodes.test.ts +28 -19
- package/src/annotations/svgNodes.ts +6 -6
- package/src/annotations/types.ts +29 -10
- package/src/canvas/AGENTS.md +1 -0
- package/src/canvas/CameraInput.test.tsx +30 -0
- package/src/canvas/CameraInput.tsx +60 -48
- package/src/canvas/CanvasStack.tsx +11 -6
- package/src/canvas/CanvasStackContext.ts +4 -1
- package/src/canvas/LinkedCursor.less +1 -1
- package/src/canvas/Stage.test.tsx +33 -4
- package/src/canvas/Stage.tsx +9 -4
- package/src/canvas/cameraRegistry.test.ts +55 -0
- package/src/canvas/cameraRegistry.ts +87 -0
- package/src/canvas/cameraZoom.test.ts +46 -0
- package/src/canvas/cameraZoom.ts +24 -0
- package/src/canvas/index.ts +14 -2
- package/src/canvas/sharedScope.test.tsx +94 -0
- package/src/canvas/worldSpec.ts +3 -1
- package/src/chrome/ChromeRegions.stories.tsx +1 -0
- package/src/chrome/builtins.test.ts +7 -6
- package/src/chrome/builtins.tsx +5 -1
- package/src/chrome/index.ts +1 -1
- package/src/chrome/merge.test.ts +5 -0
- package/src/chrome/merge.ts +4 -2
- package/src/chrome/regions/PaletteRegion.less +0 -7
- package/src/chrome/regions/PaletteRegion.test.tsx +2 -3
- package/src/chrome/regions/PaletteRegion.tsx +3 -4
- package/src/chrome/regions/SidebarRegion.less +12 -2
- package/src/chrome/regions/ViewportRegion.browser.test.less +6 -0
- package/src/chrome/regions/ViewportRegion.browser.test.tsx +38 -0
- package/src/chrome/regions/ViewportRegion.less +6 -0
- package/src/chrome/regions/ViewportRegion.tsx +10 -4
- package/src/chrome/types.ts +4 -2
- package/src/config/auto.ts +1 -0
- package/src/config/builder.test.ts +2 -1
- package/src/config/builder.ts +18 -5
- package/src/config/fromConfigField.test.ts +14 -0
- package/src/config/fromConfigField.ts +18 -4
- package/src/config/path.ts +2 -5
- package/src/config/resolve.ts +4 -0
- package/src/config/types.ts +14 -9
- package/src/controls/ControlPanel.less +1 -1
- package/src/controls/ControlPanel.stories.tsx +3 -2
- package/src/controls/ControlPanel.test.tsx +98 -11
- package/src/controls/ControlPanel.tsx +61 -2
- package/src/dragdrop/DragDropRuntime.tsx +22 -13
- package/src/dragdrop/DragGhost.tsx +3 -0
- package/src/dragdrop/Palette.tsx +2 -0
- package/src/index.test.ts +5 -0
- package/src/index.ts +16 -2
- package/src/instrument/types.ts +0 -6
- package/src/job/useJob.ts +14 -9
- package/src/lab/Lab.tsx +88 -73
- package/src/lab/{LabFit.stories.less → LabFit.browser.test.less} +1 -1
- package/src/lab/{LabFit.stories.tsx → LabFit.browser.test.tsx} +41 -63
- package/src/lab/LabFullChrome.stories.tsx +1 -0
- package/src/lab/LabHeader.test.tsx +24 -14
- package/src/lab/LabHeader.tsx +11 -12
- package/src/lab/LabShell.less +9 -17
- package/src/lab/LabSwitcher.browser.test.tsx +27 -0
- package/src/lab/LabSwitcher.less +8 -6
- package/src/lab/LabZoom.test.tsx +223 -0
- package/src/lab/LabZoom.tsx +170 -0
- package/src/lab/Workspace.tsx +48 -52
- package/src/lab/index.ts +1 -0
- package/src/loupe/AGENTS.md +28 -15
- package/src/loupe/CanvasLoupe.tsx +2 -3
- package/src/loupe/DomLoupe.tsx +1 -7
- package/src/loupe/Loupe.less +16 -0
- package/src/loupe/LoupeGestures.tsx +1 -1
- package/src/loupe/TrialLoupe.tsx +120 -57
- package/src/loupe/index.ts +1 -6
- package/src/loupe/types.test.ts +3 -3
- package/src/loupe/types.ts +24 -27
- package/src/loupe/useLoupe.test.tsx +29 -4
- package/src/loupe/useLoupe.ts +20 -17
- package/src/overview/OverviewMarks.tsx +12 -4
- package/src/overview/TrialOverview.tsx +10 -8
- package/src/passthrough/weasel-ui.test.ts +2 -0
- package/src/passthrough/weasel-ui.ts +17 -5
- package/src/primitives/FloatingPanel.test.tsx +11 -0
- package/src/primitives/FloatingPanel.tsx +8 -7
- package/src/primitives/JobProgress.less +2 -1
- package/src/primitives/Legend.stories.tsx +1 -0
- package/src/primitives/Readout.browser.test.tsx +137 -0
- package/src/primitives/Readout.less +12 -0
- package/src/primitives/Readout.stories.tsx +58 -0
- package/src/primitives/Readout.test.tsx +93 -0
- package/src/primitives/Readout.tsx +56 -0
- package/src/primitives/Split.tsx +69 -41
- package/src/primitives/Toolbar.tsx +3 -3
- package/src/primitives/ZoomControl.less +1 -2
- package/src/primitives/index.ts +2 -0
- package/src/specimen/Specimen.stories.tsx +1 -0
- package/src/specimen/Specimen.tsx +2 -3
- package/src/state/Persistence.browser.test.tsx +47 -0
- package/src/state/store.test.ts +5 -1
- package/src/state/undock.ts +3 -0
- package/src/state/useOpenOnce.ts +20 -16
- package/src/state/usePersistedState.test.tsx +1 -1
- package/src/state/view.ts +1 -0
- package/src/styles.less +1 -0
- package/src/surface/index.ts +1 -1
- package/src/surface/useTiledSurface.test.tsx +14 -0
- package/src/surface/useTiledSurface.ts +11 -3
- package/src/theme/Interstellar.stories.tsx +3 -1
- package/src/theme/base.less +21 -47
- package/src/theme/interstellar.test.ts +1 -1
- package/src/theme/interstellar.theme.json +10 -3
- package/src/trial/Trial.annotations.test.tsx +73 -0
- package/src/trial/Trial.less +0 -29
- package/src/trial/Trial.loupe.test.tsx +28 -11
- package/src/trial/Trial.tsx +85 -67
- package/src/trial/TrialChrome.tsx +27 -6
- package/src/trial/index.ts +2 -0
- package/src/trial/loupeSwitch.ts +15 -0
- package/dist/_dts/LayerList.d-BoELAMsM.d.ts +0 -83
- package/dist/_dts/PrefsRow.d-DFpPIeIC.d.ts +0 -39
- package/dist/_dts/PropertyField.d-D0ndfIIt.d.ts +0 -404
- package/dist/_dts/Select.d-Cr8-zoup.d.ts +0 -569
- package/dist/chunk-4TT3PNPR.js.map +0 -1
- package/dist/chunk-6FLXL3I7.js.map +0 -1
- package/dist/chunk-ASOK76ZH.js.map +0 -1
- package/dist/chunk-CGHF6RZV.js.map +0 -1
- package/dist/chunk-CQLQPQ4P.js.map +0 -1
- package/dist/chunk-DWMSB4CA.js.map +0 -1
- package/dist/chunk-HXXTULDN.js.map +0 -1
- package/dist/chunk-IJJUK4FU.js.map +0 -1
- package/dist/chunk-IRTGUQ5O.js.map +0 -1
- package/dist/chunk-KHK5FGER.js +0 -145
- package/dist/chunk-KHK5FGER.js.map +0 -1
- package/dist/chunk-NEXR37YJ.js.map +0 -1
- package/dist/chunk-O6FFFOHS.js.map +0 -1
- package/dist/chunk-QGMOA2YE.js.map +0 -1
- package/dist/chunk-RWNDDKOH.js.map +0 -1
- package/dist/chunk-S4NCI32V.js +0 -549
- package/dist/chunk-S4NCI32V.js.map +0 -1
- package/dist/chunk-SBXNQW4G.js +0 -3
- package/dist/chunk-SLAQPUI4.js.map +0 -1
- package/dist/chunk-TJ77A4A3.js.map +0 -1
- package/dist/chunk-TYN6MLXX.js +0 -13864
- package/dist/chunk-TYN6MLXX.js.map +0 -1
- package/dist/chunk-WPLAANH4.js.map +0 -1
- package/src/primitives/useRovingTabIndex.test.ts +0 -48
- package/src/primitives/useRovingTabIndex.ts +0 -88
- package/src/state/Persistence.stories.tsx +0 -75
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dragdrop/DragGhost.tsx","../src/dragdrop/DragDropRuntime.tsx","../src/dragdrop/Palette.tsx"],"names":["useState","useEffect","jsx"],"mappings":";;;;;;;AASO,SAAS,SAAA,CAAU,EAAE,IAAA,EAAM,SAAA,EAAU,EAAuC;AACjF,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,SAAA,CAAU,MAAM,UAAA,CAAW,IAAI,CAAA,EAAG,EAAE,CAAA;AACpC,EAAA,IAAI,CAAC,OAAA,IAAW,OAAO,QAAA,KAAa,aAAa,OAAO,IAAA;AACxD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,IAAA,EAAM,CAAA,EAAG,SAAA,CAAU,CAAA,GAAI,EAAE,CAAA,EAAA,CAAA;AAAA,IACzB,GAAA,EAAK,CAAA,EAAG,SAAA,CAAU,CAAA,GAAI,EAAE,CAAA,EAAA;AAAA,GAC1B;AACA,EAAA,OAAO,YAAA;AAAA,oBACL,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EAAgB,KAAA,EAC7B,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sBAAA,EAAwB,QAAA,EAAA,IAAA,CAAK,KAAA,EAAM,CAAA,EACrD,CAAA;AAAA,IACA,QAAA,CAAS;AAAA,GACX;AACF;ACqBO,SAAS,WAAA,CAAoB;AAAA,EAClC,UAAA;AAAA,EACA,kBAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAA+C;AAC7C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,SAA2B,IAAI,CAAA;AACvD,EAAA,MAAM,OAAA,GAAU,OAAyB,IAAI,CAAA;AAC7C,EAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAGlB,EAAA,MAAM,UAAA,GAAa,OAAqB,IAAI,CAAA;AAC5C,EAAA,MAAM,UAAA,GAAa,OAA8B,IAAI,CAAA;AAIrD,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,EAAE,UAAA,EAAY,KAAA,EAAO,QAAQ,QAAA,EAAU,IAAA,EAAM,IAAA,EAAM,SAAA,EAAW,CAAA;AACrF,EAAA,OAAA,CAAQ,OAAA,GAAU,EAAE,UAAA,EAAY,KAAA,EAAO,QAAQ,QAAA,EAAU,IAAA,EAAM,MAAM,SAAA,EAAU;AAE/E,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,SAAA,KAA8B;AAC7B,MAAA,MAAM,KAAK,kBAAA,CAAmB,OAAA;AAC9B,MAAA,IAAI,CAAC,IAAI,OAAO,KAAA;AAChB,MAAA,MAAM,CAAA,GAAI,GAAG,qBAAA,EAAsB;AACnC,MAAA,OACE,SAAA,CAAU,CAAA,IAAK,CAAA,CAAE,IAAA,IACjB,UAAU,CAAA,IAAK,CAAA,CAAE,KAAA,IACjB,SAAA,CAAU,CAAA,IAAK,CAAA,CAAE,GAAA,IACjB,SAAA,CAAU,KAAK,CAAA,CAAE,MAAA;AAAA,IAErB,CAAA;AAAA,IACA,CAAC,kBAAkB;AAAA,GACrB;AAEA,EAAA,MAAM,0BAAA,GAA6B,WAAA;AAAA,IACjC,CAAC,SAAA,KAAmC;AAClC,MAAA,MAAM,KAAK,kBAAA,CAAmB,OAAA;AAC9B,MAAA,IAAI,CAAC,IAAI,OAAO,IAAA;AAChB,MAAA,MAAM,CAAA,GAAI,GAAG,qBAAA,EAAsB;AACnC,MAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,OAAA,CAAQ,OAAA,CAAQ,SAAA,EAAW,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAO,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAQ,CAAA;AAC1F,MAAA,OAAO,aAAA;AAAA,QACL,EAAE,CAAA,EAAG,SAAA,CAAU,CAAA,GAAI,CAAA,CAAE,MAAM,CAAA,EAAG,SAAA,CAAU,CAAA,GAAI,CAAA,CAAE,GAAA,EAAI;AAAA,QAClD,QAAQ,OAAA,CAAQ,IAAA;AAAA,QAChB;AAAA,OACF;AAAA,IACF,CAAA;AAAA,IACA,CAAC,kBAAkB;AAAA,GACrB;AAEA,EAAA,MAAM,SAAA,GAAY,cAAc,MAAM;AACpC,IAAA,MAAM,YAAY,UAAA,CAAW,OAAA;AAC7B,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,IAAA,MAAM,SAAS,OAAA,CAAQ,OAAA;AACvB,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,SAAA,EAAW;AAC3B,IAAA,MAAM,OAAO,OAAA,CAAQ,OAAA;AACrB,IAAA,IAAI,QAAA,GAAgC,IAAA;AACpC,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,UAAA,IAAc,YAAA,CAAa,SAAS,CAAA,EAAG;AACzD,MAAA,MAAM,KAAA,GAAQ,2BAA2B,SAAS,CAAA;AAClD,MAAA,IAAI,KAAA,EAAO,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,UAAA,CAAW,KAAA,EAAO,MAAA,CAAO,IAAA,EAAM,IAAA,CAAK,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA;AAAA,IAC9F;AACA,IAAA,OAAA,CAAQ,EAAE,GAAG,MAAA,EAAQ,SAAA,EAAW,UAAU,CAAA;AAAA,EAC5C,CAAC,CAAA;AAED,EAAA,MAAM,SAAA,GAAY,YAAY,MAAM;AAClC,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,IAAA,SAAA,CAAU,MAAA,EAAO;AACjB,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,IAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,IAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,EACd,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,SAAA,GAAY,WAAA;AAAA,IAChB,CAAC,MAAmB,CAAA,KAAyB;AAC3C,MAAA,IAAI,WAAW,OAAA,EAAS;AACxB,MAAA,MAAM,IAAA,GAAkB,EAAE,IAAA,EAAM,SAAA,EAAW,EAAE,CAAA,EAAG,CAAA,CAAE,OAAA,EAAS,CAAA,EAAG,CAAA,CAAE,OAAA,EAAQ,EAAG,UAAU,IAAA,EAAK;AAC1F,MAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA,UAAA,CAAW,OAAA,GAAU,kBAAA,CAAmB,CAAA,CAAE,aAAA,EAAe,CAAA,EAAG;AAAA,QAC1D,MAAA,EAAQ,CAAC,EAAA,KAAO;AACd,UAAA,MAAM,YAAY,EAAE,CAAA,EAAG,GAAG,OAAA,EAAS,CAAA,EAAG,GAAG,OAAA,EAAQ;AACjD,UAAA,MAAM,UAAU,OAAA,CAAQ,OAAA;AACxB,UAAA,IAAI,CAAC,OAAA,EAAS;AACd,UAAA,IAAI,UAAA,CAAW,YAAY,IAAA,EAAM;AAG/B,YAAA,UAAA,CAAW,OAAA,GAAU,SAAA;AACrB,YAAA,OAAA,CAAQ,OAAA,GAAU,EAAE,GAAG,OAAA,EAAS,SAAA,EAAU;AAC1C,YAAA,OAAA,CAAQ,QAAQ,OAAO,CAAA;AACvB,YAAA;AAAA,UACF;AACA,UAAA,UAAA,CAAW,OAAA,GAAU,SAAA;AACrB,UAAA,SAAA,CAAU,OAAA,EAAQ;AAAA,QACpB,CAAA;AAAA,QACA,KAAA,EAAO,CAAC,EAAA,KAAO;AACb,UAAA,MAAM,YAAY,EAAE,CAAA,EAAG,GAAG,OAAA,EAAS,CAAA,EAAG,GAAG,OAAA,EAAQ;AACjD,UAAA,MAAM,SAAS,OAAA,CAAQ,OAAA;AACvB,UAAA,SAAA,EAAU;AACV,UAAA,IAAI,CAAC,MAAA,IAAU,CAAC,YAAA,CAAa,SAAS,CAAA,EAAG;AACzC,UAAA,MAAM,KAAA,GAAQ,2BAA2B,SAAS,CAAA;AAClD,UAAA,IAAI,CAAC,KAAA,EAAO;AACZ,UAAA,MAAM,OAAO,OAAA,CAAQ,OAAA;AACrB,UAAA,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,UAAA,CAAW,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,IAAA,EAAM,IAAA,CAAK,KAAA,EAAO,IAAA,CAAK,MAAM,CAAC,CAAA;AACjF,UAAA,IAAA,CAAK,KAAK,kBAAkB,CAAA;AAAA,QAC9B,CAAA;AAAA;AAAA,QAEA,QAAA,EAAU;AAAA,OACX,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,SAAA,EAAW,YAAA,EAAc,0BAA0B;AAAA,GACjE;AAEA,EAAAC,SAAAA,CAAU,MAAM,MAAM,UAAA,CAAW,SAAS,MAAA,EAAO,EAAG,EAAE,CAAA;AAEtD,EAAA,OAAO,EAAE,MAAM,SAAA,EAAU;AAC3B;AAMO,SAAS,WAAA,CAAY,EAAE,IAAA,EAAK,EAAqB;AACtD,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,uBAAOC,IAAC,SAAA,EAAA,EAAU,IAAA,EAAM,KAAK,IAAA,EAAM,SAAA,EAAW,KAAK,SAAA,EAAW,CAAA;AAChE;AClKO,SAAS,OAAA,CAAQ,EAAE,KAAA,EAAO,WAAA,EAAa,WAAU,EAAiB;AACvE,EAAA,uBACEA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,SAAA,GAAY,CAAA,WAAA,EAAc,SAAS,CAAA,CAAA,GAAK,YAAA,EACrD,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,yBACVA,GAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MAEL,SAAA,EAAU,kBAAA;AAAA,MACV,aAAA,EAAe,CAAC,CAAA,KAAM;AACpB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,WAAA,CAAY,MAAM,CAAC,CAAA;AAAA,MACrB,CAAA;AAAA,MAEA,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mBAAA,EAAqB,eAAK,KAAA,EAAM;AAAA,KAAA;AAAA,IAP3C,IAAA,CAAK;AAAA,GASb,CAAA,EACH,CAAA;AAEJ","file":"chunk-WPLAANH4.js","sourcesContent":["import { type ReactPortal, useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { PaletteItem, Point } from '../instrument/types';\n\nexport interface DragGhostProps {\n item: PaletteItem;\n screenPos: Point;\n}\n\nexport function DragGhost({ item, screenPos }: DragGhostProps): ReactPortal | null {\n const [mounted, setMounted] = useState(false);\n useEffect(() => setMounted(true), []);\n if (!mounted || typeof document === 'undefined') return null;\n const style = {\n left: `${screenPos.x + 12}px`,\n top: `${screenPos.y + 12}px`,\n };\n return createPortal(\n <div className=\"lk-drag-ghost\" style={style}>\n <span className=\"lk-drag-ghost__label\">{item.label}</span>\n </div>,\n document.body,\n );\n}\n","import { openPointerSession, type PointerSession, useVisibleRaf } from '@weasel-js/core';\nimport {\n type PointerEvent as ReactPointerEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { screenToWorld } from '../canvas/canvasCoords';\nimport { resolveFrame, type WorldSpec } from '../canvas/worldSpec';\nimport type {\n DragDropCapability,\n DragFeedback,\n PaletteItem,\n Point,\n ViewTransform,\n} from '../instrument/types';\nimport { DragGhost } from './DragGhost';\n\nexport interface DragState {\n item: PaletteItem;\n screenPos: Point;\n feedback: DragFeedback | null;\n}\n\nexport interface UseDragDropArgs<TS, TC> {\n capability: DragDropCapability<TS, TC>;\n canvasContainerRef: RefObject<HTMLElement | null>;\n view: ViewTransform;\n /** The instrument's coordinate system, resolved against the container each\n * time a screen point is converted — the container is what knows its size. */\n worldSpec?: WorldSpec;\n state: TS;\n config: TC;\n setState: (next: TS | ((prev: TS) => TS)) => void;\n emit: (event: string) => void;\n}\n\nexport interface UseDragDropResult {\n drag: DragState | null;\n startDrag: (item: PaletteItem, e: ReactPointerEvent) => void;\n}\n\nexport function useDragDrop<TS, TC>({\n capability,\n canvasContainerRef,\n view,\n state,\n config,\n setState,\n emit,\n worldSpec,\n}: UseDragDropArgs<TS, TC>): UseDragDropResult {\n const [drag, setDrag] = useState<DragState | null>(null);\n const dragRef = useRef<DragState | null>(null);\n dragRef.current = drag;\n /** The move the next frame will resolve. Doubles as the throttle's flag:\n * non-null means a frame is already queued. */\n const pendingPos = useRef<Point | null>(null);\n const sessionRef = useRef<PointerSession | null>(null);\n\n /** A session keeps the closure it was opened with, so everything the drop\n * reads has to come from here rather than from that closure. */\n const liveRef = useRef({ capability, state, config, setState, emit, view, worldSpec });\n liveRef.current = { capability, state, config, setState, emit, view, worldSpec };\n\n const isOverCanvas = useCallback(\n (screenPos: Point): boolean => {\n const el = canvasContainerRef.current;\n if (!el) return false;\n const r = el.getBoundingClientRect();\n return (\n screenPos.x >= r.left &&\n screenPos.x <= r.right &&\n screenPos.y >= r.top &&\n screenPos.y <= r.bottom\n );\n },\n [canvasContainerRef],\n );\n\n const screenToWorldFromContainer = useCallback(\n (screenPos: Point): Point | null => {\n const el = canvasContainerRef.current;\n if (!el) return null;\n const r = el.getBoundingClientRect();\n const frame = resolveFrame(liveRef.current.worldSpec, { width: r.width, height: r.height });\n return screenToWorld(\n { x: screenPos.x - r.left, y: screenPos.y - r.top },\n liveRef.current.view,\n frame,\n );\n },\n [canvasContainerRef],\n );\n\n const frameLoop = useVisibleRaf(() => {\n const screenPos = pendingPos.current;\n pendingPos.current = null;\n const active = dragRef.current;\n if (!active || !screenPos) return;\n const live = liveRef.current;\n let feedback: DragFeedback | null = null;\n if (live.capability.onDragOver && isOverCanvas(screenPos)) {\n const world = screenToWorldFromContainer(screenPos);\n if (world) feedback = live.capability.onDragOver(world, active.item, live.state, live.config);\n }\n setDrag({ ...active, screenPos, feedback });\n });\n\n const clearDrag = useCallback(() => {\n pendingPos.current = null;\n frameLoop.cancel();\n sessionRef.current = null;\n dragRef.current = null;\n setDrag(null);\n }, [frameLoop]);\n\n const startDrag = useCallback(\n (item: PaletteItem, e: ReactPointerEvent) => {\n if (sessionRef.current) return;\n const next: DragState = { item, screenPos: { x: e.clientX, y: e.clientY }, feedback: null };\n dragRef.current = next;\n setDrag(next);\n sessionRef.current = openPointerSession(e.currentTarget, e, {\n onMove: (ev) => {\n const screenPos = { x: ev.clientX, y: ev.clientY };\n const current = dragRef.current;\n if (!current) return;\n if (pendingPos.current !== null) {\n // A frame is already queued: keep the ghost under the cursor and\n // let that frame probe the drop target from the newest position.\n pendingPos.current = screenPos;\n dragRef.current = { ...current, screenPos };\n setDrag(dragRef.current);\n return;\n }\n pendingPos.current = screenPos;\n frameLoop.request();\n },\n onEnd: (ev) => {\n const screenPos = { x: ev.clientX, y: ev.clientY };\n const active = dragRef.current;\n clearDrag();\n if (!active || !isOverCanvas(screenPos)) return;\n const world = screenToWorldFromContainer(screenPos);\n if (!world) return;\n const live = liveRef.current;\n live.setState(live.capability.onDrop(world, active.item, live.state, live.config));\n live.emit('canvas.itemAdded');\n },\n // An interrupted gesture never named a destination, so it drops nothing.\n onCancel: clearDrag,\n });\n },\n [clearDrag, frameLoop, isOverCanvas, screenToWorldFromContainer],\n );\n\n useEffect(() => () => sessionRef.current?.cancel(), []);\n\n return { drag, startDrag };\n}\n\nexport interface DragOverlayProps {\n drag: DragState | null;\n}\n\nexport function DragOverlay({ drag }: DragOverlayProps) {\n if (!drag) return null;\n return <DragGhost item={drag.item} screenPos={drag.screenPos} />;\n}\n","import type { PointerEvent as ReactPointerEvent } from 'react';\nimport type { PaletteItem } from '../instrument/types';\n\nexport interface PaletteProps {\n items: PaletteItem[];\n onDragStart: (item: PaletteItem, e: ReactPointerEvent) => void;\n className?: string;\n}\n\nexport function Palette({ items, onDragStart, className }: PaletteProps) {\n return (\n <div className={className ? `lk-palette ${className}` : 'lk-palette'}>\n {items.map((item) => (\n <button\n type=\"button\"\n key={item.id}\n className=\"lk-palette__item\"\n onPointerDown={(e) => {\n e.preventDefault();\n onDragStart(item, e);\n }}\n >\n <span className=\"lk-palette__label\">{item.label}</span>\n </button>\n ))}\n </div>\n );\n}\n"]}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { nextIndex } from './useRovingTabIndex';
|
|
3
|
-
|
|
4
|
-
describe('nextIndex', () => {
|
|
5
|
-
it('steps forward and wraps', () => {
|
|
6
|
-
expect(nextIndex(0, 'ArrowRight', 3)).toBe(1);
|
|
7
|
-
expect(nextIndex(2, 'ArrowRight', 3)).toBe(0);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('steps back and wraps', () => {
|
|
11
|
-
expect(nextIndex(1, 'ArrowLeft', 3)).toBe(0);
|
|
12
|
-
expect(nextIndex(0, 'ArrowLeft', 3)).toBe(2);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('jumps to the ends', () => {
|
|
16
|
-
expect(nextIndex(1, 'Home', 3)).toBe(0);
|
|
17
|
-
expect(nextIndex(1, 'End', 3)).toBe(2);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('returns null for a key it does not handle', () => {
|
|
21
|
-
expect(nextIndex(1, 'Enter', 3)).toBeNull();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('returns null when there is nothing to move to', () => {
|
|
25
|
-
expect(nextIndex(0, 'ArrowRight', 0)).toBeNull();
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe('nextIndex — vertical', () => {
|
|
30
|
-
it('walks the down/up arrows', () => {
|
|
31
|
-
expect(nextIndex(0, 'ArrowDown', 3, 'vertical')).toBe(1);
|
|
32
|
-
expect(nextIndex(2, 'ArrowDown', 3, 'vertical')).toBe(0);
|
|
33
|
-
expect(nextIndex(1, 'ArrowUp', 3, 'vertical')).toBe(0);
|
|
34
|
-
expect(nextIndex(0, 'ArrowUp', 3, 'vertical')).toBe(2);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('leaves the cross-axis arrows to the page', () => {
|
|
38
|
-
expect(nextIndex(0, 'ArrowRight', 3, 'vertical')).toBeNull();
|
|
39
|
-
expect(nextIndex(0, 'ArrowLeft', 3, 'vertical')).toBeNull();
|
|
40
|
-
expect(nextIndex(0, 'ArrowDown', 3)).toBeNull();
|
|
41
|
-
expect(nextIndex(0, 'ArrowUp', 3)).toBeNull();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('still jumps to the ends', () => {
|
|
45
|
-
expect(nextIndex(1, 'Home', 3, 'vertical')).toBe(0);
|
|
46
|
-
expect(nextIndex(1, 'End', 3, 'vertical')).toBe(2);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { type KeyboardEvent, useCallback, useEffect, useRef } from 'react';
|
|
2
|
-
|
|
3
|
-
/** Which axis a toolbar's arrow keys walk. Matches `aria-orientation`. */
|
|
4
|
-
export type RovingOrientation = 'horizontal' | 'vertical';
|
|
5
|
-
|
|
6
|
-
/** Where a key takes focus within `count` items, or null if it does not move it.
|
|
7
|
-
*
|
|
8
|
-
* Only the arrows on the toolbar's own axis move focus — APG leaves the
|
|
9
|
-
* cross-axis arrows to the page, so a vertical strip does not swallow
|
|
10
|
-
* ArrowLeft. `Home` / `End` work on both. */
|
|
11
|
-
export function nextIndex(
|
|
12
|
-
current: number,
|
|
13
|
-
key: string,
|
|
14
|
-
count: number,
|
|
15
|
-
orientation: RovingOrientation = 'horizontal',
|
|
16
|
-
): number | null {
|
|
17
|
-
if (count === 0) return null;
|
|
18
|
-
const forward = orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight';
|
|
19
|
-
const back = orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft';
|
|
20
|
-
if (key === forward) return (current + 1) % count;
|
|
21
|
-
if (key === back) return (current - 1 + count) % count;
|
|
22
|
-
if (key === 'Home') return 0;
|
|
23
|
-
if (key === 'End') return count - 1;
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The APG roving-tabindex contract: exactly one item in the tab order, arrows
|
|
29
|
-
* moving focus within. `tabIndex` is written onto the DOM nodes rather than
|
|
30
|
-
* threaded through props, because the items are arbitrary children — the
|
|
31
|
-
* container never sees them as a list it could index.
|
|
32
|
-
*/
|
|
33
|
-
export function useRovingTabIndex<T extends HTMLElement>(
|
|
34
|
-
orientation: RovingOrientation = 'horizontal',
|
|
35
|
-
) {
|
|
36
|
-
const ref = useRef<T | null>(null);
|
|
37
|
-
const stop = useRef(0);
|
|
38
|
-
|
|
39
|
-
const items = useCallback(
|
|
40
|
-
(): HTMLElement[] =>
|
|
41
|
-
ref.current
|
|
42
|
-
? Array.from(
|
|
43
|
-
ref.current.querySelectorAll<HTMLElement>('button:not([disabled]), [role="button"]'),
|
|
44
|
-
)
|
|
45
|
-
: [],
|
|
46
|
-
[],
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
const setTabStop = useCallback(
|
|
50
|
-
(index: number) => {
|
|
51
|
-
const found = items();
|
|
52
|
-
const at = Math.min(Math.max(index, 0), Math.max(found.length - 1, 0));
|
|
53
|
-
stop.current = at;
|
|
54
|
-
for (const [i, el] of found.entries()) el.tabIndex = i === at ? 0 : -1;
|
|
55
|
-
},
|
|
56
|
-
[items],
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
// Re-establish the tab stop whenever the item set changes — a trial's toolbar
|
|
60
|
-
// contributions are dynamic, and `disabled` moves a button in and out of the
|
|
61
|
-
// set without touching the child list. The focused item keeps the stop.
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
const resync = () => {
|
|
64
|
-
const focused = items().indexOf(document.activeElement as HTMLElement);
|
|
65
|
-
setTabStop(focused === -1 ? stop.current : focused);
|
|
66
|
-
};
|
|
67
|
-
resync();
|
|
68
|
-
if (!ref.current) return;
|
|
69
|
-
const mo = new MutationObserver(resync);
|
|
70
|
-
mo.observe(ref.current, { childList: true, subtree: true, attributeFilter: ['disabled'] });
|
|
71
|
-
return () => mo.disconnect();
|
|
72
|
-
}, [items, setTabStop]);
|
|
73
|
-
|
|
74
|
-
const onKeyDown = useCallback(
|
|
75
|
-
(e: KeyboardEvent<T>) => {
|
|
76
|
-
const found = items();
|
|
77
|
-
const current = found.indexOf(document.activeElement as HTMLElement);
|
|
78
|
-
const next = nextIndex(current === -1 ? 0 : current, e.key, found.length, orientation);
|
|
79
|
-
if (next === null) return;
|
|
80
|
-
e.preventDefault();
|
|
81
|
-
found[next]?.focus();
|
|
82
|
-
setTabStop(next);
|
|
83
|
-
},
|
|
84
|
-
[items, setTabStop, orientation],
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
return { ref, onKeyDown };
|
|
88
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@weasel-js/forge';
|
|
2
|
-
import { expect, userEvent, waitFor, within } from '@weasel-js/forge/play';
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
import { createIndexedDbAdapter } from './adapters';
|
|
5
|
-
import { Persistence } from './Persistence';
|
|
6
|
-
import { usePersistedState } from './usePersistedState';
|
|
7
|
-
|
|
8
|
-
// jsdom only has fake-indexeddb, an imitation. This round-trips a value through
|
|
9
|
-
// the browser's own IndexedDB: write it, unmount the provider so it closes,
|
|
10
|
-
// mount a fresh one, and read it back.
|
|
11
|
-
|
|
12
|
-
function Tab() {
|
|
13
|
-
const [tab, setTab] = usePersistedState('tab', 'shape');
|
|
14
|
-
return (
|
|
15
|
-
<p>
|
|
16
|
-
<output aria-label="tab">{tab}</output>
|
|
17
|
-
<button type="button" onClick={() => setTab('color')}>
|
|
18
|
-
choose color
|
|
19
|
-
</button>
|
|
20
|
-
</p>
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function Remountable({ database }: { database: string }) {
|
|
25
|
-
const [generation, setGeneration] = useState(0);
|
|
26
|
-
const [shown, setShown] = useState(true);
|
|
27
|
-
const storage = useState(() => createIndexedDbAdapter({ database }))[0];
|
|
28
|
-
return (
|
|
29
|
-
<div>
|
|
30
|
-
<button
|
|
31
|
-
type="button"
|
|
32
|
-
onClick={() => {
|
|
33
|
-
setShown(false);
|
|
34
|
-
// Past the provider's deferred close, which sends the queued write.
|
|
35
|
-
setTimeout(() => {
|
|
36
|
-
setGeneration((g) => g + 1);
|
|
37
|
-
setShown(true);
|
|
38
|
-
}, 100);
|
|
39
|
-
}}
|
|
40
|
-
>
|
|
41
|
-
remount
|
|
42
|
-
</button>
|
|
43
|
-
{shown ? (
|
|
44
|
-
<Persistence
|
|
45
|
-
key={generation}
|
|
46
|
-
storageKey="story"
|
|
47
|
-
storage={storage}
|
|
48
|
-
fallback={<p>loading</p>}
|
|
49
|
-
>
|
|
50
|
-
<Tab />
|
|
51
|
-
</Persistence>
|
|
52
|
-
) : null}
|
|
53
|
-
</div>
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const meta: Meta<typeof Remountable> = {
|
|
58
|
-
title: 'labkit/State/Persistence',
|
|
59
|
-
component: Remountable,
|
|
60
|
-
};
|
|
61
|
-
export default meta;
|
|
62
|
-
|
|
63
|
-
export const SurvivesARemountInIndexedDb: StoryObj<typeof Remountable> = {
|
|
64
|
-
args: { database: `labkit-story-${Date.now()}` },
|
|
65
|
-
play: async ({ canvasElement }) => {
|
|
66
|
-
const canvas = within(canvasElement);
|
|
67
|
-
await waitFor(() => expect(canvas.getByLabelText('tab').textContent).toBe('shape'));
|
|
68
|
-
await userEvent.click(canvas.getByText('choose color'));
|
|
69
|
-
await userEvent.click(canvas.getByText('remount'));
|
|
70
|
-
await waitFor(() => expect(canvas.queryByLabelText('tab')).toBeNull());
|
|
71
|
-
await waitFor(() => expect(canvas.getByLabelText('tab').textContent).toBe('color'), {
|
|
72
|
-
timeout: 3000,
|
|
73
|
-
});
|
|
74
|
-
},
|
|
75
|
-
};
|