@jbrowse/plugin-linear-genome-view 2.13.0 → 2.14.0

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 (111) hide show
  1. package/dist/BaseLinearDisplay/components/LinearBlocks.js +2 -2
  2. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +3 -1
  3. package/dist/BaseLinearDisplay/components/Tooltip.js +1 -1
  4. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +1 -1
  5. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -5
  6. package/dist/BaseLinearDisplay/models/FeatureDensityMixin.js +2 -3
  7. package/dist/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
  8. package/dist/BaseLinearDisplay/models/renderSvg.js +3 -1
  9. package/dist/BaseLinearDisplay/models/util.d.ts +1 -1
  10. package/dist/BaseLinearDisplay/models/util.js +3 -5
  11. package/dist/LaunchLinearGenomeView/index.js +12 -11
  12. package/dist/LinearBareDisplay/model.d.ts +1 -1
  13. package/dist/LinearBasicDisplay/components/AddFiltersDialog.js +9 -3
  14. package/dist/LinearBasicDisplay/components/SetMaxHeightDialog.js +6 -2
  15. package/dist/LinearBasicDisplay/model.d.ts +2 -4
  16. package/dist/LinearBasicDisplay/model.js +9 -3
  17. package/dist/LinearGenomeView/components/Cytobands.js +6 -23
  18. package/dist/LinearGenomeView/components/ExportSvgDialog.js +16 -6
  19. package/dist/LinearGenomeView/components/GetSequenceDialog.js +13 -16
  20. package/dist/LinearGenomeView/components/Header.js +6 -2
  21. package/dist/LinearGenomeView/components/Highlight.js +24 -25
  22. package/dist/LinearGenomeView/components/ImportForm.js +5 -2
  23. package/dist/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +5 -1
  24. package/dist/LinearGenomeView/components/LinearGenomeView.d.ts +2 -3
  25. package/dist/LinearGenomeView/components/LinearGenomeView.js +5 -3
  26. package/dist/LinearGenomeView/components/MiniControls.js +6 -2
  27. package/dist/LinearGenomeView/components/OverviewHighlight.js +23 -30
  28. package/dist/LinearGenomeView/components/OverviewRubberband.js +1 -1
  29. package/dist/LinearGenomeView/components/OverviewScalebar.js +6 -11
  30. package/dist/LinearGenomeView/components/OverviewScalebarPolygon.js +1 -2
  31. package/dist/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +6 -5
  32. package/dist/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +6 -2
  33. package/dist/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +3 -1
  34. package/dist/LinearGenomeView/components/RefNameAutocomplete/index.js +9 -7
  35. package/dist/LinearGenomeView/components/RubberbandSpan.js +3 -5
  36. package/dist/LinearGenomeView/components/Scalebar.js +2 -1
  37. package/dist/LinearGenomeView/components/SearchResultsDialog.js +3 -1
  38. package/dist/LinearGenomeView/components/SearchResultsTable.js +2 -3
  39. package/dist/LinearGenomeView/components/SequenceSearchDialog.js +15 -5
  40. package/dist/LinearGenomeView/components/TrackContainer.js +2 -2
  41. package/dist/LinearGenomeView/components/TrackLabel.js +15 -5
  42. package/dist/LinearGenomeView/components/TrackLabelDragHandle.js +3 -1
  43. package/dist/LinearGenomeView/components/TracksContainer.js +1 -1
  44. package/dist/LinearGenomeView/components/ZoomControls.js +10 -4
  45. package/dist/LinearGenomeView/components/hooks.d.ts +2 -2
  46. package/dist/LinearGenomeView/components/hooks.js +24 -26
  47. package/dist/LinearGenomeView/components/util.d.ts +2 -2
  48. package/dist/LinearGenomeView/model.d.ts +24 -13
  49. package/dist/LinearGenomeView/model.js +75 -46
  50. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +0 -1
  51. package/dist/LinearGenomeView/svgcomponents/SVGRuler.js +1 -1
  52. package/dist/LinearGenomeView/util.d.ts +1 -1
  53. package/dist/LinearGenomeView/util.js +4 -9
  54. package/dist/index.d.ts +3 -414
  55. package/dist/searchUtils.js +4 -6
  56. package/esm/BaseLinearDisplay/components/LinearBlocks.js +2 -2
  57. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +3 -1
  58. package/esm/BaseLinearDisplay/components/Tooltip.js +1 -1
  59. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +1 -1
  60. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -5
  61. package/esm/BaseLinearDisplay/models/FeatureDensityMixin.js +2 -3
  62. package/esm/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
  63. package/esm/BaseLinearDisplay/models/renderSvg.js +3 -1
  64. package/esm/BaseLinearDisplay/models/util.d.ts +1 -1
  65. package/esm/BaseLinearDisplay/models/util.js +3 -5
  66. package/esm/LaunchLinearGenomeView/index.js +13 -12
  67. package/esm/LinearBareDisplay/model.d.ts +1 -1
  68. package/esm/LinearBasicDisplay/components/AddFiltersDialog.js +9 -3
  69. package/esm/LinearBasicDisplay/components/SetMaxHeightDialog.js +6 -2
  70. package/esm/LinearBasicDisplay/model.d.ts +2 -4
  71. package/esm/LinearBasicDisplay/model.js +9 -3
  72. package/esm/LinearGenomeView/components/Cytobands.js +6 -23
  73. package/esm/LinearGenomeView/components/ExportSvgDialog.js +16 -6
  74. package/esm/LinearGenomeView/components/GetSequenceDialog.js +13 -16
  75. package/esm/LinearGenomeView/components/Header.js +6 -2
  76. package/esm/LinearGenomeView/components/Highlight.js +26 -27
  77. package/esm/LinearGenomeView/components/ImportForm.js +5 -2
  78. package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +5 -1
  79. package/esm/LinearGenomeView/components/LinearGenomeView.d.ts +2 -3
  80. package/esm/LinearGenomeView/components/LinearGenomeView.js +5 -3
  81. package/esm/LinearGenomeView/components/MiniControls.js +6 -2
  82. package/esm/LinearGenomeView/components/OverviewHighlight.js +24 -31
  83. package/esm/LinearGenomeView/components/OverviewRubberband.js +1 -1
  84. package/esm/LinearGenomeView/components/OverviewScalebar.js +6 -11
  85. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +1 -2
  86. package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +6 -5
  87. package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +6 -2
  88. package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +3 -1
  89. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +10 -8
  90. package/esm/LinearGenomeView/components/RubberbandSpan.js +3 -5
  91. package/esm/LinearGenomeView/components/Scalebar.js +2 -1
  92. package/esm/LinearGenomeView/components/SearchResultsDialog.js +3 -1
  93. package/esm/LinearGenomeView/components/SearchResultsTable.js +2 -3
  94. package/esm/LinearGenomeView/components/SequenceSearchDialog.js +15 -5
  95. package/esm/LinearGenomeView/components/TrackContainer.js +2 -2
  96. package/esm/LinearGenomeView/components/TrackLabel.js +15 -5
  97. package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +3 -1
  98. package/esm/LinearGenomeView/components/TracksContainer.js +1 -1
  99. package/esm/LinearGenomeView/components/ZoomControls.js +10 -4
  100. package/esm/LinearGenomeView/components/hooks.d.ts +2 -2
  101. package/esm/LinearGenomeView/components/hooks.js +24 -26
  102. package/esm/LinearGenomeView/components/util.d.ts +2 -2
  103. package/esm/LinearGenomeView/model.d.ts +24 -13
  104. package/esm/LinearGenomeView/model.js +77 -48
  105. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +0 -1
  106. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +1 -1
  107. package/esm/LinearGenomeView/util.d.ts +1 -1
  108. package/esm/LinearGenomeView/util.js +4 -9
  109. package/esm/index.d.ts +3 -414
  110. package/esm/searchUtils.js +4 -6
  111. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import { when, parseLocString, } from '@jbrowse/core/util';
1
+ import { when, parseLocString } from '@jbrowse/core/util';
2
2
  import { handleSelectedRegion } from '../searchUtils';
3
3
  export default function LaunchLinearGenomeViewF(pluginManager) {
4
4
  pluginManager.addToExtensionPoint('LaunchView-LinearGenomeView',
@@ -24,22 +24,23 @@ export default function LaunchLinearGenomeViewF(pluginManager) {
24
24
  }
25
25
  if (highlight !== undefined) {
26
26
  highlight.forEach(async (h) => {
27
- if (h) {
28
- const parsedLocString = parseLocString(h, refName => isValidRefName(refName, assembly));
29
- const location = {
30
- ...parsedLocString,
27
+ const p = parseLocString(h, refName => isValidRefName(refName, assembly));
28
+ const { start, end } = p;
29
+ if (start !== undefined && end !== undefined) {
30
+ view.addToHighlights({
31
+ ...p,
32
+ start,
33
+ end,
31
34
  assemblyName: assembly,
32
- };
33
- if ((location === null || location === void 0 ? void 0 : location.start) !== undefined &&
34
- (location === null || location === void 0 ? void 0 : location.end) !== undefined) {
35
- view.addToHighlights(location);
36
- }
35
+ });
37
36
  }
38
37
  });
39
38
  }
40
39
  await handleSelectedRegion({ input: loc, model: view, assembly: asm });
41
40
  const idsNotFound = [];
42
- tracks.forEach(track => tryTrack(view, track, idsNotFound));
41
+ tracks.forEach(track => {
42
+ tryTrack(view, track, idsNotFound);
43
+ });
43
44
  if (idsNotFound.length) {
44
45
  throw new Error(`Could not resolve identifiers: ${idsNotFound.join(',')}`);
45
46
  }
@@ -55,7 +56,7 @@ function tryTrack(model, trackId, idsNotFound) {
55
56
  model.showTrack(trackId);
56
57
  }
57
58
  catch (e) {
58
- if (`${e}`.match('Could not resolve identifier')) {
59
+ if (/Could not resolve identifier/.exec(`${e}`)) {
59
60
  idsNotFound.push(trackId);
60
61
  }
61
62
  else {
@@ -128,7 +128,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
128
128
  error: unknown;
129
129
  message: string | undefined;
130
130
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
131
- onHorizontalScroll?: Function;
131
+ onHorizontalScroll?: () => void;
132
132
  blockState?: Record<string, any>;
133
133
  }>;
134
134
  readonly DisplayBlurb: import("react").FC<{
@@ -30,7 +30,9 @@ const AddFiltersDialog = observer(function ({ model, handleClose, }) {
30
30
  .split('\n')
31
31
  .map(line => line.trim())
32
32
  .filter(line => !!line)
33
- .map(line => checkJexl(line.trim()));
33
+ .map(line => {
34
+ checkJexl(line.trim());
35
+ });
34
36
  setError(undefined);
35
37
  }
36
38
  catch (e) {
@@ -54,7 +56,9 @@ const AddFiltersDialog = observer(function ({ model, handleClose, }) {
54
56
  React.createElement("code", null, "jexl:get(feature,'score') > 400"),
55
57
  " - show only features that have a score greater than 400"))),
56
58
  error ? React.createElement("p", { className: classes.error }, `${error}`) : null,
57
- React.createElement(TextField, { variant: "outlined", multiline: true, minRows: 5, maxRows: 10, className: classes.dialogContent, fullWidth: true, value: data, onChange: event => setData(event.target.value), InputProps: {
59
+ React.createElement(TextField, { variant: "outlined", multiline: true, minRows: 5, maxRows: 10, className: classes.dialogContent, fullWidth: true, value: data, onChange: event => {
60
+ setData(event.target.value);
61
+ }, InputProps: {
58
62
  classes: {
59
63
  input: classes.textAreaFont,
60
64
  },
@@ -64,6 +68,8 @@ const AddFiltersDialog = observer(function ({ model, handleClose, }) {
64
68
  model.setJexlFilters(data.split('\n'));
65
69
  handleClose();
66
70
  } }, "Submit"),
67
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel"))));
71
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
72
+ handleClose();
73
+ } }, "Cancel"))));
68
74
  });
69
75
  export default AddFiltersDialog;
@@ -15,12 +15,16 @@ const SetMaxHeightDialog = observer(function ({ model, handleClose, }) {
15
15
  return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Set max height" },
16
16
  React.createElement(DialogContent, { className: classes.root },
17
17
  React.createElement(Typography, null, "Set max height for the track. For example, you can increase this if the layout says \"Max height reached\""),
18
- React.createElement(TextField, { value: max, onChange: event => setMax(event.target.value), placeholder: "Enter max score" })),
18
+ React.createElement(TextField, { value: max, onChange: event => {
19
+ setMax(event.target.value);
20
+ }, placeholder: "Enter max score" })),
19
21
  React.createElement(DialogActions, null,
20
22
  React.createElement(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, onClick: () => {
21
23
  model.setMaxHeight(max !== '' && !Number.isNaN(+max) ? +max : undefined);
22
24
  handleClose();
23
25
  } }, "Submit"),
24
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel"))));
26
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
27
+ handleClose();
28
+ } }, "Cancel"))));
25
29
  });
26
30
  export default SetMaxHeightDialog;
@@ -156,7 +156,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
156
156
  error: unknown;
157
157
  message: string | undefined;
158
158
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
159
- onHorizontalScroll?: Function;
159
+ onHorizontalScroll?: () => void;
160
160
  blockState? /**
161
161
  * #getter
162
162
  */: Record<string, any>;
@@ -294,9 +294,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
294
294
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
295
295
  setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
296
296
  [x: string]: any;
297
- } & import("mobx-state-tree/dist/internal" /**
298
- * #property
299
- */).NonEmptyObject & {
297
+ } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
300
298
  setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
301
299
  [x: string]: any;
302
300
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
@@ -170,14 +170,18 @@ function stateModelFactory(configSchema) {
170
170
  icon: VisibilityIcon,
171
171
  type: 'checkbox',
172
172
  checked: self.showLabels,
173
- onClick: () => self.toggleShowLabels(),
173
+ onClick: () => {
174
+ self.toggleShowLabels();
175
+ },
174
176
  },
175
177
  {
176
178
  label: 'Show descriptions',
177
179
  icon: VisibilityIcon,
178
180
  type: 'checkbox',
179
181
  checked: self.showDescriptions,
180
- onClick: () => self.toggleShowDescriptions(),
182
+ onClick: () => {
183
+ self.toggleShowDescriptions();
184
+ },
181
185
  },
182
186
  {
183
187
  label: 'Display mode',
@@ -189,7 +193,9 @@ function stateModelFactory(configSchema) {
189
193
  'collapse',
190
194
  ].map(val => ({
191
195
  label: val,
192
- onClick: () => self.setDisplayMode(val),
196
+ onClick: () => {
197
+ self.setDisplayMode(val);
198
+ },
193
199
  })),
194
200
  },
195
201
  {
@@ -5,26 +5,11 @@ import { HEADER_OVERVIEW_HEIGHT } from '..';
5
5
  import { getCytobands } from './util';
6
6
  import { getFillProps } from '@jbrowse/core/util';
7
7
  // rounded rect from https://stackoverflow.com/a/45889603/2129219
8
- // prettier-ignore
9
8
  function rightRoundedRect(x, y, width, height, radius) {
10
- return "M" + x + "," + y
11
- + "h" + (width - radius)
12
- + "a" + radius + "," + radius + " 0 0 1 " + radius + "," + radius
13
- + "v" + (height - 2 * radius)
14
- + "a" + radius + "," + radius + " 0 0 1 " + -radius + "," + radius
15
- + "h" + (radius - width)
16
- + "z";
9
+ return `M${x},${y}h${width - radius}a${radius},${radius} 0 0 1 ${radius},${radius}v${height - 2 * radius}a${radius},${radius} 0 0 1 ${-radius},${radius}h${radius - width}z`;
17
10
  }
18
- // prettier-ignore
19
11
  function leftRoundedRect(x, y, width, height, radius) {
20
- return "M" + (x + radius) + "," + y
21
- + "h" + (width - radius)
22
- + "v" + height
23
- + "h" + (radius - width)
24
- + "a" + radius + "," + radius + " 0 0 1 " + (-radius) + "," + (-radius)
25
- + "v" + (2 * radius - height)
26
- + "a" + radius + "," + radius + " 0 0 1 " + radius + "," + (-radius)
27
- + "z";
12
+ return `M${x + radius},${y}h${width - radius}v${height}h${radius - width}a${radius},${radius} 0 0 1 ${-radius},${-radius}v${2 * radius - height}a${radius},${radius} 0 0 1 ${radius},${-radius}z`;
28
13
  }
29
14
  function leftTriangle(x, y, width, height) {
30
15
  return [
@@ -71,20 +56,18 @@ const Cytobands = observer(function ({ overview, block, assembly, }) {
71
56
  ? rightTriangle(s - w, 0, w, h)
72
57
  : leftTriangle(s, 0, w, h), ...getFillProps(c) }));
73
58
  }
74
- else if (type === 'acen' && centromereSeen) {
59
+ if (type === 'acen' && centromereSeen) {
75
60
  return (React.createElement("polygon", { key: k, points: reversed
76
61
  ? leftTriangle(s - w, 0, w, h)
77
62
  : rightTriangle(s, 0, w, h), ...getFillProps(c) }));
78
63
  }
79
- else if (lcap === index) {
64
+ if (lcap === index) {
80
65
  return (React.createElement("path", { key: k, d: leftRoundedRect(l, 0, w, h, 8), ...getFillProps(c) }));
81
66
  }
82
- else if (rcap === index) {
67
+ if (rcap === index) {
83
68
  return (React.createElement("path", { key: k, d: rightRoundedRect(l, 0, w, h, 8), ...getFillProps(c) }));
84
69
  }
85
- else {
86
- return (React.createElement("rect", { key: k, x: l, y: 0, width: w, height: h, ...getFillProps(c) }));
87
- }
70
+ return (React.createElement("rect", { key: k, x: l, y: 0, width: w, height: h, ...getFillProps(c) }));
88
71
  })));
89
72
  });
90
73
  export default Cytobands;
@@ -8,7 +8,7 @@ function LoadingMessage() {
8
8
  React.createElement(Typography, { display: "inline" }, "Creating SVG")));
9
9
  }
10
10
  function useSvgLocal(key, val) {
11
- return useLocalStorage('svg-' + key, val);
11
+ return useLocalStorage(`svg-${key}`, val);
12
12
  }
13
13
  function TextField2({ children, ...rest }) {
14
14
  return (React.createElement("div", null,
@@ -26,18 +26,28 @@ export default function ExportSvgDialog({ model, handleClose, }) {
26
26
  return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Export SVG" },
27
27
  React.createElement(DialogContent, null,
28
28
  error ? (React.createElement(ErrorMessage, { error: error })) : loading ? (React.createElement(LoadingMessage, null)) : null,
29
- React.createElement(TextField2, { helperText: "filename", value: filename, onChange: event => setFilename(event.target.value) }),
30
- React.createElement(TextField2, { select: true, label: "Track label positioning", variant: "outlined", style: { width: 150 }, value: trackLabels, onChange: event => setTrackLabels(event.target.value) },
29
+ React.createElement(TextField2, { helperText: "filename", value: filename, onChange: event => {
30
+ setFilename(event.target.value);
31
+ } }),
32
+ React.createElement(TextField2, { select: true, label: "Track label positioning", variant: "outlined", style: { width: 150 }, value: trackLabels, onChange: event => {
33
+ setTrackLabels(event.target.value);
34
+ } },
31
35
  React.createElement(MenuItem, { value: "offset" }, "Offset"),
32
36
  React.createElement(MenuItem, { value: "overlay" }, "Overlay"),
33
37
  React.createElement(MenuItem, { value: "left" }, "Left"),
34
38
  React.createElement(MenuItem, { value: "none" }, "None")),
35
- session.allThemes ? (React.createElement(TextField2, { select: true, label: "Theme", variant: "outlined", value: themeName, onChange: event => setThemeName(event.target.value) }, Object.entries(session.allThemes()).map(([key, val]) => (React.createElement(MenuItem, { key: key, value: key },
39
+ session.allThemes ? (React.createElement(TextField2, { select: true, label: "Theme", variant: "outlined", value: themeName, onChange: event => {
40
+ setThemeName(event.target.value);
41
+ } }, Object.entries(session.allThemes()).map(([key, val]) => (React.createElement(MenuItem, { key: key, value: key },
36
42
  // @ts-expect-error
37
43
  val.name || '(Unknown name)'))))) : null,
38
- offscreenCanvas ? (React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: rasterizeLayers, onChange: () => setRasterizeLayers(val => !val) }), label: "Rasterize canvas based tracks? File may be much larger if this is turned off" })) : (React.createElement(Typography, null, "Note: rasterizing layers not yet supported in this browser, so SVG size may be large"))),
44
+ offscreenCanvas ? (React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: rasterizeLayers, onChange: () => {
45
+ setRasterizeLayers(val => !val);
46
+ } }), label: "Rasterize canvas based tracks? File may be much larger if this is turned off" })) : (React.createElement(Typography, null, "Note: rasterizing layers not yet supported in this browser, so SVG size may be large"))),
39
47
  React.createElement(DialogActions, null,
40
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel"),
48
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
49
+ handleClose();
50
+ } }, "Cancel"),
41
51
  React.createElement(Button, { variant: "contained", color: "primary", type: "submit", onClick: async () => {
42
52
  setLoading(true);
43
53
  setError(undefined);
@@ -48,7 +48,6 @@ async function fetchSequence(model, regions, signal) {
48
48
  }
49
49
  const GetSequenceDialog = observer(function ({ model, handleClose, }) {
50
50
  const { classes } = useStyles();
51
- const session = getSession(model);
52
51
  const [error, setError] = useState();
53
52
  const [sequenceChunks, setSequenceChunks] = useState();
54
53
  const [rev, setReverse] = useState(false);
@@ -57,7 +56,6 @@ const GetSequenceDialog = observer(function ({ model, handleClose, }) {
57
56
  const { leftOffset, rightOffset } = model;
58
57
  const loading = Boolean(sequenceChunks === undefined);
59
58
  useEffect(() => {
60
- let active = true;
61
59
  const controller = new AbortController();
62
60
  (async () => {
63
61
  try {
@@ -69,26 +67,19 @@ const GetSequenceDialog = observer(function ({ model, handleClose, }) {
69
67
  throw new Error('Selected region is out of bounds');
70
68
  }
71
69
  const chunks = await fetchSequence(model, selection, controller.signal);
72
- if (active) {
73
- setSequenceChunks(chunks);
74
- }
70
+ setSequenceChunks(chunks);
75
71
  }
76
72
  catch (e) {
77
73
  console.error(e);
78
- if (active) {
79
- setError(e);
80
- }
74
+ setError(e);
81
75
  }
82
76
  })();
83
77
  return () => {
84
78
  controller.abort();
85
- active = false;
86
79
  };
87
- }, [model, session, leftOffset, rightOffset]);
80
+ }, [model, leftOffset, rightOffset]);
88
81
  const sequence = sequenceChunks
89
- ? formatSeqFasta(sequenceChunks
90
- .filter(f => !!f)
91
- .map(chunk => {
82
+ ? formatSeqFasta(sequenceChunks.map(chunk => {
92
83
  let chunkSeq = chunk.get('seq');
93
84
  const chunkRefName = chunk.get('refName');
94
85
  const chunkStart = chunk.get('start') + 1;
@@ -127,14 +118,20 @@ const GetSequenceDialog = observer(function ({ model, handleClose, }) {
127
118
  },
128
119
  } }),
129
120
  React.createElement(FormGroup, null,
130
- React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { value: rev, onChange: event => setReverse(event.target.checked) }), label: "Reverse sequence" }),
131
- React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { value: comp, onChange: event => setComplement(event.target.checked) }), label: "Complement sequence" })),
121
+ React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { value: rev, onChange: event => {
122
+ setReverse(event.target.checked);
123
+ } }), label: "Reverse sequence" }),
124
+ React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { value: comp, onChange: event => {
125
+ setComplement(event.target.checked);
126
+ } }), label: "Complement sequence" })),
132
127
  React.createElement(Typography, { style: { margin: 10 } }, "Note: Check both boxes for the \"reverse complement\"")),
133
128
  React.createElement(DialogActions, null,
134
129
  React.createElement(Button, { onClick: () => {
135
130
  copy(sequence);
136
131
  setCopied(true);
137
- setTimeout(() => setCopied(false), 500);
132
+ setTimeout(() => {
133
+ setCopied(false);
134
+ }, 500);
138
135
  }, disabled: loading || !!error || sequenceTooLarge, color: "primary", startIcon: React.createElement(ContentCopyIcon, null) }, copied ? 'Copied' : 'Copy to clipboard'),
139
136
  React.createElement(Button, { onClick: () => {
140
137
  saveAs(new Blob([sequence || ''], {
@@ -50,9 +50,13 @@ const HeaderButtons = observer(({ model }) => {
50
50
  function PanControls({ model }) {
51
51
  const { classes } = useStyles();
52
52
  return (React.createElement(React.Fragment, null,
53
- React.createElement(Button, { variant: "outlined", className: classes.panButton, onClick: () => model.slide(-0.9) },
53
+ React.createElement(Button, { variant: "outlined", className: classes.panButton, onClick: () => {
54
+ model.slide(-0.9);
55
+ } },
54
56
  React.createElement(ArrowBackIcon, null)),
55
- React.createElement(Button, { variant: "outlined", className: classes.panButton, onClick: () => model.slide(0.9) },
57
+ React.createElement(Button, { variant: "outlined", className: classes.panButton, onClick: () => {
58
+ model.slide(0.9);
59
+ } },
56
60
  React.createElement(ArrowForwardIcon, null))));
57
61
  }
58
62
  const RegionWidth = observer(({ model }) => {
@@ -2,32 +2,29 @@ import React, { useRef, useState } from 'react';
2
2
  import { observer } from 'mobx-react';
3
3
  import { makeStyles } from 'tss-react/mui';
4
4
  import { colord } from '@jbrowse/core/util/colord';
5
- import { getSession, } from '@jbrowse/core/util';
5
+ import { getSession } from '@jbrowse/core/util';
6
6
  import { Menu } from '@jbrowse/core/ui';
7
- import { IconButton, Tooltip, useTheme } from '@mui/material';
7
+ import { IconButton, Tooltip } from '@mui/material';
8
8
  // icons
9
9
  import LinkIcon from '@mui/icons-material/Link';
10
10
  import CloseIcon from '@mui/icons-material/Close';
11
11
  import BookmarkIcon from '@mui/icons-material/Bookmark';
12
- const useStyles = makeStyles()(theme => {
13
- var _a, _b;
14
- return ({
15
- highlight: {
16
- height: '100%',
17
- position: 'absolute',
18
- overflow: 'hidden',
19
- background: `${colord((_b = (_a = theme.palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
20
- .alpha(0.35)
21
- .toRgbString()}`,
22
- },
23
- });
24
- });
12
+ const useStyles = makeStyles()(theme => ({
13
+ highlight: {
14
+ height: '100%',
15
+ position: 'absolute',
16
+ overflow: 'hidden',
17
+ background: colord(theme.palette.highlight.main).alpha(0.35).toRgbString(),
18
+ },
19
+ linkIcon: {
20
+ color: colord(theme.palette.highlight.main).darken(0.2).toRgbString(),
21
+ },
22
+ }));
25
23
  const Highlight = observer(function Highlight({ model, highlight, }) {
26
- var _a, _b, _c;
24
+ var _a;
27
25
  const { classes } = useStyles();
28
26
  const [open, setOpen] = useState(false);
29
27
  const anchorEl = useRef(null);
30
- const color = (_b = (_a = useTheme().palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod';
31
28
  const session = getSession(model);
32
29
  const { assemblyManager } = session;
33
30
  const dismissHighlight = () => {
@@ -53,20 +50,20 @@ const Highlight = observer(function Highlight({ model, highlight, }) {
53
50
  }
54
51
  : undefined;
55
52
  };
56
- const asm = assemblyManager.get(highlight === null || highlight === void 0 ? void 0 : highlight.assemblyName);
53
+ const asm = assemblyManager.get(highlight.assemblyName);
57
54
  const h = mapCoords({
58
55
  ...highlight,
59
- refName: (_c = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(highlight.refName)) !== null && _c !== void 0 ? _c : highlight.refName,
56
+ refName: (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(highlight.refName)) !== null && _a !== void 0 ? _a : highlight.refName,
60
57
  });
61
58
  return h ? (React.createElement("div", { className: classes.highlight, style: {
62
59
  left: h.left,
63
60
  width: h.width,
64
61
  } },
65
- React.createElement(Tooltip, { title: 'Highlighted from URL parameter', arrow: true },
66
- React.createElement(IconButton, { ref: anchorEl, onClick: () => setOpen(true), style: { zIndex: 3 } },
67
- React.createElement(LinkIcon, { fontSize: "small", sx: {
68
- color: `${colord(color).darken(0.2).toRgbString()}`,
69
- } }))),
62
+ React.createElement(Tooltip, { title: "Highlighted from URL parameter", arrow: true },
63
+ React.createElement(IconButton, { ref: anchorEl, onClick: () => {
64
+ setOpen(true);
65
+ }, style: { zIndex: 3 } },
66
+ React.createElement(LinkIcon, { fontSize: "small", className: classes.linkIcon }))),
70
67
  React.createElement(Menu, { anchorEl: anchorEl.current, onMenuItemClick: (_event, callback) => {
71
68
  callback(session);
72
69
  handleClose();
@@ -74,7 +71,9 @@ const Highlight = observer(function Highlight({ model, highlight, }) {
74
71
  {
75
72
  label: 'Dismiss highlight',
76
73
  icon: CloseIcon,
77
- onClick: () => dismissHighlight(),
74
+ onClick: () => {
75
+ dismissHighlight();
76
+ },
78
77
  },
79
78
  {
80
79
  label: 'Bookmark highlighted region',
@@ -84,7 +83,7 @@ const Highlight = observer(function Highlight({ model, highlight, }) {
84
83
  if (!bookmarkWidget) {
85
84
  bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
86
85
  }
87
- // @ts-ignore
86
+ // @ts-expect-error
88
87
  bookmarkWidget.addBookmark(highlight);
89
88
  dismissHighlight();
90
89
  },
@@ -92,6 +91,6 @@ const Highlight = observer(function Highlight({ model, highlight, }) {
92
91
  ] }))) : null;
93
92
  });
94
93
  const HighlightGroup = observer(function HighlightGroup({ model, }) {
95
- return model.highlight.map((highlight, idx) => (React.createElement(Highlight, { key: JSON.stringify(highlight) + '-' + idx, model: model, highlight: highlight })));
94
+ return model.highlight.map((highlight, idx) => (React.createElement(Highlight, { key: `${JSON.stringify(highlight)}-${idx}`, model: model, highlight: highlight })));
96
95
  });
97
96
  export default HighlightGroup;
@@ -35,12 +35,13 @@ const LinearGenomeViewImportForm = observer(function ({ model, }) {
35
35
  const [value, setValue] = useState('');
36
36
  const regions = assembly === null || assembly === void 0 ? void 0 : assembly.regions;
37
37
  const assemblyLoaded = !!regions;
38
- const r0 = regions ? (_a = regions[0]) === null || _a === void 0 ? void 0 : _a.refName : '';
38
+ const r0 = regions ? ((_a = regions[0]) === null || _a === void 0 ? void 0 : _a.refName) || '' : '';
39
39
  // useEffect resets to an "initial state" of displaying first region from
40
40
  // assembly after assembly change. needs to react to selectedAsm as well as
41
41
  // r0 because changing assembly will run setValue('') and then r0 may not
42
42
  // change if assembly names are the same across assemblies, but it still
43
43
  // needs to be reset
44
+ /* biome-ignore lint/correctness/useExhaustiveDependencies: */
44
45
  useEffect(() => {
45
46
  setValue(r0);
46
47
  }, [r0, selectedAsm]);
@@ -80,7 +81,9 @@ const LinearGenomeViewImportForm = observer(function ({ model, }) {
80
81
  React.createElement(Grid, { container: true, spacing: 1, justifyContent: "center", alignItems: "center" },
81
82
  React.createElement(Grid, { item: true },
82
83
  React.createElement(FormControl, null,
83
- React.createElement(AssemblySelector, { onChange: val => setSelectedAsm(val), localStorageKey: "lgv", session: session, selected: selectedAsm }))),
84
+ React.createElement(AssemblySelector, { onChange: val => {
85
+ setSelectedAsm(val);
86
+ }, localStorageKey: "lgv", session: session, selected: selectedAsm }))),
84
87
  React.createElement(Grid, { item: true }, selectedAsm ? (assemblyError ? (React.createElement(CloseIcon, { style: { color: 'red' } })) : assemblyLoaded ? (React.createElement(FormControl, null,
85
88
  React.createElement(ImportFormRefNameAutocomplete, { value: value, setValue: setValue, selectedAsm: selectedAsm, setOption: setOption, model: model }))) : (React.createElement(CircularProgress, { size: 20, disableShrink: true }))) : null),
86
89
  React.createElement(Grid, { item: true },
@@ -16,7 +16,11 @@ const ImportFormRefNameAutocomplete = observer(function ({ model, selectedAsm, v
16
16
  textSearchManager,
17
17
  rankSearchResults,
18
18
  searchScope,
19
- }), model: model, assemblyName: selectedAsm, value: value, minWidth: 270, onChange: str => setValue(str), onSelect: val => setOption(val), TextFieldProps: {
19
+ }), model: model, assemblyName: selectedAsm, value: value, minWidth: 270, onChange: str => {
20
+ setValue(str);
21
+ }, onSelect: val => {
22
+ setOption(val);
23
+ }, TextFieldProps: {
20
24
  variant: 'outlined',
21
25
  helperText: 'Enter sequence name, feature name, or location',
22
26
  } }));
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { LinearGenomeViewModel } from '..';
3
- type LGV = LinearGenomeViewModel;
4
- declare const LinearGenomeView: ({ model }: {
5
- model: LGV;
3
+ declare const LinearGenomeView: ({ model, }: {
4
+ model: LinearGenomeViewModel;
6
5
  }) => React.JSX.Element;
7
6
  export default LinearGenomeView;
@@ -20,7 +20,7 @@ const useStyles = makeStyles()(theme => ({
20
20
  zIndex: 1000,
21
21
  },
22
22
  }));
23
- const LinearGenomeView = observer(({ model }) => {
23
+ const LinearGenomeView = observer(function ({ model, }) {
24
24
  const { tracks, error, initialized, hasDisplayedRegions } = model;
25
25
  const ref = useRef(null);
26
26
  const session = getSession(model);
@@ -30,7 +30,7 @@ const LinearGenomeView = observer(({ model }) => {
30
30
  // necessary for subviews to be focused properly
31
31
  function handleSelectView(e) {
32
32
  var _a, _b;
33
- if (e.target instanceof Element && ((_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
33
+ if (e.target instanceof Element && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
34
34
  (_b = session.setFocusedViewId) === null || _b === void 0 ? void 0 : _b.call(session, model.id);
35
35
  }
36
36
  }
@@ -49,7 +49,9 @@ const LinearGenomeView = observer(({ model }) => {
49
49
  }
50
50
  const MiniControlsComponent = model.MiniControlsComponent();
51
51
  const HeaderComponent = model.HeaderComponent();
52
- return (React.createElement("div", { className: classes.rel, ref: ref, onMouseLeave: () => session.setHovered(undefined), onMouseMove: event => {
52
+ return (React.createElement("div", { className: classes.rel, ref: ref, onMouseLeave: () => {
53
+ session.setHovered(undefined);
54
+ }, onMouseMove: event => {
53
55
  const c = ref.current;
54
56
  if (!c) {
55
57
  return;
@@ -27,9 +27,13 @@ const MiniControls = observer(function ({ model, }) {
27
27
  React.createElement(Paper, { className: focusedViewId === id ? classes.focusedBackground : undefined },
28
28
  React.createElement(CascadingMenuButton, { menuItems: model.menuItems() },
29
29
  React.createElement(ArrowDown, { fontSize: "small" })),
30
- React.createElement(IconButton, { "data-testid": "zoom_out", onClick: () => model.zoom(bpPerPx * 2), disabled: bpPerPx >= maxBpPerPx - 0.0001 || scaleFactor !== 1 },
30
+ React.createElement(IconButton, { "data-testid": "zoom_out", onClick: () => {
31
+ model.zoom(bpPerPx * 2);
32
+ }, disabled: bpPerPx >= maxBpPerPx - 0.0001 || scaleFactor !== 1 },
31
33
  React.createElement(ZoomOut, { fontSize: "small" })),
32
- React.createElement(IconButton, { "data-testid": "zoom_in", onClick: () => model.zoom(bpPerPx / 2), disabled: bpPerPx <= minBpPerPx + 0.0001 || scaleFactor !== 1 },
34
+ React.createElement(IconButton, { "data-testid": "zoom_in", onClick: () => {
35
+ model.zoom(bpPerPx / 2);
36
+ }, disabled: bpPerPx <= minBpPerPx + 0.0001 || scaleFactor !== 1 },
33
37
  React.createElement(ZoomIn, { fontSize: "small" }))))) : null;
34
38
  });
35
39
  export default MiniControls;
@@ -2,54 +2,47 @@ import React from 'react';
2
2
  import { observer } from 'mobx-react';
3
3
  import { makeStyles } from 'tss-react/mui';
4
4
  import { colord } from '@jbrowse/core/util/colord';
5
- import { getSession, notEmpty, } from '@jbrowse/core/util';
6
- const useStyles = makeStyles()(theme => {
7
- var _a, _b, _c, _d, _e, _f;
8
- return ({
9
- highlight: {
10
- height: '100%',
11
- position: 'absolute',
12
- background: `${colord((_b = (_a = theme.palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
13
- .alpha(0.35)
14
- .toRgbString()}`,
15
- borderLeft: `1px solid ${(_d = (_c = theme.palette.highlight) === null || _c === void 0 ? void 0 : _c.main) !== null && _d !== void 0 ? _d : 'goldenrod'}`,
16
- borderRight: `1px solid ${(_f = (_e = theme.palette.highlight) === null || _e === void 0 ? void 0 : _e.main) !== null && _f !== void 0 ? _f : 'goldenrod'}`,
17
- },
18
- });
19
- });
5
+ import { getSession, notEmpty } from '@jbrowse/core/util';
6
+ const useStyles = makeStyles()(theme => ({
7
+ highlight: {
8
+ height: '100%',
9
+ position: 'absolute',
10
+ background: colord(theme.palette.highlight.main).alpha(0.35).toRgbString(),
11
+ borderLeft: `1px solid ${theme.palette.highlight.main}`,
12
+ borderRight: `1px solid ${theme.palette.highlight.main}`,
13
+ },
14
+ }));
20
15
  const OverviewHighlight = observer(function OverviewHighlight({ model, overview, }) {
21
16
  const { classes } = useStyles();
22
- const { cytobandOffset } = model;
17
+ const { highlight, cytobandOffset } = model;
23
18
  const session = getSession(model);
24
19
  const { assemblyManager } = session;
25
- // coords
26
- const mapCoords = (r) => {
20
+ return highlight
21
+ .map(r => {
22
+ var _a;
23
+ const asm = assemblyManager.get(r.assemblyName);
24
+ const refName = (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(r.refName)) !== null && _a !== void 0 ? _a : r.refName;
27
25
  const s = overview.bpToPx({
28
26
  ...r,
29
- coord: r.reversed ? r.end : r.start,
27
+ refName,
28
+ coord: r.start,
30
29
  });
31
30
  const e = overview.bpToPx({
32
31
  ...r,
33
- coord: r.reversed ? r.start : r.end,
32
+ refName,
33
+ coord: r.end,
34
34
  });
35
- return s !== undefined && e != undefined
35
+ return s !== undefined && e !== undefined
36
36
  ? {
37
37
  width: Math.abs(e - s),
38
38
  left: s + cytobandOffset,
39
39
  }
40
40
  : undefined;
41
- };
42
- return model.highlight
43
- .map(h => {
44
- var _a;
45
- const asm = assemblyManager.get(h === null || h === void 0 ? void 0 : h.assemblyName);
46
- return mapCoords({
47
- ...h,
48
- refName: (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(h.refName)) !== null && _a !== void 0 ? _a : h.refName,
49
- });
50
41
  })
51
42
  .filter(notEmpty)
52
- .map(({ left, width }, idx) => (React.createElement("div", { key: `${left}_${width}_${idx}`, className: classes.highlight, style: {
43
+ .map(({ left, width }, idx) => (React.createElement("div", {
44
+ /* biome-ignore lint/suspicious/noArrayIndexKey: */
45
+ key: `${left}_${width}_${idx}`, className: classes.highlight, style: {
53
46
  width: width,
54
47
  left: left,
55
48
  } })));