1- import { createStyles , makeStyles , Theme , useTheme } from '@material-ui/core'
1+ import { createStyles , IconButton , makeStyles , SwipeableDrawer , Theme , Tooltip , useTheme } from '@material-ui/core'
2+ import MenuIcon from '@material-ui/icons/Menu'
23import { ODataFieldParameter , ODataParams } from '@sensenet/client-core'
34import { PathHelper } from '@sensenet/client-utils'
45import { GenericContent } from '@sensenet/default-content-types'
@@ -16,8 +17,8 @@ import { clsx } from 'clsx'
1617import React , { useContext , useEffect , useMemo , useRef , useState } from 'react'
1718import { useHistory } from 'react-router'
1819import { GridKeyEnum } from '../../../src/components/grid/enums/GridKey.enum'
19- import { ResponsivePersonalSettings } from '../../context'
20- import { useGlobalStyles } from '../../globalStyles'
20+ import { ResponsiveContext , ResponsivePersonalSettings } from '../../context'
21+ import { globals , useGlobalStyles } from '../../globalStyles'
2122import { useQuery , useSelectionService , useSnRoute } from '../../hooks'
2223import { getPrimaryActionUrl , navigateToAction } from '../../services'
2324import { ContentBreadcrumbs } from '../ContentBreadcrumbs'
@@ -72,21 +73,34 @@ const useStyles = makeStyles<Theme, { width: number }>((theme) =>
7273 boxSizing : 'border-box' ,
7374 borderBottom : theme . palette . type === 'light' ? '1px solid #DBDBDB' : '1px solid rgba(255, 255, 255, 0.11)' ,
7475 justifyContent : 'start' ,
76+ minHeight : globals . common . drawerItemHeight ,
77+ overflow : 'hidden' ,
78+ } ,
79+ breadcrumbsContent : {
80+ minWidth : 0 ,
81+ overflow : 'hidden' ,
82+ flexGrow : 1 ,
7583 } ,
7684 treeAndDatagridWrapper : {
7785 display : 'flex' ,
7886 width : '100%' ,
7987 height : '100%' ,
8088 position : 'relative' ,
81- overflow : 'auto' ,
89+ overflow : 'hidden' ,
90+ minWidth : 0 ,
8291 } ,
8392 exploreContainer : {
8493 display : 'flex' ,
8594 flexFlow : 'column' ,
8695 width : '100%' ,
96+ minWidth : 0 ,
97+ flexGrow : 1 ,
8798 position : 'relative' ,
8899 overflow : 'hidden' ,
89100 borderLeft : theme . palette . type === 'light' ? '1px solid #DBDBDB' : '1px solid rgba(255, 255, 255, 0.11)' ,
101+ [ theme . breakpoints . down ( 'sm' ) ] : {
102+ borderLeft : 'none' ,
103+ } ,
90104 } ,
91105 simpleTree : {
92106 width : ( { width } ) => `${ width } px` ,
@@ -121,6 +135,30 @@ const useStyles = makeStyles<Theme, { width: number }>((theme) =>
121135 borderLeft : '1px dashed #cececeff' ,
122136 } ,
123137 } ,
138+ mobileTreeButton : {
139+ display : 'none' ,
140+ flexShrink : 0 ,
141+ marginLeft : '4px' ,
142+ [ theme . breakpoints . down ( 'sm' ) ] : {
143+ display : 'inline-flex' ,
144+ } ,
145+ } ,
146+ mobileTreePaper : {
147+ width : '86vw' ,
148+ maxWidth : 360 ,
149+ backgroundColor : theme . palette . background . default ,
150+ overflow : 'hidden' ,
151+ } ,
152+ mobileTreeHeader : {
153+ height : globals . common . drawerItemHeight ,
154+ borderBottom : theme . palette . type === 'light' ? '1px solid #DBDBDB' : '1px solid rgba(255, 255, 255, 0.11)' ,
155+ padding : '0 12px' ,
156+ fontWeight : 500 ,
157+ } ,
158+ mobileTreeContent : {
159+ height : `calc(100% - ${ globals . common . drawerItemHeight } px)` ,
160+ overflow : 'auto' ,
161+ } ,
124162 resizeButton : {
125163 position : 'sticky' ,
126164 top : 0 ,
@@ -247,6 +285,9 @@ export function Explore({
247285 const classes = useStyles ( { width } )
248286 const globalClasses = useGlobalStyles ( )
249287 const isResizing = useRef ( false )
288+ const device = useContext ( ResponsiveContext )
289+ const [ mobileTreeOpened , setMobileTreeOpened ] = useState ( false )
290+ const isMobile = device === 'mobile'
250291
251292 const handleMouseDown = ( e : React . MouseEvent < HTMLDivElement > ) => {
252293 isResizing . current = true
@@ -370,6 +411,22 @@ export function Explore({
370411 )
371412 }
372413
414+ const handleTreeNavigate = ( item : GenericContent ) => {
415+ onNavigate ( item )
416+ setMobileTreeOpened ( false )
417+ }
418+
419+ const renderTree = ( ) => (
420+ < SimpleTree
421+ onItemClick = { handleTreeNavigate }
422+ parentPath = { PathHelper . isAncestorOf ( rootPath , currentPath ) ? rootPath : currentPath }
423+ activeItemPath = { currentPath }
424+ loadSettings = { loadTreeSettings }
425+ onNavigate = { handleTreeNavigate }
426+ rootLoaded = { false }
427+ />
428+ )
429+
373430 return (
374431 < LoadSettingsContextProvider
375432 key = { JSON . stringify ( currentChildrenLoadSettings ) }
@@ -379,33 +436,48 @@ export function Explore({
379436 < CurrentChildrenProvider loadSettings = { loadChildrenSettings } alwaysRefresh = { alwaysRefreshChildren } >
380437 < CurrentAncestorsProvider root = { rootPath } >
381438 < div className = { clsx ( classes . breadcrumbsWrapper , globalClasses . centeredVertical ) } >
382- < ContentBreadcrumbs
383- onItemClick = { ( i ) => {
384- onNavigate ( i . content )
385- } }
386- batchActions = { true }
387- />
439+ { hasTree && isMobile ? (
440+ < Tooltip title = "Open tree" placement = "bottom" >
441+ < IconButton
442+ className = { classes . mobileTreeButton }
443+ size = "small"
444+ aria-label = "Open tree"
445+ onClick = { ( ) => setMobileTreeOpened ( true ) } >
446+ < MenuIcon fontSize = "small" />
447+ </ IconButton >
448+ </ Tooltip >
449+ ) : null }
450+ < div className = { classes . breadcrumbsContent } >
451+ < ContentBreadcrumbs
452+ onItemClick = { ( i ) => {
453+ onNavigate ( i . content )
454+ } }
455+ batchActions = { true }
456+ />
457+ </ div >
388458 </ div >
389459
390460 < div className = { `${ classes . treeAndDatagridWrapper } leftTree theme-${ theme . palette . type } ` } >
391- { hasTree && (
461+ { hasTree && ! isMobile && (
392462 < div className = { classes . simpleTree } >
393463 < div className = { classes . resizeButton } onMouseDown = { handleMouseDown } >
394464 < div className = { classes . symbol } > ↔</ div >
395465 </ div >
396- < SimpleTree
397- onItemClick = { ( item ) => {
398- onNavigate ( item )
399- } }
400- parentPath = { PathHelper . isAncestorOf ( rootPath , currentPath ) ? rootPath : currentPath }
401- activeItemPath = { currentPath }
402- loadSettings = { loadTreeSettings }
403- onNavigate = { onNavigate }
404- rootLoaded = { false }
405- />
466+ { renderTree ( ) }
406467 </ div >
407468 ) }
408469 < div className = { classes . exploreContainer } > { renderContent ( ) } </ div >
470+ { hasTree && isMobile ? (
471+ < SwipeableDrawer
472+ open = { mobileTreeOpened }
473+ onOpen = { ( ) => setMobileTreeOpened ( true ) }
474+ onClose = { ( ) => setMobileTreeOpened ( false ) }
475+ ModalProps = { { keepMounted : true } }
476+ PaperProps = { { className : classes . mobileTreePaper } } >
477+ < div className = { clsx ( classes . mobileTreeHeader , globalClasses . centeredVertical ) } > Content tree</ div >
478+ < div className = { classes . mobileTreeContent } > { renderTree ( ) } </ div >
479+ </ SwipeableDrawer >
480+ ) : null }
409481 </ div >
410482 </ CurrentAncestorsProvider >
411483 </ CurrentChildrenProvider >
0 commit comments