JSFiddle - React, Tailwind, and code Playground
by Tyler Brown
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
SCSS
* {
transition: all 200ms;
}
.ex {
display: flex;
flex: 1;
flex-direction: row;
align-items: center;
border: 1px solid #CCC;
border-bottom: 0;
font-family: 'Avenir', 'Helvetica', Arial;
&.active .ex-name {
color: black;
font-weight: bold;
}
&.inactive .ex-name {
color: #CCC;
}
&-name {
width: 300px;
/* border: 1px solid black; */
padding: 0 12px;
}
&-weeks {
flex: 1;
border-left: 1px solid #CCC;
display: flex;
flex-direction: row;
&-week {
border-right: 1px solid #CCC;
width: 30px;
height: 30px;
&.date {
text-align: center;
font-size: 11px;
}
&.phase-1 { background-color: #FDD; }
&.phase-2 { background-color: #FFD; }
&.phase-3 { background-color: #DFD; }
&.phase-4 { background-color: #DFF; }
&.phase-5 { background-color: #DDF; }
&.phase-1.active { background-color: #F88; }
&.phase-2.active { background-color: #FF8; }
&.phase-3.active { background-color: #8F8; }
&.phase-4.active { background-color: #8FF; }
&.phase-5.active { background-color: #88F; }
.dot {
width: 24px;
height: 24px;
/* background-color: #CCC; */
border-radius: 100px;
margin: 3px;
}
&.on .dot {
background-color: #CCC;
}
&.on.active .dot {
background-color: #333;
}
}
}
}
Babel + JSX
const weeks = [...Array(12).keys()].map(n => n + 1);
const weekPhaseMap = {
1: 1,
2: 1,
3: 1,
4: 2,
5: 2,
6: 2,
7: 3,
8: 3,
9: 4,
10: 4,
11: 4,
12: 5,
};
const weekDateMap = {
1: '1/25',
2: '2/1',
3: '2/8',
4: '2/15',
5: '2/22',
6: '3/1',
7: '3/8',
8: '3/15',
9: '3/22',
10: '3/29',
11: '4/5',
12: '4/12',
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
activeWeek: 1,
};
}
onWeekMouseEnter(week) {
this.setState({activeWeek: week});
}
render() {
return (
<div>
{this.state.activeWeek || 'none'}
<div className="exercise ex">
<div className="ex-name"></div>
<div className="ex-weeks">
{weeks.map((week) => {
const date = weekDateMap[week];
return (
<div className="ex-weeks-week date">{date}</div>
);
})}
</div>
</div>
{exercises.map((exercise) => {
const isActive = this.state.activeWeek >= exercise.startWeek && this.state.activeWeek <= exercise.endWeek;
return (
<div className={`exercise ex ${isActive ? 'active' : 'inactive'}`}>
<div className="ex-name">{exercise.name}</div>
<div className="ex-weeks">
{weeks.map((week) => {
const isOn = week >= exercise.startWeek && week <= exercise.endWeek;
const isActiveWeek = this.state.activeWeek == week;
const phase = weekPhaseMap[week];
return (
<div className={`ex-weeks-week ${isOn ? 'on' : 'off'} ${isActiveWeek ? 'active' : 'inactive'} phase-${phase}`} onMouseEnter={this.onWeekMouseEnter.bind(this, week)}><div className="dot" /></div>
);
})}
</div>
</div>
);
})}
</div>
);
}
};
const exercises = [
{name: "standing abduction w/o...