react-msaview 4.1.1 → 4.3.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 (91) hide show
  1. package/bundle/index.js +104 -213
  2. package/bundle/index.js.LICENSE.txt +173 -0
  3. package/bundle/index.js.map +1 -0
  4. package/dist/components/TextTrack.d.ts +2 -1
  5. package/dist/components/TextTrack.js.map +1 -1
  6. package/dist/components/Track.js.map +1 -1
  7. package/dist/components/header/Header.js +10 -3
  8. package/dist/components/header/Header.js.map +1 -1
  9. package/dist/components/header/HeaderMenu.js +199 -11
  10. package/dist/components/header/HeaderMenu.js.map +1 -1
  11. package/dist/components/header/MultiAlignmentSelector.js +3 -3
  12. package/dist/components/header/MultiAlignmentSelector.js.map +1 -1
  13. package/dist/components/header/{HeaderMenuExtra.d.ts → SettingsMenu.d.ts} +2 -2
  14. package/dist/components/header/SettingsMenu.js +141 -0
  15. package/dist/components/header/SettingsMenu.js.map +1 -0
  16. package/dist/components/header/ZoomControls.d.ts +1 -1
  17. package/dist/components/header/ZoomControls.js +1 -46
  18. package/dist/components/header/ZoomControls.js.map +1 -1
  19. package/dist/components/header/ZoomMenu.d.ts +6 -0
  20. package/dist/components/header/ZoomMenu.js +33 -0
  21. package/dist/components/header/ZoomMenu.js.map +1 -0
  22. package/dist/components/header/ZoomStar.d.ts +6 -0
  23. package/dist/components/header/ZoomStar.js +40 -0
  24. package/dist/components/header/ZoomStar.js.map +1 -0
  25. package/dist/components/tree/renderTreeCanvas.js +6 -3
  26. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  27. package/dist/flatToTree.d.ts +17 -0
  28. package/dist/flatToTree.js +41 -0
  29. package/dist/flatToTree.js.map +1 -0
  30. package/dist/model.d.ts +21 -28
  31. package/dist/model.js +47 -32
  32. package/dist/model.js.map +1 -1
  33. package/dist/parseAsn1.d.ts +34 -0
  34. package/dist/parseAsn1.js +385 -0
  35. package/dist/parseAsn1.js.map +1 -0
  36. package/dist/parseAsn1.test.d.ts +1 -0
  37. package/dist/parseAsn1.test.js +8 -0
  38. package/dist/parseAsn1.test.js.map +1 -0
  39. package/dist/parsers/ClustalMSA.d.ts +1 -1
  40. package/dist/parsers/ClustalMSA.js.map +1 -1
  41. package/dist/parsers/EmfMSA.d.ts +1 -1
  42. package/dist/parsers/FastaMSA.d.ts +1 -1
  43. package/dist/parsers/StockholmMSA.d.ts +1 -1
  44. package/dist/parsers/StockholmMSA.js.map +1 -1
  45. package/dist/renderToSvg.d.ts +3 -2
  46. package/dist/renderToSvg.js.map +1 -1
  47. package/dist/reparseTree.d.ts +1 -1
  48. package/dist/reparseTree.js +2 -0
  49. package/dist/reparseTree.js.map +1 -1
  50. package/dist/types.d.ts +38 -0
  51. package/dist/types.js +2 -0
  52. package/dist/types.js.map +1 -0
  53. package/dist/util.d.ts +6 -20
  54. package/dist/util.js +19 -0
  55. package/dist/util.js.map +1 -1
  56. package/dist/version.d.ts +1 -1
  57. package/dist/version.js +1 -1
  58. package/dist/webpack.d.ts +5 -0
  59. package/dist/webpack.js +7 -0
  60. package/dist/webpack.js.map +1 -0
  61. package/package.json +4 -3
  62. package/src/__snapshots__/parseAsn1.test.ts.snap +2400 -0
  63. package/src/components/TextTrack.tsx +2 -1
  64. package/src/components/Track.tsx +0 -2
  65. package/src/components/header/Header.tsx +11 -3
  66. package/src/components/header/HeaderMenu.tsx +215 -11
  67. package/src/components/header/MultiAlignmentSelector.tsx +7 -6
  68. package/src/components/header/SettingsMenu.tsx +169 -0
  69. package/src/components/header/ZoomControls.tsx +1 -52
  70. package/src/components/header/ZoomMenu.tsx +42 -0
  71. package/src/components/header/ZoomStar.tsx +74 -0
  72. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +1 -1
  73. package/src/components/msa/renderMSABlock.ts +1 -1
  74. package/src/components/tree/renderTreeCanvas.ts +13 -3
  75. package/src/flatToTree.ts +57 -0
  76. package/src/model.ts +75 -61
  77. package/src/parseAsn1.test.ts +11 -0
  78. package/src/parseAsn1.ts +494 -0
  79. package/src/parsers/ClustalMSA.ts +2 -1
  80. package/src/parsers/EmfMSA.ts +1 -1
  81. package/src/parsers/FastaMSA.ts +1 -1
  82. package/src/parsers/StockholmMSA.ts +4 -1
  83. package/src/renderToSvg.tsx +6 -4
  84. package/src/reparseTree.ts +3 -1
  85. package/src/types.ts +44 -0
  86. package/src/util.ts +26 -22
  87. package/src/version.ts +1 -1
  88. package/src/webpack.ts +9 -0
  89. package/dist/components/header/HeaderMenuExtra.js +0 -122
  90. package/dist/components/header/HeaderMenuExtra.js.map +0 -1
  91. package/src/components/header/HeaderMenuExtra.tsx +0 -135
@@ -5,7 +5,8 @@ import { observer } from 'mobx-react'
5
5
 
6
6
  import { colorContrast } from '../util'
7
7
 
8
- import type { ITextTrack, MsaViewModel } from '../model'
8
+ import type { MsaViewModel } from '../model'
9
+ import type { ITextTrack } from '../types'
9
10
 
10
11
  const AnnotationBlock = observer(function ({
11
12
  track,
@@ -6,8 +6,6 @@ import { observer } from 'mobx-react'
6
6
  import normalizeWheel from 'normalize-wheel'
7
7
  import { makeStyles } from 'tss-react/mui'
8
8
 
9
- // icons
10
-
11
9
  import type { MsaViewModel } from '../model'
12
10
 
13
11
  // lazies
@@ -6,10 +6,13 @@ import { IconButton } from '@mui/material'
6
6
  import { observer } from 'mobx-react'
7
7
 
8
8
  import HeaderInfoArea from './HeaderInfoArea'
9
- import HeaderMenuExtra from './HeaderMenuExtra'
9
+ import HeaderMenu from './HeaderMenu'
10
10
  import HeaderStatusArea from './HeaderStatusArea'
11
11
  import MultiAlignmentSelector from './MultiAlignmentSelector'
12
+ import SettingsMenu from './SettingsMenu'
12
13
  import ZoomControls from './ZoomControls'
14
+ import ZoomMenu from './ZoomMenu'
15
+ import ZoomStar from './ZoomStar'
13
16
 
14
17
  import type { MsaViewModel } from '../../model'
15
18
 
@@ -22,9 +25,14 @@ const Header = observer(function ({ model }: { model: MsaViewModel }) {
22
25
  }, [model, height])
23
26
  return (
24
27
  <div ref={ref} style={{ display: 'flex' }}>
25
- <HeaderMenuExtra model={model} />
28
+ <HeaderMenu model={model} />
29
+ <SettingsMenu model={model} />
26
30
  <ZoomControls model={model} />
27
- <MultiAlignmentSelector model={model} />
31
+ {model.showZoomStar ? <ZoomStar model={model} /> : null}
32
+ <ZoomMenu model={model} />
33
+ <div style={{ margin: 'auto' }}>
34
+ <MultiAlignmentSelector model={model} />
35
+ </div>
28
36
  <HeaderInfoArea model={model} />
29
37
  <Spacer />
30
38
  <HeaderStatusArea model={model} />
@@ -1,11 +1,18 @@
1
1
  import React, { lazy } from 'react'
2
2
 
3
3
  import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
4
+ import AccountTreeIcon from '@mui/icons-material/AccountTree'
4
5
  import Assignment from '@mui/icons-material/Assignment'
6
+ import FilterAlt from '@mui/icons-material/FilterAlt'
5
7
  import FolderOpen from '@mui/icons-material/FolderOpen'
8
+ import GridOn from '@mui/icons-material/GridOn'
6
9
  import List from '@mui/icons-material/List'
7
- import Menu from '@mui/icons-material/Menu'
10
+ import MoreVert from '@mui/icons-material/Menu'
11
+ import PhotoCamera from '@mui/icons-material/PhotoCamera'
12
+ import Search from '@mui/icons-material/Search'
8
13
  import Settings from '@mui/icons-material/Settings'
14
+ import Sort from '@mui/icons-material/Sort'
15
+ import Visibility from '@mui/icons-material/Visibility'
9
16
  import { observer } from 'mobx-react'
10
17
 
11
18
  import type { MsaViewModel } from '../../model'
@@ -14,8 +21,27 @@ import type { MsaViewModel } from '../../model'
14
21
  const SettingsDialog = lazy(() => import('../dialogs/SettingsDialog'))
15
22
  const MetadataDialog = lazy(() => import('../dialogs/MetadataDialog'))
16
23
  const TracklistDialog = lazy(() => import('../dialogs/TracklistDialog'))
24
+ const ExportSVGDialog = lazy(() => import('../dialogs/ExportSVGDialog'))
25
+ const FeatureFilterDialog = lazy(() => import('../dialogs/FeatureDialog'))
26
+ const UserProvidedDomainsDialog = lazy(
27
+ () => import('../dialogs/UserProvidedDomainsDialog'),
28
+ )
29
+ const InterProScanDialog = lazy(() => import('../dialogs/InterProScanDialog'))
17
30
 
18
- const HeaderMenu = observer(function ({ model }: { model: MsaViewModel }) {
31
+ const HeaderMenu = observer(({ model }: { model: MsaViewModel }) => {
32
+ const {
33
+ drawTree,
34
+ showBranchLen,
35
+ labelsAlignRight,
36
+ drawNodeBubbles,
37
+ showDomains,
38
+ actuallyShowDomains,
39
+ subFeatureRows,
40
+ drawLabels,
41
+ treeWidthMatchesArea,
42
+ noDomains,
43
+ noTree,
44
+ } = model
19
45
  return (
20
46
  <CascadingMenuButton
21
47
  menuItems={[
@@ -27,29 +53,207 @@ const HeaderMenu = observer(function ({ model }: { model: MsaViewModel }) {
27
53
  },
28
54
  },
29
55
  {
56
+ icon: Settings,
30
57
  label: 'Settings',
58
+ type: 'subMenu',
59
+ subMenu: [
60
+ {
61
+ label: 'Tree settings',
62
+ type: 'subMenu',
63
+ icon: AccountTreeIcon,
64
+ subMenu: [
65
+ {
66
+ label: 'Show branch length',
67
+ type: 'checkbox',
68
+ checked: showBranchLen,
69
+ onClick: () => {
70
+ model.setShowBranchLen(!showBranchLen)
71
+ },
72
+ },
73
+ {
74
+ label: 'Show tree',
75
+ type: 'checkbox',
76
+ checked: drawTree,
77
+ onClick: () => {
78
+ model.setDrawTree(!drawTree)
79
+ },
80
+ },
81
+ {
82
+ label: 'Draw clickable bubbles on tree branches',
83
+ type: 'checkbox',
84
+ checked: drawNodeBubbles,
85
+ onClick: () => {
86
+ model.setDrawNodeBubbles(!drawNodeBubbles)
87
+ },
88
+ },
89
+ {
90
+ label: 'Tree labels align right',
91
+ type: 'checkbox',
92
+ checked: labelsAlignRight,
93
+ onClick: () => {
94
+ model.setLabelsAlignRight(!labelsAlignRight)
95
+ },
96
+ },
97
+ {
98
+ label: 'Draw labels',
99
+ type: 'checkbox',
100
+ checked: drawLabels,
101
+ onClick: () => {
102
+ model.setDrawLabels(!drawLabels)
103
+ },
104
+ },
105
+ ...(noTree
106
+ ? []
107
+ : [
108
+ {
109
+ label: 'Make tree width fit to tree area',
110
+ type: 'checkbox' as const,
111
+ checked: treeWidthMatchesArea,
112
+ onClick: () => {
113
+ model.setTreeWidthMatchesArea(!treeWidthMatchesArea)
114
+ },
115
+ },
116
+ ]),
117
+ ],
118
+ },
119
+ {
120
+ label: 'MSA settings',
121
+ type: 'subMenu',
122
+ icon: GridOn,
123
+ subMenu: [],
124
+ },
125
+ {
126
+ label: 'More',
127
+ icon: Settings,
128
+ type: 'subMenu',
129
+ subMenu: [
130
+ {
131
+ label: 'More settings',
132
+ onClick: () => {
133
+ model.queueDialog(onClose => [
134
+ SettingsDialog,
135
+ {
136
+ model,
137
+ onClose,
138
+ },
139
+ ])
140
+ },
141
+ },
142
+ ],
143
+ },
144
+ ],
145
+ },
146
+
147
+ {
148
+ label: 'Metadata',
149
+ icon: Assignment,
31
150
  onClick: () => {
32
- model.queueDialog(onClose => [SettingsDialog, { model, onClose }])
151
+ model.queueDialog(onClose => [
152
+ MetadataDialog,
153
+ {
154
+ model,
155
+ onClose,
156
+ },
157
+ ])
33
158
  },
34
- icon: Settings,
35
159
  },
36
160
  {
37
- label: 'Metadata',
161
+ label: ' tracks',
162
+ icon: List,
38
163
  onClick: () => {
39
- model.queueDialog(onClose => [MetadataDialog, { model, onClose }])
164
+ model.queueDialog(onClose => [
165
+ TracklistDialog,
166
+ {
167
+ model,
168
+ onClose,
169
+ },
170
+ ])
40
171
  },
41
- icon: Assignment,
42
172
  },
173
+
43
174
  {
44
- label: 'Extra tracks',
175
+ label: 'Export SVG',
176
+ icon: PhotoCamera,
45
177
  onClick: () => {
46
- model.queueDialog(onClose => [TracklistDialog, { model, onClose }])
178
+ model.queueDialog(onClose => [
179
+ ExportSVGDialog,
180
+ {
181
+ onClose,
182
+ model,
183
+ },
184
+ ])
47
185
  },
48
- icon: List,
49
186
  },
187
+ {
188
+ label: 'Features/protein domains',
189
+ type: 'subMenu',
190
+ subMenu: [
191
+ {
192
+ label: 'Open domains...',
193
+ icon: FolderOpen,
194
+ onClick: () => {
195
+ model.queueDialog(handleClose => [
196
+ UserProvidedDomainsDialog,
197
+ {
198
+ handleClose,
199
+ model,
200
+ },
201
+ ])
202
+ },
203
+ },
204
+ {
205
+ label: 'Query InterProScan for domains...',
206
+ icon: Search,
207
+ onClick: () => {
208
+ model.queueDialog(handleClose => [
209
+ InterProScanDialog,
210
+ {
211
+ handleClose,
212
+ model,
213
+ },
214
+ ])
215
+ },
216
+ },
217
+ {
218
+ label: `Show domains${noDomains ? ' (no domains loaded)' : ''}`,
219
+ disabled: noDomains,
220
+ icon: Visibility,
221
+ checked: actuallyShowDomains ? showDomains : false,
222
+ type: 'checkbox',
223
+ onClick: () => {
224
+ model.setShowDomains(!showDomains)
225
+ },
226
+ },
227
+ {
228
+ label: `Use sub-row layout${noDomains ? ' (no domains loaded)' : ''}`,
229
+ disabled: noDomains,
230
+ checked: actuallyShowDomains ? subFeatureRows : false,
231
+ icon: Sort,
232
+ type: 'checkbox',
233
+ onClick: () => {
234
+ model.setSubFeatureRows(!subFeatureRows)
235
+ },
236
+ },
237
+ {
238
+ label: `Filter domains${noDomains ? ' (no domains loaded)' : ''}`,
239
+ icon: FilterAlt,
240
+ disabled: noDomains,
241
+ onClick: () => {
242
+ model.queueDialog(onClose => [
243
+ FeatureFilterDialog,
244
+ {
245
+ onClose,
246
+ model,
247
+ },
248
+ ])
249
+ },
250
+ },
251
+ ],
252
+ },
253
+ ...model.extraViewMenuItems(),
50
254
  ]}
51
255
  >
52
- <Menu />
256
+ <MoreVert />
53
257
  </CascadingMenuButton>
54
258
  )
55
259
  })
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
 
3
- import { Select } from '@mui/material'
3
+ import { MenuItem, TextField } from '@mui/material'
4
4
  import { observer } from 'mobx-react'
5
5
 
6
6
  import type { MsaViewModel } from '../../model'
@@ -12,8 +12,9 @@ const MultiAlignmentSelector = observer(function ({
12
12
  }) {
13
13
  const { currentAlignment, alignmentNames } = model
14
14
  return alignmentNames.length > 0 ? (
15
- <Select
16
- native
15
+ <TextField
16
+ select
17
+ variant="outlined"
17
18
  value={currentAlignment}
18
19
  size="small"
19
20
  onChange={event => {
@@ -23,11 +24,11 @@ const MultiAlignmentSelector = observer(function ({
23
24
  }}
24
25
  >
25
26
  {alignmentNames.map((option, index) => (
26
- <option key={`${option}-${index}`} value={index}>
27
+ <MenuItem key={`${option}-${index}`} value={index}>
27
28
  {option}
28
- </option>
29
+ </MenuItem>
29
30
  ))}
30
- </Select>
31
+ </TextField>
31
32
  ) : null
32
33
  })
33
34
  export default MultiAlignmentSelector
@@ -0,0 +1,169 @@
1
+ import React, { lazy } from 'react'
2
+
3
+ import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
4
+ import AccountTreeIcon from '@mui/icons-material/AccountTree'
5
+ import ColorLensIcon from '@mui/icons-material/ColorLens'
6
+ import GridOn from '@mui/icons-material/GridOn'
7
+ import Settings from '@mui/icons-material/Settings'
8
+ import { observer } from 'mobx-react'
9
+
10
+ import colorSchemes from '../../colorSchemes'
11
+
12
+
13
+ import type { MsaViewModel } from '../../model'
14
+
15
+ // lazies
16
+ const SettingsDialog = lazy(() => import('../dialogs/SettingsDialog'))
17
+
18
+ const SettingsMenu = observer(({ model }: { model: MsaViewModel }) => {
19
+ const {
20
+ drawTree,
21
+ showBranchLen,
22
+ labelsAlignRight,
23
+ drawNodeBubbles,
24
+ drawLabels,
25
+ treeWidthMatchesArea,
26
+ drawMsaLetters,
27
+ noTree,
28
+ bgColor,
29
+ hideGaps,
30
+ contrastLettering,
31
+ colorSchemeName,
32
+ } = model
33
+ return (
34
+ <CascadingMenuButton
35
+ menuItems={[
36
+ {
37
+ label: 'Tree settings',
38
+ type: 'subMenu',
39
+ icon: AccountTreeIcon,
40
+ subMenu: [
41
+ {
42
+ label: 'Show branch length',
43
+ type: 'checkbox',
44
+ checked: showBranchLen,
45
+ onClick: () => {
46
+ model.setShowBranchLen(!showBranchLen)
47
+ },
48
+ },
49
+ {
50
+ label: 'Show tree',
51
+ type: 'checkbox',
52
+ checked: drawTree,
53
+ onClick: () => {
54
+ model.setDrawTree(!drawTree)
55
+ },
56
+ },
57
+ {
58
+ label: 'Draw clickable bubbles on tree branches',
59
+ type: 'checkbox',
60
+ checked: drawNodeBubbles,
61
+ onClick: () => {
62
+ model.setDrawNodeBubbles(!drawNodeBubbles)
63
+ },
64
+ },
65
+ {
66
+ label: 'Tree labels align right',
67
+ type: 'checkbox',
68
+ checked: labelsAlignRight,
69
+ onClick: () => {
70
+ model.setLabelsAlignRight(!labelsAlignRight)
71
+ },
72
+ },
73
+ {
74
+ label: 'Draw labels',
75
+ type: 'checkbox',
76
+ checked: drawLabels,
77
+ onClick: () => {
78
+ model.setDrawLabels(!drawLabels)
79
+ },
80
+ },
81
+ ...(noTree
82
+ ? []
83
+ : [
84
+ {
85
+ label: 'Make tree width fit to tree area',
86
+ type: 'checkbox' as const,
87
+ checked: treeWidthMatchesArea,
88
+ onClick: () => {
89
+ model.setTreeWidthMatchesArea(!treeWidthMatchesArea)
90
+ },
91
+ },
92
+ ]),
93
+ ],
94
+ },
95
+ {
96
+ label: 'MSA settings',
97
+ type: 'subMenu',
98
+ icon: GridOn,
99
+ subMenu: [
100
+ {
101
+ label: 'Draw letters',
102
+ type: 'checkbox',
103
+ checked: drawMsaLetters,
104
+ onClick: () => {
105
+ model.setDrawMsaLetters(!drawMsaLetters)
106
+ },
107
+ },
108
+ {
109
+ label: 'Color background tiles of MSA?',
110
+ type: 'checkbox',
111
+ checked: bgColor,
112
+ onClick: () => {
113
+ model.setBgColor(!bgColor)
114
+ },
115
+ },
116
+ {
117
+ label: 'Use contrast lettering',
118
+ type: 'checkbox',
119
+ checked: contrastLettering,
120
+ onClick: () => {
121
+ model.setContrastLettering(!contrastLettering)
122
+ },
123
+ },
124
+ {
125
+ label: 'Enable hiding gappy columns?',
126
+ type: 'checkbox',
127
+ checked: hideGaps,
128
+ onClick: () => {
129
+ model.setHideGaps(!hideGaps)
130
+ },
131
+ },
132
+ ],
133
+ },
134
+ {
135
+ label: 'Color scheme',
136
+ type: 'subMenu',
137
+ icon: ColorLensIcon,
138
+ subMenu: Object.keys(colorSchemes).map(
139
+ option =>
140
+ ({
141
+ label: option,
142
+ type: 'radio',
143
+ checked: colorSchemeName === option,
144
+ onClick: () => {
145
+ model.setColorSchemeName(option)
146
+ },
147
+ }) as const,
148
+ ),
149
+ },
150
+ {
151
+ label: 'More settings',
152
+ onClick: () => {
153
+ model.queueDialog(onClose => [
154
+ SettingsDialog,
155
+ {
156
+ model,
157
+ onClose,
158
+ },
159
+ ])
160
+ },
161
+ },
162
+ ]}
163
+ >
164
+ <Settings />
165
+ </CascadingMenuButton>
166
+ )
167
+ })
168
+
169
+ export default SettingsMenu
@@ -1,16 +1,11 @@
1
1
  import React from 'react'
2
2
 
3
- import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
4
- import MoreVert from '@mui/icons-material/MoreVert'
5
- import RestartAlt from '@mui/icons-material/RestartAlt'
6
3
  import ZoomIn from '@mui/icons-material/ZoomIn'
7
4
  import ZoomOut from '@mui/icons-material/ZoomOut'
8
5
  import { IconButton } from '@mui/material'
9
6
  import { observer } from 'mobx-react'
10
7
 
11
- import { MsaViewModel } from '../../model'
12
-
13
- // icons
8
+ import type { MsaViewModel } from '../../model'
14
9
 
15
10
  const ZoomControls = observer(function ZoomControls({
16
11
  model,
@@ -33,52 +28,6 @@ const ZoomControls = observer(function ZoomControls({
33
28
  >
34
29
  <ZoomOut />
35
30
  </IconButton>
36
- <CascadingMenuButton
37
- menuItems={[
38
- {
39
- label: 'Zoom in horizontal',
40
- onClick: () => {
41
- model.zoomInHorizontal()
42
- },
43
- },
44
- {
45
- label: 'Zoom in vertical',
46
- onClick: () => {
47
- model.zoomInVertical()
48
- },
49
- },
50
- {
51
- label: 'Zoom out horizontal',
52
- onClick: () => {
53
- model.zoomOutHorizontal()
54
- },
55
- },
56
-
57
- {
58
- label: 'Zoom out vertical',
59
- onClick: () => {
60
- model.zoomOutVertical()
61
- },
62
- },
63
-
64
- {
65
- label: 'Show entire view',
66
- onClick: () => {
67
- model.showEntire()
68
- },
69
- },
70
- {
71
- label: 'Reset zoom to default',
72
- icon: RestartAlt,
73
- onClick: () => {
74
- model.setColWidth(16)
75
- model.setRowHeight(20)
76
- },
77
- },
78
- ]}
79
- >
80
- <MoreVert />
81
- </CascadingMenuButton>
82
31
  </>
83
32
  )
84
33
  })
@@ -0,0 +1,42 @@
1
+ import React from 'react'
2
+
3
+ import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
4
+ import MoreVert from '@mui/icons-material/MoreVert'
5
+ import RestartAlt from '@mui/icons-material/RestartAlt'
6
+ import { observer } from 'mobx-react'
7
+
8
+ import type { MsaViewModel } from '../../model'
9
+
10
+ const ZoomMenu = observer(function ({ model }: { model: MsaViewModel }) {
11
+ return (
12
+ <CascadingMenuButton
13
+ menuItems={[
14
+ {
15
+ label: 'Fit to view',
16
+ onClick: () => {
17
+ model.showEntire()
18
+ },
19
+ },
20
+ {
21
+ label: 'Reset zoom to default',
22
+ icon: RestartAlt,
23
+ onClick: () => {
24
+ model.resetZoom()
25
+ },
26
+ },
27
+ {
28
+ label: 'Show extra zoom options',
29
+ checked: model.showZoomStar,
30
+ type: 'checkbox',
31
+ onClick: () => {
32
+ model.setShowZoomStar(!model.showZoomStar)
33
+ },
34
+ },
35
+ ]}
36
+ >
37
+ <MoreVert />
38
+ </CascadingMenuButton>
39
+ )
40
+ })
41
+
42
+ export default ZoomMenu