From 616fdee4fc9e46f531bb224421fc32779978f763 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Sun, 3 Mar 2019 17:29:59 +0100 Subject: [PATCH 1/6] move radio and checkbox styles in separate files --- src/Foundation.hs | 2 + static/css/utils/checkbox.scss | 74 ++++++++++++++++++++ static/css/utils/inputs.scss | 124 --------------------------------- static/css/utils/radio.scss | 86 +++++++++++++++++++++++ 4 files changed, 162 insertions(+), 124 deletions(-) create mode 100644 static/css/utils/checkbox.scss create mode 100644 static/css/utils/radio.scss diff --git a/src/Foundation.hs b/src/Foundation.hs index 718c1c705..047e3f670 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -1035,9 +1035,11 @@ siteLayout' headingOverride widget = do addStylesheet $ StaticR css_utils_asyncForm_scss addStylesheet $ StaticR css_utils_asyncTable_scss addStylesheet $ StaticR css_utils_asyncTableFilter_scss + addStylesheet $ StaticR css_utils_checkbox_scss addStylesheet $ StaticR css_utils_form_scss addStylesheet $ StaticR css_utils_inputs_scss addStylesheet $ StaticR css_utils_modal_scss + addStylesheet $ StaticR css_utils_radio_scss addStylesheet $ StaticR css_utils_showHide_scss addStylesheet $ StaticR css_utils_tabber_scss addStylesheet $ StaticR css_utils_tooltip_scss diff --git a/static/css/utils/checkbox.scss b/static/css/utils/checkbox.scss new file mode 100644 index 000000000..4cab1568e --- /dev/null +++ b/static/css/utils/checkbox.scss @@ -0,0 +1,74 @@ + +/* CUSTOM CHECKBOXES */ +/* Completely replaces legacy checkbox */ +.checkbox { + position: relative; + display: inline-block; + + [type="checkbox"] { + position: fixed; + top: -1px; + left: -1px; + width: 1px; + height: 1px; + overflow: hidden; + } + + label { + display: block; + height: 24px; + width: 24px; + background-color: #f3f3f3; + box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05); + border: 2px solid var(--color-primary); + border-radius: 4px; + color: white; + cursor: pointer; + } + + label::before, + label::after { + position: absolute; + display: block; + top: 12px; + left: 8px; + height: 2px; + width: 8px; + background-color: var(--color-font); + } + + :checked + label { + background-color: var(--color-primary); + } + + [type="checkbox"]:focus + label { + border-color: #3273dc; + box-shadow: 0 0 0 0.125em rgba(50,115,220,.25); + outline: 0; + } + + :checked + label::before, + :checked + label::after { + content: ''; + } + + :checked + label::before { + background-color: white; + transform: rotate(45deg); + left: 4px; + } + + :checked + label::after { + background-color: white; + transform: rotate(-45deg); + top: 11px; + width: 13px; + } + + [disabled] + label { + pointer-events: none; + border: none; + opacity: 0.6; + filter: grayscale(1); + } +} diff --git a/static/css/utils/inputs.scss b/static/css/utils/inputs.scss index f30155892..05f60e294 100644 --- a/static/css/utils/inputs.scss +++ b/static/css/utils/inputs.scss @@ -183,130 +183,6 @@ option { } } -/* CUSTOM LEGACY CHECKBOX AND RADIO BOXES */ -input[type="checkbox"] { - position: relative; - height: 20px; - width: 20px; - -webkit-appearance: none; - appearance: none; - cursor: pointer; -} -input[type="checkbox"]::before { - content: ''; - position: absolute; - width: 20px; - height: 20px; - background-color: var(--color-lighter); - display: flex; - align-items: center; - justify-content: center; - border-radius: 2px; -} -input[type="checkbox"]:checked::before { - background-color: var(--color-light); -} -input[type="checkbox"]:checked::after { - content: '✓'; - position: absolute; - width: 20px; - height: 20px; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 20px; -} - -/* CUSTOM CHECKBOXES AND RADIO BOXES */ -/* Completely replaces legacy checkbox and radiobox */ -.checkbox, -.radio { - position: relative; - display: inline-block; - - [type="checkbox"], - [type="radio"] { - position: fixed; - top: -1px; - left: -1px; - width: 1px; - height: 1px; - overflow: hidden; - } - - label { - display: block; - height: 24px; - width: 24px; - background-color: #f3f3f3; - box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05); - border: 2px solid var(--color-primary); - border-radius: 4px; - color: white; - cursor: pointer; - } - - label::before, - label::after { - position: absolute; - display: block; - top: 12px; - left: 8px; - height: 2px; - width: 8px; - background-color: var(--color-font); - } - - :checked + label { - background-color: var(--color-primary); - } - - [type="checkbox"]:focus + label, - [type="radio"]:focus + label { - border-color: #3273dc; - box-shadow: 0 0 0 0.125em rgba(50,115,220,.25); - outline: 0; - } - - :checked + label::before, - :checked + label::after { - content: ''; - } - - :checked + label::before { - background-color: white; - transform: rotate(45deg); - left: 4px; - } - - :checked + label::after { - background-color: white; - transform: rotate(-45deg); - top: 11px; - width: 13px; - } - - [disabled] + label { - pointer-events: none; - border: none; - opacity: 0.6; - filter: grayscale(1); - } -} - -.radio::before { - content: ''; - position: absolute; - top: 2px; - left: 2px; - right: 2px; - bottom: 2px; - border-radius: 4px; - border: 2px solid white; - z-index: -1; -} - /* CUSTOM FILE INPUT */ .file-input__label { cursor: pointer; diff --git a/static/css/utils/radio.scss b/static/css/utils/radio.scss new file mode 100644 index 000000000..f32cf073a --- /dev/null +++ b/static/css/utils/radio.scss @@ -0,0 +1,86 @@ + +/* CUSTOM RADIO BOXES */ +/* Completely replaces legacy radiobox */ +.radio { + position: relative; + display: inline-block; + + [type="radio"] { + position: fixed; + top: -1px; + left: -1px; + width: 1px; + height: 1px; + overflow: hidden; + } + + label { + display: block; + height: 24px; + width: 24px; + background-color: #f3f3f3; + box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05); + border: 2px solid var(--color-primary); + border-radius: 4px; + color: white; + cursor: pointer; + } + + label::before, + label::after { + position: absolute; + display: block; + top: 12px; + left: 8px; + height: 2px; + width: 8px; + background-color: var(--color-font); + } + + :checked + label { + background-color: var(--color-primary); + } + + [type="radio"]:focus + label { + border-color: #3273dc; + box-shadow: 0 0 0 0.125em rgba(50,115,220,.25); + outline: 0; + } + + :checked + label::before, + :checked + label::after { + content: ''; + } + + :checked + label::before { + background-color: white; + transform: rotate(45deg); + left: 4px; + } + + :checked + label::after { + background-color: white; + transform: rotate(-45deg); + top: 11px; + width: 13px; + } + + [disabled] + label { + pointer-events: none; + border: none; + opacity: 0.6; + filter: grayscale(1); + } +} + +.radio::before { + content: ''; + position: absolute; + top: 2px; + left: 2px; + right: 2px; + bottom: 2px; + border-radius: 4px; + border: 2px solid white; + z-index: -1; +} From 18c1cc7466d196991896bc068dddbc1d196b61e6 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Sun, 3 Mar 2019 17:49:17 +0100 Subject: [PATCH 2/6] split checkboxRadio js util into two separate utils --- static/js/utils/checkAll.js | 2 +- static/js/utils/inputs.js | 45 +++++++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/static/js/utils/checkAll.js b/static/js/utils/checkAll.js index c885ee100..8cbeb28b6 100644 --- a/static/js/utils/checkAll.js +++ b/static/js/utils/checkAll.js @@ -82,7 +82,7 @@ checkAllCheckbox.setAttribute('id', getCheckboxId()); th.innerHTML = ''; th.insertBefore(checkAllCheckbox, null); - utilInstances.push(window.utils.setup('checkboxRadio', checkAllCheckbox)); + utilInstances.push(window.utils.setup('checkbox', checkAllCheckbox)); checkAllCheckbox.addEventListener('input', onCheckAllCheckboxInput); setupCheckboxListeners(); diff --git a/static/js/utils/inputs.js b/static/js/utils/inputs.js index 26970f0e2..4d8f79946 100644 --- a/static/js/utils/inputs.js +++ b/static/js/utils/inputs.js @@ -13,10 +13,16 @@ var utilInstances = []; - // checkboxes / radios - var checkboxes = Array.from(wrapper.querySelectorAll('input[type="checkbox"], input[type="radio"]')); + // checkboxes + var checkboxes = Array.from(wrapper.querySelectorAll('input[type="checkbox"]')); checkboxes.filter(isNotInitialized).forEach(function(checkbox) { - utilInstances.push(window.utils.setup('checkboxRadio', checkbox)); + utilInstances.push(window.utils.setup('checkbox', checkbox)); + }); + + // radios + var radios = Array.from(wrapper.querySelectorAll('input[type="radio"]')); + radios.filter(isNotInitialized).forEach(function(radio) { + utilInstances.push(window.utils.setup('radio', radio)); }); // file-uploads @@ -167,17 +173,15 @@ }; } - // turns native checkboxes and radio buttons into custom ones - window.utils.checkboxRadio = function(input) { + // turns native checkboxes into custom ones + window.utils.checkbox = function(input) { - var type = input.getAttribute('type'); - - if (!input.parentElement.classList.contains(type)) { + if (!input.parentElement.classList.contains('checkbox')) { var parentEl = input.parentElement; var siblingEl = input.nextElementSibling; var wrapperEl = document.createElement('div'); var labelEl = document.createElement('label'); - wrapperEl.classList.add(type); + wrapperEl.classList.add('checkbox'); labelEl.setAttribute('for', input.id); wrapperEl.appendChild(input); wrapperEl.appendChild(labelEl); @@ -195,4 +199,27 @@ }; } + // turns native radio buttons into custom ones + window.utils.radio = function(input) { + + if (!input.parentElement.classList.contains('radio')) { + var parentEl = input.parentElement; + var siblingEl = input.nextElementSibling; + var wrapperEl = document.createElement('div'); + wrapperEl.classList.add('radio'); + wrapperEl.appendChild(input); + + if (siblingEl && siblingEl.matches('label')) { + wrapperEl.appendChild(siblingEl); + } + + input.classList.add(JS_INITIALIZED_CLASS); + parentEl.appendChild(wrapperEl); + } + + return { + destroy: function() {}, + }; + } + })(); From 1363a29778836e3e52aef4cfb11f0d34986dfbda Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Sun, 3 Mar 2019 17:55:32 +0100 Subject: [PATCH 3/6] add initial styles for radio groups --- static/css/utils/radio.scss | 67 ++++++++++--------------------------- 1 file changed, 17 insertions(+), 50 deletions(-) diff --git a/static/css/utils/radio.scss b/static/css/utils/radio.scss index f32cf073a..3a8a87d85 100644 --- a/static/css/utils/radio.scss +++ b/static/css/utils/radio.scss @@ -1,6 +1,14 @@ - /* CUSTOM RADIO BOXES */ -/* Completely replaces legacy radiobox */ +/* Completely replaces native radiobox */ + +.radio-group { + display: flex; +} + +.radio-group__option { + min-width: 30px; +} + .radio { position: relative; display: inline-block; @@ -16,55 +24,26 @@ label { display: block; - height: 24px; - width: 24px; + height: 48px; + min-width: 48px; + padding: 0 7px; background-color: #f3f3f3; box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05); border: 2px solid var(--color-primary); - border-radius: 4px; - color: white; + color: var(--color-font); cursor: pointer; } - label::before, - label::after { - position: absolute; - display: block; - top: 12px; - left: 8px; - height: 2px; - width: 8px; - background-color: var(--color-font); - } - :checked + label { - background-color: var(--color-primary); + background-color: #dedede; } - [type="radio"]:focus + label { + :focus + label { border-color: #3273dc; - box-shadow: 0 0 0 0.125em rgba(50,115,220,.25); + box-shadow: 0 0 0.125em 0 rgba(50,115,220,0.8); outline: 0; } - :checked + label::before, - :checked + label::after { - content: ''; - } - - :checked + label::before { - background-color: white; - transform: rotate(45deg); - left: 4px; - } - - :checked + label::after { - background-color: white; - transform: rotate(-45deg); - top: 11px; - width: 13px; - } - [disabled] + label { pointer-events: none; border: none; @@ -72,15 +51,3 @@ filter: grayscale(1); } } - -.radio::before { - content: ''; - position: absolute; - top: 2px; - left: 2px; - right: 2px; - bottom: 2px; - border-radius: 4px; - border: 2px solid white; - z-index: -1; -} From aaf14087b6b28788e76f2ff27fbbf176283af4f9 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Sun, 3 Mar 2019 20:25:06 +0100 Subject: [PATCH 4/6] hide filter in showhide --- messages/uniworx/de.msg | 1 + static/css/utils/radio.scss | 33 +++++++++++++++++--- static/js/utils/asyncTable.js | 3 ++ static/js/utils/showHide.js | 18 ++++++++--- templates/table/layout-filter-default.hamlet | 15 ++++----- templates/table/layout-filter-default.lucius | 4 +++ templates/widgets/fields/bool.hamlet | 2 +- 7 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 templates/table/layout-filter-default.lucius diff --git a/messages/uniworx/de.msg b/messages/uniworx/de.msg index 08f096088..0616590e1 100644 --- a/messages/uniworx/de.msg +++ b/messages/uniworx/de.msg @@ -87,6 +87,7 @@ CourseRegisterToTip: Anmeldung darf auch unbegrenzt offen bleiben CourseDeregisterUntilTip: Abmeldung darf auch unbegrenzt erlaubt bleiben CourseFilterSearch: Volltext-Suche CourseFilterRegistered: Registriert +CourseFilterNone: Egal CourseDeleteQuestion: Wollen Sie den unten aufgeführten Kurs wirklich löschen? CourseDeleted: Kurs gelöscht CourseUserNote: Notiz diff --git a/static/css/utils/radio.scss b/static/css/utils/radio.scss index 3a8a87d85..e30894013 100644 --- a/static/css/utils/radio.scss +++ b/static/css/utils/radio.scss @@ -24,18 +24,21 @@ label { display: block; - height: 48px; - min-width: 48px; + height: 34px; + min-width: 42px; + line-height: 34px; + text-align: center; padding: 0 7px; background-color: #f3f3f3; - box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05); - border: 2px solid var(--color-primary); + box-shadow: inset 2px 1px 2px 1px rgba(50, 50, 50, 0.05); color: var(--color-font); cursor: pointer; } :checked + label { - background-color: #dedede; + background-color: #818181; + color: var(--color-lightwhite); + box-shadow: inset -2px -1px 2px 1px rgba(255, 255, 255, 0.15); } :focus + label { @@ -51,3 +54,23 @@ filter: grayscale(1); } } + +.radio:first-child { + label { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + } +} + +.radio:last-child { + label { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + } +} + +@media (max-width: 768px) { + .radio + .radio { + margin-left: 10px; + } +} diff --git a/static/js/utils/asyncTable.js b/static/js/utils/asyncTable.js index 7e7e88855..0eeb7528d 100644 --- a/static/js/utils/asyncTable.js +++ b/static/js/utils/asyncTable.js @@ -51,6 +51,9 @@ // check all utilInstances.push(window.utils.setup('checkAll', wrapper)); + // showhide + utilInstances.push(window.utils.setup('showHide', wrapper)); + // filter var filterForm = wrapper.querySelector('.' + TABLE_FILTER_FORM_CLASS); if (filterForm) { diff --git a/static/js/utils/showHide.js b/static/js/utils/showHide.js index a2bb2edc0..094ff1d5c 100644 --- a/static/js/utils/showHide.js +++ b/static/js/utils/showHide.js @@ -4,6 +4,10 @@ window.utils = window.utils || {}; var LOCAL_STORAGE_SHOW_HIDE = 'SHOW_HIDE'; + var SHOW_HIDE_TOGGLE_CLASS = 'js-show-hide__toggle'; + var SHOW_HIDE_COLLAPSED_CLASS = 'js-show-hide--collapsed'; + var SHOW_HIDE_TARGET_CLASS = 'js-show-hide__target'; + /** * div * div.js-show-hide__toggle @@ -12,9 +16,13 @@ * content here */ window.utils.showHide = function(wrapper, options) { + + options = options || {}; + // make + function addEventHandler(el) { el.addEventListener('click', function elClickListener() { - var newState = el.parentElement.classList.toggle('js-show-hide--collapsed'); + var newState = el.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS); updateLSState(el.dataset.shIndex || null, newState); }); } @@ -37,16 +45,16 @@ } Array - .from(wrapper.querySelectorAll('.js-show-hide__toggle')) + .from(wrapper.querySelectorAll('.' + SHOW_HIDE_TOGGLE_CLASS)) .forEach(function(el) { var index = el.dataset.shIndex || null; el.parentElement.classList.toggle( - 'js-show-hide--collapsed', + SHOW_HIDE_COLLAPSED_CLASS, collapsedStateInLocalStorage(index) || el.dataset.collapsed === 'true' ); Array.from(el.parentElement.children).forEach(function(el) { - if (!el.classList.contains('js-show-hide__toggle')) { - el.classList.add('js-show-hide__target'); + if (!el.classList.contains('' + SHOW_HIDE_TOGGLE_CLASS)) { + el.classList.add(SHOW_HIDE_TARGET_CLASS); } }); addEventHandler(el); diff --git a/templates/table/layout-filter-default.hamlet b/templates/table/layout-filter-default.hamlet index dae7cd085..d09a586af 100644 --- a/templates/table/layout-filter-default.hamlet +++ b/templates/table/layout-filter-default.hamlet @@ -1,8 +1,9 @@ $newline never -
-
- ^{filterWgdt} -