@jbrowse/plugin-linear-genome-view 3.0.5 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/BaseLinearDisplay/components/BlockErrorMessage.d.ts +7 -0
  2. package/dist/BaseLinearDisplay/components/{BlockError.js → BlockErrorMessage.js} +6 -3
  3. package/dist/BaseLinearDisplay/components/BlockLoadingMessage.d.ts +6 -0
  4. package/dist/BaseLinearDisplay/components/BlockLoadingMessage.js +26 -0
  5. package/dist/BaseLinearDisplay/components/BlockMsg.js +4 -2
  6. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +4 -24
  7. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +9 -9
  8. package/dist/LaunchLinearGenomeView/index.js +9 -5
  9. package/dist/LinearGenomeView/components/CenterLine.js +1 -1
  10. package/dist/LinearGenomeView/components/Gridlines.d.ts +2 -1
  11. package/dist/LinearGenomeView/components/Gridlines.js +3 -4
  12. package/dist/LinearGenomeView/components/Header.js +2 -0
  13. package/dist/LinearGenomeView/components/LinearGenomeView.js +2 -49
  14. package/dist/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +5 -0
  15. package/dist/LinearGenomeView/components/LinearGenomeViewContainer.js +98 -0
  16. package/dist/LinearGenomeView/components/MiniControls.js +0 -1
  17. package/dist/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
  18. package/dist/LinearGenomeView/components/OverviewRubberband.js +2 -15
  19. package/dist/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +10 -0
  20. package/dist/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +36 -0
  21. package/dist/LinearGenomeView/components/Rubberband.js +7 -2
  22. package/dist/LinearGenomeView/components/RubberbandSpan.d.ts +3 -1
  23. package/dist/LinearGenomeView/components/RubberbandSpan.js +13 -25
  24. package/dist/LinearGenomeView/components/RubberbandTooltip.d.ts +5 -0
  25. package/dist/LinearGenomeView/components/RubberbandTooltip.js +28 -0
  26. package/dist/LinearGenomeView/components/Scalebar.js +2 -2
  27. package/dist/LinearGenomeView/components/TrackContainer.js +9 -4
  28. package/dist/LinearGenomeView/components/TrackLabel.js +1 -1
  29. package/dist/LinearGenomeView/components/TrackLabelContainer.js +1 -1
  30. package/dist/LinearGenomeView/components/TrackLabelMenu.js +21 -0
  31. package/dist/LinearGenomeView/components/TrackRenderingContainer.js +0 -1
  32. package/dist/LinearGenomeView/components/TracksContainer.js +3 -4
  33. package/dist/LinearGenomeView/components/VerticalGuide.js +12 -5
  34. package/dist/LinearGenomeView/model.d.ts +31 -3
  35. package/dist/LinearGenomeView/model.js +84 -24
  36. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +2 -2
  37. package/dist/LinearGenomeView/types.d.ts +5 -0
  38. package/esm/BaseLinearDisplay/components/BlockErrorMessage.d.ts +7 -0
  39. package/esm/BaseLinearDisplay/components/{BlockError.js → BlockErrorMessage.js} +6 -3
  40. package/esm/BaseLinearDisplay/components/BlockLoadingMessage.d.ts +6 -0
  41. package/esm/BaseLinearDisplay/components/BlockLoadingMessage.js +24 -0
  42. package/esm/BaseLinearDisplay/components/BlockMsg.js +4 -2
  43. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +4 -24
  44. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +9 -9
  45. package/esm/LaunchLinearGenomeView/index.js +9 -5
  46. package/esm/LinearGenomeView/components/CenterLine.js +1 -1
  47. package/esm/LinearGenomeView/components/Gridlines.d.ts +2 -1
  48. package/esm/LinearGenomeView/components/Gridlines.js +3 -4
  49. package/esm/LinearGenomeView/components/Header.js +2 -0
  50. package/esm/LinearGenomeView/components/LinearGenomeView.js +3 -50
  51. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +5 -0
  52. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +60 -0
  53. package/esm/LinearGenomeView/components/MiniControls.js +0 -1
  54. package/esm/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
  55. package/esm/LinearGenomeView/components/OverviewRubberband.js +3 -16
  56. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +10 -0
  57. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +34 -0
  58. package/esm/LinearGenomeView/components/Rubberband.js +7 -2
  59. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +3 -1
  60. package/esm/LinearGenomeView/components/RubberbandSpan.js +11 -26
  61. package/esm/LinearGenomeView/components/RubberbandTooltip.d.ts +5 -0
  62. package/esm/LinearGenomeView/components/RubberbandTooltip.js +25 -0
  63. package/esm/LinearGenomeView/components/Scalebar.js +2 -2
  64. package/esm/LinearGenomeView/components/TrackContainer.js +9 -4
  65. package/esm/LinearGenomeView/components/TrackLabel.js +1 -1
  66. package/esm/LinearGenomeView/components/TrackLabelContainer.js +1 -1
  67. package/esm/LinearGenomeView/components/TrackLabelMenu.js +21 -0
  68. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +0 -1
  69. package/esm/LinearGenomeView/components/TracksContainer.js +3 -4
  70. package/esm/LinearGenomeView/components/VerticalGuide.js +13 -6
  71. package/esm/LinearGenomeView/model.d.ts +31 -3
  72. package/esm/LinearGenomeView/model.js +84 -24
  73. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +2 -2
  74. package/esm/LinearGenomeView/types.d.ts +5 -0
  75. package/package.json +3 -3
  76. package/dist/BaseLinearDisplay/components/BlockError.d.ts +0 -4
  77. package/esm/BaseLinearDisplay/components/BlockError.d.ts +0 -4
@@ -0,0 +1,6 @@
1
+ declare const BlockLoadingMessage: ({ model, }: {
2
+ model: {
3
+ status?: string;
4
+ };
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ export default BlockLoadingMessage;
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { LoadingEllipses } from '@jbrowse/core/ui';
3
+ import { observer } from 'mobx-react';
4
+ import { getParent } from 'mobx-state-tree';
5
+ import { makeStyles } from 'tss-react/mui';
6
+ const useStyles = makeStyles()(theme => {
7
+ const bg = theme.palette.action.disabledBackground;
8
+ return {
9
+ loading: {
10
+ paddingLeft: '0.6em',
11
+ backgroundColor: theme.palette.background.default,
12
+ backgroundImage: `repeating-linear-gradient(45deg, transparent, transparent 5px, ${bg} 5px, ${bg} 10px)`,
13
+ textAlign: 'center',
14
+ },
15
+ };
16
+ });
17
+ const BlockLoadingMessage = observer(function ({ model, }) {
18
+ const { classes } = useStyles();
19
+ const { status: blockStatus } = model;
20
+ const { message: displayStatus } = getParent(model, 2);
21
+ const status = displayStatus || blockStatus;
22
+ return (_jsx("div", { className: classes.loading, children: _jsx(LoadingEllipses, { message: status }) }));
23
+ });
24
+ export default BlockLoadingMessage;
@@ -9,7 +9,9 @@ const useStyles = makeStyles()({
9
9
  });
10
10
  export default function BlockMsg({ message, severity, action, }) {
11
11
  const { classes } = useStyles();
12
- return (_jsx(Alert, { onClick: event => {
12
+ return (_jsx(Alert, { severity: severity, action: action, classes: {
13
+ message: classes.ellipses,
14
+ }, onMouseDown: event => {
13
15
  event.stopPropagation();
14
- }, severity: severity, action: action, classes: { message: classes.ellipses }, children: _jsx(Tooltip, { title: message, children: _jsx("div", { children: message }) }) }));
16
+ }, children: _jsx(Tooltip, { title: message, children: _jsx("div", { children: message }) }) }));
15
17
  }
@@ -1,38 +1,18 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Suspense, isValidElement, lazy } from 'react';
3
- import { LoadingEllipses } from '@jbrowse/core/ui';
4
3
  import { observer } from 'mobx-react';
5
- import { getParent } from 'mobx-state-tree';
6
- import { makeStyles } from 'tss-react/mui';
4
+ import BlockLoadingMessage from './BlockLoadingMessage';
7
5
  import BlockMsg from './BlockMsg';
8
- const BlockError = lazy(() => import('./BlockError'));
9
- const useStyles = makeStyles()(theme => {
10
- const bg = theme.palette.action.disabledBackground;
11
- return {
12
- loading: {
13
- paddingLeft: '0.6em',
14
- backgroundColor: theme.palette.background.default,
15
- backgroundImage: `repeating-linear-gradient(45deg, transparent, transparent 5px, ${bg} 5px, ${bg} 10px)`,
16
- textAlign: 'center',
17
- },
18
- };
19
- });
20
- const LoadingMessage = observer(({ model }) => {
21
- const { classes } = useStyles();
22
- const { status: blockStatus } = model;
23
- const { message: displayStatus } = getParent(model, 2);
24
- const status = displayStatus || blockStatus;
25
- return (_jsx("div", { className: classes.loading, children: _jsx(LoadingEllipses, { message: status }) }));
26
- });
6
+ const BlockErrorMessage = lazy(() => import('./BlockErrorMessage'));
27
7
  const ServerSideRenderedBlockContent = observer(function ({ model, }) {
28
8
  if (model.error) {
29
- return (_jsx(Suspense, { fallback: null, children: _jsx(BlockError, { model: model }) }));
9
+ return (_jsx(Suspense, { fallback: null, children: _jsx(BlockErrorMessage, { model: model }) }));
30
10
  }
31
11
  else if (model.message) {
32
12
  return isValidElement(model.message) ? (model.message) : (_jsx(BlockMsg, { message: `${model.message}`, severity: "info" }));
33
13
  }
34
14
  else if (!model.filled) {
35
- return _jsx(LoadingMessage, { model: model });
15
+ return _jsx(BlockLoadingMessage, { model: model });
36
16
  }
37
17
  else {
38
18
  return model.reactElement;
@@ -78,14 +78,14 @@ function stateModelFactory() {
78
78
  return (_b = (_a = self.blockState.get(blockKey)) === null || _a === void 0 ? void 0 : _a.layout) === null || _b === void 0 ? void 0 : _b.getByID(id);
79
79
  },
80
80
  searchFeatureByID(id) {
81
+ var _a;
81
82
  let ret;
82
- self.blockState.forEach(block => {
83
- var _a;
83
+ for (const block of self.blockState.values()) {
84
84
  const val = (_a = block.layout) === null || _a === void 0 ? void 0 : _a.getByID(id);
85
85
  if (val) {
86
86
  ret = val;
87
87
  }
88
- });
88
+ }
89
89
  return ret;
90
90
  },
91
91
  }))
@@ -138,9 +138,9 @@ function stateModelFactory() {
138
138
  self.setError();
139
139
  self.setCurrStatsBpPerPx(0);
140
140
  self.clearFeatureDensityStats();
141
- [...self.blockState.values()].forEach(val => {
141
+ for (const val of self.blockState.values()) {
142
142
  val.doReload();
143
- });
143
+ }
144
144
  superReload();
145
145
  },
146
146
  };
@@ -230,17 +230,17 @@ function stateModelFactory() {
230
230
  if (!view.initialized) {
231
231
  return;
232
232
  }
233
- self.blockDefinitions.contentBlocks.forEach(block => {
233
+ for (const block of self.blockDefinitions.contentBlocks) {
234
234
  blocksPresent[block.key] = true;
235
235
  if (!self.blockState.has(block.key)) {
236
236
  self.addBlock(block.key, block);
237
237
  }
238
- });
239
- self.blockState.forEach((_, key) => {
238
+ }
239
+ for (const key of self.blockState.keys()) {
240
240
  if (!blocksPresent[key]) {
241
241
  self.deleteBlock(key);
242
242
  }
243
- });
243
+ }
244
244
  }));
245
245
  },
246
246
  }))
@@ -20,7 +20,7 @@ export default function LaunchLinearGenomeViewF(pluginManager) {
20
20
  view.setHideHeader(!nav);
21
21
  }
22
22
  if (highlight !== undefined) {
23
- highlight.forEach(async (h) => {
23
+ for (const h of highlight) {
24
24
  const p = parseLocString(h, refName => assemblyManager.isValidRefName(refName, assembly));
25
25
  const { start, end } = p;
26
26
  if (start !== undefined && end !== undefined) {
@@ -31,13 +31,17 @@ export default function LaunchLinearGenomeViewF(pluginManager) {
31
31
  assemblyName: assembly,
32
32
  });
33
33
  }
34
- });
34
+ }
35
35
  }
36
- await handleSelectedRegion({ input: loc, model: view, assembly: asm });
36
+ await handleSelectedRegion({
37
+ input: loc,
38
+ model: view,
39
+ assembly: asm,
40
+ });
37
41
  const idsNotFound = [];
38
- tracks.forEach(track => {
42
+ for (const track of tracks) {
39
43
  tryTrack(view, track, idsNotFound);
40
- });
44
+ }
41
45
  if (idsNotFound.length) {
42
46
  throw new Error(`Could not resolve identifiers: ${idsNotFound.join(',')}`);
43
47
  }
@@ -6,7 +6,7 @@ const useStyles = makeStyles()(theme => ({
6
6
  centerLineContainer: {
7
7
  background: 'transparent',
8
8
  height: '100%',
9
- zIndex: 5,
9
+ zIndex: 4,
10
10
  position: 'absolute',
11
11
  border: `1px ${theme.palette.action.active} dashed`,
12
12
  borderTop: 'none',
@@ -1,6 +1,7 @@
1
1
  import type { LinearGenomeViewModel } from '..';
2
2
  type LGV = LinearGenomeViewModel;
3
- declare const Gridlines: ({ model }: {
3
+ declare const Gridlines: ({ model, offset, }: {
4
4
  model: LGV;
5
+ offset?: number;
5
6
  }) => import("react/jsx-runtime").JSX.Element;
6
7
  export default Gridlines;
@@ -6,15 +6,14 @@ import { makeTicks } from '../util';
6
6
  const useStyles = makeStyles()(theme => ({
7
7
  verticalGuidesZoomContainer: {
8
8
  position: 'absolute',
9
+ top: 0,
9
10
  height: '100%',
10
11
  width: '100%',
11
- zIndex: 1,
12
12
  pointerEvents: 'none',
13
13
  },
14
14
  verticalGuidesContainer: {
15
15
  position: 'absolute',
16
16
  height: '100%',
17
- zIndex: 1,
18
17
  pointerEvents: 'none',
19
18
  display: 'flex',
20
19
  },
@@ -56,13 +55,13 @@ const RenderedVerticalGuides = observer(({ model }) => {
56
55
  return null;
57
56
  }) }));
58
57
  });
59
- const Gridlines = observer(function ({ model }) {
58
+ const Gridlines = observer(function ({ model, offset = 0, }) {
60
59
  const { classes } = useStyles();
61
60
  const offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
62
61
  return (_jsx("div", { className: classes.verticalGuidesZoomContainer, style: {
63
62
  transform: model.scaleFactor !== 1 ? `scaleX(${model.scaleFactor})` : undefined,
64
63
  }, children: _jsx("div", { className: classes.verticalGuidesContainer, style: {
65
- left: offsetLeft,
64
+ left: offsetLeft - offset,
66
65
  width: model.staticBlocks.totalWidthPx,
67
66
  }, children: _jsx(RenderedVerticalGuides, { model: model }) }) }));
68
67
  });
@@ -8,9 +8,11 @@ import HeaderTrackSelectorButton from './HeaderTrackSelectorButton';
8
8
  import HeaderZoomControls from './HeaderZoomControls';
9
9
  import OverviewScalebar from './OverviewScalebar';
10
10
  import SearchBox from './SearchBox';
11
+ import { HEADER_BAR_HEIGHT } from '../consts';
11
12
  const useStyles = makeStyles()({
12
13
  headerBar: {
13
14
  display: 'flex',
15
+ height: HEADER_BAR_HEIGHT,
14
16
  },
15
17
  headerForm: {
16
18
  flexWrap: 'nowrap',
@@ -1,21 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Suspense, lazy, useEffect, useRef } from 'react';
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { lazy } from 'react';
3
3
  import { LoadingEllipses } from '@jbrowse/core/ui';
4
- import { getSession } from '@jbrowse/core/util';
5
4
  import { observer } from 'mobx-react';
6
- import { makeStyles } from 'tss-react/mui';
7
- import TrackContainer from './TrackContainer';
8
- import TracksContainer from './TracksContainer';
5
+ import LinearGenomeViewContainer from './LinearGenomeViewContainer';
9
6
  const ImportForm = lazy(() => import('./ImportForm'));
10
- const NoTracksActiveButton = lazy(() => import('./NoTracksActiveButton'));
11
- const useStyles = makeStyles()({
12
- rel: {
13
- position: 'relative',
14
- },
15
- top: {
16
- zIndex: 1000,
17
- },
18
- });
19
7
  const LinearGenomeView = observer(function ({ model, }) {
20
8
  const { error, initialized, hasDisplayedRegions } = model;
21
9
  if (!initialized && !error) {
@@ -28,39 +16,4 @@ const LinearGenomeView = observer(function ({ model, }) {
28
16
  return _jsx(LinearGenomeViewContainer, { model: model });
29
17
  }
30
18
  });
31
- const LinearGenomeViewContainer = observer(function ({ model, }) {
32
- const { tracks } = model;
33
- const { classes } = useStyles();
34
- const session = getSession(model);
35
- const ref = useRef(null);
36
- const MiniControlsComponent = model.MiniControlsComponent();
37
- const HeaderComponent = model.HeaderComponent();
38
- useEffect(() => {
39
- function handleSelectView(e) {
40
- var _a, _b;
41
- if (e.target instanceof Element && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
42
- (_b = session.setFocusedViewId) === null || _b === void 0 ? void 0 : _b.call(session, model.id);
43
- }
44
- }
45
- document.addEventListener('mousedown', handleSelectView);
46
- document.addEventListener('keydown', handleSelectView);
47
- return () => {
48
- document.removeEventListener('mousedown', handleSelectView);
49
- document.removeEventListener('keydown', handleSelectView);
50
- };
51
- }, [session, model]);
52
- return (_jsxs("div", { className: classes.rel, ref: ref, onMouseLeave: () => {
53
- session.setHovered(undefined);
54
- }, onMouseMove: event => {
55
- const c = ref.current;
56
- if (!c) {
57
- return;
58
- }
59
- const { tracks } = model;
60
- const leftPx = event.clientX - c.getBoundingClientRect().left;
61
- const hoverPosition = model.pxToBp(leftPx);
62
- const hoverFeature = tracks.find(t => t.displays[0].featureUnderMouse);
63
- session.setHovered({ hoverPosition, hoverFeature });
64
- }, children: [_jsx(HeaderComponent, { model: model }), _jsx(MiniControlsComponent, { model: model }), _jsx(TracksContainer, { model: model, children: !tracks.length ? (_jsx(Suspense, { fallback: null, children: _jsx(NoTracksActiveButton, { model: model }) })) : (tracks.map(track => (_jsx(TrackContainer, { model: model, track: track }, track.id)))) })] }));
65
- });
66
19
  export default LinearGenomeView;
@@ -0,0 +1,5 @@
1
+ import type { LinearGenomeViewModel } from '..';
2
+ declare const LinearGenomeViewContainer: ({ model, }: {
3
+ model: LinearGenomeViewModel;
4
+ }) => import("react/jsx-runtime").JSX.Element;
5
+ export default LinearGenomeViewContainer;
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Suspense, lazy, useEffect, useRef } from 'react';
3
+ import { VIEW_HEADER_HEIGHT } from '@jbrowse/core/ui';
4
+ import { getSession } from '@jbrowse/core/util';
5
+ import Paper from '@mui/material/Paper';
6
+ import { observer } from 'mobx-react';
7
+ import { makeStyles } from 'tss-react/mui';
8
+ import TrackContainer from './TrackContainer';
9
+ import TracksContainer from './TracksContainer';
10
+ const NoTracksActiveButton = lazy(() => import('./NoTracksActiveButton'));
11
+ const useStyles = makeStyles()(theme => ({
12
+ header: {
13
+ background: theme.palette.background.paper,
14
+ top: VIEW_HEADER_HEIGHT,
15
+ zIndex: 850,
16
+ },
17
+ pinnedTracks: {
18
+ position: 'sticky',
19
+ zIndex: 3,
20
+ },
21
+ rel: {
22
+ position: 'relative',
23
+ },
24
+ }));
25
+ const LinearGenomeViewContainer = observer(function ({ model, }) {
26
+ const { pinnedTracks, stickyViewHeaders, pinnedTracksTop, tracks, unpinnedTracks, } = model;
27
+ const { classes } = useStyles();
28
+ const session = getSession(model);
29
+ const ref = useRef(null);
30
+ const MiniControlsComponent = model.MiniControlsComponent();
31
+ const HeaderComponent = model.HeaderComponent();
32
+ useEffect(() => {
33
+ function handleSelectView(e) {
34
+ var _a, _b;
35
+ if (e.target instanceof Element && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
36
+ (_b = session.setFocusedViewId) === null || _b === void 0 ? void 0 : _b.call(session, model.id);
37
+ }
38
+ }
39
+ document.addEventListener('mousedown', handleSelectView);
40
+ document.addEventListener('keydown', handleSelectView);
41
+ return () => {
42
+ document.removeEventListener('mousedown', handleSelectView);
43
+ document.removeEventListener('keydown', handleSelectView);
44
+ };
45
+ }, [session, model]);
46
+ return (_jsxs("div", { className: classes.rel, ref: ref, onMouseLeave: () => {
47
+ session.setHovered(undefined);
48
+ }, onMouseMove: event => {
49
+ const c = ref.current;
50
+ if (!c) {
51
+ return;
52
+ }
53
+ const { tracks } = model;
54
+ const leftPx = event.clientX - c.getBoundingClientRect().left;
55
+ const hoverPosition = model.pxToBp(leftPx);
56
+ const hoverFeature = tracks.find(t => t.displays[0].featureUnderMouse);
57
+ session.setHovered({ hoverPosition, hoverFeature });
58
+ }, children: [_jsxs("div", { className: classes.header, style: { position: stickyViewHeaders ? 'sticky' : undefined }, children: [_jsx(HeaderComponent, { model: model }), _jsx(MiniControlsComponent, { model: model })] }), _jsx(TracksContainer, { model: model, children: !tracks.length ? (_jsx(Suspense, { fallback: null, children: _jsx(NoTracksActiveButton, { model: model }) })) : (_jsxs(_Fragment, { children: [pinnedTracks.length ? (_jsx(Paper, { elevation: 6, className: classes.pinnedTracks, style: { top: pinnedTracksTop }, children: pinnedTracks.map(track => (_jsx(TrackContainer, { model: model, track: track }, track.id))) })) : null, unpinnedTracks.map(track => (_jsx(TrackContainer, { model: model, track: track }, track.id)))] })) })] }));
59
+ });
60
+ export default LinearGenomeViewContainer;
@@ -11,7 +11,6 @@ const useStyles = makeStyles()(theme => ({
11
11
  background: {
12
12
  position: 'absolute',
13
13
  right: 0,
14
- zIndex: 1001,
15
14
  background: theme.palette.background.paper,
16
15
  },
17
16
  focusedBackground: {
@@ -10,7 +10,7 @@ const useStyles = makeStyles()(theme => ({
10
10
  paddingBottom: theme.spacing(1),
11
11
  },
12
12
  top: {
13
- zIndex: 1000,
13
+ zIndex: 800,
14
14
  },
15
15
  }));
16
16
  const NoTracksActiveButton = observer(function ({ model, }) {
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useRef, useState } from 'react';
3
- import { getSession, stringify } from '@jbrowse/core/util';
4
- import { Tooltip } from '@mui/material';
3
+ import { getSession } from '@jbrowse/core/util';
5
4
  import { observer } from 'mobx-react';
6
5
  import { makeStyles } from 'tss-react/mui';
6
+ import OverviewRubberbandHoverTooltip from './OverviewRubberbandHoverTooltip';
7
7
  import RubberbandSpan from './RubberbandSpan';
8
8
  import { getRelativeX } from './util';
9
9
  const useStyles = makeStyles()({
@@ -17,24 +17,11 @@ const useStyles = makeStyles()({
17
17
  height: '100%',
18
18
  width: 1,
19
19
  position: 'absolute',
20
- zIndex: 10,
21
20
  },
22
21
  rel: {
23
22
  position: 'relative',
24
23
  },
25
24
  });
26
- const HoverTooltip = observer(function ({ model, open, guideX, overview, }) {
27
- var _a;
28
- const { classes } = useStyles();
29
- const { cytobandOffset } = model;
30
- const { assemblyManager } = getSession(model);
31
- const px = overview.pxToBp(guideX - cytobandOffset);
32
- const assembly = assemblyManager.get(px.assemblyName);
33
- const cytoband = (_a = assembly === null || assembly === void 0 ? void 0 : assembly.cytobands) === null || _a === void 0 ? void 0 : _a.find(f => px.coord > f.get('start') &&
34
- px.coord < f.get('end') &&
35
- px.refName === assembly.getCanonicalRefName(f.get('refName')));
36
- return (_jsx(Tooltip, { open: open, placement: "top", title: [stringify(px), cytoband === null || cytoband === void 0 ? void 0 : cytoband.get('name')].join(' '), arrow: true, children: _jsx("div", { className: classes.guide, style: { left: guideX } }) }));
37
- });
38
25
  const OverviewRubberband = observer(function OverviewRubberband({ model, overview, ControlComponent = _jsx("div", {}), }) {
39
26
  const { cytobandOffset } = model;
40
27
  const [startX, setStartX] = useState();
@@ -104,7 +91,7 @@ const OverviewRubberband = observer(function OverviewRubberband({ model, overvie
104
91
  setGuideX(undefined);
105
92
  }
106
93
  if (startX === undefined) {
107
- return (_jsxs("div", { className: classes.rel, children: [guideX !== undefined ? (_jsx(HoverTooltip, { model: model, open: !mouseDragging, overview: overview, guideX: guideX })) : null, _jsx("div", { className: classes.rubberbandControl, ref: controlsRef, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove, children: ControlComponent })] }));
94
+ return (_jsxs("div", { className: classes.rel, children: [guideX !== undefined ? (_jsx(OverviewRubberbandHoverTooltip, { model: model, open: !mouseDragging, overview: overview, guideX: guideX })) : null, _jsx("div", { className: classes.rubberbandControl, ref: controlsRef, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove, children: ControlComponent })] }));
108
95
  }
109
96
  let left = startX || 0;
110
97
  let width = 0;
@@ -0,0 +1,10 @@
1
+ import type { LinearGenomeViewModel } from '..';
2
+ import type { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel';
3
+ type LGV = LinearGenomeViewModel;
4
+ declare const OverviewRubberbandHoverTooltip: ({ model, open, guideX, overview, }: {
5
+ model: LGV;
6
+ open: boolean;
7
+ guideX: number;
8
+ overview: Base1DViewModel;
9
+ }) => import("react/jsx-runtime").JSX.Element;
10
+ export default OverviewRubberbandHoverTooltip;
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { getSession, stringify } from '@jbrowse/core/util';
3
+ import { Tooltip } from '@mui/material';
4
+ import { observer } from 'mobx-react';
5
+ import { makeStyles } from 'tss-react/mui';
6
+ const useStyles = makeStyles()({
7
+ rubberbandControl: {
8
+ cursor: 'crosshair',
9
+ width: '100%',
10
+ minHeight: 8,
11
+ },
12
+ guide: {
13
+ pointerEvents: 'none',
14
+ height: '100%',
15
+ width: 1,
16
+ position: 'absolute',
17
+ },
18
+ rel: {
19
+ position: 'relative',
20
+ },
21
+ });
22
+ const OverviewRubberbandHoverTooltip = observer(function ({ model, open, guideX, overview, }) {
23
+ var _a;
24
+ const { classes } = useStyles();
25
+ const { cytobandOffset } = model;
26
+ const { assemblyManager } = getSession(model);
27
+ const px = overview.pxToBp(guideX - cytobandOffset);
28
+ const assembly = assemblyManager.get(px.assemblyName);
29
+ const cytoband = (_a = assembly === null || assembly === void 0 ? void 0 : assembly.cytobands) === null || _a === void 0 ? void 0 : _a.find(f => px.coord > f.get('start') &&
30
+ px.coord < f.get('end') &&
31
+ px.refName === assembly.getCanonicalRefName(f.get('refName')));
32
+ return (_jsx(Tooltip, { open: open, placement: "top", title: [stringify(px), cytoband === null || cytoband === void 0 ? void 0 : cytoband.get('name')].join(' '), arrow: true, children: _jsx("div", { className: classes.guide, style: { left: guideX } }) }));
33
+ });
34
+ export default OverviewRubberbandHoverTooltip;
@@ -11,15 +11,20 @@ const useStyles = makeStyles()({
11
11
  cursor: 'crosshair',
12
12
  width: '100%',
13
13
  minHeight: 8,
14
+ zIndex: 825,
14
15
  },
15
16
  });
16
17
  const Rubberband = observer(function ({ model, ControlComponent = _jsx("div", {}), }) {
17
18
  const ref = useRef(null);
18
19
  const { classes } = useStyles();
20
+ const { stickyViewHeaders, rubberbandTop } = model;
19
21
  const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, handleMenuItemClick, handleClose, mouseMove, mouseDown, mouseOut, } = useRangeSelect(ref, model);
20
- return (_jsxs(_Fragment, { children: [guideX !== undefined ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
22
+ return (_jsxs(_Fragment, { children: [guideX !== undefined ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandTop, sticky: stickyViewHeaders })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
21
23
  left: anchorPosition.clientX,
22
24
  top: anchorPosition.clientY,
23
- }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null, _jsx("div", { "data-testid": "rubberband_controls", className: classes.rubberbandControl, ref: ref, onMouseDown: mouseDown, onMouseMove: mouseMove, onMouseOut: mouseOut, children: ControlComponent })] }));
25
+ }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null, _jsx("div", { "data-testid": "rubberband_controls", className: classes.rubberbandControl, style: {
26
+ top: rubberbandTop,
27
+ position: stickyViewHeaders ? 'sticky' : undefined,
28
+ }, ref: ref, onMouseDown: mouseDown, onMouseMove: mouseMove, onMouseOut: mouseOut, children: ControlComponent })] }));
24
29
  });
25
30
  export default Rubberband;
@@ -3,11 +3,13 @@ interface Offset {
3
3
  refName?: string;
4
4
  oob?: boolean;
5
5
  }
6
- export default function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, }: {
6
+ export default function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, top, sticky, }: {
7
7
  leftBpOffset: Offset;
8
8
  rightBpOffset: Offset;
9
9
  numOfBpSelected?: number;
10
10
  left: number;
11
11
  width: number;
12
+ top?: number;
13
+ sticky?: boolean;
12
14
  }): import("react/jsx-runtime").JSX.Element;
13
15
  export {};
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
3
  import { stringify, toLocale } from '@jbrowse/core/util';
4
- import { Popover, Typography, alpha } from '@mui/material';
4
+ import { Typography, alpha } from '@mui/material';
5
5
  import { makeStyles } from 'tss-react/mui';
6
+ import RubberbandTooltip from './RubberbandTooltip';
6
7
  const useStyles = makeStyles()(theme => {
7
8
  const { tertiary } = theme.palette;
8
9
  const background = alpha(tertiary.light, 0.7);
@@ -11,9 +12,8 @@ const useStyles = makeStyles()(theme => {
11
12
  height: '100%',
12
13
  background,
13
14
  position: 'absolute',
14
- zIndex: 10,
15
+ zIndex: 830,
15
16
  textAlign: 'center',
16
- overflow: 'hidden',
17
17
  },
18
18
  rubberbandControl: {
19
19
  cursor: 'crosshair',
@@ -21,32 +21,17 @@ const useStyles = makeStyles()(theme => {
21
21
  minHeight: 8,
22
22
  },
23
23
  rubberbandText: {
24
- color: tertiary.contrastText,
25
- },
26
- popover: {
27
- mouseEvents: 'none',
28
- cursor: 'crosshair',
29
- },
30
- paper: {
31
- paddingLeft: theme.spacing(1),
32
- paddingRight: theme.spacing(1),
24
+ color: theme.palette.tertiary.contrastText,
33
25
  },
34
26
  };
35
27
  });
36
- function Tooltip({ anchorEl, side, text, }) {
37
- const { classes } = useStyles();
38
- return (_jsx(Popover, { className: classes.popover, classes: { paper: classes.paper }, open: true, anchorEl: anchorEl, anchorOrigin: {
39
- vertical: 'top',
40
- horizontal: side === 'left' ? 'right' : 'left',
41
- }, transformOrigin: {
42
- vertical: 'bottom',
43
- horizontal: side === 'left' ? 'left' : 'right',
44
- }, keepMounted: true, disableRestoreFocus: true, children: _jsx(Typography, { children: text }) }));
45
- }
46
- export default function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, }) {
28
+ export default function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, top = 0, sticky = false, }) {
47
29
  const { classes } = useStyles();
48
30
  const [anchorEl, setAnchorEl] = useState(null);
49
- return (_jsxs(_Fragment, { children: [anchorEl ? (_jsxs(_Fragment, { children: [_jsx(Tooltip, { side: "left", anchorEl: anchorEl, text: stringify(leftBpOffset) }), _jsx(Tooltip, { side: "right", anchorEl: anchorEl, text: stringify(rightBpOffset) })] })) : null, _jsx("div", { ref: el => {
50
- setAnchorEl(el);
51
- }, className: classes.rubberband, style: { left, width }, children: numOfBpSelected ? (_jsxs(Typography, { variant: "h6", className: classes.rubberbandText, children: [toLocale(numOfBpSelected), " bp"] })) : null })] }));
31
+ return (_jsxs(_Fragment, { children: [anchorEl ? (_jsxs(_Fragment, { children: [_jsx(RubberbandTooltip, { side: "left", anchorEl: anchorEl, text: stringify(leftBpOffset) }), _jsx(RubberbandTooltip, { side: "right", anchorEl: anchorEl, text: stringify(rightBpOffset) })] })) : null, _jsx("div", { className: classes.rubberband, style: { left, width }, children: numOfBpSelected ? (_jsxs(Typography, { ref: el => {
32
+ setAnchorEl(el);
33
+ }, variant: "h6", className: classes.rubberbandText, style: {
34
+ top,
35
+ position: sticky ? 'sticky' : undefined,
36
+ }, children: [toLocale(numOfBpSelected), " bp"] })) : null })] }));
52
37
  }
@@ -0,0 +1,5 @@
1
+ export default function RubberbandTooltip({ anchorEl, side, text, }: {
2
+ anchorEl: HTMLSpanElement;
3
+ side: string;
4
+ text: string;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Popover, Typography } from '@mui/material';
3
+ import { makeStyles } from 'tss-react/mui';
4
+ const useStyles = makeStyles()(theme => {
5
+ return {
6
+ popover: {
7
+ mouseEvents: 'none',
8
+ cursor: 'crosshair',
9
+ },
10
+ paper: {
11
+ paddingLeft: theme.spacing(1),
12
+ paddingRight: theme.spacing(1),
13
+ },
14
+ };
15
+ });
16
+ export default function RubberbandTooltip({ anchorEl, side, text, }) {
17
+ const { classes } = useStyles();
18
+ return (_jsx(Popover, { className: classes.popover, classes: { paper: classes.paper }, open: true, anchorEl: anchorEl, anchorOrigin: {
19
+ vertical: 'top',
20
+ horizontal: side === 'left' ? 'left' : 'right',
21
+ }, transformOrigin: {
22
+ vertical: 'bottom',
23
+ horizontal: side === 'left' ? 'right' : 'left',
24
+ }, keepMounted: true, disableRestoreFocus: true, children: _jsx(Typography, { children: text }) }));
25
+ }