@jbrowse/app-core 2.6.1

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 (107) hide show
  1. package/LICENSE +201 -0
  2. package/dist/Assemblies/SessionAssembliesMixin.d.ts +72 -0
  3. package/dist/Assemblies/SessionAssembliesMixin.js +44 -0
  4. package/dist/Assemblies/TemporaryAssembliesMixin.d.ts +22 -0
  5. package/dist/Assemblies/TemporaryAssembliesMixin.js +45 -0
  6. package/dist/Assemblies/index.d.ts +2 -0
  7. package/dist/Assemblies/index.js +18 -0
  8. package/dist/HistoryManagement/index.d.ts +30 -0
  9. package/dist/HistoryManagement/index.js +54 -0
  10. package/dist/JBrowseConfig/index.d.ts +158 -0
  11. package/dist/JBrowseConfig/index.js +155 -0
  12. package/dist/JBrowseModel/index.d.ts +144 -0
  13. package/dist/JBrowseModel/index.js +132 -0
  14. package/dist/RootMenu/index.d.ts +68 -0
  15. package/dist/RootMenu/index.js +142 -0
  16. package/dist/index.d.ts +6 -0
  17. package/dist/index.js +22 -0
  18. package/dist/ui/App/App.d.ts +19 -0
  19. package/dist/ui/App/App.js +95 -0
  20. package/dist/ui/App/AppFab.d.ts +6 -0
  21. package/dist/ui/App/AppFab.js +32 -0
  22. package/dist/ui/App/AppToolbar.d.ts +19 -0
  23. package/dist/ui/App/AppToolbar.js +54 -0
  24. package/dist/ui/App/DialogQueue.d.ts +6 -0
  25. package/dist/ui/App/DialogQueue.js +32 -0
  26. package/dist/ui/App/Drawer.d.ts +8 -0
  27. package/dist/ui/App/Drawer.js +34 -0
  28. package/dist/ui/App/DrawerWidget.d.ts +6 -0
  29. package/dist/ui/App/DrawerWidget.js +132 -0
  30. package/dist/ui/App/ViewContainer.d.ts +9 -0
  31. package/dist/ui/App/ViewContainer.js +76 -0
  32. package/dist/ui/App/ViewContainerTitle.d.ts +6 -0
  33. package/dist/ui/App/ViewContainerTitle.js +42 -0
  34. package/dist/ui/App/ViewLauncher.d.ts +18 -0
  35. package/dist/ui/App/ViewLauncher.js +50 -0
  36. package/dist/ui/App/ViewMenu.d.ts +9 -0
  37. package/dist/ui/App/ViewMenu.js +38 -0
  38. package/dist/ui/App/ViewPanel.d.ts +19 -0
  39. package/dist/ui/App/ViewPanel.js +50 -0
  40. package/dist/ui/App/index.d.ts +1 -0
  41. package/dist/ui/App/index.js +17 -0
  42. package/dist/ui/index.d.ts +1 -0
  43. package/dist/ui/index.js +17 -0
  44. package/esm/Assemblies/SessionAssembliesMixin.d.ts +72 -0
  45. package/esm/Assemblies/SessionAssembliesMixin.js +40 -0
  46. package/esm/Assemblies/TemporaryAssembliesMixin.d.ts +22 -0
  47. package/esm/Assemblies/TemporaryAssembliesMixin.js +41 -0
  48. package/esm/Assemblies/index.d.ts +2 -0
  49. package/esm/Assemblies/index.js +2 -0
  50. package/esm/HistoryManagement/index.d.ts +30 -0
  51. package/esm/HistoryManagement/index.js +47 -0
  52. package/esm/JBrowseConfig/index.d.ts +158 -0
  53. package/esm/JBrowseConfig/index.js +148 -0
  54. package/esm/JBrowseModel/index.d.ts +144 -0
  55. package/esm/JBrowseModel/index.js +128 -0
  56. package/esm/RootMenu/index.d.ts +68 -0
  57. package/esm/RootMenu/index.js +138 -0
  58. package/esm/index.d.ts +6 -0
  59. package/esm/index.js +6 -0
  60. package/esm/ui/App/App.d.ts +19 -0
  61. package/esm/ui/App/App.js +66 -0
  62. package/esm/ui/App/AppFab.d.ts +6 -0
  63. package/esm/ui/App/AppFab.js +27 -0
  64. package/esm/ui/App/AppToolbar.d.ts +19 -0
  65. package/esm/ui/App/AppToolbar.js +49 -0
  66. package/esm/ui/App/DialogQueue.d.ts +6 -0
  67. package/esm/ui/App/DialogQueue.js +7 -0
  68. package/esm/ui/App/Drawer.d.ts +8 -0
  69. package/esm/ui/App/Drawer.js +29 -0
  70. package/esm/ui/App/DrawerWidget.d.ts +6 -0
  71. package/esm/ui/App/DrawerWidget.js +104 -0
  72. package/esm/ui/App/ViewContainer.d.ts +9 -0
  73. package/esm/ui/App/ViewContainer.js +48 -0
  74. package/esm/ui/App/ViewContainerTitle.d.ts +6 -0
  75. package/esm/ui/App/ViewContainerTitle.js +37 -0
  76. package/esm/ui/App/ViewLauncher.d.ts +18 -0
  77. package/esm/ui/App/ViewLauncher.js +25 -0
  78. package/esm/ui/App/ViewMenu.d.ts +9 -0
  79. package/esm/ui/App/ViewMenu.js +33 -0
  80. package/esm/ui/App/ViewPanel.d.ts +19 -0
  81. package/esm/ui/App/ViewPanel.js +22 -0
  82. package/esm/ui/App/index.d.ts +1 -0
  83. package/esm/ui/App/index.js +1 -0
  84. package/esm/ui/index.d.ts +1 -0
  85. package/esm/ui/index.js +1 -0
  86. package/package.json +66 -0
  87. package/src/Assemblies/SessionAssembliesMixin.ts +50 -0
  88. package/src/Assemblies/TemporaryAssembliesMixin.ts +51 -0
  89. package/src/Assemblies/index.ts +2 -0
  90. package/src/HistoryManagement/index.ts +56 -0
  91. package/src/JBrowseConfig/index.ts +173 -0
  92. package/src/JBrowseModel/index.ts +150 -0
  93. package/src/RootMenu/index.ts +157 -0
  94. package/src/index.ts +6 -0
  95. package/src/ui/App/App.tsx +117 -0
  96. package/src/ui/App/AppFab.tsx +45 -0
  97. package/src/ui/App/AppToolbar.tsx +89 -0
  98. package/src/ui/App/DialogQueue.tsx +22 -0
  99. package/src/ui/App/Drawer.tsx +56 -0
  100. package/src/ui/App/DrawerWidget.tsx +238 -0
  101. package/src/ui/App/ViewContainer.tsx +76 -0
  102. package/src/ui/App/ViewContainerTitle.tsx +55 -0
  103. package/src/ui/App/ViewLauncher.tsx +64 -0
  104. package/src/ui/App/ViewMenu.tsx +54 -0
  105. package/src/ui/App/ViewPanel.tsx +63 -0
  106. package/src/ui/App/index.ts +1 -0
  107. package/src/ui/index.ts +1 -0
@@ -0,0 +1,157 @@
1
+ import { MenuItem } from '@jbrowse/core/ui/Menu'
2
+ import { types } from 'mobx-state-tree'
3
+
4
+ export interface Menu {
5
+ label: string
6
+ menuItems: MenuItem[]
7
+ }
8
+ export function RootAppMenuMixin() {
9
+ return types.model({}).actions(s => {
10
+ const self = s as { menus: Menu[] }
11
+ return {
12
+ /**
13
+ * #action
14
+ */
15
+ setMenus(newMenus: Menu[]) {
16
+ self.menus = newMenus
17
+ },
18
+ /**
19
+ * #action
20
+ * Add a top-level menu
21
+ * @param menuName - Name of the menu to insert.
22
+ * @returns The new length of the top-level menus array
23
+ */
24
+ appendMenu(menuName: string) {
25
+ return self.menus.push({ label: menuName, menuItems: [] })
26
+ },
27
+ /**
28
+ * #action
29
+ * Insert a top-level menu
30
+ * @param menuName - Name of the menu to insert.
31
+ * @param position - Position to insert menu. If negative, counts from th
32
+ * end, e.g. `insertMenu('My Menu', -1)` will insert the menu as the
33
+ * second-to-last one.
34
+ * @returns The new length of the top-level menus array
35
+ */
36
+ insertMenu(menuName: string, position: number) {
37
+ self.menus.splice(
38
+ (position < 0 ? self.menus.length : 0) + position,
39
+ 0,
40
+ {
41
+ label: menuName,
42
+ menuItems: [],
43
+ },
44
+ )
45
+ return self.menus.length
46
+ },
47
+ /**
48
+ * #action
49
+ * Add a menu item to a top-level menu
50
+ * @param menuName - Name of the top-level menu to append to.
51
+ * @param menuItem - Menu item to append.
52
+ * @returns The new length of the menu
53
+ */
54
+ appendToMenu(menuName: string, menuItem: MenuItem) {
55
+ const menu = self.menus.find(m => m.label === menuName)
56
+ if (!menu) {
57
+ self.menus.push({ label: menuName, menuItems: [menuItem] })
58
+ return 1
59
+ }
60
+ return menu.menuItems.push(menuItem)
61
+ },
62
+ /**
63
+ * #action
64
+ * Insert a menu item into a top-level menu
65
+ * @param menuName - Name of the top-level menu to insert into
66
+ * @param menuItem - Menu item to insert
67
+ * @param position - Position to insert menu item. If negative, counts
68
+ * from the end, e.g. `insertMenu('My Menu', -1)` will insert the menu as
69
+ * the second-to-last one.
70
+ * @returns The new length of the menu
71
+ */
72
+ insertInMenu(menuName: string, menuItem: MenuItem, position: number) {
73
+ const menu = self.menus.find(m => m.label === menuName)
74
+ if (!menu) {
75
+ self.menus.push({ label: menuName, menuItems: [menuItem] })
76
+ return 1
77
+ }
78
+ const insertPosition =
79
+ position < 0 ? menu.menuItems.length + position : position
80
+ menu.menuItems.splice(insertPosition, 0, menuItem)
81
+ return menu.menuItems.length
82
+ },
83
+ /**
84
+ * #action
85
+ * Add a menu item to a sub-menu
86
+ * @param menuPath - Path to the sub-menu to add to, starting with the
87
+ * top-level menu (e.g. `['File', 'Insert']`).
88
+ * @param menuItem - Menu item to append.
89
+ * @returns The new length of the sub-menu
90
+ */
91
+ appendToSubMenu(menuPath: string[], menuItem: MenuItem) {
92
+ let topMenu = self.menus.find(m => m.label === menuPath[0])
93
+ if (!topMenu) {
94
+ const idx = this.appendMenu(menuPath[0])
95
+ topMenu = self.menus[idx - 1]
96
+ }
97
+ let { menuItems: subMenu } = topMenu
98
+ const pathSoFar = [menuPath[0]]
99
+ menuPath.slice(1).forEach(menuName => {
100
+ pathSoFar.push(menuName)
101
+ let sm = subMenu.find(mi => 'label' in mi && mi.label === menuName)
102
+ if (!sm) {
103
+ const idx = subMenu.push({ label: menuName, subMenu: [] })
104
+ sm = subMenu[idx - 1]
105
+ }
106
+ if (!('subMenu' in sm)) {
107
+ throw new Error(
108
+ `"${menuName}" in path "${pathSoFar}" is not a subMenu`,
109
+ )
110
+ }
111
+ subMenu = sm.subMenu
112
+ })
113
+ return subMenu.push(menuItem)
114
+ },
115
+ /**
116
+ * #action
117
+ * Insert a menu item into a sub-menu
118
+ * @param menuPath - Path to the sub-menu to add to, starting with the
119
+ * top-level menu (e.g. `['File', 'Insert']`).
120
+ * @param menuItem - Menu item to insert.
121
+ * @param position - Position to insert menu item. If negative, counts
122
+ * from the end, e.g. `insertMenu('My Menu', -1)` will insert the menu as
123
+ * the second-to-last one.
124
+ * @returns The new length of the sub-menu
125
+ */
126
+ insertInSubMenu(
127
+ menuPath: string[],
128
+ menuItem: MenuItem,
129
+ position: number,
130
+ ) {
131
+ let topMenu = self.menus.find(m => m.label === menuPath[0])
132
+ if (!topMenu) {
133
+ const idx = this.appendMenu(menuPath[0])
134
+ topMenu = self.menus[idx - 1]
135
+ }
136
+ let { menuItems: subMenu } = topMenu
137
+ const pathSoFar = [menuPath[0]]
138
+ menuPath.slice(1).forEach(menuName => {
139
+ pathSoFar.push(menuName)
140
+ let sm = subMenu.find(mi => 'label' in mi && mi.label === menuName)
141
+ if (!sm) {
142
+ const idx = subMenu.push({ label: menuName, subMenu: [] })
143
+ sm = subMenu[idx - 1]
144
+ }
145
+ if (!('subMenu' in sm)) {
146
+ throw new Error(
147
+ `"${menuName}" in path "${pathSoFar}" is not a subMenu`,
148
+ )
149
+ }
150
+ subMenu = sm.subMenu
151
+ })
152
+ subMenu.splice(position, 0, menuItem)
153
+ return subMenu.length
154
+ },
155
+ }
156
+ })
157
+ }
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './ui'
2
+ export * from './HistoryManagement'
3
+ export * from './JBrowseConfig'
4
+ export * from './JBrowseModel'
5
+ export * from './Assemblies'
6
+ export * from './RootMenu'
@@ -0,0 +1,117 @@
1
+ import React, { Suspense, lazy } from 'react'
2
+ import { AppBar } from '@mui/material'
3
+ import { makeStyles } from 'tss-react/mui'
4
+ import { observer } from 'mobx-react'
5
+ import { SessionWithDrawerWidgets } from '@jbrowse/core/util'
6
+ import Snackbar from '@jbrowse/core/ui/Snackbar'
7
+ import { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel'
8
+ import { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu'
9
+
10
+ // locals
11
+ import AppToolbar from './AppToolbar'
12
+ import ViewLauncher from './ViewLauncher'
13
+ import ViewPanel from './ViewPanel'
14
+ import DialogQueue from './DialogQueue'
15
+ import AppFab from './AppFab'
16
+
17
+ const DrawerWidget = lazy(() => import('./DrawerWidget'))
18
+
19
+ const useStyles = makeStyles()(theme => ({
20
+ root: {
21
+ display: 'grid',
22
+ height: '100vh',
23
+ width: '100%',
24
+ colorScheme: theme.palette.mode,
25
+ },
26
+ appContainer: {
27
+ gridColumn: 'main',
28
+ display: 'grid',
29
+ gridTemplateRows: '[menubar] min-content [components] auto',
30
+ height: '100vh',
31
+ },
32
+ viewContainer: {
33
+ overflowY: 'auto',
34
+ gridRow: 'components',
35
+ },
36
+ appBar: {
37
+ flexGrow: 1,
38
+ gridRow: 'menubar',
39
+ },
40
+ }))
41
+
42
+ type Props = {
43
+ HeaderButtons?: React.ReactElement
44
+ session: SessionWithDrawerWidgets & {
45
+ savedSessionNames: string[]
46
+ menus: { label: string; menuItems: JBMenuItem[] }[]
47
+ renameCurrentSession: (arg: string) => void
48
+ snackbarMessages: SnackbarMessage[]
49
+ popSnackbarMessage: () => unknown
50
+ }
51
+ }
52
+
53
+ const LazyDrawerWidget = observer(function (props: Props) {
54
+ const { session } = props
55
+ return (
56
+ <Suspense fallback={<React.Fragment />}>
57
+ <DrawerWidget session={session} />
58
+ </Suspense>
59
+ )
60
+ })
61
+
62
+ const ViewContainer = observer(function (props: Props) {
63
+ const { session } = props
64
+ const { views } = session
65
+ const { classes } = useStyles()
66
+ return (
67
+ <div className={classes.viewContainer}>
68
+ {views.length > 0 ? (
69
+ views.map(view => (
70
+ <ViewPanel key={`view-${view.id}`} view={view} session={session} />
71
+ ))
72
+ ) : (
73
+ <ViewLauncher {...props} />
74
+ )}
75
+
76
+ {/* blank space at the bottom of screen allows scroll */}
77
+ <div style={{ height: 300 }} />
78
+ </div>
79
+ )
80
+ })
81
+
82
+ const App = observer(function (props: Props) {
83
+ const { session } = props
84
+ const { classes } = useStyles()
85
+ const { minimized, visibleWidget, drawerWidth, drawerPosition } = session
86
+ const drawerVisible = visibleWidget && !minimized
87
+ const d = drawerVisible ? `[drawer] ${drawerWidth}px` : undefined
88
+ const grid =
89
+ drawerPosition === 'right' ? ['[main] 1fr', d] : [d, '[main] 1fr']
90
+
91
+ return (
92
+ <div
93
+ className={classes.root}
94
+ style={{ gridTemplateColumns: grid?.filter(f => !!f).join(' ') }}
95
+ >
96
+ {drawerVisible && drawerPosition === 'left' ? (
97
+ <LazyDrawerWidget session={session} />
98
+ ) : null}
99
+ <DialogQueue session={session} />
100
+ <div className={classes.appContainer}>
101
+ <AppBar className={classes.appBar} position="static">
102
+ <AppToolbar {...props} />
103
+ </AppBar>
104
+ <ViewContainer {...props} />
105
+ </div>
106
+ <AppFab session={session} />
107
+
108
+ {drawerVisible && drawerPosition === 'right' ? (
109
+ <LazyDrawerWidget session={session} />
110
+ ) : null}
111
+
112
+ <Snackbar session={session} />
113
+ </div>
114
+ )
115
+ })
116
+
117
+ export { App }
@@ -0,0 +1,45 @@
1
+ import React from 'react'
2
+ import { Fab, Tooltip } from '@mui/material'
3
+ import { makeStyles } from 'tss-react/mui'
4
+ import { observer } from 'mobx-react'
5
+ import { SessionWithDrawerWidgets } from '@jbrowse/core/util'
6
+
7
+ // icons
8
+ import LaunchIcon from '@mui/icons-material/Launch'
9
+
10
+ const useStyles = makeStyles()(theme => ({
11
+ left: {
12
+ zIndex: 10000,
13
+ position: 'fixed',
14
+ bottom: theme.spacing(2),
15
+ left: theme.spacing(2),
16
+ },
17
+ right: {
18
+ zIndex: 10000,
19
+ position: 'fixed',
20
+ bottom: theme.spacing(2),
21
+ right: theme.spacing(2),
22
+ },
23
+ }))
24
+
25
+ export default observer(function AppFab({
26
+ session,
27
+ }: {
28
+ session: SessionWithDrawerWidgets
29
+ }) {
30
+ const { minimized, activeWidgets, drawerPosition } = session
31
+ const { classes } = useStyles()
32
+
33
+ return activeWidgets.size > 0 && minimized ? (
34
+ <Tooltip title="Open drawer widget">
35
+ <Fab
36
+ className={drawerPosition === 'right' ? classes.right : classes.left}
37
+ color="primary"
38
+ data-testid="drawer-maximize"
39
+ onClick={() => session.showWidgetDrawer()}
40
+ >
41
+ <LaunchIcon />
42
+ </Fab>
43
+ </Tooltip>
44
+ ) : null
45
+ })
@@ -0,0 +1,89 @@
1
+ import React from 'react'
2
+ import { Toolbar, Tooltip } from '@mui/material'
3
+ import { makeStyles } from 'tss-react/mui'
4
+ import { observer } from 'mobx-react'
5
+ import { SessionWithDrawerWidgets } from '@jbrowse/core/util'
6
+ import DropDownMenu from '@jbrowse/core/ui/DropDownMenu'
7
+ import EditableTypography from '@jbrowse/core/ui/EditableTypography'
8
+ import AppLogo from '@jbrowse/core/ui/AppLogo'
9
+ import { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu'
10
+ import { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel'
11
+
12
+ const useStyles = makeStyles()(theme => ({
13
+ grow: {
14
+ flexGrow: 1,
15
+ },
16
+ inputBase: {
17
+ color: theme.palette.primary.contrastText,
18
+ },
19
+ inputRoot: {
20
+ '&:hover': {
21
+ backgroundColor: theme.palette.primary.light,
22
+ },
23
+ },
24
+ inputFocused: {
25
+ borderColor: theme.palette.secondary.main,
26
+ backgroundColor: theme.palette.primary.light,
27
+ },
28
+ }))
29
+
30
+ type AppSession = SessionWithDrawerWidgets & {
31
+ savedSessionNames: string[]
32
+ menus: { label: string; menuItems: JBMenuItem[] }[]
33
+ renameCurrentSession: (arg: string) => void
34
+ snackbarMessages: SnackbarMessage[]
35
+ popSnackbarMessage: () => unknown
36
+ }
37
+
38
+ const AppToolbar = observer(function ({
39
+ session,
40
+ HeaderButtons = <div />,
41
+ }: {
42
+ HeaderButtons?: React.ReactElement
43
+ session: AppSession
44
+ }) {
45
+ const { classes } = useStyles()
46
+ const { savedSessionNames, name, menus } = session
47
+
48
+ return (
49
+ <Toolbar>
50
+ {menus.map(menu => (
51
+ <DropDownMenu
52
+ key={menu.label}
53
+ menuTitle={menu.label}
54
+ menuItems={menu.menuItems}
55
+ session={session}
56
+ />
57
+ ))}
58
+ <div className={classes.grow} />
59
+ <Tooltip title="Rename Session" arrow>
60
+ <EditableTypography
61
+ value={name}
62
+ setValue={newName => {
63
+ if (savedSessionNames?.includes(newName)) {
64
+ session.notify(
65
+ `Cannot rename session to "${newName}", a saved session with that name already exists`,
66
+ 'warning',
67
+ )
68
+ } else {
69
+ session.renameCurrentSession(newName)
70
+ }
71
+ }}
72
+ variant="body1"
73
+ classes={{
74
+ inputBase: classes.inputBase,
75
+ inputRoot: classes.inputRoot,
76
+ inputFocused: classes.inputFocused,
77
+ }}
78
+ />
79
+ </Tooltip>
80
+ {HeaderButtons}
81
+ <div className={classes.grow} />
82
+ <div style={{ width: 150, maxHeight: 48 }}>
83
+ <AppLogo session={session} />
84
+ </div>
85
+ </Toolbar>
86
+ )
87
+ })
88
+
89
+ export default AppToolbar
@@ -0,0 +1,22 @@
1
+ import React, { Suspense } from 'react'
2
+ import { observer } from 'mobx-react'
3
+
4
+ // locals
5
+ import { SessionWithDrawerWidgets } from '@jbrowse/core/util'
6
+
7
+ export default observer(function ({
8
+ session,
9
+ }: {
10
+ session: SessionWithDrawerWidgets
11
+ }) {
12
+ const { DialogComponent, DialogProps } = session
13
+ return (
14
+ <>
15
+ {DialogComponent ? (
16
+ <Suspense fallback={<React.Fragment />}>
17
+ <DialogComponent {...DialogProps} />
18
+ </Suspense>
19
+ ) : null}
20
+ </>
21
+ )
22
+ })
@@ -0,0 +1,56 @@
1
+ import React from 'react'
2
+ import { Paper } from '@mui/material'
3
+ import { makeStyles } from 'tss-react/mui'
4
+ import { observer } from 'mobx-react'
5
+ import ResizeHandle from '@jbrowse/core/ui/ResizeHandle'
6
+ import { SessionWithDrawerWidgets } from '@jbrowse/core/util/types'
7
+
8
+ const useStyles = makeStyles()(theme => ({
9
+ paper: {
10
+ overflowY: 'auto',
11
+ height: '100%',
12
+ zIndex: theme.zIndex.drawer,
13
+ outline: 'none',
14
+ background: theme.palette.background.default,
15
+ },
16
+ resizeHandle: {
17
+ width: 4,
18
+ position: 'fixed',
19
+ top: 0,
20
+ zIndex: theme.zIndex.drawer + 1,
21
+ },
22
+ }))
23
+
24
+ function Drawer({
25
+ children,
26
+ session,
27
+ }: {
28
+ children: React.ReactNode
29
+ session: SessionWithDrawerWidgets
30
+ }) {
31
+ const { drawerPosition, drawerWidth } = session
32
+ const { classes } = useStyles()
33
+
34
+ return (
35
+ <Paper className={classes.paper} elevation={16} square>
36
+ {drawerPosition === 'right' ? (
37
+ <ResizeHandle
38
+ onDrag={session.resizeDrawer}
39
+ className={classes.resizeHandle}
40
+ vertical
41
+ />
42
+ ) : null}
43
+ {children}
44
+ {drawerPosition === 'left' ? (
45
+ <ResizeHandle
46
+ onDrag={session.resizeDrawer}
47
+ className={classes.resizeHandle}
48
+ style={{ left: drawerWidth }}
49
+ vertical
50
+ />
51
+ ) : null}
52
+ </Paper>
53
+ )
54
+ }
55
+
56
+ export default observer(Drawer)