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 };