SidebarWrapper.tsx 8.47 KB
Newer Older
Matija Obreza's avatar
Matija Obreza committed
1
import * as React from 'react';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
2
import {bindActionCreators, compose} from 'redux';
3
import {connect} from 'react-redux';
Matija Obreza's avatar
Matija Obreza committed
4 5 6 7 8
import {withStyles} from '@material-ui/core/styles';
import SidebarDrawer from './SidebarDrawer';
import ChevronRight from '@material-ui/icons/ChevronRight';
import ChevronLeft from '@material-ui/icons/ChevronLeft';

9
import { collapseSidebar } from 'actions/layout';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
10 11
import withWidth from '@material-ui/core/withWidth/withWidth';
import {Breakpoint} from '@material-ui/core/styles/createBreakpoints';
12

Matija Obreza's avatar
Matija Obreza committed
13 14 15
interface ISidebarProps extends React.ClassAttributes<any> {
    classes: any;
    sidebarContent: any;
16 17
    collapseSidebar: (isOpen: boolean) => void;
    isOpen: boolean;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
18
    width: Breakpoint;
Oleksii Savran's avatar
Oleksii Savran committed
19
    customHeight?: boolean;
20
    right?: boolean;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
21
    alwaysCollapsible?: boolean;
Matija Obreza's avatar
Matija Obreza committed
22 23
}

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
24 25
const mobile = ['sm', 'xs'] as Breakpoint[];

Matija Obreza's avatar
Matija Obreza committed
26 27 28 29
const styles = (theme) => ({

    /* tslint:disable */
    drawer: {
30
        boxShadow: '-4px 0px 2px -1px rgba(0, 0, 0, 0.2)',
Matija Obreza's avatar
Matija Obreza committed
31 32
        position: 'sticky' as 'sticky',
        top: '72px',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
33
        zIndex: 10,
Matija Obreza's avatar
Matija Obreza committed
34
        height: 'calc(100vh - 72px)',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
35
        flex: '0 0 0',
Matija Obreza's avatar
Matija Obreza committed
36 37 38
        '& > div': {
            top: 'auto' as 'auto',
            position: 'initial' as 'initial',
39 40
            height: '100%' as '100%',
            overflow: 'visible',
Matija Obreza's avatar
Matija Obreza committed
41
        },
42 43 44 45 46 47 48
        [theme.breakpoints.down('md')]: {
          height: 'calc(100vh - 3.5rem)',
          top: '3.5rem',
        },
        [theme.breakpoints.down('sm')]: {
          maxWidth: '90%',
          position: 'fixed' as 'fixed',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
49
          zIndex: 1250,
50 51 52 53
        },
        [theme.breakpoints.down('xs')]: {
          maxWidth: '100%',
        }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
54
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
55
    drawerAlwaysCollapsible: {
Oleksii Savran's avatar
Oleksii Savran committed
56
      maxWidth: '90%!important',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
57 58 59
      position: 'fixed' as 'fixed',
      zIndex: 1250,
    },
Oleksii Savran's avatar
Oleksii Savran committed
60 61 62 63 64 65 66 67
    drawerHeightV2: {
      top: '83px',
      height: 'calc(100vh - 83px)',
      [theme.breakpoints.down('md')]: {
        height: 'calc(100vh - 3.5rem)',
        top: '3.5rem',
      },
    },
68 69 70
    drawerRight: {
      right: '0',
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
71
    drawerCollapsed: {
72 73 74 75 76
      [theme.breakpoints.down('sm')]: {
        minWidth: 'auto',
        width: 'auto',
        position: 'sticky' as 'sticky',
      }
Matija Obreza's avatar
Matija Obreza committed
77 78 79
    },
    sidebar: {
        whiteSpace: 'nowrap' as 'nowrap',
Oleksii Savran's avatar
Oleksii Savran committed
80 81 82 83
        minWidth: '360px',
        'html[dir="rtl"] &' : {
            minWidth: '420px',
        },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
84
        height: '100%',
85 86 87
        display: 'flex' as 'flex',
        flexDirection: 'column' as 'column',
        justifyContent: 'flex-start' as 'flex-start',
Matija Obreza's avatar
Matija Obreza committed
88 89 90 91 92 93 94 95 96 97
        transition: theme.transitions.create('min-width', {
            easing: theme.transitions.easing.sharp,
            duration: theme.transitions.duration.enteringScreen,
        }),
    },
    sidebarCollapsed: {
        transition: theme.transitions.create('min-width', {
            easing: theme.transitions.easing.sharp,
            duration: theme.transitions.duration.leavingScreen,
        }),
98 99
        cursor: 'e-resize',
        minWidth: theme.spacing.unit * 3,
Oleksii Savran's avatar
Oleksii Savran committed
100 101 102
        'html[dir="rtl"] &' : {
            minWidth: theme.spacing.unit * 3,
        },
Matija Obreza's avatar
Matija Obreza committed
103 104 105
        [theme.breakpoints.up('sm')]: {
            maxWidth: theme.spacing.unit * 9,
        },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
106 107 108
        [theme.breakpoints.up('md')]: {
          height: '100%',
        },
Matija Obreza's avatar
Matija Obreza committed
109
    },
110 111 112 113 114 115 116 117
    collapsedText: {
      transform: 'rotate(90deg)',
      transformOrigin: 'bottom' as 'bottom',
      width: 0,
      color: '#999494',
      fontWeight: 'bold' as 'bold',
      fontSize: '1.2rem',
    },
Matija Obreza's avatar
Matija Obreza committed
118 119
    sidebarContents: {
        width: '100%',
120
        height: 'auto' as 'auto',
121
        overflow: 'auto' as 'auto',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
122 123 124 125
        [theme.breakpoints.down('sm')]: {
          minHeight: 'calc(100% - 3rem)',
        },
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
126 127 128
    sidebarContentsAlwaysCollapsible: {
        minHeight: 'calc(100% - 3rem)',
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
129 130
    sidebarContentsCollapsed: {
      minHeight: 'calc(100% - 52px)',
131
      whiteSpace: 'nowrap' as 'nowrap',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
132 133 134
      [theme.breakpoints.down('sm')]: {
        minHeight: 'calc(100% - 38px)',
      },
Matija Obreza's avatar
Matija Obreza committed
135 136 137
    },
    /* tslint:disable */
    collapseButton: {
138
        display: 'none',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
139 140
        width: '100%',
        backgroundColor: '#e6e6e6',
141 142 143
        height: '3rem',
        flex: '1 1 100%',

Matija Obreza's avatar
Matija Obreza committed
144 145 146 147 148 149 150
        transition: theme.transitions.create('width', {
            easing: theme.transitions.easing.sharp,
            duration: theme.transitions.duration.enteringScreen,
        }),
        '&:hover': {
            backgroundColor: '#ccc',
        },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
151 152 153 154
        '& > span': {
          display: 'flex' as 'flex',
          alignItems: 'center' as 'center',
          height: '100%',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
155 156 157 158
          fontSize: '16px',
          [theme.breakpoints.down('sm')]: {
            fontSize: '1.5rem',
          },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
159
        },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
160 161 162 163
        '& > span > svg':{
            'html[dir="rtl"] &' : {
                transform: 'rotate(180deg)',
            },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
164 165
        },
        [theme.breakpoints.down('sm')]: {
166
            display: 'block' as 'block',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
167
        },
Matija Obreza's avatar
Matija Obreza committed
168
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
169 170 171 172 173 174
    collapseButtonAlwaysCollapsible:{
      display: 'block' as 'block',
      '& > span': {
          fontSize: '1.5rem',
      },
    },
Matija Obreza's avatar
Matija Obreza committed
175
    buttonCollapsed: {
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
        top: '100%',
        transition: theme.transitions.create('width', {
            easing: theme.transitions.easing.sharp,
            duration: theme.transitions.duration.leavingScreen,
        }),
        display: 'flex' as 'flex',
        alignItems: 'center' as 'center',
        '&  > svg':{
            'html[dir="rtl"] &' : {
                transform: 'rotate(180deg)',
            },
        }
    },
    pageContent: {
      zIndex: -2,
      backgroundColor: '#878787',
      opacity: 0.4,
      position: 'fixed' as 'fixed',
      width: '100%',
      height: '100%',
      top: 0,
      left: 0,
      [theme.breakpoints.up('md')]: {
        display: 'none' as 'none',
      },
    },
Matija Obreza's avatar
Matija Obreza committed
202 203 204 205
});

class SidebarWrapper extends React.Component<ISidebarProps, any> {

206 207
    setIsCollapsed = (isCollapsed: boolean) => {
        this.props.collapseSidebar(! isCollapsed);
Matija Obreza's avatar
Matija Obreza committed
208 209 210 211 212 213 214
    };

    public constructor(props: any) {
        super(props);
    }

    public render() {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
215 216
        const { sidebarContent, classes, isOpen, width, customHeight, alwaysCollapsible = false, right = false } = this.props;
        const isMobile = alwaysCollapsible || mobile.indexOf(width) !== -1;
217

Matija Obreza's avatar
Matija Obreza committed
218 219
        return (
            <SidebarDrawer
220 221
                className={ `
                  ${classes.drawer}
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
222
                  ${alwaysCollapsible && classes.drawerAlwaysCollapsible}
223 224 225 226
                  ${!isOpen ? classes.drawerCollapsed : ''}
                  ${customHeight ? classes.drawerHeightV2 : ''}
                  ${right ? classes.drawerRight : ''}
                ` }
Matija Obreza's avatar
Matija Obreza committed
227 228 229
                isOpen={ isOpen }
                variant={ 'permanent' }
            >
230
              { (!isMobile || isOpen) &&
231
                <div className={ `${ classes.sidebar }` }>
232 233
                    <div
                      onClick={() => { this.setIsCollapsed(true); }}
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
234
                      className={ `${classes.collapseButton} ${alwaysCollapsible && classes.collapseButtonAlwaysCollapsible}` }>
235 236 237 238
                      <span>
                        { right ? (<ChevronRight />):(<ChevronLeft />) } Collapse
                      </span>
                    </div>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
239
                    <div className={ ` ${classes.sidebarContents} ${alwaysCollapsible && classes.sidebarContentsAlwaysCollapsible}` }>
240 241
                        { sidebarContent }
                    </div>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
242
                  <div className={classes.pageContent}  onClick={() => { isMobile ? this.setIsCollapsed(true) : null; } }> </div>
243 244
                </div>
              }
245
              { (!isOpen && isMobile) &&
246
                <div className={ `${ classes.sidebar } ${classes.sidebarCollapsed}` }>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
247
                    <div
248 249
                      onClick={() => { this.setIsCollapsed(false); }}
                      className={ `${classes.collapseButton} ${classes.buttonCollapsed}` }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
250
                    >
251 252 253 254
                      { right ? (<ChevronLeft />):(<ChevronRight />) }
                    </div>
                    <div className={ `${classes.sidebarContents} ${classes.sidebarContentsCollapsed}` } onClick={() => { this.setIsCollapsed(false); }}>
                        <p className={ classes.collapsedText }>Open sidebar</p>
Matija Obreza's avatar
Matija Obreza committed
255 256
                    </div>
                </div>
257
              }
Matija Obreza's avatar
Matija Obreza committed
258 259 260 261 262
            </SidebarDrawer>
        );
    }
}

263
const mapStateToProps = (state, ownProps) => ({
264
    isOpen: state.user.public.sidebarOpen,
265 266 267 268 269 270
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
    collapseSidebar,
}, dispatch);

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
271
export default connect(mapStateToProps, mapDispatchToProps)(compose(withWidth(), withStyles(styles))(SidebarWrapper));