Homer timeline
by PhilQ
HTML
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/css/all.min.css">
<!-- <link href="https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@300;400;700;900&display=swap" rel="stylesheet"> -->
<div class="timeline-wrapper container-fluid">
<div class="row">
<div class="timeline-left-content col bg-white dropshadow-r-2 pt-4">
<div class="timeline-inner-wrapper">
<div class="timeline-head row align-items-center">
<div class="timeline-image col-3 col-xl-2">
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" />
</div>
<div class="timeline-name col-9 col-xl-10">
<h2 class="font-weight-black text-green">Student Name</h2>
</div>
</div>
<div class="timeline row">
<div class="scrolling-box">
<div class="timeline-row row type-add">
<!-- <form> -->
<div class="col-3 col-xl-2">
<a href="#" class="fas icon"></a>
<div class="timeline-add-select-type">
<a href="#" class="timeline-select-type-lesson" title="Les"><i class="fas fa-book"></i></a>
<a href="#" class="timeline-select-type-assignment" title="Opdracht"><i class="fas fa-pencil-alt"></i></a>
<a href="#" class="timeline-select-type-document" title="Bestand"><i class="fas fa-paperclip"></i></a>
<a href="#" class="timeline-select-type-message" title="Les"><i class="fas fa-comment"></i></a>
</div>
</div>
<div class="col-9 col-xl-10">
<input type="text" class="timeline-add-title form-control" value="" placeholder="Type hier een titel" />
<span class="timeline-add-content">
<span class="timeline-add-lesson">Hier komen invoervelden per type.</span>
<!-- submit...
SCSS
// Fonts
//@import url('https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@300;400;700;900&display=swap');
// Reset
*,
:before,
:after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
// Colors
$theme-colors: ("green": #45cd98,
"yellow": #f9e5a5,
"orange": #fac694,
"red": #e37762,
"darkred": #752e38,
);
$theme-colors: map-merge($theme-colors, ("green-60": mix(map-get($theme-colors, "green"), #fff, 60%),
"green-25": mix(map-get($theme-colors, "green"), #fff, 25%),
"green-10": mix(map-get($theme-colors, "green"), #fff, 10%),
"light-grey": rgb(247, 247, 247),
"dark-grey": rgb(153, 153, 153),
"border-grey": rgb(204, 204, 204),
"cb-grey": rgb(212, 212, 212),
"cb-dark-grey": rgb(179, 179, 179),
"near-black": #222,
));
// Utilities helper
$utilities: () !default;
$utilities: map-merge(("color": (class: text,
property: color,
values: $theme-colors),
"background": (class: bg,
property: background-color,
values: $theme-colors),
"dropshadow": (class: dropshadow,
property: box-shadow,
values: ("b-1": 0 -8px 8px 8px rgba(0, 0, 0, .2),
"b-2": 0 -7px 8px 8px rgba(0, 0, 0, .2),
"r-1": -8px -8px 8px 8px rgba(0, 0, 0, .2),
"r-2": -7px -7px 8px 8px rgba(0, 0, 0, .2),
)),
// ...
// "margin": (
// responsive: true,
// property: margin,
// class: m,
// values: map-merge($spacers, (auto: auto))
// ),
// ...
), $utilities);
// Generate utility classes
@each $uk, $u in $utilities {
@each $vk, $v in map-get($u, "values") {
.#{map-get($u, "class")}-#{$vk} {
#{map-get($u, "property")}: $v;
}
}
}
// Bootstrap function (just for JSFiddle)
@function theme-color($key: "primary") {
@return map-get($theme-colors, $key);
}
.font-weight-black {
font-weight: 900;
}
// General styling
html,
body {
height: 100%;
}
body {
font-family: 'Nunito Sans', sans-serif;
font-size: 16px;
...
JavaScript
$( document ).ready(function(){
$('.timeline-row.type-add').each(function(i,el){
var $el = $( el );
// Type selector
$el.find('> div:first-child > a.icon').on('click', function(ev){
ev.preventDefault();
var $this = $( this );
if ( $this.next().hasClass('show') ) {
$this.parent().parent()
// Remove all classes starting with "type-" except "type-add"
.removeClass(function(i2, css) {
return (css.match(/(?:^|\s)type-(?!add).+/g) || []).join(' ');
});
//TODO: Reset form
}
$this.next().toggleClass('show');
})
.next().find('a').on('click', function(ev){
ev.preventDefault();
var $this = $( this );
var item_type = $this.attr('class').replace(/^timeline-select-/, '');
// Close selector
$this.parent()
.removeClass('show')
.parent().parent()
// Remove all classes starting with "type-" except "type-add"
.removeClass(function(i2, css) {
return (css.match(/(?:^|\s)type-(?!add).+/g) || []).join(' ');
})
// Set selected type
.addClass( item_type );
//TODO: set hidden input field
//TODO: only show input fields for this type (or use Vue.JS')
});
});
//TODO: focus/blur event handling (also with inputs)
//TODO: reset "+" at cancel --> when is this?
});