@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.
- package/esm/LinearGenomeView/afterAttach.d.ts +22 -5
- package/esm/LinearGenomeView/afterAttach.js +129 -106
- package/esm/LinearGenomeView/axisConfigSchema.d.ts +18 -0
- package/esm/LinearGenomeView/axisConfigSchema.js +22 -0
- package/esm/LinearGenomeView/components/CenterLine.js +10 -5
- package/esm/LinearGenomeView/components/ConnectedHoverHighlight.js +2 -3
- package/esm/LinearGenomeView/components/CrisprGuidePanel.js +3 -5
- package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +9 -4
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +45 -8
- 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.d.ts +3 -3
- package/esm/LinearGenomeView/components/HeaderPanControls.js +6 -3
- package/esm/LinearGenomeView/components/HeaderSearchBoxes.js +4 -1
- package/esm/LinearGenomeView/components/HeaderZoomControls.js +6 -35
- package/esm/LinearGenomeView/components/Highlight.js +27 -11
- package/esm/LinearGenomeView/components/HighlightBand.d.ts +11 -2
- package/esm/LinearGenomeView/components/HighlightBand.js +32 -13
- package/esm/LinearGenomeView/components/HighlightChip.d.ts +3 -3
- package/esm/LinearGenomeView/components/HighlightChip.js +13 -8
- package/esm/LinearGenomeView/components/HighlightLabelDialog.d.ts +6 -0
- package/esm/LinearGenomeView/components/HighlightLabelDialog.js +18 -0
- package/esm/LinearGenomeView/components/HoverPositionHighlight.js +3 -3
- package/esm/LinearGenomeView/components/ImportForm.js +7 -9
- package/esm/LinearGenomeView/components/LinearGenomeView.js +5 -12
- package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +13 -14
- package/esm/LinearGenomeView/components/MiniControls.js +11 -5
- package/esm/LinearGenomeView/components/OverviewHighlight.js +3 -3
- package/esm/LinearGenomeView/components/OverviewHighlightBand.d.ts +3 -2
- package/esm/LinearGenomeView/components/OverviewHighlightBand.js +6 -5
- package/esm/LinearGenomeView/components/OverviewRubberband.js +25 -48
- package/esm/LinearGenomeView/components/OverviewScalebar.js +4 -5
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +5 -3
- package/esm/LinearGenomeView/components/PaddingBlocks.js +3 -8
- package/esm/LinearGenomeView/components/RangeSelectOverlay.js +5 -6
- package/esm/LinearGenomeView/components/RegionWidthEditorDialog.d.ts +3 -2
- package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +4 -4
- package/esm/LinearGenomeView/components/ResizeAllTracksHandle.d.ts +5 -0
- package/esm/LinearGenomeView/components/ResizeAllTracksHandle.js +74 -0
- package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -2
- package/esm/LinearGenomeView/components/Rubberband.js +3 -2
- package/esm/LinearGenomeView/components/SVGHighlightBand.d.ts +10 -1
- package/esm/LinearGenomeView/components/SVGHighlightBand.js +16 -5
- package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -6
- package/esm/LinearGenomeView/components/Scalebar.js +8 -5
- package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +51 -36
- package/esm/LinearGenomeView/components/SearchBox.js +10 -16
- package/esm/LinearGenomeView/components/SearchPanelForm.d.ts +3 -2
- package/esm/LinearGenomeView/components/SearchPanelForm.js +4 -2
- package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +4 -8
- package/esm/LinearGenomeView/components/SearchResultsDialog.js +7 -4
- package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +4 -7
- package/esm/LinearGenomeView/components/SearchResultsTable.js +25 -53
- package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.js +2 -3
- package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +2 -4
- package/esm/LinearGenomeView/components/StrandCheckboxes.d.ts +3 -2
- package/esm/LinearGenomeView/components/StrandCheckboxes.js +4 -2
- package/esm/LinearGenomeView/components/TrackContainer.d.ts +2 -3
- package/esm/LinearGenomeView/components/TrackContainer.js +63 -10
- package/esm/LinearGenomeView/components/TrackLabel.js +14 -4
- package/esm/LinearGenomeView/components/TrackLabelButtons.js +2 -2
- package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +4 -5
- package/esm/LinearGenomeView/components/TrackLabelMenu.js +11 -14
- package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.d.ts +3 -4
- package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.js +23 -10
- package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +6 -4
- package/esm/LinearGenomeView/components/TrackRenderingContainer.js +12 -24
- package/esm/LinearGenomeView/components/TracksContainer.js +11 -23
- package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -2
- package/esm/LinearGenomeView/components/VerticalGuide.js +3 -16
- package/esm/LinearGenomeView/components/fetchSequence.d.ts +1 -2
- package/esm/LinearGenomeView/components/fetchSequence.js +15 -7
- package/esm/LinearGenomeView/components/recentLocationsMenu.js +10 -0
- package/esm/LinearGenomeView/components/useRangeSelect.d.ts +0 -3
- package/esm/LinearGenomeView/components/useRangeSelect.js +26 -61
- package/esm/LinearGenomeView/components/useSearchBoxPrefs.d.ts +3 -1
- package/esm/LinearGenomeView/components/useSearchBoxPrefs.js +4 -2
- package/esm/LinearGenomeView/components/useSideScroll.d.ts +17 -2
- package/esm/LinearGenomeView/components/useSideScroll.js +156 -102
- 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 +2 -7
- package/esm/LinearGenomeView/index.js +5 -7
- package/esm/LinearGenomeView/keyboardHandler.d.ts +8 -7
- package/esm/LinearGenomeView/keyboardHandler.js +61 -23
- package/esm/LinearGenomeView/launchKeys.d.ts +1 -1
- package/esm/LinearGenomeView/launchKeys.js +11 -6
- package/esm/LinearGenomeView/lazyDialogs.d.ts +16 -3
- package/esm/LinearGenomeView/lazyDialogs.js +1 -0
- package/esm/LinearGenomeView/linkedViewSync.d.ts +3 -11
- package/esm/LinearGenomeView/linkedViewSync.js +27 -49
- package/esm/LinearGenomeView/menuItems.d.ts +16 -18
- package/esm/LinearGenomeView/menuItems.js +264 -164
- package/esm/LinearGenomeView/model.d.ts +1192 -560
- package/esm/LinearGenomeView/model.js +805 -590
- package/esm/LinearGenomeView/rExport/exportLinearView.d.ts +17 -0
- package/esm/LinearGenomeView/rExport/exportLinearView.js +117 -0
- package/esm/LinearGenomeView/rExport/rScript.d.ts +110 -0
- package/esm/LinearGenomeView/rExport/rScript.js +524 -0
- package/esm/LinearGenomeView/sharedScaleContainer.d.ts +1 -1
- package/esm/LinearGenomeView/sharedScaleContainer.js +2 -12
- package/esm/LinearGenomeView/showFiles.d.ts +2 -0
- package/esm/LinearGenomeView/showFiles.js +19 -0
- package/esm/LinearGenomeView/showRegionsWithUndo.d.ts +1 -1
- package/esm/LinearGenomeView/showRegionsWithUndo.js +13 -5
- 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.d.ts +3 -1
- package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +9 -9
- package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.d.ts +3 -1
- package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +5 -5
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +13 -18
- 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 +26 -0
- package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.js +12 -0
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +21 -13
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +4 -5
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +7 -6
- package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +2 -3
- package/esm/LinearGenomeView/svgcomponents/SVGView.js +17 -3
- package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +24 -20
- package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +42 -29
- package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +74 -77
- package/esm/LinearGenomeView/svgcomponents/util.d.ts +28 -12
- package/esm/LinearGenomeView/svgcomponents/util.js +41 -29
- package/esm/LinearGenomeView/types.d.ts +13 -10
- package/esm/LinearGenomeView/types.js +0 -1
- package/esm/LinearGenomeView/util.d.ts +103 -46
- package/esm/LinearGenomeView/util.js +222 -170
- package/esm/MultiLevelRubberband/MultiLevelRubberband.js +9 -6
- 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 +45 -59
- package/esm/TrackModifiers/index.d.ts +83 -0
- package/esm/TrackModifiers/index.js +231 -0
- package/esm/displayKitTests/perRegionTestEnv.d.ts +244 -68
- package/esm/displayKitTests/perRegionTestEnv.js +30 -26
- package/esm/index.d.ts +21 -99
- package/esm/index.js +17 -38
- package/esm/searchUtils.d.ts +26 -10
- package/esm/searchUtils.js +137 -137
- package/esm/shared/RubberbandSpan.d.ts +3 -2
- package/esm/shared/RubberbandSpan.js +6 -3
- package/esm/shared/coordLabels.d.ts +11 -4
- package/esm/shared/coordLabels.js +20 -5
- package/esm/shared/useWindowDrag.d.ts +18 -0
- package/esm/shared/useWindowDrag.js +47 -0
- package/package.json +12 -11
- package/esm/FeatureTrack/configSchema.d.ts +0 -124
- package/esm/FeatureTrack/configSchema.js +0 -54
- package/esm/FeatureTrack/index.d.ts +0 -2
- package/esm/FeatureTrack/index.js +0 -13
- package/esm/LinearGenomeView/initKeys.d.ts +0 -12
- package/esm/LinearGenomeView/initKeys.js +0 -68
- 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,11 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { getContainingView } from '@jbrowse/core/util';
|
|
3
2
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
3
|
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
|
5
4
|
import ArrowRightIcon from '@mui/icons-material/ArrowRight';
|
|
6
5
|
import CloseIcon from '@mui/icons-material/Close';
|
|
7
6
|
import { IconButton } from '@mui/material';
|
|
8
7
|
import { observer } from 'mobx-react';
|
|
8
|
+
import { containingLgv } from '../../LinearGenomeView/containingLgv.js';
|
|
9
9
|
const useStyles = makeStyles()({
|
|
10
10
|
iconButton: {
|
|
11
11
|
padding: 0,
|
|
@@ -21,7 +21,7 @@ const useStyles = makeStyles()({
|
|
|
21
21
|
// write it.
|
|
22
22
|
export const TrackLabelCloseButton = observer(function TrackLabelCloseButton({ track, }) {
|
|
23
23
|
const { classes } = useStyles();
|
|
24
|
-
const view =
|
|
24
|
+
const view = containingLgv(track);
|
|
25
25
|
return (_jsx(IconButton, { onClick: () => view.hideTrack(track.trackId), className: classes.iconButton, title: "close this track", "data-testid": `track-close-${track.trackId}`, children: _jsx(CloseIcon, { fontSize: "small" }) }));
|
|
26
26
|
});
|
|
27
27
|
export const TrackLabelMinimizeButton = observer(function TrackLabelMinimizeButton({ track }) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { getContainingView } from '@jbrowse/core/util';
|
|
3
2
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
3
|
import DragIcon from '@mui/icons-material/DragIndicator';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
5
|
+
import { containingLgv } from '../../LinearGenomeView/containingLgv.js';
|
|
6
6
|
const useStyles = makeStyles()({
|
|
7
7
|
dragHandle: {
|
|
8
8
|
cursor: 'grab',
|
|
@@ -15,12 +15,11 @@ const useStyles = makeStyles()({
|
|
|
15
15
|
});
|
|
16
16
|
const TrackLabelDragHandle = observer(function TrackLabelDragHandle({ track, }) {
|
|
17
17
|
const { classes } = useStyles();
|
|
18
|
-
const view =
|
|
18
|
+
const view = containingLgv(track);
|
|
19
19
|
const trackId = track.trackId;
|
|
20
20
|
return (_jsx("span", { draggable: true, className: classes.dragHandle, onDragStart: event => {
|
|
21
|
-
const
|
|
22
|
-
if (
|
|
23
|
-
const parent = target.parentNode;
|
|
21
|
+
const parent = event.currentTarget.parentElement;
|
|
22
|
+
if (parent) {
|
|
24
23
|
event.dataTransfer.setDragImage(parent, 20, 20);
|
|
25
24
|
view.setDraggingTrackId(track.id);
|
|
26
25
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
|
|
3
|
-
import {
|
|
3
|
+
import { TRACK_MENU_PRIORITY, subMenuIfAny } from '@jbrowse/core/ui/menuItems';
|
|
4
|
+
import { getSession } from '@jbrowse/core/util';
|
|
4
5
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
5
6
|
import LowPriorityIcon from '@mui/icons-material/LowPriority';
|
|
6
7
|
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
7
8
|
import { observer } from 'mobx-react';
|
|
9
|
+
import { containingLgv } from '../../LinearGenomeView/containingLgv.js';
|
|
8
10
|
import { getTrackOrderSubMenu } from './trackLabelMenuItems.js';
|
|
9
11
|
// IconButton's default 5px padding made this the tallest thing in the label
|
|
10
12
|
// (27px), so it, not the text or the other controls, set the label height and
|
|
@@ -17,7 +19,7 @@ const useStyles = makeStyles()({
|
|
|
17
19
|
});
|
|
18
20
|
const TrackLabelMenu = observer(function TrackLabelMenu({ track, }) {
|
|
19
21
|
const { classes } = useStyles();
|
|
20
|
-
const view =
|
|
22
|
+
const view = containingLgv(track);
|
|
21
23
|
const session = getSession(track);
|
|
22
24
|
function getMenuItems() {
|
|
23
25
|
const orderSubMenu = getTrackOrderSubMenu({ view, track });
|
|
@@ -26,21 +28,16 @@ const TrackLabelMenu = observer(function TrackLabelMenu({ track, }) {
|
|
|
26
28
|
view,
|
|
27
29
|
}) ?? [];
|
|
28
30
|
return [
|
|
29
|
-
...(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
priority: 1000,
|
|
36
|
-
subMenu: orderSubMenu,
|
|
37
|
-
},
|
|
38
|
-
]
|
|
39
|
-
: []),
|
|
31
|
+
...subMenuIfAny({
|
|
32
|
+
label: 'Track order',
|
|
33
|
+
icon: LowPriorityIcon,
|
|
34
|
+
priority: TRACK_MENU_PRIORITY.trackOrder,
|
|
35
|
+
subMenu: orderSubMenu,
|
|
36
|
+
}),
|
|
40
37
|
...sessionItems,
|
|
41
38
|
track.saveTrackDataMenuItem,
|
|
42
39
|
...track.trackMenuItems(),
|
|
43
|
-
]
|
|
40
|
+
];
|
|
44
41
|
}
|
|
45
42
|
return (_jsx(CascadingMenuButton, { menuItems: getMenuItems, className: classes.menuButton, "data-testid": "track_menu_icon", "data-trackid": track.trackId, tooltip: "Track settings", children: _jsx(MoreVertIcon, { fontSize: "small" }) }));
|
|
46
43
|
});
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models';
|
|
2
2
|
/**
|
|
3
|
-
* The track label's warning for a file
|
|
4
|
-
* common with the assembly's
|
|
5
|
-
*
|
|
6
|
-
* exactly like a track with no features in view.
|
|
3
|
+
* The track label's warning for a file that does not fit its assembly: its
|
|
4
|
+
* reference names have nothing in common with the assembly's, so the track
|
|
5
|
+
* draws nothing, or its contig lengths say it was made against another build.
|
|
7
6
|
*
|
|
8
7
|
* The label rather than the display chrome, deliberately. The chrome's states
|
|
9
8
|
* are `displayPhase`'s, which are mutually exclusive and two of which replace
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import { refNameMismatchMessage } from '@jbrowse/core/assemblyManager/assembly';
|
|
3
|
+
import { contigLengthMismatchMessage, refNameMismatchMessage, } from '@jbrowse/core/assemblyManager/assembly';
|
|
4
4
|
import { InfoDialog } from '@jbrowse/core/ui';
|
|
5
5
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
6
6
|
import WarningIcon from '@mui/icons-material/Warning';
|
|
@@ -12,11 +12,24 @@ const useStyles = makeStyles()(theme => ({
|
|
|
12
12
|
color: theme.palette.warning.main,
|
|
13
13
|
},
|
|
14
14
|
}));
|
|
15
|
+
function warningFor(track) {
|
|
16
|
+
const { refNameMismatch, contigLengthMismatch } = track;
|
|
17
|
+
return refNameMismatch
|
|
18
|
+
? {
|
|
19
|
+
title: 'Reference names do not match the assembly',
|
|
20
|
+
message: refNameMismatchMessage(refNameMismatch),
|
|
21
|
+
}
|
|
22
|
+
: contigLengthMismatch
|
|
23
|
+
? {
|
|
24
|
+
title: 'Reference sequence lengths do not match the assembly',
|
|
25
|
+
message: contigLengthMismatchMessage(contigLengthMismatch),
|
|
26
|
+
}
|
|
27
|
+
: undefined;
|
|
28
|
+
}
|
|
15
29
|
/**
|
|
16
|
-
* The track label's warning for a file
|
|
17
|
-
* common with the assembly's
|
|
18
|
-
*
|
|
19
|
-
* exactly like a track with no features in view.
|
|
30
|
+
* The track label's warning for a file that does not fit its assembly: its
|
|
31
|
+
* reference names have nothing in common with the assembly's, so the track
|
|
32
|
+
* draws nothing, or its contig lengths say it was made against another build.
|
|
20
33
|
*
|
|
21
34
|
* The label rather than the display chrome, deliberately. The chrome's states
|
|
22
35
|
* are `displayPhase`'s, which are mutually exclusive and two of which replace
|
|
@@ -32,15 +45,15 @@ const useStyles = makeStyles()(theme => ({
|
|
|
32
45
|
const TrackLabelRefNameWarning = observer(function TrackLabelRefNameWarning({ track, }) {
|
|
33
46
|
const { classes } = useStyles();
|
|
34
47
|
const [open, setOpen] = useState(false);
|
|
35
|
-
const
|
|
36
|
-
if (!
|
|
48
|
+
const warning = warningFor(track);
|
|
49
|
+
if (!warning) {
|
|
37
50
|
return null;
|
|
38
51
|
}
|
|
39
|
-
const message =
|
|
52
|
+
const { title, message } = warning;
|
|
40
53
|
return (_jsxs(_Fragment, { children: [_jsx(IconButton, { onClick: () => {
|
|
41
54
|
setOpen(true);
|
|
42
|
-
}, className: classes.iconButton, title: message, "data-testid": `track-refname-warning-${track.trackId}`, children: _jsx(WarningIcon, { fontSize: "small" }) }), open ? (_jsxs(InfoDialog, { open: true, title:
|
|
55
|
+
}, className: classes.iconButton, title: message, "data-testid": `track-refname-warning-${track.trackId}`, children: _jsx(WarningIcon, { fontSize: "small" }) }), open ? (_jsxs(InfoDialog, { open: true, title: title, onClose: () => {
|
|
43
56
|
setOpen(false);
|
|
44
|
-
}, children: [_jsx(Typography, { children: message }), _jsx(Typography, { variant: "body2", style: { marginTop: 8 }, children: "The track menu's \"About track\" shows every reference name the file uses." })] })) : null] }));
|
|
57
|
+
}, children: [_jsx(Typography, { children: message }), _jsx(Typography, { variant: "body2", style: { marginTop: 8 }, children: "The track menu's \"About track\" shows every reference name the file uses, with the lengths it states." })] })) : null] }));
|
|
45
58
|
});
|
|
46
59
|
export default TrackLabelRefNameWarning;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { LinearGenomeViewModel } from '../index.ts';
|
|
2
|
-
import type {
|
|
1
|
+
import type { LinearGenomeViewModel, LinearGenomeViewTrack } from '../index.ts';
|
|
2
|
+
import type { LinearDisplayModel } from '@jbrowse/display-kit/types';
|
|
3
3
|
type LGV = LinearGenomeViewModel;
|
|
4
|
-
declare const TrackRenderingContainer: ({ model, track, }: {
|
|
4
|
+
declare const TrackRenderingContainer: ({ model, track, display, ref, }: {
|
|
5
5
|
model: LGV;
|
|
6
|
-
track:
|
|
6
|
+
track: LinearGenomeViewTrack;
|
|
7
|
+
display: LinearDisplayModel;
|
|
8
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
7
9
|
}) => import("react").JSX.Element;
|
|
8
10
|
export default TrackRenderingContainer;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Suspense
|
|
2
|
+
import { Suspense } from 'react';
|
|
3
3
|
import { LoadingOverlay } from '@jbrowse/core/ui';
|
|
4
|
-
import { getSession } from '@jbrowse/core/util';
|
|
4
|
+
import { coarseStripHTML, getSession } from '@jbrowse/core/util';
|
|
5
5
|
import { getTrackName } from '@jbrowse/core/util/tracks';
|
|
6
6
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
7
|
+
import { TrackOverlayPortal } from '@jbrowse/display-ui';
|
|
7
8
|
import { observer } from 'mobx-react';
|
|
8
|
-
import {
|
|
9
|
+
import { TRACK_OUTLINE_BORDER } from '../consts.js';
|
|
9
10
|
const useStyles = makeStyles()({
|
|
10
11
|
// aligns with block boundaries. check for example the breakpoint split view
|
|
11
12
|
// demo to see if features align if wanting to change things. the -1 left
|
|
@@ -17,7 +18,7 @@ const useStyles = makeStyles()({
|
|
|
17
18
|
width: '100%',
|
|
18
19
|
},
|
|
19
20
|
// Tracks never scroll natively on this outer container — every display owns
|
|
20
|
-
// its own vertical scroll:
|
|
21
|
+
// its own vertical scroll: feature displays scroll an inner sticky-canvas
|
|
21
22
|
// container (FeatureComponent), while alignments and variants draw a custom
|
|
22
23
|
// VerticalScrollbar overlay and redraw the canvas at `scrollTop`. A native
|
|
23
24
|
// scroll port here only produced a *second*, spurious scrollbar whenever a
|
|
@@ -68,32 +69,19 @@ const useStyles = makeStyles()({
|
|
|
68
69
|
// nothing. `figure` names the box and keeps what is inside it reachable. Revisit
|
|
69
70
|
// if inline interactive chrome ever goes away.
|
|
70
71
|
const TrackDisplayRegion = observer(function TrackDisplayRegion({ model, track, children, ...divProps }) {
|
|
71
|
-
const trackName = getTrackName(track.configuration, getSession(track));
|
|
72
|
+
const trackName = coarseStripHTML(getTrackName(track.configuration, getSession(track)));
|
|
72
73
|
const loc = model.coarseVisibleLocStrings;
|
|
73
74
|
return (_jsx("div", { ...divProps, role: "figure", "aria-label": loc ? `${trackName} track, showing ${loc}` : `${trackName} track`, children: children }));
|
|
74
75
|
});
|
|
75
|
-
const TrackRenderingContainer = observer(function TrackRenderingContainer({ model, track, }) {
|
|
76
|
+
const TrackRenderingContainer = observer(function TrackRenderingContainer({ model, track, display, ref, }) {
|
|
76
77
|
const { classes } = useStyles();
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const display = track.activeDisplay;
|
|
80
|
-
const { height, RenderingComponent, DisplayBlurb } = display;
|
|
81
|
-
const { trackRefs, showTrackOutlines } = model;
|
|
78
|
+
const { RenderingComponent, DisplayBlurb } = display;
|
|
79
|
+
const { showTrackOutlines } = model;
|
|
82
80
|
const trackId = track.trackId;
|
|
83
81
|
const minimized = track.minimized;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (el) {
|
|
88
|
-
trackRefs[trackId] = el;
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
delete trackRefs[trackId];
|
|
92
|
-
}
|
|
93
|
-
}, [trackRefs, trackId]);
|
|
94
|
-
return (_jsx("div", { className: classes.trackRenderingContainer, style: {
|
|
95
|
-
height: minimized ? MINIMIZED_TRACK_HEIGHT : height,
|
|
96
|
-
}, "data-testid": `trackRenderingContainer-${model.id}-${trackId}`, children: !minimized ? (_jsxs(_Fragment, { children: [_jsx(TrackDisplayRegion, { model: model, track: track, ref: setRef, className: classes.renderingComponentContainer, style: { left: showTrackOutlines ? -1 : 0 }, children: _jsx(Suspense, { fallback: _jsx(LoadingOverlay, { isVisible: true, immediate: true }), children: _jsx(RenderingComponent, { model: display, onHorizontalScroll: model.horizontalScroll }) }) }), DisplayBlurb ? (_jsx("div", { style: {
|
|
82
|
+
return (_jsx("div", { ref: ref, className: classes.trackRenderingContainer, style: {
|
|
83
|
+
height: model.trackHeight(track),
|
|
84
|
+
}, "data-testid": `trackRenderingContainer-${model.id}-${trackId}`, children: !minimized ? (_jsxs(_Fragment, { children: [_jsx(TrackDisplayRegion, { model: model, track: track, className: classes.renderingComponentContainer, style: { left: showTrackOutlines ? -TRACK_OUTLINE_BORDER : 0 }, children: _jsx(Suspense, { fallback: _jsx(TrackOverlayPortal, { children: _jsx(LoadingOverlay, { isVisible: true, immediate: true }) }), children: _jsx(RenderingComponent, { model: display, onHorizontalScroll: model.horizontalScroll }) }) }), DisplayBlurb ? (_jsx("div", { style: {
|
|
97
85
|
position: 'absolute',
|
|
98
86
|
left: 0,
|
|
99
87
|
top: display.height - 20,
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Suspense, lazy, useRef } from 'react';
|
|
3
3
|
import { PluggableElements } from '@jbrowse/core/ui';
|
|
4
|
-
import {
|
|
5
|
-
import { useMouseTracking } from '@jbrowse/core/ui/useMouseTracking';
|
|
4
|
+
import { useStyleTheme } from '@jbrowse/core/ui/PaletteContext';
|
|
6
5
|
import { getEnv, getSession } from '@jbrowse/core/util';
|
|
7
6
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
8
|
-
import { useTheme } from '@mui/material';
|
|
9
7
|
import { observer } from 'mobx-react';
|
|
10
8
|
import { SCALE_BAR_HEIGHT } from '../consts.js';
|
|
11
9
|
import Gridlines from './Gridlines.js';
|
|
@@ -13,7 +11,6 @@ import OverviewHighlightBand from './OverviewHighlightBand.js';
|
|
|
13
11
|
import PaddingBlocks from './PaddingBlocks.js';
|
|
14
12
|
import RangeSelectOverlay from './RangeSelectOverlay.js';
|
|
15
13
|
import Rubberband from './Rubberband.js';
|
|
16
|
-
import Scalebar from './Scalebar.js';
|
|
17
14
|
import VerticalGuide from './VerticalGuide.js';
|
|
18
15
|
import { useRangeSelect } from './useRangeSelect.js';
|
|
19
16
|
import { useSideScroll } from './useSideScroll.js';
|
|
@@ -24,6 +21,9 @@ const useStyles = makeStyles()({
|
|
|
24
21
|
tracksContainer: {
|
|
25
22
|
position: 'relative',
|
|
26
23
|
contain: 'layout style',
|
|
24
|
+
// horizontal drags and pinches are the view's; vertical scroll stays the
|
|
25
|
+
// page's
|
|
26
|
+
touchAction: 'pan-y',
|
|
27
27
|
},
|
|
28
28
|
scalebarHighlights: {
|
|
29
29
|
position: 'absolute',
|
|
@@ -39,40 +39,28 @@ const useStyles = makeStyles()({
|
|
|
39
39
|
const TracksContainer = observer(function TracksContainer({ children, model, }) {
|
|
40
40
|
const { classes } = useStyles();
|
|
41
41
|
const { pluginManager } = getEnv(model);
|
|
42
|
-
const
|
|
43
|
-
const { showGridlines, showCenterLine } = model;
|
|
42
|
+
const sideScroll = useSideScroll(model);
|
|
43
|
+
const { axisGrid: showGridlines, showCenterLine } = model;
|
|
44
44
|
const ref = useRef(null);
|
|
45
45
|
// shift-drag range select over the whole tracks area. This is intentionally
|
|
46
46
|
// a separate range-select instance from the one inside <Rubberband> (the
|
|
47
47
|
// scalebar control); don't dedupe them — they cover different regions.
|
|
48
48
|
const range = useRangeSelect(ref, model, true);
|
|
49
|
-
|
|
50
|
-
// read it, and a position in state here would re-render the whole tracks area
|
|
51
|
-
// every frame the pointer moves over it
|
|
52
|
-
const { mouseTracker, handleMouseMove, handleMouseLeave } = useMouseTracking();
|
|
53
|
-
return (_jsx("div", { ref: ref, "data-testid": "tracksContainer", className: classes.tracksContainer, onMouseDown: event => {
|
|
54
|
-
sideScrollMouseDown(event);
|
|
55
|
-
range.mouseDown(event);
|
|
56
|
-
}, onMouseMove: event => {
|
|
57
|
-
handleMouseMove(event);
|
|
49
|
+
return (_jsxs("div", { ref: ref, "data-testid": "tracksContainer", className: classes.tracksContainer, ...sideScroll, onMouseDown: range.mouseDown, onMouseMove: event => {
|
|
58
50
|
range.mouseMove(event);
|
|
59
51
|
}, onMouseLeave: () => {
|
|
60
|
-
handleMouseLeave();
|
|
61
52
|
range.mouseOut();
|
|
62
|
-
},
|
|
63
|
-
height: SCALE_BAR_HEIGHT,
|
|
64
|
-
boxSizing: 'border-box',
|
|
65
|
-
} }) }), _jsx(ScalebarHighlightGroup, { model: model }), _jsx(HighlightGroup, { model: model }), _jsx(PluggableElements, { pluginManager: pluginManager, name: "LinearGenomeView-TracksContainerComponent", props: { model } }), children] }) }));
|
|
53
|
+
}, children: [showGridlines ? (_jsxs(_Fragment, { children: [_jsx(Gridlines, { model: model }), _jsx(PaddingBlocks, { model: model })] })) : null, _jsx(Suspense, { fallback: null, children: showCenterLine ? _jsx(CenterLine, { model: model }) : null }), _jsx(RangeSelectOverlay, { model: model, range: range }), model.volatileGuides.map((guide, idx) => (_jsx(VerticalGuide, { model: model, coordX: guide.xPos }, idx))), _jsx(Rubberband, { model: model }), _jsx(ScalebarHighlightGroup, { model: model }), _jsx(HighlightGroup, { model: model }), _jsx(PluggableElements, { pluginManager: pluginManager, name: "LinearGenomeView-TracksContainerComponent", props: { model } }), children] }));
|
|
66
54
|
});
|
|
67
55
|
const HighlightGroup = observer(function HighlightGroup({ model, }) {
|
|
68
|
-
return getSession(model).highlightsVisible && model.
|
|
56
|
+
return getSession(model).highlightsVisible && model.highlights.length ? (_jsx(Suspense, { fallback: null, children: model.highlights.map((highlight, idx) => (_jsx(Highlight, { model: model, highlight: highlight }, highlightKey(highlight, idx)))) })) : null;
|
|
69
57
|
});
|
|
70
58
|
const ScalebarHighlightGroup = observer(function ScalebarHighlightGroup({ model, }) {
|
|
71
|
-
const theme =
|
|
59
|
+
const theme = useStyleTheme();
|
|
72
60
|
const { pluginManager } = getEnv(model);
|
|
73
61
|
const { classes } = useStyles();
|
|
74
62
|
const viewBands = getSession(model).highlightsVisible
|
|
75
|
-
? model.
|
|
63
|
+
? model.highlights.map((h, idx) => {
|
|
76
64
|
const coords = model.getHighlightCoords(h);
|
|
77
65
|
return coords ? (_jsx(OverviewHighlightBand, { coords: coords, background: getHighlightColor(h, theme).toRgbString() }, highlightKey(h, idx))) : null;
|
|
78
66
|
})
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { LinearGenomeViewModel } from '../index.ts';
|
|
2
|
-
type LGV = LinearGenomeViewModel;
|
|
3
2
|
declare const VerticalGuide: ({ model, coordX, }: {
|
|
4
|
-
model:
|
|
3
|
+
model: LinearGenomeViewModel;
|
|
5
4
|
coordX: number;
|
|
6
5
|
}) => import("react").JSX.Element;
|
|
7
6
|
export default VerticalGuide;
|
|
@@ -1,24 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { stringify } from '@jbrowse/core/util';
|
|
3
|
-
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
3
|
import { observer } from 'mobx-react';
|
|
5
|
-
import {
|
|
4
|
+
import { VerticalGuideLine } from '../../shared/coordLabels.js';
|
|
6
5
|
import { stickyChromeTops } from '../stickyChrome.js';
|
|
7
|
-
const useStyles = makeStyles()({
|
|
8
|
-
guide: {
|
|
9
|
-
pointerEvents: 'none',
|
|
10
|
-
height: '100%',
|
|
11
|
-
width: 1,
|
|
12
|
-
position: 'absolute',
|
|
13
|
-
left: 0,
|
|
14
|
-
background: 'red',
|
|
15
|
-
zIndex: 1001,
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
6
|
const VerticalGuide = observer(function VerticalGuide({ model, coordX, }) {
|
|
19
|
-
const { classes } = useStyles();
|
|
20
7
|
const { width, stickyViewHeaders, headerHeight } = model;
|
|
21
8
|
const { scalebar } = stickyChromeTops({ stickyViewHeaders, headerHeight });
|
|
22
|
-
return (
|
|
9
|
+
return (_jsx(VerticalGuideLine, { coordX: coordX, viewWidth: width, stickyTop: scalebar, children: stringify(model.pxToBp(coordX)) }));
|
|
23
10
|
});
|
|
24
11
|
export default VerticalGuide;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { StatusCallback } from '@jbrowse/core/util';
|
|
2
|
-
import type { StopToken } from '@jbrowse/core/util/stopToken';
|
|
3
2
|
import type { Region } from '@jbrowse/core/util/types';
|
|
4
3
|
import type { IAnyStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
5
4
|
export declare function fetchSequence(model: IAnyStateTreeNode, regions: Region[], opts?: {
|
|
6
|
-
|
|
5
|
+
signal?: AbortSignal;
|
|
7
6
|
statusCallback?: StatusCallback;
|
|
8
7
|
}): Promise<import("@jbrowse/core/util").Feature[]>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getSequenceAdapterConfig } from '@jbrowse/core/assemblyManager/assembly';
|
|
2
|
-
import { getSession } from '@jbrowse/core/util';
|
|
2
|
+
import { assembleLocString, getSession } from '@jbrowse/core/util';
|
|
3
3
|
export async function fetchSequence(model, regions, opts = {}) {
|
|
4
4
|
const session = getSession(model);
|
|
5
5
|
const assemblyNames = new Set(regions.map(r => r.assemblyName));
|
|
@@ -25,10 +25,18 @@ export async function fetchSequence(model, regions, opts = {}) {
|
|
|
25
25
|
if (!adapterConfig) {
|
|
26
26
|
throw new Error(`assembly ${assemblyName} has no resolved configuration, so its sequence adapter cannot be read`);
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
// one call per region: a multi-region fetch merges its regions' streams in
|
|
29
|
+
// the order they finish, and a region the sequence lacks yields nothing,
|
|
30
|
+
// where the reader wants one entry per selected region, in selection order
|
|
31
|
+
return Promise.all(regions.map(async (region) => {
|
|
32
|
+
const [feature] = await rpcManager.call('getSequence', 'CoreGetFeatures', {
|
|
33
|
+
adapterConfig,
|
|
34
|
+
regions: [region],
|
|
35
|
+
...opts,
|
|
36
|
+
});
|
|
37
|
+
if (!feature) {
|
|
38
|
+
throw new Error(`no sequence found for ${assembleLocString(region)} in assembly ${assemblyName}`);
|
|
39
|
+
}
|
|
40
|
+
return feature;
|
|
41
|
+
}));
|
|
34
42
|
}
|
|
@@ -19,6 +19,16 @@ export function recentLocationsMenu({ recentLocations, onNavigate, onClear, }) {
|
|
|
19
19
|
label: 'Recent',
|
|
20
20
|
subMenu: [
|
|
21
21
|
...recentLocations.map(({ label, loc }) => ({
|
|
22
|
+
// the list dedupes on the location, so two rows can share a
|
|
23
|
+
// display string — two features of the same name at different
|
|
24
|
+
// loci, or two snippets ellipsized to the same text. `id` is what
|
|
25
|
+
// keeps them separate rows to React, which otherwise keys both on
|
|
26
|
+
// that one label.
|
|
27
|
+
//
|
|
28
|
+
// Prefixed, because a freehand row has no location and falls back
|
|
29
|
+
// to its label, which may itself be a locstring — unprefixed, that
|
|
30
|
+
// row and a recorded one at the same locus share an id.
|
|
31
|
+
id: loc ? `loc:${loc}` : `query:${label}`,
|
|
22
32
|
label,
|
|
23
33
|
onClick: () => {
|
|
24
34
|
// a row that recorded a location navigates straight to it; one
|
|
@@ -7,11 +7,8 @@ interface AnchorPosition {
|
|
|
7
7
|
isClick: boolean;
|
|
8
8
|
}
|
|
9
9
|
export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement | null>, model: LinearGenomeViewModel, shiftOnly?: boolean): {
|
|
10
|
-
open: boolean;
|
|
11
10
|
isClick: boolean | undefined;
|
|
12
|
-
clickBpOffset: import("@jbrowse/core/util/Base1DUtils").PxToBpResult | undefined;
|
|
13
11
|
guideX: number | undefined;
|
|
14
|
-
rubberbandOn: boolean;
|
|
15
12
|
mouseDown: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
16
13
|
mouseMove: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
17
14
|
mouseOut: () => void;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { useCallback,
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
2
|
import { getRelativeX } from '@jbrowse/core/util/getRelativeX';
|
|
3
|
+
import { isClaimedPress, isFromPortal } from '@jbrowse/core/util/pressOwner';
|
|
4
|
+
import { useWindowDrag } from '../../shared/useWindowDrag.js';
|
|
5
|
+
import { isOnScalebarRefLabel } from './util.js';
|
|
3
6
|
export function useRangeSelect(ref, model, shiftOnly) {
|
|
4
7
|
const [startX, setStartX] = useState();
|
|
5
8
|
const [currentX, setCurrentX] = useState();
|
|
9
|
+
const [startedOnRefLabel, setStartedOnRefLabel] = useState(false);
|
|
6
10
|
// clientX and clientY used for anchorPosition for menu
|
|
7
11
|
// offsetX used for calculations about width of selection
|
|
8
12
|
const [anchorPosition, setAnchorPosition] = useState();
|
|
@@ -14,69 +18,37 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
14
18
|
setCurrentX(undefined);
|
|
15
19
|
setGuideX(undefined);
|
|
16
20
|
}, []);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// it once here rather than calling getBoundingClientRect on every mousemove
|
|
24
|
-
const { left } = el.getBoundingClientRect();
|
|
25
|
-
function globalMouseMove(event) {
|
|
26
|
-
setCurrentX(event.clientX - left);
|
|
27
|
-
}
|
|
28
|
-
function globalMouseUp(event) {
|
|
29
|
-
if (startX === undefined) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const { clientX, clientY } = event;
|
|
33
|
-
const offsetX = clientX - left;
|
|
34
|
-
const isClick = Math.abs(offsetX - startX) <= 3;
|
|
35
|
-
// Clear the flag unconditionally once consumed: the label's own onClick
|
|
36
|
-
// also clears it, but that only fires if mouseup lands on the label, so
|
|
37
|
-
// relying on it alone can leave the flag stuck (swallowing the next
|
|
38
|
-
// scalebar click) when mouseup drifts a few px off the label edge.
|
|
39
|
-
const startedOnRefLabel = model.scalebarRefNameClickPending;
|
|
40
|
-
if (startedOnRefLabel) {
|
|
41
|
-
model.setScalebarRefNameClickPending(false);
|
|
42
|
-
}
|
|
43
|
-
// A click that began on a scalebar refname label is handled by that
|
|
44
|
-
// label's onClick (opens its menu), not by the rubberband menu here.
|
|
45
|
-
// Drop the hover guide too: the label's menu covers it while it is open,
|
|
46
|
-
// and nothing else clears it, so picking an item like "Focus on X" left a
|
|
47
|
-
// red line stranded on the scalebar with the pointer nowhere near it
|
|
21
|
+
useWindowDrag(ref, mouseDragging ? startX : undefined, {
|
|
22
|
+
onMove: setCurrentX,
|
|
23
|
+
onEnd: ({ startX, endX, isClick, clientX, clientY }) => {
|
|
24
|
+
// A click on a scalebar refName label belongs to the label's own menu.
|
|
25
|
+
// Drop the hover guide too: that menu covers it, and nothing else clears
|
|
26
|
+
// it once the menu closes
|
|
48
27
|
if (isClick && startedOnRefLabel) {
|
|
49
28
|
setStartX(undefined);
|
|
50
29
|
setCurrentX(undefined);
|
|
51
30
|
setGuideX(undefined);
|
|
52
31
|
return;
|
|
53
32
|
}
|
|
54
|
-
setAnchorPosition({ offsetX, clientX, clientY, isClick });
|
|
33
|
+
setAnchorPosition({ offsetX: endX, clientX, clientY, isClick });
|
|
55
34
|
if (isClick) {
|
|
56
|
-
setGuideX(
|
|
35
|
+
setGuideX(endX);
|
|
57
36
|
}
|
|
58
37
|
else {
|
|
59
|
-
model.setOffsets(model.pxToBp(Math.min(startX,
|
|
38
|
+
model.setOffsets(model.pxToBp(Math.min(startX, endX)), model.pxToBp(Math.max(startX, endX)));
|
|
60
39
|
setGuideX(undefined);
|
|
61
40
|
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
window.addEventListener('mousemove', globalMouseMove);
|
|
70
|
-
window.addEventListener('mouseup', globalMouseUp);
|
|
71
|
-
window.addEventListener('keydown', globalKeyDown);
|
|
72
|
-
return () => {
|
|
73
|
-
window.removeEventListener('mousemove', globalMouseMove);
|
|
74
|
-
window.removeEventListener('mouseup', globalMouseUp);
|
|
75
|
-
window.removeEventListener('keydown', globalKeyDown);
|
|
76
|
-
};
|
|
77
|
-
}, [startX, mouseDragging, model, ref]);
|
|
41
|
+
},
|
|
42
|
+
onCancel: () => {
|
|
43
|
+
setStartX(undefined);
|
|
44
|
+
setCurrentX(undefined);
|
|
45
|
+
},
|
|
46
|
+
});
|
|
78
47
|
function mouseDown(event) {
|
|
79
|
-
if (
|
|
48
|
+
if (event.button !== 0 ||
|
|
49
|
+
(shiftOnly
|
|
50
|
+
? !event.shiftKey || isClaimedPress(event)
|
|
51
|
+
: isFromPortal(event))) {
|
|
80
52
|
return;
|
|
81
53
|
}
|
|
82
54
|
// a press with the refName menu already open reopens it on the label under
|
|
@@ -90,13 +62,14 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
90
62
|
// clear any leftover menu/selection so a fresh drag isn't blocked by a
|
|
91
63
|
// stale anchorPosition keeping mouseDragging false
|
|
92
64
|
setAnchorPosition(undefined);
|
|
65
|
+
setStartedOnRefLabel(isOnScalebarRefLabel(event.target));
|
|
93
66
|
const relativeX = getRelativeX(event, ref.current);
|
|
94
67
|
setStartX(relativeX);
|
|
95
68
|
setCurrentX(relativeX);
|
|
96
69
|
}
|
|
97
70
|
function mouseMove(event) {
|
|
98
71
|
// Keep the rubberband visible while a drag-selection menu is open
|
|
99
|
-
if (anchorPosition?.isClick === false) {
|
|
72
|
+
if (anchorPosition?.isClick === false || isFromPortal(event)) {
|
|
100
73
|
return;
|
|
101
74
|
}
|
|
102
75
|
const wantsGuide = !mouseDragging && (!shiftOnly || event.shiftKey);
|
|
@@ -111,11 +84,7 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
111
84
|
callback();
|
|
112
85
|
handleClose();
|
|
113
86
|
}
|
|
114
|
-
const open = Boolean(anchorPosition);
|
|
115
87
|
const isClick = anchorPosition?.isClick;
|
|
116
|
-
const clickBpOffset = isClick
|
|
117
|
-
? model.pxToBp(anchorPosition.offsetX)
|
|
118
|
-
: undefined;
|
|
119
88
|
// rubberband geometry only exists while a drag is in progress (startX set);
|
|
120
89
|
// grouped so a single truthiness check narrows all fields for RubberbandSpan
|
|
121
90
|
let rubberband;
|
|
@@ -132,12 +101,8 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
132
101
|
};
|
|
133
102
|
}
|
|
134
103
|
return {
|
|
135
|
-
open,
|
|
136
104
|
isClick,
|
|
137
|
-
clickBpOffset,
|
|
138
105
|
guideX,
|
|
139
|
-
// true only mid-drag and not a click — drives RubberbandSpan vs guide
|
|
140
|
-
rubberbandOn: rubberband !== undefined && !isClick,
|
|
141
106
|
mouseDown,
|
|
142
107
|
mouseMove,
|
|
143
108
|
mouseOut,
|
|
@@ -22,5 +22,7 @@ export type SearchBoxPrefs = ReturnType<typeof useSearchBoxPrefs>;
|
|
|
22
22
|
/**
|
|
23
23
|
* The menu rows that drive those prefs. "Stacked" rather than "Vertical": the
|
|
24
24
|
* two headers name the same state and had drifted apart on it once already.
|
|
25
|
+
* A caller spreading the rows into a "Show" submenu passes `'Search boxes'`
|
|
26
|
+
* as the toggle's label.
|
|
25
27
|
*/
|
|
26
|
-
export declare function searchBoxMenuItems({ showSearchBoxes, setShowSearchBoxes, sideBySide, setSideBySide, }: SearchBoxPrefs): MenuItem[];
|
|
28
|
+
export declare function searchBoxMenuItems({ showSearchBoxes, setShowSearchBoxes, sideBySide, setSideBySide, }: SearchBoxPrefs, toggleLabel?: string): MenuItem[];
|
|
@@ -22,11 +22,13 @@ export function useSearchBoxPrefs(prefix, numViews) {
|
|
|
22
22
|
/**
|
|
23
23
|
* The menu rows that drive those prefs. "Stacked" rather than "Vertical": the
|
|
24
24
|
* two headers name the same state and had drifted apart on it once already.
|
|
25
|
+
* A caller spreading the rows into a "Show" submenu passes `'Search boxes'`
|
|
26
|
+
* as the toggle's label.
|
|
25
27
|
*/
|
|
26
|
-
export function searchBoxMenuItems({ showSearchBoxes, setShowSearchBoxes, sideBySide, setSideBySide, }) {
|
|
28
|
+
export function searchBoxMenuItems({ showSearchBoxes, setShowSearchBoxes, sideBySide, setSideBySide, }, toggleLabel = 'Show search boxes') {
|
|
27
29
|
return [
|
|
28
30
|
{
|
|
29
|
-
label:
|
|
31
|
+
label: toggleLabel,
|
|
30
32
|
type: 'checkbox',
|
|
31
33
|
checked: showSearchBoxes,
|
|
32
34
|
onClick: () => {
|