@jbrowse/plugin-linear-genome-view 4.3.0 → 5.0.0-beta.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 (357) hide show
  1. package/esm/FeatureTrack/configSchema.d.ts +104 -65
  2. package/esm/FeatureTrack/configSchema.js +47 -1
  3. package/esm/FeatureTrack/index.js +1 -1
  4. package/esm/LaunchLinearGenomeView/index.d.ts +14 -0
  5. package/esm/LaunchLinearGenomeView/index.js +6 -12
  6. package/esm/LinearGenomeView/afterAttach.d.ts +20 -2
  7. package/esm/LinearGenomeView/afterAttach.js +250 -121
  8. package/esm/LinearGenomeView/components/CenterLine.d.ts +1 -1
  9. package/esm/LinearGenomeView/components/CenterLine.js +16 -7
  10. package/esm/LinearGenomeView/components/ConnectedHoverHighlight.d.ts +7 -0
  11. package/esm/LinearGenomeView/components/ConnectedHoverHighlight.js +22 -0
  12. package/esm/LinearGenomeView/components/CrisprGuidePanel.d.ts +3 -0
  13. package/esm/LinearGenomeView/components/CrisprGuidePanel.js +144 -0
  14. package/esm/LinearGenomeView/components/Cytobands.d.ts +6 -6
  15. package/esm/LinearGenomeView/components/Cytobands.js +76 -53
  16. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +7 -3
  17. package/esm/LinearGenomeView/components/ExportSvgDialog.js +11 -67
  18. package/esm/LinearGenomeView/components/GetSequenceDialog.d.ts +5 -9
  19. package/esm/LinearGenomeView/components/GetSequenceDialog.js +84 -88
  20. package/esm/LinearGenomeView/components/Gridlines.d.ts +1 -1
  21. package/esm/LinearGenomeView/components/Gridlines.js +29 -58
  22. package/esm/LinearGenomeView/components/Header.d.ts +1 -1
  23. package/esm/LinearGenomeView/components/Header.js +32 -16
  24. package/esm/LinearGenomeView/components/HeaderClearHighlightButton.d.ts +21 -0
  25. package/esm/LinearGenomeView/components/HeaderClearHighlightButton.js +35 -0
  26. package/esm/LinearGenomeView/components/HeaderPanControls.d.ts +3 -2
  27. package/esm/LinearGenomeView/components/HeaderPanControls.js +16 -7
  28. package/esm/LinearGenomeView/components/HeaderRegionWidth.d.ts +1 -1
  29. package/esm/LinearGenomeView/components/HeaderRegionWidth.js +9 -6
  30. package/esm/LinearGenomeView/components/HeaderSearchBoxRow.d.ts +6 -0
  31. package/esm/LinearGenomeView/components/HeaderSearchBoxRow.js +27 -0
  32. package/esm/LinearGenomeView/components/HeaderSearchBoxes.d.ts +5 -0
  33. package/esm/LinearGenomeView/components/HeaderSearchBoxes.js +28 -0
  34. package/esm/LinearGenomeView/components/HeaderTrackSelectorButton.d.ts +3 -2
  35. package/esm/LinearGenomeView/components/HeaderTrackSelectorButton.js +11 -4
  36. package/esm/LinearGenomeView/components/HeaderZoomControls.d.ts +3 -2
  37. package/esm/LinearGenomeView/components/HeaderZoomControls.js +67 -51
  38. package/esm/LinearGenomeView/components/Highlight.d.ts +1 -1
  39. package/esm/LinearGenomeView/components/Highlight.js +19 -23
  40. package/esm/LinearGenomeView/components/HighlightBand.d.ts +3 -2
  41. package/esm/LinearGenomeView/components/HighlightBand.js +25 -8
  42. package/esm/LinearGenomeView/components/HighlightChip.d.ts +9 -0
  43. package/esm/LinearGenomeView/components/HighlightChip.js +15 -0
  44. package/esm/LinearGenomeView/components/HoverPositionHighlight.d.ts +12 -0
  45. package/esm/LinearGenomeView/components/HoverPositionHighlight.js +25 -0
  46. package/esm/LinearGenomeView/components/ImportForm.d.ts +3 -4
  47. package/esm/LinearGenomeView/components/ImportForm.js +95 -61
  48. package/esm/LinearGenomeView/components/LinearGenomeView.d.ts +1 -1
  49. package/esm/LinearGenomeView/components/LinearGenomeView.js +6 -5
  50. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +1 -1
  51. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +89 -30
  52. package/esm/LinearGenomeView/components/MiniControls.d.ts +1 -1
  53. package/esm/LinearGenomeView/components/MiniControls.js +13 -10
  54. package/esm/LinearGenomeView/components/MotifListPanel.d.ts +3 -0
  55. package/esm/LinearGenomeView/components/MotifListPanel.js +59 -0
  56. package/esm/LinearGenomeView/components/NavigationAnnouncer.d.ts +32 -0
  57. package/esm/LinearGenomeView/components/NavigationAnnouncer.js +51 -0
  58. package/esm/LinearGenomeView/components/NoTracksActiveButton.d.ts +1 -1
  59. package/esm/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
  60. package/esm/LinearGenomeView/components/OverviewHighlight.d.ts +2 -4
  61. package/esm/LinearGenomeView/components/OverviewHighlight.js +23 -44
  62. package/esm/LinearGenomeView/components/OverviewHighlightBand.d.ts +9 -0
  63. package/esm/LinearGenomeView/components/OverviewHighlightBand.js +26 -0
  64. package/esm/LinearGenomeView/components/OverviewRubberband.d.ts +3 -3
  65. package/esm/LinearGenomeView/components/OverviewRubberband.js +44 -57
  66. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +4 -5
  67. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +13 -20
  68. package/esm/LinearGenomeView/components/OverviewScalebar.d.ts +3 -2
  69. package/esm/LinearGenomeView/components/OverviewScalebar.js +84 -79
  70. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +19 -5
  71. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +55 -32
  72. package/esm/LinearGenomeView/components/OverviewScalebarTickLabels.d.ts +4 -5
  73. package/esm/LinearGenomeView/components/OverviewScalebarTickLabels.js +16 -18
  74. package/esm/LinearGenomeView/components/PaddingBlocks.d.ts +7 -0
  75. package/esm/LinearGenomeView/components/PaddingBlocks.js +61 -0
  76. package/esm/LinearGenomeView/components/RangeSelectOverlay.d.ts +9 -0
  77. package/esm/LinearGenomeView/components/RangeSelectOverlay.js +20 -0
  78. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.d.ts +2 -3
  79. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +19 -26
  80. package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -1
  81. package/esm/LinearGenomeView/components/Rubberband.js +13 -16
  82. package/esm/LinearGenomeView/components/SVGHighlightBand.d.ts +10 -0
  83. package/esm/LinearGenomeView/components/SVGHighlightBand.js +9 -0
  84. package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -2
  85. package/esm/LinearGenomeView/components/Scalebar.js +16 -21
  86. package/esm/LinearGenomeView/components/ScalebarCoordinateLabels.d.ts +1 -1
  87. package/esm/LinearGenomeView/components/ScalebarCoordinateLabels.js +54 -35
  88. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.d.ts +1 -1
  89. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +142 -126
  90. package/esm/LinearGenomeView/components/SearchBox.d.ts +22 -2
  91. package/esm/LinearGenomeView/components/SearchBox.js +58 -66
  92. package/esm/LinearGenomeView/components/SearchPanelForm.d.ts +9 -0
  93. package/esm/LinearGenomeView/components/SearchPanelForm.js +18 -0
  94. package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +3 -3
  95. package/esm/LinearGenomeView/components/SearchResultsDialog.js +5 -7
  96. package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +4 -3
  97. package/esm/LinearGenomeView/components/SearchResultsTable.js +45 -53
  98. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.d.ts +5 -0
  99. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.js +37 -0
  100. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlightExtension.d.ts +2 -0
  101. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlightExtension.js +5 -0
  102. package/esm/LinearGenomeView/components/SequencePatternPanel.d.ts +3 -0
  103. package/esm/LinearGenomeView/components/SequencePatternPanel.js +42 -0
  104. package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +2 -2
  105. package/esm/LinearGenomeView/components/SequenceSearchDialog.js +31 -53
  106. package/esm/LinearGenomeView/components/StrandCheckboxes.d.ts +8 -0
  107. package/esm/LinearGenomeView/components/StrandCheckboxes.js +13 -0
  108. package/esm/LinearGenomeView/components/TrackContainer.d.ts +1 -1
  109. package/esm/LinearGenomeView/components/TrackContainer.js +83 -39
  110. package/esm/LinearGenomeView/components/TrackLabel.d.ts +2 -3
  111. package/esm/LinearGenomeView/components/TrackLabel.js +11 -24
  112. package/esm/LinearGenomeView/components/TrackLabelButtons.d.ts +7 -0
  113. package/esm/LinearGenomeView/components/TrackLabelButtons.js +33 -0
  114. package/esm/LinearGenomeView/components/TrackLabelDragHandle.d.ts +2 -5
  115. package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +6 -2
  116. package/esm/LinearGenomeView/components/TrackLabelMenu.d.ts +1 -1
  117. package/esm/LinearGenomeView/components/TrackLabelMenu.js +32 -85
  118. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.d.ts +22 -0
  119. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.js +46 -0
  120. package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +1 -1
  121. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +72 -18
  122. package/esm/LinearGenomeView/components/TracksContainer.d.ts +1 -1
  123. package/esm/LinearGenomeView/components/TracksContainer.js +65 -32
  124. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -1
  125. package/esm/LinearGenomeView/components/VerticalGuide.js +6 -13
  126. package/esm/LinearGenomeView/components/ZoomButton.d.ts +7 -0
  127. package/esm/LinearGenomeView/components/ZoomButton.js +27 -0
  128. package/esm/LinearGenomeView/components/ZoomTransform.d.ts +9 -0
  129. package/esm/LinearGenomeView/components/ZoomTransform.js +37 -0
  130. package/esm/LinearGenomeView/components/defaultMotifs.d.ts +1 -0
  131. package/esm/LinearGenomeView/components/defaultMotifs.js +22 -0
  132. package/esm/LinearGenomeView/components/fetchSequence.d.ts +7 -8
  133. package/esm/LinearGenomeView/components/fetchSequence.js +17 -9
  134. package/esm/LinearGenomeView/components/recentLocationsMenu.d.ts +15 -0
  135. package/esm/LinearGenomeView/components/recentLocationsMenu.js +36 -0
  136. package/esm/LinearGenomeView/components/searchModes.d.ts +13 -0
  137. package/esm/LinearGenomeView/components/searchModes.js +22 -0
  138. package/esm/LinearGenomeView/components/trackLabelMenuItems.d.ts +7 -0
  139. package/esm/LinearGenomeView/components/trackLabelMenuItems.js +67 -0
  140. package/esm/LinearGenomeView/components/useRangeSelect.d.ts +11 -66
  141. package/esm/LinearGenomeView/components/useRangeSelect.js +82 -91
  142. package/esm/LinearGenomeView/components/useSearchBoxPrefs.d.ts +26 -0
  143. package/esm/LinearGenomeView/components/useSearchBoxPrefs.js +58 -0
  144. package/esm/LinearGenomeView/components/useSideScroll.d.ts +1 -1
  145. package/esm/LinearGenomeView/components/useSideScroll.js +87 -19
  146. package/esm/LinearGenomeView/components/util.d.ts +20 -6
  147. package/esm/LinearGenomeView/components/util.js +27 -6
  148. package/esm/LinearGenomeView/consts.d.ts +7 -2
  149. package/esm/LinearGenomeView/consts.js +18 -2
  150. package/esm/LinearGenomeView/flyTo.d.ts +38 -0
  151. package/esm/LinearGenomeView/flyTo.js +135 -0
  152. package/esm/LinearGenomeView/headerFit.d.ts +27 -0
  153. package/esm/LinearGenomeView/headerFit.js +59 -0
  154. package/esm/LinearGenomeView/index.d.ts +32 -2
  155. package/esm/LinearGenomeView/index.js +16 -6
  156. package/esm/LinearGenomeView/initKeys.d.ts +12 -0
  157. package/esm/LinearGenomeView/initKeys.js +68 -0
  158. package/esm/LinearGenomeView/keyboardHandler.d.ts +7 -0
  159. package/esm/LinearGenomeView/keyboardHandler.js +10 -0
  160. package/esm/LinearGenomeView/launchKeys.d.ts +2 -0
  161. package/esm/LinearGenomeView/launchKeys.js +23 -0
  162. package/esm/LinearGenomeView/lazyDialogs.d.ts +7 -11
  163. package/esm/LinearGenomeView/lazyDialogs.js +3 -3
  164. package/esm/LinearGenomeView/linkedViewSync.d.ts +20 -0
  165. package/esm/LinearGenomeView/linkedViewSync.js +58 -0
  166. package/esm/LinearGenomeView/menuItems.d.ts +27 -2
  167. package/esm/LinearGenomeView/menuItems.js +137 -101
  168. package/esm/LinearGenomeView/model.d.ts +3238 -136
  169. package/esm/LinearGenomeView/model.js +2425 -528
  170. package/esm/LinearGenomeView/sharedScaleContainer.d.ts +18 -0
  171. package/esm/LinearGenomeView/sharedScaleContainer.js +17 -0
  172. package/esm/LinearGenomeView/showRegionsWithUndo.d.ts +35 -0
  173. package/esm/LinearGenomeView/showRegionsWithUndo.js +44 -0
  174. package/esm/LinearGenomeView/stickyChrome.d.ts +19 -0
  175. package/esm/LinearGenomeView/stickyChrome.js +30 -0
  176. package/esm/LinearGenomeView/svgcomponents/SVGGridlines.d.ts +1 -1
  177. package/esm/LinearGenomeView/svgcomponents/SVGGridlines.js +15 -16
  178. package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +2 -3
  179. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +45 -33
  180. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.d.ts +5 -0
  181. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +26 -0
  182. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.d.ts +5 -0
  183. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +13 -0
  184. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +1 -3
  185. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +77 -41
  186. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +1 -1
  187. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +23 -3
  188. package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.d.ts +8 -0
  189. package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.js +37 -0
  190. package/esm/LinearGenomeView/svgcomponents/SVGRuler.d.ts +3 -3
  191. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +64 -36
  192. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +1 -1
  193. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +7 -5
  194. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +5 -3
  195. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +43 -7
  196. package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +8 -14
  197. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +16 -21
  198. package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +18 -0
  199. package/esm/LinearGenomeView/svgcomponents/SVGView.js +13 -0
  200. package/esm/LinearGenomeView/svgcomponents/figureContract.d.ts +45 -0
  201. package/esm/LinearGenomeView/svgcomponents/figureContract.js +130 -0
  202. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +76 -0
  203. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +66 -0
  204. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.d.ts +70 -0
  205. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +263 -0
  206. package/esm/LinearGenomeView/svgcomponents/util.d.ts +92 -5
  207. package/esm/LinearGenomeView/svgcomponents/util.js +236 -3
  208. package/esm/LinearGenomeView/types.d.ts +17 -31
  209. package/esm/LinearGenomeView/types.js +1 -0
  210. package/esm/LinearGenomeView/util.d.ts +332 -12
  211. package/esm/LinearGenomeView/util.js +606 -62
  212. package/esm/MultiLevelRubberband/MultiLevelRubberband.d.ts +6 -0
  213. package/esm/MultiLevelRubberband/MultiLevelRubberband.js +37 -0
  214. package/esm/MultiLevelRubberband/VerticalGuide.d.ts +6 -0
  215. package/esm/MultiLevelRubberband/VerticalGuide.js +21 -0
  216. package/esm/MultiLevelRubberband/index.d.ts +2 -0
  217. package/esm/MultiLevelRubberband/index.js +1 -0
  218. package/esm/MultiLevelRubberband/types.d.ts +6 -0
  219. package/esm/MultiLevelRubberband/useRangeSelect.d.ts +24 -0
  220. package/esm/MultiLevelRubberband/useRangeSelect.js +136 -0
  221. package/esm/displayKitTests/perRegionTestEnv.d.ts +1286 -0
  222. package/esm/displayKitTests/perRegionTestEnv.js +138 -0
  223. package/esm/index.d.ts +122 -1235
  224. package/esm/index.js +101 -24
  225. package/esm/lazyPluginExports.d.ts +23 -0
  226. package/esm/lazyPluginExports.js +36 -0
  227. package/esm/searchUtils.d.ts +55 -11
  228. package/esm/searchUtils.js +342 -45
  229. package/esm/shared/RubberbandSpan.d.ts +15 -0
  230. package/esm/shared/RubberbandSpan.js +33 -0
  231. package/esm/shared/coordLabels.d.ts +40 -0
  232. package/esm/shared/coordLabels.js +119 -0
  233. package/package.json +18 -19
  234. package/esm/BaseLinearDisplay/SVGLegend.d.ts +0 -6
  235. package/esm/BaseLinearDisplay/SVGLegend.js +0 -17
  236. package/esm/BaseLinearDisplay/calculateSvgLegendWidth.d.ts +0 -2
  237. package/esm/BaseLinearDisplay/calculateSvgLegendWidth.js +0 -11
  238. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +0 -8
  239. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js +0 -53
  240. package/esm/BaseLinearDisplay/components/Block.d.ts +0 -14
  241. package/esm/BaseLinearDisplay/components/Block.js +0 -45
  242. package/esm/BaseLinearDisplay/components/BlockErrorMessage.d.ts +0 -7
  243. package/esm/BaseLinearDisplay/components/BlockErrorMessage.js +0 -22
  244. package/esm/BaseLinearDisplay/components/BlockMsg.d.ts +0 -6
  245. package/esm/BaseLinearDisplay/components/BlockMsg.js +0 -26
  246. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/CollapseIntronsDialog.d.ts +0 -9
  247. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/CollapseIntronsDialog.js +0 -42
  248. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/TranscriptTable.d.ts +0 -11
  249. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/TranscriptTable.js +0 -40
  250. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/util.d.ts +0 -19
  251. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/util.js +0 -45
  252. package/esm/BaseLinearDisplay/components/FloatingLabels.d.ts +0 -5
  253. package/esm/BaseLinearDisplay/components/FloatingLabels.js +0 -75
  254. package/esm/BaseLinearDisplay/components/FloatingLegend.d.ts +0 -8
  255. package/esm/BaseLinearDisplay/components/FloatingLegend.js +0 -43
  256. package/esm/BaseLinearDisplay/components/LinearBlocks.d.ts +0 -5
  257. package/esm/BaseLinearDisplay/components/LinearBlocks.js +0 -23
  258. package/esm/BaseLinearDisplay/components/LoadingOverlay.d.ts +0 -5
  259. package/esm/BaseLinearDisplay/components/LoadingOverlay.js +0 -49
  260. package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.d.ts +0 -4
  261. package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.js +0 -26
  262. package/esm/BaseLinearDisplay/components/MenuPage.d.ts +0 -8
  263. package/esm/BaseLinearDisplay/components/MenuPage.js +0 -24
  264. package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.d.ts +0 -21
  265. package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.js +0 -52
  266. package/esm/BaseLinearDisplay/components/RenderedBlocks.d.ts +0 -12
  267. package/esm/BaseLinearDisplay/components/RenderedBlocks.js +0 -22
  268. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.d.ts +0 -12
  269. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +0 -18
  270. package/esm/BaseLinearDisplay/components/TooLargeMessage.d.ts +0 -10
  271. package/esm/BaseLinearDisplay/components/TooLargeMessage.js +0 -20
  272. package/esm/BaseLinearDisplay/components/Tooltip.d.ts +0 -13
  273. package/esm/BaseLinearDisplay/components/Tooltip.js +0 -22
  274. package/esm/BaseLinearDisplay/components/types.d.ts +0 -1
  275. package/esm/BaseLinearDisplay/components/util.d.ts +0 -21
  276. package/esm/BaseLinearDisplay/components/util.js +0 -107
  277. package/esm/BaseLinearDisplay/index.d.ts +0 -17
  278. package/esm/BaseLinearDisplay/index.js +0 -13
  279. package/esm/BaseLinearDisplay/model.d.ts +0 -1197
  280. package/esm/BaseLinearDisplay/model.js +0 -432
  281. package/esm/BaseLinearDisplay/models/FeatureDensityMixin.d.ts +0 -32
  282. package/esm/BaseLinearDisplay/models/FeatureDensityMixin.js +0 -113
  283. package/esm/BaseLinearDisplay/models/NonBlockCanvasDisplayMixin.d.ts +0 -26
  284. package/esm/BaseLinearDisplay/models/NonBlockCanvasDisplayMixin.js +0 -57
  285. package/esm/BaseLinearDisplay/models/SvgFloatingLabels.d.ts +0 -8
  286. package/esm/BaseLinearDisplay/models/SvgFloatingLabels.js +0 -19
  287. package/esm/BaseLinearDisplay/models/TrackHeightMixin.d.ts +0 -11
  288. package/esm/BaseLinearDisplay/models/TrackHeightMixin.js +0 -31
  289. package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.d.ts +0 -2
  290. package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.js +0 -29
  291. package/esm/BaseLinearDisplay/models/configSchema.d.ts +0 -29
  292. package/esm/BaseLinearDisplay/models/configSchema.js +0 -33
  293. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +0 -98
  294. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -242
  295. package/esm/BaseLinearDisplay/models/util.d.ts +0 -9
  296. package/esm/BaseLinearDisplay/models/util.js +0 -43
  297. package/esm/BaseLinearDisplay/renderSvg.d.ts +0 -3
  298. package/esm/BaseLinearDisplay/renderSvg.js +0 -63
  299. package/esm/BaseLinearDisplay/types.d.ts +0 -43
  300. package/esm/BaseLinearDisplay/types.js +0 -3
  301. package/esm/BaseLinearDisplay/util.d.ts +0 -16
  302. package/esm/BaseLinearDisplay/util.js +0 -71
  303. package/esm/BasicTrack/configSchema.d.ts +0 -85
  304. package/esm/BasicTrack/configSchema.js +0 -8
  305. package/esm/BasicTrack/index.d.ts +0 -2
  306. package/esm/BasicTrack/index.js +0 -12
  307. package/esm/LinearBareDisplay/configSchema.d.ts +0 -32
  308. package/esm/LinearBareDisplay/configSchema.js +0 -11
  309. package/esm/LinearBareDisplay/index.d.ts +0 -4
  310. package/esm/LinearBareDisplay/index.js +0 -20
  311. package/esm/LinearBareDisplay/model.d.ts +0 -1196
  312. package/esm/LinearBareDisplay/model.js +0 -32
  313. package/esm/LinearBasicDisplay/components/LinearBasicDisplayComponent.d.ts +0 -5
  314. package/esm/LinearBasicDisplay/components/LinearBasicDisplayComponent.js +0 -9
  315. package/esm/LinearBasicDisplay/configSchema.d.ts +0 -32
  316. package/esm/LinearBasicDisplay/configSchema.js +0 -11
  317. package/esm/LinearBasicDisplay/index.d.ts +0 -4
  318. package/esm/LinearBasicDisplay/index.js +0 -20
  319. package/esm/LinearBasicDisplay/model.d.ts +0 -1391
  320. package/esm/LinearBasicDisplay/model.js +0 -158
  321. package/esm/LinearFeatureDisplay/components/AddFiltersDialog.d.ts +0 -9
  322. package/esm/LinearFeatureDisplay/components/AddFiltersDialog.js +0 -58
  323. package/esm/LinearFeatureDisplay/components/SetMaxHeightDialog.d.ts +0 -8
  324. package/esm/LinearFeatureDisplay/components/SetMaxHeightDialog.js +0 -26
  325. package/esm/LinearFeatureDisplay/configSchema.d.ts +0 -32
  326. package/esm/LinearFeatureDisplay/configSchema.js +0 -11
  327. package/esm/LinearFeatureDisplay/index.d.ts +0 -3
  328. package/esm/LinearFeatureDisplay/index.js +0 -2
  329. package/esm/LinearFeatureDisplay/model.d.ts +0 -1443
  330. package/esm/LinearFeatureDisplay/model.js +0 -305
  331. package/esm/LinearGenomeView/SVGErrorBox.d.ts +0 -5
  332. package/esm/LinearGenomeView/SVGErrorBox.js +0 -4
  333. package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.d.ts +0 -11
  334. package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +0 -27
  335. package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.d.ts +0 -5
  336. package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +0 -13
  337. package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.d.ts +0 -3
  338. package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +0 -17
  339. package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.d.ts +0 -3
  340. package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +0 -8
  341. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +0 -16
  342. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +0 -101
  343. package/esm/LinearGenomeView/components/RefNameAutocomplete/util.d.ts +0 -10
  344. package/esm/LinearGenomeView/components/RefNameAutocomplete/util.js +0 -45
  345. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +0 -15
  346. package/esm/LinearGenomeView/components/RubberbandSpan.js +0 -32
  347. package/esm/LinearGenomeView/components/RubberbandTooltip.d.ts +0 -5
  348. package/esm/LinearGenomeView/components/RubberbandTooltip.js +0 -17
  349. package/esm/LinearGenomeView/components/TrackLabelContainer.d.ts +0 -8
  350. package/esm/LinearGenomeView/components/TrackLabelContainer.js +0 -25
  351. package/esm/LinearGenomeView/components/useWheelScroll.d.ts +0 -7
  352. package/esm/LinearGenomeView/components/useWheelScroll.js +0 -69
  353. package/esm/LinearGenomeView/svgExportUtil.d.ts +0 -9
  354. package/esm/LinearGenomeView/svgExportUtil.js +0 -6
  355. package/esm/LinearGenomeView/svgcomponents/SVGBackground.d.ts +0 -5
  356. package/esm/LinearGenomeView/svgcomponents/SVGBackground.js +0 -7
  357. /package/esm/{BaseLinearDisplay/components → MultiLevelRubberband}/types.js +0 -0
@@ -0,0 +1,12 @@
1
+ import type { LinearGenomeViewModel } from '../model.ts';
2
+ export interface HoverHighlightPosition {
3
+ refName: string;
4
+ start: number;
5
+ end: number;
6
+ assemblyName?: string;
7
+ }
8
+ declare const HoverPositionHighlight: ({ model, position, }: {
9
+ model: LinearGenomeViewModel;
10
+ position: HoverHighlightPosition;
11
+ }) => import("react").JSX.Element | null;
12
+ export default HoverPositionHighlight;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { alpha } from '@jbrowse/core/ui/palette';
3
+ import { makeStyles } from '@jbrowse/core/util/tss-react';
4
+ import { observer } from 'mobx-react';
5
+ const useStyles = makeStyles()(theme => ({
6
+ highlight: {
7
+ height: '100%',
8
+ position: 'absolute',
9
+ background: alpha(theme.palette.primary.main, 0.4),
10
+ borderLeft: `2px solid ${theme.palette.primary.main}`,
11
+ borderRight: `2px solid ${theme.palette.primary.main}`,
12
+ pointerEvents: 'none',
13
+ zIndex: 10,
14
+ },
15
+ }));
16
+ // Renders one crosshair box on the LGV for a hovered genomic interval, or
17
+ // nothing if the interval is off-screen. Shared by the widgets that publish a
18
+ // hover position (e.g. the feature-detail sequence panel and the MAF sequence
19
+ // widget).
20
+ const HoverPositionHighlight = observer(function HoverPositionHighlight({ model, position, }) {
21
+ const { classes } = useStyles();
22
+ const coords = model.getHighlightCoords(position);
23
+ return coords ? (_jsx("div", { className: classes.highlight, style: { left: coords.left, width: coords.width } })) : null;
24
+ });
25
+ export default HoverPositionHighlight;
@@ -1,6 +1,5 @@
1
1
  import type { LinearGenomeViewModel } from '../index.ts';
2
- type LGV = LinearGenomeViewModel;
3
- declare const LinearGenomeViewImportForm: ({ model }: {
4
- model: LGV;
5
- }) => import("react/jsx-runtime").JSX.Element;
2
+ declare const LinearGenomeViewImportForm: ({ model, }: {
3
+ model: LinearGenomeViewModel;
4
+ }) => import("react").JSX.Element;
6
5
  export default LinearGenomeViewImportForm;
@@ -1,77 +1,111 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
3
- import { AssemblySelector, ErrorMessage } from '@jbrowse/core/ui';
2
+ import { useState } from 'react';
3
+ import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
4
+ import { AssemblySelector, ErrorBanner, RefNameAutocomplete, RefNameAutocompleteEndAdornment, adornmentReservePx, useAssemblySelection, useRecentLocations, } from '@jbrowse/core/ui';
4
5
  import { getSession } from '@jbrowse/core/util';
5
6
  import { makeStyles } from '@jbrowse/core/util/tss-react';
6
7
  import CloseIcon from '@mui/icons-material/Close';
7
- import { Button, CircularProgress, Container, FormControl, Grid as Grid, } from '@mui/material';
8
+ import { Button, CircularProgress, Container, Grid } from '@mui/material';
8
9
  import { observer } from 'mobx-react';
9
- import ImportFormRefNameAutocomplete from "./ImportFormRefNameAutocomplete.js";
10
- import { handleSelectedRegion, navToOption } from "../../searchUtils.js";
10
+ import { fetchResults, navigateToSelectedOption, notifySearchFailure, } from '../../searchUtils.js';
11
+ import { recentLocationOf, recentLocationsMenu } from './recentLocationsMenu.js';
11
12
  const useStyles = makeStyles()(theme => ({
12
13
  importFormContainer: {
13
- padding: theme.spacing(2),
14
+ padding: theme.spacing(4),
14
15
  },
15
16
  button: {
16
17
  margin: theme.spacing(2),
17
18
  },
18
- container: {
19
- padding: theme.spacing(4),
20
- },
21
19
  }));
22
- const LinearGenomeViewImportForm = observer(function LinearGenomeViewImportForm({ model }) {
20
+ const LinearGenomeViewImportForm = observer(function LinearGenomeViewImportForm({ model, }) {
23
21
  const { classes } = useStyles();
24
22
  const session = getSession(model);
25
- const { assemblyNames, assemblyManager } = session;
26
- const { initialized, error } = model;
27
- const [selectedAsm, setSelectedAsm] = useState(assemblyNames[0]);
28
- const [option, setOption] = useState();
29
- const assembly = assemblyManager.get(selectedAsm);
30
- const assemblyError = assemblyNames.length
31
- ? assembly?.error
32
- : 'No configured assemblies';
33
- const displayError = assemblyError || error;
34
- const [value, setValue] = useState('');
35
- const regions = assembly?.regions;
36
- const assemblyLoaded = !!regions;
37
- const r0 = regions ? regions[0]?.refName || '' : '';
38
- useEffect(() => {
39
- setValue(r0);
40
- }, [r0, selectedAsm]);
41
- return (_jsxs("div", { className: classes.container, children: [displayError ? _jsx(ErrorMessage, { error: displayError }) : null, initialized ? (_jsx(Container, { className: classes.importFormContainer, children: _jsx("form", { onSubmit: async (event) => {
42
- event.preventDefault();
43
- model.setError(undefined);
44
- if (value) {
45
- try {
46
- if (option?.getDisplayString() === value &&
47
- option.hasLocation()) {
48
- await navToOption({
49
- option,
50
- model,
51
- assemblyName: selectedAsm,
52
- });
53
- }
54
- else if (option?.results?.length) {
55
- model.setSearchResults(option.results, option.getLabel(), selectedAsm);
56
- }
57
- else if (assembly) {
58
- await handleSelectedRegion({
59
- input: value,
60
- assembly,
61
- model,
62
- });
63
- }
64
- }
65
- catch (e) {
66
- console.error(e);
67
- session.notify(`${e}`, 'warning');
68
- }
69
- }
70
- }, children: _jsxs(Grid, { container: true, spacing: 1, justifyContent: "center", alignItems: "center", children: [_jsx(FormControl, { children: _jsx(AssemblySelector, { onChange: val => {
71
- setSelectedAsm(val);
72
- }, localStorageKey: "lgv", session: session, selected: selectedAsm }) }), selectedAsm ? (assemblyError ? (_jsx(CloseIcon, { style: { color: 'red' } })) : assemblyLoaded ? (_jsx(FormControl, { children: _jsx(ImportFormRefNameAutocomplete, { value: value, setValue: setValue, selectedAsm: selectedAsm, setOption: setOption, model: model }) })) : (_jsx(CircularProgress, { size: 20, disableShrink: true }))) : null, _jsx(FormControl, { children: _jsx(Button, { type: "submit", disabled: !value, className: classes.button, variant: "contained", color: "primary", children: "Open" }) }), _jsx(FormControl, { children: _jsx(Button, { disabled: !value, className: classes.button, onClick: () => {
73
- model.setError(undefined);
74
- model.showAllRegionsInAssembly(selectedAsm);
75
- }, variant: "contained", color: "secondary", children: "Show all regions in assembly" }) })] }) }) })) : null] }));
23
+ const { textSearchManager } = session;
24
+ const { error: viewError } = model;
25
+ const { selectedAssemblyName: selectedAsm, setSelectedAssemblyName, assembly, assemblyError, regions, } = useAssemblySelection(session, 'lgv');
26
+ const { recentLocations, addRecentLocation, clearRecentLocations } = useRecentLocations(selectedAsm);
27
+ // The location the form will open, tagged with the assembly it was entered
28
+ // for, and read back only while that tag still matches. Switching assembly
29
+ // then drops it structurally — nothing has to remember to clear it — which
30
+ // is the shape `useAssemblySelection` already uses for the assembly choice
31
+ // itself ("stored as an override, re-resolved against the live list every
32
+ // render") and the breakpoint form uses for its shared track. One object
33
+ // rather than a text/option pair for the same reason: they are only ever
34
+ // valid together, and as two useStates every write had to remember to reset
35
+ // the other.
36
+ //
37
+ // Undefined means "nothing entered yet", which is what makes the box fall
38
+ // back to the first refname below and keeps that default out of the recent
39
+ // locations list.
40
+ const [entered, setEntered] = useState();
41
+ const current = entered?.assemblyName === selectedAsm ? entered : undefined;
42
+ const value = current?.text ?? regions?.[0]?.refName ?? '';
43
+ const displayError = assemblyError ?? viewError;
44
+ async function navigate({ option, record, }) {
45
+ model.setError(undefined);
46
+ if (selectedAsm) {
47
+ try {
48
+ await navigateToSelectedOption({
49
+ option,
50
+ model,
51
+ assemblyName: selectedAsm,
52
+ });
53
+ if (record) {
54
+ addRecentLocation(recentLocationOf(option));
55
+ }
56
+ }
57
+ catch (e) {
58
+ notifySearchFailure(session, e);
59
+ }
60
+ }
61
+ }
62
+ const recentMenuItems = recentLocationsMenu({
63
+ recentLocations,
64
+ onNavigate: option => {
65
+ navigate({ option, record: true }).catch(() => { });
66
+ },
67
+ onClear: clearRecentLocations,
68
+ });
69
+ return (_jsxs(Container, { className: classes.importFormContainer, "data-testid": "import-form", children: [displayError ? _jsx(ErrorBanner, { error: displayError }) : null, _jsx("form", { onSubmit: async (event) => {
70
+ event.preventDefault();
71
+ if (value) {
72
+ await navigate({
73
+ option: current?.option ?? new BaseResult({ label: value }),
74
+ record: current !== undefined,
75
+ });
76
+ }
77
+ }, children: _jsxs(Grid, { container: true, spacing: 1, sx: { justifyContent: 'center', alignItems: 'center' }, children: [_jsx(AssemblySelector, { onChange: val => {
78
+ // Only the model's error needs clearing by hand: it lives
79
+ // outside React and is not tagged with the assembly it was
80
+ // about. The typed location isn't reset here — `entered` is
81
+ // tagged, so it drops itself. The banner reports the previous
82
+ // assembly's failure (that is why the form is up at all), so it
83
+ // has to go with it; the circular form clears here for the same
84
+ // reason.
85
+ model.setError(undefined);
86
+ setSelectedAssemblyName(val);
87
+ }, session: session, selected: selectedAsm }), selectedAsm ? (assemblyError ? (_jsx(CloseIcon, { color: "error" })) : regions ? (_jsx(RefNameAutocomplete, { fetchResults: (queryString, stopToken) => fetchResults({
88
+ queryString,
89
+ assembly,
90
+ textSearchManager,
91
+ assemblyName: selectedAsm,
92
+ stopToken,
93
+ }), session: session, assemblyName: selectedAsm, value: value, minWidth: 270, adornmentWidth: adornmentReservePx({
94
+ menuItemCount: recentMenuItems.length,
95
+ }), onChange: v => {
96
+ // no `option` on the new object, so typing over a picked
97
+ // search result discards it rather than opening the old
98
+ // one's location under the new text
99
+ setEntered({ assemblyName: selectedAsm, text: v });
100
+ }, onSelect: opt => {
101
+ setEntered({
102
+ assemblyName: selectedAsm,
103
+ text: opt.getDisplayString(),
104
+ option: opt,
105
+ });
106
+ }, endAdornment: _jsx(RefNameAutocompleteEndAdornment, { menuItems: recentMenuItems }), helperText: "Enter sequence name, feature name, or location" })) : (_jsx(CircularProgress, { size: 20, disableShrink: true }))) : null, _jsx(Button, { type: "submit", disabled: !value, className: classes.button, variant: "contained", color: "primary", children: "Open" }), _jsx(Button, { disabled: !!assemblyError || !regions, className: classes.button, onClick: () => {
107
+ model.setError(undefined);
108
+ model.showAllRegionsInAssembly(selectedAsm);
109
+ }, variant: "contained", color: "secondary", children: "Show all regions in assembly" })] }) })] }));
76
110
  });
77
111
  export default LinearGenomeViewImportForm;
@@ -1,5 +1,5 @@
1
1
  import type { LinearGenomeViewModel } from '../index.ts';
2
2
  declare const LinearGenomeView: ({ model, }: {
3
3
  model: LinearGenomeViewModel;
4
- }) => import("react/jsx-runtime").JSX.Element;
4
+ }) => import("react").JSX.Element;
5
5
  export default LinearGenomeView;
@@ -1,13 +1,14 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { lazy } from 'react';
3
- import { LoadingEllipses } from '@jbrowse/core/ui';
3
+ import { ViewLoadingScreen } from '@jbrowse/core/ui';
4
4
  import { observer } from 'mobx-react';
5
- import LinearGenomeViewContainer from "./LinearGenomeViewContainer.js";
6
- const ImportForm = lazy(() => import("./ImportForm.js"));
5
+ import LinearGenomeViewContainer from './LinearGenomeViewContainer.js';
6
+ // lazies
7
+ const ImportForm = lazy(() => import('./ImportForm.js'));
7
8
  const LinearGenomeView = observer(function LinearGenomeView({ model, }) {
8
- const { showLoading, showImportForm, loadingMessage } = model;
9
+ const { showLoading, showImportForm, loadingMessage, loadingProgress } = model;
9
10
  if (showLoading) {
10
- return _jsx(LoadingEllipses, { variant: "h6", message: loadingMessage });
11
+ return (_jsx(ViewLoadingScreen, { message: loadingMessage, fraction: loadingProgress, source: model.loadingSource }));
11
12
  }
12
13
  else if (showImportForm) {
13
14
  return _jsx(ImportForm, { model: model });
@@ -1,5 +1,5 @@
1
1
  import type { LinearGenomeViewModel } from '../index.ts';
2
2
  declare const LinearGenomeViewContainer: ({ model, }: {
3
3
  model: LinearGenomeViewModel;
4
- }) => import("react/jsx-runtime").JSX.Element;
4
+ }) => import("react").JSX.Element;
5
5
  export default LinearGenomeViewContainer;
@@ -1,59 +1,118 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Suspense, lazy, useEffect, useRef } from 'react';
3
3
  import { VIEW_HEADER_HEIGHT } from '@jbrowse/core/ui';
4
4
  import { getSession } from '@jbrowse/core/util';
5
+ import { LGV_HEADER_HEIGHT_VAR, SCROLL_PORT_HEIGHT_VAR, VIEW_HEADER_HEIGHT_VAR, useChromeHeightVar, useFocusOnInteraction, } from '@jbrowse/core/util/hooks';
5
6
  import { makeStyles } from '@jbrowse/core/util/tss-react';
7
+ import { useWheelZoom } from '@jbrowse/core/util/usePanZoom';
6
8
  import Paper from '@mui/material/Paper';
7
9
  import { observer } from 'mobx-react';
8
- import TrackContainer from "./TrackContainer.js";
9
- import TracksContainer from "./TracksContainer.js";
10
- const NoTracksActiveButton = lazy(() => import("./NoTracksActiveButton.js"));
10
+ import { SCALE_BAR_HEIGHT } from '../consts.js';
11
+ import { stickyChromeTops } from '../stickyChrome.js';
12
+ import Header from './Header.js';
13
+ import MiniControls from './MiniControls.js';
14
+ import NavigationAnnouncer from './NavigationAnnouncer.js';
15
+ import Rubberband from './Rubberband.js';
16
+ import Scalebar from './Scalebar.js';
17
+ import TrackContainer from './TrackContainer.js';
18
+ import TracksContainer from './TracksContainer.js';
19
+ // lazies
20
+ const NoTracksActiveButton = lazy(() => import('./NoTracksActiveButton.js'));
11
21
  const useStyles = makeStyles()(theme => ({
12
22
  header: {
13
23
  background: theme.palette.background.paper,
14
- top: VIEW_HEADER_HEIGHT,
24
+ // measured, with the constant as the fallback: the view header above is a
25
+ // minimum-height box that grows with its content, so summing constants
26
+ // here put this over the bottom of it at a larger root font size
27
+ top: `var(${VIEW_HEADER_HEIGHT_VAR}, ${VIEW_HEADER_HEIGHT}px)`,
15
28
  zIndex: 850,
16
29
  },
17
30
  pinnedTracks: {
18
31
  position: 'sticky',
19
32
  zIndex: 3,
33
+ // cap the sticky block at the space below its top offset so pinning
34
+ // many/tall tracks scrolls within the block instead of burying the
35
+ // unpinned tracks underneath it — see the maxHeight below for which space
36
+ overflowY: 'auto',
20
37
  },
21
38
  rel: {
22
39
  position: 'relative',
23
40
  },
24
41
  }));
25
42
  const LinearGenomeViewContainer = observer(function LinearGenomeViewContainer({ model, }) {
26
- const { pinnedTracks, stickyViewHeaders, pinnedTracksTop, tracks, unpinnedTracks, } = model;
43
+ const { pinnedTracks, stickyViewHeaders, headerHeight, tracks, unpinnedTracks, hideHeader, } = model;
44
+ const stickyTops = stickyChromeTops({ stickyViewHeaders, headerHeight });
45
+ const headerRef = useRef(null);
46
+ useChromeHeightVar(headerRef, LGV_HEADER_HEIGHT_VAR);
27
47
  const { classes } = useStyles();
28
48
  const session = getSession(model);
29
49
  const ref = useRef(null);
30
- const MiniControlsComponent = model.MiniControlsComponent();
31
- const HeaderComponent = model.HeaderComponent();
50
+ // cached left edge of the view, refreshed on resize, so the mousemove hover
51
+ // handler doesn't call getBoundingClientRect() (a layout reflow) every move
52
+ const rectLeftRef = useRef(0);
53
+ // The tracks area, and not the whole view — the same rule the click-drag half
54
+ // already follows (see TracksContainer's useSideScroll), for a bigger payoff.
55
+ // The chrome above the tracks is the only surface left where a wheel still
56
+ // means "move down the page": the view header is `position: sticky`, so
57
+ // binding the gesture below it leaves ~100px of always-visible gutter that
58
+ // scrolls, instead of the ~26px of view title bar that is all a full-view
59
+ // binding leaves. That gutter is the whole answer for scroll-to-zoom users,
60
+ // because there is no modifier to fall back on — the browser turns shift into
61
+ // horizontal scroll, ctrl/meta is pinch-zoom, and Firefox binds alt to
62
+ // history navigation.
63
+ //
64
+ // Nothing is lost by it: a wheel over the toolbar used to zoom the view from
65
+ // a point that shows none of it. `wheelBinding.test.tsx` is the pin — which
66
+ // element the listener is on is a DOM fact, so jsdom sees it exactly;
67
+ // `browser-tests/probe-scroll-gutter.ts` measures how many pixels wide the
68
+ // resulting band is, which is the part that needs a real layout and runs by
69
+ // hand.
70
+ const tracksRef = useRef(null);
71
+ useWheelZoom(tracksRef, model);
32
72
  useEffect(() => {
33
- function handleSelectView(e) {
34
- if (e.target instanceof Element && ref.current?.contains(e.target)) {
35
- session.setFocusedViewId?.(model.id);
36
- }
73
+ const curr = ref.current;
74
+ if (!curr) {
75
+ return;
37
76
  }
38
- document.addEventListener('mousedown', handleSelectView);
39
- document.addEventListener('keydown', handleSelectView);
77
+ rectLeftRef.current = curr.getBoundingClientRect().left;
78
+ const observer = 'ResizeObserver' in window
79
+ ? new ResizeObserver(() => {
80
+ rectLeftRef.current = curr.getBoundingClientRect().left;
81
+ })
82
+ : undefined;
83
+ observer?.observe(curr);
40
84
  return () => {
41
- document.removeEventListener('mousedown', handleSelectView);
42
- document.removeEventListener('keydown', handleSelectView);
85
+ observer?.disconnect();
43
86
  };
44
- }, [session, model]);
45
- return (_jsxs("div", { className: classes.rel, ref: ref, onMouseLeave: () => {
46
- session.setHovered(undefined);
47
- }, onMouseMove: event => {
48
- const c = ref.current;
49
- if (!c) {
50
- return;
51
- }
52
- const { tracks } = model;
53
- const leftPx = event.clientX - c.getBoundingClientRect().left;
54
- const hoverPosition = model.pxToBp(leftPx);
55
- const hoverFeature = tracks.find(t => t.displays[0].featureUnderMouse);
56
- session.setHovered({ hoverPosition, hoverFeature });
57
- }, children: [_jsxs("div", { className: classes.header, style: { position: stickyViewHeaders ? 'sticky' : undefined }, children: [_jsx(HeaderComponent, { model: model }), _jsx(MiniControlsComponent, { model: model })] }), _jsx(TracksContainer, { model: model, children: !tracks.length ? (_jsx(Suspense, { fallback: null, children: _jsx(NoTracksActiveButton, { model: model }) })) : (_jsxs(_Fragment, { children: [pinnedTracks.length ? (_jsx(Paper, { elevation: 6, className: classes.pinnedTracks, style: { top: pinnedTracksTop }, children: pinnedTracks.map(track => (_jsx(TrackContainer, { model: model, track: track }, track.id))) })) : null, unpinnedTracks.map(track => (_jsx(TrackContainer, { model: model, track: track }, track.id)))] })) })] }));
87
+ }, []);
88
+ // sets the focused view id based on a click within the LGV; necessary for
89
+ // subviews to be focused properly
90
+ useFocusOnInteraction(ref, () => {
91
+ session.setFocusedViewId?.(model.id);
92
+ });
93
+ return (_jsx(_Fragment, { children: _jsxs("div", { "data-testid": `linear-genome-view-${model.id}`, className: classes.rel, ref: ref, onMouseLeave: () => {
94
+ session.setHovered(undefined);
95
+ }, onMouseMove: event => {
96
+ const leftPx = event.clientX - rectLeftRef.current;
97
+ const hoverPosition = model.pxToBp(leftPx);
98
+ // `hoveredFeature` is BaseDisplay's hook, so every display type
99
+ // answers it — this used to read `featureUnderMouse`, a name only the
100
+ // wiggle, alignments and Manhattan families used, off `displays[0]`
101
+ // alone. At most one display can be under the pointer, so the first
102
+ // non-empty answer is the answer.
103
+ const hoverFeature = tracks
104
+ .flatMap(t => t.displays)
105
+ .map(d => d.hoveredFeature)
106
+ .find(Boolean);
107
+ session.setHovered({ hoverPosition, hoverFeature });
108
+ }, children: [_jsx(NavigationAnnouncer, { model: model }), _jsxs("div", { ref: headerRef, className: classes.header, style: { position: stickyViewHeaders ? 'sticky' : undefined }, children: [_jsx(Header, { model: model }), hideHeader ? _jsx(MiniControls, { model: model }) : null] }), _jsx("div", { ref: tracksRef, children: model.scalebarOnly ? (_jsx(Rubberband, { model: model, ControlComponent: _jsx(Scalebar, { model: model, style: { height: SCALE_BAR_HEIGHT, boxSizing: 'border-box' } }) })) : (_jsx(TracksContainer, { model: model, children: !tracks.length ? (_jsx(Suspense, { fallback: null, children: _jsx(NoTracksActiveButton, { model: model }) })) : (_jsxs(_Fragment, { children: [pinnedTracks.length ? (_jsx(Paper, { elevation: 6, className: classes.pinnedTracks, style: {
109
+ top: stickyTops.pinnedTracks,
110
+ // the scroll port this sticks in, not the window: it is
111
+ // under the app bar in the classic stack, a dockview
112
+ // cell in a workspace, and the host's box when embedded.
113
+ // The fallback is what an unbounded embed gets, where
114
+ // the page itself is the scroller
115
+ maxHeight: `calc(var(${SCROLL_PORT_HEIGHT_VAR}, 100vh) - ${stickyTops.pinnedTracks})`,
116
+ }, children: pinnedTracks.map(track => (_jsx(TrackContainer, { model: model, track: track }, track.id))) })) : null, unpinnedTracks.map(track => (_jsx(TrackContainer, { model: model, track: track }, track.id)))] })) })) })] }) }));
58
117
  });
59
118
  export default LinearGenomeViewContainer;
@@ -1,5 +1,5 @@
1
1
  import type { LinearGenomeViewModel } from '../index.ts';
2
2
  declare const MiniControls: ({ model, }: {
3
3
  model: LinearGenomeViewModel;
4
- }) => import("react/jsx-runtime").JSX.Element | null;
4
+ }) => import("react").JSX.Element;
5
5
  export default MiniControls;
@@ -1,17 +1,20 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
3
+ import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons';
3
4
  import { getSession } from '@jbrowse/core/util';
4
5
  import { makeStyles } from '@jbrowse/core/util/tss-react';
5
- import ArrowDown from '@mui/icons-material/KeyboardArrowDown';
6
- import ZoomIn from '@mui/icons-material/ZoomIn';
7
- import ZoomOut from '@mui/icons-material/ZoomOut';
8
- import { IconButton, Paper, alpha } from '@mui/material';
6
+ import AddIcon from '@mui/icons-material/Add';
7
+ import MoreVertIcon from '@mui/icons-material/MoreVert';
8
+ import RemoveIcon from '@mui/icons-material/Remove';
9
+ import { IconButton, Paper, Tooltip, alpha } from '@mui/material';
9
10
  import { observer } from 'mobx-react';
11
+ import ZoomButton from './ZoomButton.js';
10
12
  const useStyles = makeStyles()(theme => ({
11
13
  background: {
12
14
  position: 'absolute',
13
15
  right: 0,
14
16
  background: theme.palette.background.paper,
17
+ // needed when sticky header is off in lgv, e.g. in breakpoint split view
15
18
  zIndex: 2,
16
19
  },
17
20
  focusedBackground: {
@@ -20,12 +23,12 @@ const useStyles = makeStyles()(theme => ({
20
23
  }));
21
24
  const MiniControls = observer(function MiniControls({ model, }) {
22
25
  const { classes } = useStyles();
23
- const { id, bpPerPx, maxBpPerPx, minBpPerPx, hideHeader, effectiveBpPerPx } = model;
26
+ const { id, scalebarOnly } = model;
24
27
  const { focusedViewId } = getSession(model);
25
- return hideHeader ? (_jsx(Paper, { className: classes.background, children: _jsxs(Paper, { className: focusedViewId === id ? classes.focusedBackground : undefined, children: [_jsx(CascadingMenuButton, { menuItems: () => model.menuItems(), children: _jsx(ArrowDown, { fontSize: "small" }) }), _jsx(IconButton, { "data-testid": "zoom_out", onClick: () => {
26
- model.zoom(bpPerPx * 2);
27
- }, disabled: effectiveBpPerPx >= maxBpPerPx - 0.0001, children: _jsx(ZoomOut, { fontSize: "small" }) }), _jsx(IconButton, { "data-testid": "zoom_in", onClick: () => {
28
- model.zoom(bpPerPx / 2);
29
- }, disabled: effectiveBpPerPx <= minBpPerPx + 0.0001, children: _jsx(ZoomIn, { fontSize: "small" }) })] }) })) : null;
28
+ return (_jsx(Paper, { className: classes.background, children: _jsxs(Paper, { className: focusedViewId === id ? classes.focusedBackground : undefined, children: [_jsx(Tooltip, { title: "Open track selector", children: _jsx(IconButton, { size: "small", onClick: () => {
29
+ model.activateTrackSelector();
30
+ }, children: _jsx(TrackSelectorIcon, { fontSize: "small" }) }) }), _jsx(CascadingMenuButton, { menuItems: () => model.menuItems(), children: _jsx(MoreVertIcon, { fontSize: "small" }) }), _jsx(Tooltip, { title: scalebarOnly ? 'Expand tracks' : 'Collapse to ruler', children: _jsx(IconButton, { size: "small", onClick: () => {
31
+ model.setScalebarOnly(!scalebarOnly);
32
+ }, children: scalebarOnly ? (_jsx(AddIcon, { fontSize: "small" })) : (_jsx(RemoveIcon, { fontSize: "small" })) }) }), _jsx(ZoomButton, { model: model, direction: "out", small: true }), _jsx(ZoomButton, { model: model, direction: "in", small: true })] }) }));
30
33
  });
31
34
  export default MiniControls;
@@ -0,0 +1,3 @@
1
+ import type { SequenceSearchModeProps } from './searchModes.ts';
2
+ declare const MotifListPanel: ({ model, handleClose, }: SequenceSearchModeProps) => import("react").JSX.Element;
3
+ export default MotifListPanel;
@@ -0,0 +1,59 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { isPalindromic, parseMotifList, pluralize } from '@jbrowse/core/util';
4
+ import { Button, TextField, Typography } from '@mui/material';
5
+ import { observer } from 'mobx-react';
6
+ import SearchPanelForm from './SearchPanelForm.js';
7
+ import StrandCheckboxes from './StrandCheckboxes.js';
8
+ import { DEFAULT_MOTIFS } from './defaultMotifs.js';
9
+ import { addReferenceScanTrack } from './searchModes.js';
10
+ const MotifListPanel = observer(function MotifListPanel({ model, handleClose, }) {
11
+ const [text, setText] = useState(DEFAULT_MOTIFS);
12
+ const [searchForward, setSearchForward] = useState(true);
13
+ const [searchReverse, setSearchReverse] = useState(true);
14
+ const { motifs, errors } = parseMotifList(text);
15
+ // strand choice only means something for motifs that read differently on the
16
+ // two strands; most restriction sites are palindromes, which always match both
17
+ const hasStrandedMotif = motifs.some(m => !isPalindromic(m.site));
18
+ const strandValid = !hasStrandedMotif || searchForward || searchReverse;
19
+ const canSubmit = motifs.length > 0 && errors.length === 0 && strandValid;
20
+ function handleSubmitCombined() {
21
+ addReferenceScanTrack(model, {
22
+ trackId: `motif_search_${Date.now()}`,
23
+ name: motifs.length === 1
24
+ ? `Motif ${motifs[0].name}`
25
+ : `Motif search (${motifs.length} motifs)`,
26
+ adapter: {
27
+ type: 'MotifListAdapter',
28
+ motifs: text,
29
+ searchForward,
30
+ searchReverse,
31
+ },
32
+ });
33
+ handleClose();
34
+ }
35
+ function handleSubmitSeparate() {
36
+ const now = Date.now();
37
+ for (const [idx, motif] of motifs.entries()) {
38
+ addReferenceScanTrack(model, {
39
+ trackId: `motif_search_${now}_${idx}`,
40
+ name: `Motif ${motif.name}`,
41
+ adapter: {
42
+ type: 'MotifListAdapter',
43
+ motifs: motif.line,
44
+ searchForward,
45
+ searchReverse,
46
+ },
47
+ });
48
+ }
49
+ handleClose();
50
+ }
51
+ return (_jsxs(SearchPanelForm, { onSubmit: handleSubmitCombined, handleClose: handleClose, submitDisabled: !canSubmit, submitText: "Launch as one track", actions: motifs.length > 1 ? (_jsx(Button, { type: "button", onClick: () => {
52
+ handleSubmitSeparate();
53
+ }, disabled: !canSubmit, variant: "contained", color: "primary", children: "Launch one track per motif" })) : null, children: [_jsx(TextField, { multiline: true, fullWidth: true, rows: 12, variant: "outlined", label: "Motifs", value: text, onChange: event => {
54
+ setText(event.target.value);
55
+ }, slotProps: { htmlInput: { style: { fontFamily: 'monospace' } } } }), errors.length > 0 ? (_jsx(Typography, { color: "error", variant: "body2", children: errors.map(e => `Line ${e.line}: ${e.message}`).join('\n') })) : (_jsx(Typography, { variant: "body2", color: "textSecondary", children: motifs.length === 0
56
+ ? 'Add at least one motif'
57
+ : `${motifs.length} ${pluralize(motifs.length, 'motif')}` })), hasStrandedMotif ? (_jsx(StrandCheckboxes, { searchForward: searchForward, searchReverse: searchReverse, setSearchForward: setSearchForward, setSearchReverse: setSearchReverse })) : motifs.length > 0 ? (_jsx(Typography, { variant: "body2", color: "textSecondary", children: "All motifs are palindromic, so each match covers both strands." })) : null] }));
58
+ });
59
+ export default MotifListPanel;
@@ -0,0 +1,32 @@
1
+ import type { LinearGenomeViewModel } from '../index.ts';
2
+ /**
3
+ * The one thing that tells a screen-reader user a pan, a zoom or a search
4
+ * actually moved the view: a polite live region restating where the view now is.
5
+ *
6
+ * **It reads `coarseVisibleLocStrings`, never `visibleLocStrings`**, and that is
7
+ * the whole design. The fine one changes on every `offsetPx` write — every frame
8
+ * of a drag, a wheel zoom or a keyboard slide — and a live region driven by it
9
+ * queues an utterance per frame, which does not merely say too much: it makes
10
+ * the screen reader unusable for as long as the drag lasts, because polite
11
+ * announcements are a queue rather than a latest-value. The coarse blocks are
12
+ * already the view's settled signal, published by a `delay: 500` autorun
13
+ * (`setupCoarseDynamicBlocksAutorun`) and flushed synchronously by `moveTo` so a
14
+ * discrete jump — a search, a bookmark, `navToLocString` — announces at once
15
+ * instead of 500ms later. Both properties are what this needs, so this adds no
16
+ * timer of its own; if the debounce ever moves, this moves with it.
17
+ *
18
+ * Its own observer so the view container does not re-render when the locus
19
+ * settles: this component is a text node with no children, and the container
20
+ * mounts every track.
21
+ *
22
+ * The region is rendered with its text from the first render rather than being
23
+ * filled after mount. A live region whose content is present when the node is
24
+ * inserted is generally not announced (the region has to exist before the
25
+ * change), so in practice a freshly-mounted view says nothing; where a reader
26
+ * does announce it, "chr1:1..1,000" as the view appears is a fair thing to hear,
27
+ * and it is one utterance per view rather than one per frame.
28
+ */
29
+ declare const NavigationAnnouncer: ({ model, }: {
30
+ model: LinearGenomeViewModel;
31
+ }) => import("react").JSX.Element;
32
+ export default NavigationAnnouncer;
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { observer } from 'mobx-react';
3
+ // Off-screen but not `display:none` / `visibility:hidden` / `aria-hidden` — any
4
+ // of those takes the node out of the accessibility tree, which is exactly what a
5
+ // live region must not be. The 1px-clipped box is the long-standing spelling of
6
+ // "readable by assistive tech, occupying no layout".
7
+ const visuallyHidden = {
8
+ position: 'absolute',
9
+ width: 1,
10
+ height: 1,
11
+ margin: -1,
12
+ padding: 0,
13
+ border: 0,
14
+ overflow: 'hidden',
15
+ clipPath: 'inset(50%)',
16
+ whiteSpace: 'nowrap',
17
+ };
18
+ /**
19
+ * The one thing that tells a screen-reader user a pan, a zoom or a search
20
+ * actually moved the view: a polite live region restating where the view now is.
21
+ *
22
+ * **It reads `coarseVisibleLocStrings`, never `visibleLocStrings`**, and that is
23
+ * the whole design. The fine one changes on every `offsetPx` write — every frame
24
+ * of a drag, a wheel zoom or a keyboard slide — and a live region driven by it
25
+ * queues an utterance per frame, which does not merely say too much: it makes
26
+ * the screen reader unusable for as long as the drag lasts, because polite
27
+ * announcements are a queue rather than a latest-value. The coarse blocks are
28
+ * already the view's settled signal, published by a `delay: 500` autorun
29
+ * (`setupCoarseDynamicBlocksAutorun`) and flushed synchronously by `moveTo` so a
30
+ * discrete jump — a search, a bookmark, `navToLocString` — announces at once
31
+ * instead of 500ms later. Both properties are what this needs, so this adds no
32
+ * timer of its own; if the debounce ever moves, this moves with it.
33
+ *
34
+ * Its own observer so the view container does not re-render when the locus
35
+ * settles: this component is a text node with no children, and the container
36
+ * mounts every track.
37
+ *
38
+ * The region is rendered with its text from the first render rather than being
39
+ * filled after mount. A live region whose content is present when the node is
40
+ * inserted is generally not announced (the region has to exist before the
41
+ * change), so in practice a freshly-mounted view says nothing; where a reader
42
+ * does announce it, "chr1:1..1,000" as the view appears is a fair thing to hear,
43
+ * and it is one utterance per view rather than one per frame.
44
+ */
45
+ const NavigationAnnouncer = observer(function NavigationAnnouncer({ model, }) {
46
+ const { coarseVisibleLocStrings, coarseTotalBpDisplayStr } = model;
47
+ return (_jsx("div", { role: "status", "aria-live": "polite", "aria-atomic": "true", style: visuallyHidden, children: coarseVisibleLocStrings
48
+ ? `${coarseVisibleLocStrings} (${coarseTotalBpDisplayStr})`
49
+ : '' }));
50
+ });
51
+ export default NavigationAnnouncer;