@jbrowse/plugin-linear-genome-view 5.0.0-beta.7 → 5.0.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/esm/FeatureTrack/configSchema.d.ts +140 -48
  2. package/esm/LinearGenomeView/afterAttach.d.ts +5 -5
  3. package/esm/LinearGenomeView/afterAttach.js +18 -24
  4. package/esm/LinearGenomeView/closeUps.d.ts +83 -0
  5. package/esm/LinearGenomeView/closeUps.js +211 -0
  6. package/esm/LinearGenomeView/components/AddCloseUpDialog.d.ts +19 -0
  7. package/esm/LinearGenomeView/components/AddCloseUpDialog.js +29 -0
  8. package/esm/LinearGenomeView/components/CloseUps.d.ts +5 -0
  9. package/esm/LinearGenomeView/components/CloseUps.js +75 -0
  10. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +2 -1
  11. package/esm/LinearGenomeView/components/ExportSvgDialog.js +6 -2
  12. package/esm/LinearGenomeView/components/GetSequenceDialog.js +2 -2
  13. package/esm/LinearGenomeView/components/Header.js +6 -1
  14. package/esm/LinearGenomeView/components/HeaderZoomControls.js +4 -34
  15. package/esm/LinearGenomeView/components/Highlight.js +2 -4
  16. package/esm/LinearGenomeView/components/HighlightBand.js +2 -2
  17. package/esm/LinearGenomeView/components/HighlightChip.d.ts +1 -2
  18. package/esm/LinearGenomeView/components/HighlightChip.js +5 -7
  19. package/esm/LinearGenomeView/components/ImportForm.js +2 -2
  20. package/esm/LinearGenomeView/components/LinearGenomeView.js +3 -3
  21. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +3 -2
  22. package/esm/LinearGenomeView/components/OverviewHighlight.js +1 -1
  23. package/esm/LinearGenomeView/components/OverviewHighlightBand.js +2 -3
  24. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +7 -1
  25. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +22 -7
  26. package/esm/LinearGenomeView/components/SVGHighlightBand.js +2 -3
  27. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +6 -21
  28. package/esm/LinearGenomeView/components/SearchBox.js +2 -2
  29. package/esm/LinearGenomeView/components/TrackContainer.js +12 -5
  30. package/esm/LinearGenomeView/components/TrackLabel.js +1 -1
  31. package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +3 -1
  32. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +3 -7
  33. package/esm/LinearGenomeView/components/TracksContainer.js +7 -15
  34. package/esm/LinearGenomeView/components/fetchSequence.d.ts +1 -2
  35. package/esm/LinearGenomeView/components/useSideScroll.js +1 -1
  36. package/esm/LinearGenomeView/consts.d.ts +2 -0
  37. package/esm/LinearGenomeView/consts.js +5 -0
  38. package/esm/LinearGenomeView/headerFit.d.ts +2 -1
  39. package/esm/LinearGenomeView/headerFit.js +7 -2
  40. package/esm/LinearGenomeView/index.d.ts +1 -1
  41. package/esm/LinearGenomeView/keyboardHandler.d.ts +2 -0
  42. package/esm/LinearGenomeView/keyboardHandler.js +11 -0
  43. package/esm/LinearGenomeView/launchKeys.d.ts +1 -1
  44. package/esm/LinearGenomeView/launchKeys.js +15 -5
  45. package/esm/LinearGenomeView/lazyDialogs.d.ts +7 -0
  46. package/esm/LinearGenomeView/lazyDialogs.js +2 -0
  47. package/esm/LinearGenomeView/menuItems.d.ts +28 -16
  48. package/esm/LinearGenomeView/menuItems.js +213 -85
  49. package/esm/LinearGenomeView/model.d.ts +367 -199
  50. package/esm/LinearGenomeView/model.js +302 -143
  51. package/esm/LinearGenomeView/sharedScaleContainer.d.ts +1 -1
  52. package/esm/LinearGenomeView/showRegionsWithUndo.js +7 -1
  53. package/esm/LinearGenomeView/svgcomponents/SVGCloseUpFrame.d.ts +5 -0
  54. package/esm/LinearGenomeView/svgcomponents/SVGCloseUpFrame.js +8 -0
  55. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +3 -4
  56. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +3 -3
  57. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +95 -24
  58. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +4 -5
  59. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +13 -4
  60. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +4 -4
  61. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +1 -1
  62. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +52 -63
  63. package/esm/LinearGenomeView/svgcomponents/util.d.ts +8 -6
  64. package/esm/LinearGenomeView/svgcomponents/util.js +37 -16
  65. package/esm/LinearGenomeView/types.d.ts +5 -4
  66. package/esm/LinearGenomeView/util.d.ts +20 -37
  67. package/esm/LinearGenomeView/util.js +58 -141
  68. package/esm/displayKitTests/perRegionTestEnv.d.ts +64 -45
  69. package/esm/displayKitTests/perRegionTestEnv.js +6 -6
  70. package/esm/index.d.ts +9 -67
  71. package/esm/index.js +6 -22
  72. package/esm/searchUtils.d.ts +2 -3
  73. package/esm/searchUtils.js +2 -2
  74. package/package.json +7 -7
  75. package/esm/lazyPluginExports.d.ts +0 -23
  76. package/esm/lazyPluginExports.js +0 -36
@@ -24,6 +24,6 @@ const useStyles = makeStyles()(theme => ({
24
24
  const TrackLabel = observer(function TrackLabel({ track, className, }) {
25
25
  const { classes } = useStyles();
26
26
  const trackName = getTrackName(track.configuration, getSession(track));
27
- return (_jsxs(Paper, { className: cx(className, classes.root), children: [_jsx(TrackLabelDragHandle, { track: track }), _jsx(TrackLabelCloseButton, { track: track }), _jsx(TrackLabelMinimizeButton, { track: track }), _jsx(Typography, { variant: "body2", component: "span", className: classes.trackName, children: _jsx(SanitizedHTML, { html: trackName }) }), _jsx(TrackLabelRefNameWarning, { track: track }), _jsx(TrackLabelMenu, { track: track })] }));
27
+ return (_jsxs(Paper, { className: cx(className, classes.root), "data-testid": `trackLabel-${track.trackId}`, children: [_jsx(TrackLabelDragHandle, { track: track }), _jsx(TrackLabelCloseButton, { track: track }), _jsx(TrackLabelMinimizeButton, { track: track }), _jsx(Typography, { variant: "body2", component: "span", className: classes.trackName, children: _jsx(SanitizedHTML, { html: trackName }) }), _jsx(TrackLabelRefNameWarning, { track: track }), _jsx(TrackLabelMenu, { track: track })] }));
28
28
  });
29
29
  export default TrackLabel;
@@ -1,9 +1,11 @@
1
1
  import type { LinearGenomeViewModel } from '../index.ts';
2
2
  import type { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models';
3
+ import type { LinearDisplayModel } from '@jbrowse/display-kit/types';
3
4
  type LGV = LinearGenomeViewModel;
4
- declare const TrackRenderingContainer: ({ model, track, ref, }: {
5
+ declare const TrackRenderingContainer: ({ model, track, display, ref, }: {
5
6
  model: LGV;
6
7
  track: BaseTrackModel;
8
+ display: LinearDisplayModel;
7
9
  ref?: React.Ref<HTMLDivElement>;
8
10
  }) => import("react").JSX.Element;
9
11
  export default TrackRenderingContainer;
@@ -5,7 +5,6 @@ import { 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
7
  import { observer } from 'mobx-react';
8
- import { MINIMIZED_TRACK_HEIGHT } from '../consts.js';
9
8
  const useStyles = makeStyles()({
10
9
  // aligns with block boundaries. check for example the breakpoint split view
11
10
  // demo to see if features align if wanting to change things. the -1 left
@@ -72,17 +71,14 @@ const TrackDisplayRegion = observer(function TrackDisplayRegion({ model, track,
72
71
  const loc = model.coarseVisibleLocStrings;
73
72
  return (_jsx("div", { ...divProps, role: "figure", "aria-label": loc ? `${trackName} track, showing ${loc}` : `${trackName} track`, children: children }));
74
73
  });
75
- const TrackRenderingContainer = observer(function TrackRenderingContainer({ model, track, ref, }) {
74
+ const TrackRenderingContainer = observer(function TrackRenderingContainer({ model, track, display, ref, }) {
76
75
  const { classes } = useStyles();
77
- // an LGV track always holds at least one linear display (activeDisplay =
78
- // displays[0]); narrow to the linear shape for height/RenderingComponent
79
- const display = track.activeDisplay;
80
- const { height, RenderingComponent, DisplayBlurb } = display;
76
+ const { RenderingComponent, DisplayBlurb } = display;
81
77
  const { showTrackOutlines } = model;
82
78
  const trackId = track.trackId;
83
79
  const minimized = track.minimized;
84
80
  return (_jsx("div", { ref: ref, className: classes.trackRenderingContainer, style: {
85
- height: minimized ? MINIMIZED_TRACK_HEIGHT : height,
81
+ height: model.trackHeight(track),
86
82
  }, "data-testid": `trackRenderingContainer-${model.id}-${trackId}`, children: !minimized ? (_jsxs(_Fragment, { children: [_jsx(TrackDisplayRegion, { model: model, track: track, 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: {
87
83
  position: 'absolute',
88
84
  left: 0,
@@ -1,8 +1,6 @@
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 { OverlayPointerProvider } from '@jbrowse/core/ui/highlightChipReveal';
5
- import { useMouseTracking } from '@jbrowse/core/ui/useMouseTracking';
6
4
  import { getEnv, getSession } from '@jbrowse/core/util';
7
5
  import { makeStyles } from '@jbrowse/core/util/tss-react';
8
6
  import { useTheme } from '@mui/material';
@@ -46,33 +44,27 @@ const TracksContainer = observer(function TracksContainer({ children, model, })
46
44
  // a separate range-select instance from the one inside <Rubberband> (the
47
45
  // scalebar control); don't dedupe them — they cover different regions.
48
46
  const range = useRangeSelect(ref, model, true);
49
- // published rather than held (see `useMouseTracking`): the highlight bands
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 => {
47
+ return (_jsxs("div", { ref: ref, "data-testid": "tracksContainer", className: classes.tracksContainer, onMouseDown: event => {
54
48
  sideScrollMouseDown(event);
55
49
  range.mouseDown(event);
56
50
  }, onMouseMove: event => {
57
- handleMouseMove(event);
58
51
  range.mouseMove(event);
59
52
  }, onMouseLeave: () => {
60
- handleMouseLeave();
61
53
  range.mouseOut();
62
- }, onMouseUp: mouseUp, children: _jsxs(OverlayPointerProvider, { value: mouseTracker, 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, ControlComponent: _jsx(Scalebar, { model: model, style: {
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] }) }));
54
+ }, onMouseUp: mouseUp, 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, ControlComponent: _jsx(Scalebar, { model: model, style: {
55
+ height: SCALE_BAR_HEIGHT,
56
+ boxSizing: 'border-box',
57
+ } }) }), _jsx(ScalebarHighlightGroup, { model: model }), _jsx(HighlightGroup, { model: model }), _jsx(PluggableElements, { pluginManager: pluginManager, name: "LinearGenomeView-TracksContainerComponent", props: { model } }), children] }));
66
58
  });
67
59
  const HighlightGroup = observer(function HighlightGroup({ model, }) {
68
- return getSession(model).highlightsVisible && model.highlight.length ? (_jsx(Suspense, { fallback: null, children: model.highlight.map((highlight, idx) => (_jsx(Highlight, { model: model, highlight: highlight }, highlightKey(highlight, idx)))) })) : null;
60
+ 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
61
  });
70
62
  const ScalebarHighlightGroup = observer(function ScalebarHighlightGroup({ model, }) {
71
63
  const theme = useTheme();
72
64
  const { pluginManager } = getEnv(model);
73
65
  const { classes } = useStyles();
74
66
  const viewBands = getSession(model).highlightsVisible
75
- ? model.highlight.map((h, idx) => {
67
+ ? model.highlights.map((h, idx) => {
76
68
  const coords = model.getHighlightCoords(h);
77
69
  return coords ? (_jsx(OverviewHighlightBand, { coords: coords, background: getHighlightColor(h, theme).toRgbString() }, highlightKey(h, idx))) : null;
78
70
  })
@@ -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
- stopToken?: StopToken;
5
+ signal?: AbortSignal;
7
6
  statusCallback?: StatusCallback;
8
7
  }): Promise<import("@jbrowse/core/util").Feature[]>;
@@ -94,7 +94,7 @@ export function useSideScroll(model) {
94
94
  }
95
95
  // skip the click-drag pan when pressing an interactive control: a
96
96
  // draggable element, a control that claimed the press (resize handles, the
97
- // scalebar), or a button (e.g. the menu button on a highlight/bookmark
97
+ // scalebar), or a button (e.g. the menu button on a highlight
98
98
  // chip, whose actual target is the icon inside it). All three are matched
99
99
  // with `closest`, since the press usually lands on a child of the control
100
100
  // rather than the control itself.
@@ -4,6 +4,8 @@ export declare const HEADER_BAR_HEIGHT = 48;
4
4
  export declare const HEADER_OVERVIEW_HEIGHT = 20;
5
5
  export declare const SCALE_BAR_HEIGHT = 17;
6
6
  export declare const SVG_SCALEBAR_CAP = 5;
7
+ export declare const CLOSE_UP_CONNECTOR_HEIGHT = 64;
8
+ export declare const MIN_CLOSE_UP_CONNECTOR_HEIGHT = 4;
7
9
  export declare const RESIZE_HANDLE_HEIGHT = 4;
8
10
  export declare const TRACK_TOP_GAP = 2;
9
11
  export declare const TRACK_OUTLINE_BORDER = 1;
@@ -9,6 +9,11 @@ export const SCALE_BAR_HEIGHT = 17;
9
9
  // Half-height of the total-bp scalebar's end caps in the SVG export; also the
10
10
  // clearance the bar needs below the assembly label.
11
11
  export const SVG_SCALEBAR_CAP = 5;
12
+ // Height of the band a close-up's trapezoid is drawn in: the default the host's
13
+ // property starts at, and the floor a drag on the band stops at, since the band
14
+ // is its own drag handle.
15
+ export const CLOSE_UP_CONNECTOR_HEIGHT = 64;
16
+ export const MIN_CLOSE_UP_CONNECTOR_HEIGHT = 4;
12
17
  // The three pieces of chrome TrackContainer puts around a track's rendering
13
18
  // container. The model sums them to place a track without measuring the DOM, so
14
19
  // TrackContainer lays its Paper out from these same three and nothing else —
@@ -19,9 +19,10 @@ export type HeaderFit = Record<(typeof SHEDDABLE)[number][0], boolean>;
19
19
  * not a cliff: it shrinks from what it asked for rather than from the 101px the
20
20
  * unshed row used to leave it.
21
21
  */
22
- export declare function headerFit({ width, searchBoxPx, clearHighlight, }: {
22
+ export declare function headerFit({ width, searchBoxPx, clearHighlight, viewMenu, }: {
23
23
  width: number | undefined;
24
24
  searchBoxPx: number;
25
25
  clearHighlight?: boolean;
26
+ viewMenu?: boolean;
26
27
  }): HeaderFit;
27
28
  export {};
@@ -10,6 +10,9 @@ const ROW_WITHOUT_SEARCH_PX = 591;
10
10
  // box this whole table exists to protect — so its width is taken off the top
11
11
  // rather than left for the search box to absorb.
12
12
  const CLEAR_HIGHLIGHT_PX = 35;
13
+ // An embedded view has no title bar, so its menu button leads this row: a
14
+ // 40px icon button and its flex gap.
15
+ const VIEW_MENU_PX = 44;
13
16
  // What the header gives up as its window narrows, cheapest first, with the
14
17
  // pixels each one frees. Whitespace goes before words, words before a redundant
15
18
  // control, and that before a readout. The search box is not on the list: it is
@@ -41,12 +44,14 @@ const SHEDDABLE = [
41
44
  * not a cliff: it shrinks from what it asked for rather than from the 101px the
42
45
  * unshed row used to leave it.
43
46
  */
44
- export function headerFit({ width, searchBoxPx, clearHighlight = false, }) {
47
+ export function headerFit({ width, searchBoxPx, clearHighlight = false, viewMenu = false, }) {
45
48
  const fit = Object.fromEntries(SHEDDABLE.map(([k]) => [k, true]));
46
49
  if (width === undefined) {
47
50
  return fit;
48
51
  }
49
- const room = width - (clearHighlight ? CLEAR_HIGHLIGHT_PX : 0);
52
+ const room = width -
53
+ (clearHighlight ? CLEAR_HIGHLIGHT_PX : 0) -
54
+ (viewMenu ? VIEW_MENU_PX : 0);
50
55
  let need = ROW_WITHOUT_SEARCH_PX + searchBoxPx;
51
56
  for (const [key, saves] of SHEDDABLE) {
52
57
  if (need <= room) {
@@ -27,7 +27,7 @@ export default function LinearGenomeViewF(pluginManager: PluginManager): void;
27
27
  export { stateModelFactory } from './model.ts';
28
28
  export { lgvLaunchKeys } from './launchKeys.ts';
29
29
  export type { LinearGenomeViewModel, LinearGenomeViewStateModel, } from './model.ts';
30
- export type { BpOffset, ExportSvgOptions, HighlightType, InitState, LinearGenomeViewLaunchProps, NavLocation, TrackLabelMode, VolatileGuide, } from './types.ts';
30
+ export type { BpOffset, ExportSvgOptions, HighlightInput, HighlightType, InitState, LinearGenomeViewLaunchProps, NavLocation, TrackLabelMode, ViewTrackLabelMode, VolatileGuide, } from './types.ts';
31
31
  export { type SyncableViewAction, installLinkedViewSync, } from './linkedViewSync.ts';
32
32
  export { default as HighlightBand } from './components/HighlightBand.tsx';
33
33
  export { default as HighlightChip } from './components/HighlightChip.tsx';
@@ -5,5 +5,7 @@ import type { LinearGenomeViewModel } from './model.ts';
5
5
  * - Ctrl/Cmd + ArrowRight: slide right
6
6
  * - Ctrl/Cmd + ArrowUp: zoom in
7
7
  * - Ctrl/Cmd + ArrowDown: zoom out
8
+ * - Ctrl/Cmd + Shift + D: highlight the region in view
9
+ * - Ctrl/Cmd + Shift + M: go to the newest highlight
8
10
  */
9
11
  export declare function setupKeyboardHandler(self: LinearGenomeViewModel): void;
@@ -6,6 +6,8 @@ import { addDisposer } from '@jbrowse/mobx-state-tree';
6
6
  * - Ctrl/Cmd + ArrowRight: slide right
7
7
  * - Ctrl/Cmd + ArrowUp: zoom in
8
8
  * - Ctrl/Cmd + ArrowDown: zoom out
9
+ * - Ctrl/Cmd + Shift + D: highlight the region in view
10
+ * - Ctrl/Cmd + Shift + M: go to the newest highlight
9
11
  */
10
12
  export function setupKeyboardHandler(self) {
11
13
  if (typeof document === 'undefined') {
@@ -30,6 +32,15 @@ export function setupKeyboardHandler(self) {
30
32
  e.preventDefault();
31
33
  self.zoom(self.bpPerPx * 2);
32
34
  }
35
+ else if (e.shiftKey && e.code === 'KeyD') {
36
+ e.preventDefault();
37
+ self.highlightCurrentRegion();
38
+ session.notify('Region highlighted.', 'success');
39
+ }
40
+ else if (e.shiftKey && e.code === 'KeyM') {
41
+ e.preventDefault();
42
+ void self.navigateNewestHighlight();
43
+ }
33
44
  }
34
45
  }
35
46
  document.addEventListener('keydown', handler);
@@ -1,2 +1,2 @@
1
1
  import type { InitState } from './types.ts';
2
- export declare const lgvLaunchKeys: import("@jbrowse/core/util/withLaunchInput").LaunchKeyRegistration<InitState, "bpPerPx" | "offsetPx">;
2
+ export declare const lgvLaunchKeys: import("@jbrowse/core/util/withLaunchInput").LaunchKeyRegistration<InitState, "bpPerPx" | "cytobandsVisible" | "offsetPx" | "showCytobandsSetting">;
@@ -4,9 +4,11 @@ import { defineLaunchKeys } from '@jbrowse/core/util/withLaunchInput';
4
4
  // key that partitions as a typo.
5
5
  //
6
6
  // `bpPerPx`/`offsetPx` are the viewport spelling from before it was stored as a
7
- // window. They are no longer declared properties, so the partition would read
8
- // them as typos; the model's own preProcessSnapshot still converts them, so a
9
- // URL or saved spec naming them goes on working. Deletable with `legacyBpPerPx`.
7
+ // window, and `showCytobandsSetting`/`cytobandsVisible` the two the cytoband
8
+ // toggle had before `showCytobands`. None is a declared property, so the
9
+ // partition would read them as typos; the model's own preProcessSnapshot still
10
+ // converts them, so a URL or saved spec naming them goes on working. The
11
+ // viewport pair is deletable with `legacyBpPerPx`.
10
12
  //
11
13
  // #launchKeys LinearGenomeView — the URL parameters page renders this list
12
14
  // rather than restating it; each of these keys has its own `&param=` section
@@ -14,10 +16,18 @@ import { defineLaunchKeys } from '@jbrowse/core/util/withLaunchInput';
14
16
  export const lgvLaunchKeys = defineLaunchKeys()({
15
17
  loc: { kind: 'launch' },
16
18
  grow: { kind: 'launch' },
19
+ showHitTrack: { kind: 'launch' },
17
20
  assembly: { kind: 'launch' },
18
21
  displayedRegionNames: { kind: 'launch' },
19
22
  tracklist: { kind: 'launch' },
20
23
  nav: { kind: 'launch' },
21
24
  tracks: { kind: 'trackEntries' },
22
- highlight: { kind: 'highlightEntries' },
23
- }, { passThrough: ['bpPerPx', 'offsetPx'] });
25
+ highlight: { kind: 'launch' },
26
+ }, {
27
+ passThrough: [
28
+ 'bpPerPx',
29
+ 'offsetPx',
30
+ 'showCytobandsSetting',
31
+ 'cytobandsVisible',
32
+ ],
33
+ });
@@ -17,3 +17,10 @@ export declare const GetSequenceDialog: import("react").LazyExoticComponent<({ m
17
17
  regions: import("@jbrowse/core/util").Region[];
18
18
  handleClose: () => void;
19
19
  }) => import("react").JSX.Element>;
20
+ export declare const RegionWidthEditorDialog: import("react").LazyExoticComponent<typeof import("./components/RegionWidthEditorDialog.tsx").default>;
21
+ export declare const AddCloseUpDialog: import("react").LazyExoticComponent<({ model, leftOffset, rightOffset, handleClose, }: {
22
+ model: import("./model.ts").LinearGenomeViewModel;
23
+ leftOffset?: import("./types.ts").BpOffset;
24
+ rightOffset?: import("./types.ts").BpOffset;
25
+ handleClose: () => void;
26
+ }) => import("react").JSX.Element>;
@@ -3,3 +3,5 @@ export const ReturnToImportFormDialog = lazy(() => import('@jbrowse/core/ui/Retu
3
3
  export const SequenceSearchDialog = lazy(() => import('./components/SequenceSearchDialog.js'));
4
4
  export const ExportSvgDialog = lazy(() => import('./components/ExportSvgDialog.js'));
5
5
  export const GetSequenceDialog = lazy(() => import('./components/GetSequenceDialog.js'));
6
+ export const RegionWidthEditorDialog = lazy(() => import('./components/RegionWidthEditorDialog.js'));
7
+ export const AddCloseUpDialog = lazy(() => import('./components/AddCloseUpDialog.js'));
@@ -2,28 +2,40 @@ import type { LinearGenomeViewModel } from './model.ts';
2
2
  import type { BpOffset } from './types.ts';
3
3
  import type { MenuItem } from '@jbrowse/core/ui';
4
4
  /**
5
- * Zoom all the way out, shared by the view menu and the header's zoom menu —
6
- * one definition so the two cannot drift in label, and the view menu is the
5
+ * The zoom ladder, shared by the header's zoom button and the view menu's
6
+ * "Zoom" — one definition so the two cannot drift, and the view menu is the
7
7
  * only one of the two that survives `hideHeader`.
8
- *
9
- * The zoom menu earns it on the merits: this is the bottom of the same "Zoom
10
- * out 100x" ladder, and it is where someone already zooming looks.
11
- *
12
- * The label is the import form's button text verbatim (`ImportForm.tsx`), which
13
- * is where most people meet the phrase. No icon: the four-arrows glyph it
14
- * carried reads as "fullscreen", and nothing else names the same gesture, so a
15
- * substitute would be decoration rather than a distinction.
16
8
  */
17
- export declare function showAllRegionsMenuItem(self: LinearGenomeViewModel): MenuItem;
9
+ export declare function zoomMenuItems(self: LinearGenomeViewModel): MenuItem[];
18
10
  /**
19
- * Build the main view menu items
11
+ * Build the main view menu items. A row stacked in another view has no import
12
+ * form of its own, so only a top-level view offers the way back to one.
13
+ *
14
+ * Four actions, a Zoom group and a Show group. The four are what people open
15
+ * this menu to do — pick tracks, take a picture, search the sequence, start
16
+ * over — and the once-a-session settings that used to sit beside them are a
17
+ * popup away instead of in front of every reader every time.
20
18
  */
21
19
  export declare function buildMenuItems(self: LinearGenomeViewModel): MenuItem[];
22
20
  /**
23
- * Build rubberband selection menu items. `launchItems` are the plugin-supplied
24
- * things a selection can start (`rubberBandLaunchMenuItems()`); they collect
25
- * under one "Launch" submenu so the menu stays three actions plus a group
26
- * however many plugins are loaded, and vanish entirely when none apply.
21
+ * Build rubberband selection menu items. What a selection can open collects
22
+ * under one "Launch" submenu, which sorts last, below any row a plugin appends
23
+ * to the menu itself: a close-up view first, then `launchItems`, the
24
+ * plugin-supplied ones (`rubberBandLaunchMenuItems()`).
25
+ *
26
+ * A close-up is offered from HERE and nowhere else, because a drag is what the
27
+ * feature was always asking for and a menu item could not: the close-up shows
28
+ * one span of one place, and this is the gesture that names both. From the view
29
+ * menu it could only guess — a tenth of the middle, which is a span nobody
30
+ * picked.
31
+ *
32
+ * Only a view of its own offers it, which `isTopLevelView` is the whole of. A
33
+ * row of a comparative stack is already part of somebody's figure: the synteny
34
+ * ribbons and the breakpoint split panels are placed against each row's own
35
+ * height, and those views' exports draw one row per view, so a close-up grown
36
+ * there walks the ribbons off their rows and is dropped from the picture
37
+ * without a word. A close-up, living under a view rather than under the
38
+ * session, is not a top-level view either.
27
39
  */
28
40
  export declare function buildRubberBandMenuItems(self: LinearGenomeViewModel, launchItems: MenuItem[]): MenuItem[];
29
41
  /**