@jbrowse/core 5.0.0-beta.8 → 5.0.0-beta.9

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 (379) hide show
  1. package/README.md +427 -130
  2. package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.d.ts +3 -2
  3. package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +5 -3
  4. package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts +3 -5
  5. package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.js +8 -9
  6. package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +8 -13
  7. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +2 -1
  8. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +3 -3
  9. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +8 -0
  10. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +24 -0
  11. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts +3 -2
  12. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.js +5 -3
  13. package/esm/BaseFeatureWidget/BaseFeatureDetail/index.d.ts +1 -0
  14. package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +1 -4
  15. package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.d.ts +16 -0
  16. package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.js +53 -0
  17. package/esm/BaseFeatureWidget/BaseFeatureDetail/util.d.ts +0 -8
  18. package/esm/BaseFeatureWidget/BaseFeatureDetail/util.js +0 -16
  19. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceContents.js +7 -34
  20. package/esm/BaseFeatureWidget/configSchema.d.ts +1 -1
  21. package/esm/BaseFeatureWidget/formatDetails.d.ts +13 -29
  22. package/esm/BaseFeatureWidget/formatDetails.js +46 -79
  23. package/esm/BaseFeatureWidget/index.d.ts +1 -0
  24. package/esm/BaseFeatureWidget/stateModelFactory.d.ts +35 -28
  25. package/esm/BaseFeatureWidget/stateModelFactory.js +94 -102
  26. package/esm/BaseFeatureWidget/types.d.ts +3 -0
  27. package/esm/BaseFeatureWidget/util.d.ts +0 -3
  28. package/esm/BaseFeatureWidget/util.js +0 -17
  29. package/esm/PluginLoader.d.ts +14 -9
  30. package/esm/PluginLoader.js +34 -26
  31. package/esm/PluginManager.d.ts +4 -4
  32. package/esm/PluginManager.js +1 -1
  33. package/esm/ReExports/coreModules.generated.d.ts +2 -0
  34. package/esm/ReExports/coreModules.generated.js +492 -0
  35. package/esm/ReExports/coreWorkerModules.generated.d.ts +2 -0
  36. package/esm/ReExports/coreWorkerModules.generated.js +453 -0
  37. package/esm/ReExports/frameworkModules.d.ts +2 -0
  38. package/esm/ReExports/frameworkModules.js +67 -0
  39. package/esm/ReExports/frameworkShared.d.ts +12 -0
  40. package/esm/ReExports/frameworkShared.js +16 -0
  41. package/esm/ReExports/frameworkWorkerModules.generated.d.ts +2 -0
  42. package/esm/ReExports/frameworkWorkerModules.generated.js +130 -0
  43. package/esm/ReExports/list.js +493 -79
  44. package/esm/ReExports/modules.d.ts +1 -1
  45. package/esm/ReExports/modules.js +10 -87
  46. package/esm/ReExports/registry.d.ts +1 -0
  47. package/esm/ReExports/registry.js +23 -5
  48. package/esm/ReExports/uiStub.d.ts +2 -1
  49. package/esm/ReExports/uiStub.js +24 -2
  50. package/esm/ReExports/workerModules.js +8 -12
  51. package/esm/TextSearch/TextSearchManager.d.ts +3 -12
  52. package/esm/TextSearch/TextSearchManager.js +22 -10
  53. package/esm/assemblyManager/assembly.d.ts +10 -14
  54. package/esm/assemblyManager/assembly.js +10 -14
  55. package/esm/assemblyManager/assemblyConfigSchema.d.ts +23 -81
  56. package/esm/assemblyManager/assemblyManager.d.ts +10 -16
  57. package/esm/assemblyManager/assemblyManager.js +7 -10
  58. package/esm/assemblyManager/loadRefNameMap.js +3 -3
  59. package/esm/configuration/configurationSchema.d.ts +75 -31
  60. package/esm/configuration/configurationSchema.js +74 -40
  61. package/esm/configuration/configurationSchemaUnion.d.ts +39 -0
  62. package/esm/configuration/configurationSchemaUnion.js +59 -0
  63. package/esm/configuration/configurationSlot.d.ts +37 -12
  64. package/esm/configuration/configurationSlot.js +83 -22
  65. package/esm/configuration/formatAboutConfigSchema.d.ts +7 -21
  66. package/esm/configuration/formatDetailsConfigSchema.d.ts +11 -37
  67. package/esm/configuration/formatDetailsConfigSchema.js +10 -13
  68. package/esm/configuration/getConf.d.ts +17 -9
  69. package/esm/configuration/getConf.js +52 -7
  70. package/esm/configuration/index.d.ts +11 -4
  71. package/esm/configuration/index.js +7 -4
  72. package/esm/configuration/mergeFormatCallbacks.d.ts +6 -7
  73. package/esm/configuration/mergeFormatCallbacks.js +13 -10
  74. package/esm/configuration/readConfObject.d.ts +2 -22
  75. package/esm/configuration/readConfObject.js +15 -49
  76. package/esm/configuration/requirements.d.ts +37 -0
  77. package/esm/configuration/requirements.js +88 -0
  78. package/esm/configuration/schemaRegistry.d.ts +21 -1
  79. package/esm/configuration/schemaRegistry.js +11 -0
  80. package/esm/configuration/schemaTypes.d.ts +3 -0
  81. package/esm/configuration/schemaTypes.js +10 -0
  82. package/esm/configuration/slotFacade.d.ts +35 -4
  83. package/esm/configuration/slotFacade.js +96 -9
  84. package/esm/configuration/snapshotPreprocess.d.ts +27 -0
  85. package/esm/configuration/snapshotPreprocess.js +102 -0
  86. package/esm/configuration/types.d.ts +161 -22
  87. package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +2 -2
  88. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +11 -2
  89. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +12 -1
  90. package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +2 -3
  91. package/esm/data_adapters/BaseAdapter/featureDensity.js +2 -3
  92. package/esm/data_adapters/BaseAdapter/index.d.ts +22 -3
  93. package/esm/data_adapters/BaseAdapter/types.d.ts +3 -4
  94. package/esm/data_adapters/BaseAdapter/zoomRange.d.ts +10 -0
  95. package/esm/data_adapters/BaseAdapter/zoomRange.js +1 -0
  96. package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +9 -11
  97. package/esm/data_adapters/getSequenceSubAdapter.d.ts +1 -3
  98. package/esm/data_adapters/getSequenceSubAdapter.js +1 -3
  99. package/esm/pluggableElementTypes/AdapterType.d.ts +7 -7
  100. package/esm/pluggableElementTypes/RpcMethodType.d.ts +1 -1
  101. package/esm/pluggableElementTypes/RpcMethodType.js +3 -8
  102. package/esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts +1 -2
  103. package/esm/pluggableElementTypes/TextSearchAdapterType.d.ts +7 -7
  104. package/esm/pluggableElementTypes/index.d.ts +1 -1
  105. package/esm/pluggableElementTypes/index.js +1 -1
  106. package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +17 -7
  107. package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +45 -48
  108. package/esm/pluggableElementTypes/models/BaseDisplayModel.js +40 -36
  109. package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +10 -13
  110. package/esm/pluggableElementTypes/models/BaseTrackModel.js +6 -6
  111. package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +37 -17
  112. package/esm/pluggableElementTypes/models/BaseViewModel.js +25 -10
  113. package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +26 -16
  114. package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +1 -1
  115. package/esm/pluggableElementTypes/models/baseConnectionConfig.d.ts +22 -18
  116. package/esm/pluggableElementTypes/models/baseConnectionConfig.js +5 -5
  117. package/esm/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +26 -31
  118. package/esm/pluggableElementTypes/models/baseTrackConfig.d.ts +57 -141
  119. package/esm/pluggableElementTypes/models/baseTrackConfig.js +22 -26
  120. package/esm/pluggableElementTypes/models/components/SaveTrackData.js +2 -2
  121. package/esm/pluggableElementTypes/models/components/fetchTrackData.d.ts +3 -4
  122. package/esm/pluggableElementTypes/models/components/fetchTrackData.js +3 -3
  123. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.d.ts +15 -7
  124. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +38 -29
  125. package/esm/pluggableElementTypes/models/index.d.ts +1 -2
  126. package/esm/pluggableElementTypes/models/index.js +1 -2
  127. package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.d.ts +3 -3
  128. package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.js +4 -4
  129. package/esm/pluggableElementTypes/models/saveTrackFileTypes/types.d.ts +3 -3
  130. package/esm/rpc/BaseRpcDriver.d.ts +1 -2
  131. package/esm/rpc/BaseRpcDriver.js +23 -30
  132. package/esm/rpc/MainThreadRpcDriver.d.ts +2 -2
  133. package/esm/rpc/MainThreadRpcDriver.js +13 -8
  134. package/esm/rpc/RpcClient.d.ts +17 -6
  135. package/esm/rpc/RpcClient.js +42 -12
  136. package/esm/rpc/RpcManager.d.ts +8 -10
  137. package/esm/rpc/RpcManager.js +1 -1
  138. package/esm/rpc/RpcRegistry.d.ts +8 -2
  139. package/esm/rpc/RpcServer.d.ts +3 -1
  140. package/esm/rpc/RpcServer.js +19 -12
  141. package/esm/rpc/WebWorkerRpcDriver.d.ts +3 -3
  142. package/esm/rpc/WebWorkerRpcDriver.js +9 -47
  143. package/esm/rpc/byteBudget.d.ts +3 -5
  144. package/esm/rpc/byteBudget.js +4 -4
  145. package/esm/rpc/configSchema.d.ts +7 -21
  146. package/esm/rpc/coreRpcMethods.d.ts +1 -0
  147. package/esm/rpc/coreRpcMethods.js +1 -0
  148. package/esm/rpc/methods/CoreEncodeFeatures.d.ts +6 -5
  149. package/esm/rpc/methods/CoreEncodeFeatures.js +26 -31
  150. package/esm/rpc/methods/CoreGetEncodedFeature.d.ts +13 -0
  151. package/esm/rpc/methods/CoreGetEncodedFeature.js +31 -0
  152. package/esm/rpc/methods/CoreGetExportData.js +2 -2
  153. package/esm/rpc/methods/CoreGetFeatureDensity.js +2 -2
  154. package/esm/rpc/methods/CoreGetFeatures.js +2 -2
  155. package/esm/rpc/methods/CoreGetSequence.js +2 -2
  156. package/esm/rpc/methods/layerFeatures.d.ts +26 -0
  157. package/esm/rpc/methods/layerFeatures.js +40 -0
  158. package/esm/svg/SvgExport.js +3 -4
  159. package/esm/svg/SvgThemeProviders.d.ts +12 -0
  160. package/esm/svg/SvgThemeProviders.js +15 -0
  161. package/esm/svg/exportViewSvg.d.ts +32 -0
  162. package/esm/svg/exportViewSvg.js +13 -0
  163. package/esm/svg/normalizeSvgMarkup.d.ts +7 -0
  164. package/esm/svg/normalizeSvgMarkup.js +99 -0
  165. package/esm/svg/serializeSvg.d.ts +7 -0
  166. package/esm/svg/serializeSvg.js +11 -0
  167. package/esm/svg/svgReady.d.ts +8 -7
  168. package/esm/svg/svgReady.js +8 -7
  169. package/esm/svg/trackNames.d.ts +5 -5
  170. package/esm/svg/trackNames.js +6 -6
  171. package/esm/svg/wrapSvgExport.js +6 -74
  172. package/esm/ui/CascadingMenu.js +83 -86
  173. package/esm/ui/ErrorMessageStackTraceDialog.js +0 -5
  174. package/esm/ui/FileSelector/useInternetAccounts.d.ts +156 -96
  175. package/esm/ui/HoverMenu.d.ts +1 -2
  176. package/esm/ui/HoverMenu.js +6 -3
  177. package/esm/ui/JexlFilterDialog.d.ts +13 -10
  178. package/esm/ui/JexlFilterDialog.js +122 -49
  179. package/esm/ui/JexlFilterRowEditors.d.ts +15 -0
  180. package/esm/ui/JexlFilterRowEditors.js +90 -0
  181. package/esm/ui/LazyBaseTooltip.d.ts +4 -0
  182. package/esm/ui/LazyBaseTooltip.js +9 -0
  183. package/esm/ui/LoadingOverlay.js +3 -1
  184. package/esm/ui/MonospaceTextField.d.ts +2 -1
  185. package/esm/ui/MonospaceTextField.js +21 -19
  186. package/esm/ui/PaletteContext.d.ts +7 -9
  187. package/esm/ui/PaletteContext.js +24 -10
  188. package/esm/ui/RefNameAutocomplete/index.d.ts +1 -2
  189. package/esm/ui/RefNameAutocomplete/index.js +1 -1
  190. package/esm/ui/ScrollChrome.d.ts +6 -9
  191. package/esm/ui/ScrollChrome.js +5 -6
  192. package/esm/ui/ScrollEdgeShadow.d.ts +6 -9
  193. package/esm/ui/ScrollEdgeShadow.js +9 -24
  194. package/esm/ui/SettingsChangesTable.js +3 -3
  195. package/esm/ui/VerticalScrollbar.d.ts +13 -34
  196. package/esm/ui/VerticalScrollbar.js +29 -83
  197. package/esm/ui/ViewLoadingScreen.d.ts +2 -2
  198. package/esm/ui/ViewLoadingScreen.js +3 -3
  199. package/esm/ui/colorScale.d.ts +26 -1
  200. package/esm/ui/colorScale.js +28 -5
  201. package/esm/ui/colors.d.ts +49 -1
  202. package/esm/ui/colors.js +139 -4
  203. package/esm/ui/hoverBoxStyle.d.ts +14 -2
  204. package/esm/ui/hoverBoxStyle.js +17 -2
  205. package/esm/ui/index.d.ts +5 -3
  206. package/esm/ui/index.js +9 -7
  207. package/esm/ui/launchViewMenu.js +3 -3
  208. package/esm/ui/legendSpec.d.ts +2 -0
  209. package/esm/ui/legendSpec.js +3 -0
  210. package/esm/ui/palette.d.ts +0 -1
  211. package/esm/ui/palette.js +3 -27
  212. package/esm/ui/replaceViewAction.d.ts +1 -1
  213. package/esm/ui/replaceViewAction.js +1 -1
  214. package/esm/ui/theme.d.ts +1 -1
  215. package/esm/ui/theme.js +6 -40
  216. package/esm/ui/viewHeaderHeight.d.ts +1 -0
  217. package/esm/ui/viewHeaderHeight.js +1 -0
  218. package/esm/util/Base1DUtils.d.ts +1 -1
  219. package/esm/util/Base1DUtils.js +2 -2
  220. package/esm/util/SvgCanvas.d.ts +15 -13
  221. package/esm/util/SvgCanvas.js +72 -53
  222. package/esm/util/aborting.d.ts +39 -0
  223. package/esm/util/aborting.js +84 -0
  224. package/esm/util/adapterMetadata.d.ts +1 -1
  225. package/esm/util/adapterMetadata.js +6 -6
  226. package/esm/util/addAndShowTrack.d.ts +1 -4
  227. package/esm/util/addRelativeUris.d.ts +10 -2
  228. package/esm/util/addRelativeUris.js +22 -7
  229. package/esm/util/addTrackFromWidget.d.ts +2 -5
  230. package/esm/util/animationAllowed.d.ts +9 -0
  231. package/esm/util/animationAllowed.js +13 -0
  232. package/esm/util/applyRowResizeWheel.d.ts +10 -5
  233. package/esm/util/applyRowResizeWheel.js +10 -21
  234. package/esm/util/bandLayout.d.ts +4 -4
  235. package/esm/util/bandLayout.js +4 -4
  236. package/esm/util/bezierConnector.js +5 -4
  237. package/esm/util/bgzfWorkerPool.d.ts +20 -74
  238. package/esm/util/bgzfWorkerPool.js +20 -74
  239. package/esm/util/cachedSetup.d.ts +1 -1
  240. package/esm/util/cachedSetup.js +2 -2
  241. package/esm/util/categoricalField.d.ts +37 -0
  242. package/esm/util/categoricalField.js +52 -0
  243. package/esm/util/color/cssColorsLevel4.d.ts +1 -0
  244. package/esm/util/color/cssColorsLevel4.js +1 -0
  245. package/esm/util/color/index.d.ts +5 -3
  246. package/esm/util/color/index.js +7 -4
  247. package/esm/util/colorBits.d.ts +1 -2
  248. package/esm/util/colorBits.js +17 -39
  249. package/esm/util/colorRamp.d.ts +27 -1
  250. package/esm/util/colorRamp.js +56 -2
  251. package/esm/util/colorSchemes.d.ts +9 -0
  252. package/esm/util/colorSchemes.js +7 -0
  253. package/esm/util/{createStopTokenRotation.d.ts → createAbortRotation.d.ts} +11 -14
  254. package/esm/util/{createStopTokenRotation.js → createAbortRotation.js} +14 -26
  255. package/esm/util/cssColorParse.d.ts +15 -0
  256. package/esm/util/cssColorParse.js +53 -0
  257. package/esm/util/diagonalizeRegions.d.ts +2 -3
  258. package/esm/util/diagonalizeRegions.js +7 -12
  259. package/esm/util/expandLooseSearchIndex.d.ts +7 -0
  260. package/esm/util/expandLooseSearchIndex.js +25 -0
  261. package/esm/util/featureTransforms.d.ts +30 -3
  262. package/esm/util/featureTransforms.js +233 -36
  263. package/esm/util/fetchAndMaybeUnzip.js +5 -6
  264. package/esm/util/fetchContext.d.ts +5 -6
  265. package/esm/util/fetchContext.js +1 -1
  266. package/esm/util/fetchHub.d.ts +3 -1
  267. package/esm/util/fetchHub.js +2 -2
  268. package/esm/util/fetchSeq.d.ts +2 -3
  269. package/esm/util/fetchSeq.js +2 -2
  270. package/esm/util/fieldReader.d.ts +17 -0
  271. package/esm/util/fieldReader.js +62 -0
  272. package/esm/util/groupKeys.d.ts +75 -0
  273. package/esm/util/groupKeys.js +152 -0
  274. package/esm/util/highlights.d.ts +6 -4
  275. package/esm/util/highlights.js +12 -25
  276. package/esm/util/hooks.d.ts +1 -2
  277. package/esm/util/hooks.js +1 -2
  278. package/esm/util/index.d.ts +3 -3
  279. package/esm/util/index.js +4 -3
  280. package/esm/util/indexCandidates.js +1 -1
  281. package/esm/util/installFetch.d.ts +13 -10
  282. package/esm/util/installFetch.js +11 -10
  283. package/esm/util/installPrerequisiteFetch.d.ts +5 -3
  284. package/esm/util/installPrerequisiteFetch.js +3 -4
  285. package/esm/util/io/index.js +12 -12
  286. package/esm/util/isDataCurrent.d.ts +7 -5
  287. package/esm/util/isDataCurrent.js +9 -6
  288. package/esm/util/jexl.js +24 -21
  289. package/esm/util/jexlFilterRows.d.ts +89 -0
  290. package/esm/util/jexlFilterRows.js +252 -0
  291. package/esm/util/jexlFilters.d.ts +7 -5
  292. package/esm/util/jexlStrings.d.ts +3 -4
  293. package/esm/util/jexlStrings.js +2 -3
  294. package/esm/util/legendCandidates.d.ts +31 -27
  295. package/esm/util/legendCandidates.js +79 -53
  296. package/esm/util/localStorage.js +4 -4
  297. package/esm/util/markEncoding.d.ts +32 -16
  298. package/esm/util/markEncoding.js +177 -150
  299. package/esm/util/markEncodingTypes.d.ts +137 -66
  300. package/esm/util/mstUtils.d.ts +19 -22
  301. package/esm/util/mstUtils.js +19 -22
  302. package/esm/util/numericUtils.d.ts +7 -0
  303. package/esm/util/numericUtils.js +16 -0
  304. package/esm/util/numericValue.d.ts +14 -0
  305. package/esm/util/numericValue.js +34 -0
  306. package/esm/util/openFeatureWidget.js +1 -2
  307. package/esm/util/openViews.d.ts +1 -0
  308. package/esm/util/openViews.js +3 -3
  309. package/esm/util/parseLineByLine.d.ts +3 -4
  310. package/esm/util/parseLineByLine.js +7 -13
  311. package/esm/util/progress.d.ts +21 -21
  312. package/esm/util/progress.js +27 -26
  313. package/esm/util/renameRegions.d.ts +1 -2
  314. package/esm/util/renderToStaticMarkup.js +16 -16
  315. package/esm/util/rxjs.d.ts +7 -8
  316. package/esm/util/rxjs.js +12 -15
  317. package/esm/util/simpleFeature.d.ts +0 -1
  318. package/esm/util/svgColorProps.d.ts +11 -0
  319. package/esm/util/svgColorProps.js +28 -1
  320. package/esm/util/tabix.d.ts +3 -4
  321. package/esm/util/tabix.js +6 -7
  322. package/esm/util/thresholdScale.d.ts +54 -0
  323. package/esm/util/thresholdScale.js +112 -0
  324. package/esm/util/timeGate.d.ts +4 -5
  325. package/esm/util/timeGate.js +4 -5
  326. package/esm/util/trackConfigDelta.d.ts +22 -18
  327. package/esm/util/trackConfigDelta.js +40 -38
  328. package/esm/util/tracks.d.ts +27 -4
  329. package/esm/util/tracks.js +116 -43
  330. package/esm/util/translateTranscript.d.ts +44 -0
  331. package/esm/util/translateTranscript.js +102 -0
  332. package/esm/util/types/index.d.ts +19 -7
  333. package/esm/util/types/services.d.ts +1 -1
  334. package/esm/util/unknownSnapshotKeys.d.ts +15 -0
  335. package/esm/util/unknownSnapshotKeys.js +13 -0
  336. package/esm/util/useFeatureSequence.js +4 -4
  337. package/esm/util/useFetch.d.ts +3 -4
  338. package/esm/util/useFetch.js +5 -6
  339. package/esm/util/usePanelVirtualScroll.d.ts +7 -39
  340. package/esm/util/usePanelVirtualScroll.js +9 -40
  341. package/esm/util/useRowVirtualScroll.d.ts +6 -29
  342. package/esm/util/useRowVirtualScroll.js +8 -49
  343. package/esm/util/useVirtualScrollWheel.d.ts +20 -4
  344. package/esm/util/useVirtualScrollWheel.js +40 -84
  345. package/esm/util/viewHighlights.d.ts +3 -0
  346. package/esm/util/viewHighlights.js +5 -0
  347. package/esm/util/viewStatus.d.ts +24 -15
  348. package/esm/util/viewStatus.js +17 -0
  349. package/esm/util/withLaunchInput.d.ts +1 -1
  350. package/esm/util/withLaunchInput.js +0 -4
  351. package/package.json +26 -12
  352. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.d.ts +0 -80
  353. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.js +0 -583
  354. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +0 -141
  355. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.js +0 -1116
  356. package/esm/ReExports/BaseFeatureDetails.d.ts +0 -1
  357. package/esm/ReExports/BaseFeatureDetails.js +0 -10
  358. package/esm/ReExports/barrelOnlyNames.d.ts +0 -5
  359. package/esm/ReExports/barrelOnlyNames.js +0 -63
  360. package/esm/ReExports/index.d.ts +0 -1
  361. package/esm/ReExports/index.js +0 -1
  362. package/esm/ReExports/publicTracks.d.ts +0 -1
  363. package/esm/ReExports/publicTracks.js +0 -14
  364. package/esm/ReExports/publicUi.d.ts +0 -4
  365. package/esm/ReExports/publicUi.js +0 -33
  366. package/esm/ReExports/publicUtil.d.ts +0 -1
  367. package/esm/ReExports/publicUtil.js +0 -32
  368. package/esm/ReExports/sharedModules.d.ts +0 -96
  369. package/esm/ReExports/sharedModules.js +0 -66
  370. package/esm/ReExports/workerNamespaceNames.d.ts +0 -11
  371. package/esm/ReExports/workerNamespaceNames.js +0 -275
  372. package/esm/pluggableElementTypes/models/HighlightsMixin.d.ts +0 -51
  373. package/esm/pluggableElementTypes/models/HighlightsMixin.js +0 -78
  374. package/esm/ui/highlightChipReveal.d.ts +0 -32
  375. package/esm/ui/highlightChipReveal.js +0 -39
  376. package/esm/util/adapterConfigKey.d.ts +0 -12
  377. package/esm/util/adapterConfigKey.js +0 -14
  378. package/esm/util/stopToken.d.ts +0 -212
  379. package/esm/util/stopToken.js +0 -438
@@ -0,0 +1,90 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import CloseIcon from '@mui/icons-material/Close';
3
+ import { Autocomplete, IconButton, ListItemText, MenuItem, TextField, } from '@mui/material';
4
+ import { OPERATORS, stripJexlPrefix, typedField, withField, withOp, } from '../util/jexlFilterRows.js';
5
+ import { makeStyles } from '../util/tss-react/index.js';
6
+ import MonospaceTextField from './MonospaceTextField.js';
7
+ const useStyles = makeStyles()(theme => ({
8
+ row: {
9
+ display: 'flex',
10
+ alignItems: 'flex-start',
11
+ gap: theme.spacing(1),
12
+ marginBottom: theme.spacing(1),
13
+ },
14
+ field: {
15
+ width: 220,
16
+ flexShrink: 0,
17
+ },
18
+ op: {
19
+ width: 130,
20
+ flexShrink: 0,
21
+ },
22
+ value: {
23
+ flex: 1,
24
+ },
25
+ expression: {
26
+ width: 24,
27
+ flexShrink: 0,
28
+ textAlign: 'center',
29
+ fontStyle: 'italic',
30
+ fontFamily: 'serif',
31
+ fontSize: 18,
32
+ paddingTop: 6,
33
+ color: theme.palette.text.secondary,
34
+ },
35
+ }));
36
+ export function compileError(line, jexl) {
37
+ try {
38
+ jexl.compile(stripJexlPrefix(line.trim()));
39
+ return undefined;
40
+ }
41
+ catch (e) {
42
+ return e instanceof Error ? e.message : String(e);
43
+ }
44
+ }
45
+ function RemoveButton({ onClick }) {
46
+ return (_jsx(IconButton, { size: "small", "aria-label": "Remove condition", onClick: onClick, children: _jsx(CloseIcon, { fontSize: "small" }) }));
47
+ }
48
+ function ValueInput({ row, onChange, }) {
49
+ const { classes } = useStyles();
50
+ const { field, op, value } = row;
51
+ if (op === 'set' || op === '!set') {
52
+ return _jsx("div", { className: classes.value });
53
+ }
54
+ const suggestions = field?.values ?? [];
55
+ if (op === 'in') {
56
+ return (_jsx(Autocomplete, { className: classes.value, size: "small", multiple: true, freeSolo: true, autoSelect: true, options: suggestions, value: [value].flat(), onChange: (_, next) => {
57
+ onChange({ ...row, value: next });
58
+ }, renderInput: params => (_jsx(TextField, { ...params, placeholder: "Values, Enter after each" })) }));
59
+ }
60
+ const text = [value].flat()[0] ?? '';
61
+ return suggestions.length > 0 && op !== '~' ? (_jsx(Autocomplete, { className: classes.value, size: "small", freeSolo: true, options: suggestions, inputValue: text, onInputChange: (_, next) => {
62
+ onChange({ ...row, value: next });
63
+ }, renderInput: params => _jsx(TextField, { ...params, placeholder: "Value" }) })) : (_jsx(TextField, { className: classes.value, size: "small", placeholder: op === '~' ? 'Regular expression' : 'Value', type: field?.type === 'number' ? 'number' : 'text', disabled: !field, value: text, onChange: event => {
64
+ onChange({ ...row, value: event.target.value });
65
+ } }));
66
+ }
67
+ export function ConditionRowEditor({ row, choices, onChange, onRemove, }) {
68
+ const { classes } = useStyles();
69
+ const { field } = row;
70
+ const grouped = choices.some(choice => choice.group);
71
+ return (_jsxs("div", { className: classes.row, children: [_jsx(Autocomplete, { className: classes.field, size: "small", freeSolo: true, autoSelect: true, options: choices, groupBy: grouped ? choice => choice.group ?? '' : undefined, getOptionLabel: choice => typeof choice === 'string' ? choice : choice.label, getOptionKey: choice => typeof choice === 'string' ? choice : choice.key, isOptionEqualToValue: (a, b) => typeof b !== 'string' && a.key === b.key, value: field ?? null, onChange: (_, next) => {
72
+ const chosen = typeof next !== 'string'
73
+ ? next
74
+ : next === field?.label
75
+ ? field
76
+ : (choices.find(choice => choice.label === next) ??
77
+ typedField(next));
78
+ if (chosen && chosen.key !== field?.key) {
79
+ onChange(withField(row, chosen));
80
+ }
81
+ }, renderOption: ({ key, ...props }, choice) => (_jsx("li", { ...props, children: _jsx(ListItemText, { primary: choice.label, secondary: choice.description }) }, key)), renderInput: params => _jsx(TextField, { ...params, placeholder: "Field" }) }), _jsx(TextField, { className: classes.op, select: true, size: "small", disabled: !field, value: row.op, helperText: field?.multi ? 'any value' : undefined, onChange: event => {
82
+ onChange(withOp(row, event.target.value));
83
+ }, children: OPERATORS[field?.type ?? 'any'].map(({ op, label }) => (_jsx(MenuItem, { value: op, children: label }, op))) }), _jsx(ValueInput, { row: row, onChange: onChange }), _jsx(RemoveButton, { onClick: onRemove })] }));
84
+ }
85
+ export function TextRowEditor({ row, jexl, onChange, onRemove, }) {
86
+ const { classes } = useStyles();
87
+ return (_jsxs("div", { className: classes.row, children: [_jsx("div", { className: classes.expression, title: "An expression the field pickers cannot show", children: "\u0192" }), _jsx(MonospaceTextField, { className: classes.value, variant: "standard", fullWidth: true, value: row.text, error: compileError(row.text, jexl), onChange: text => {
88
+ onChange({ ...row, text });
89
+ } }), _jsx(RemoveButton, { onClick: onRemove })] }));
90
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentProps } from 'react';
2
+ declare const Lazy: import("react").LazyExoticComponent<typeof import("./BaseTooltip.tsx").default>;
3
+ export default function LazyBaseTooltip(props: ComponentProps<typeof Lazy>): import("react").JSX.Element;
4
+ export {};
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Suspense, lazy } from 'react';
3
+ // The tooltip, behind its own chunk: @floating-ui is ~266KB and this is what
4
+ // lets the ui barrel export it without putting that on the startup path. A
5
+ // consumer that wants the eager component deep-imports './BaseTooltip.tsx'.
6
+ const Lazy = lazy(() => import('./BaseTooltip.js'));
7
+ export default function LazyBaseTooltip(props) {
8
+ return (_jsx(Suspense, { fallback: null, children: _jsx(Lazy, { ...props }) }));
9
+ }
@@ -129,7 +129,9 @@ export default function LoadingOverlay({ statusMessage, progress, isVisible, imm
129
129
  // swallow clicks/hovers over the top-center of every track it overlays. There
130
130
  // is no fade transition, so mount/unmount is visually identical to toggling
131
131
  // opacity anyway.
132
- return shown ? (_jsx("span", { className: classes.overlay, "data-testid": "loading-overlay", children: _jsx("span", { className: classes.content, children: canceled ? (_jsxs("span", { className: classes.row, children: [_jsx("span", { className: classes.text, children: "Loading canceled" }), onRetry ? (_jsx(Tooltip, { title: "Retry", children: _jsx(IconButton, { size: "small", "data-testid": "loading-overlay-retry", onClick: () => {
132
+ // `loading-overlay` is a readiness selector meaning work in flight, so the
133
+ // canceled state, which is finished, publishes its own
134
+ return shown ? (_jsx("span", { className: classes.overlay, "data-testid": canceled ? 'loading-overlay-canceled' : 'loading-overlay', children: _jsx("span", { className: classes.content, children: canceled ? (_jsxs("span", { className: classes.row, children: [_jsx("span", { className: classes.text, children: "Loading canceled" }), onRetry ? (_jsx(Tooltip, { title: "Retry", children: _jsx(IconButton, { size: "small", "data-testid": "loading-overlay-retry", onClick: () => {
133
135
  onRetry();
134
136
  }, children: _jsx(RefreshIcon, { fontSize: "inherit" }) }) })) : null] })) : (_jsxs(_Fragment, { children: [_jsxs("span", { className: classes.row, children: [_jsxs("span", { className: classes.text, children: [progressLabel(statusMessage || 'Loading', progress), hasProgress ? null : _jsx(LoadingDots, {})] }), onCancel && cancelable ? (_jsx(Tooltip, { title: "Cancel", children: _jsx(IconButton, { size: "small", "data-testid": "loading-overlay-cancel", onClick: () => {
135
137
  onCancel();
@@ -1,9 +1,10 @@
1
1
  import type { TextFieldProps } from '@mui/material';
2
- export default function MonospaceTextField({ value, onChange, error, label, children, style, className, readOnly, variant, ...rest }: {
2
+ export default function MonospaceTextField({ value, onChange, error, label, children, style, className, readOnly, inputTestId, helperText, variant, ...rest }: {
3
3
  value: string;
4
4
  onChange?: (value: string) => void;
5
5
  error?: unknown;
6
6
  label?: React.ReactNode;
7
7
  children?: React.ReactNode;
8
8
  readOnly?: boolean;
9
+ inputTestId?: string;
9
10
  } & Omit<TextFieldProps, 'value' | 'onChange' | 'error' | 'slotProps'>): import("react").JSX.Element;
@@ -1,12 +1,8 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { InputLabel, TextField, alpha } from '@mui/material';
3
3
  import { makeStyles } from '../util/tss-react/index.js';
4
4
  const monospaceFontFamily = 'Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace';
5
5
  const useStyles = makeStyles()(theme => ({
6
- error: {
7
- color: theme.palette.error.main,
8
- fontSize: '0.8em',
9
- },
10
6
  container: {
11
7
  width: '100%',
12
8
  overflowX: 'auto',
@@ -18,20 +14,26 @@ const useStyles = makeStyles()(theme => ({
18
14
  background: alpha(theme.palette.error.main, 0.15),
19
15
  },
20
16
  }));
21
- // Monospace multiline TextField for code/jexl/JSON/sequence content. Turns red
22
- // on a parse error, renders an optional error banner above and an InputLabel,
23
- // and applies the shared monospace font stack to the input slot. `children`
17
+ // Monospace multiline TextField for code/jexl/JSON/sequence content. A parse
18
+ // error turns it red and takes the helper text's place under the field, so
19
+ // the text does not move while it flips between valid and invalid. `children`
24
20
  // render below the field (e.g. a description or help button).
25
- export default function MonospaceTextField({ value, onChange, error, label, children, style, className, readOnly, variant = 'outlined', ...rest }) {
21
+ export default function MonospaceTextField({ value, onChange, error, label, children, style, className, readOnly, inputTestId, helperText, variant = 'outlined', ...rest }) {
26
22
  const { classes, cx } = useStyles();
27
- return (_jsxs(_Fragment, { children: [error ? _jsx("p", { className: classes.error, children: `${error}` }) : null, _jsxs("div", { className: classes.container, children: [label ? _jsx(InputLabel, { shrink: true, children: label }) : null, _jsx(TextField, { ...rest, variant: variant, multiline: true, value: value, onChange: event => {
28
- onChange?.(event.target.value);
29
- }, className: cx(className, error ? classes.errorField : undefined), style: style, slotProps: {
30
- input: {
31
- readOnly,
32
- classes: {
33
- input: classes.field,
34
- },
35
- },
36
- } }), children] })] }));
23
+ return (_jsxs("div", { className: classes.container, children: [label ? _jsx(InputLabel, { shrink: true, children: label }) : null, _jsx(TextField, { ...rest, variant: variant, multiline: true, error: !!error, helperText: error ? `${error}` : helperText, value: value, onChange: event => {
24
+ onChange?.(event.target.value);
25
+ }, className: cx(className, error ? classes.errorField : undefined), style: style, slotProps: {
26
+ input: {
27
+ readOnly,
28
+ classes: {
29
+ input: classes.field,
30
+ },
31
+ },
32
+ htmlInput: {
33
+ 'data-testid': inputTestId,
34
+ spellCheck: false,
35
+ autoCorrect: 'off',
36
+ autoCapitalize: 'off',
37
+ },
38
+ } }), children] }));
37
39
  }
@@ -39,10 +39,9 @@ export interface ThemeModeSession {
39
39
  * follow its dark mode mounts {@link SessionPaletteProvider}, which is this
40
40
  * hook and the provider in one.
41
41
  *
42
- * How the host knows its own mode is the host's business — an attribute on
43
- * `<html>`, a design-system context, a toggle in its own state. Pass no mode
44
- * and JBrowse follows `prefers-color-scheme` instead, tracking OS changes; a
45
- * host whose mode is only ever the OS preference has nothing to write.
42
+ * Pass no mode and JBrowse follows the page: its declared CSS `color-scheme`
43
+ * when that names one of light or dark, the OS preference otherwise, tracking
44
+ * both. A host whose mode lives somewhere a stylesheet cannot see passes it.
46
45
  *
47
46
  * **Both halves are load-bearing, which is why the pairing is published as a
48
47
  * component.** The palette is what *React* draws with; the config `theme` slot
@@ -68,11 +67,10 @@ export declare function useSessionPalette(session: ThemeModeSession, mode?: 'lig
68
67
  * </SessionPaletteProvider>
69
68
  * ```
70
69
  *
71
- * `mode` is optional. Left out, JBrowse follows `prefers-color-scheme` and
72
- * re-themes when the OS preference changes, through the same session write an
73
- * explicit mode takes — so a host whose dark mode *is* the OS preference mounts
74
- * this with a session and nothing else. Pass a mode as soon as the host has a
75
- * toggle of its own, since the media query cannot see it.
70
+ * `mode` is optional. Left out, JBrowse follows the page's declared
71
+ * `color-scheme` — so a host whose dark-mode toggle sets it, as most do, mounts
72
+ * this with a session and nothing else — and the OS preference where the page
73
+ * declares none.
76
74
  *
77
75
  * A component rather than a documented pair of calls because the pair has a
78
76
  * half that can be left out with nothing to show for it. `PaletteProvider` is
@@ -55,12 +55,28 @@ function darkSchemeQuery() {
55
55
  function subscribeToColorScheme(onChange) {
56
56
  const media = darkSchemeQuery();
57
57
  media?.addEventListener('change', onChange);
58
+ const observer = typeof MutationObserver === 'function'
59
+ ? new MutationObserver(onChange)
60
+ : undefined;
61
+ observer?.observe(document.documentElement, { attributes: true });
58
62
  return () => {
59
63
  media?.removeEventListener('change', onChange);
64
+ observer?.disconnect();
60
65
  };
61
66
  }
67
+ // The page's declared `color-scheme`, as the browser resolves it for form
68
+ // controls: a page that declares only one of light or dark gets that one, and
69
+ // one that declares both, or neither, gets the OS preference.
62
70
  function readColorScheme() {
63
- return darkSchemeQuery()?.matches ? 'dark' : 'light';
71
+ const declared = getComputedStyle(document.documentElement)
72
+ .getPropertyValue('color-scheme')
73
+ .split(/\s+/)
74
+ .filter((word) => ['light', 'dark'].includes(word));
75
+ return declared.length === 1
76
+ ? declared[0]
77
+ : darkSchemeQuery()?.matches
78
+ ? 'dark'
79
+ : 'light';
64
80
  }
65
81
  const alwaysLight = () => 'light';
66
82
  const subscribeToNothing = () => () => { };
@@ -75,10 +91,9 @@ function useResolvedMode(mode) {
75
91
  * follow its dark mode mounts {@link SessionPaletteProvider}, which is this
76
92
  * hook and the provider in one.
77
93
  *
78
- * How the host knows its own mode is the host's business — an attribute on
79
- * `<html>`, a design-system context, a toggle in its own state. Pass no mode
80
- * and JBrowse follows `prefers-color-scheme` instead, tracking OS changes; a
81
- * host whose mode is only ever the OS preference has nothing to write.
94
+ * Pass no mode and JBrowse follows the page: its declared CSS `color-scheme`
95
+ * when that names one of light or dark, the OS preference otherwise, tracking
96
+ * both. A host whose mode lives somewhere a stylesheet cannot see passes it.
82
97
  *
83
98
  * **Both halves are load-bearing, which is why the pairing is published as a
84
99
  * component.** The palette is what *React* draws with; the config `theme` slot
@@ -110,11 +125,10 @@ export function useSessionPalette(session, mode) {
110
125
  * </SessionPaletteProvider>
111
126
  * ```
112
127
  *
113
- * `mode` is optional. Left out, JBrowse follows `prefers-color-scheme` and
114
- * re-themes when the OS preference changes, through the same session write an
115
- * explicit mode takes — so a host whose dark mode *is* the OS preference mounts
116
- * this with a session and nothing else. Pass a mode as soon as the host has a
117
- * toggle of its own, since the media query cannot see it.
128
+ * `mode` is optional. Left out, JBrowse follows the page's declared
129
+ * `color-scheme` — so a host whose dark-mode toggle sets it, as most do, mounts
130
+ * this with a session and nothing else — and the OS preference where the page
131
+ * declares none.
118
132
  *
119
133
  * A component rather than a documented pair of calls because the pair has a
120
134
  * half that can be left out with nothing to show for it. `PaletteProvider` is
@@ -1,12 +1,11 @@
1
1
  import type BaseResult from '../../TextSearch/BaseResults.ts';
2
2
  import type { AbstractSessionModel } from '../../util/index.ts';
3
- import type { StopToken } from '../../util/stopToken.ts';
4
3
  import type { CSSProperties, ReactNode } from 'react';
5
4
  declare const RefNameAutocomplete: ({ session, assemblyName, value, fetchResults, onSelect, onChange, minWidth, maxWidth, adornmentWidth, style, endAdornment, helperText, inputStyle, }: {
6
5
  session: AbstractSessionModel;
7
6
  assemblyName?: string;
8
7
  value?: string;
9
- fetchResults: (query: string, stopToken?: StopToken) => Promise<BaseResult[]>;
8
+ fetchResults: (query: string, signal?: AbortSignal) => Promise<BaseResult[]>;
10
9
  onSelect?: (region: BaseResult) => void;
11
10
  onChange?: (val: string) => void;
12
11
  minWidth?: number;
@@ -24,7 +24,7 @@ const RefNameAutocomplete = observer(function RefNameAutocomplete({ session, ass
24
24
  // the named parameters below cannot be destructured out of
25
25
  shouldSearch
26
26
  ? ['refNameSearch', assemblyName, debouncedSearch]
27
- : null, async (_tag, _assembly, query, stopToken) => getDeduplicatedResult(await fetchResults(query, stopToken)), {
27
+ : null, async (_tag, _assembly, query, signal) => getDeduplicatedResult(await fetchResults(query, signal)), {
28
28
  onError: e => {
29
29
  session.notifyError(`${e}`, e);
30
30
  },
@@ -1,14 +1,11 @@
1
+ import type { VirtualScrollModel } from '../util/useVirtualScrollWheel.ts';
1
2
  /**
2
- * The chrome a display that scrolls its content virtually mounts over its
3
- * viewport: `ScrollEdgeShadow` saying content is hidden past an edge, and
4
- * `VerticalScrollbar` to reach it. Both read the same three numbers, so a
5
- * display hands them over once here. Renders nothing when the content fits.
3
+ * The chrome a virtually scrolled display mounts over its viewport: the edge
4
+ * shadow saying content is hidden, and the scrollbar to reach it. Renders
5
+ * nothing when the content fits.
6
6
  */
7
- export default function ScrollChrome({ scrollTop, setScrollTop, viewportHeight, contentHeight, controlsId, top, }: {
8
- scrollTop: number;
9
- setScrollTop: (n: number) => void;
10
- viewportHeight: number;
11
- contentHeight: number;
7
+ export default function ScrollChrome({ model, controlsId, top, }: {
8
+ model: VirtualScrollModel;
12
9
  /** `id` of the scrolled viewport element, for `aria-controls`. */
13
10
  controlsId: string;
14
11
  /** Viewport offset from the top, for a display with a sticky band above it. */
@@ -2,11 +2,10 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
2
2
  import ScrollEdgeShadow from './ScrollEdgeShadow.js';
3
3
  import VerticalScrollbar from './VerticalScrollbar.js';
4
4
  /**
5
- * The chrome a display that scrolls its content virtually mounts over its
6
- * viewport: `ScrollEdgeShadow` saying content is hidden past an edge, and
7
- * `VerticalScrollbar` to reach it. Both read the same three numbers, so a
8
- * display hands them over once here. Renders nothing when the content fits.
5
+ * The chrome a virtually scrolled display mounts over its viewport: the edge
6
+ * shadow saying content is hidden, and the scrollbar to reach it. Renders
7
+ * nothing when the content fits.
9
8
  */
10
- export default function ScrollChrome({ scrollTop, setScrollTop, viewportHeight, contentHeight, controlsId, top = 0, }) {
11
- return (_jsxs(_Fragment, { children: [_jsx(ScrollEdgeShadow, { scrollTop: scrollTop, viewportHeight: viewportHeight, contentHeight: contentHeight, top: top }), _jsx(VerticalScrollbar, { scrollTop: scrollTop, setScrollTop: setScrollTop, viewportHeight: viewportHeight, contentHeight: contentHeight, controlsId: controlsId, top: top })] }));
9
+ export default function ScrollChrome({ model, controlsId, top = 0, }) {
10
+ return (_jsxs(_Fragment, { children: [_jsx(ScrollEdgeShadow, { model: model, top: top }), _jsx(VerticalScrollbar, { model: model, controlsId: controlsId, top: top })] }));
12
11
  }
@@ -1,7 +1,7 @@
1
+ import type { VirtualScrollModel } from '../util/useVirtualScrollWheel.ts';
1
2
  /**
2
3
  * The "there is more content this way" edge shadow for a display that scrolls
3
- * its content virtually — the same displays that mount `VerticalScrollbar`,
4
- * drawn from the same three numbers.
4
+ * its content virtually, mounted beside `VerticalScrollbar` by `ScrollChrome`.
5
5
  *
6
6
  * It answers a question the scrollbar technically also answers and in practice
7
7
  * does not: **is this track showing me all of its features?** A 6px thumb on a
@@ -33,12 +33,9 @@
33
33
  * — autogrow/fit, and the truncation warning for features that were dropped
34
34
  * rather than merely scrolled away). This says *that*; that says *what to do*.
35
35
  */
36
- export default function ScrollEdgeShadow({ scrollTop, viewportHeight, contentHeight, top, }: {
37
- scrollTop: number;
38
- /** the visible viewport height */
39
- viewportHeight: number;
40
- /** the full scrollable content height */
41
- contentHeight: number;
36
+ declare const ScrollEdgeShadow: ({ model, top, }: {
37
+ model: VirtualScrollModel;
42
38
  /** viewport offset from the top, for a display with a sticky band above it */
43
39
  top?: number;
44
- }): import("react").JSX.Element | null;
40
+ }) => import("react").JSX.Element | null;
41
+ export default ScrollEdgeShadow;
@@ -1,4 +1,5 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { observer } from 'mobx-react';
2
3
  import { clamp } from '../util/numericUtils.js';
3
4
  import { makeStyles } from '../util/tss-react/index.js';
4
5
  /**
@@ -7,17 +8,7 @@ import { makeStyles } from '../util/tss-react/index.js';
7
8
  * a display draws is ~7px in its most compact mode).
8
9
  */
9
10
  const SHADOW_HEIGHT = 16;
10
- /**
11
- * Sub-pixel slack before an edge counts as scrolled away from. A fit/grow mode
12
- * scale leaves float epsilon in `contentHeight`, and without this a track that
13
- * exactly fits draws a permanent bottom fade — the one thing this must never
14
- * do, since "nothing is hidden" is the state it exists to distinguish.
15
- *
16
- * `VerticalScrollbar` has no equivalent and so still draws a full-height thumb
17
- * on that same sub-pixel overflow. Deliberately not lifted there: a thumb
18
- * filling its track reads as "nothing to scroll", where a permanent fade reads
19
- * as "something is hidden" — the wrong answer rather than a redundant one.
20
- */
11
+ // Slack at each edge, so a float residue in `scrollTop` doesn't mark one.
21
12
  const EPSILON = 0.5;
22
13
  const useStyles = makeStyles()(theme => {
23
14
  // The ink flips with the theme, and has to: a black shadow is invisible on
@@ -46,8 +37,7 @@ const useStyles = makeStyles()(theme => {
46
37
  });
47
38
  /**
48
39
  * The "there is more content this way" edge shadow for a display that scrolls
49
- * its content virtually — the same displays that mount `VerticalScrollbar`,
50
- * drawn from the same three numbers.
40
+ * its content virtually, mounted beside `VerticalScrollbar` by `ScrollChrome`.
51
41
  *
52
42
  * It answers a question the scrollbar technically also answers and in practice
53
43
  * does not: **is this track showing me all of its features?** A 6px thumb on a
@@ -79,20 +69,15 @@ const useStyles = makeStyles()(theme => {
79
69
  * — autogrow/fit, and the truncation warning for features that were dropped
80
70
  * rather than merely scrolled away). This says *that*; that says *what to do*.
81
71
  */
82
- export default function ScrollEdgeShadow({ scrollTop, viewportHeight, contentHeight, top = 0, }) {
72
+ const ScrollEdgeShadow = observer(function ScrollEdgeShadow({ model, top = 0, }) {
83
73
  const { classes, cx } = useStyles();
84
- const scrollableHeight = Math.max(0, contentHeight - viewportHeight);
74
+ const { scrollableHeight, scrollViewportHeight: viewportHeight } = model;
85
75
  if (scrollableHeight <= 0) {
86
76
  return null;
87
77
  }
88
- const clamped = clamp(scrollTop, 0, scrollableHeight);
89
- // never deeper than the viewport itself: the bottom edge is placed by
90
- // subtracting this from the viewport's floor, so an unclamped SHADOW_HEIGHT
91
- // on a viewport shorter than it puts the ink above the viewport's own top,
92
- // over whatever pinned band the display stacked there. Reachable both ways —
93
- // the variants displays floor availableHeight at 0 because lineZoneHeight can
94
- // exceed the display height on its own, and the pileup's coverage band drags
95
- // up to the same place.
78
+ const clamped = clamp(model.scrollTop, 0, scrollableHeight);
79
+ // never deeper than the viewport, or the bottom edge inks the band above it
96
80
  const height = Math.min(SHADOW_HEIGHT, viewportHeight);
97
81
  return (_jsxs(_Fragment, { children: [clamped > EPSILON ? (_jsx("div", { "data-testid": "scroll-edge-shadow-top", className: cx(classes.edge, classes.top), style: { top, height } })) : null, clamped < scrollableHeight - EPSILON ? (_jsx("div", { "data-testid": "scroll-edge-shadow-bottom", className: cx(classes.edge, classes.bottom), style: { top: top + viewportHeight - height, height } })) : null] }));
98
- }
82
+ });
83
+ export default ScrollEdgeShadow;
@@ -16,9 +16,9 @@ const useStyles = makeStyles()(theme => ({
16
16
  color: theme.palette.text.secondary,
17
17
  },
18
18
  }));
19
- // Many config values are `{ type: 'x' }` discriminated unions (colorBy,
20
- // groupBy, sortedBy, ...). Show just the type when that is the whole object so
21
- // the table reads "methylation" rather than `{"type":"methylation"}`; richer
19
+ // Many config values are `{ type: 'x' }` discriminated unions (sortedBy,
20
+ // ...). Show just the type when that is the whole object so
21
+ // the table reads "basePair" rather than `{"type":"basePair"}`; richer
22
22
  // objects keep full JSON so no detail is hidden.
23
23
  function isSoleTypeObject(v) {
24
24
  return ('type' in v && typeof v.type === 'string' && Object.keys(v).length === 1);
@@ -1,45 +1,24 @@
1
+ import type { VirtualScrollModel } from '../util/useVirtualScrollWheel.ts';
1
2
  /**
2
- * How much of a display's right edge this occupies while it is drawn.
3
- *
4
- * Exported because the things that have to *clear* it are drawn by the displays
5
- * that mount it, not by this file: the bottom-right indicator row and the
6
- * alignments coverage axis label. Both kept a private copy of the number (and
7
- * the alignments indicator row kept none at all, so its chips were drawn over
8
- * the thumb), which is a copy that can only be checked by looking at two files
9
- * at once.
3
+ * How much of a display's right edge this occupies while it is drawn, for the
4
+ * chrome the displays draw beside it.
10
5
  */
11
6
  export declare const VERTICAL_SCROLLBAR_WIDTH = 12;
12
- /**
13
- * Where the right edge of anything that has to sit *beside* the thumb goes: the
14
- * track's width plus a hair of air, so a chip or an axis label doesn't touch it.
15
- *
16
- * The four call sites all spelled `VERTICAL_SCROLLBAR_WIDTH + 2` inline, which
17
- * is the same copy the width constant was exported to stop — one addition
18
- * further along. The `+ 2` is a gap and belongs to the thing being cleared, not
19
- * to the scrollbar's own geometry, so it is named rather than folded into the
20
- * width (`right: 2` on the thumb is a different 2 and must not move with it).
21
- */
7
+ /** Where the right edge of something sitting beside the thumb goes. */
22
8
  export declare const VERTICAL_SCROLLBAR_CLEARANCE: number;
23
9
  /**
24
- * Draggable vertical scrollbar overlay for canvas-backed displays that scroll
25
- * their content via a `scrollTop` value (alignments pileup, variant matrix).
26
- * Renders nothing when the content fits the viewport. The thumb geometry and
27
- * the drag-to-scroll mapping live here so the consumers don't each re-derive
28
- * them; the wheel handling stays per-display (their gesture semantics differ).
10
+ * Draggable vertical scrollbar overlay for a virtually scrolled display.
11
+ * Renders nothing when the content fits.
29
12
  *
30
- * Deliberately NOT a keyboard tab stop: the surrounding views have no working
31
- * keyboard navigation to reach the scrolled content anyway, so a per-track
32
- * `tabIndex` would only add noise to the tab order. The `role="scrollbar"` +
33
- * `aria-value*` semantics are kept — they cost nothing and expose scroll
34
- * position to pointer/voice assistive tech.
13
+ * Not a keyboard tab stop: the views have no keyboard navigation to reach the
14
+ * scrolled content, so `tabIndex` would only add noise. The `role="scrollbar"`
15
+ * semantics stay for pointer and voice assistive tech.
35
16
  */
36
- export default function VerticalScrollbar({ scrollTop, setScrollTop, viewportHeight, contentHeight, controlsId, top, }: {
37
- scrollTop: number;
38
- setScrollTop: (n: number) => void;
39
- viewportHeight: number;
40
- contentHeight: number;
17
+ declare const VerticalScrollbar: ({ model, controlsId, top, }: {
18
+ model: VirtualScrollModel;
41
19
  /** `id` of the scrolled viewport element, for `aria-controls`. */
42
20
  controlsId: string;
43
21
  /** Track offset from the top, for displays with a sticky band above it. */
44
22
  top?: number;
45
- }): import("react").JSX.Element | null;
23
+ }) => import("react").JSX.Element | null;
24
+ export default VerticalScrollbar;