Merge branch 'feat/asidenav_and_form_rework' into 'master'

Feat/asidenav and form rework

See merge request !32
This commit is contained in:
Felix Hamann 2018-06-21 00:27:45 +02:00
commit 710ace42bf
11 changed files with 224 additions and 357 deletions

View File

@ -12,20 +12,22 @@
$if not $ Just HomeR == mcurrentRoute
^{breadcrumbs}
$maybe headline <- contentHeadline
<h1>
^{headline}
<div .main__content-body>
<!-- prime page actions -->
^{pageactionprime}
$maybe headline <- contentHeadline
<h1>
^{headline}
<!-- alerts -->
$forall (status, msg) <- mmsgs
$with status2 <- bool status "info" (status == "")
<div class="alert alert-#{status2}">
<div .alert__content>
#{msg}
<!-- prime page actions -->
^{pageactionprime}
<!-- actual content -->
<!-- alerts -->
$forall (status, msg) <- mmsgs
$with status2 <- bool status "info" (status == "")
<div class="alert alert-#{status2}">
<div .alert__content>
#{msg}
^{widget}
<!-- actual content -->
^{widget}

View File

@ -131,17 +131,19 @@ h4 {
/* LAYOUT */
.main {
display: flex;
min-height: calc(100vh - var(--header-height));
overflow: hidden;
}
@media (max-width: 768px) {
.main {
min-height: calc(100vh - var(--header-height-collapsed));
}
}
.main__content {
position: relative;
background-color: white;
padding: 0 40px;
padding-bottom: 60px;
flex: 1;
z-index: 0;
overflow: hidden;
@ -154,6 +156,17 @@ h4 {
}
}
.main__content-body {
padding: 10px 40px 60px;
}
@media (max-width: 768px) {
.main__content-body {
padding: 10px 20px 60px;
}
}
.pseudo-focus {
outline: 5px auto var(--color-light);
outline: 5px auto -webkit-focus-ring-color;

View File

@ -3,27 +3,6 @@
window.utils = window.utils || {};
// makes <label> smaller if <input> is focussed
window.utils.reactiveInputLabel = function(input, label) {
// updates to dom
if (input.value.length > 0) {
label.classList.add('reactive-label--small');
}
// add event listeners
input.addEventListener('focus', function() {
label.classList.add('reactive-label--small');
});
label.addEventListener('click', function() {
label.classList.add('reactive-label--small');
input.focus();
});
input.addEventListener('blur', function() {
if (input.value.length < 1) {
label.classList.remove('reactive-label--small');
}
});
};
// allows for multiple file uploads with separate inputs
window.utils.reactiveFileUpload = function(input, formGroup) {
var currValidInputCount = 0;
@ -143,6 +122,8 @@
if (isMulti) {
wrapper = document.createElement('div');
wrapper.classList.add('file-input__wrapper');
console.log(wrapper);
// TODO: fix file input
formGroup.insertBefore(wrapper, input);
}
input.remove();
@ -182,54 +163,37 @@
setup();
}
window.utils.reactiveFormGroup = function(formGroup, input) {
// updates to dom
if (input.value.length > 0) {
formGroup.classList.add('form-group--valid');
} else {
formGroup.classList.remove('form-group--valid');
window.utils.initializeCheckboxRadio = function(input, type) {
if (!input.parentElement.classList.contains(type)) {
var parentEl = input.parentElement;
var wrapperEl = document.createElement('div');
var labelEl = document.createElement('label');
wrapperEl.classList.add(type);
labelEl.setAttribute('for', input.id);
wrapperEl.appendChild(input);
wrapperEl.appendChild(labelEl);
parentEl.appendChild(wrapperEl);
}
input.addEventListener('input', function() {
formGroup.classList.remove('form-group--has-error');
if (input.value.length > 0) {
formGroup.classList.add('form-group--valid');
} else {
formGroup.classList.remove('form-group--valid');
}
});
};
}
})();
document.addEventListener('DOMContentLoaded', function() {
// setup reactive labels
Array.from(document.querySelectorAll('.reactive-label')).forEach(function(label) {
var input = document.querySelector('#' + label.getAttribute('for'));
if (!input) {
console.error('No input found for ReactiveLabel! Targeted input: \'#%s\'', label.getAttribute('for'));
label.classList.remove('reactive-label');
return false;
}
// initialize checkboxes
Array.from(document.querySelectorAll('input[type="checkbox"]')).forEach(function(inp) {
window.utils.initializeCheckboxRadio(inp, 'checkbox');
});
var parent = label.parentElement;
var type = input.getAttribute('type');
var isListening = !RegExp(['date', 'checkbox', 'radio', 'hidden', 'file'].join('|')).test(type);
var isInFormGroup = parent.classList.contains('form-group') && parent.classList.contains('form-group--required');
if (isInFormGroup) {
window.utils.reactiveFormGroup(parent, input);
}
if (isListening) {
window.utils.reactiveInputLabel(input, label);
} else {
label.classList.remove('reactive-label');
}
// initialize radios
Array.from(document.querySelectorAll('input[type="radio"]')).forEach(function(inp) {
window.utils.initializeCheckboxRadio(inp, 'radio');
});
// initialize file-upload-fields
Array.from(document.querySelectorAll('input[type="file"]')).map(function(inp) {
Array.from(document.querySelectorAll('input[type="file"]')).forEach(function(inp) {
var formGroup = inp.parentNode;
while (!formGroup.classList.contains('form-group') && formGroup !== document.body) {
formGroup = formGroup.parentNode;
@ -238,7 +202,7 @@ document.addEventListener('DOMContentLoaded', function() {
});
// initialize file-checkbox-fields
Array.from(document.querySelectorAll('.js-file-checkbox')).map(function(inp) {
Array.from(document.querySelectorAll('.js-file-checkbox')).forEach(function(inp) {
window.utils.reactiveFileCheckbox(inp);
});
});

View File

@ -8,33 +8,27 @@ form {
position: relative;
display: flex;
display: grid;
grid-template-columns: 25% max-content;
grid-auto-columns: 25%;
grid-template-columns: 1fr 3fr;
grid-gap: 5px;
justify-content: flex-start;
align-items: center;
margin: 17px 0;
padding-left: 10px;
align-items: baseline;
border-left: 2px solid transparent;
+ .form-group {
margin-top: 17px;
}
}
.form-group__label {
width: 25%;
white-space: nowrap;
font-weight: 600;
}
@media (max-width: 999px) {
@media (max-width: 768px) {
.form-group {
grid-template-columns: 1fr;
grid-template-rows: 30px;
align-items: baseline;
margin-top: 17px;
flex-direction: column;
> * {
width: 100%;
}
}
}
@ -43,28 +37,30 @@ input[type="text"],
input[type="password"],
input[type="url"],
input[type="number"],
input[type="email"] {
input[type="email"],
input[type*="date"],
input[type*="time"] {
/* from bulma.css */
background-color: #fff;
border-color: #dbdbdb;
color: #363636;
box-shadow: inset 0 2px 3px 1px rgba(50,50,50,.1);
min-width: 400px;
border-color: #dbdbdb;
background-color: #f3f3f3;
box-shadow: inset 0 1px 2px 1px rgba(50,50,50,.05);
width: 100%;
max-width: 600px;
-webkit-appearance: none;
align-items: center;
border: 1px solid transparent;
border-radius: 4px;
display: inline-flex;
font-size: 1rem;
height: 2.25em;
justify-content: flex-start;
line-height: 1.5;
padding-bottom: calc(.375em - 1px);
padding-left: calc(.625em - 1px);
padding-right: calc(.625em - 1px);
padding-top: calc(.375em - 1px);
position: relative;
vertical-align: top;
padding: 4px 13px;
}
input[type*="date"],
input[type*="time"] {
width: 50%;
min-width: 240px;
}
.form-group--required {
@ -111,25 +107,19 @@ input[type="email"]:focus {
/* TEXTAREAS */
textarea {
width: 100%;
height: 170px;
max-width: 600px;
font-size: 1rem;
line-height: 1.5;
color: #363636;
background-color: #f3f3f3;
padding: 4px 13px;
-webkit-appearance: none;
appearance: none;
border: 1px solid transparent;
border: 1px solid #dbdbdb;
border-radius: 2px;
display: inline-flex;
font-size: 1rem;
height: 170px;
width: 400px;
line-height: 1.5;
padding-bottom: calc(.375em - 1px);
padding-left: calc(.625em - 1px);
padding-right: calc(.625em - 1px);
padding-top: calc(.375em - 1px);
position: relative;
vertical-align: top;
background-color: #fff;
border-color: #dbdbdb;
color: #363636;
box-shadow: inset 0 1px 2px rgba(10,10,10,.1);
box-shadow: inset 0 1px 2px 1px rgba(50,50,50,.05);
}
textarea:focus {
@ -179,12 +169,12 @@ input[type="checkbox"]:checked::after {
.radio {
position: relative;
> [type="checkbox"],
> [type="radio"] {
[type="checkbox"],
[type="radio"] {
display: none;
}
> label {
label {
display: block;
height: 30px;
width: 30px;
@ -194,8 +184,8 @@ input[type="checkbox"]:checked::after {
cursor: pointer;
}
> label::before,
> label::after {
label::before,
label::after {
content: '';
position: absolute;
top: 14px;
@ -207,52 +197,36 @@ input[type="checkbox"]:checked::after {
transition: all .2s;
}
> label::before {
label::before {
width: 20px;
height: 2px;
transform: scale(0.1, 0.1);
}
> label::after {
label::after {
width: 20px;
height: 2px;
transform: scale(0.1, 0.1);
}
> :checked + label {
:checked + label {
background-color: var(--color-light);
text-decoration: underline;
}
&:hover > label {
background-color: var(--color-lighter);
}
&:hover > label::before {
transform: scale(0.8, 0.4);
}
> :checked + label::before {
:checked + label::before {
transform: scale(1, 1) rotate(45deg);
}
> :checked + label:hover::after,
> :checked + label:hover::before {
transform: scale(1, 1) rotate(0deg);
}
&:hover > label::after {
transform: scale(0.8, 0.4);
}
> :checked + label::after {
:checked + label::after {
transform: scale(1, 1) rotate(-45deg);
}
}
.radio > label::before {
.radio label::before {
transform: scale(0.01, 0.01) rotate(45deg);
}
.radio > label::after {
.radio label::after {
transform: scale(0.01, 0.01) rotate(-45deg);
}
@ -268,29 +242,6 @@ input[type="checkbox"]:checked::after {
z-index: -1;
}
/* REACTIVE LABELS */
.reactive-label {
cursor: text;
color: var(--color-fontsec);
transform: translate(0, 0);
transition: all .1s;
}
.reactive-label--small {
cursor: default;
color: var(--color-font);
}
@media (max-width: 999px) {
.reactive-label {
position: relative;
transform: translate(2px, 30px);
}
.reactive-label--small {
transform: translate(2px, 0px);
color: var(--color-fontsec);
/*font-size: 14px;*/
}
}
/* CUSTOM FILE INPUT */
input[type="file"].js-file-input {
color: white;
@ -310,8 +261,6 @@ input[type="file"].js-file-input {
.file-checkbox__container,
.file-input__unpack {
grid-column-start: 2;
display: flex;
justify-content: space-between;
margin: 4px 0;
}
.file-input__label,
@ -397,7 +346,7 @@ input[type="file"].js-file-input {
.file-input__container--valid > .file-input__remover {
display: block;
}
@media (max-width: 999px) {
@media (max-width: 768px) {
.file-input__wrapper,
.file-input__container,
.file-checkbox__container,

View File

@ -23,17 +23,17 @@
}
}
@media (max-width: 999px) {
@media (max-width: 1024px) {
.modal {
min-width: 80vw;
}
}
@media (max-width: 666px) {
@media (max-width: 768px) {
.modal {
min-width: 90vw;
}
}
@media (max-width: 444px) {
@media (max-width: 425px) {
.modal {
min-width: calc(100vw - 20px);
}

View File

@ -30,15 +30,4 @@ $newline never
<a .asidenav__link-wrapper href=@{menuItemRoute}>#{menuItemLabel}
$of _
<div .asidenav__box>
<h3 .asidenav__box-title>
Themes (dev)
<select #theme-selector>
<option value="default">Default Blue
<option value="neutral-blue">Neutral Blue
<option value="aberdeen-reds">Aberdeen Reds
<option value="mint-green">Mint Green
<option value="sky-love">Sky Love
<div .asidenav__toggler>

View File

@ -84,41 +84,18 @@
document.addEventListener('DOMContentLoaded', function() {
utils.aside(document.querySelector('.main__aside'));
var asidenavEl = document.querySelector('.main__aside');
var mainEl = document.querySelector('.main__content');
// remove me before flight:
// EXPERIMENTAL
var selector = document.querySelector('#theme-selector');
var lsTheme = window.localStorage.getItem('theme');
setTheme(lsTheme || 'default');
var options = Array.from(selector.querySelectorAll('option'))
.reduce(function(acc, optEl) {
if (!acc.includes(optEl.value)) {
acc.push(optEl.value);
}
return acc;
},
[]);
asidenavEl.style.height = `${mainEl.clientHeight + 75}px`;
selector.addEventListener('change', function(event) {
setTheme(event.target.value);
window.addEventListener('resize', function() {
window.requestAnimationFrame(function() {
asidenavEl.style.height = `${mainEl.clientHeight + 75}px`;
});
});
function setTheme(theme) {
window.localStorage.setItem('theme', theme);
document.body.className = 'theme--' + theme;
}
// random theme on loading and again every 20 seconds
// setInterval(function() {
// setTheme(randomOption());
// }, 20000);
// function randomOption() {
// return options[Math.floor(Math.random() * options.length)];
// }
// // initial theme
// setTheme(randomOption());
// TODO: make it swipeable on mobile and narrower
// utils.aside(asidenavEl);
});

View File

@ -1,39 +1,26 @@
.main__aside {
position: relative;
position: absolute;
background-color: var(--color-dark);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
z-index: 1;
flex: 0 0 300px;
}
.main__aside--transitioning {
transition: flex-basis .2s ease;
}
.main__aside--transitioning .asidenav__box{
transition: opacity .2s ease;
min-height: calc(100% - 80px);
transition: all .2s ease-out;
width: 300px;
~ .main__content {
padding-left: 300px;
transition: padding-left .2s ease-out;
}
}
.asidenav {
width: 300px;
color: white;
}
.js-show-hide__target {
overflow: visible;
}
.js-show-hide__toggle::before {
top: 14px;
right: 12px;
left: auto !important;
}
.js-show-hide__toggle:hover::before,
.js-show-hide--collapsed .js-show-hide__toggle::before {
top: 10px !important;
right: 8px !important;
}
.js-show-hide--collapsed .js-show-hide__toggle:hover::before {
top: 14px !important;
right: 12px !important;
}
.asidenav__box {
transition: opacity .2s ease;
}
.asidenav__box-title {
@ -46,7 +33,6 @@
.asidenav__list-item {
position: relative;
color: var(--color-lightwhite);
margin: 4px 0;
padding-left: 10px;
&:hover {
@ -69,6 +55,10 @@
width: 200px;
}
}
+ .asidenav__list-item {
margin-top: 4px;
}
}
.asidenav__list-item--active {
@ -88,8 +78,8 @@
.asidenav__link-wrapper {
position: relative;
display: flex;
height: 43px;
align-items: center;
padding: 7px 0;
justify-content: flex-start;
color: var(--color-lightwhite);
z-index: 1;
@ -109,6 +99,7 @@
}
.asidenav__link-label {
line-height: 1;
padding-left: 13px;
}
@ -139,15 +130,8 @@
background-color: white;
color: var(--color-link);
}
.asidenav__nested-list {
transform: translateX(100%);
opacity: 1;
width: 200px;
}
}
.asidenav__link-wrapper {
.asidenav__link-wrapper {
padding-left: 13px;
padding-right: 13px;
border-left: 20px solid white;
@ -156,100 +140,86 @@
}
}
.asidenav__toggler {
position: absolute;
bottom: 20px;
height: 50px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
transition: background-color .2s ease;
border-top: 1px solid var(--color-lightwhite);
border-bottom: 1px solid var(--color-lightwhite);
cursor: pointer;
/* STATE COLLAPSED */
@media (max-width: 768px) {
&::before {
content: '\e079';
display: block;
font-family: 'Glyphicons Halflings';
color: var(--color-lightwhite);
}
&:hover {
background-color: var(--color-light);
}
}
.main__aside--collapsed {
width: 50px;
flex-basis: 50px;
overflow: hidden;
&.pseudo-hover {
overflow: visible;
}
.asidenav__toggler::before {
content: '\e080';
}
.asidenav__box-title {
.main__aside {
width: 50px;
padding: 1px;
font-size: 18px;
text-align: center;
margin-bottom: 0;
}
flex-basis: 50px;
overflow: hidden;
min-height: calc(100% - 50px);
.asidenav__link-shorthand {
display: flex;
position: static;
// TODO: make shorthands in collapsed beautiful *.*
// background-color: var(--color-dark);
// color: var(--color-lightwhite);
height: 50px;
width: 50px;
text-align: center;
opacity: 1;
font-size: 15px;
line-height: 1em;
margin-right: 13px;
flex-shrink: 0;
padding: 1px;
outline: 1px solid white;
text-transform: uppercase;
word-break: break-all;
align-items: center;
justify-content: center;
}
.asidenav__list-item {
padding-left: 0;
}
.asidenav__list-item:hover {
> .asidenav__link-wrapper {
color: var(--color-dark);
background-color: var(--color-lightwhite);
~ .main__content {
padding-left: 50px;
}
}
.asidenav__link-wrapper {
color: var(--color-lightwhite);
// background-color: var(--color-dark);
}
&.pseudo-hover {
overflow: visible;
flex-basis: 300px;
}
.asidenav__link-label {
padding-left: 0;
}
.asidenav__box-title {
width: 50px;
padding: 1px;
font-size: 18px;
text-align: center;
margin-bottom: 0;
}
.asidenav__list-item--active {
.asidenav__link-shorthand {
display: flex;
position: static;
// TODO: make shorthands in collapsed beautiful *.*
// background-color: var(--color-dark);
// color: var(--color-lightwhite);
height: 50px;
width: 50px;
text-align: center;
opacity: 1;
font-size: 15px;
line-height: 1em;
margin-right: 13px;
flex-shrink: 0;
padding: 1px;
outline: 1px solid white;
text-transform: uppercase;
word-break: break-all;
align-items: center;
justify-content: center;
}
.asidenav__list-item {
padding-left: 0;
+ .asidenav__list-item {
margin: 0;
}
}
.asidenav__list-item:hover {
> .asidenav__link-wrapper {
color: var(--color-dark);
background-color: var(--color-lightwhite);
}
}
.asidenav__link-wrapper {
background-color: var(--color-lightwhite);
color: var(--color-dark);
color: var(--color-lightwhite);
padding: 0;
// background-color: var(--color-dark);
}
.asidenav__link-label {
padding-left: 0;
}
.asidenav__list-item--active {
.asidenav__link-wrapper {
background-color: var(--color-lightwhite);
color: var(--color-dark);
}
}
}
}

View File

@ -3,9 +3,6 @@
align-self: flex-end;
background-color: var(--color-dark);
color: white;
margin-left: -40px;
margin-right: -40px;
margin-bottom: 20px;
transition: margin-bottom .2s ease;
}
@ -35,9 +32,6 @@
opacity: 1;
}
&:first-child {
padding-left: 50px;
}
&::after {
content: '';

View File

@ -5,6 +5,9 @@ $case formLayout
$forall view <- views
<div .form-group :fvRequired view:.form-group--required :not $ fvRequired view:.form-group--optional :isJust $ fvErrors view:.form-group--has-error>
$if not (Blaze.null $ fvLabel view)
<label .form-group__label .reactive-label for=#{fvId view}>#{fvLabel view}
<label .form-group__label for=#{fvId view}>#{fvLabel view}
$# TODO: inputs should have proper placeholders
^{fvInput view}
$# TODO: can we wrap checkboxes in a <div.checkbox> and radio buttons in a <div.radio>?
<div .form-group__input>
$# FIXME: file-input does not have `required` attribute, although set on form-group
^{fvInput view}

View File

@ -21,15 +21,24 @@
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
}
@media (max-width: 999px) {
@media (max-width: 768px) {
.navbar {
padding-left: 90px;
}
}
@media (max-width: 500px) {
.navbar {
padding-left: 20px;
}
}
.navbar__logo {
transition: all .2s ease;
transform-origin: left;
width: 0px;
&::before {
content: 'UniWorkY';
@ -43,17 +52,14 @@
@media (max-width: 768px) {
.navbar__logo {
transform: scale(0.7, 0.7);
transform-origin: left;
position: absolute;
transform: scale(0.7);
}
}
@media (max-width: 500px) {
@media (max-width: 425px) {
.navbar__logo {
left: 20px;
transform: scale(0.3, 0.3);
transform: scale(0.3);
}
}