@jbrowse/core 4.0.3 → 4.0.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.
@@ -1,9 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
2
3
  import Attributes from "./Attributes.js";
3
4
  import BasicValue from "./BasicValue.js";
4
5
  import FieldName from "./FieldName.js";
5
6
  import { isObject } from "../../util/index.js";
6
7
  import { makeStyles } from "../../util/tss-react/index.js";
8
+ const MAX_ARRAY_LENGTH = 100;
7
9
  const useStyles = makeStyles()(theme => ({
8
10
  field: {
9
11
  display: 'flex',
@@ -20,6 +22,9 @@ const useStyles = makeStyles()(theme => ({
20
22
  }));
21
23
  export default function ArrayValue({ name, value, description, formatter, prefix = [], }) {
22
24
  const { classes } = useStyles();
25
+ const [showAll, setShowAll] = useState(false);
26
+ const needsTruncation = value.length > MAX_ARRAY_LENGTH;
27
+ const displayedValues = needsTruncation && !showAll ? value.slice(0, MAX_ARRAY_LENGTH) : value;
23
28
  if (value.length === 1) {
24
29
  return isObject(value[0]) ? (_jsx(Attributes, { formatter: formatter, attributes: value[0], prefix: [...prefix, name] })) : (_jsxs("div", { className: classes.field, children: [_jsx(FieldName, { prefix: prefix, description: description, name: name }), _jsx(BasicValue, { value: formatter ? formatter(value[0], name) : value[0] })] }));
25
30
  }
@@ -27,6 +32,10 @@ export default function ArrayValue({ name, value, description, formatter, prefix
27
32
  return (_jsx(_Fragment, { children: value.map((val, i) => (_jsx(Attributes, { formatter: formatter, attributes: val, prefix: [...prefix, `${name}-${i}`] }, `${JSON.stringify(val)}-${i}`))) }));
28
33
  }
29
34
  else {
30
- return (_jsxs("div", { className: classes.field, children: [_jsx(FieldName, { prefix: prefix, description: description, name: name }), value.map((val, i) => (_jsx("div", { className: classes.fieldSubvalue, children: _jsx(BasicValue, { value: formatter ? formatter(val, name) : val }) }, `${JSON.stringify(val)}-${i}`)))] }));
35
+ return (_jsxs("div", { className: classes.field, children: [_jsx(FieldName, { prefix: prefix, description: description, name: name }), displayedValues.map((val, i) => (_jsx("div", { className: classes.fieldSubvalue, children: _jsx(BasicValue, { value: formatter ? formatter(val, name) : val }) }, `${JSON.stringify(val)}-${i}`))), needsTruncation ? (_jsx("button", { type: "button", onClick: () => {
36
+ setShowAll(val => !val);
37
+ }, children: showAll
38
+ ? 'Show less'
39
+ : `Showing ${MAX_ARRAY_LENGTH} of ${value.length}. Show all...` })) : null] }));
31
40
  }
32
41
  }
@@ -52,6 +52,7 @@ export declare const BaseDisplay: import("@jbrowse/mobx-state-tree").IModelType<
52
52
  }> | null;
53
53
  readonly adapterConfig: any;
54
54
  readonly parentTrack: import("../../util/index.ts").AbstractTrackModel;
55
+ readonly isMinimized: boolean;
55
56
  readonly parentDisplay: any;
56
57
  readonly effectiveRpcDriverName: any;
57
58
  } & {
@@ -108,6 +109,7 @@ export declare const BaseDisplay: import("@jbrowse/mobx-state-tree").IModelType<
108
109
  }> | null;
109
110
  readonly adapterConfig: any;
110
111
  readonly parentTrack: import("../../util/index.ts").AbstractTrackModel;
112
+ readonly isMinimized: boolean;
111
113
  readonly parentDisplay: any;
112
114
  readonly effectiveRpcDriverName: any;
113
115
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -161,6 +163,7 @@ export declare const BaseDisplay: import("@jbrowse/mobx-state-tree").IModelType<
161
163
  }> | null;
162
164
  readonly adapterConfig: any;
163
165
  readonly parentTrack: import("../../util/index.ts").AbstractTrackModel;
166
+ readonly isMinimized: boolean;
164
167
  readonly parentDisplay: any;
165
168
  readonly effectiveRpcDriverName: any;
166
169
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -30,6 +30,9 @@ function stateModelFactory() {
30
30
  get parentTrack() {
31
31
  return getContainingTrack(self);
32
32
  },
33
+ get isMinimized() {
34
+ return this.parentTrack.minimized;
35
+ },
33
36
  get parentDisplay() {
34
37
  try {
35
38
  const parent = getParent(self);
@@ -62,7 +65,7 @@ function stateModelFactory() {
62
65
  renderProps() {
63
66
  return {
64
67
  ...getParentRenderProps(self),
65
- notReady: getContainingView(self).minimized,
68
+ notReady: self.isMinimized || getContainingView(self).minimized,
66
69
  rpcDriverName: self.effectiveRpcDriverName,
67
70
  };
68
71
  },
@@ -5,9 +5,16 @@ import { Divider, ListItemIcon, ListItemText, ListSubheader, Menu, MenuItem, } f
5
5
  import CascadingMenuHelpIconButton from "./CascadingMenuHelpIconButton.js";
6
6
  import HoverMenu from "./HoverMenu.js";
7
7
  import { MenuItemEndDecoration } from "./MenuItems.js";
8
+ function labelToTestId(label) {
9
+ if (typeof label === 'string') {
10
+ return label.toLowerCase().replace(/\s+/g, '_');
11
+ }
12
+ return undefined;
13
+ }
8
14
  function CascadingSubmenu({ title, Icon, inset, menuItems, onMenuItemClick, closeAfterItemClick, onCloseRoot, isOpen, onOpen, onClose, }) {
9
15
  const [anchorEl, setAnchorEl] = useState(null);
10
- return (_jsxs(_Fragment, { children: [_jsxs(MenuItem, { ref: setAnchorEl, onMouseOver: onOpen, onFocus: onOpen, onClick: onOpen, children: [Icon ? (_jsx(ListItemIcon, { children: _jsx(Icon, {}) })) : null, _jsx(ListItemText, { primary: title, inset: inset }), _jsx(ChevronRight, {})] }), _jsx(HoverMenu, { open: isOpen, anchorEl: anchorEl, onClose: onClose, anchorOrigin: { vertical: 'top', horizontal: 'right' }, transformOrigin: { vertical: 'top', horizontal: 'left' }, children: _jsx(CascadingMenuList, { closeAfterItemClick: closeAfterItemClick, onMenuItemClick: onMenuItemClick, menuItems: menuItems, onCloseRoot: onCloseRoot }) })] }));
16
+ const testId = labelToTestId(title);
17
+ return (_jsxs(_Fragment, { children: [_jsxs(MenuItem, { ref: setAnchorEl, "data-testid": testId ? `cascading-submenu-${testId}` : undefined, onMouseOver: onOpen, onFocus: onOpen, onClick: onOpen, children: [Icon ? (_jsx(ListItemIcon, { children: _jsx(Icon, {}) })) : null, _jsx(ListItemText, { primary: title, inset: inset }), _jsx(ChevronRight, {})] }), _jsx(HoverMenu, { open: isOpen, anchorEl: anchorEl, onClose: onClose, anchorOrigin: { vertical: 'top', horizontal: 'right' }, transformOrigin: { vertical: 'top', horizontal: 'left' }, children: _jsx(CascadingMenuList, { closeAfterItemClick: closeAfterItemClick, onMenuItemClick: onMenuItemClick, menuItems: menuItems, onCloseRoot: onCloseRoot }) })] }));
11
18
  }
12
19
  function CascadingMenuList({ onMenuItemClick, closeAfterItemClick, menuItems, onCloseRoot, }) {
13
20
  const [openSubmenuIdx, setOpenSubmenuIdx] = useState();
@@ -34,7 +41,8 @@ function CascadingMenuList({ onMenuItemClick, closeAfterItemClick, menuItems, on
34
41
  const actionItem = item;
35
42
  const helpText = actionItem.helpText;
36
43
  const isCheckOrRadio = actionItem.type === 'checkbox' || actionItem.type === 'radio';
37
- return (_jsxs(MenuItem, { disabled: Boolean(actionItem.disabled), onClick: event => {
44
+ const itemTestId = labelToTestId(actionItem.label);
45
+ return (_jsxs(MenuItem, { "data-testid": itemTestId ? `cascading-menuitem-${itemTestId}` : undefined, disabled: Boolean(actionItem.disabled), onClick: event => {
38
46
  if (closeAfterItemClick) {
39
47
  onCloseRoot();
40
48
  }
@@ -1,4 +1,4 @@
1
1
  import * as React from 'react';
2
2
  import type { MenuProps } from '@mui/material';
3
- declare const HoverMenu: React.ComponentType<MenuProps>;
3
+ declare const HoverMenu: React.ForwardRefExoticComponent<Omit<MenuProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
4
4
  export default HoverMenu;
@@ -1 +1,2 @@
1
+ export declare function createElementId(): string;
1
2
  export declare const ElementId: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
@@ -1,3 +1,6 @@
1
1
  import { types } from '@jbrowse/mobx-state-tree';
2
2
  import { nanoid } from "../nanoid.js";
3
- export const ElementId = types.optional(types.identifier, () => nanoid(10));
3
+ export function createElementId() {
4
+ return nanoid(10);
5
+ }
6
+ export const ElementId = types.optional(types.identifier, createElementId);
@@ -190,6 +190,7 @@ export interface AbstractTrackModel {
190
190
  configuration: AnyConfigurationModel & {
191
191
  displays: Display[];
192
192
  };
193
+ minimized: boolean;
193
194
  }
194
195
  export declare function isTrackModel(thing: unknown): thing is AbstractTrackModel;
195
196
  export interface AbstractDisplayModel {
@@ -104,4 +104,4 @@ export declare const FileLocation: import("@jbrowse/mobx-state-tree").ISnapshotP
104
104
  authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
105
105
  }, {}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
106
106
  }>> & import("@jbrowse/mobx-state-tree/dist/internal").NonEmptyObject)>, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>;
107
- export { ElementId } from './ElementId.ts';
107
+ export { ElementId, createElementId } from './ElementId.ts';
@@ -65,4 +65,4 @@ export const FileLocation = types.snapshotProcessor(types.union(LocalPathLocatio
65
65
  return snap;
66
66
  },
67
67
  });
68
- export { ElementId } from "./ElementId.js";
68
+ export { ElementId, createElementId } from "./ElementId.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/core",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
4
4
  "type": "module",
5
5
  "description": "JBrowse 2 core libraries used by plugins",
6
6
  "keywords": [
@@ -398,10 +398,6 @@
398
398
  "types": "./esm/util/mst-reflection.d.ts",
399
399
  "import": "./esm/util/mst-reflection.js"
400
400
  },
401
- "./util/nanoid": {
402
- "types": "./esm/util/nanoid.d.ts",
403
- "import": "./esm/util/nanoid.js"
404
- },
405
401
  "./util/offscreenCanvasPonyfill": {
406
402
  "types": "./esm/util/offscreenCanvasPonyfill.d.ts",
407
403
  "import": "./esm/util/offscreenCanvasPonyfill.js"
@@ -457,6 +453,10 @@
457
453
  "./ui/ReturnToImportFormDialog": {
458
454
  "types": "./esm/ui/ReturnToImportFormDialog.d.ts",
459
455
  "import": "./esm/ui/ReturnToImportFormDialog.js"
456
+ },
457
+ "./util/nanoid": {
458
+ "types": "./esm/util/nanoid.d.ts",
459
+ "import": "./esm/util/nanoid.js"
460
460
  }
461
461
  },
462
462
  "files": [
@@ -468,8 +468,8 @@
468
468
  "@emotion/utils": "^1.4.2",
469
469
  "@floating-ui/react": "^0.27.16",
470
470
  "@gmod/abortable-promise-cache": "^3.0.4",
471
- "@gmod/bgzf-filehandle": "^6.0.9",
472
- "@gmod/http-range-fetcher": "^5.0.6",
471
+ "@gmod/bgzf-filehandle": "^6.0.10",
472
+ "@gmod/http-range-fetcher": "^5.0.7",
473
473
  "@jbrowse/jexl": "^3.0.1",
474
474
  "@jbrowse/mobx-state-tree": "^5.5.0",
475
475
  "@jbrowse/quick-lru": "^7.3.5",
@@ -478,7 +478,8 @@
478
478
  "@mui/material": "^7.3.6",
479
479
  "@mui/system": "^7.3.6",
480
480
  "@mui/types": "^7.4.9",
481
- "@mui/x-data-grid": "^8.23.0",
481
+ "@mui/x-data-grid": "^8.25.0",
482
+ "@types/file-saver-es": "^2.0.3",
482
483
  "canvas-sequencer-ts": "^3.1.3",
483
484
  "canvas2svg": "^1.0.16",
484
485
  "colord": "^2.9.3",
@@ -488,7 +489,6 @@
488
489
  "dompurify": "^3.3.1",
489
490
  "escape-html": "^1.0.3",
490
491
  "fast-deep-equal": "^3.1.3",
491
- "@types/file-saver-es": "^2.0.3",
492
492
  "file-saver-es": "^2.0.5",
493
493
  "generic-filehandle2": "^2.0.18",
494
494
  "librpc-web-mod": "^2.1.1",