@jbrowse/plugin-linear-genome-view 2.2.1 → 2.2.2

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 (184) hide show
  1. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +1 -1
  2. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
  3. package/dist/LaunchLinearGenomeView/index.d.ts +3 -0
  4. package/dist/LaunchLinearGenomeView/index.js +44 -0
  5. package/dist/LaunchLinearGenomeView/index.js.map +1 -0
  6. package/dist/LinearBareDisplay/index.d.ts +6 -2
  7. package/dist/LinearBareDisplay/index.js +17 -2
  8. package/dist/LinearBareDisplay/index.js.map +1 -1
  9. package/dist/LinearBasicDisplay/components/SetMaxHeight.js +2 -15
  10. package/dist/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
  11. package/dist/LinearBasicDisplay/index.d.ts +6 -2
  12. package/dist/LinearBasicDisplay/index.js +20 -4
  13. package/dist/LinearBasicDisplay/index.js.map +1 -1
  14. package/dist/LinearBasicDisplay/model.d.ts +19 -12
  15. package/dist/LinearBasicDisplay/model.js +2 -1
  16. package/dist/LinearBasicDisplay/model.js.map +1 -1
  17. package/dist/LinearGenomeView/components/ExportSvgDialog.js +1 -19
  18. package/dist/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
  19. package/dist/LinearGenomeView/components/GetSequenceDialog.js +7 -18
  20. package/dist/LinearGenomeView/components/GetSequenceDialog.js.map +1 -1
  21. package/dist/LinearGenomeView/components/Header.js +2 -2
  22. package/dist/LinearGenomeView/components/HelpDialog.js +2 -17
  23. package/dist/LinearGenomeView/components/HelpDialog.js.map +1 -1
  24. package/dist/LinearGenomeView/components/ImportForm.js +10 -9
  25. package/dist/LinearGenomeView/components/ImportForm.js.map +1 -1
  26. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js +5 -5
  27. package/dist/LinearGenomeView/components/{OverviewRubberBand.d.ts → OverviewRubberband.d.ts} +2 -2
  28. package/dist/LinearGenomeView/components/{OverviewRubberBand.js → OverviewRubberband.js} +27 -79
  29. package/dist/LinearGenomeView/components/OverviewRubberband.js.map +1 -0
  30. package/{esm/LinearGenomeView/components/OverviewScaleBar.d.ts → dist/LinearGenomeView/components/OverviewScalebar.d.ts} +2 -2
  31. package/dist/LinearGenomeView/components/{OverviewScaleBar.js → OverviewScalebar.js} +25 -24
  32. package/dist/LinearGenomeView/components/OverviewScalebar.js.map +1 -0
  33. package/dist/LinearGenomeView/components/RefNameAutocomplete.js +1 -1
  34. package/dist/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  35. package/dist/LinearGenomeView/components/{RubberBand.d.ts → Rubberband.d.ts} +2 -2
  36. package/dist/LinearGenomeView/components/Rubberband.js +57 -0
  37. package/dist/LinearGenomeView/components/Rubberband.js.map +1 -0
  38. package/dist/LinearGenomeView/components/RubberbandSpan.d.ts +14 -0
  39. package/dist/LinearGenomeView/components/RubberbandSpan.js +90 -0
  40. package/dist/LinearGenomeView/components/RubberbandSpan.js.map +1 -0
  41. package/dist/LinearGenomeView/components/{ScaleBar.d.ts → Scalebar.d.ts} +2 -2
  42. package/dist/LinearGenomeView/components/{ScaleBar.js → Scalebar.js} +11 -11
  43. package/dist/LinearGenomeView/components/{ScaleBar.js.map → Scalebar.js.map} +1 -1
  44. package/dist/LinearGenomeView/components/SearchBox.js +6 -6
  45. package/dist/LinearGenomeView/components/SearchBox.js.map +1 -1
  46. package/dist/LinearGenomeView/components/SearchResultsDialog.js +17 -31
  47. package/dist/LinearGenomeView/components/SearchResultsDialog.js.map +1 -1
  48. package/dist/LinearGenomeView/components/SequenceSearchDialog.js +4 -19
  49. package/dist/LinearGenomeView/components/SequenceSearchDialog.js.map +1 -1
  50. package/dist/LinearGenomeView/components/TrackContainer.js +2 -2
  51. package/dist/LinearGenomeView/components/TrackContainer.js.map +1 -1
  52. package/dist/LinearGenomeView/components/TracksContainer.js +21 -118
  53. package/dist/LinearGenomeView/components/TracksContainer.js.map +1 -1
  54. package/dist/LinearGenomeView/components/VerticalGuide.d.ts +9 -0
  55. package/dist/LinearGenomeView/components/VerticalGuide.js +29 -0
  56. package/dist/LinearGenomeView/components/VerticalGuide.js.map +1 -0
  57. package/dist/LinearGenomeView/components/hooks.d.ts +65 -0
  58. package/dist/LinearGenomeView/components/hooks.js +264 -0
  59. package/dist/LinearGenomeView/components/hooks.js.map +1 -0
  60. package/dist/LinearGenomeView/components/util.d.ts +5 -2
  61. package/dist/LinearGenomeView/components/util.js +7 -6
  62. package/dist/LinearGenomeView/components/util.js.map +1 -1
  63. package/dist/LinearGenomeView/index.d.ts +3 -534
  64. package/dist/LinearGenomeView/index.js +11 -1327
  65. package/dist/LinearGenomeView/index.js.map +1 -1
  66. package/dist/LinearGenomeView/model.d.ts +535 -0
  67. package/dist/LinearGenomeView/model.js +1357 -0
  68. package/dist/LinearGenomeView/model.js.map +1 -0
  69. package/dist/index.d.ts +2 -2
  70. package/dist/index.js +9 -72
  71. package/dist/index.js.map +1 -1
  72. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +1 -1
  73. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
  74. package/esm/LaunchLinearGenomeView/index.d.ts +3 -0
  75. package/esm/LaunchLinearGenomeView/index.js +42 -0
  76. package/esm/LaunchLinearGenomeView/index.js.map +1 -0
  77. package/esm/LinearBareDisplay/index.d.ts +6 -2
  78. package/esm/LinearBareDisplay/index.js +18 -2
  79. package/esm/LinearBareDisplay/index.js.map +1 -1
  80. package/esm/LinearBasicDisplay/components/SetMaxHeight.js +3 -13
  81. package/esm/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
  82. package/esm/LinearBasicDisplay/index.d.ts +6 -2
  83. package/esm/LinearBasicDisplay/index.js +19 -2
  84. package/esm/LinearBasicDisplay/index.js.map +1 -1
  85. package/esm/LinearBasicDisplay/model.d.ts +19 -12
  86. package/esm/LinearBasicDisplay/model.js +2 -1
  87. package/esm/LinearBasicDisplay/model.js.map +1 -1
  88. package/esm/LinearGenomeView/components/ExportSvgDialog.js +3 -18
  89. package/esm/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
  90. package/esm/LinearGenomeView/components/GetSequenceDialog.js +8 -19
  91. package/esm/LinearGenomeView/components/GetSequenceDialog.js.map +1 -1
  92. package/esm/LinearGenomeView/components/Header.js +2 -2
  93. package/esm/LinearGenomeView/components/HelpDialog.js +3 -18
  94. package/esm/LinearGenomeView/components/HelpDialog.js.map +1 -1
  95. package/esm/LinearGenomeView/components/ImportForm.js +10 -9
  96. package/esm/LinearGenomeView/components/ImportForm.js.map +1 -1
  97. package/esm/LinearGenomeView/components/LinearGenomeViewSvg.js +3 -3
  98. package/esm/LinearGenomeView/components/{OverviewRubberBand.d.ts → OverviewRubberband.d.ts} +2 -2
  99. package/esm/LinearGenomeView/components/{OverviewRubberBand.js → OverviewRubberband.js} +25 -80
  100. package/esm/LinearGenomeView/components/OverviewRubberband.js.map +1 -0
  101. package/{dist/LinearGenomeView/components/OverviewScaleBar.d.ts → esm/LinearGenomeView/components/OverviewScalebar.d.ts} +2 -2
  102. package/esm/LinearGenomeView/components/{OverviewScaleBar.js → OverviewScalebar.js} +25 -24
  103. package/esm/LinearGenomeView/components/OverviewScalebar.js.map +1 -0
  104. package/esm/LinearGenomeView/components/RefNameAutocomplete.js +1 -1
  105. package/esm/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  106. package/esm/LinearGenomeView/components/{RubberBand.d.ts → Rubberband.d.ts} +2 -2
  107. package/esm/LinearGenomeView/components/Rubberband.js +29 -0
  108. package/esm/LinearGenomeView/components/Rubberband.js.map +1 -0
  109. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +14 -0
  110. package/esm/LinearGenomeView/components/RubberbandSpan.js +65 -0
  111. package/esm/LinearGenomeView/components/RubberbandSpan.js.map +1 -0
  112. package/esm/LinearGenomeView/components/{ScaleBar.d.ts → Scalebar.d.ts} +2 -2
  113. package/esm/LinearGenomeView/components/{ScaleBar.js → Scalebar.js} +11 -11
  114. package/esm/LinearGenomeView/components/{ScaleBar.js.map → Scalebar.js.map} +1 -1
  115. package/esm/LinearGenomeView/components/SearchBox.js +6 -6
  116. package/esm/LinearGenomeView/components/SearchBox.js.map +1 -1
  117. package/esm/LinearGenomeView/components/SearchResultsDialog.js +18 -32
  118. package/esm/LinearGenomeView/components/SearchResultsDialog.js.map +1 -1
  119. package/esm/LinearGenomeView/components/SequenceSearchDialog.js +5 -17
  120. package/esm/LinearGenomeView/components/SequenceSearchDialog.js.map +1 -1
  121. package/esm/LinearGenomeView/components/TrackContainer.js +2 -2
  122. package/esm/LinearGenomeView/components/TrackContainer.js.map +1 -1
  123. package/esm/LinearGenomeView/components/TracksContainer.js +22 -119
  124. package/esm/LinearGenomeView/components/TracksContainer.js.map +1 -1
  125. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +9 -0
  126. package/esm/LinearGenomeView/components/VerticalGuide.js +24 -0
  127. package/esm/LinearGenomeView/components/VerticalGuide.js.map +1 -0
  128. package/esm/LinearGenomeView/components/hooks.d.ts +65 -0
  129. package/esm/LinearGenomeView/components/hooks.js +255 -0
  130. package/esm/LinearGenomeView/components/hooks.js.map +1 -0
  131. package/esm/LinearGenomeView/components/util.d.ts +5 -2
  132. package/esm/LinearGenomeView/components/util.js +4 -3
  133. package/esm/LinearGenomeView/components/util.js.map +1 -1
  134. package/esm/LinearGenomeView/index.d.ts +3 -534
  135. package/esm/LinearGenomeView/index.js +9 -1318
  136. package/esm/LinearGenomeView/index.js.map +1 -1
  137. package/esm/LinearGenomeView/model.d.ts +535 -0
  138. package/esm/LinearGenomeView/model.js +1322 -0
  139. package/esm/LinearGenomeView/model.js.map +1 -0
  140. package/esm/index.d.ts +2 -2
  141. package/esm/index.js +9 -72
  142. package/esm/index.js.map +1 -1
  143. package/package.json +3 -3
  144. package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +1 -1
  145. package/src/LaunchLinearGenomeView/index.ts +66 -0
  146. package/src/LinearBareDisplay/index.ts +21 -2
  147. package/src/LinearBasicDisplay/components/SetMaxHeight.tsx +3 -28
  148. package/src/LinearBasicDisplay/index.ts +23 -2
  149. package/src/LinearBasicDisplay/model.ts +2 -1
  150. package/src/LinearGenomeView/components/ExportSvgDialog.tsx +2 -23
  151. package/src/LinearGenomeView/components/GetSequenceDialog.tsx +13 -31
  152. package/src/LinearGenomeView/components/Header.tsx +3 -3
  153. package/src/LinearGenomeView/components/HelpDialog.tsx +8 -34
  154. package/src/LinearGenomeView/components/ImportForm.tsx +10 -9
  155. package/src/LinearGenomeView/components/LinearGenomeViewSvg.tsx +3 -3
  156. package/src/LinearGenomeView/components/{OverviewRubberBand.tsx → OverviewRubberband.tsx} +32 -114
  157. package/src/LinearGenomeView/components/{OverviewScaleBar.tsx → OverviewScalebar.tsx} +26 -25
  158. package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +2 -1
  159. package/src/LinearGenomeView/components/Rubberband.tsx +89 -0
  160. package/src/LinearGenomeView/components/RubberbandSpan.tsx +116 -0
  161. package/src/LinearGenomeView/components/{ScaleBar.test.tsx → Scalebar.test.tsx} +5 -5
  162. package/src/LinearGenomeView/components/{ScaleBar.tsx → Scalebar.tsx} +11 -11
  163. package/src/LinearGenomeView/components/SearchBox.tsx +6 -6
  164. package/src/LinearGenomeView/components/SearchResultsDialog.tsx +17 -44
  165. package/src/LinearGenomeView/components/SequenceSearchDialog.tsx +4 -30
  166. package/src/LinearGenomeView/components/TrackContainer.tsx +4 -2
  167. package/src/LinearGenomeView/components/TracksContainer.tsx +59 -136
  168. package/src/LinearGenomeView/components/VerticalGuide.tsx +37 -0
  169. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.tsx.snap +37 -39
  170. package/src/LinearGenomeView/components/hooks.ts +300 -0
  171. package/src/LinearGenomeView/components/util.ts +8 -11
  172. package/src/LinearGenomeView/index.test.ts +6 -7
  173. package/src/LinearGenomeView/index.ts +17 -0
  174. package/src/LinearGenomeView/{index.tsx → model.ts} +7 -4
  175. package/src/index.ts +13 -108
  176. package/dist/LinearGenomeView/components/OverviewRubberBand.js.map +0 -1
  177. package/dist/LinearGenomeView/components/OverviewScaleBar.js.map +0 -1
  178. package/dist/LinearGenomeView/components/RubberBand.js +0 -221
  179. package/dist/LinearGenomeView/components/RubberBand.js.map +0 -1
  180. package/esm/LinearGenomeView/components/OverviewRubberBand.js.map +0 -1
  181. package/esm/LinearGenomeView/components/OverviewScaleBar.js.map +0 -1
  182. package/esm/LinearGenomeView/components/RubberBand.js +0 -196
  183. package/esm/LinearGenomeView/components/RubberBand.js.map +0 -1
  184. package/src/LinearGenomeView/components/RubberBand.tsx +0 -308
@@ -2,10 +2,10 @@
2
2
  import React from 'react'
3
3
  import { render } from '@testing-library/react'
4
4
  import { createTestSession } from '@jbrowse/web/src/rootModel'
5
- import ScaleBar from './ScaleBar'
5
+ import Scalebar from './Scalebar'
6
6
  jest.mock('@jbrowse/web/src/makeWorkerInstance', () => () => {})
7
7
 
8
- describe('ScaleBar genome view component', () => {
8
+ describe('Scalebar genome view component', () => {
9
9
  it('renders two regions', () => {
10
10
  const session = createTestSession({
11
11
  views: [
@@ -47,7 +47,7 @@ describe('ScaleBar genome view component', () => {
47
47
  },
48
48
  })
49
49
  const model = session.views[0]
50
- const { getByTestId } = render(<ScaleBar model={model} />)
50
+ const { getByTestId } = render(<Scalebar model={model} />)
51
51
  const ret1 = getByTestId('refLabel-ctgA')
52
52
  const ret2 = getByTestId('refLabel-ctgB')
53
53
  expect(ret1.style.left).toBe('-1px')
@@ -89,7 +89,7 @@ describe('ScaleBar genome view component', () => {
89
89
  },
90
90
  })
91
91
  const model = session.views[0]
92
- const { getByTestId } = render(<ScaleBar model={model} />)
92
+ const { getByTestId } = render(<Scalebar model={model} />)
93
93
  const ret1 = getByTestId('refLabel-ctgA')
94
94
  const ret2 = getByTestId('refLabel-ctgB')
95
95
  expect(ret1.style.left).toBe('99px')
@@ -134,7 +134,7 @@ describe('ScaleBar genome view component', () => {
134
134
  },
135
135
  })
136
136
  const model = session.views[0]
137
- const { queryByTestId } = render(<ScaleBar model={model} />)
137
+ const { queryByTestId } = render(<Scalebar model={model} />)
138
138
  const ret2 = queryByTestId('refLabel-ctgB')
139
139
  const ret3 = queryByTestId('refLabel-ctgC')
140
140
  const ret4 = queryByTestId('refLabel-ctgD')
@@ -19,15 +19,15 @@ import { getTickDisplayStr } from '@jbrowse/core/util'
19
19
  type LGV = LinearGenomeViewModel
20
20
 
21
21
  const useStyles = makeStyles()(theme => ({
22
- scaleBarContainer: {
22
+ scalebarContainer: {
23
23
  overflow: 'hidden',
24
24
  position: 'relative',
25
25
  },
26
- scaleBarZoomContainer: {
26
+ scalebarZoomContainer: {
27
27
  position: 'relative',
28
28
  zIndex: 1,
29
29
  },
30
- scaleBar: {
30
+ scalebar: {
31
31
  position: 'absolute',
32
32
  display: 'flex',
33
33
  pointerEvents: 'none',
@@ -94,7 +94,7 @@ const RenderedRefNameLabels = observer(({ model }: { model: LGV }) => {
94
94
  )
95
95
  })
96
96
 
97
- const RenderedScaleBarLabels = observer(({ model }: { model: LGV }) => {
97
+ const RenderedScalebarLabels = observer(({ model }: { model: LGV }) => {
98
98
  const { classes } = useStyles()
99
99
  const { bpPerPx, staticBlocks } = model
100
100
 
@@ -150,13 +150,13 @@ const RenderedScaleBarLabels = observer(({ model }: { model: LGV }) => {
150
150
  )
151
151
  })
152
152
 
153
- interface ScaleBarProps {
153
+ interface ScalebarProps {
154
154
  model: LGV
155
155
  style?: React.CSSProperties
156
156
  className?: string
157
157
  }
158
158
 
159
- const ScaleBar = React.forwardRef<HTMLDivElement, ScaleBarProps>(
159
+ const Scalebar = React.forwardRef<HTMLDivElement, ScalebarProps>(
160
160
  ({ model, style, className, ...other }, ref) => {
161
161
  const { classes, cx } = useStyles()
162
162
 
@@ -164,14 +164,14 @@ const ScaleBar = React.forwardRef<HTMLDivElement, ScaleBarProps>(
164
164
  return (
165
165
  <Paper
166
166
  data-resizer="true" // used to avoid click-and-drag scrolls on trackscontainer
167
- className={cx(classes.scaleBarContainer, className)}
167
+ className={cx(classes.scalebarContainer, className)}
168
168
  variant="outlined"
169
169
  ref={ref}
170
170
  style={style}
171
171
  {...other}
172
172
  >
173
173
  <div
174
- className={classes.scaleBarZoomContainer}
174
+ className={classes.scalebarZoomContainer}
175
175
  style={{
176
176
  transform:
177
177
  model.scaleFactor !== 1
@@ -180,14 +180,14 @@ const ScaleBar = React.forwardRef<HTMLDivElement, ScaleBarProps>(
180
180
  }}
181
181
  >
182
182
  <div
183
- className={classes.scaleBar}
183
+ className={classes.scalebar}
184
184
  style={{
185
185
  left: offsetLeft - 1,
186
186
  width: model.staticBlocks.totalWidthPx,
187
187
  ...style,
188
188
  }}
189
189
  >
190
- <RenderedScaleBarLabels model={model} />
190
+ <RenderedScalebarLabels model={model} />
191
191
  </div>
192
192
  </div>
193
193
  <RenderedRefNameLabels model={model} />
@@ -196,4 +196,4 @@ const ScaleBar = React.forwardRef<HTMLDivElement, ScaleBarProps>(
196
196
  },
197
197
  )
198
198
 
199
- export default observer(ScaleBar)
199
+ export default observer(Scalebar)
@@ -33,11 +33,11 @@ function SearchBox({
33
33
  const assembly = assemblyManager.get(assemblyName)
34
34
  const searchScope = model.searchScope(assemblyName)
35
35
 
36
- function navToOption(option: BaseResult) {
36
+ async function navToOption(option: BaseResult) {
37
37
  const location = option.getLocation()
38
38
  const trackId = option.getTrackId()
39
39
  if (location) {
40
- model.navToLocString(location, assemblyName)
40
+ await model.navToLocString(location, assemblyName)
41
41
  if (trackId) {
42
42
  model.showTrack(trackId)
43
43
  }
@@ -52,7 +52,7 @@ function SearchBox({
52
52
  async function handleSelectedRegion(option: BaseResult) {
53
53
  try {
54
54
  if (option.hasLocation()) {
55
- navToOption(option)
55
+ await navToOption(option)
56
56
  } else {
57
57
  const input = option.getLabel()
58
58
  const [ref, rest] = splitLast(input, ':')
@@ -61,7 +61,7 @@ function SearchBox({
61
61
  allRefs.includes(input) ||
62
62
  (allRefs.includes(ref) && !Number.isNaN(parseInt(rest, 10)))
63
63
  ) {
64
- model.navToLocString(input, assemblyName)
64
+ await model.navToLocString(input, assemblyName)
65
65
  } else {
66
66
  const results = await fetchResults({
67
67
  queryString: input,
@@ -75,9 +75,9 @@ function SearchBox({
75
75
  if (results.length > 1) {
76
76
  model.setSearchResults(results, input.toLowerCase())
77
77
  } else if (results.length === 1) {
78
- navToOption(results[0])
78
+ await navToOption(results[0])
79
79
  } else {
80
- model.navToLocString(input, assemblyName)
80
+ await model.navToLocString(input, assemblyName)
81
81
  }
82
82
  }
83
83
  }
@@ -1,15 +1,12 @@
1
1
  import React from 'react'
2
- import { makeStyles } from 'tss-react/mui'
3
2
  import { resolveIdentifier, getRoot } from 'mobx-state-tree'
4
3
  import { getSession, getEnv } from '@jbrowse/core/util'
4
+ import { Dialog } from '@jbrowse/core/ui'
5
5
  import {
6
6
  Button,
7
- Dialog,
8
7
  DialogActions,
9
8
  DialogContent,
10
- DialogTitle,
11
9
  Divider,
12
- IconButton,
13
10
  Paper,
14
11
  Table,
15
12
  TableBody,
@@ -19,20 +16,8 @@ import {
19
16
  TableRow,
20
17
  Typography,
21
18
  } from '@mui/material'
22
- import CloseIcon from '@mui/icons-material/Close'
23
- import { LinearGenomeViewModel } from '../..'
24
19
 
25
- const useStyles = makeStyles()(theme => ({
26
- dialogContent: {
27
- width: '80em',
28
- },
29
- closeButton: {
30
- position: 'absolute',
31
- right: theme.spacing(1),
32
- top: theme.spacing(1),
33
- color: theme.palette.grey[500],
34
- },
35
- }))
20
+ import { LinearGenomeViewModel } from '../..'
36
21
 
37
22
  export default function SearchResultsDialog({
38
23
  model,
@@ -43,7 +28,6 @@ export default function SearchResultsDialog({
43
28
  optAssemblyName?: string
44
29
  handleClose: () => void
45
30
  }) {
46
- const { classes } = useStyles()
47
31
  const session = getSession(model)
48
32
  const { pluginManager } = getEnv(session)
49
33
  const { assemblyManager } = session
@@ -63,7 +47,7 @@ export default function SearchResultsDialog({
63
47
  }
64
48
  const assemblyRegions = assembly.regions
65
49
 
66
- function handleClick(location: string) {
50
+ async function handleClick(location: string) {
67
51
  try {
68
52
  const newRegion = assemblyRegions.find(
69
53
  region => location === region.refName,
@@ -74,7 +58,7 @@ export default function SearchResultsDialog({
74
58
  // region visible, xref #1703
75
59
  model.showAllRegions()
76
60
  } else {
77
- model.navToLocString(location, assemblyName)
61
+ await model.navToLocString(location, assemblyName)
78
62
  }
79
63
  } catch (e) {
80
64
  console.warn(e)
@@ -92,23 +76,7 @@ export default function SearchResultsDialog({
92
76
  }
93
77
 
94
78
  return (
95
- <Dialog open maxWidth="xl" onClose={handleClose}>
96
- <DialogTitle>
97
- Search results
98
- {handleClose ? (
99
- <IconButton
100
- data-testid="close-resultsDialog"
101
- className={classes.closeButton}
102
- onClick={() => {
103
- handleClose()
104
- }}
105
- size="large"
106
- >
107
- <CloseIcon />
108
- </IconButton>
109
- ) : null}
110
- </DialogTitle>
111
- <Divider />
79
+ <Dialog open maxWidth="xl" onClose={handleClose} title="Search results">
112
80
  <DialogContent>
113
81
  {!model.searchResults?.length ? (
114
82
  <Typography>
@@ -143,14 +111,19 @@ export default function SearchResultsDialog({
143
111
  </TableCell>
144
112
  <TableCell align="right">
145
113
  <Button
146
- onClick={() => {
147
- const location = result.getLocation()
148
- if (location) {
149
- handleClick(location)
150
- const resultTrackId = result.getTrackId()
151
- if (resultTrackId) {
152
- model.showTrack(resultTrackId)
114
+ onClick={async () => {
115
+ try {
116
+ const location = result.getLocation()
117
+ if (location) {
118
+ await handleClick(location)
119
+ const resultTrackId = result.getTrackId()
120
+ if (resultTrackId) {
121
+ model.showTrack(resultTrackId)
122
+ }
153
123
  }
124
+ } catch (e) {
125
+ console.error(e)
126
+ session.notify(`${e}`, 'error')
154
127
  }
155
128
  handleClose()
156
129
  }}
@@ -2,36 +2,24 @@ import React, { useState } from 'react'
2
2
  import {
3
3
  Button,
4
4
  Checkbox,
5
- Dialog,
6
5
  DialogActions,
7
6
  DialogContent,
8
- DialogTitle,
9
- Divider,
10
7
  FormGroup,
11
8
  FormControlLabel,
12
- IconButton,
13
9
  TextField,
14
10
  Typography,
15
11
  } from '@mui/material'
12
+ import { Dialog } from '@jbrowse/core/ui'
16
13
  import { getSnapshot } from 'mobx-state-tree'
17
14
  import { makeStyles } from 'tss-react/mui'
18
15
  import { observer } from 'mobx-react'
19
16
  import { getSession } from '@jbrowse/core/util'
20
17
 
21
- // icons
22
- import CloseIcon from '@mui/icons-material/Close'
23
-
24
- const useStyles = makeStyles()(theme => ({
25
- closeButton: {
26
- position: 'absolute',
27
- right: theme.spacing(1),
28
- top: theme.spacing(1),
29
- color: theme.palette.grey[500],
30
- },
18
+ const useStyles = makeStyles()({
31
19
  dialogContent: {
32
20
  width: '40em',
33
21
  },
34
- }))
22
+ })
35
23
 
36
24
  function SequenceDialog({
37
25
  model,
@@ -55,21 +43,7 @@ function SequenceDialog({
55
43
  }
56
44
 
57
45
  return (
58
- <Dialog maxWidth="xl" open onClose={handleClose}>
59
- <DialogTitle>
60
- Sequence search
61
- {handleClose ? (
62
- <IconButton
63
- className={classes.closeButton}
64
- onClick={() => handleClose()}
65
- size="large"
66
- >
67
- <CloseIcon />
68
- </IconButton>
69
- ) : null}
70
- </DialogTitle>
71
- <Divider />
72
-
46
+ <Dialog maxWidth="xl" open onClose={handleClose} title="Sequence search">
73
47
  <DialogContent className={classes.dialogContent}>
74
48
  <Typography>
75
49
  Supply a sequence to search for. A track will be created with the
@@ -3,10 +3,12 @@ import { Paper } from '@mui/material'
3
3
  import { makeStyles } from 'tss-react/mui'
4
4
  import { observer } from 'mobx-react'
5
5
  import { isAlive } from 'mobx-state-tree'
6
+ import { ErrorBoundary } from 'react-error-boundary'
7
+
8
+ // jbrowse core
6
9
  import { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models'
7
10
  import { getConf } from '@jbrowse/core/configuration'
8
11
  import { ResizeHandle, ErrorMessage } from '@jbrowse/core/ui'
9
- import { ErrorBoundary } from 'react-error-boundary'
10
12
  import { useDebouncedCallback } from '@jbrowse/core/util'
11
13
 
12
14
  // locals
@@ -35,7 +37,7 @@ const useStyles = makeStyles()({
35
37
  zIndex: 3,
36
38
  },
37
39
 
38
- // aligns with block bounderies. check for example the breakpoint split view
40
+ // aligns with block boundaries. check for example the breakpoint split view
39
41
  // demo to see if features align if wanting to change things
40
42
  renderingComponentContainer: {
41
43
  position: 'absolute',
@@ -1,14 +1,19 @@
1
- import React, { useEffect, useRef, useState } from 'react'
1
+ import React, { useRef } from 'react'
2
2
  import { makeStyles } from 'tss-react/mui'
3
3
  import { observer } from 'mobx-react'
4
- import normalizeWheel from 'normalize-wheel'
4
+ import { Menu } from '@jbrowse/core/ui'
5
5
 
6
- // locals
6
+ // local utils
7
7
  import { LinearGenomeViewModel, SCALE_BAR_HEIGHT } from '..'
8
- import RubberBand from './RubberBand'
9
- import ScaleBar from './ScaleBar'
8
+ import { useSideScroll, useRangeSelect, useWheelScroll } from './hooks'
9
+
10
+ // local components
11
+ import Rubberband from './Rubberband'
12
+ import Scalebar from './Scalebar'
10
13
  import Gridlines from './Gridlines'
11
14
  import CenterLine from './CenterLine'
15
+ import VerticalGuide from './VerticalGuide'
16
+ import RubberbandSpan from './RubberbandSpan'
12
17
 
13
18
  const useStyles = makeStyles()({
14
19
  tracksContainer: {
@@ -22,7 +27,6 @@ const useStyles = makeStyles()({
22
27
  })
23
28
 
24
29
  type LGV = LinearGenomeViewModel
25
- type Timer = ReturnType<typeof setTimeout>
26
30
 
27
31
  function TracksContainer({
28
32
  children,
@@ -32,149 +36,68 @@ function TracksContainer({
32
36
  model: LGV
33
37
  }) {
34
38
  const { classes } = useStyles()
35
- // refs are to store these variables to avoid repeated rerenders associated
36
- // with useState/setState
37
- const delta = useRef(0)
38
- const scheduled = useRef(false)
39
- const timeout = useRef<Timer>()
39
+ const { mouseDown: mouseDown1, mouseUp } = useSideScroll(model)
40
40
  const ref = useRef<HTMLDivElement>(null)
41
- const prevX = useRef<number>(0)
42
-
43
- const [mouseDragging, setMouseDragging] = useState(false)
44
-
45
- useEffect(() => {
46
- let cleanup = () => {}
47
-
48
- function globalMouseMove(event: MouseEvent) {
49
- event.preventDefault()
50
- const currX = event.clientX
51
- const distance = currX - prevX.current
52
- if (distance) {
53
- // use rAF to make it so multiple event handlers aren't fired per-frame
54
- // see https://calendar.perfplanet.com/2013/the-runtime-performance-checklist/
55
- if (!scheduled.current) {
56
- scheduled.current = true
57
- window.requestAnimationFrame(() => {
58
- model.horizontalScroll(-distance)
59
- scheduled.current = false
60
- prevX.current = event.clientX
61
- })
62
- }
63
- }
64
- }
65
-
66
- function globalMouseUp() {
67
- prevX.current = 0
68
- if (mouseDragging) {
69
- setMouseDragging(false)
70
- }
71
- }
72
-
73
- if (mouseDragging) {
74
- window.addEventListener('mousemove', globalMouseMove, true)
75
- window.addEventListener('mouseup', globalMouseUp, true)
76
- cleanup = () => {
77
- window.removeEventListener('mousemove', globalMouseMove, true)
78
- window.removeEventListener('mouseup', globalMouseUp, true)
79
- }
80
- }
81
- return cleanup
82
- }, [model, mouseDragging, prevX])
83
-
84
- function mouseDown(event: React.MouseEvent) {
85
- // check if clicking a draggable element or a resize handle
86
- const target = event.target as HTMLElement
87
- if (target.draggable || target.dataset.resizer) {
88
- return
89
- }
90
-
91
- // otherwise do click and drag scroll
92
- if (event.button === 0) {
93
- prevX.current = event.clientX
94
- setMouseDragging(true)
95
- }
96
- }
97
-
98
- // this local mouseup is used in addition to the global because sometimes
99
- // the global add/remove are not called in time, resulting in issue #533
100
- function mouseUp(event: React.MouseEvent) {
101
- event.preventDefault()
102
- setMouseDragging(false)
103
- }
104
-
105
- function mouseLeave(event: React.MouseEvent) {
106
- event.preventDefault()
107
- }
108
-
109
- useEffect(() => {
110
- const curr = ref.current
111
- // if ctrl is held down, zoom in with y-scroll
112
- // else scroll horizontally with x-scroll
113
- function onWheel(origEvent: WheelEvent) {
114
- const event = normalizeWheel(origEvent)
115
- if (origEvent.ctrlKey === true) {
116
- origEvent.preventDefault()
117
- delta.current += event.pixelY / 500
118
- model.setScaleFactor(
119
- delta.current < 0 ? 1 - delta.current : 1 / (1 + delta.current),
120
- )
121
- if (timeout.current) {
122
- clearTimeout(timeout.current)
123
- }
124
- timeout.current = setTimeout(() => {
125
- model.setScaleFactor(1)
126
- model.zoomTo(
127
- delta.current > 0
128
- ? model.bpPerPx * (1 + delta.current)
129
- : model.bpPerPx / (1 - delta.current),
130
- )
131
- delta.current = 0
132
- }, 300)
133
- } else {
134
- // this is needed to stop the event from triggering "back button
135
- // action" on MacOSX etc. but is a heuristic to avoid preventing the
136
- // inner-track scroll behavior
137
- if (Math.abs(event.pixelX) > Math.abs(2 * event.pixelY)) {
138
- origEvent.preventDefault()
139
- }
140
- delta.current += event.pixelX
141
- if (!scheduled.current) {
142
- // use rAF to make it so multiple event handlers aren't fired per-frame
143
- // see https://calendar.perfplanet.com/2013/the-runtime-performance-checklist/
144
- scheduled.current = true
145
- window.requestAnimationFrame(() => {
146
- model.horizontalScroll(delta.current)
147
- delta.current = 0
148
- scheduled.current = false
149
- })
150
- }
151
- }
152
- }
153
- if (curr) {
154
- curr.addEventListener('wheel', onWheel)
155
- return () => {
156
- curr.removeEventListener('wheel', onWheel)
157
- }
158
- }
159
- return () => {}
160
- }, [model])
41
+ const {
42
+ guideX,
43
+ rubberbandOn,
44
+ leftBpOffset,
45
+ rightBpOffset,
46
+ numOfBpSelected,
47
+ width,
48
+ left,
49
+ anchorPosition,
50
+ handleMenuItemClick,
51
+ open,
52
+ handleClose,
53
+ mouseMove,
54
+ mouseDown: mouseDown2,
55
+ } = useRangeSelect(ref, model, true)
56
+ useWheelScroll(ref, model)
161
57
 
162
58
  return (
163
59
  <div
164
60
  ref={ref}
165
61
  data-testid="trackContainer"
166
62
  className={classes.tracksContainer}
167
- onMouseDown={mouseDown}
63
+ onMouseDown={event => {
64
+ mouseDown1(event)
65
+ mouseDown2(event)
66
+ }}
67
+ onMouseMove={mouseMove}
168
68
  onMouseUp={mouseUp}
169
- onMouseLeave={mouseLeave}
170
69
  >
171
70
  {model.showGridlines ? <Gridlines model={model} /> : null}
172
71
  {model.showCenterLine ? <CenterLine model={model} /> : null}
173
-
174
- <RubberBand
72
+ {guideX !== undefined ? (
73
+ <VerticalGuide model={model} coordX={guideX} />
74
+ ) : rubberbandOn ? (
75
+ <RubberbandSpan
76
+ leftBpOffset={leftBpOffset}
77
+ rightBpOffset={rightBpOffset}
78
+ numOfBpSelected={numOfBpSelected}
79
+ width={width}
80
+ left={left}
81
+ />
82
+ ) : null}
83
+ {anchorPosition ? (
84
+ <Menu
85
+ anchorReference="anchorPosition"
86
+ anchorPosition={{
87
+ left: anchorPosition.clientX,
88
+ top: anchorPosition.clientY,
89
+ }}
90
+ onMenuItemClick={handleMenuItemClick}
91
+ open={open}
92
+ onClose={handleClose}
93
+ menuItems={model.rubberBandMenuItems()}
94
+ />
95
+ ) : null}
96
+
97
+ <Rubberband
175
98
  model={model}
176
99
  ControlComponent={
177
- <ScaleBar
100
+ <Scalebar
178
101
  model={model}
179
102
  style={{ height: SCALE_BAR_HEIGHT, boxSizing: 'border-box' }}
180
103
  />
@@ -0,0 +1,37 @@
1
+ import React from 'react'
2
+ import { Tooltip } from '@mui/material'
3
+ import { makeStyles } from 'tss-react/mui'
4
+ import { observer } from 'mobx-react'
5
+ import { stringify } from '@jbrowse/core/util'
6
+
7
+ // locals
8
+ import { LinearGenomeViewModel } from '..'
9
+
10
+ type LGV = LinearGenomeViewModel
11
+
12
+ const useStyles = makeStyles()({
13
+ guide: {
14
+ pointerEvents: 'none',
15
+ height: '100%',
16
+ width: 1,
17
+ position: 'absolute',
18
+ zIndex: 10,
19
+ },
20
+ })
21
+
22
+ function VerticalGuide({ model, coordX }: { model: LGV; coordX: number }) {
23
+ const { classes } = useStyles()
24
+ return (
25
+ <Tooltip open placement="top" title={stringify(model.pxToBp(coordX))} arrow>
26
+ <div
27
+ className={classes.guide}
28
+ style={{
29
+ left: coordX,
30
+ background: 'red',
31
+ }}
32
+ />
33
+ </Tooltip>
34
+ )
35
+ }
36
+
37
+ export default observer(VerticalGuide)