@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
@@ -62,11 +62,11 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
62
62
  setValue(r0)
63
63
  }, [r0, selectedAsm])
64
64
 
65
- function navToOption(option: BaseResult) {
65
+ async function navToOption(option: BaseResult) {
66
66
  const location = option.getLocation()
67
67
  const trackId = option.getTrackId()
68
68
  if (location) {
69
- model.navToLocString(location, selectedAsm)
69
+ await model.navToLocString(location, selectedAsm)
70
70
  if (trackId) {
71
71
  model.showTrack(trackId)
72
72
  }
@@ -81,7 +81,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
81
81
  async function handleSelectedRegion(input: string) {
82
82
  try {
83
83
  if (option?.getDisplayString() === input && option.hasLocation()) {
84
- navToOption(option)
84
+ await navToOption(option)
85
85
  } else {
86
86
  const [ref, rest] = splitLast(input, ':')
87
87
  const allRefs = assembly?.allRefNamesWithLowerCase || []
@@ -89,7 +89,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
89
89
  allRefs.includes(input) ||
90
90
  (allRefs.includes(ref) && !Number.isNaN(parseInt(rest, 10)))
91
91
  ) {
92
- model.navToLocString(input, selectedAsm)
92
+ await model.navToLocString(input, selectedAsm)
93
93
  } else {
94
94
  const results = await fetchResults({
95
95
  queryString: input,
@@ -103,9 +103,9 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
103
103
  if (results.length > 1) {
104
104
  model.setSearchResults(results, input.toLowerCase())
105
105
  } else if (results.length === 1) {
106
- navToOption(results[0])
106
+ await navToOption(results[0])
107
107
  } else {
108
- model.navToLocString(input, selectedAsm)
108
+ await model.navToLocString(input, selectedAsm)
109
109
  }
110
110
  }
111
111
  }
@@ -122,11 +122,12 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
122
122
  {displayError ? <ErrorMessage error={displayError} /> : null}
123
123
  <Container className={classes.importFormContainer}>
124
124
  <form
125
- onSubmit={event => {
125
+ onSubmit={async event => {
126
126
  event.preventDefault()
127
127
  model.setError(undefined)
128
128
  if (value) {
129
- handleSelectedRegion(value)
129
+ // has it's own error handling
130
+ await handleSelectedRegion(value)
130
131
  }
131
132
  }}
132
133
  >
@@ -167,7 +168,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
167
168
  model={model}
168
169
  assemblyName={assemblyError ? undefined : selectedAsm}
169
170
  value={value}
170
- // note: minWidth 270 accomodates full width of helperText
171
+ // note: minWidth 270 accommodates full width of helperText
171
172
  minWidth={270}
172
173
  onChange={str => setValue(str)}
173
174
  onSelect={val => setOption(val)}
@@ -14,11 +14,11 @@ import {
14
14
  ExportSvgOptions,
15
15
  HEADER_OVERVIEW_HEIGHT,
16
16
  } from '..'
17
- import { Polygon, Cytobands } from './OverviewScaleBar'
17
+ import { Polygon, Cytobands } from './OverviewScalebar'
18
18
 
19
19
  type LGV = LinearGenomeViewModel
20
20
 
21
- function ScaleBar({ model, fontSize }: { model: LGV; fontSize: number }) {
21
+ function Scalebar({ model, fontSize }: { model: LGV; fontSize: number }) {
22
22
  const {
23
23
  offsetPx,
24
24
  dynamicBlocks: { totalWidthPxWithoutBorders: totalWidthPx, totalBp },
@@ -178,7 +178,7 @@ const SVGHeader = ({ model }: { model: LGV }) => {
178
178
  ) : null}
179
179
 
180
180
  <g transform={`translate(0 ${fontSize + cytobandHeight})`}>
181
- <ScaleBar model={model} fontSize={fontSize} />
181
+ <Scalebar model={model} fontSize={fontSize} />
182
182
  </g>
183
183
  <g transform={`translate(0 ${rulerHeight + cytobandHeight})`}>
184
184
  <SVGRuler model={model} fontSize={fontSize} width={width} />
@@ -1,51 +1,28 @@
1
1
  import React, { useRef, useEffect, useState } from 'react'
2
- import { Popover, Tooltip, Typography, alpha } from '@mui/material'
2
+ import { Tooltip } from '@mui/material'
3
3
  import { makeStyles } from 'tss-react/mui'
4
4
  import { getSession, stringify } from '@jbrowse/core/util'
5
5
  import { observer } from 'mobx-react'
6
6
  import { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel'
7
- import { LinearGenomeViewModel, HEADER_OVERVIEW_HEIGHT } from '..'
7
+ import { LinearGenomeViewModel } from '..'
8
+ import RubberbandSpan from './RubberbandSpan'
9
+ import { getRelativeX } from './util'
8
10
 
9
11
  type LGV = LinearGenomeViewModel
10
12
 
11
- const useStyles = makeStyles()(theme => {
12
- const { tertiary, primary } = theme.palette
13
- const background = tertiary
14
- ? alpha(tertiary.main, 0.7)
15
- : alpha(primary.main, 0.7)
16
- return {
17
- rubberBand: {
18
- height: '100%',
19
- background,
20
- position: 'absolute',
21
- zIndex: 10,
22
- textAlign: 'center',
23
- overflow: 'hidden',
24
- },
25
- rubberBandControl: {
26
- cursor: 'crosshair',
27
- width: '100%',
28
- minHeight: 8,
29
- },
30
- rubberBandText: {
31
- color: tertiary ? tertiary.contrastText : primary.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
- guide: {
42
- pointerEvents: 'none',
43
- height: '100%',
44
- width: 1,
45
- position: 'absolute',
46
- zIndex: 10,
47
- },
48
- }
13
+ const useStyles = makeStyles()({
14
+ rubberbandControl: {
15
+ cursor: 'crosshair',
16
+ width: '100%',
17
+ minHeight: 8,
18
+ },
19
+ guide: {
20
+ pointerEvents: 'none',
21
+ height: '100%',
22
+ width: 1,
23
+ position: 'absolute',
24
+ zIndex: 10,
25
+ },
49
26
  })
50
27
 
51
28
  const HoverTooltip = observer(
@@ -91,7 +68,7 @@ const HoverTooltip = observer(
91
68
  },
92
69
  )
93
70
 
94
- function OverviewRubberBand({
71
+ function OverviewRubberband({
95
72
  model,
96
73
  overview,
97
74
  ControlComponent = <div />,
@@ -105,7 +82,6 @@ function OverviewRubberBand({
105
82
  const [currentX, setCurrentX] = useState<number>()
106
83
  const [guideX, setGuideX] = useState<number>()
107
84
  const controlsRef = useRef<HTMLDivElement>(null)
108
- const rubberBandRef = useRef<HTMLDivElement>(null)
109
85
  const { classes } = useStyles()
110
86
  const mouseDragging = startX !== undefined
111
87
 
@@ -113,8 +89,7 @@ function OverviewRubberBand({
113
89
  function globalMouseMove(event: MouseEvent) {
114
90
  const ref = controlsRef.current
115
91
  if (ref && mouseDragging) {
116
- const relativeX = event.clientX - ref.getBoundingClientRect().left
117
- setCurrentX(relativeX)
92
+ setCurrentX(getRelativeX(event, ref))
118
93
  }
119
94
  }
120
95
 
@@ -172,19 +147,11 @@ function OverviewRubberBand({
172
147
  function mouseDown(event: React.MouseEvent<HTMLDivElement>) {
173
148
  event.preventDefault()
174
149
  event.stopPropagation()
175
- if (controlsRef.current) {
176
- setStartX(
177
- event.clientX - controlsRef.current.getBoundingClientRect().left,
178
- )
179
- }
150
+ setStartX(getRelativeX(event, controlsRef.current))
180
151
  }
181
152
 
182
153
  function mouseMove(event: React.MouseEvent<HTMLDivElement>) {
183
- if (controlsRef.current) {
184
- setGuideX(
185
- event.clientX - controlsRef.current.getBoundingClientRect().left,
186
- )
187
- }
154
+ setGuideX(getRelativeX(event, controlsRef.current))
188
155
  }
189
156
 
190
157
  function mouseOut() {
@@ -203,7 +170,7 @@ function OverviewRubberBand({
203
170
  />
204
171
  ) : null}
205
172
  <div
206
- className={classes.rubberBandControl}
173
+ className={classes.rubberbandControl}
207
174
  role="presentation"
208
175
  ref={controlsRef}
209
176
  onMouseDown={mouseDown}
@@ -235,66 +202,17 @@ function OverviewRubberBand({
235
202
 
236
203
  return (
237
204
  <div style={{ position: 'relative' }}>
238
- {rubberBandRef.current ? (
239
- <>
240
- <Popover
241
- className={classes.popover}
242
- classes={{
243
- paper: classes.paper,
244
- }}
245
- open
246
- anchorEl={rubberBandRef.current}
247
- anchorOrigin={{
248
- vertical: 'top',
249
- horizontal: 'left',
250
- }}
251
- transformOrigin={{
252
- vertical: 'bottom',
253
- horizontal: 'right',
254
- }}
255
- keepMounted
256
- disableRestoreFocus
257
- >
258
- <Typography>
259
- {leftBpOffset ? stringify(leftBpOffset) : ''}
260
- </Typography>
261
- </Popover>
262
- <Popover
263
- className={classes.popover}
264
- classes={{
265
- paper: classes.paper,
266
- }}
267
- open
268
- anchorEl={rubberBandRef.current}
269
- anchorOrigin={{
270
- vertical: 'top',
271
- horizontal: 'right',
272
- }}
273
- transformOrigin={{
274
- vertical: 'bottom',
275
- horizontal: 'left',
276
- }}
277
- keepMounted
278
- disableRestoreFocus
279
- >
280
- <Typography>
281
- {rightBpOffset ? stringify(rightBpOffset) : ''}
282
- </Typography>
283
- </Popover>
284
- </>
205
+ {leftBpOffset && rightBpOffset ? (
206
+ <RubberbandSpan
207
+ leftBpOffset={leftBpOffset}
208
+ rightBpOffset={rightBpOffset}
209
+ width={width}
210
+ left={left}
211
+ />
285
212
  ) : null}
286
213
  <div
287
- ref={rubberBandRef}
288
- className={classes.rubberBand}
289
- style={{
290
- left,
291
- width: Math.abs(width),
292
- height: HEADER_OVERVIEW_HEIGHT,
293
- }}
294
- />
295
- <div
296
- data-testid="rubberBand_controls"
297
- className={classes.rubberBandControl}
214
+ data-testid="rubberband_controls"
215
+ className={classes.rubberbandControl}
298
216
  role="presentation"
299
217
  ref={controlsRef}
300
218
  onMouseDown={mouseDown}
@@ -307,4 +225,4 @@ function OverviewRubberBand({
307
225
  )
308
226
  }
309
227
 
310
- export default observer(OverviewRubberBand)
228
+ export default observer(OverviewRubberband)
@@ -3,6 +3,7 @@ import { Typography, useTheme, alpha } from '@mui/material'
3
3
  import { makeStyles } from 'tss-react/mui'
4
4
  import { observer } from 'mobx-react'
5
5
 
6
+ // core
6
7
  import Base1DView, { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel'
7
8
  import { getSession, getTickDisplayStr } from '@jbrowse/core/util'
8
9
  import { ContentBlock } from '@jbrowse/core/util/blockTypes'
@@ -15,46 +16,46 @@ import {
15
16
  HEADER_OVERVIEW_HEIGHT,
16
17
  } from '..'
17
18
  import { chooseGridPitch } from '../util'
18
- import OverviewRubberBand from './OverviewRubberBand'
19
+ import OverviewRubberband from './OverviewRubberband'
19
20
 
20
21
  const wholeSeqSpacer = 2
21
22
 
22
23
  const useStyles = makeStyles()(theme => ({
23
- scaleBar: {
24
+ scalebar: {
24
25
  height: HEADER_OVERVIEW_HEIGHT,
25
26
  },
26
- scaleBarBorder: {
27
+ scalebarBorder: {
27
28
  border: '1px solid',
28
29
  },
29
- scaleBarContig: {
30
+ scalebarContig: {
30
31
  backgroundColor: theme.palette.background.default,
31
32
  position: 'absolute',
32
33
  top: 0,
33
34
  height: HEADER_OVERVIEW_HEIGHT,
34
35
  },
35
- scaleBarContigForward: {
36
+ scalebarContigForward: {
36
37
  backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 9'%3E%3Cpath d='M-.1 0L6 4.5L-.1 9' fill='none' stroke='%23ddd'/%3E%3C/svg%3E")`,
37
38
  backgroundRepeat: 'repeat',
38
39
  },
39
- scaleBarContigReverse: {
40
+ scalebarContigReverse: {
40
41
  backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 9'%3E%3Cpath d='M6 0L0 4.5L6 9' fill='none' stroke='%23ddd'/%3E%3C/svg%3E")`,
41
42
  backgroundRepeat: 'repeat',
42
43
  },
43
44
 
44
- scaleBarRefName: {
45
+ scalebarRefName: {
45
46
  position: 'absolute',
46
47
  fontWeight: 'bold',
47
48
  pointerEvents: 'none',
48
49
  zIndex: 100,
49
50
  },
50
- scaleBarLabel: {
51
+ scalebarLabel: {
51
52
  height: HEADER_OVERVIEW_HEIGHT,
52
53
  position: 'absolute',
53
54
  display: 'flex',
54
55
  justifyContent: 'center',
55
56
  pointerEvents: 'none',
56
57
  },
57
- scaleBarVisibleRegion: {
58
+ scalebarVisibleRegion: {
58
59
  position: 'absolute',
59
60
  height: HEADER_OVERVIEW_HEIGHT,
60
61
  pointerEvents: 'none',
@@ -328,19 +329,19 @@ const OverviewBox = observer(
328
329
  left: block.offsetPx + 3,
329
330
  color: canDisplayCytobands ? 'black' : refNameColor,
330
331
  }}
331
- className={classes.scaleBarRefName}
332
+ className={classes.scalebarRefName}
332
333
  >
333
334
  {refName}
334
335
  </Typography>
335
336
  <div
336
337
  className={cx(
337
- classes.scaleBarContig,
338
+ classes.scalebarContig,
338
339
  canDisplayCytobands
339
340
  ? undefined
340
341
  : reversed
341
- ? classes.scaleBarContigReverse
342
- : classes.scaleBarContigForward,
343
- !canDisplayCytobands ? classes.scaleBarBorder : undefined,
342
+ ? classes.scalebarContigReverse
343
+ : classes.scalebarContigForward,
344
+ !canDisplayCytobands ? classes.scalebarBorder : undefined,
344
345
  )}
345
346
  style={{
346
347
  left: block.offsetPx + cytobandOffset,
@@ -352,7 +353,7 @@ const OverviewBox = observer(
352
353
  ? tickLabels.map((tickLabel, labelIdx) => (
353
354
  <Typography
354
355
  key={`${JSON.stringify(block)}-${tickLabel}-${labelIdx}`}
355
- className={classes.scaleBarLabel}
356
+ className={classes.scalebarLabel}
356
357
  variant="body2"
357
358
  style={{
358
359
  left: ((labelIdx + 1) * majorPitch) / scale,
@@ -380,7 +381,7 @@ const OverviewBox = observer(
380
381
  },
381
382
  )
382
383
 
383
- const ScaleBar = observer(
384
+ const Scalebar = observer(
384
385
  ({
385
386
  model,
386
387
  scale,
@@ -397,7 +398,7 @@ const ScaleBar = observer(
397
398
  const overviewVisibleRegions = overview.dynamicBlocks
398
399
 
399
400
  const { tertiary, primary } = theme.palette
400
- const scaleBarColor = tertiary ? tertiary.light : primary.light
401
+ const scalebarColor = tertiary ? tertiary.light : primary.light
401
402
 
402
403
  if (!visibleRegions.length) {
403
404
  return null
@@ -416,13 +417,13 @@ const ScaleBar = observer(
416
417
  coord: last.reversed ? last.start : last.end,
417
418
  }) || 0
418
419
 
419
- const color = showCytobands ? '#f00' : scaleBarColor
420
+ const color = showCytobands ? '#f00' : scalebarColor
420
421
  const transparency = showCytobands ? 0.1 : 0.3
421
422
 
422
423
  return (
423
- <div className={classes.scaleBar}>
424
+ <div className={classes.scalebar}>
424
425
  <div
425
- className={classes.scaleBarVisibleRegion}
426
+ className={classes.scalebarVisibleRegion}
426
427
  style={{
427
428
  width: lastOverviewPx - firstOverviewPx,
428
429
  left: firstOverviewPx + cytobandOffset,
@@ -435,7 +436,7 @@ const ScaleBar = observer(
435
436
  return !(block instanceof ContentBlock) ? (
436
437
  <div
437
438
  key={`${JSON.stringify(block)}-${idx}`}
438
- className={classes.scaleBarContig}
439
+ className={classes.scalebarContig}
439
440
  style={{
440
441
  width: block.widthPx,
441
442
  left: block.offsetPx,
@@ -459,7 +460,7 @@ const ScaleBar = observer(
459
460
  },
460
461
  )
461
462
 
462
- function OverviewScaleBar({
463
+ function OverviewScalebar({
463
464
  model,
464
465
  children,
465
466
  }: {
@@ -484,11 +485,11 @@ function OverviewScaleBar({
484
485
 
485
486
  return (
486
487
  <div>
487
- <OverviewRubberBand
488
+ <OverviewRubberband
488
489
  model={model}
489
490
  overview={overview}
490
491
  ControlComponent={
491
- <ScaleBar model={model} overview={overview} scale={scale} />
492
+ <Scalebar model={model} overview={overview} scale={scale} />
492
493
  }
493
494
  />
494
495
  <div className={classes.overview}>
@@ -501,6 +502,6 @@ function OverviewScaleBar({
501
502
  )
502
503
  }
503
504
 
504
- export default observer(OverviewScaleBar)
505
+ export default observer(OverviewScalebar)
505
506
 
506
507
  export { Cytobands, Polygon }
@@ -94,6 +94,7 @@ function RefNameAutocomplete({
94
94
  useEffect(() => {
95
95
  let active = true
96
96
 
97
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
97
98
  ;(async () => {
98
99
  try {
99
100
  if (debouncedSearch === '' || !assemblyName) {
@@ -146,7 +147,7 @@ function RefNameAutocomplete({
146
147
  const inputBoxVal = coarseVisibleLocStrings || value || ''
147
148
 
148
149
  // heuristic, text width + icon width
149
- // + 45 accomodates help icon and search icon
150
+ // + 45 accommodates help icon and search icon
150
151
  const width = Math.min(
151
152
  Math.max(measureText(inputBoxVal, 16) + 45, minWidth),
152
153
  550,
@@ -0,0 +1,89 @@
1
+ import React, { useRef } from 'react'
2
+ import { observer } from 'mobx-react'
3
+ import { makeStyles } from 'tss-react/mui'
4
+ import { Menu } from '@jbrowse/core/ui'
5
+
6
+ // locals
7
+ import VerticalGuide from './VerticalGuide'
8
+ import RubberbandSpan from './RubberbandSpan'
9
+ import { useRangeSelect } from './hooks'
10
+ import { LinearGenomeViewModel } from '..'
11
+
12
+ type LGV = LinearGenomeViewModel
13
+
14
+ const useStyles = makeStyles()({
15
+ rubberbandControl: {
16
+ cursor: 'crosshair',
17
+ width: '100%',
18
+ minHeight: 8,
19
+ },
20
+ })
21
+
22
+ function Rubberband({
23
+ model,
24
+ ControlComponent = <div />,
25
+ }: {
26
+ model: LGV
27
+ ControlComponent?: React.ReactElement
28
+ }) {
29
+ const ref = useRef<HTMLDivElement>(null)
30
+ const { classes } = useStyles()
31
+
32
+ const {
33
+ guideX,
34
+ rubberbandOn,
35
+ leftBpOffset,
36
+ rightBpOffset,
37
+ numOfBpSelected,
38
+ width,
39
+ left,
40
+ anchorPosition,
41
+ handleMenuItemClick,
42
+ open,
43
+ handleClose,
44
+ mouseMove,
45
+ mouseDown,
46
+ mouseOut,
47
+ } = useRangeSelect(ref, model)
48
+
49
+ return (
50
+ <>
51
+ {guideX !== undefined ? (
52
+ <VerticalGuide model={model} coordX={guideX} />
53
+ ) : rubberbandOn ? (
54
+ <RubberbandSpan
55
+ leftBpOffset={leftBpOffset}
56
+ rightBpOffset={rightBpOffset}
57
+ numOfBpSelected={numOfBpSelected}
58
+ width={width}
59
+ left={left}
60
+ />
61
+ ) : null}
62
+ {anchorPosition ? (
63
+ <Menu
64
+ anchorReference="anchorPosition"
65
+ anchorPosition={{
66
+ left: anchorPosition.clientX,
67
+ top: anchorPosition.clientY,
68
+ }}
69
+ onMenuItemClick={handleMenuItemClick}
70
+ open={open}
71
+ onClose={handleClose}
72
+ menuItems={model.rubberBandMenuItems()}
73
+ />
74
+ ) : null}
75
+ <div
76
+ data-testid="rubberband_controls"
77
+ className={classes.rubberbandControl}
78
+ ref={ref}
79
+ onMouseDown={mouseDown}
80
+ onMouseMove={mouseMove}
81
+ onMouseOut={mouseOut}
82
+ >
83
+ {ControlComponent}
84
+ </div>
85
+ </>
86
+ )
87
+ }
88
+
89
+ export default observer(Rubberband)
@@ -0,0 +1,116 @@
1
+ import React, { useRef } from 'react'
2
+ import { makeStyles } from 'tss-react/mui'
3
+
4
+ import { Popover, Typography, alpha } from '@mui/material'
5
+ import { stringify, toLocale } from '@jbrowse/core/util'
6
+
7
+ const useStyles = makeStyles()(theme => {
8
+ const { primary, tertiary } = theme.palette
9
+ const background = tertiary
10
+ ? alpha(tertiary.main, 0.7)
11
+ : alpha(primary.main, 0.7)
12
+ return {
13
+ rubberband: {
14
+ height: '100%',
15
+ background,
16
+ position: 'absolute',
17
+ zIndex: 10,
18
+ textAlign: 'center',
19
+ overflow: 'hidden',
20
+ },
21
+ rubberbandControl: {
22
+ cursor: 'crosshair',
23
+ width: '100%',
24
+ minHeight: 8,
25
+ },
26
+ rubberbandText: {
27
+ color: tertiary ? tertiary.contrastText : primary.contrastText,
28
+ },
29
+ popover: {
30
+ mouseEvents: 'none',
31
+ cursor: 'crosshair',
32
+ },
33
+ paper: {
34
+ paddingLeft: theme.spacing(1),
35
+ paddingRight: theme.spacing(1),
36
+ },
37
+ }
38
+ })
39
+
40
+ interface Offset {
41
+ coord: number
42
+ refName?: string
43
+ oob?: boolean
44
+ }
45
+
46
+ function RubberbandSpan({
47
+ leftBpOffset,
48
+ rightBpOffset,
49
+ numOfBpSelected,
50
+ left,
51
+ width,
52
+ }: {
53
+ leftBpOffset: Offset
54
+ rightBpOffset: Offset
55
+ numOfBpSelected?: number
56
+ left: number
57
+ width: number
58
+ }) {
59
+ const ref = useRef(null)
60
+ const { classes } = useStyles()
61
+ return (
62
+ <>
63
+ {ref.current ? (
64
+ <>
65
+ <Popover
66
+ className={classes.popover}
67
+ classes={{ paper: classes.paper }}
68
+ open
69
+ anchorEl={ref.current}
70
+ anchorOrigin={{
71
+ vertical: 'top',
72
+ horizontal: 'left',
73
+ }}
74
+ transformOrigin={{
75
+ vertical: 'bottom',
76
+ horizontal: 'right',
77
+ }}
78
+ keepMounted
79
+ disableRestoreFocus
80
+ >
81
+ <Typography>{stringify(leftBpOffset)}</Typography>
82
+ </Popover>
83
+ <Popover
84
+ className={classes.popover}
85
+ classes={{
86
+ paper: classes.paper,
87
+ }}
88
+ open
89
+ anchorEl={ref.current}
90
+ anchorOrigin={{
91
+ vertical: 'top',
92
+ horizontal: 'right',
93
+ }}
94
+ transformOrigin={{
95
+ vertical: 'bottom',
96
+ horizontal: 'left',
97
+ }}
98
+ keepMounted
99
+ disableRestoreFocus
100
+ >
101
+ <Typography>{stringify(rightBpOffset)}</Typography>
102
+ </Popover>
103
+ </>
104
+ ) : null}
105
+ <div ref={ref} className={classes.rubberband} style={{ left, width }}>
106
+ {numOfBpSelected ? (
107
+ <Typography variant="h6" className={classes.rubberbandText}>
108
+ {toLocale(numOfBpSelected)} bp
109
+ </Typography>
110
+ ) : null}
111
+ </div>
112
+ </>
113
+ )
114
+ }
115
+
116
+ export default RubberbandSpan