@jbrowse/plugin-linear-comparative-view 3.5.1 → 3.6.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 (69) hide show
  1. package/dist/LinearComparativeDisplay/stateModelFactory.d.ts +4 -0
  2. package/dist/LinearComparativeDisplay/stateModelFactory.js +14 -7
  3. package/dist/LinearComparativeView/components/Rubberband.d.ts +2 -2
  4. package/dist/LinearComparativeView/components/Rubberband.js +16 -154
  5. package/dist/LinearComparativeView/components/RubberbandSpan.d.ts +15 -0
  6. package/dist/LinearComparativeView/components/RubberbandSpan.js +38 -0
  7. package/dist/LinearComparativeView/components/RubberbandTooltip.d.ts +5 -0
  8. package/dist/LinearComparativeView/components/RubberbandTooltip.js +20 -0
  9. package/dist/LinearComparativeView/components/useRangeSelect.d.ts +59 -0
  10. package/dist/LinearComparativeView/components/useRangeSelect.js +128 -0
  11. package/dist/LinearComparativeView/components/util.d.ts +4 -0
  12. package/dist/LinearComparativeView/components/util.js +6 -0
  13. package/dist/LinearSyntenyDisplay/components/BlockError.d.ts +3 -0
  14. package/dist/LinearSyntenyDisplay/components/BlockError.js +16 -0
  15. package/dist/LinearSyntenyDisplay/components/BlockMessage.d.ts +3 -0
  16. package/dist/LinearSyntenyDisplay/components/BlockMessage.js +24 -0
  17. package/dist/LinearSyntenyDisplay/components/Component.js +11 -50
  18. package/dist/LinearSyntenyDisplay/components/LoadingMessage.d.ts +3 -0
  19. package/dist/LinearSyntenyDisplay/components/LoadingMessage.js +21 -0
  20. package/dist/LinearSyntenyDisplay/model.d.ts +4 -0
  21. package/dist/LinearSyntenyView/components/ImportForm/ImportSyntenyOpenCustomTrack.js +2 -51
  22. package/dist/LinearSyntenyView/components/ImportForm/selectors/AnchorsSelector.d.ts +3 -0
  23. package/dist/LinearSyntenyView/components/ImportForm/selectors/AnchorsSelector.js +13 -0
  24. package/dist/LinearSyntenyView/components/ImportForm/selectors/PifGzSelector.d.ts +3 -0
  25. package/dist/LinearSyntenyView/components/ImportForm/selectors/PifGzSelector.js +13 -0
  26. package/dist/LinearSyntenyView/components/ImportForm/selectors/SelectorTypes.d.ts +19 -0
  27. package/dist/LinearSyntenyView/components/ImportForm/selectors/SelectorTypes.js +10 -0
  28. package/dist/LinearSyntenyView/components/ImportForm/selectors/StandardFormatSelector.d.ts +3 -0
  29. package/dist/LinearSyntenyView/components/ImportForm/selectors/StandardFormatSelector.js +20 -0
  30. package/dist/LinearSyntenyView/components/ImportForm/selectors/SwapAssemblies.d.ts +13 -0
  31. package/dist/LinearSyntenyView/components/ImportForm/selectors/SwapAssemblies.js +32 -0
  32. package/dist/LinearSyntenyView/components/ImportForm/selectors/index.d.ts +4 -0
  33. package/dist/LinearSyntenyView/components/ImportForm/selectors/index.js +27 -0
  34. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +1 -1
  35. package/esm/LinearComparativeDisplay/stateModelFactory.d.ts +4 -0
  36. package/esm/LinearComparativeDisplay/stateModelFactory.js +14 -7
  37. package/esm/LinearComparativeView/components/Rubberband.d.ts +2 -2
  38. package/esm/LinearComparativeView/components/Rubberband.js +17 -155
  39. package/esm/LinearComparativeView/components/RubberbandSpan.d.ts +15 -0
  40. package/esm/LinearComparativeView/components/RubberbandSpan.js +32 -0
  41. package/esm/LinearComparativeView/components/RubberbandTooltip.d.ts +5 -0
  42. package/esm/LinearComparativeView/components/RubberbandTooltip.js +17 -0
  43. package/esm/LinearComparativeView/components/useRangeSelect.d.ts +59 -0
  44. package/esm/LinearComparativeView/components/useRangeSelect.js +125 -0
  45. package/esm/LinearComparativeView/components/util.d.ts +4 -0
  46. package/esm/LinearComparativeView/components/util.js +3 -0
  47. package/esm/LinearSyntenyDisplay/components/BlockError.d.ts +3 -0
  48. package/esm/LinearSyntenyDisplay/components/BlockError.js +13 -0
  49. package/esm/LinearSyntenyDisplay/components/BlockMessage.d.ts +3 -0
  50. package/esm/LinearSyntenyDisplay/components/BlockMessage.js +21 -0
  51. package/esm/LinearSyntenyDisplay/components/Component.js +9 -48
  52. package/esm/LinearSyntenyDisplay/components/LoadingMessage.d.ts +3 -0
  53. package/esm/LinearSyntenyDisplay/components/LoadingMessage.js +18 -0
  54. package/esm/LinearSyntenyDisplay/model.d.ts +4 -0
  55. package/esm/LinearSyntenyView/components/ImportForm/ImportSyntenyOpenCustomTrack.js +3 -49
  56. package/esm/LinearSyntenyView/components/ImportForm/selectors/AnchorsSelector.d.ts +3 -0
  57. package/esm/LinearSyntenyView/components/ImportForm/selectors/AnchorsSelector.js +8 -0
  58. package/esm/LinearSyntenyView/components/ImportForm/selectors/PifGzSelector.d.ts +3 -0
  59. package/esm/LinearSyntenyView/components/ImportForm/selectors/PifGzSelector.js +8 -0
  60. package/esm/LinearSyntenyView/components/ImportForm/selectors/SelectorTypes.d.ts +19 -0
  61. package/esm/LinearSyntenyView/components/ImportForm/selectors/SelectorTypes.js +7 -0
  62. package/esm/LinearSyntenyView/components/ImportForm/selectors/StandardFormatSelector.d.ts +3 -0
  63. package/esm/LinearSyntenyView/components/ImportForm/selectors/StandardFormatSelector.js +15 -0
  64. package/esm/LinearSyntenyView/components/ImportForm/selectors/SwapAssemblies.d.ts +13 -0
  65. package/esm/LinearSyntenyView/components/ImportForm/selectors/SwapAssemblies.js +27 -0
  66. package/esm/LinearSyntenyView/components/ImportForm/selectors/index.d.ts +4 -0
  67. package/esm/LinearSyntenyView/components/ImportForm/selectors/index.js +4 -0
  68. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +1 -1
  69. package/package.json +5 -5
@@ -70,6 +70,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
70
70
  renderInProgress: string | undefined;
71
71
  features: Feature[] | undefined;
72
72
  message: string | undefined;
73
+ loadingStatus: string | undefined;
73
74
  } & {
74
75
  readonly level: number;
75
76
  readonly height: number;
@@ -152,6 +153,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
152
153
  renderInProgress: string | undefined;
153
154
  features: Feature[] | undefined;
154
155
  message: string | undefined;
156
+ loadingStatus: string | undefined;
155
157
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
156
158
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
157
159
  type: import("mobx-state-tree").ISimpleType<string>;
@@ -221,12 +223,14 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
221
223
  renderInProgress: string | undefined;
222
224
  features: Feature[] | undefined;
223
225
  message: string | undefined;
226
+ loadingStatus: string | undefined;
224
227
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
225
228
  highResolutionScaling: number;
226
229
  };
227
230
  } & {
228
231
  setLoading(newStopToken: string): void;
229
232
  setMessage(messageText: string): void;
233
+ setLoadingStatus(messageText: string): void;
230
234
  setRendered(args?: {
231
235
  features: Feature[];
232
236
  }): void;
@@ -16,6 +16,7 @@ function stateModelFactory(configSchema) {
16
16
  renderInProgress: undefined,
17
17
  features: undefined,
18
18
  message: undefined,
19
+ loadingStatus: undefined,
19
20
  }))
20
21
  .views(self => ({
21
22
  get level() {
@@ -45,6 +46,9 @@ function stateModelFactory(configSchema) {
45
46
  self.error = undefined;
46
47
  stopToken = undefined;
47
48
  },
49
+ setLoadingStatus(messageText) {
50
+ self.loadingStatus = messageText;
51
+ },
48
52
  setRendered(args) {
49
53
  if (!args) {
50
54
  return;
@@ -110,6 +114,7 @@ function renderBlockData(self) {
110
114
  rpcManager,
111
115
  renderProps: {
112
116
  ...display.renderProps(),
117
+ model: display,
113
118
  level,
114
119
  view: parent,
115
120
  adapterConfig,
@@ -125,15 +130,17 @@ async function renderBlockEffect(props) {
125
130
  return;
126
131
  }
127
132
  const { rpcManager, renderProps } = props;
128
- const { sessionId, adapterConfig, level } = renderProps;
133
+ const { model, sessionId, adapterConfig, level } = renderProps;
129
134
  const view = renderProps.view.views[level];
130
- const features = (await rpcManager.call('getFeats', 'CoreGetFeatures', {
131
- regions: view.staticBlocks.contentBlocks,
132
- sessionId,
133
- adapterConfig,
134
- }));
135
135
  return {
136
- features: (0, util_1.dedupe)(features, f => f.id()),
136
+ features: (0, util_1.dedupe)((await rpcManager.call('getFeats', 'CoreGetFeatures', {
137
+ regions: view.staticBlocks.contentBlocks,
138
+ sessionId,
139
+ adapterConfig,
140
+ statusCallback: (arg) => {
141
+ model.setLoadingStatus(arg);
142
+ },
143
+ })), f => f.id()),
137
144
  };
138
145
  }
139
146
  exports.default = stateModelFactory;
@@ -1,7 +1,7 @@
1
1
  import type { LinearComparativeViewModel } from '../model';
2
2
  type LCV = LinearComparativeViewModel;
3
- declare const LinearComparativeRubberband: ({ model, ControlComponent, }: {
3
+ declare const Rubberband: ({ model, ControlComponent, }: {
4
4
  model: LCV;
5
5
  ControlComponent?: React.ReactElement;
6
6
  }) => import("react/jsx-runtime").JSX.Element;
7
- export default LinearComparativeRubberband;
7
+ export default Rubberband;
@@ -6,165 +6,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const jsx_runtime_1 = require("react/jsx-runtime");
7
7
  const react_1 = require("react");
8
8
  const ui_1 = require("@jbrowse/core/ui");
9
- const util_1 = require("@jbrowse/core/util");
10
- const material_1 = require("@mui/material");
11
- const mobx_1 = require("mobx");
12
9
  const mobx_react_1 = require("mobx-react");
13
10
  const mui_1 = require("tss-react/mui");
11
+ const RubberbandSpan_1 = __importDefault(require("./RubberbandSpan"));
14
12
  const VerticalGuide_1 = __importDefault(require("./VerticalGuide"));
15
- const useStyles = (0, mui_1.makeStyles)()(theme => {
16
- return {
17
- rubberband: {
18
- height: '100%',
19
- background: (0, material_1.alpha)(theme.palette.tertiary.main, 0.7),
20
- position: 'absolute',
21
- zIndex: 900,
22
- textAlign: 'center',
23
- overflow: 'hidden',
24
- },
25
- rubberbandControl: {
26
- cursor: 'crosshair',
27
- width: '100%',
28
- minHeight: 8,
29
- },
30
- rubberbandText: {
31
- color: theme.palette.tertiary.contrastText,
32
- },
33
- popover: {
34
- mouseEvents: 'none',
35
- cursor: 'crosshair',
36
- },
37
- paper: {
38
- paddingLeft: theme.spacing(1),
39
- paddingRight: theme.spacing(1),
40
- },
41
- };
13
+ const useRangeSelect_1 = require("./useRangeSelect");
14
+ const useStyles = (0, mui_1.makeStyles)()({
15
+ rubberbandControl: {
16
+ cursor: 'crosshair',
17
+ width: '100%',
18
+ minHeight: 8,
19
+ position: 'relative',
20
+ zIndex: 900,
21
+ },
42
22
  });
43
- const LinearComparativeRubberband = (0, mobx_react_1.observer)(function Rubberband({ model, ControlComponent = (0, jsx_runtime_1.jsx)("div", {}), }) {
44
- const [startX, setStartX] = (0, react_1.useState)();
45
- const [currentX, setCurrentX] = (0, react_1.useState)();
46
- const [anchorPosition, setAnchorPosition] = (0, react_1.useState)();
47
- const [guideX, setGuideX] = (0, react_1.useState)();
48
- const controlsRef = (0, react_1.useRef)(null);
49
- const rubberbandRef = (0, react_1.useRef)(null);
23
+ const Rubberband = (0, mobx_react_1.observer)(function ({ model, ControlComponent = (0, jsx_runtime_1.jsx)("div", {}), }) {
24
+ const ref = (0, react_1.useRef)(null);
50
25
  const { classes } = useStyles();
51
- const mouseDragging = startX !== undefined && anchorPosition === undefined;
52
- (0, react_1.useEffect)(() => {
53
- function computeOffsets(offsetX, view) {
54
- if (startX === undefined) {
55
- return;
56
- }
57
- let leftPx = startX;
58
- let rightPx = offsetX;
59
- if (rightPx < leftPx) {
60
- ;
61
- [leftPx, rightPx] = [rightPx, leftPx];
62
- }
63
- const leftOffset = view.pxToBp(leftPx);
64
- const rightOffset = view.pxToBp(rightPx);
65
- return { leftOffset, rightOffset };
66
- }
67
- function globalMouseMove(event) {
68
- if (controlsRef.current && mouseDragging) {
69
- const relativeX = event.clientX - controlsRef.current.getBoundingClientRect().left;
70
- setCurrentX(relativeX);
71
- }
72
- }
73
- function globalMouseUp(event) {
74
- if (startX !== undefined && controlsRef.current) {
75
- const { clientX, clientY } = event;
76
- const ref = controlsRef.current;
77
- const offsetX = clientX - ref.getBoundingClientRect().left;
78
- setAnchorPosition({
79
- offsetX,
80
- clientX,
81
- clientY,
82
- });
83
- (0, mobx_1.transaction)(() => {
84
- for (const view of model.views) {
85
- const args = computeOffsets(offsetX, view);
86
- if (args) {
87
- const { leftOffset, rightOffset } = args;
88
- view.setOffsets(leftOffset, rightOffset);
89
- }
90
- }
91
- });
92
- setGuideX(undefined);
93
- }
94
- }
95
- if (mouseDragging) {
96
- window.addEventListener('mousemove', globalMouseMove);
97
- window.addEventListener('mouseup', globalMouseUp);
98
- return () => {
99
- window.removeEventListener('mousemove', globalMouseMove);
100
- window.removeEventListener('mouseup', globalMouseUp);
101
- };
102
- }
103
- return () => { };
104
- }, [startX, mouseDragging, model]);
105
- (0, react_1.useEffect)(() => {
106
- if (!mouseDragging &&
107
- currentX !== undefined &&
108
- startX !== undefined &&
109
- Math.abs(currentX - startX) <= 3) {
110
- handleClose();
111
- }
112
- }, [mouseDragging, currentX, startX]);
113
- function mouseDown(event) {
114
- event.preventDefault();
115
- event.stopPropagation();
116
- const relativeX = event.clientX -
117
- event.target.getBoundingClientRect().left;
118
- setStartX(relativeX);
119
- setCurrentX(relativeX);
120
- }
121
- function mouseMove(event) {
122
- const target = event.target;
123
- setGuideX(event.clientX - target.getBoundingClientRect().left);
124
- }
125
- function mouseOut() {
126
- setGuideX(undefined);
127
- (0, mobx_1.transaction)(() => {
128
- for (const view of model.views) {
129
- view.setOffsets(undefined, undefined);
130
- }
131
- });
132
- }
133
- function handleClose() {
134
- setAnchorPosition(undefined);
135
- setStartX(undefined);
136
- setCurrentX(undefined);
137
- }
138
- const open = Boolean(anchorPosition);
139
- function handleMenuItemClick(_, callback) {
140
- callback();
141
- handleClose();
142
- }
143
- if (startX === undefined) {
144
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [guideX !== undefined ? ((0, jsx_runtime_1.jsx)(VerticalGuide_1.default, { model: model, coordX: guideX })) : null, (0, jsx_runtime_1.jsx)("div", { ref: controlsRef, className: classes.rubberbandControl, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove, children: ControlComponent })] }));
145
- }
146
- const right = anchorPosition ? anchorPosition.offsetX : currentX || 0;
147
- const left = Math.min(right, startX);
148
- const width = Math.abs(right - startX);
149
- const { views } = model;
150
- const leftBpOffset = views.map(view => view.pxToBp(left));
151
- const rightBpOffset = views.map(view => view.pxToBp(left + width));
152
- const numOfBpSelected = views.map(view => Math.ceil(width * view.bpPerPx));
153
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [rubberbandRef.current ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Popover, { className: classes.popover, classes: { paper: classes.paper }, open: true, anchorEl: rubberbandRef.current, anchorOrigin: {
154
- vertical: 'top',
155
- horizontal: 'left',
156
- }, transformOrigin: {
157
- vertical: 'bottom',
158
- horizontal: 'right',
159
- }, keepMounted: true, disableRestoreFocus: true, children: leftBpOffset.map((l, idx) => ((0, jsx_runtime_1.jsx)(material_1.Typography, { children: (0, util_1.stringify)(l, true) }, [JSON.stringify(l), idx, 'left'].join('-')))) }), (0, jsx_runtime_1.jsx)(material_1.Popover, { className: classes.popover, classes: { paper: classes.paper }, open: true, anchorEl: rubberbandRef.current, anchorOrigin: {
160
- vertical: 'top',
161
- horizontal: 'right',
162
- }, transformOrigin: {
163
- vertical: 'bottom',
164
- horizontal: 'left',
165
- }, keepMounted: true, disableRestoreFocus: true, children: rightBpOffset.map((l, idx) => ((0, jsx_runtime_1.jsx)(material_1.Typography, { children: (0, util_1.stringify)(l, true) }, [JSON.stringify(l), idx, 'right'].join('-')))) })] })) : null, (0, jsx_runtime_1.jsx)("div", { ref: rubberbandRef, className: classes.rubberband, style: { left, width }, children: (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", className: classes.rubberbandText, children: numOfBpSelected.map((n, i) => ((0, jsx_runtime_1.jsx)(material_1.Typography, { children: `${n.toLocaleString('en-US')}bp` }, `${n}_${i}`))) }) }), (0, jsx_runtime_1.jsx)("div", { className: classes.rubberbandControl, ref: controlsRef, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove, children: ControlComponent }), anchorPosition ? ((0, jsx_runtime_1.jsx)(ui_1.Menu, { anchorReference: "anchorPosition", anchorPosition: {
26
+ const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, handleMenuItemClick, handleClose, mouseMove, mouseDown, mouseOut, } = (0, useRangeSelect_1.useRangeSelect)(ref, model);
27
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [guideX !== undefined ? ((0, jsx_runtime_1.jsx)(VerticalGuide_1.default, { model: model, coordX: guideX })) : rubberbandOn ? ((0, jsx_runtime_1.jsx)(RubberbandSpan_1.default, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left })) : null, anchorPosition ? ((0, jsx_runtime_1.jsx)(ui_1.Menu, { anchorReference: "anchorPosition", anchorPosition: {
166
28
  left: anchorPosition.clientX,
167
29
  top: anchorPosition.clientY,
168
- }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null] }));
30
+ }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null, (0, jsx_runtime_1.jsx)("div", { "data-testid": "rubberband_controls", className: classes.rubberbandControl, ref: ref, onMouseDown: mouseDown, onMouseMove: mouseMove, onMouseOut: mouseOut, children: ControlComponent })] }));
169
31
  });
170
- exports.default = LinearComparativeRubberband;
32
+ exports.default = Rubberband;
@@ -0,0 +1,15 @@
1
+ interface Offset {
2
+ coord: number;
3
+ refName?: string;
4
+ oob?: boolean;
5
+ }
6
+ export default function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, top, sticky, }: {
7
+ leftBpOffset: Offset[];
8
+ rightBpOffset: Offset[];
9
+ numOfBpSelected?: number[];
10
+ left: number;
11
+ width: number;
12
+ top?: number;
13
+ sticky?: boolean;
14
+ }): import("react/jsx-runtime").JSX.Element;
15
+ export {};
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = RubberbandSpan;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("react");
9
+ const util_1 = require("@jbrowse/core/util");
10
+ const material_1 = require("@mui/material");
11
+ const mui_1 = require("tss-react/mui");
12
+ const RubberbandTooltip_1 = __importDefault(require("./RubberbandTooltip"));
13
+ const useStyles = (0, mui_1.makeStyles)()(theme => {
14
+ const { tertiary } = theme.palette;
15
+ const background = (0, material_1.alpha)(tertiary.light, 0.7);
16
+ return {
17
+ rubberband: {
18
+ height: '100%',
19
+ background,
20
+ position: 'absolute',
21
+ zIndex: 830,
22
+ textAlign: 'center',
23
+ },
24
+ rubberbandText: {
25
+ color: theme.palette.tertiary.contrastText,
26
+ },
27
+ };
28
+ });
29
+ function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, top = 0, sticky = false, }) {
30
+ const { classes } = useStyles();
31
+ const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
32
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [anchorEl ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(RubberbandTooltip_1.default, { side: "left", anchorEl: anchorEl, text: leftBpOffset.map((l, idx) => ((0, jsx_runtime_1.jsx)("div", { children: (0, util_1.stringify)(l, true) }, `JSON.stringify(l)-${idx}`))) }), (0, jsx_runtime_1.jsx)(RubberbandTooltip_1.default, { side: "right", anchorEl: anchorEl, text: rightBpOffset.map((l, idx) => ((0, jsx_runtime_1.jsx)("div", { children: (0, util_1.stringify)(l, true) }, `JSON.stringify(l)-${idx}`))) })] })) : null, (0, jsx_runtime_1.jsx)("div", { className: classes.rubberband, style: { left, width }, children: numOfBpSelected ? ((0, jsx_runtime_1.jsx)(material_1.Typography, { ref: el => {
33
+ setAnchorEl(el);
34
+ }, variant: "h6", className: classes.rubberbandText, style: {
35
+ top,
36
+ position: sticky ? 'sticky' : undefined,
37
+ }, children: numOfBpSelected.map((n, i) => ((0, jsx_runtime_1.jsx)("div", { children: (0, util_1.getBpDisplayStr)(n) }, i))) })) : null })] }));
38
+ }
@@ -0,0 +1,5 @@
1
+ export default function RubberbandTooltip({ anchorEl, side, text, }: {
2
+ anchorEl: HTMLSpanElement;
3
+ side: string;
4
+ text: React.ReactNode;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = RubberbandTooltip;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const material_1 = require("@mui/material");
6
+ function RubberbandTooltip({ anchorEl, side, text, }) {
7
+ return ((0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: text, open: true, placement: side === 'left' ? 'left-start' : 'right-start', slotProps: {
8
+ popper: {
9
+ anchorEl,
10
+ modifiers: [
11
+ {
12
+ name: 'offset',
13
+ options: {
14
+ offset: [-30, -10],
15
+ },
16
+ },
17
+ ],
18
+ },
19
+ }, children: (0, jsx_runtime_1.jsx)("span", {}) }));
20
+ }
@@ -0,0 +1,59 @@
1
+ import type React from 'react';
2
+ import type { LinearComparativeViewModel } from '../model';
3
+ interface AnchorPosition {
4
+ offsetX: number;
5
+ clientX: number;
6
+ clientY: number;
7
+ }
8
+ export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement | null>, model: LinearComparativeViewModel): {
9
+ open: boolean;
10
+ guideX: number | undefined;
11
+ mouseDown: (event: React.MouseEvent<HTMLDivElement>) => void;
12
+ mouseMove: (event: React.MouseEvent<HTMLDivElement>) => void;
13
+ mouseOut: () => void;
14
+ handleMenuItemClick: (_: unknown, callback: () => void) => void;
15
+ rubberbandOn?: undefined;
16
+ handleClose?: undefined;
17
+ leftBpOffset?: undefined;
18
+ rightBpOffset?: undefined;
19
+ anchorPosition?: undefined;
20
+ numOfBpSelected?: undefined;
21
+ width?: undefined;
22
+ left?: undefined;
23
+ } | {
24
+ open: boolean;
25
+ rubberbandOn: boolean;
26
+ mouseDown: (event: React.MouseEvent<HTMLDivElement>) => void;
27
+ mouseMove: (event: React.MouseEvent<HTMLDivElement>) => void;
28
+ mouseOut: () => void;
29
+ handleClose: () => void;
30
+ handleMenuItemClick: (_: unknown, callback: () => void) => void;
31
+ leftBpOffset: {
32
+ coord: number;
33
+ index: number;
34
+ refName: string;
35
+ oob: boolean;
36
+ assemblyName: string;
37
+ offset: number;
38
+ start: number;
39
+ end: number;
40
+ reversed?: boolean;
41
+ }[];
42
+ rightBpOffset: {
43
+ coord: number;
44
+ index: number;
45
+ refName: string;
46
+ oob: boolean;
47
+ assemblyName: string;
48
+ offset: number;
49
+ start: number;
50
+ end: number;
51
+ reversed?: boolean;
52
+ }[];
53
+ anchorPosition: AnchorPosition | undefined;
54
+ numOfBpSelected: number[];
55
+ width: number;
56
+ left: number;
57
+ guideX?: undefined;
58
+ };
59
+ export {};
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useRangeSelect = useRangeSelect;
4
+ const react_1 = require("react");
5
+ const mobx_1 = require("mobx");
6
+ const util_1 = require("./util");
7
+ function useRangeSelect(ref, model) {
8
+ const [startX, setStartX] = (0, react_1.useState)();
9
+ const [currentX, setCurrentX] = (0, react_1.useState)();
10
+ const [anchorPosition, setAnchorPosition] = (0, react_1.useState)();
11
+ const [guideX, setGuideX] = (0, react_1.useState)();
12
+ const mouseDragging = startX !== undefined && anchorPosition === undefined;
13
+ (0, react_1.useEffect)(() => {
14
+ function computeOffsets(offsetX) {
15
+ if (startX === undefined) {
16
+ return;
17
+ }
18
+ const leftPx = Math.min(startX, offsetX);
19
+ const rightPx = Math.max(startX, offsetX);
20
+ return model.views.map(view => ({
21
+ leftOffset: view.pxToBp(leftPx),
22
+ rightOffset: view.pxToBp(rightPx),
23
+ }));
24
+ }
25
+ function globalMouseMove(event) {
26
+ if (ref.current && mouseDragging) {
27
+ const relativeX = (0, util_1.getRelativeX)(event, ref.current);
28
+ setCurrentX(relativeX);
29
+ }
30
+ }
31
+ function globalMouseUp(event) {
32
+ if (startX !== undefined && ref.current) {
33
+ const { clientX, clientY } = event;
34
+ const offsetX = (0, util_1.getRelativeX)(event, ref.current);
35
+ setAnchorPosition({
36
+ offsetX,
37
+ clientX,
38
+ clientY,
39
+ });
40
+ const offsets = computeOffsets(offsetX);
41
+ if (offsets) {
42
+ (0, mobx_1.transaction)(() => {
43
+ for (const [idx, elt] of offsets.entries()) {
44
+ model.views[idx].setOffsets(elt.leftOffset, elt.rightOffset);
45
+ }
46
+ });
47
+ }
48
+ setGuideX(undefined);
49
+ }
50
+ }
51
+ if (mouseDragging) {
52
+ window.addEventListener('mousemove', globalMouseMove);
53
+ window.addEventListener('mouseup', globalMouseUp);
54
+ return () => {
55
+ window.removeEventListener('mousemove', globalMouseMove);
56
+ window.removeEventListener('mouseup', globalMouseUp);
57
+ };
58
+ }
59
+ return () => { };
60
+ }, [startX, mouseDragging, model, ref]);
61
+ (0, react_1.useEffect)(() => {
62
+ if (!mouseDragging &&
63
+ currentX !== undefined &&
64
+ startX !== undefined &&
65
+ Math.abs(currentX - startX) <= 3) {
66
+ handleClose();
67
+ }
68
+ }, [mouseDragging, currentX, startX]);
69
+ function mouseDown(event) {
70
+ event.preventDefault();
71
+ event.stopPropagation();
72
+ const relativeX = (0, util_1.getRelativeX)(event, ref.current);
73
+ setStartX(relativeX);
74
+ setCurrentX(relativeX);
75
+ }
76
+ function mouseMove(event) {
77
+ setGuideX((0, util_1.getRelativeX)(event, ref.current));
78
+ }
79
+ function mouseOut() {
80
+ setGuideX(undefined);
81
+ (0, mobx_1.transaction)(() => {
82
+ for (const view of model.views) {
83
+ view.setOffsets(undefined, undefined);
84
+ }
85
+ });
86
+ }
87
+ function handleClose() {
88
+ setAnchorPosition(undefined);
89
+ setStartX(undefined);
90
+ setCurrentX(undefined);
91
+ }
92
+ function handleMenuItemClick(_, callback) {
93
+ callback();
94
+ handleClose();
95
+ }
96
+ const open = Boolean(anchorPosition);
97
+ if (startX === undefined) {
98
+ return {
99
+ open,
100
+ guideX,
101
+ mouseDown,
102
+ mouseMove,
103
+ mouseOut,
104
+ handleMenuItemClick,
105
+ };
106
+ }
107
+ const right = anchorPosition ? anchorPosition.offsetX : currentX || 0;
108
+ const left = Math.min(right, startX);
109
+ const width = Math.abs(right - startX);
110
+ const leftBpOffset = model.views.map(view => view.pxToBp(left));
111
+ const rightBpOffset = model.views.map(view => view.pxToBp(left + width));
112
+ const numOfBpSelected = model.views.map(view => Math.ceil(width * view.bpPerPx));
113
+ return {
114
+ open,
115
+ rubberbandOn: true,
116
+ mouseDown,
117
+ mouseMove,
118
+ mouseOut,
119
+ handleClose,
120
+ handleMenuItemClick,
121
+ leftBpOffset,
122
+ rightBpOffset,
123
+ anchorPosition,
124
+ numOfBpSelected,
125
+ width,
126
+ left,
127
+ };
128
+ }
@@ -0,0 +1,4 @@
1
+ export declare function getRelativeX(event: {
2
+ clientX: number;
3
+ target: EventTarget | null;
4
+ }, element: HTMLElement | null): number;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRelativeX = getRelativeX;
4
+ function getRelativeX(event, element) {
5
+ return event.clientX - ((element === null || element === void 0 ? void 0 : element.getBoundingClientRect().left) || 0);
6
+ }
@@ -0,0 +1,3 @@
1
+ export default function BlockError({ error }: {
2
+ error: unknown;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = BlockError;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const mui_1 = require("tss-react/mui");
6
+ const useStyles = (0, mui_1.makeStyles)()({
7
+ blockError: {
8
+ background: '#f1f1f1',
9
+ padding: 10,
10
+ color: 'red',
11
+ },
12
+ });
13
+ function BlockError({ error }) {
14
+ const { classes } = useStyles();
15
+ return (0, jsx_runtime_1.jsx)("div", { className: classes.blockError, children: `${error}` });
16
+ }
@@ -0,0 +1,3 @@
1
+ export default function BlockMessage({ messageText }: {
2
+ messageText: string;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = BlockMessage;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const mui_1 = require("tss-react/mui");
6
+ const useStyles = (0, mui_1.makeStyles)()(theme => {
7
+ const bg = theme.palette.action.disabledBackground;
8
+ return {
9
+ loading: {
10
+ paddingLeft: '0.6em',
11
+ backgroundColor: theme.palette.background.default,
12
+ backgroundImage: `repeating-linear-gradient(45deg, transparent, transparent 5px, ${bg} 5px, ${bg} 10px)`,
13
+ textAlign: 'center',
14
+ },
15
+ blockMessage: {
16
+ background: '#f1f1f1',
17
+ padding: 10,
18
+ },
19
+ };
20
+ });
21
+ function BlockMessage({ messageText }) {
22
+ const { classes } = useStyles();
23
+ return (0, jsx_runtime_1.jsx)("div", { className: classes.blockMessage, children: messageText });
24
+ }