@jbrowse/core 2.3.3 → 2.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ui/Dialog.js CHANGED
@@ -7,8 +7,11 @@ const react_1 = __importDefault(require("react"));
7
7
  const material_1 = require("@mui/material");
8
8
  const mobx_react_1 = require("mobx-react");
9
9
  const mui_1 = require("tss-react/mui");
10
+ const react_error_boundary_1 = require("react-error-boundary");
10
11
  // icons
11
12
  const Close_1 = __importDefault(require("@mui/icons-material/Close"));
13
+ // locals
14
+ const ErrorMessage_1 = __importDefault(require("./ErrorMessage"));
12
15
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
13
16
  closeButton: {
14
17
  position: 'absolute',
@@ -17,6 +20,10 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
17
20
  color: theme.palette.grey[500],
18
21
  },
19
22
  }));
23
+ function DialogError({ error }) {
24
+ return (react_1.default.createElement("div", { style: { width: 800, margin: 40 } },
25
+ react_1.default.createElement(ErrorMessage_1.default, { error: error })));
26
+ }
20
27
  function JBrowseDialog(props) {
21
28
  const { classes } = useStyles();
22
29
  const { title, children, onClose } = props;
@@ -30,6 +37,6 @@ function JBrowseDialog(props) {
30
37
  } },
31
38
  react_1.default.createElement(Close_1.default, null))) : null),
32
39
  react_1.default.createElement(material_1.Divider, null),
33
- children)));
40
+ react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: DialogError }, children))));
34
41
  }
35
42
  exports.default = (0, mobx_react_1.observer)(JBrowseDialog);
@@ -33,9 +33,6 @@ const mobx_react_1 = require("mobx-react");
33
33
  const ArrowDropDown_1 = __importDefault(require("@mui/icons-material/ArrowDropDown"));
34
34
  const Menu_1 = __importDefault(require("./Menu"));
35
35
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
36
- root: {
37
- display: 'flex',
38
- },
39
36
  buttonRoot: {
40
37
  '&:hover': {
41
38
  backgroundColor: (0, material_1.alpha)(theme.palette.primary.contrastText, theme.palette.action.hoverOpacity),
@@ -59,7 +56,7 @@ function DropDownMenu({ menuTitle, session, menuItems, }) {
59
56
  function handleClose() {
60
57
  setOpen(false);
61
58
  }
62
- return (react_1.default.createElement("div", { className: classes.root },
59
+ return (react_1.default.createElement(react_1.default.Fragment, null,
63
60
  react_1.default.createElement(material_1.Button, { ref: anchorEl, onClick: handleToggle, color: "inherit", "data-testid": "dropDownMenuButton", classes: { root: classes.buttonRoot } },
64
61
  menuTitle,
65
62
  react_1.default.createElement(ArrowDropDown_1.default, null)),
@@ -88,7 +88,7 @@ const EditableTypography = react_1.default.forwardRef((props, ref) => {
88
88
  setBlur(true);
89
89
  }
90
90
  }, onBlur: () => {
91
- setValue(editedValue || '');
91
+ setValue(editedValue || value || '');
92
92
  setEditedValue(undefined);
93
93
  } })));
94
94
  });
package/ui/Menu.js CHANGED
@@ -245,7 +245,15 @@ const MenuPage = react_1.default.forwardRef((props, ref) => {
245
245
  });
246
246
  function Menu(props) {
247
247
  const { open, onClose, menuItems, onMenuItemClick, ...other } = props;
248
- return (react_1.default.createElement(material_1.Popover, { transitionDuration: 0, open: open, onClose: onClose, BackdropProps: { invisible: true }, ...other },
248
+ return (react_1.default.createElement(material_1.Popover, { open: open, onClose: onClose, BackdropProps: { invisible: true }, anchorOrigin: {
249
+ vertical: 'bottom',
250
+ horizontal: 'right',
251
+ ...other.anchorOrigin,
252
+ }, transformOrigin: {
253
+ vertical: 'top',
254
+ horizontal: 'left',
255
+ ...other.transformOrigin,
256
+ }, ...other },
249
257
  react_1.default.createElement(MenuPage, { open: open, onClose: onClose, menuItems: menuItems, onMenuItemClick: onMenuItemClick, top: true })));
250
258
  }
251
259
  exports.default = Menu;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export declare function useResizeBar(): {
3
+ ref: React.RefObject<HTMLDivElement>;
4
+ scrollLeft: number;
5
+ };
6
+ export default function ResizeBar({ widths, setWidths, checkbox, scrollLeft, }: {
7
+ widths: number[];
8
+ setWidths: (arg: number[]) => void;
9
+ checkbox?: boolean;
10
+ scrollLeft?: number;
11
+ }): JSX.Element;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.useResizeBar = void 0;
30
+ const react_1 = __importStar(require("react"));
31
+ const mui_1 = require("tss-react/mui");
32
+ // locals
33
+ const ResizeHandle_1 = __importDefault(require("./ResizeHandle"));
34
+ const useStyles = (0, mui_1.makeStyles)()({
35
+ resizeBar: {
36
+ background: 'lightgrey',
37
+ height: 12,
38
+ position: 'relative',
39
+ overflow: 'hidden',
40
+ },
41
+ tick: {
42
+ position: 'absolute',
43
+ height: '100%',
44
+ pointerEvents: 'none',
45
+ background: 'black',
46
+ width: 1,
47
+ },
48
+ hiddenTick: {
49
+ position: 'absolute',
50
+ height: '100%',
51
+ background: 'lightgrey',
52
+ width: 5,
53
+ },
54
+ });
55
+ function useResizeBar() {
56
+ const ref = (0, react_1.useRef)(null);
57
+ const [scrollLeft, setScrollLeft] = (0, react_1.useState)(0);
58
+ (0, react_1.useEffect)(() => {
59
+ const timer = setInterval(() => {
60
+ var _a;
61
+ const elt = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.querySelector('.MuiDataGrid-virtualScroller');
62
+ if (elt) {
63
+ setScrollLeft(elt.scrollLeft);
64
+ }
65
+ }, 100);
66
+ return () => {
67
+ clearInterval(timer);
68
+ };
69
+ }, []);
70
+ return { ref, scrollLeft };
71
+ }
72
+ exports.useResizeBar = useResizeBar;
73
+ function Tick({ left, scrollLeft, idx, onDrag, }) {
74
+ const { classes } = useStyles();
75
+ const cb = (0, react_1.useCallback)((d) => {
76
+ onDrag(d, idx);
77
+ }, [idx, onDrag]);
78
+ // has an invisible wider than tick mark (1px) clickable area (5px)
79
+ return (react_1.default.createElement(react_1.default.Fragment, null,
80
+ react_1.default.createElement(ResizeHandle_1.default, { onDrag: cb, vertical: true, className: classes.hiddenTick, style: { left: left - scrollLeft - 2.5 } }),
81
+ react_1.default.createElement("div", { style: { left: left - scrollLeft }, className: classes.tick })));
82
+ }
83
+ function ResizeBar({ widths, setWidths, checkbox, scrollLeft = 0, }) {
84
+ const { classes } = useStyles();
85
+ const offsets = [];
86
+ widths.reduce((a, b, i) => (offsets[i] = a + b), checkbox ? 52 : 0);
87
+ const onDrag = (0, react_1.useCallback)((distance, idx) => {
88
+ const newWidths = [...widths];
89
+ // mui doesn't allow columns smaller than 50
90
+ newWidths[idx] = Math.max(newWidths[idx] + distance, 50);
91
+ setWidths(newWidths);
92
+ }, [widths, setWidths]);
93
+ return (react_1.default.createElement("div", { className: classes.resizeBar }, offsets.map((left, i) => (react_1.default.createElement(Tick, { key: i, left: i === offsets.length - 1 ? left - 3 : left, onDrag: onDrag, idx: i, scrollLeft: scrollLeft })))));
94
+ }
95
+ exports.default = ResizeBar;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  declare function ResizeHandle({ onDrag, vertical, flexbox, className: originalClassName, ...props }: {
3
- onDrag: (arg: number) => number;
3
+ onDrag: (arg: number) => number | void;
4
4
  vertical?: boolean;
5
5
  flexbox?: boolean;
6
6
  className?: string;
@@ -89,6 +89,6 @@ function ResizeHandle({ onDrag, vertical = false, flexbox = false, className: or
89
89
  event.preventDefault();
90
90
  prevPos.current = vertical ? event.clientX : event.clientY;
91
91
  setMouseDragging(true);
92
- }, role: "presentation", className: cx(className, originalClassName), ...props }));
92
+ }, className: cx(className, originalClassName), ...props }));
93
93
  }
94
94
  exports.default = ResizeHandle;
@@ -65,7 +65,7 @@ function SanitizedHTML({ html }) {
65
65
  }
66
66
  });
67
67
  }
68
- return (react_1.default.createElement("div", {
68
+ return (react_1.default.createElement("span", {
69
69
  // eslint-disable-next-line react/no-danger
70
70
  dangerouslySetInnerHTML: {
71
71
  __html: dompurify_1.default.sanitize(value),
package/ui/theme.d.ts CHANGED
@@ -116,6 +116,16 @@ export declare function createJBrowseDefaultProps(): {
116
116
  size: "small";
117
117
  };
118
118
  };
119
+ MuiPopover: {
120
+ defaultProps: {
121
+ transitionDuration: number;
122
+ };
123
+ };
124
+ MuiMenu: {
125
+ defaultProps: {
126
+ transitionDuration: number;
127
+ };
128
+ };
119
129
  MuiMenuList: {
120
130
  defaultProps: {
121
131
  dense: boolean;
package/ui/theme.js CHANGED
@@ -102,6 +102,16 @@ function createJBrowseDefaultProps( /* palette: PaletteOptions = {} */) {
102
102
  size: 'small',
103
103
  },
104
104
  },
105
+ MuiPopover: {
106
+ defaultProps: {
107
+ transitionDuration: 0,
108
+ },
109
+ },
110
+ MuiMenu: {
111
+ defaultProps: {
112
+ transitionDuration: 0,
113
+ },
114
+ },
105
115
  MuiMenuList: {
106
116
  defaultProps: {
107
117
  dense: true,
package/util/index.d.ts CHANGED
@@ -1,22 +1,22 @@
1
1
  import PluginManager from '../PluginManager';
2
2
  import { IAnyStateTreeNode, IStateTreeNode } from 'mobx-state-tree';
3
3
  import { IReactionPublic, IReactionOptions } from 'mobx';
4
- import SimpleFeature, { Feature, isFeature } from './simpleFeature';
4
+ import SimpleFeature, { Feature, SimpleFeatureSerialized, isFeature } from './simpleFeature';
5
5
  import { AssemblyManager, Region, TypeTestedByPredicate } from './types';
6
6
  import { BaseBlock } from './blockTypes';
7
- export type { Feature };
8
7
  export * from './types';
9
8
  export * from './aborting';
10
9
  export * from './when';
11
10
  export * from './range';
12
11
  export * from './dedupe';
13
12
  export { SimpleFeature, isFeature };
13
+ export type { Feature, SimpleFeatureSerialized };
14
14
  export * from './offscreenCanvasPonyfill';
15
15
  export * from './offscreenCanvasUtils';
16
16
  export declare const inDevelopment: boolean;
17
17
  export declare const inProduction: boolean;
18
18
  export declare function useDebounce<T>(value: T, delay: number): T;
19
- export declare function useDebouncedCallback<A extends any[]>(callback: (...args: A) => void, wait?: number): (...args: A) => void;
19
+ export declare function useDebouncedCallback<T>(callback: (...args: T[]) => void, wait?: number): (...args: T[]) => void;
20
20
  /** find the first node in the hierarchy that matches the given predicate */
21
21
  export declare function findParentThat(node: IAnyStateTreeNode, predicate: (thing: IAnyStateTreeNode) => boolean): IAnyStateTreeNode;
22
22
  export declare function springAnimate(fromValue: number, toValue: number, setValue: (value: number) => void, onFinish?: () => void, precision?: number, tension?: number, friction?: number): (() => void)[];
@@ -153,7 +153,7 @@ export declare function bpSpanPx(leftBp: number, rightBp: number, region: {
153
153
  end: number;
154
154
  reversed?: boolean;
155
155
  }, bpPerPx: number): [number, number];
156
- export declare function iterMap<T, U>(iterable: Iterable<T>, func: (item: T) => U, sizeHint?: number): U[];
156
+ export declare function iterMap<T, U>(iter: Iterable<T>, func: (arg: T) => U, sizeHint?: number): U[];
157
157
  /**
158
158
  * Returns the index of the last element in the array where predicate is true,
159
159
  * and -1 otherwise.
@@ -280,8 +280,8 @@ export declare const defaultCodonTable: {
280
280
  GGT: string;
281
281
  };
282
282
  /**
283
- * take CodonTable above and generate larger codon table that includes
284
- * all permutations of upper and lower case nucleotides
283
+ * take CodonTable above and generate larger codon table that includes all
284
+ * permutations of upper and lower case nucleotides
285
285
  */
286
286
  export declare function generateCodonTable(table: any): {
287
287
  [key: string]: string;
@@ -337,7 +337,13 @@ export declare function getUriLink(value: {
337
337
  baseUri?: string;
338
338
  }): string;
339
339
  export declare function getStr(obj: unknown): string;
340
- export declare function measureGridWidth(elements: string[]): number;
340
+ export declare function measureGridWidth(elements: string[], args?: {
341
+ minWidth?: number;
342
+ fontSize?: number;
343
+ maxWidth?: number;
344
+ padding?: number;
345
+ stripHTML?: boolean;
346
+ }): number;
341
347
  export declare function getEnv(obj: any): {
342
348
  pluginManager: PluginManager;
343
349
  };
package/util/index.js CHANGED
@@ -504,10 +504,10 @@ function bpSpanPx(leftBp, rightBp, region, bpPerPx) {
504
504
  }
505
505
  exports.bpSpanPx = bpSpanPx;
506
506
  // do an array map of an iterable
507
- function iterMap(iterable, func, sizeHint) {
507
+ function iterMap(iter, func, sizeHint) {
508
508
  const results = sizeHint ? new Array(sizeHint) : [];
509
509
  let counter = 0;
510
- for (const item of iterable) {
510
+ for (const item of iter) {
511
511
  results[counter] = func(item);
512
512
  counter += 1;
513
513
  }
@@ -664,8 +664,10 @@ function stringify({ refName, coord, oob, }) {
664
664
  : '';
665
665
  }
666
666
  exports.stringify = stringify;
667
- // this is recommended in a later comment in https://github.com/electron/electron/issues/2288
668
- // for detecting electron in a renderer process, which is the one that has node enabled for us
667
+ // this is recommended in a later comment in
668
+ // https://github.com/electron/electron/issues/2288 for detecting electron in a
669
+ // renderer process, which is the one that has node enabled for us
670
+ //
669
671
  // const isElectron = process.versions.electron
670
672
  // const i2 = process.versions.hasOwnProperty('electron')
671
673
  exports.isElectron = /electron/i.test(typeof navigator !== 'undefined' ? navigator.userAgent : '');
@@ -829,8 +831,8 @@ exports.defaultCodonTable = {
829
831
  GGT: 'G',
830
832
  };
831
833
  /**
832
- * take CodonTable above and generate larger codon table that includes
833
- * all permutations of upper and lower case nucleotides
834
+ * take CodonTable above and generate larger codon table that includes all
835
+ * permutations of upper and lower case nucleotides
834
836
  */
835
837
  function generateCodonTable(table) {
836
838
  const tempCodonTable = {};
@@ -1002,9 +1004,18 @@ function getStr(obj) {
1002
1004
  : String(obj);
1003
1005
  }
1004
1006
  exports.getStr = getStr;
1007
+ // tries to measure grid width without HTML tags included
1008
+ function coarseStripHTML(s) {
1009
+ return s.replace(/(<([^>]+)>)/gi, '');
1010
+ }
1005
1011
  // heuristic measurement for a column of a @mui/x-data-grid, pass in values from a column
1006
- function measureGridWidth(elements) {
1007
- return max(elements.map(element => Math.min(Math.max(measureText(getStr(element), 14) + 50, 80), 1000)));
1012
+ function measureGridWidth(elements, args) {
1013
+ const { padding = 30, minWidth = 80, fontSize = 12, maxWidth = 1000, stripHTML = false, } = args || {};
1014
+ return max(elements
1015
+ .map(element => getStr(element))
1016
+ .map(str => (stripHTML ? coarseStripHTML(str) : str))
1017
+ .map(str => measureText(str, fontSize))
1018
+ .map(n => Math.min(Math.max(n + padding, minWidth), maxWidth)));
1008
1019
  }
1009
1020
  exports.measureGridWidth = measureGridWidth;
1010
1021
  function getEnv(obj) {