@jbrowse/plugin-linear-genome-view 5.0.0-beta.13 → 5.0.0-beta.16

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 (63) hide show
  1. package/esm/FeatureTrack/configSchema.d.ts +2 -1
  2. package/esm/FeatureTrack/configSchema.js +2 -1
  3. package/esm/LinearGenomeView/afterAttach.js +1 -23
  4. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +6 -2
  5. package/esm/LinearGenomeView/components/ExportSvgDialog.js +31 -7
  6. package/esm/LinearGenomeView/components/HeaderPanControls.d.ts +3 -3
  7. package/esm/LinearGenomeView/components/HeaderPanControls.js +4 -2
  8. package/esm/LinearGenomeView/components/HighlightBand.d.ts +3 -2
  9. package/esm/LinearGenomeView/components/HighlightBand.js +4 -2
  10. package/esm/LinearGenomeView/components/HighlightChip.d.ts +3 -2
  11. package/esm/LinearGenomeView/components/HighlightChip.js +4 -2
  12. package/esm/LinearGenomeView/components/LinearGenomeView.js +5 -12
  13. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +4 -5
  14. package/esm/LinearGenomeView/components/OverviewHighlightBand.d.ts +3 -2
  15. package/esm/LinearGenomeView/components/OverviewHighlightBand.js +4 -2
  16. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.d.ts +3 -2
  17. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +4 -4
  18. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +4 -4
  19. package/esm/LinearGenomeView/components/SearchPanelForm.d.ts +3 -2
  20. package/esm/LinearGenomeView/components/SearchPanelForm.js +4 -2
  21. package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +4 -9
  22. package/esm/LinearGenomeView/components/SearchResultsDialog.js +7 -4
  23. package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +3 -8
  24. package/esm/LinearGenomeView/components/SearchResultsTable.js +4 -32
  25. package/esm/LinearGenomeView/components/StrandCheckboxes.d.ts +3 -2
  26. package/esm/LinearGenomeView/components/StrandCheckboxes.js +4 -2
  27. package/esm/LinearGenomeView/components/TrackContainer.js +1 -1
  28. package/esm/LinearGenomeView/components/TrackLabelMenu.js +8 -12
  29. package/esm/LinearGenomeView/components/useRangeSelect.js +3 -2
  30. package/esm/LinearGenomeView/components/useSearchBoxPrefs.d.ts +3 -1
  31. package/esm/LinearGenomeView/components/useSearchBoxPrefs.js +4 -2
  32. package/esm/LinearGenomeView/components/useSideScroll.js +11 -12
  33. package/esm/LinearGenomeView/lazyDialogs.d.ts +17 -2
  34. package/esm/LinearGenomeView/menuItems.js +32 -24
  35. package/esm/LinearGenomeView/model.d.ts +197 -151
  36. package/esm/LinearGenomeView/model.js +203 -201
  37. package/esm/LinearGenomeView/rExport/exportLinearView.d.ts +13 -0
  38. package/esm/LinearGenomeView/rExport/exportLinearView.js +98 -0
  39. package/esm/LinearGenomeView/rExport/rScript.d.ts +75 -0
  40. package/esm/LinearGenomeView/rExport/rScript.js +465 -0
  41. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +3 -6
  42. package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.d.ts +1 -2
  43. package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.js +2 -2
  44. package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +1 -2
  45. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +4 -4
  46. package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +1 -2
  47. package/esm/LinearGenomeView/svgcomponents/SVGView.js +3 -3
  48. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +22 -20
  49. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +42 -29
  50. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +6 -11
  51. package/esm/LinearGenomeView/svgcomponents/util.d.ts +2 -1
  52. package/esm/LinearGenomeView/util.d.ts +42 -0
  53. package/esm/LinearGenomeView/util.js +81 -0
  54. package/esm/MultiLevelRubberband/MultiLevelRubberband.js +2 -2
  55. package/esm/displayKitTests/perRegionTestEnv.d.ts +45 -12
  56. package/esm/index.d.ts +4 -2
  57. package/esm/index.js +3 -1
  58. package/esm/searchUtils.js +1 -0
  59. package/esm/shared/RubberbandSpan.d.ts +3 -2
  60. package/esm/shared/RubberbandSpan.js +4 -2
  61. package/esm/shared/coordLabels.d.ts +6 -6
  62. package/esm/shared/coordLabels.js +7 -6
  63. package/package.json +9 -9
@@ -1,5 +1,6 @@
1
1
  import { useCallback, useState } from 'react';
2
2
  import { getRelativeX } from '@jbrowse/core/util/getRelativeX';
3
+ import { isFromPortal } from '@jbrowse/core/util/pressOwner';
3
4
  import { useWindowDrag } from '../../shared/useWindowDrag.js';
4
5
  import { isOnScalebarRefLabel } from './util.js';
5
6
  export function useRangeSelect(ref, model, shiftOnly) {
@@ -44,7 +45,7 @@ export function useRangeSelect(ref, model, shiftOnly) {
44
45
  },
45
46
  });
46
47
  function mouseDown(event) {
47
- if (shiftOnly && !event.shiftKey) {
48
+ if (isFromPortal(event) || (shiftOnly && !event.shiftKey)) {
48
49
  return;
49
50
  }
50
51
  // a press with the refName menu already open reopens it on the label under
@@ -65,7 +66,7 @@ export function useRangeSelect(ref, model, shiftOnly) {
65
66
  }
66
67
  function mouseMove(event) {
67
68
  // Keep the rubberband visible while a drag-selection menu is open
68
- if (anchorPosition?.isClick === false) {
69
+ if (anchorPosition?.isClick === false || isFromPortal(event)) {
69
70
  return;
70
71
  }
71
72
  const wantsGuide = !mouseDragging && (!shiftOnly || event.shiftKey);
@@ -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: 'Show search boxes',
31
+ label: toggleLabel,
30
32
  type: 'checkbox',
31
33
  checked: showSearchBoxes,
32
34
  onClick: () => {
@@ -1,4 +1,5 @@
1
1
  import { useEffect, useRef } from 'react';
2
+ import { isClaimedPress } from '@jbrowse/core/util/pressOwner';
2
3
  import { transaction } from 'mobx';
3
4
  // A press that travels further than this is a pan, and the click that ends it
4
5
  // is not a click. A hand that wobbles two pixels can still select something.
@@ -13,9 +14,6 @@ const PAN_CLICK_THRESHOLD_PX = 4;
13
14
  // before any track sees it.
14
15
  const PAN_DRAGGING_ATTR = 'data-pan-dragging';
15
16
  const PAN_MOVED_ATTR = 'data-pan-moved';
16
- function preventDefault(event) {
17
- event.preventDefault();
18
- }
19
17
  function pointOf(event) {
20
18
  return { x: event.clientX, y: event.clientY };
21
19
  }
@@ -51,13 +49,7 @@ export function useSideScroll(model) {
51
49
  if (event.shiftKey || event.button !== 0 || !event.isPrimary) {
52
50
  return;
53
51
  }
54
- // a draggable element, a control that claimed the press (resize handles,
55
- // the scalebar, a legend), or a button: `closest`, since the press usually
56
- // lands on a child of the control
57
- const target = event.target;
58
- if (target.draggable ||
59
- target.closest('[data-gesture-owner]') ||
60
- target.closest('button')) {
52
+ if (isClaimedPress(event)) {
61
53
  return;
62
54
  }
63
55
  const left = host.getBoundingClientRect().left;
@@ -66,6 +58,13 @@ export function useSideScroll(model) {
66
58
  const pointers = new Map([[event.pointerId, pointOf(event)]]);
67
59
  let applied = new Map(pointers);
68
60
  let frame;
61
+ // only a selection that starts in the tracks, so a press that leaks here
62
+ // cannot block selection in the rest of the app
63
+ function blockSelection(e) {
64
+ if (e.target instanceof Node && host.contains(e.target)) {
65
+ e.preventDefault();
66
+ }
67
+ }
69
68
  function flush() {
70
69
  frame = undefined;
71
70
  const [a, b] = [...pointers.keys()];
@@ -124,7 +123,7 @@ export function useSideScroll(model) {
124
123
  window.removeEventListener('pointermove', move, true);
125
124
  window.removeEventListener('pointerup', release, true);
126
125
  window.removeEventListener('pointercancel', release, true);
127
- window.removeEventListener('selectstart', preventDefault, true);
126
+ window.removeEventListener('selectstart', blockSelection, true);
128
127
  gestureRef.current = undefined;
129
128
  }
130
129
  // pointercancel as well as pointerup: the browser cancels a touch it takes
@@ -146,7 +145,7 @@ export function useSideScroll(model) {
146
145
  window.addEventListener('pointermove', move, true);
147
146
  window.addEventListener('pointerup', release, true);
148
147
  window.addEventListener('pointercancel', release, true);
149
- window.addEventListener('selectstart', preventDefault, true);
148
+ window.addEventListener('selectstart', blockSelection, true);
150
149
  gestureRef.current = {
151
150
  join(e) {
152
151
  if (e.pointerType !== 'touch' || pointers.size > 1) {
@@ -8,10 +8,25 @@ export declare const SequenceSearchDialog: import("react").LazyExoticComponent<(
8
8
  model: import("./components/searchModes.ts").SequenceSearchModel;
9
9
  handleClose: () => void;
10
10
  }) => import("react").JSX.Element>;
11
- export declare const ExportSvgDialog: import("react").LazyExoticComponent<typeof import("./components/ExportSvgDialog.tsx").default>;
11
+ export declare const ExportSvgDialog: import("react").LazyExoticComponent<({ model, handleClose, chooseWidth, }: {
12
+ model: {
13
+ width?: number;
14
+ effectiveTrackLabels?: import("@jbrowse/display-kit/types").ViewTrackLabelMode;
15
+ exportSvg(opts: import("@jbrowse/core/ui").BaseExportSvgOptions & {
16
+ trackLabels: import("@jbrowse/display-kit/types").TrackLabelMode;
17
+ showGridlines: boolean;
18
+ viewWidth?: number;
19
+ }): Promise<unknown>;
20
+ };
21
+ handleClose: () => void;
22
+ chooseWidth?: boolean;
23
+ }) => import("react").JSX.Element>;
12
24
  export declare const GetSequenceDialog: import("react").LazyExoticComponent<({ model, regions, handleClose, }: {
13
25
  model: import("@jbrowse/mobx-state-tree").IAnyStateTreeNode;
14
26
  regions: import("@jbrowse/core/util").Region[];
15
27
  handleClose: () => void;
16
28
  }) => import("react").JSX.Element>;
17
- export declare const RegionWidthEditorDialog: import("react").LazyExoticComponent<typeof import("./components/RegionWidthEditorDialog.tsx").default>;
29
+ export declare const RegionWidthEditorDialog: import("react").LazyExoticComponent<({ model, handleClose, }: {
30
+ model: import("./model.ts").LinearGenomeViewModel;
31
+ handleClose: () => void;
32
+ }) => import("react").JSX.Element>;
@@ -1,5 +1,5 @@
1
1
  import { Highlighter, TrackSelector as TrackSelectorIcon, } from '@jbrowse/core/ui/Icons';
2
- import { radioItems } from '@jbrowse/core/ui/menuItems';
2
+ import { radioItems, subMenuIfAny } from '@jbrowse/core/ui/menuItems';
3
3
  import { makeShowSubMenu } from '@jbrowse/core/ui/showSubMenu';
4
4
  import { assembleLocStrings, getDialogHost, getSession, isSessionWithAddSessionTrack, toLocale, } from '@jbrowse/core/util';
5
5
  import { basePaintedAt, computeMoveToLayout, } from '@jbrowse/core/util/Base1DUtils';
@@ -7,6 +7,7 @@ import { copyText } from '@jbrowse/core/util/copyText';
7
7
  import { renameIds } from '@jbrowse/core/util/types/mst';
8
8
  import { getSnapshot } from '@jbrowse/mobx-state-tree';
9
9
  import CenterFocusStrongIcon from '@mui/icons-material/CenterFocusStrong';
10
+ import CodeIcon from '@mui/icons-material/Code';
10
11
  import ContentCopyIcon from '@mui/icons-material/ContentCopy';
11
12
  import FitScreenIcon from '@mui/icons-material/FitScreen';
12
13
  import FolderOpenIcon from '@mui/icons-material/FolderOpen';
@@ -97,7 +98,7 @@ export function buildMenuItems(self) {
97
98
  icon: TrackSelectorIcon,
98
99
  },
99
100
  {
100
- label: 'Export SVG',
101
+ label: 'Export SVG...',
101
102
  icon: PhotoCameraIcon,
102
103
  onClick: () => {
103
104
  session.queueDialog(handleClose => [
@@ -105,10 +106,22 @@ export function buildMenuItems(self) {
105
106
  {
106
107
  model: self,
107
108
  handleClose,
109
+ chooseWidth: true,
108
110
  },
109
111
  ]);
110
112
  },
111
113
  },
114
+ {
115
+ label: 'Export R script',
116
+ icon: CodeIcon,
117
+ onClick: () => {
118
+ import('./rExport/exportLinearView.js')
119
+ .then(({ downloadRScript }) => downloadRScript(self))
120
+ .catch((e) => {
121
+ session.notifyError(`${e}`, e);
122
+ });
123
+ },
124
+ },
112
125
  ...(isSessionWithAddSessionTrack(session)
113
126
  ? [
114
127
  {
@@ -165,7 +178,7 @@ export function buildMenuItems(self) {
165
178
  ...makeShowSubMenu([
166
179
  showAllRegionsMenuItem(self),
167
180
  {
168
- label: 'Show ruler only',
181
+ label: 'Ruler only',
169
182
  type: 'checkbox',
170
183
  checked: self.scalebarOnly,
171
184
  onClick: () => {
@@ -173,7 +186,7 @@ export function buildMenuItems(self) {
173
186
  },
174
187
  },
175
188
  {
176
- label: 'Show header',
189
+ label: 'Header',
177
190
  type: 'checkbox',
178
191
  checked: !self.hideHeader,
179
192
  // opts out of the checkbox "stay open" default: with the header
@@ -185,7 +198,7 @@ export function buildMenuItems(self) {
185
198
  },
186
199
  },
187
200
  {
188
- label: 'Show header overview',
201
+ label: 'Header overview',
189
202
  type: 'checkbox',
190
203
  checked: !self.hideHeaderOverview,
191
204
  onClick: () => {
@@ -196,7 +209,7 @@ export function buildMenuItems(self) {
196
209
  ...(self.canShowCytobands
197
210
  ? [
198
211
  {
199
- label: 'Show ideogram',
212
+ label: 'Ideogram',
200
213
  type: 'checkbox',
201
214
  checked: self.showCytobands,
202
215
  onClick: () => {
@@ -206,7 +219,7 @@ export function buildMenuItems(self) {
206
219
  ]
207
220
  : []),
208
221
  {
209
- label: 'Show center line',
222
+ label: 'Center line',
210
223
  type: 'checkbox',
211
224
  checked: self.showCenterLine,
212
225
  onClick: () => {
@@ -214,7 +227,7 @@ export function buildMenuItems(self) {
214
227
  },
215
228
  },
216
229
  {
217
- label: 'Show guidelines',
230
+ label: 'Guidelines',
218
231
  type: 'checkbox',
219
232
  checked: self.showGridlines,
220
233
  onClick: () => {
@@ -222,7 +235,7 @@ export function buildMenuItems(self) {
222
235
  },
223
236
  },
224
237
  {
225
- label: 'Show track outlines',
238
+ label: 'Track outlines',
226
239
  type: 'checkbox',
227
240
  checked: self.showTrackOutlines,
228
241
  onClick: () => {
@@ -230,7 +243,7 @@ export function buildMenuItems(self) {
230
243
  },
231
244
  },
232
245
  {
233
- label: 'Show no tracks active button',
246
+ label: 'No tracks active button',
234
247
  type: 'checkbox',
235
248
  checked: !self.hideNoTracksActive,
236
249
  onClick: () => {
@@ -239,7 +252,7 @@ export function buildMenuItems(self) {
239
252
  },
240
253
  { type: 'subHeader', label: 'Sequence' },
241
254
  {
242
- label: 'Show CDS reading frame colors',
255
+ label: 'CDS reading frame colors',
243
256
  type: 'checkbox',
244
257
  checked: self.colorByCDS,
245
258
  onClick: () => {
@@ -247,7 +260,7 @@ export function buildMenuItems(self) {
247
260
  },
248
261
  },
249
262
  {
250
- label: 'Show amino acids when zoomed in',
263
+ label: 'Amino acids when zoomed in',
251
264
  type: 'checkbox',
252
265
  checked: self.showAminoAcids,
253
266
  onClick: () => {
@@ -331,7 +344,7 @@ export function buildRubberBandMenuItems(self, launchItems) {
331
344
  },
332
345
  },
333
346
  {
334
- label: 'Get sequence',
347
+ label: 'Get sequence...',
335
348
  icon: MenuOpenIcon,
336
349
  onClick: () => {
337
350
  const regions = self.getSelectedRegions(leftOffset, rightOffset);
@@ -365,17 +378,12 @@ export function buildRubberBandMenuItems(self, launchItems) {
365
378
  }
366
379
  },
367
380
  },
368
- ...(launch.length
369
- ? [
370
- {
371
- label: 'Launch',
372
- icon: LaunchIcon,
373
- type: 'subMenu',
374
- priority: -1000,
375
- subMenu: launch,
376
- },
377
- ]
378
- : []),
381
+ ...subMenuIfAny({
382
+ label: 'Launch',
383
+ icon: LaunchIcon,
384
+ priority: -1000,
385
+ subMenu: launch,
386
+ }),
379
387
  ];
380
388
  }
381
389
  /**