@jbrowse/plugin-linear-genome-view 1.7.9 → 1.7.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.
Files changed (32) hide show
  1. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +1 -5
  2. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js +32 -120
  3. package/dist/BaseLinearDisplay/components/Tooltip.d.ts +8 -0
  4. package/dist/BaseLinearDisplay/components/Tooltip.js +125 -0
  5. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +3 -2
  6. package/dist/LinearGenomeView/components/Header.js +5 -2
  7. package/dist/LinearGenomeView/components/HelpDialog.js +2 -3
  8. package/dist/LinearGenomeView/components/LinearGenomeView.js +6 -2
  9. package/dist/LinearGenomeView/components/LinearGenomeView.test.js +2 -2
  10. package/dist/LinearGenomeView/components/OverviewScaleBar.js +2 -2
  11. package/dist/LinearGenomeView/components/ScaleBar.d.ts +6 -2
  12. package/dist/LinearGenomeView/components/ScaleBar.js +8 -3
  13. package/dist/LinearGenomeView/components/TrackLabel.js +25 -41
  14. package/dist/LinearGenomeView/index.d.ts +3 -8
  15. package/dist/LinearGenomeView/index.js +59 -32
  16. package/dist/LinearGenomeView/index.test.js +22 -5
  17. package/dist/index.js +22 -11
  18. package/package.json +3 -2
  19. package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +4 -89
  20. package/src/BaseLinearDisplay/components/Tooltip.tsx +97 -0
  21. package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +10 -4
  22. package/src/LinearGenomeView/components/Header.tsx +3 -2
  23. package/src/LinearGenomeView/components/HelpDialog.tsx +5 -4
  24. package/src/LinearGenomeView/components/LinearGenomeView.test.js +2 -2
  25. package/src/LinearGenomeView/components/LinearGenomeView.tsx +16 -10
  26. package/src/LinearGenomeView/components/OverviewScaleBar.tsx +3 -4
  27. package/src/LinearGenomeView/components/ScaleBar.tsx +6 -9
  28. package/src/LinearGenomeView/components/TrackLabel.tsx +25 -28
  29. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.js.snap +4 -21
  30. package/src/LinearGenomeView/index.test.ts +20 -5
  31. package/src/LinearGenomeView/index.tsx +54 -26
  32. package/src/index.ts +35 -30
@@ -7,30 +7,32 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.default = void 0;
9
9
 
10
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
11
 
12
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
12
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
13
 
14
14
  var _react = _interopRequireDefault(require("react"));
15
15
 
16
16
  var _configuration = require("@jbrowse/core/configuration");
17
17
 
18
- var _ui = require("@jbrowse/core/ui");
18
+ var _CascadingMenu = _interopRequireDefault(require("@jbrowse/core/ui/CascadingMenu"));
19
19
 
20
20
  var _util = require("@jbrowse/core/util");
21
21
 
22
22
  var _core = require("@material-ui/core");
23
23
 
24
+ var _hooks = require("material-ui-popup-state/hooks");
25
+
26
+ var _clsx = _interopRequireDefault(require("clsx"));
27
+
28
+ var _mobxReact = require("mobx-react");
29
+
24
30
  var _MoreVert = _interopRequireDefault(require("@material-ui/icons/MoreVert"));
25
31
 
26
32
  var _DragIndicator = _interopRequireDefault(require("@material-ui/icons/DragIndicator"));
27
33
 
28
34
  var _Close = _interopRequireDefault(require("@material-ui/icons/Close"));
29
35
 
30
- var _clsx = _interopRequireDefault(require("clsx"));
31
-
32
- var _mobxReact = require("mobx-react");
33
-
34
36
  // icons
35
37
  var useStyles = (0, _core.makeStyles)(function (theme) {
36
38
  return {
@@ -64,30 +66,20 @@ var useStyles = (0, _core.makeStyles)(function (theme) {
64
66
  };
65
67
  });
66
68
 
67
- var TrackLabel = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
69
+ var TrackLabel = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref) {
68
70
  var _session$getTrackActi;
69
71
 
72
+ var track = _ref.track,
73
+ className = _ref.className;
70
74
  var classes = useStyles();
71
-
72
- var _React$useState = _react.default.useState(null),
73
- _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
74
- anchorEl = _React$useState2[0],
75
- setAnchorEl = _React$useState2[1];
76
-
77
- var track = props.track,
78
- className = props.className;
79
75
  var view = (0, _util.getContainingView)(track);
80
76
  var session = (0, _util.getSession)(track);
81
77
  var trackConf = track.configuration;
82
78
  var trackId = (0, _configuration.getConf)(track, 'trackId');
83
-
84
- var handleClick = function handleClick(event) {
85
- setAnchorEl(event.currentTarget);
86
- };
87
-
88
- var handleClose = function handleClose() {
89
- setAnchorEl(null);
90
- };
79
+ var popupState = (0, _hooks.usePopupState)({
80
+ popupId: 'trackLabelMenu',
81
+ variant: 'popover'
82
+ });
91
83
 
92
84
  var onDragStart = function onDragStart(event) {
93
85
  var target = event.target;
@@ -108,12 +100,7 @@ var TrackLabel = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
108
100
  var r = session.assemblies.find(function (a) {
109
101
  return a.sequence === trackConf;
110
102
  });
111
- trackName = (0, _configuration.readConfObject)(trackConf, 'name') || (r ? "Reference Sequence (".concat((0, _configuration.readConfObject)(r, 'name'), ")") : 'Reference Sequence');
112
- }
113
-
114
- function handleMenuItemClick(_, callback) {
115
- callback();
116
- handleClose();
103
+ trackName = trackName || (r ? "Reference Sequence (".concat((0, _configuration.readConfObject)(r, 'name'), ")") : 'Reference Sequence');
117
104
  }
118
105
 
119
106
  var items = [].concat((0, _toConsumableArray2.default)(((_session$getTrackActi = session.getTrackActionMenuItems) === null || _session$getTrackActi === void 0 ? void 0 : _session$getTrackActi.call(session, trackConf)) || []), (0, _toConsumableArray2.default)(track.trackMenuItems())).sort(function (a, b) {
@@ -141,21 +128,18 @@ var TrackLabel = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
141
128
  variant: "body1",
142
129
  component: "span",
143
130
  className: classes.trackName
144
- }, trackName), /*#__PURE__*/_react.default.createElement(_core.IconButton, {
145
- "aria-controls": "simple-menu",
146
- "aria-haspopup": "true",
147
- onClick: handleClick,
131
+ }, trackName), /*#__PURE__*/_react.default.createElement(_core.IconButton, (0, _extends2.default)({}, (0, _hooks.bindTrigger)(popupState), {
148
132
  className: classes.iconButton,
149
133
  color: "secondary",
150
134
  "data-testid": "track_menu_icon",
151
135
  disabled: !items.length
152
- }, /*#__PURE__*/_react.default.createElement(_MoreVert.default, null))), /*#__PURE__*/_react.default.createElement(_ui.Menu, {
153
- anchorEl: anchorEl,
154
- onMenuItemClick: handleMenuItemClick,
155
- open: Boolean(anchorEl),
156
- onClose: handleClose,
157
- menuItems: items
158
- }));
136
+ }), /*#__PURE__*/_react.default.createElement(_MoreVert.default, null))), /*#__PURE__*/_react.default.createElement(_CascadingMenu.default, (0, _extends2.default)({}, (0, _hooks.bindPopover)(popupState), {
137
+ onMenuItemClick: function onMenuItemClick(_, callback) {
138
+ return callback();
139
+ },
140
+ menuItems: items,
141
+ popupState: popupState
142
+ })));
159
143
  });
160
144
 
161
145
  var _default = (0, _mobxReact.observer)(TrackLabel);
@@ -56,6 +56,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
56
56
  tracks: import("mobx-state-tree").IArrayType<import("mobx-state-tree").IAnyType>;
57
57
  hideHeader: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
58
58
  hideHeaderOverview: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
59
+ hideNoTracksActive: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
59
60
  trackSelectorType: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<"hierarchical">, [undefined]>;
60
61
  trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
61
62
  showCenterLine: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
@@ -87,6 +88,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
87
88
  } & {
88
89
  readonly width: number;
89
90
  readonly interRegionPaddingWidth: number;
91
+ readonly assemblyNames: string[];
90
92
  } & {
91
93
  readonly assemblyErrors: string;
92
94
  readonly assembliesInitialized: boolean;
@@ -106,19 +108,11 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
106
108
  readonly minOffset: number;
107
109
  readonly displayedRegionsTotalPx: number;
108
110
  renderProps(): any;
109
- readonly assemblyNames: string[];
110
111
  searchScope(assemblyName: string): {
111
112
  assemblyName: string;
112
113
  includeAggregateIndexes: boolean;
113
114
  tracks: import("mobx-state-tree").IMSTArray<import("mobx-state-tree").IAnyType> & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IAnyType>>;
114
115
  };
115
- /**
116
- * @param refName - refName of the displayedRegion
117
- * @param coord - coordinate at the displayed Region
118
- * @param regionNumber - optional param used as identifier when
119
- * there are multiple displayedRegions with the same refName
120
- * @returns offsetPx of the displayed region that it lands in
121
- */
122
116
  bpToPx({ refName, coord, regionNumber, }: {
123
117
  refName: string;
124
118
  coord: number;
@@ -164,6 +158,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
164
158
  setError(error: Error | undefined): void;
165
159
  toggleHeader(): void;
166
160
  toggleHeaderOverview(): void;
161
+ toggleNoTracksActive(): void;
167
162
  scrollTo(offsetPx: number): number;
168
163
  zoomTo(bpPerPx: number): number;
169
164
  setOffsets(left: undefined | BpOffset, right: undefined | BpOffset): void;
@@ -155,6 +155,7 @@ function stateModelFactory(pluginManager) {
155
155
  tracks: _mobxStateTree.types.array(pluginManager.pluggableMstType('track', 'stateModel')),
156
156
  hideHeader: false,
157
157
  hideHeaderOverview: false,
158
+ hideNoTracksActive: false,
158
159
  trackSelectorType: _mobxStateTree.types.optional(_mobxStateTree.types.enumeration(['hierarchical']), 'hierarchical'),
159
160
  trackLabels: _mobxStateTree.types.optional(_mobxStateTree.types.string, function () {
160
161
  return localStorageGetItem('lgv-trackLabels') || 'overlapping';
@@ -199,6 +200,12 @@ function stateModelFactory(pluginManager) {
199
200
 
200
201
  get interRegionPaddingWidth() {
201
202
  return INTER_REGION_PADDING_WIDTH;
203
+ },
204
+
205
+ get assemblyNames() {
206
+ return (0, _toConsumableArray2.default)(new Set(self.displayedRegions.map(function (region) {
207
+ return region.assemblyName;
208
+ })));
202
209
  }
203
210
 
204
211
  };
@@ -208,7 +215,8 @@ function stateModelFactory(pluginManager) {
208
215
  var _getSession = (0, _util.getSession)(self),
209
216
  assemblyManager = _getSession.assemblyManager;
210
217
 
211
- return this.assemblyNames.map(function (a) {
218
+ var assemblyNames = self.assemblyNames;
219
+ return assemblyNames.map(function (a) {
212
220
  var _assemblyManager$get;
213
221
 
214
222
  return (_assemblyManager$get = assemblyManager.get(a)) === null || _assemblyManager$get === void 0 ? void 0 : _assemblyManager$get.error;
@@ -221,7 +229,8 @@ function stateModelFactory(pluginManager) {
221
229
  var _getSession2 = (0, _util.getSession)(self),
222
230
  assemblyManager = _getSession2.assemblyManager;
223
231
 
224
- return this.assemblyNames.every(function (a) {
232
+ var assemblyNames = self.assemblyNames;
233
+ return assemblyNames.every(function (a) {
225
234
  var _assemblyManager$get2;
226
235
 
227
236
  return (_assemblyManager$get2 = assemblyManager.get(a)) === null || _assemblyManager$get2 === void 0 ? void 0 : _assemblyManager$get2.initialized;
@@ -312,13 +321,6 @@ function stateModelFactory(pluginManager) {
312
321
  highResolutionScaling: (0, _configuration.getConf)((0, _util.getSession)(self), 'highResolutionScaling')
313
322
  });
314
323
  },
315
-
316
- get assemblyNames() {
317
- return (0, _toConsumableArray2.default)(new Set(self.displayedRegions.map(function (region) {
318
- return region.assemblyName;
319
- })));
320
- },
321
-
322
324
  searchScope: function searchScope(assemblyName) {
323
325
  return {
324
326
  assemblyName: assemblyName,
@@ -326,14 +328,6 @@ function stateModelFactory(pluginManager) {
326
328
  tracks: self.tracks
327
329
  };
328
330
  },
329
-
330
- /**
331
- * @param refName - refName of the displayedRegion
332
- * @param coord - coordinate at the displayed Region
333
- * @param regionNumber - optional param used as identifier when
334
- * there are multiple displayedRegions with the same refName
335
- * @returns offsetPx of the displayed region that it lands in
336
- */
337
331
  bpToPx: function bpToPx(_ref) {
338
332
  var refName = _ref.refName,
339
333
  coord = _ref.coord,
@@ -432,10 +426,8 @@ function stateModelFactory(pluginManager) {
432
426
  return track.configuration.trackId;
433
427
  });
434
428
  results.forEach(function (result) {
435
- if (openTrackIds !== []) {
436
- if (openTrackIds.includes(result.trackId)) {
437
- result.updateScore(result.getScore() + 1);
438
- }
429
+ if (openTrackIds.includes(result.trackId)) {
430
+ result.updateScore(result.getScore() + 1);
439
431
  }
440
432
  });
441
433
  return results;
@@ -509,6 +501,9 @@ function stateModelFactory(pluginManager) {
509
501
  toggleHeaderOverview: function toggleHeaderOverview() {
510
502
  self.hideHeaderOverview = !self.hideHeaderOverview;
511
503
  },
504
+ toggleNoTracksActive: function toggleNoTracksActive() {
505
+ self.hideNoTracksActive = !self.hideNoTracksActive;
506
+ },
512
507
  scrollTo: function scrollTo(offsetPx) {
513
508
  var newOffsetPx = (0, _util.clamp)(offsetPx, self.minOffset, self.maxOffset);
514
509
  self.offsetPx = newOffsetPx;
@@ -692,6 +687,8 @@ function stateModelFactory(pluginManager) {
692
687
  throw new Error("invalid track selector type ".concat(self.trackSelectorType));
693
688
  },
694
689
  navToLocString: function navToLocString(locString, optAssemblyName) {
690
+ var _parsedLocStrings;
691
+
695
692
  var assemblyNames = self.assemblyNames;
696
693
 
697
694
  var _getSession3 = (0, _util.getSession)(self),
@@ -699,14 +696,38 @@ function stateModelFactory(pluginManager) {
699
696
 
700
697
  var isValidRefName = assemblyManager.isValidRefName;
701
698
  var assemblyName = optAssemblyName || assemblyNames[0];
702
- var parsedLocStrings = locString.split(' ').filter(function (f) {
703
- return !!f.trim();
704
- }).map(function (l) {
705
- return (0, _util.parseLocString)(l, function (ref) {
706
- return isValidRefName(ref, assemblyName);
699
+ var parsedLocStrings;
700
+ var inputs = locString.split(/(\s+)/).map(function (f) {
701
+ return f.trim();
702
+ }).filter(function (f) {
703
+ return !!f;
704
+ }); // first try interpreting as a whitespace-separated sequence of
705
+ // multiple locstrings
706
+
707
+ try {
708
+ parsedLocStrings = inputs.map(function (l) {
709
+ return (0, _util.parseLocString)(l, function (ref) {
710
+ return isValidRefName(ref, assemblyName);
711
+ });
707
712
  });
708
- });
709
- var locations = parsedLocStrings.map(function (region) {
713
+ } catch (e) {
714
+ // if this fails, try interpreting as a whitespace-separated refname,
715
+ // start, end if start and end are integer inputs
716
+ var _inputs = (0, _slicedToArray2.default)(inputs, 3),
717
+ refName = _inputs[0],
718
+ start = _inputs[1],
719
+ end = _inputs[2];
720
+
721
+ if ("".concat(e).match(/Unknown reference sequence/) && Number.isInteger(+start) && Number.isInteger(+end)) {
722
+ parsedLocStrings = [(0, _util.parseLocString)(refName + ':' + start + '..' + end, function (ref) {
723
+ return isValidRefName(ref, assemblyName);
724
+ })];
725
+ } else {
726
+ throw e;
727
+ }
728
+ }
729
+
730
+ var locations = (_parsedLocStrings = parsedLocStrings) === null || _parsedLocStrings === void 0 ? void 0 : _parsedLocStrings.map(function (region) {
710
731
  var asmName = region.assemblyName || assemblyName;
711
732
  var asm = assemblyManager.get(asmName);
712
733
  var refName = region.refName;
@@ -746,12 +767,12 @@ function stateModelFactory(pluginManager) {
746
767
  this.setDisplayedRegions([_objectSpread({
747
768
  reversed: loc.reversed
748
769
  }, loc.parentRegion)]);
749
- var start = loc.start,
750
- end = loc.end,
770
+ var _start = loc.start,
771
+ _end = loc.end,
751
772
  parentRegion = loc.parentRegion;
752
773
  this.navTo(_objectSpread(_objectSpread({}, loc), {}, {
753
- start: (0, _util.clamp)(start !== null && start !== void 0 ? start : 0, 0, parentRegion.end),
754
- end: (0, _util.clamp)(end !== null && end !== void 0 ? end : parentRegion.end, 0, parentRegion.end)
774
+ start: (0, _util.clamp)(_start !== null && _start !== void 0 ? _start : 0, 0, parentRegion.end),
775
+ end: (0, _util.clamp)(_end !== null && _end !== void 0 ? _end : parentRegion.end, 0, parentRegion.end)
755
776
  }));
756
777
  } else {
757
778
  this.setDisplayedRegions( // @ts-ignore
@@ -1230,6 +1251,12 @@ function stateModelFactory(pluginManager) {
1230
1251
  checked: !self.hideHeaderOverview,
1231
1252
  onClick: self.toggleHeaderOverview,
1232
1253
  disabled: self.hideHeader
1254
+ }, {
1255
+ label: 'Show no tracks active button',
1256
+ icon: _Visibility.default,
1257
+ type: 'checkbox',
1258
+ checked: !self.hideNoTracksActive,
1259
+ onClick: self.toggleNoTracksActive
1233
1260
  }, {
1234
1261
  label: 'Track labels',
1235
1262
  icon: _Label.default,
@@ -82,7 +82,7 @@ function initialize() {
82
82
  }).actions(function (self) {
83
83
  return {
84
84
  isValidRefName: function isValidRefName(str) {
85
- return !str.includes(':');
85
+ return str === 'ctgA' || str === 'ctgB';
86
86
  },
87
87
  get: function get(str) {
88
88
  return self.assemblies.get(str);
@@ -1163,8 +1163,25 @@ test('multi region', function () {
1163
1163
  model.setDisplayedRegions(_volvoxDisplayedRegions.default.slice(0, 1));
1164
1164
  model.navToLocString('ctgA ctgB');
1165
1165
  expect(model.displayedRegions[0].refName).toBe('ctgA');
1166
- expect(model.displayedRegions[1].refName).toBe('ctgB'); // [
1167
- // { refName: 'ctgA', start: 0, end: 50001 },
1168
- // { refName: 'ctgB', start: 0, end: 6079 },
1169
- // ])
1166
+ expect(model.displayedRegions[1].refName).toBe('ctgB');
1167
+ });
1168
+ test('space separated locstring', function () {
1169
+ var _initialize15 = initialize(),
1170
+ Session = _initialize15.Session,
1171
+ LinearGenomeModel = _initialize15.LinearGenomeModel;
1172
+
1173
+ var model = Session.create({
1174
+ configuration: {}
1175
+ }).setView(LinearGenomeModel.create({
1176
+ type: 'LinearGenomeView',
1177
+ tracks: [{
1178
+ name: 'foo track',
1179
+ type: 'BasicTrack'
1180
+ }]
1181
+ }));
1182
+ model.setWidth(800);
1183
+ model.setDisplayedRegions(_volvoxDisplayedRegions.default.slice(0, 1));
1184
+ model.navToLocString('ctgA 0 100');
1185
+ expect(model.offsetPx).toBe(0);
1186
+ expect(model.bpPerPx).toBe(0.125);
1170
1187
  });
package/dist/index.js CHANGED
@@ -211,36 +211,37 @@ var LinearGenomeViewPlugin = /*#__PURE__*/function (_Plugin) {
211
211
  switch (_context.prev = _context.next) {
212
212
  case 0:
213
213
  session = _ref.session, assembly = _ref.assembly, loc = _ref.loc, _ref$tracks = _ref.tracks, tracks = _ref$tracks === void 0 ? [] : _ref$tracks;
214
+ _context.prev = 1;
214
215
  assemblyManager = session.assemblyManager;
215
216
  view = session.addView('LinearGenomeView', {});
216
- _context.next = 5;
217
+ _context.next = 6;
217
218
  return (0, _mobx.when)(function () {
218
219
  return !!view.volatileWidth;
219
220
  });
220
221
 
221
- case 5:
222
+ case 6:
222
223
  if (assembly) {
223
- _context.next = 7;
224
+ _context.next = 8;
224
225
  break;
225
226
  }
226
227
 
227
228
  throw new Error('No assembly provided when launching linear genome view');
228
229
 
229
- case 7:
230
- _context.next = 9;
230
+ case 8:
231
+ _context.next = 10;
231
232
  return assemblyManager.waitForAssembly(assembly);
232
233
 
233
- case 9:
234
+ case 10:
234
235
  asm = _context.sent;
235
236
 
236
237
  if (asm) {
237
- _context.next = 12;
238
+ _context.next = 13;
238
239
  break;
239
240
  }
240
241
 
241
242
  throw new Error("Assembly \"".concat(assembly, "\" not found when launching linear genome view"));
242
243
 
243
- case 12:
244
+ case 13:
244
245
  view.navToLocString(loc, assembly);
245
246
  idsNotFound = [];
246
247
  tracks.forEach(function (track) {
@@ -256,18 +257,28 @@ var LinearGenomeViewPlugin = /*#__PURE__*/function (_Plugin) {
256
257
  });
257
258
 
258
259
  if (!idsNotFound.length) {
259
- _context.next = 17;
260
+ _context.next = 18;
260
261
  break;
261
262
  }
262
263
 
263
264
  throw new Error("Could not resolve identifiers: ".concat(idsNotFound.join(',')));
264
265
 
265
- case 17:
266
+ case 18:
267
+ _context.next = 24;
268
+ break;
269
+
270
+ case 20:
271
+ _context.prev = 20;
272
+ _context.t0 = _context["catch"](1);
273
+ session.notify("".concat(_context.t0), 'error');
274
+ throw _context.t0;
275
+
276
+ case 24:
266
277
  case "end":
267
278
  return _context.stop();
268
279
  }
269
280
  }
270
- }, _callee);
281
+ }, _callee, null, [[1, 20]]);
271
282
  }));
272
283
 
273
284
  return function (_x) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-linear-genome-view",
3
- "version": "1.7.9",
3
+ "version": "1.7.10",
4
4
  "description": "JBrowse 2 linear genome view",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -40,6 +40,7 @@
40
40
  "clsx": "^1.0.4",
41
41
  "copy-to-clipboard": "^3.3.1",
42
42
  "file-saver": "^2.0.0",
43
+ "material-ui-popup-state": "^1.9.3",
43
44
  "normalize-wheel": "^1.0.1",
44
45
  "react-popper": "^2.0.0"
45
46
  },
@@ -57,5 +58,5 @@
57
58
  "publishConfig": {
58
59
  "access": "public"
59
60
  },
60
- "gitHead": "a6504c385d703ce6e755d05652ef659ffe28c864"
61
+ "gitHead": "02d8c1e88e5603ea5855faed4ccb814e28071b32"
61
62
  }
@@ -1,19 +1,15 @@
1
- import React, { useState, useRef, useMemo } from 'react'
1
+ import React, { useState, useRef } from 'react'
2
2
  import { observer } from 'mobx-react'
3
- import { Portal, alpha, useTheme, makeStyles } from '@material-ui/core'
3
+ import { useTheme, makeStyles } from '@material-ui/core'
4
4
  import { getConf } from '@jbrowse/core/configuration'
5
5
  import { Menu } from '@jbrowse/core/ui'
6
- import { usePopper } from 'react-popper'
7
6
 
8
7
  // locals
8
+ import Tooltip from './Tooltip'
9
9
  import LinearBlocks from './LinearBlocks'
10
10
  import { BaseLinearDisplayModel } from '../models/BaseLinearDisplayModel'
11
11
 
12
- function round(value: number) {
13
- return Math.round(value * 1e5) / 1e5
14
- }
15
-
16
- const useStyles = makeStyles(theme => ({
12
+ const useStyles = makeStyles({
17
13
  display: {
18
14
  position: 'relative',
19
15
  whiteSpace: 'nowrap',
@@ -21,89 +17,8 @@ const useStyles = makeStyles(theme => ({
21
17
  width: '100%',
22
18
  minHeight: '100%',
23
19
  },
24
-
25
- // these styles come from
26
- // https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Tooltip/Tooltip.js
27
- tooltip: {
28
- pointerEvents: 'none',
29
- backgroundColor: alpha(theme.palette.grey[700], 0.9),
30
- borderRadius: theme.shape.borderRadius,
31
- color: theme.palette.common.white,
32
- fontFamily: theme.typography.fontFamily,
33
- padding: '4px 8px',
34
- fontSize: theme.typography.pxToRem(12),
35
- lineHeight: `${round(14 / 10)}em`,
36
- maxWidth: 300,
37
- wordWrap: 'break-word',
38
- },
39
- }))
40
-
41
- const TooltipContents = React.forwardRef<
42
- HTMLDivElement,
43
- { message: React.ReactNode | string }
44
- >(({ message }: { message: React.ReactNode | string }, ref) => {
45
- return <div ref={ref}>{message}</div>
46
20
  })
47
21
 
48
- const Tooltip = observer(
49
- ({
50
- model,
51
- clientMouseCoord,
52
- }: {
53
- model: BaseLinearDisplayModel
54
- clientMouseCoord: Coord
55
- }) => {
56
- const classes = useStyles()
57
- const { featureUnderMouse } = model
58
- const [width, setWidth] = useState(0)
59
- const [popperElt, setPopperElt] = useState<HTMLDivElement | null>(null)
60
-
61
- // must be memoized a la https://github.com/popperjs/react-popper/issues/391
62
- const virtElement = useMemo(
63
- () => ({
64
- getBoundingClientRect: () => {
65
- const x = clientMouseCoord[0] + width / 2 + 20
66
- const y = clientMouseCoord[1]
67
- return {
68
- top: y,
69
- left: x,
70
- bottom: y,
71
- right: x,
72
- width: 0,
73
- height: 0,
74
- x,
75
- y,
76
- toJSON() {},
77
- }
78
- },
79
- }),
80
- [clientMouseCoord, width],
81
- )
82
- const { styles, attributes } = usePopper(virtElement, popperElt)
83
-
84
- const contents = featureUnderMouse
85
- ? getConf(model, 'mouseover', { feature: featureUnderMouse })
86
- : undefined
87
-
88
- return featureUnderMouse && contents ? (
89
- <Portal>
90
- <div
91
- ref={setPopperElt}
92
- className={classes.tooltip}
93
- // zIndex needed to go over widget drawer
94
- style={{ ...styles.popper, zIndex: 100000 }}
95
- {...attributes.popper}
96
- >
97
- <TooltipContents
98
- ref={elt => setWidth(elt?.getBoundingClientRect().width || 0)}
99
- message={contents}
100
- />
101
- </div>
102
- </Portal>
103
- ) : null
104
- },
105
- )
106
-
107
22
  type Coord = [number, number]
108
23
  const BaseLinearDisplay = observer(
109
24
  (props: { model: BaseLinearDisplayModel; children?: React.ReactNode }) => {