Tabs.tsx 3.24 KB
Newer Older
Maxym Borodenko's avatar
Maxym Borodenko committed
1 2 3 4 5 6
//
// Customized tabs rendered using material-ui
// Child <Tab elements are converted to material-ui/Tab
// Navigation is peformed using router
//
import * as React from 'react';
Viacheslav Pavlov's avatar
i18n  
Viacheslav Pavlov committed
7
import {translate} from 'react-i18next';
Maxym Borodenko's avatar
Maxym Borodenko committed
8 9 10
import {connect} from 'react-redux';
import { Link } from 'react-router-dom';

Matija Obreza's avatar
Matija Obreza committed
11 12
import MuiTabs from '@material-ui/core/Tabs';
import MuiTab from '@material-ui/core/Tab';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
13
import {withStyles} from '@material-ui/core/styles';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
14
import Grid from '@material-ui/core/Grid';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
15 16

/*tslint:disable*/
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
17
const styles = (theme) => ({
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
18 19
  root: {
    width: '100%',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
20 21
    display: 'flex' as 'flex',
    height: 'auto',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
22
    borderBottom: '1px #ccc solid',
Oleksii Savran's avatar
Oleksii Savran committed
23 24
    alignItems: 'center' as 'center',
    justifyContent: 'space-between' as 'space-between',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
25 26 27 28
  },
  actionsArea: {
    display: 'flex' as 'flex',
    alignItems: 'center' as 'center',
Oleksii Savran's avatar
Oleksii Savran committed
29
    // position: 'sticky' as 'sticky',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
30
    overflow: 'hidden' as 'hidden',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
31
    height: '48px',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
32
    left: '100%',
Oleksii Savran's avatar
Oleksii Savran committed
33 34
    '& > * > button': {
      marginLeft: '15px',
Oleksii Savran's avatar
Oleksii Savran committed
35 36 37 38
      'html[dir="rtl"] &' : {
        marginRight: '15px',
        marginLeft: '0',
      },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
39
      [theme.breakpoints.down('sm')]: {
Oleksii Savran's avatar
Oleksii Savran committed
40 41 42 43 44
        marginTop: '5px',
        marginBottom: '5px',
      },
      [theme.breakpoints.down('xs')]: {
        marginLeft: '5px',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
45
        width: '100%',
Oleksii Savran's avatar
Oleksii Savran committed
46 47 48 49
        'html[dir="rtl"] &' : {
          marginRight: '5px',
          marginLeft: '0',
        },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
50
      },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
51
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
52 53 54 55 56 57 58
    [theme.breakpoints.down('sm')]: {
      overflow: 'initial' as 'initial',
      padding: '0',
      height: 'auto' as 'auto',
      '& > *': {
        width: '100%',
      }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
59
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
60
  },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
61
  tabsArea: {
Oleksii Savran's avatar
Oleksii Savran committed
62
    alignSelf: 'flex-end' as 'flex-end',
63 64 65
    '& a': {
      color: 'black',
    }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
66
  }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
67 68
});
/*tslint:enable*/
Maxym Borodenko's avatar
Maxym Borodenko committed
69 70

interface ITabProps extends React.Props<any> {
Matija Obreza's avatar
Matija Obreza committed
71 72 73
  name?: string;
  to: string;
  children: any;
Maxym Borodenko's avatar
Maxym Borodenko committed
74 75 76
}

class Tab extends React.Component<ITabProps, any> {
Matija Obreza's avatar
Matija Obreza committed
77 78 79 80 81 82
  public render() {
    const { to, children } = this.props;
    return (
      <Link to={ to }>{ children }</Link>
    );
  }
Maxym Borodenko's avatar
Maxym Borodenko committed
83 84 85
}

class Tabs extends React.Component<any> {
Matija Obreza's avatar
Matija Obreza committed
86
  public render() {
87
    const { tab, children, actions, classes, t } = this.props;
Maxym Borodenko's avatar
Maxym Borodenko committed
88

Matija Obreza's avatar
Matija Obreza committed
89 90 91 92 93 94 95
    const tabs = (children as Tab[]).map((ch) => {
      return {
        to: ch.props.to,
        name: ch.props.name || '',
        label: ch.props.children,
      };
    });
Maxym Borodenko's avatar
Maxym Borodenko committed
96

Matija Obreza's avatar
Matija Obreza committed
97 98 99
    const currentTab: number = tabs.findIndex((t) => {
      return t.name === tab;
    }) || 0;
Maxym Borodenko's avatar
Maxym Borodenko committed
100

Matija Obreza's avatar
Matija Obreza committed
101
    return (
Oleksii Savran's avatar
Oleksii Savran committed
102
      <Grid  container className={ `pr-10 ${classes.root}` }>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
103
        <Grid item className={ `float-left ${classes.tabsArea}` }>
104 105 106 107 108 109 110 111 112 113 114
          <MuiTabs value={ currentTab } indicatorColor="primary">
            { tabs.map((tab) => {
              return (
                <MuiTab
                  key={ tab.to }
                  label={ typeof tab.label === 'string' ? t(tab.label) : tab.label }
                  component={ Link as any }
                  { ...tab }
                />
              );
            }) }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
115
          </MuiTabs>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
116 117 118 119 120
        </Grid>
        <Grid item className={ `float-right ${classes.actionsArea}` }>
          { actions }
        </Grid>
      </Grid>
Matija Obreza's avatar
Matija Obreza committed
121 122
    );
  }
Maxym Borodenko's avatar
Maxym Borodenko committed
123 124 125
}

const mapStateToProps = (state, ownProps) => ({
Matija Obreza's avatar
Matija Obreza committed
126 127
  tab: ownProps.tab || '',
  foo: ownProps,
Maxym Borodenko's avatar
Maxym Borodenko committed
128 129
});

130
const tabs = translate()(connect(mapStateToProps, null)(withStyles(styles)(Tabs)));
Maxym Borodenko's avatar
Maxym Borodenko committed
131 132

export { tabs as default, Tab };