@jbrowse/plugin-linear-genome-view 5.0.0-beta.2 → 5.0.0-beta.20

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 (177) hide show
  1. package/esm/LinearGenomeView/afterAttach.d.ts +22 -5
  2. package/esm/LinearGenomeView/afterAttach.js +129 -106
  3. package/esm/LinearGenomeView/axisConfigSchema.d.ts +18 -0
  4. package/esm/LinearGenomeView/axisConfigSchema.js +22 -0
  5. package/esm/LinearGenomeView/components/CenterLine.js +10 -5
  6. package/esm/LinearGenomeView/components/ConnectedHoverHighlight.js +2 -3
  7. package/esm/LinearGenomeView/components/CrisprGuidePanel.js +3 -5
  8. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +9 -4
  9. package/esm/LinearGenomeView/components/ExportSvgDialog.js +45 -8
  10. package/esm/LinearGenomeView/components/GetSequenceDialog.js +2 -2
  11. package/esm/LinearGenomeView/components/Header.js +11 -1
  12. package/esm/LinearGenomeView/components/HeaderClearHighlightButton.js +2 -2
  13. package/esm/LinearGenomeView/components/HeaderPanControls.d.ts +3 -3
  14. package/esm/LinearGenomeView/components/HeaderPanControls.js +6 -3
  15. package/esm/LinearGenomeView/components/HeaderSearchBoxes.js +4 -1
  16. package/esm/LinearGenomeView/components/HeaderZoomControls.js +6 -35
  17. package/esm/LinearGenomeView/components/Highlight.js +27 -11
  18. package/esm/LinearGenomeView/components/HighlightBand.d.ts +11 -2
  19. package/esm/LinearGenomeView/components/HighlightBand.js +32 -13
  20. package/esm/LinearGenomeView/components/HighlightChip.d.ts +3 -3
  21. package/esm/LinearGenomeView/components/HighlightChip.js +13 -8
  22. package/esm/LinearGenomeView/components/HighlightLabelDialog.d.ts +6 -0
  23. package/esm/LinearGenomeView/components/HighlightLabelDialog.js +18 -0
  24. package/esm/LinearGenomeView/components/HoverPositionHighlight.js +3 -3
  25. package/esm/LinearGenomeView/components/ImportForm.js +7 -9
  26. package/esm/LinearGenomeView/components/LinearGenomeView.js +5 -12
  27. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +13 -14
  28. package/esm/LinearGenomeView/components/MiniControls.js +11 -5
  29. package/esm/LinearGenomeView/components/OverviewHighlight.js +3 -3
  30. package/esm/LinearGenomeView/components/OverviewHighlightBand.d.ts +3 -2
  31. package/esm/LinearGenomeView/components/OverviewHighlightBand.js +6 -5
  32. package/esm/LinearGenomeView/components/OverviewRubberband.js +25 -48
  33. package/esm/LinearGenomeView/components/OverviewScalebar.js +4 -5
  34. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +5 -3
  35. package/esm/LinearGenomeView/components/PaddingBlocks.js +3 -8
  36. package/esm/LinearGenomeView/components/RangeSelectOverlay.js +5 -6
  37. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.d.ts +3 -2
  38. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +4 -4
  39. package/esm/LinearGenomeView/components/ResizeAllTracksHandle.d.ts +5 -0
  40. package/esm/LinearGenomeView/components/ResizeAllTracksHandle.js +74 -0
  41. package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -2
  42. package/esm/LinearGenomeView/components/Rubberband.js +3 -2
  43. package/esm/LinearGenomeView/components/SVGHighlightBand.d.ts +10 -1
  44. package/esm/LinearGenomeView/components/SVGHighlightBand.js +16 -5
  45. package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -6
  46. package/esm/LinearGenomeView/components/Scalebar.js +8 -5
  47. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +51 -36
  48. package/esm/LinearGenomeView/components/SearchBox.js +10 -16
  49. package/esm/LinearGenomeView/components/SearchPanelForm.d.ts +3 -2
  50. package/esm/LinearGenomeView/components/SearchPanelForm.js +4 -2
  51. package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +4 -8
  52. package/esm/LinearGenomeView/components/SearchResultsDialog.js +7 -4
  53. package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +4 -7
  54. package/esm/LinearGenomeView/components/SearchResultsTable.js +25 -53
  55. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.js +2 -3
  56. package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +2 -4
  57. package/esm/LinearGenomeView/components/StrandCheckboxes.d.ts +3 -2
  58. package/esm/LinearGenomeView/components/StrandCheckboxes.js +4 -2
  59. package/esm/LinearGenomeView/components/TrackContainer.d.ts +2 -3
  60. package/esm/LinearGenomeView/components/TrackContainer.js +63 -10
  61. package/esm/LinearGenomeView/components/TrackLabel.js +14 -4
  62. package/esm/LinearGenomeView/components/TrackLabelButtons.js +2 -2
  63. package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +4 -5
  64. package/esm/LinearGenomeView/components/TrackLabelMenu.js +11 -14
  65. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.d.ts +3 -4
  66. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.js +23 -10
  67. package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +6 -4
  68. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +12 -24
  69. package/esm/LinearGenomeView/components/TracksContainer.js +11 -23
  70. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -2
  71. package/esm/LinearGenomeView/components/VerticalGuide.js +3 -16
  72. package/esm/LinearGenomeView/components/fetchSequence.d.ts +1 -2
  73. package/esm/LinearGenomeView/components/fetchSequence.js +15 -7
  74. package/esm/LinearGenomeView/components/recentLocationsMenu.js +10 -0
  75. package/esm/LinearGenomeView/components/useRangeSelect.d.ts +0 -3
  76. package/esm/LinearGenomeView/components/useRangeSelect.js +26 -61
  77. package/esm/LinearGenomeView/components/useSearchBoxPrefs.d.ts +3 -1
  78. package/esm/LinearGenomeView/components/useSearchBoxPrefs.js +4 -2
  79. package/esm/LinearGenomeView/components/useSideScroll.d.ts +17 -2
  80. package/esm/LinearGenomeView/components/useSideScroll.js +156 -102
  81. package/esm/LinearGenomeView/components/util.d.ts +4 -0
  82. package/esm/LinearGenomeView/components/util.js +4 -2
  83. package/esm/LinearGenomeView/consts.d.ts +2 -0
  84. package/esm/LinearGenomeView/consts.js +3 -1
  85. package/esm/LinearGenomeView/containingLgv.d.ts +21 -0
  86. package/esm/LinearGenomeView/containingLgv.js +23 -0
  87. package/esm/LinearGenomeView/headerFit.d.ts +4 -2
  88. package/esm/LinearGenomeView/headerFit.js +20 -7
  89. package/esm/LinearGenomeView/index.d.ts +2 -7
  90. package/esm/LinearGenomeView/index.js +5 -7
  91. package/esm/LinearGenomeView/keyboardHandler.d.ts +8 -7
  92. package/esm/LinearGenomeView/keyboardHandler.js +61 -23
  93. package/esm/LinearGenomeView/launchKeys.d.ts +1 -1
  94. package/esm/LinearGenomeView/launchKeys.js +11 -6
  95. package/esm/LinearGenomeView/lazyDialogs.d.ts +16 -3
  96. package/esm/LinearGenomeView/lazyDialogs.js +1 -0
  97. package/esm/LinearGenomeView/linkedViewSync.d.ts +3 -11
  98. package/esm/LinearGenomeView/linkedViewSync.js +27 -49
  99. package/esm/LinearGenomeView/menuItems.d.ts +16 -18
  100. package/esm/LinearGenomeView/menuItems.js +264 -164
  101. package/esm/LinearGenomeView/model.d.ts +1192 -560
  102. package/esm/LinearGenomeView/model.js +805 -590
  103. package/esm/LinearGenomeView/rExport/exportLinearView.d.ts +17 -0
  104. package/esm/LinearGenomeView/rExport/exportLinearView.js +117 -0
  105. package/esm/LinearGenomeView/rExport/rScript.d.ts +110 -0
  106. package/esm/LinearGenomeView/rExport/rScript.js +524 -0
  107. package/esm/LinearGenomeView/sharedScaleContainer.d.ts +1 -1
  108. package/esm/LinearGenomeView/sharedScaleContainer.js +2 -12
  109. package/esm/LinearGenomeView/showFiles.d.ts +2 -0
  110. package/esm/LinearGenomeView/showFiles.js +19 -0
  111. package/esm/LinearGenomeView/showRegionsWithUndo.d.ts +1 -1
  112. package/esm/LinearGenomeView/showRegionsWithUndo.js +13 -5
  113. package/esm/LinearGenomeView/stickyChrome.d.ts +5 -9
  114. package/esm/LinearGenomeView/stickyChrome.js +5 -9
  115. package/esm/LinearGenomeView/svgcomponents/SVGGridlines.js +4 -4
  116. package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +4 -1
  117. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +8 -21
  118. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.d.ts +3 -1
  119. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +9 -9
  120. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.d.ts +3 -1
  121. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +5 -5
  122. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +13 -18
  123. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +2 -5
  124. package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.js +5 -6
  125. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +9 -10
  126. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +3 -3
  127. package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.d.ts +26 -0
  128. package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.js +12 -0
  129. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +21 -13
  130. package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +4 -5
  131. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +7 -6
  132. package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +2 -3
  133. package/esm/LinearGenomeView/svgcomponents/SVGView.js +17 -3
  134. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +24 -20
  135. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +42 -29
  136. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +74 -77
  137. package/esm/LinearGenomeView/svgcomponents/util.d.ts +28 -12
  138. package/esm/LinearGenomeView/svgcomponents/util.js +41 -29
  139. package/esm/LinearGenomeView/types.d.ts +13 -10
  140. package/esm/LinearGenomeView/types.js +0 -1
  141. package/esm/LinearGenomeView/util.d.ts +103 -46
  142. package/esm/LinearGenomeView/util.js +222 -170
  143. package/esm/MultiLevelRubberband/MultiLevelRubberband.js +9 -6
  144. package/esm/MultiLevelRubberband/index.d.ts +2 -0
  145. package/esm/MultiLevelRubberband/index.js +2 -0
  146. package/esm/MultiLevelRubberband/menuItems.d.ts +34 -0
  147. package/esm/MultiLevelRubberband/menuItems.js +52 -0
  148. package/esm/MultiLevelRubberband/rowLabel.d.ts +22 -0
  149. package/esm/MultiLevelRubberband/rowLabel.js +27 -0
  150. package/esm/MultiLevelRubberband/types.d.ts +1 -0
  151. package/esm/MultiLevelRubberband/useRangeSelect.d.ts +2 -1
  152. package/esm/MultiLevelRubberband/useRangeSelect.js +45 -59
  153. package/esm/TrackModifiers/index.d.ts +83 -0
  154. package/esm/TrackModifiers/index.js +231 -0
  155. package/esm/displayKitTests/perRegionTestEnv.d.ts +244 -68
  156. package/esm/displayKitTests/perRegionTestEnv.js +30 -26
  157. package/esm/index.d.ts +21 -99
  158. package/esm/index.js +17 -38
  159. package/esm/searchUtils.d.ts +26 -10
  160. package/esm/searchUtils.js +137 -137
  161. package/esm/shared/RubberbandSpan.d.ts +3 -2
  162. package/esm/shared/RubberbandSpan.js +6 -3
  163. package/esm/shared/coordLabels.d.ts +11 -4
  164. package/esm/shared/coordLabels.js +20 -5
  165. package/esm/shared/useWindowDrag.d.ts +18 -0
  166. package/esm/shared/useWindowDrag.js +47 -0
  167. package/package.json +12 -11
  168. package/esm/FeatureTrack/configSchema.d.ts +0 -124
  169. package/esm/FeatureTrack/configSchema.js +0 -54
  170. package/esm/FeatureTrack/index.d.ts +0 -2
  171. package/esm/FeatureTrack/index.js +0 -13
  172. package/esm/LinearGenomeView/initKeys.d.ts +0 -12
  173. package/esm/LinearGenomeView/initKeys.js +0 -68
  174. package/esm/MultiLevelRubberband/VerticalGuide.d.ts +0 -6
  175. package/esm/MultiLevelRubberband/VerticalGuide.js +0 -21
  176. package/esm/lazyPluginExports.d.ts +0 -23
  177. package/esm/lazyPluginExports.js +0 -36
@@ -24,9 +24,9 @@ export function highlightedDisplays(model) {
24
24
  .filter(isFeatureHighlightCapable)
25
25
  .filter(d => d.featureHighlights.length > 0);
26
26
  }
27
- // Clears every highlight in the view at once. Shown only while there is one.
27
+ // Clears every feature highlight in the view. Shown only while there is one.
28
28
  const HeaderClearHighlightButton = observer(function HeaderClearHighlightButton({ highlighted, }) {
29
- return highlighted.length > 0 ? (_jsx(IconButton, { "data-testid": "clear_search_highlight", title: "Clear highlights", onClick: () => {
29
+ return highlighted.length > 0 ? (_jsx(IconButton, { "data-testid": "clear_search_highlight", title: "Clear feature highlights", onClick: () => {
30
30
  for (const d of highlighted) {
31
31
  d.clearFeatureHighlights();
32
32
  }
@@ -1,7 +1,7 @@
1
1
  import type { LinearGenomeViewModel } from '../index.ts';
2
2
  type LGV = LinearGenomeViewModel;
3
- export default function HeaderPanControls({ model, compact, }: {
3
+ declare const HeaderPanControls: ({ model, compact, }: {
4
4
  model: LGV;
5
5
  compact?: boolean;
6
- }): import("react").JSX.Element;
7
- export {};
6
+ }) => import("react").JSX.Element;
7
+ export default HeaderPanControls;
@@ -1,8 +1,10 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { alpha } from '@jbrowse/core/ui/palette';
2
3
  import { makeStyles } from '@jbrowse/core/util/tss-react';
3
4
  import ArrowBackIcon from '@mui/icons-material/ArrowBack';
4
5
  import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
5
- import { Button, alpha } from '@mui/material';
6
+ import { Button } from '@mui/material';
7
+ import { observer } from 'mobx-react';
6
8
  import { SPACING, WIDGET_HEIGHT } from '../consts.js';
7
9
  const useStyles = makeStyles()(theme => ({
8
10
  panButton: {
@@ -19,7 +21,7 @@ const useStyles = makeStyles()(theme => ({
19
21
  padding: theme.spacing(0, 0.5),
20
22
  },
21
23
  }));
22
- export default function HeaderPanControls({ model, compact, }) {
24
+ const HeaderPanControls = observer(function HeaderPanControls({ model, compact, }) {
23
25
  const { classes, cx } = useStyles();
24
26
  const className = cx(classes.panButton, compact && classes.compact);
25
27
  return (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "outlined", "aria-label": "Pan left", className: className, onClick: () => {
@@ -27,4 +29,5 @@ export default function HeaderPanControls({ model, compact, }) {
27
29
  }, children: _jsx(ArrowBackIcon, {}) }), _jsx(Button, { variant: "outlined", "aria-label": "Pan right", className: className, onClick: () => {
28
30
  model.slide(0.9);
29
31
  }, children: _jsx(ArrowForwardIcon, {}) })] }));
30
- }
32
+ });
33
+ export default HeaderPanControls;
@@ -13,8 +13,11 @@ const useStyles = makeStyles()(theme => ({
13
13
  display: 'flex',
14
14
  alignItems: 'center',
15
15
  gap: theme.spacing(0.5),
16
+ minWidth: 0,
16
17
  },
17
18
  }));
19
+ const MIN_BOX_WIDTH = 100;
20
+ const boxStyle = { margin: 0, minWidth: MIN_BOX_WIDTH };
18
21
  // One row's locate control in a header that stacks several linear genome views:
19
22
  // the compact search box, then the assembly name and the span on screen. The
20
23
  // comparative view and the breakpoint split view each draw one per row, and each
@@ -23,6 +26,6 @@ const useStyles = makeStyles()(theme => ({
23
26
  const HeaderSearchBoxes = observer(function HeaderSearchBoxes({ view, }) {
24
27
  const { classes } = useStyles();
25
28
  const { assemblyDisplayNames, coarseTotalBp } = view;
26
- return (_jsxs("span", { className: classes.searchBox, children: [_jsx(SearchBox, { model: view, showHelp: false, maxWidth: 250, minWidth: 100, style: { margin: 0 } }), _jsxs(Typography, { variant: "body2", color: "text.secondary", className: classes.bp, children: [assemblyDisplayNames.join(','), " ", getBpDisplayStr(coarseTotalBp)] })] }));
29
+ return (_jsxs("span", { className: classes.searchBox, children: [_jsx(SearchBox, { model: view, showHelp: false, maxWidth: 250, minWidth: MIN_BOX_WIDTH, style: boxStyle }), _jsxs(Typography, { variant: "body2", color: "text.secondary", className: classes.bp, children: [assemblyDisplayNames.join(','), " ", getBpDisplayStr(coarseTotalBp)] })] }));
27
30
  });
28
31
  export default HeaderSearchBoxes;
@@ -1,14 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { lazy, useState } from 'react';
2
+ import { useState } from 'react';
3
3
  import { SingleSlider } from '@jbrowse/core/ui';
4
4
  import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
5
- import { getBpDisplayStr, getDialogHost } from '@jbrowse/core/util';
5
+ import { getBpDisplayStr } from '@jbrowse/core/util';
6
6
  import { makeStyles } from '@jbrowse/core/util/tss-react';
7
7
  import MoreVert from '@mui/icons-material/MoreVert';
8
8
  import { observer } from 'mobx-react';
9
- import { showAllRegionsMenuItem } from '../menuItems.js';
9
+ import { zoomMenuItems } from '../menuItems.js';
10
10
  import ZoomButton from './ZoomButton.js';
11
- const RegionWidthEditorDialog = lazy(() => import('./RegionWidthEditorDialog.js'));
12
11
  const useStyles = makeStyles()(theme => ({
13
12
  container: {
14
13
  display: 'flex',
@@ -29,35 +28,6 @@ const useStyles = makeStyles()(theme => ({
29
28
  },
30
29
  },
31
30
  }));
32
- function getZoomMenuItems(model) {
33
- return [
34
- ...[10, 50, 100].map(r => ({
35
- label: `Zoom in ${r}x`,
36
- onClick: () => {
37
- model.zoom(model.bpPerPx / r);
38
- },
39
- })),
40
- ...[10, 50, 100].map(r => ({
41
- label: `Zoom out ${r}x`,
42
- onClick: () => {
43
- model.zoom(model.bpPerPx * r);
44
- },
45
- })),
46
- showAllRegionsMenuItem(model),
47
- {
48
- label: 'Custom zoom',
49
- onClick: () => {
50
- getDialogHost(model).queueDialog(handleClose => [
51
- RegionWidthEditorDialog,
52
- {
53
- model,
54
- handleClose,
55
- },
56
- ]);
57
- },
58
- },
59
- ];
60
- }
61
31
  // The slider tracks live `bpPerPx`, which changes on every animation frame of a
62
32
  // zoom. Isolated into its own observer so the surrounding zoom buttons/menu —
63
33
  // whose MUI Tooltip/IconButton machinery is comparatively expensive and only
@@ -67,11 +37,12 @@ const ZoomSlider = observer(function ZoomSlider({ model, }) {
67
37
  const { width, maxBpPerPx, minBpPerPx, bpPerPx } = model;
68
38
  const [dragValue, setDragValue] = useState(null);
69
39
  const value = dragValue ?? -Math.log2(bpPerPx) * 100;
40
+ const windowSize = (sliderValue) => `Window size: ${getBpDisplayStr(2 ** (-sliderValue / 100) * width)}`;
70
41
  return (_jsx(SingleSlider, { size: "small", className: classes.slider, value: value, min: -Math.log2(maxBpPerPx) * 100, max: -Math.log2(minBpPerPx) * 100, onChangeCommitted: val => {
71
42
  setDragValue(null);
72
43
  model.cancelZoomAnimation();
73
44
  model.zoomTo(2 ** (-val / 100));
74
- }, valueLabelDisplay: "auto", valueLabelFormat: newValue => `Window size: ${getBpDisplayStr(2 ** (-newValue / 100) * width)}`, onChange: val => {
45
+ }, valueLabelDisplay: "auto", "aria-label": "Zoom level", valueLabelFormat: newValue => windowSize(newValue), getAriaValueText: newValue => windowSize(newValue), onChange: val => {
75
46
  // Take over from any in-flight animated zoom as soon as the user grabs
76
47
  // the thumb, so the view stops lurching underneath the drag.
77
48
  if (dragValue === null) {
@@ -82,6 +53,6 @@ const ZoomSlider = observer(function ZoomSlider({ model, }) {
82
53
  });
83
54
  const HeaderZoomControls = observer(function HeaderZoomControls({ model, showSlider = true, }) {
84
55
  const { classes } = useStyles();
85
- return (_jsxs("div", { className: classes.container, children: [_jsx(ZoomButton, { model: model, direction: "out" }), showSlider ? _jsx(ZoomSlider, { model: model }) : null, _jsx(ZoomButton, { model: model, direction: "in" }), _jsx(CascadingMenuButton, { menuItems: () => getZoomMenuItems(model), children: _jsx(MoreVert, {}) })] }));
56
+ return (_jsxs("div", { className: classes.container, children: [_jsx(ZoomButton, { model: model, direction: "out" }), showSlider ? _jsx(ZoomSlider, { model: model }) : null, _jsx(ZoomButton, { model: model, direction: "in" }), _jsx(CascadingMenuButton, { tooltip: "Zoom options", menuItems: () => zoomMenuItems(model), children: _jsx(MoreVert, {}) })] }));
86
57
  });
87
58
  export default HeaderZoomControls;
@@ -1,28 +1,44 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useHighlightChip } from '@jbrowse/core/ui/highlightChipReveal';
2
+ import { useStyleTheme } from '@jbrowse/core/ui/PaletteContext';
3
3
  import { getSession } from '@jbrowse/core/util';
4
4
  import CloseIcon from '@mui/icons-material/Close';
5
+ import EditIcon from '@mui/icons-material/Edit';
5
6
  import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
6
- import { useTheme } from '@mui/material';
7
7
  import { observer } from 'mobx-react';
8
8
  import HighlightBand from './HighlightBand.js';
9
9
  import HighlightChip from './HighlightChip.js';
10
+ import HighlightLabelDialog from './HighlightLabelDialog.js';
10
11
  import { getHighlightColor } from './util.js';
11
- // A band narrower than the link-icon chip clips it into a smudge, so below this
12
- // width the chip is dropped (the band itself still draws).
13
- const CHIP_MIN_WIDTH = 24;
14
12
  const Highlight = observer(function Highlight({ model, highlight, }) {
15
- const theme = useTheme();
13
+ const theme = useStyleTheme();
16
14
  const coords = model.getHighlightCoords(highlight);
17
15
  const bandColor = getHighlightColor(highlight, theme);
18
- const label = model.labelsVisible ? highlight.label : undefined;
19
- const { chipVisible, setMenuOpen } = useHighlightChip(coords, model.showHighlightChips);
20
- return coords ? (_jsx(HighlightBand, { coords: coords, background: bandColor.toRgbString(), label: label, children: chipVisible && coords.width >= CHIP_MIN_WIDTH ? (_jsx(HighlightChip, { color: bandColor, label: label, tooltip: highlight.label ?? 'Highlighted region', setOpen: setMenuOpen, menuItems: [
16
+ const label = getSession(model).highlightLabelsVisible
17
+ ? highlight.label
18
+ : undefined;
19
+ return coords ? (_jsx(HighlightBand, { coords: coords, background: bandColor.toRgbString(), label: label, gaps: model.nonGenomicTrackBands(), children: _jsx(HighlightChip, { color: bandColor, label: label, tooltip: highlight.label ?? 'Highlighted region', menuItems: [
20
+ {
21
+ label: 'Edit label...',
22
+ icon: EditIcon,
23
+ onClick: () => {
24
+ const session = getSession(model);
25
+ session.queueDialog(handleClose => [
26
+ HighlightLabelDialog,
27
+ {
28
+ label: highlight.label,
29
+ onSubmit: (label) => {
30
+ session.updateHighlight(highlight, { label });
31
+ },
32
+ handleClose,
33
+ },
34
+ ]);
35
+ },
36
+ },
21
37
  {
22
38
  label: 'Dismiss highlight',
23
39
  icon: CloseIcon,
24
40
  onClick: () => {
25
- model.removeHighlight(highlight);
41
+ getSession(model).removeHighlight(highlight);
26
42
  },
27
43
  },
28
44
  {
@@ -33,6 +49,6 @@ const Highlight = observer(function Highlight({ model, highlight, }) {
33
49
  },
34
50
  },
35
51
  ...model.highlightMenuItems(highlight),
36
- ] })) : null })) : null;
52
+ ] }) })) : null;
37
53
  });
38
54
  export default Highlight;
@@ -1,9 +1,18 @@
1
- export default function HighlightBand({ coords, background, label, children, }: {
1
+ export declare function gapMask(gaps: {
2
+ top: number;
3
+ height: number;
4
+ }[]): string;
5
+ declare const HighlightBand: ({ coords, background, label, gaps, children, }: {
2
6
  coords: {
3
7
  left: number;
4
8
  width: number;
5
9
  };
6
10
  background: string;
7
11
  label?: string;
12
+ gaps?: {
13
+ top: number;
14
+ height: number;
15
+ }[];
8
16
  children?: React.ReactNode;
9
- }): import("react").JSX.Element;
17
+ }) => import("react").JSX.Element;
18
+ export default HighlightBand;
@@ -1,6 +1,7 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { makeStyles } from '@jbrowse/core/util/tss-react';
3
3
  import { Typography } from '@mui/material';
4
+ import { observer } from 'mobx-react';
4
5
  const useStyles = makeStyles()(theme => ({
5
6
  highlight: {
6
7
  height: '100%',
@@ -15,26 +16,44 @@ const useStyles = makeStyles()(theme => ({
15
16
  zIndex: 1,
16
17
  pointerEvents: 'none',
17
18
  },
19
+ // a sibling of the band, so a label wider than a narrow band runs past its
20
+ // right edge. No `top`: its static position is the band's top edge, where
21
+ // the first track's TrackLabel (zIndex 200) would otherwise cover it
18
22
  overlay: {
19
23
  position: 'absolute',
20
- top: 0,
21
24
  left: 3,
25
+ zIndex: 201,
26
+ pointerEvents: 'none',
27
+ whiteSpace: 'nowrap',
22
28
  },
23
29
  label: {
24
30
  color: theme.palette.text.primary,
25
31
  },
26
32
  }));
27
- // Shared band renderer for LGV and grid-bookmark highlights; OverviewHighlight
28
- // stays separate (different bpToPx API). A non-interactive colored band with an
29
- // optional top label; when `children` (the highlight chip) is passed it renders
30
- // that instead of the plain label. Visibility is toggled from the view menu
31
- export default function HighlightBand({ coords, background, label, children, }) {
33
+ export function gapMask(gaps) {
34
+ const stops = gaps.flatMap(g => [
35
+ `#000 ${g.top}px`,
36
+ `transparent ${g.top}px`,
37
+ `transparent ${g.top + g.height}px`,
38
+ `#000 ${g.top + g.height}px`,
39
+ ]);
40
+ return `linear-gradient(to bottom, ${stops.join(', ')})`;
41
+ }
42
+ // A colored band with an optional top label; when `children` (the highlight
43
+ // chip) is passed it renders that instead of the plain label. Clicks fall
44
+ // through it to the tracks, which is what keeps it apart from the hoverable
45
+ // OverviewHighlightBand. Visibility is toggled from the view menu
46
+ const HighlightBand = observer(function HighlightBand({ coords, background, label, gaps, children, }) {
32
47
  const { classes } = useStyles();
48
+ const mask = gaps?.length ? gapMask(gaps) : undefined;
33
49
  const content = children ??
34
50
  (label ? (_jsx(Typography, { variant: "caption", className: classes.label, noWrap: true, children: label })) : null);
35
- return (_jsx("div", { "data-testid": "highlight-band", className: classes.highlight, style: {
36
- transform: `translateX(${coords.left}px)`,
37
- width: coords.width,
38
- background,
39
- }, children: coords.width > 3 && content ? (_jsx("div", { className: classes.overlay, children: content })) : null }));
40
- }
51
+ return (_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "highlight-band", className: classes.highlight, style: {
52
+ transform: `translateX(${coords.left}px)`,
53
+ width: coords.width,
54
+ background,
55
+ maskImage: mask,
56
+ WebkitMaskImage: mask,
57
+ } }), content ? (_jsx("div", { className: classes.overlay, style: { transform: `translateX(${coords.left}px)` }, children: content })) : null] }));
58
+ });
59
+ export default HighlightBand;
@@ -1,9 +1,9 @@
1
1
  import type { MenuItem } from '@jbrowse/core/ui';
2
2
  import type { Colord } from '@jbrowse/core/util/colord';
3
- export default function HighlightChip({ color, label, tooltip, menuItems, setOpen, }: {
3
+ declare const HighlightChip: ({ color, label, tooltip, menuItems, }: {
4
4
  color: Colord;
5
5
  label?: string;
6
6
  tooltip?: string;
7
7
  menuItems: MenuItem[];
8
- setOpen?: (arg: boolean) => void;
9
- }): import("react").JSX.Element;
8
+ }) => import("react").JSX.Element;
9
+ export default HighlightChip;
@@ -2,14 +2,19 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
3
3
  import LinkIcon from '@mui/icons-material/Link';
4
4
  import { Box, Tooltip, Typography } from '@mui/material';
5
- // Interactive chip drawn inside a highlight band while the band is revealing it
6
- // (see `useHighlightChip`): a link icon tinted to the band color plus an
7
- // optional inline label, wrapped in a context menu. Sets its own pointer-events
8
- // since the band is click-through. `setOpen` is how the band learns to keep the
9
- // chip drawn while the menu is up.
10
- export default function HighlightChip({ color, label, tooltip, menuItems, setOpen, }) {
5
+ import { observer } from 'mobx-react';
6
+ // Interactive chip at a highlight band's top: a link icon tinted to the band
7
+ // color plus an optional inline label, wrapped in a context menu. Its own
8
+ // background keeps it legible over the first track's label, and it sets its own
9
+ // pointer-events since the band is click-through.
10
+ const HighlightChip = observer(function HighlightChip({ color, label, tooltip, menuItems, }) {
11
11
  // hide the icon color when the band is fully transparent ("label-only"
12
12
  // highlight); otherwise bump to 0.8 alpha so the chip stays legible
13
13
  const chipAlpha = color.alpha() === 0 ? 0 : 0.8;
14
- return (_jsx(Box, { sx: { pointerEvents: 'auto' }, children: _jsx(CascadingMenuButton, { "data-testid": "highlight-chip", menuItems: menuItems, setOpen: setOpen, children: _jsx(Tooltip, { title: tooltip, arrow: true, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 0.5 }, children: [_jsx(LinkIcon, { fontSize: "small", sx: { color: color.alpha(chipAlpha).toRgbString() } }), label ? (_jsx(Typography, { variant: "caption", noWrap: true, children: label })) : null] }) }) }) }));
15
- }
14
+ return (_jsx(Box, { sx: {
15
+ pointerEvents: 'auto',
16
+ bgcolor: 'background.paper',
17
+ borderRadius: 1,
18
+ }, children: _jsx(CascadingMenuButton, { "data-testid": "highlight-chip", menuItems: menuItems, children: _jsx(Tooltip, { title: tooltip, arrow: true, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 0.5 }, children: [_jsx(LinkIcon, { fontSize: "small", sx: { color: color.alpha(chipAlpha).toRgbString() } }), label ? (_jsx(Typography, { variant: "caption", noWrap: true, children: label })) : null] }) }) }) }));
19
+ });
20
+ export default HighlightChip;
@@ -0,0 +1,6 @@
1
+ declare const HighlightLabelDialog: ({ label, onSubmit, handleClose, }: {
2
+ label?: string;
3
+ onSubmit: (label: string | undefined) => void;
4
+ handleClose: () => void;
5
+ }) => import("react").JSX.Element;
6
+ export default HighlightLabelDialog;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { SubmitDialog } from '@jbrowse/core/ui';
4
+ import { TextField } from '@mui/material';
5
+ import { observer } from 'mobx-react';
6
+ // Names a highlight. The label is written on the band and in every view that
7
+ // draws the session's highlights, such as an alignment's column or a
8
+ // structure's residue; an empty label leaves the highlight unnamed.
9
+ const HighlightLabelDialog = observer(function HighlightLabelDialog({ label, onSubmit, handleClose, }) {
10
+ const [val, setVal] = useState(label ?? '');
11
+ return (_jsx(SubmitDialog, { open: true, maxWidth: "xs", fullWidth: true, title: "Edit highlight label", onCancel: handleClose, onSubmit: () => {
12
+ onSubmit(val.trim() || undefined);
13
+ handleClose();
14
+ }, children: _jsx(TextField, { label: "Label", autoFocus: true, fullWidth: true, variant: "outlined", value: val, onChange: event => {
15
+ setVal(event.target.value);
16
+ } }) }));
17
+ });
18
+ export default HighlightLabelDialog;
@@ -6,9 +6,9 @@ const useStyles = makeStyles()(theme => ({
6
6
  highlight: {
7
7
  height: '100%',
8
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}`,
9
+ background: alpha(theme.palette.accent, 0.4),
10
+ borderLeft: `2px solid ${theme.palette.accent}`,
11
+ borderRight: `2px solid ${theme.palette.accent}`,
12
12
  pointerEvents: 'none',
13
13
  zIndex: 10,
14
14
  },
@@ -20,9 +20,8 @@ const useStyles = makeStyles()(theme => ({
20
20
  const LinearGenomeViewImportForm = observer(function LinearGenomeViewImportForm({ model, }) {
21
21
  const { classes } = useStyles();
22
22
  const session = getSession(model);
23
- const { textSearchManager } = session;
24
23
  const { error: viewError } = model;
25
- const { selectedAssemblyName: selectedAsm, setSelectedAssemblyName, assembly, assemblyError, regions, } = useAssemblySelection(session, 'lgv');
24
+ const { selectedAssemblyName: selectedAsm, setSelectedAssemblyName, assemblyError, regions, } = useAssemblySelection(session, 'lgv');
26
25
  const { recentLocations, addRecentLocation, clearRecentLocations } = useRecentLocations(selectedAsm);
27
26
  // The location the form will open, tagged with the assembly it was entered
28
27
  // for, and read back only while that tag still matches. Switching assembly
@@ -45,12 +44,12 @@ const LinearGenomeViewImportForm = observer(function LinearGenomeViewImportForm(
45
44
  model.setError(undefined);
46
45
  if (selectedAsm) {
47
46
  try {
48
- await navigateToSelectedOption({
47
+ const moved = await navigateToSelectedOption({
49
48
  option,
50
49
  model,
51
50
  assemblyName: selectedAsm,
52
51
  });
53
- if (record) {
52
+ if (record && moved) {
54
53
  addRecentLocation(recentLocationOf(option));
55
54
  }
56
55
  }
@@ -62,7 +61,7 @@ const LinearGenomeViewImportForm = observer(function LinearGenomeViewImportForm(
62
61
  const recentMenuItems = recentLocationsMenu({
63
62
  recentLocations,
64
63
  onNavigate: option => {
65
- navigate({ option, record: true }).catch(() => { });
64
+ void navigate({ option, record: true });
66
65
  },
67
66
  onClear: clearRecentLocations,
68
67
  });
@@ -84,12 +83,11 @@ const LinearGenomeViewImportForm = observer(function LinearGenomeViewImportForm(
84
83
  // reason.
85
84
  model.setError(undefined);
86
85
  setSelectedAssemblyName(val);
87
- }, session: session, selected: selectedAsm }), selectedAsm ? (assemblyError ? (_jsx(CloseIcon, { color: "error" })) : regions ? (_jsx(RefNameAutocomplete, { fetchResults: (queryString, stopToken) => fetchResults({
86
+ }, session: session, selected: selectedAsm }), selectedAsm ? (assemblyError ? (_jsx(CloseIcon, { color: "error" })) : regions ? (_jsx(RefNameAutocomplete, { fetchResults: (queryString, signal) => fetchResults({
87
+ session,
88
88
  queryString,
89
- assembly,
90
- textSearchManager,
91
89
  assemblyName: selectedAsm,
92
- stopToken,
90
+ signal,
93
91
  }), session: session, assemblyName: selectedAsm, value: value, minWidth: 270, adornmentWidth: adornmentReservePx({
94
92
  menuItemCount: recentMenuItems.length,
95
93
  }), onChange: v => {
@@ -1,20 +1,13 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { lazy } from 'react';
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Suspense, lazy } from 'react';
3
3
  import { ViewLoadingScreen } from '@jbrowse/core/ui';
4
4
  import { observer } from 'mobx-react';
5
5
  import LinearGenomeViewContainer from './LinearGenomeViewContainer.js';
6
6
  // lazies
7
7
  const ImportForm = lazy(() => import('./ImportForm.js'));
8
+ const SearchResultsDialog = lazy(() => import('./SearchResultsDialog.js'));
8
9
  const LinearGenomeView = observer(function LinearGenomeView({ model, }) {
9
- const { showLoading, showImportForm, loadingMessage, loadingProgress } = model;
10
- if (showLoading) {
11
- return (_jsx(ViewLoadingScreen, { message: loadingMessage, fraction: loadingProgress, source: model.loadingSource }));
12
- }
13
- else if (showImportForm) {
14
- return _jsx(ImportForm, { model: model });
15
- }
16
- else {
17
- return _jsx(LinearGenomeViewContainer, { model: model });
18
- }
10
+ const { loading, showImportForm, searchPicker } = model;
11
+ return (_jsxs(_Fragment, { children: [loading ? (_jsx(ViewLoadingScreen, { ...loading })) : showImportForm ? (_jsx(ImportForm, { model: model })) : (_jsx(LinearGenomeViewContainer, { model: model })), searchPicker ? (_jsx(Suspense, { fallback: null, children: _jsx(SearchResultsDialog, { model: model }) })) : null] }));
19
12
  });
20
13
  export default LinearGenomeView;
@@ -1,5 +1,5 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Suspense, lazy, useEffect, useRef } from 'react';
2
+ import { useEffect, useRef } from 'react';
3
3
  import { VIEW_HEADER_HEIGHT } from '@jbrowse/core/ui';
4
4
  import { getSession } from '@jbrowse/core/util';
5
5
  import { LGV_HEADER_HEIGHT_VAR, SCROLL_PORT_HEIGHT_VAR, VIEW_HEADER_HEIGHT_VAR, useChromeHeightVar, useFocusOnInteraction, } from '@jbrowse/core/util/hooks';
@@ -7,17 +7,15 @@ import { makeStyles } from '@jbrowse/core/util/tss-react';
7
7
  import { useWheelZoom } from '@jbrowse/core/util/usePanZoom';
8
8
  import Paper from '@mui/material/Paper';
9
9
  import { observer } from 'mobx-react';
10
- import { SCALE_BAR_HEIGHT } from '../consts.js';
11
10
  import { stickyChromeTops } from '../stickyChrome.js';
12
11
  import Header from './Header.js';
13
12
  import MiniControls from './MiniControls.js';
14
13
  import NavigationAnnouncer from './NavigationAnnouncer.js';
14
+ import NoTracksActiveButton from './NoTracksActiveButton.js';
15
+ import ResizeAllTracksHandle from './ResizeAllTracksHandle.js';
15
16
  import Rubberband from './Rubberband.js';
16
- import Scalebar from './Scalebar.js';
17
17
  import TrackContainer from './TrackContainer.js';
18
18
  import TracksContainer from './TracksContainer.js';
19
- // lazies
20
- const NoTracksActiveButton = lazy(() => import('./NoTracksActiveButton.js'));
21
19
  const useStyles = makeStyles()(theme => ({
22
20
  header: {
23
21
  background: theme.palette.background.paper,
@@ -101,18 +99,19 @@ const LinearGenomeViewContainer = observer(function LinearGenomeViewContainer({
101
99
  // alone. At most one display can be under the pointer, so the first
102
100
  // non-empty answer is the answer.
103
101
  const hoverFeature = tracks
104
- .flatMap(t => t.displays)
102
+ .flatMap((t) => t.displays)
105
103
  .map(d => d.hoveredFeature)
106
104
  .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: {
105
+ // `viewId` lets a view paired with one linear view ignore another
106
+ // showing the same locus
107
+ session.setHovered({ hoverPosition, hoverFeature, viewId: model.id });
108
+ }, children: [_jsx(NavigationAnnouncer, { model: model }), _jsxs("div", { ref: headerRef, "data-testid": `lgv-header-${model.id}`, 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 })) : (_jsx(TracksContainer, { model: model, children: !tracks.length ? (_jsx(NoTracksActiveButton, { model: model })) : (_jsxs(_Fragment, { children: [pinnedTracks.length ? (_jsx(Paper, { elevation: 2, "data-testid": "pinned-tracks", className: classes.pinnedTracks, style: {
109
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
110
+ // the scroll port this sticks in, not the window: a
111
+ // workspace cell, or the host's box when embedded. The
112
+ // fallback is what an unbounded embed gets, where the
113
+ // page itself is the scroller
115
114
  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)))] })) })) })] }) }));
115
+ }, children: pinnedTracks.map(track => (_jsx(TrackContainer, { model: model, track: track }, track.id))) })) : null, unpinnedTracks.map(track => (_jsx(TrackContainer, { model: model, track: track }, track.id))), _jsx(ResizeAllTracksHandle, { model: model })] })) })) })] }) }));
117
116
  });
118
117
  export default LinearGenomeViewContainer;
@@ -1,33 +1,39 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
3
3
  import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons';
4
+ import { alpha } from '@jbrowse/core/ui/palette';
4
5
  import { getSession } from '@jbrowse/core/util';
5
6
  import { makeStyles } from '@jbrowse/core/util/tss-react';
6
7
  import AddIcon from '@mui/icons-material/Add';
7
8
  import MoreVertIcon from '@mui/icons-material/MoreVert';
8
9
  import RemoveIcon from '@mui/icons-material/Remove';
9
- import { IconButton, Paper, Tooltip, alpha } from '@mui/material';
10
+ import { IconButton, Paper, Tooltip } from '@mui/material';
10
11
  import { observer } from 'mobx-react';
11
12
  import ZoomButton from './ZoomButton.js';
12
13
  const useStyles = makeStyles()(theme => ({
13
14
  background: {
14
15
  position: 'absolute',
15
16
  right: 0,
16
- background: theme.palette.background.paper,
17
17
  // needed when sticky header is off in lgv, e.g. in breakpoint split view
18
18
  zIndex: 2,
19
19
  },
20
20
  focusedBackground: {
21
- background: alpha(theme.palette.secondary.light, 0.2),
21
+ backgroundColor: alpha(theme.palette.secondary.light, 0.2),
22
22
  },
23
23
  }));
24
24
  const MiniControls = observer(function MiniControls({ model, }) {
25
25
  const { classes } = useStyles();
26
26
  const { id, scalebarOnly } = model;
27
27
  const { focusedViewId } = getSession(model);
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: () => {
28
+ // A ruler-only row is shorter than these controls, so they rise from the
29
+ // ruler's bottom edge rather than hang from its top: a nested row always has
30
+ // chrome above it, while the last row of a stack has only the view's frame
31
+ // below.
32
+ return (_jsx(Paper, { "data-testid": "lgv-mini-controls", className: classes.background, style: scalebarOnly
33
+ ? { top: model.scalebarHeight, transform: 'translateY(-100%)' }
34
+ : undefined, children: _jsxs(Paper, { className: focusedViewId === id ? classes.focusedBackground : undefined, children: [_jsx(Tooltip, { title: "Open track selector", children: _jsx(IconButton, { size: "small", onClick: () => {
29
35
  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: () => {
36
+ }, children: _jsx(TrackSelectorIcon, { fontSize: "small" }) }) }), _jsx(CascadingMenuButton, { tooltip: "View menu", menuItems: () => model.menuItems(), children: _jsx(MoreVertIcon, { fontSize: "small" }) }), _jsx(Tooltip, { title: scalebarOnly ? 'Show tracks' : 'Show ruler only', children: _jsx(IconButton, { size: "small", onClick: () => {
31
37
  model.setScalebarOnly(!scalebarOnly);
32
38
  }, 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 })] }) }));
33
39
  });
@@ -1,17 +1,17 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useStyleTheme } from '@jbrowse/core/ui/PaletteContext';
2
3
  import { getSession, notEmpty } from '@jbrowse/core/util';
3
4
  import { colord } from '@jbrowse/core/util/colord';
4
- import { useTheme } from '@mui/material';
5
5
  import { observer } from 'mobx-react';
6
6
  import OverviewHighlightBand from './OverviewHighlightBand.js';
7
7
  import { getHighlightColor, highlightKey } from './util.js';
8
8
  const OverviewHighlight = observer(function OverviewHighlight({ model, }) {
9
- const theme = useTheme();
9
+ const theme = useStyleTheme();
10
10
  const themed = colord(theme.palette.highlight.main);
11
11
  // gate on highlightsVisible to match the main-view band, scalebar band, and
12
12
  // SVG export — otherwise "Turn off highlights" leaves the overview bands up
13
13
  return getSession(model).highlightsVisible
14
- ? model.highlight
14
+ ? model.highlights
15
15
  .map(highlight => {
16
16
  const coords = model.getOverviewHighlightCoords(highlight);
17
17
  return coords ? { coords, highlight } : undefined;
@@ -1,4 +1,4 @@
1
- export default function OverviewHighlightBand({ coords, background, borderColor, tooltip, }: {
1
+ declare const OverviewHighlightBand: ({ coords, background, borderColor, tooltip, }: {
2
2
  coords: {
3
3
  left: number;
4
4
  width: number;
@@ -6,4 +6,5 @@ export default function OverviewHighlightBand({ coords, background, borderColor,
6
6
  background: string;
7
7
  borderColor?: string;
8
8
  tooltip?: string;
9
- }): import("react").JSX.Element;
9
+ }) => import("react").JSX.Element;
10
+ export default OverviewHighlightBand;