@eureca/eureca-ui
Version:
UI component library of Eureca's user and admin apps
196 lines (177 loc) • 5.08 kB
JavaScript
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'styled-components';
import { motion } from 'framer-motion';
import { Typography, Box, useTheme } from '@material-ui/core';
import { IconContext } from 'react-icons';
import { Flex } from '../Flex';
import { Chips } from '../Chips';
import { colors } from '../../theme/colors';
import { shadows } from '../../theme';
const variants = {
closed: { height: 0 },
open: { height: 'auto' },
transition: { duration: 500, ease: 'easeInOut' },
};
const styles = muiTheme => ({
wrapper: {
boxShadow: shadows.cardShadow,
overflow: 'hidden',
width: '100%',
},
track: { fontWeight: muiTheme.typography.fontWeightRegular },
});
const Wrapper = styled(Box)`
${() => css`
border-bottom: 1px solid ${colors.gray5};
&:last-child {
border-bottom: 0;
}
`}
`;
const ModuleWrapper = styled(Box)`
${() => css`
border-bottom: 1px solid ${colors.gray5};
cursor: pointer;
`}
`;
const Module = ({ item, active, onClick, index }) => (
<ModuleWrapper
p={2}
bgcolor={item.id === active ? colors.green5 : colors.white}
onClick={() => onClick(item.id)}
>
<Flex directionRow alignCenter>
<Box mr={1} width={40}>
<IconContext.Provider
value={{
color: item.done ? colors.green1 : colors.gray3,
size: '1.3rem',
}}
>
{item.icon}
</IconContext.Provider>
</Box>
<Typography variant="subtitle2">{`Módulo ${index + 1}: ${item.title}`}</Typography>
</Flex>
</ModuleWrapper>
);
Module.propTypes = {
item: PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
done: PropTypes.bool,
type: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
}),
active: PropTypes.number,
index: PropTypes.number.isRequired,
};
const Track = ({ item, active, onClickModule, ...props }) => {
const muiTheme = useTheme();
const style = styles(muiTheme);
const moduleIsActiveOnThisTrack = item.modules.filter(modules => modules.id === active)[0];
const [isOpen, setIsOpen] = useState(Boolean(moduleIsActiveOnThisTrack));
const toggleWrapper = () => setIsOpen(!isOpen);
return (
<div style={style.wrapper}>
<Wrapper
p={2}
bgcolor={item.disabled ? colors.gray4 : colors.white}
onClick={!item.disabled ? toggleWrapper : null}
style={{
cursor: item.disabled ? 'auto' : 'pointer',
}}
>
<Flex directionRow alignCenter>
<Box mr={1} width={muiTheme.spacing(5)}>
<IconContext.Provider
value={{
color: !item.disabled ? colors.green1 : colors.gray3,
size: 32,
}}
>
{item.icon}
</IconContext.Provider>
</Box>
<Typography
variant="button"
style={{
...style.track,
color: item.disabled ? colors.gray3 : colors.gray2,
}}
>
{item.title}
</Typography>
{item.finished && (
<Box ml={1}>
<Chips
label="Encerrada"
size="small"
style={{
backgroundColor: colors.gray2,
color: colors.white,
}}
/>
</Box>
)}
</Flex>
</Wrapper>
{!item.disabled ? (
<motion.div variants={variants} animate={isOpen ? 'open' : 'closed'}>
{item.modules.map((child, index) => (
<Module
item={child}
index={index}
key={`track-${item.id}-module-${child.id}`}
active={active}
onClick={value => onClickModule(item.id, value)}
{...props}
/>
))}
</motion.div>
) : null}
</div>
);
};
Track.propTypes = {
item: PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
type: PropTypes.string.isRequired,
finished: PropTypes.bool,
disabled: PropTypes.bool,
modules: PropTypes.array.isRequired,
}),
active: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
};
const TrackNavigationSideBar = ({ data, active, onClickModule, ...props }) => {
return data.map(item => (
<Track item={item} active={active} key={item.id} onClickModule={onClickModule} {...props} />
));
};
TrackNavigationSideBar.propTypes = {
data: PropTypes.array,
onClickModule: PropTypes.func,
};
TrackNavigationSideBar.defaultProps = {
data: [
{
id: 0,
type: 'tipo',
title: 'Título',
icon: null,
finished: false,
disabled: false,
modules: [
{
id: 0,
done: false,
type: 'tipo',
name: 'Titulo',
icon: null,
},
],
},
],
onClickModule: () => {},
};
export { TrackNavigationSideBar };