@jbrowse/plugin-linear-genome-view 5.0.0-beta.1 → 5.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/FeatureTrack/configSchema.d.ts +142 -50
- package/esm/LaunchLinearGenomeView/index.js +2 -13
- package/esm/LinearGenomeView/afterAttach.d.ts +5 -5
- package/esm/LinearGenomeView/afterAttach.js +73 -59
- package/esm/LinearGenomeView/components/CenterLine.js +5 -3
- package/esm/LinearGenomeView/components/CrisprGuidePanel.js +3 -5
- package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +3 -2
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +6 -2
- package/esm/LinearGenomeView/components/GetSequenceDialog.js +2 -2
- package/esm/LinearGenomeView/components/Header.js +11 -1
- package/esm/LinearGenomeView/components/HeaderClearHighlightButton.js +2 -2
- package/esm/LinearGenomeView/components/HeaderPanControls.js +2 -1
- package/esm/LinearGenomeView/components/HeaderZoomControls.js +4 -34
- package/esm/LinearGenomeView/components/Highlight.js +7 -7
- package/esm/LinearGenomeView/components/HighlightBand.js +2 -2
- package/esm/LinearGenomeView/components/HighlightChip.d.ts +1 -2
- package/esm/LinearGenomeView/components/HighlightChip.js +5 -7
- package/esm/LinearGenomeView/components/HoverPositionHighlight.js +3 -3
- package/esm/LinearGenomeView/components/ImportForm.js +2 -2
- package/esm/LinearGenomeView/components/LinearGenomeView.js +3 -3
- package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +3 -4
- package/esm/LinearGenomeView/components/MiniControls.js +3 -2
- package/esm/LinearGenomeView/components/OverviewHighlight.js +3 -3
- package/esm/LinearGenomeView/components/OverviewHighlightBand.js +2 -3
- package/esm/LinearGenomeView/components/OverviewRubberband.js +20 -45
- package/esm/LinearGenomeView/components/OverviewScalebar.js +4 -5
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +5 -3
- package/esm/LinearGenomeView/components/PaddingBlocks.d.ts +1 -1
- package/esm/LinearGenomeView/components/PaddingBlocks.js +14 -9
- package/esm/LinearGenomeView/components/RangeSelectOverlay.js +5 -6
- package/esm/LinearGenomeView/components/ResizeAllTracksHandle.d.ts +5 -0
- package/esm/LinearGenomeView/components/ResizeAllTracksHandle.js +71 -0
- package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -2
- package/esm/LinearGenomeView/components/Rubberband.js +3 -2
- package/esm/LinearGenomeView/components/SVGHighlightBand.js +2 -3
- package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -6
- package/esm/LinearGenomeView/components/Scalebar.js +8 -5
- package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +49 -34
- package/esm/LinearGenomeView/components/SearchBox.js +8 -7
- package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +2 -1
- package/esm/LinearGenomeView/components/SearchResultsDialog.js +2 -2
- package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +2 -1
- package/esm/LinearGenomeView/components/SearchResultsTable.js +12 -29
- package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +2 -4
- package/esm/LinearGenomeView/components/TrackContainer.js +63 -9
- package/esm/LinearGenomeView/components/TrackLabel.js +10 -3
- package/esm/LinearGenomeView/components/TrackLabelButtons.js +2 -2
- package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +2 -2
- package/esm/LinearGenomeView/components/TrackLabelMenu.js +3 -2
- package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +4 -1
- package/esm/LinearGenomeView/components/TrackRenderingContainer.js +11 -23
- package/esm/LinearGenomeView/components/TracksContainer.js +10 -22
- package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -2
- package/esm/LinearGenomeView/components/VerticalGuide.js +3 -16
- package/esm/LinearGenomeView/components/ZoomButton.js +6 -1
- package/esm/LinearGenomeView/components/ZoomTransform.js +4 -0
- package/esm/LinearGenomeView/components/fetchSequence.d.ts +1 -2
- package/esm/LinearGenomeView/components/recentLocationsMenu.js +10 -0
- package/esm/LinearGenomeView/components/searchModes.d.ts +1 -1
- package/esm/LinearGenomeView/components/searchModes.js +1 -1
- package/esm/LinearGenomeView/components/useRangeSelect.d.ts +0 -3
- package/esm/LinearGenomeView/components/useRangeSelect.js +20 -59
- package/esm/LinearGenomeView/components/useSideScroll.d.ts +16 -2
- package/esm/LinearGenomeView/components/useSideScroll.js +153 -103
- package/esm/LinearGenomeView/components/util.d.ts +4 -0
- package/esm/LinearGenomeView/components/util.js +4 -2
- package/esm/LinearGenomeView/consts.d.ts +2 -0
- package/esm/LinearGenomeView/consts.js +3 -1
- package/esm/LinearGenomeView/containingLgv.d.ts +21 -0
- package/esm/LinearGenomeView/containingLgv.js +23 -0
- package/esm/LinearGenomeView/headerFit.d.ts +4 -2
- package/esm/LinearGenomeView/headerFit.js +20 -7
- package/esm/LinearGenomeView/index.d.ts +1 -5
- package/esm/LinearGenomeView/index.js +10 -7
- package/esm/LinearGenomeView/keyboardHandler.d.ts +2 -0
- package/esm/LinearGenomeView/keyboardHandler.js +15 -1
- package/esm/LinearGenomeView/launchKeys.d.ts +2 -0
- package/esm/LinearGenomeView/launchKeys.js +27 -0
- package/esm/LinearGenomeView/lazyDialogs.d.ts +2 -4
- package/esm/LinearGenomeView/lazyDialogs.js +1 -0
- package/esm/LinearGenomeView/linkedViewSync.d.ts +3 -11
- package/esm/LinearGenomeView/linkedViewSync.js +27 -43
- package/esm/LinearGenomeView/menuItems.d.ts +16 -18
- package/esm/LinearGenomeView/menuItems.js +242 -151
- package/esm/LinearGenomeView/model.d.ts +2009 -200
- package/esm/LinearGenomeView/model.js +545 -395
- package/esm/LinearGenomeView/sharedScaleContainer.d.ts +1 -1
- package/esm/LinearGenomeView/showRegionsWithUndo.js +7 -1
- package/esm/LinearGenomeView/stickyChrome.d.ts +5 -9
- package/esm/LinearGenomeView/stickyChrome.js +5 -9
- package/esm/LinearGenomeView/svgcomponents/SVGGridlines.js +4 -4
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +4 -1
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +8 -21
- package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +8 -8
- package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +3 -3
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +7 -11
- package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +2 -5
- package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.js +5 -6
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +9 -10
- package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +3 -3
- package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.d.ts +27 -0
- package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.js +12 -0
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +15 -6
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +4 -4
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +6 -5
- package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +1 -1
- package/esm/LinearGenomeView/svgcomponents/SVGView.js +1 -1
- package/esm/LinearGenomeView/svgcomponents/figureContract.js +14 -14
- package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +1 -1
- package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +50 -68
- package/esm/LinearGenomeView/svgcomponents/util.d.ts +9 -5
- package/esm/LinearGenomeView/svgcomponents/util.js +26 -21
- package/esm/LinearGenomeView/types.d.ts +8 -11
- package/esm/LinearGenomeView/util.d.ts +60 -45
- package/esm/LinearGenomeView/util.js +131 -160
- package/esm/MultiLevelRubberband/MultiLevelRubberband.js +7 -4
- package/esm/MultiLevelRubberband/index.d.ts +2 -0
- package/esm/MultiLevelRubberband/index.js +2 -0
- package/esm/MultiLevelRubberband/menuItems.d.ts +34 -0
- package/esm/MultiLevelRubberband/menuItems.js +52 -0
- package/esm/MultiLevelRubberband/rowLabel.d.ts +22 -0
- package/esm/MultiLevelRubberband/rowLabel.js +27 -0
- package/esm/MultiLevelRubberband/types.d.ts +1 -0
- package/esm/MultiLevelRubberband/useRangeSelect.d.ts +2 -1
- package/esm/MultiLevelRubberband/useRangeSelect.js +31 -47
- package/esm/displayKitTests/perRegionTestEnv.d.ts +214 -86
- package/esm/displayKitTests/perRegionTestEnv.js +30 -29
- package/esm/index.d.ts +15 -85
- package/esm/index.js +13 -36
- package/esm/searchUtils.d.ts +18 -9
- package/esm/searchUtils.js +85 -69
- package/esm/shared/RubberbandSpan.js +2 -1
- package/esm/shared/coordLabels.d.ts +7 -0
- package/esm/shared/coordLabels.js +15 -1
- package/esm/shared/useWindowDrag.d.ts +18 -0
- package/esm/shared/useWindowDrag.js +45 -0
- package/package.json +10 -10
- package/esm/LinearGenomeView/FloatingSvgOverlay.d.ts +0 -5
- package/esm/LinearGenomeView/FloatingSvgOverlay.js +0 -25
- package/esm/LinearGenomeView/initKeys.d.ts +0 -13
- package/esm/LinearGenomeView/initKeys.js +0 -104
- package/esm/MultiLevelRubberband/VerticalGuide.d.ts +0 -6
- package/esm/MultiLevelRubberband/VerticalGuide.js +0 -21
- package/esm/lazyPluginExports.d.ts +0 -23
- package/esm/lazyPluginExports.js +0 -36
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
|
|
2
3
|
import ScrollZoomToggle from '@jbrowse/core/ui/ScrollZoomToggle';
|
|
4
|
+
import { getSession } from '@jbrowse/core/util';
|
|
3
5
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
6
|
import useMeasure from '@jbrowse/core/util/useMeasure';
|
|
7
|
+
import MenuIcon from '@mui/icons-material/Menu';
|
|
8
|
+
import { useMediaQuery } from '@mui/material';
|
|
5
9
|
import { observer } from 'mobx-react';
|
|
6
10
|
import { HEADER_BAR_HEIGHT } from '../consts.js';
|
|
7
11
|
import { headerFit } from '../headerFit.js';
|
|
@@ -35,12 +39,18 @@ const Controls = observer(function Controls({ model, }) {
|
|
|
35
39
|
// row
|
|
36
40
|
const [ref, { width }] = useMeasure('width');
|
|
37
41
|
const highlighted = highlightedDisplays(model);
|
|
42
|
+
const viewMenu = getSession(model).viewTitleBars === false;
|
|
43
|
+
const touch = useMediaQuery('(pointer: coarse)', {
|
|
44
|
+
noSsr: true,
|
|
45
|
+
});
|
|
38
46
|
const fit = headerFit({
|
|
39
47
|
width,
|
|
40
48
|
searchBoxPx: searchBoxWidth(model.coarseVisibleLocStrings),
|
|
41
49
|
clearHighlight: highlighted.length > 0,
|
|
50
|
+
viewMenu,
|
|
51
|
+
touch,
|
|
42
52
|
});
|
|
43
|
-
return (_jsxs("div", { className: classes.headerBar, ref: ref, children: [_jsx(HeaderTrackSelectorButton, { model: model, indent: fit.trackSelectorIndent }), _jsx(ScrollZoomToggle, { model: model, iconOnly: !fit.scrollZoomLabel }), _jsx("div", { className: classes.spacer }), _jsx(HeaderPanControls, { model: model, compact: !fit.panButtonSpacing }), _jsx(SearchBox, { model: model }), _jsx(HeaderClearHighlightButton, { highlighted: highlighted }), fit.regionWidth ? _jsx(HeaderRegionWidth, { model: model }) : null, _jsx(HeaderZoomControls, { model: model, showSlider: fit.zoomSlider }), _jsx("div", { className: classes.spacer })] }));
|
|
53
|
+
return (_jsxs("div", { className: classes.headerBar, ref: ref, children: [viewMenu ? (_jsx(CascadingMenuButton, { menuItems: () => model.menuItems(), "data-testid": "view_menu_icon", children: _jsx(MenuIcon, {}) })) : null, _jsx(HeaderTrackSelectorButton, { model: model, indent: fit.trackSelectorIndent }), touch ? null : (_jsx(ScrollZoomToggle, { model: model, iconOnly: !fit.scrollZoomLabel })), _jsx("div", { className: classes.spacer }), touch ? null : (_jsx(HeaderPanControls, { model: model, compact: !fit.panButtonSpacing })), _jsx(SearchBox, { model: model }), _jsx(HeaderClearHighlightButton, { highlighted: highlighted }), fit.regionWidth ? _jsx(HeaderRegionWidth, { model: model }) : null, _jsx(HeaderZoomControls, { model: model, showSlider: fit.zoomSlider }), _jsx("div", { className: classes.spacer })] }));
|
|
44
54
|
});
|
|
45
55
|
const LinearGenomeViewHeader = observer(function LinearGenomeViewHeader({ model, }) {
|
|
46
56
|
const { hideHeader, hideHeaderOverview } = model;
|
|
@@ -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
|
|
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,8 +1,9 @@
|
|
|
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
|
|
6
|
+
import { Button } from '@mui/material';
|
|
6
7
|
import { SPACING, WIDGET_HEIGHT } from '../consts.js';
|
|
7
8
|
const useStyles = makeStyles()(theme => ({
|
|
8
9
|
panButton: {
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
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
|
|
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 {
|
|
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
|
|
@@ -82,6 +52,6 @@ const ZoomSlider = observer(function ZoomSlider({ model, }) {
|
|
|
82
52
|
});
|
|
83
53
|
const HeaderZoomControls = observer(function HeaderZoomControls({ model, showSlider = true, }) {
|
|
84
54
|
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: () =>
|
|
55
|
+
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: () => zoomMenuItems(model), children: _jsx(MoreVert, {}) })] }));
|
|
86
56
|
});
|
|
87
57
|
export default HeaderZoomControls;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
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
5
|
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
|
|
6
|
-
import { useTheme } from '@mui/material';
|
|
7
6
|
import { observer } from 'mobx-react';
|
|
8
7
|
import HighlightBand from './HighlightBand.js';
|
|
9
8
|
import HighlightChip from './HighlightChip.js';
|
|
@@ -12,17 +11,18 @@ import { getHighlightColor } from './util.js';
|
|
|
12
11
|
// width the chip is dropped (the band itself still draws).
|
|
13
12
|
const CHIP_MIN_WIDTH = 24;
|
|
14
13
|
const Highlight = observer(function Highlight({ model, highlight, }) {
|
|
15
|
-
const theme =
|
|
14
|
+
const theme = useStyleTheme();
|
|
16
15
|
const coords = model.getHighlightCoords(highlight);
|
|
17
16
|
const bandColor = getHighlightColor(highlight, theme);
|
|
18
|
-
const label = model.
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const label = getSession(model).highlightLabelsVisible
|
|
18
|
+
? highlight.label
|
|
19
|
+
: undefined;
|
|
20
|
+
return coords ? (_jsx(HighlightBand, { coords: coords, background: bandColor.toRgbString(), label: label, children: coords.width >= CHIP_MIN_WIDTH ? (_jsx(HighlightChip, { color: bandColor, label: label, tooltip: highlight.label ?? 'Highlighted region', menuItems: [
|
|
21
21
|
{
|
|
22
22
|
label: 'Dismiss highlight',
|
|
23
23
|
icon: CloseIcon,
|
|
24
24
|
onClick: () => {
|
|
25
|
-
model.removeHighlight(highlight);
|
|
25
|
+
getSession(model).removeHighlight(highlight);
|
|
26
26
|
},
|
|
27
27
|
},
|
|
28
28
|
{
|
|
@@ -24,8 +24,8 @@ const useStyles = makeStyles()(theme => ({
|
|
|
24
24
|
color: theme.palette.text.primary,
|
|
25
25
|
},
|
|
26
26
|
}));
|
|
27
|
-
//
|
|
28
|
-
//
|
|
27
|
+
// OverviewHighlight stays separate (different bpToPx API). A non-interactive
|
|
28
|
+
// colored band with an
|
|
29
29
|
// optional top label; when `children` (the highlight chip) is passed it renders
|
|
30
30
|
// that instead of the plain label. Visibility is toggled from the view menu
|
|
31
31
|
export default function HighlightBand({ coords, background, label, children, }) {
|
|
@@ -1,9 +1,8 @@
|
|
|
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,
|
|
3
|
+
export default function 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
8
|
}): import("react").JSX.Element;
|
|
@@ -2,14 +2,12 @@ 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
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
// chip drawn while the menu is up.
|
|
10
|
-
export default function HighlightChip({ color, label, tooltip, menuItems, setOpen, }) {
|
|
5
|
+
// Interactive chip drawn inside a highlight band: a link icon tinted to the
|
|
6
|
+
// band color plus an optional inline label, wrapped in a context menu. Sets its
|
|
7
|
+
// own pointer-events since the band is click-through.
|
|
8
|
+
export default function HighlightChip({ color, label, tooltip, menuItems, }) {
|
|
11
9
|
// hide the icon color when the band is fully transparent ("label-only"
|
|
12
10
|
// highlight); otherwise bump to 0.8 alpha so the chip stays legible
|
|
13
11
|
const chipAlpha = color.alpha() === 0 ? 0 : 0.8;
|
|
14
|
-
return (_jsx(Box, { sx: { pointerEvents: 'auto' }, children: _jsx(CascadingMenuButton, { "data-testid": "highlight-chip", menuItems: menuItems,
|
|
12
|
+
return (_jsx(Box, { sx: { pointerEvents: 'auto' }, 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] }) }) }) }));
|
|
15
13
|
}
|
|
@@ -6,9 +6,9 @@ const useStyles = makeStyles()(theme => ({
|
|
|
6
6
|
highlight: {
|
|
7
7
|
height: '100%',
|
|
8
8
|
position: 'absolute',
|
|
9
|
-
background: alpha(theme.palette.
|
|
10
|
-
borderLeft: `2px solid ${theme.palette.
|
|
11
|
-
borderRight: `2px solid ${theme.palette.
|
|
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
|
},
|
|
@@ -84,12 +84,12 @@ const LinearGenomeViewImportForm = observer(function LinearGenomeViewImportForm(
|
|
|
84
84
|
// reason.
|
|
85
85
|
model.setError(undefined);
|
|
86
86
|
setSelectedAssemblyName(val);
|
|
87
|
-
}, session: session, selected: selectedAsm }), selectedAsm ? (assemblyError ? (_jsx(CloseIcon, { color: "error" })) : regions ? (_jsx(RefNameAutocomplete, { fetchResults: (queryString,
|
|
87
|
+
}, session: session, selected: selectedAsm }), selectedAsm ? (assemblyError ? (_jsx(CloseIcon, { color: "error" })) : regions ? (_jsx(RefNameAutocomplete, { fetchResults: (queryString, signal) => fetchResults({
|
|
88
88
|
queryString,
|
|
89
89
|
assembly,
|
|
90
90
|
textSearchManager,
|
|
91
91
|
assemblyName: selectedAsm,
|
|
92
|
-
|
|
92
|
+
signal,
|
|
93
93
|
}), session: session, assemblyName: selectedAsm, value: value, minWidth: 270, adornmentWidth: adornmentReservePx({
|
|
94
94
|
menuItemCount: recentMenuItems.length,
|
|
95
95
|
}), onChange: v => {
|
|
@@ -6,9 +6,9 @@ import LinearGenomeViewContainer from './LinearGenomeViewContainer.js';
|
|
|
6
6
|
// lazies
|
|
7
7
|
const ImportForm = lazy(() => import('./ImportForm.js'));
|
|
8
8
|
const LinearGenomeView = observer(function LinearGenomeView({ model, }) {
|
|
9
|
-
const {
|
|
10
|
-
if (
|
|
11
|
-
return
|
|
9
|
+
const { loading, showImportForm } = model;
|
|
10
|
+
if (loading) {
|
|
11
|
+
return _jsx(ViewLoadingScreen, { ...loading });
|
|
12
12
|
}
|
|
13
13
|
else if (showImportForm) {
|
|
14
14
|
return _jsx(ImportForm, { model: model });
|
|
@@ -7,13 +7,12 @@ 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 ResizeAllTracksHandle from './ResizeAllTracksHandle.js';
|
|
15
15
|
import Rubberband from './Rubberband.js';
|
|
16
|
-
import Scalebar from './Scalebar.js';
|
|
17
16
|
import TrackContainer from './TrackContainer.js';
|
|
18
17
|
import TracksContainer from './TracksContainer.js';
|
|
19
18
|
// lazies
|
|
@@ -105,7 +104,7 @@ const LinearGenomeViewContainer = observer(function LinearGenomeViewContainer({
|
|
|
105
104
|
.map(d => d.hoveredFeature)
|
|
106
105
|
.find(Boolean);
|
|
107
106
|
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
|
|
107
|
+
}, 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(Suspense, { fallback: null, children: _jsx(NoTracksActiveButton, { model: model }) })) : (_jsxs(_Fragment, { children: [pinnedTracks.length ? (_jsx(Paper, { elevation: 2, "data-testid": "pinned-tracks", className: classes.pinnedTracks, style: {
|
|
109
108
|
top: stickyTops.pinnedTracks,
|
|
110
109
|
// the scroll port this sticks in, not the window: it is
|
|
111
110
|
// under the app bar in the classic stack, a dockview
|
|
@@ -113,6 +112,6 @@ const LinearGenomeViewContainer = observer(function LinearGenomeViewContainer({
|
|
|
113
112
|
// The fallback is what an unbounded embed gets, where
|
|
114
113
|
// the 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,12 +1,13 @@
|
|
|
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
|
|
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 => ({
|
|
@@ -27,7 +28,7 @@ const MiniControls = observer(function MiniControls({ model, }) {
|
|
|
27
28
|
const { focusedViewId } = getSession(model);
|
|
28
29
|
return (_jsx(Paper, { className: classes.background, children: _jsxs(Paper, { className: focusedViewId === id ? classes.focusedBackground : undefined, children: [_jsx(Tooltip, { title: "Open track selector", children: _jsx(IconButton, { size: "small", onClick: () => {
|
|
29
30
|
model.activateTrackSelector();
|
|
30
|
-
}, children: _jsx(TrackSelectorIcon, { fontSize: "small" }) }) }), _jsx(CascadingMenuButton, { menuItems: () => model.menuItems(), children: _jsx(MoreVertIcon, { fontSize: "small" }) }), _jsx(Tooltip, { title: scalebarOnly ? '
|
|
31
|
+
}, children: _jsx(TrackSelectorIcon, { fontSize: "small" }) }) }), _jsx(CascadingMenuButton, { menuItems: () => model.menuItems(), children: _jsx(MoreVertIcon, { fontSize: "small" }) }), _jsx(Tooltip, { title: scalebarOnly ? 'Show tracks' : 'Show ruler only', children: _jsx(IconButton, { size: "small", onClick: () => {
|
|
31
32
|
model.setScalebarOnly(!scalebarOnly);
|
|
32
33
|
}, 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
34
|
});
|
|
@@ -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 =
|
|
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.
|
|
14
|
+
? model.highlights
|
|
15
15
|
.map(highlight => {
|
|
16
16
|
const coords = model.getOverviewHighlightCoords(highlight);
|
|
17
17
|
return coords ? { coords, highlight } : undefined;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
3
3
|
import { Tooltip } from '@mui/material';
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// The 1px border keeps very narrow bands visible.
|
|
4
|
+
// A single absolute-positioned band over the overview scalebar. The 1px border
|
|
5
|
+
// keeps very narrow bands visible.
|
|
7
6
|
const useStyles = makeStyles()({
|
|
8
7
|
highlight: {
|
|
9
8
|
height: '100%',
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
3
|
import { getNotificationSink, stringify } from '@jbrowse/core/util';
|
|
4
4
|
import { getRelativeX } from '@jbrowse/core/util/getRelativeX';
|
|
5
5
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
6
6
|
import { observer } from 'mobx-react';
|
|
7
7
|
import RubberbandSpan from '../../shared/RubberbandSpan.js';
|
|
8
|
+
import { useWindowDrag } from '../../shared/useWindowDrag.js';
|
|
8
9
|
import OverviewRubberbandHoverTooltip from './OverviewRubberbandHoverTooltip.js';
|
|
9
10
|
import { overviewPxToBp } from './util.js';
|
|
10
11
|
const useStyles = makeStyles()({
|
|
@@ -25,57 +26,31 @@ const OverviewRubberband = observer(function OverviewRubberband({ model, overvie
|
|
|
25
26
|
const controlsRef = useRef(null);
|
|
26
27
|
const { classes } = useStyles();
|
|
27
28
|
const mouseDragging = startX !== undefined;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
function globalMouseUp(event) {
|
|
40
|
-
// read the up position from the event so currentX state doesn't need to
|
|
41
|
-
// be a dep (which would re-subscribe these listeners every mousemove)
|
|
42
|
-
if (startX !== undefined) {
|
|
43
|
-
const offsetX = event.clientX - left;
|
|
44
|
-
if (Math.abs(offsetX - startX) > 3) {
|
|
45
|
-
const leftPx = Math.min(startX, offsetX);
|
|
46
|
-
const rightPx = Math.max(startX, offsetX);
|
|
47
|
-
model.moveTo(overviewPxToBp(overview, leftPx, cytobandOffset), overviewPxToBp(overview, rightPx, cytobandOffset));
|
|
29
|
+
useWindowDrag(controlsRef, startX, {
|
|
30
|
+
onMove: setCurrentX,
|
|
31
|
+
onEnd: ({ startX, endX, isClick }) => {
|
|
32
|
+
if (!isClick) {
|
|
33
|
+
model.moveTo(overviewPxToBp(overview, Math.min(startX, endX), cytobandOffset), overviewPxToBp(overview, Math.max(startX, endX), cytobandOffset));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const click = overviewPxToBp(overview, startX, cytobandOffset);
|
|
37
|
+
if (click.refName) {
|
|
38
|
+
model.centerAt(click.coord0, click.refName, click.index);
|
|
48
39
|
}
|
|
49
40
|
else {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
model.centerAt(click.coord0, click.refName, click.index);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
getNotificationSink(model).notify('unknown position clicked');
|
|
56
|
-
console.error('unknown position clicked', click);
|
|
57
|
-
}
|
|
41
|
+
getNotificationSink(model).notify('unknown position clicked');
|
|
42
|
+
console.error('unknown position clicked', click);
|
|
58
43
|
}
|
|
59
44
|
}
|
|
60
45
|
setStartX(undefined);
|
|
61
46
|
setCurrentX(undefined);
|
|
62
47
|
setGuideX(undefined);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
window.addEventListener('mousemove', globalMouseMove);
|
|
71
|
-
window.addEventListener('mouseup', globalMouseUp);
|
|
72
|
-
window.addEventListener('keydown', globalKeyDown);
|
|
73
|
-
return () => {
|
|
74
|
-
window.removeEventListener('mousemove', globalMouseMove);
|
|
75
|
-
window.removeEventListener('mouseup', globalMouseUp);
|
|
76
|
-
window.removeEventListener('keydown', globalKeyDown);
|
|
77
|
-
};
|
|
78
|
-
}, [startX, mouseDragging, model, overview, cytobandOffset]);
|
|
48
|
+
},
|
|
49
|
+
onCancel: () => {
|
|
50
|
+
setStartX(undefined);
|
|
51
|
+
setCurrentX(undefined);
|
|
52
|
+
},
|
|
53
|
+
});
|
|
79
54
|
function mouseDown(event) {
|
|
80
55
|
event.preventDefault();
|
|
81
56
|
event.stopPropagation();
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PluggableElements } from '@jbrowse/core/ui';
|
|
3
|
+
import { alpha } from '@jbrowse/core/ui/palette';
|
|
3
4
|
import { getEnv, getSession } from '@jbrowse/core/util';
|
|
4
5
|
import { cx, makeStyles } from '@jbrowse/core/util/tss-react';
|
|
5
|
-
import { Typography
|
|
6
|
+
import { Typography } from '@mui/material';
|
|
6
7
|
import { observer } from 'mobx-react';
|
|
7
8
|
import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT } from '../consts.js';
|
|
8
9
|
import { REF_NAME_LABEL_FONT_SIZE, getBlockRefName, showRefNameLabels, } from '../util.js';
|
|
@@ -89,8 +90,7 @@ const useStyles = makeStyles()(theme => ({
|
|
|
89
90
|
},
|
|
90
91
|
}));
|
|
91
92
|
const OverviewBox = observer(function OverviewBox({ model, block, showRefName, }) {
|
|
92
|
-
const { classes } = useStyles();
|
|
93
|
-
const theme = useTheme();
|
|
93
|
+
const { classes, theme } = useStyles();
|
|
94
94
|
const { cytobandOffset, effectiveShowCytobands, overviewLayout: overview, } = model;
|
|
95
95
|
const { reversed, refName, assemblyName } = block;
|
|
96
96
|
const { assemblyManager } = getSession(model);
|
|
@@ -120,8 +120,7 @@ const OverviewBox = observer(function OverviewBox({ model, block, showRefName, }
|
|
|
120
120
|
}, children: [showRefName ? (_jsx(Typography, { style: { color: refNameColor, left: 3 }, className: classes.scalebarRefName, children: refName })) : null, _jsx(OverviewScalebarTickLabels, { model: model, block: block, refNameColor: refNameColor, showRefName: showRefName })] }));
|
|
121
121
|
});
|
|
122
122
|
const VisibleRegionBox = observer(function VisibleRegionBox({ model, }) {
|
|
123
|
-
const { classes } = useStyles();
|
|
124
|
-
const theme = useTheme();
|
|
123
|
+
const { classes, theme } = useStyles();
|
|
125
124
|
const { effectiveShowCytobands, cytobandOffset, overviewRegionPxSpan: span, } = model;
|
|
126
125
|
if (!span) {
|
|
127
126
|
return null;
|
|
@@ -24,10 +24,12 @@ function trapezoidPoints(top, bottom, height) {
|
|
|
24
24
|
// class computed once per theme (makeStyles memoizes) — an on-screen zoom frame
|
|
25
25
|
// then does zero color parsing. SVG export can't carry a CSS class, so that path
|
|
26
26
|
// serializes explicit fill/stroke attributes instead (see `exportSvg` below).
|
|
27
|
+
const FILL_OPACITY = 0.3;
|
|
28
|
+
const STROKE_OPACITY = 0.8;
|
|
27
29
|
const useStyles = makeStyles()(theme => ({
|
|
28
30
|
polygon: {
|
|
29
|
-
fill: alpha(theme.palette.tertiary.light,
|
|
30
|
-
stroke: alpha(theme.palette.tertiary.light,
|
|
31
|
+
fill: alpha(theme.palette.tertiary.light, FILL_OPACITY),
|
|
32
|
+
stroke: alpha(theme.palette.tertiary.light, STROKE_OPACITY),
|
|
31
33
|
},
|
|
32
34
|
}));
|
|
33
35
|
/**
|
|
@@ -57,6 +59,6 @@ const OverviewScalebarPolygon = observer(function OverviewScalebarPolygon({ mode
|
|
|
57
59
|
const top = transformPxSpan(extent, bpPerPx / overview.bpPerPx, overviewOffsetPx);
|
|
58
60
|
const bottom = transformPxSpan(extent, 1, -offsetPx);
|
|
59
61
|
const points = trapezoidPoints(top, bottom, HEADER_BAR_HEIGHT);
|
|
60
|
-
return exportSvg ? (_jsx("polygon", { points: points, ...getFillProps(alpha(theme.palette.tertiary.light,
|
|
62
|
+
return exportSvg ? (_jsx("polygon", { points: points, ...getFillProps(alpha(theme.palette.tertiary.light, FILL_OPACITY)), ...getStrokeProps(alpha(theme.palette.tertiary.light, STROKE_OPACITY)) })) : (_jsx("polygon", { points: points, className: classes.polygon }));
|
|
61
63
|
});
|
|
62
64
|
export default OverviewScalebarPolygon;
|
|
@@ -16,15 +16,10 @@ const useStyles = makeStyles()(theme => ({
|
|
|
16
16
|
boundaryBlock: {
|
|
17
17
|
background: theme.palette.action.disabledBackground,
|
|
18
18
|
},
|
|
19
|
+
// opaque, since a translucent fill would darken unevenly where the
|
|
20
|
+
// container-level and per-track PaddingBlocks overlap
|
|
19
21
|
regionSeparator: {
|
|
20
|
-
|
|
21
|
-
// out contiguously so the separator paints directly over track data on both
|
|
22
|
-
// sides. A translucent fill would tint the data instead of masking it, and
|
|
23
|
-
// would darken unevenly where the container-level and per-track
|
|
24
|
-
// PaddingBlocks overlap. An opaque grey masks cleanly and stays seamless.
|
|
25
|
-
background: theme.palette.mode === 'dark'
|
|
26
|
-
? theme.palette.grey[500]
|
|
27
|
-
: theme.palette.grey[600],
|
|
22
|
+
background: theme.palette.regionSeparator,
|
|
28
23
|
},
|
|
29
24
|
elided: {
|
|
30
25
|
...elidedBlockStyles,
|
|
@@ -41,11 +36,21 @@ const PaddingBlocks = observer(function PaddingBlocks({ model, offset = 0, }) {
|
|
|
41
36
|
// the geometry is `model.paddingSpans` -- shared with any host drawing this
|
|
42
37
|
// itself, so a seam here and a seam in an embedder's own chrome can't be
|
|
43
38
|
// computed two different ways. This file owns only what the spans look like.
|
|
39
|
+
const spans = model.paddingSpans;
|
|
40
|
+
// Nothing to mask, so no positioned container to hold it — the common case,
|
|
41
|
+
// since a view sitting inside one contig has no seam, elision or boundary.
|
|
42
|
+
// The wrapper is not free: `ZoomTransform` reads `staticBlocks`, so an empty
|
|
43
|
+
// one still re-rendered and rewrote its transform on every gesture frame, per
|
|
44
|
+
// track. The view returns one shared array here, so this bails without even
|
|
45
|
+
// re-rendering.
|
|
46
|
+
if (spans.length === 0) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
44
49
|
const kindClass = {
|
|
45
50
|
seam: classes.regionSeparator,
|
|
46
51
|
elided: classes.elided,
|
|
47
52
|
boundary: classes.boundaryBlock,
|
|
48
53
|
};
|
|
49
|
-
return (_jsx(ZoomTransform, { model: model, offset: offset, children: _jsx("div", { className: classes.absoluteFill, children:
|
|
54
|
+
return (_jsx(ZoomTransform, { model: model, offset: offset, children: _jsx("div", { className: classes.absoluteFill, children: spans.map(({ x, width, kind }, i) => (_jsx("div", { className: cx(classes.block, kindClass[kind]), style: { transform: `translateX(${x}px)`, width } }, i))) }) }));
|
|
50
55
|
});
|
|
51
56
|
export default PaddingBlocks;
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Suspense, lazy } from 'react';
|
|
3
2
|
import { Menu } from '@jbrowse/core/ui';
|
|
4
3
|
import { getBpDisplayStr, stringify } from '@jbrowse/core/util';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
5
|
+
import RubberbandSpan from '../../shared/RubberbandSpan.js';
|
|
6
6
|
import { stickyChromeTops } from '../stickyChrome.js';
|
|
7
7
|
import VerticalGuide from './VerticalGuide.js';
|
|
8
|
-
const RubberbandSpan = lazy(() => import('../../shared/RubberbandSpan.js'));
|
|
9
8
|
const RangeSelectOverlay = observer(function RangeSelectOverlay({ model, range, menuOffsetX = 0, }) {
|
|
10
9
|
const { stickyViewHeaders, headerHeight, isScalebarRefNameMenuOpen } = model;
|
|
11
10
|
const { scalebar } = stickyChromeTops({ stickyViewHeaders, headerHeight });
|
|
12
|
-
const { guideX,
|
|
13
|
-
return (_jsxs(_Fragment, { children: [guideX !== undefined && !isScalebarRefNameMenuOpen ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) :
|
|
11
|
+
const { guideX, rubberband, anchorPosition, isClick, handleMenuItemClick, handleClose, } = range;
|
|
12
|
+
return (_jsxs(_Fragment, { children: [guideX !== undefined && !isScalebarRefNameMenuOpen ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberband && !isClick ? (_jsx(RubberbandSpan, { left: rubberband.left, width: rubberband.width, viewWidth: model.width, stickyTop: scalebar, leftLabel: stringify(rubberband.leftBpOffset), rightLabel: stringify(rubberband.rightBpOffset), size: getBpDisplayStr(rubberband.numOfBpSelected) })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
|
|
14
13
|
left: anchorPosition.clientX + menuOffsetX,
|
|
15
14
|
top: anchorPosition.clientY,
|
|
16
|
-
}, onMenuItemClick: handleMenuItemClick, open:
|
|
17
|
-
? model.rubberbandClickMenuItems(
|
|
15
|
+
}, onMenuItemClick: handleMenuItemClick, open: true, onClose: handleClose, menuItems: isClick
|
|
16
|
+
? model.rubberbandClickMenuItems(model.pxToBp(anchorPosition.offsetX))
|
|
18
17
|
: model.rubberBandMenuItems() })) : null] }));
|
|
19
18
|
});
|
|
20
19
|
export default RangeSelectOverlay;
|