From e655bc6e700f1b9668633f6beaef7acf8db484f0 Mon Sep 17 00:00:00 2001 From: Sarah Vaupel Date: Thu, 28 Nov 2019 12:33:44 +0100 Subject: [PATCH] feat(hide-columns): more (broken) styling; move hider elements in DOM --- .../src/utils/hide-columns/hide-columns.js | 82 ++++++++++++++----- .../src/utils/hide-columns/hide-columns.scss | 44 +++++----- 2 files changed, 85 insertions(+), 41 deletions(-) diff --git a/frontend/src/utils/hide-columns/hide-columns.js b/frontend/src/utils/hide-columns/hide-columns.js index 242c51095..0b2ee8c50 100644 --- a/frontend/src/utils/hide-columns/hide-columns.js +++ b/frontend/src/utils/hide-columns/hide-columns.js @@ -8,7 +8,13 @@ const TABLE_HEADER_IDENT = 'uw-hide-column-header'; const TABLE_UTILS_ATTR = 'table-utils'; const TABLE_UTILS_CONTAINER_SELECTOR = `[${TABLE_UTILS_ATTR}]`; -const HIDE_BUTTON_FADE_DELAY = 3000; +const TABLE_HIDER_CONTAINER_CLASS = 'table-hiders'; + +const HIDER_HIDE_CLASS = 'table-pill--hide'; +const HIDER_HIDDEN_CLASS = 'table-pill--hidden'; +const HIDER_FLOATING_CLASS = 'table-pill--floating'; + +const CELL_HIDDEN_CLASS = 'hide-columns--hidden-cell'; @Utility({ selector: `[${HIDE_COLUMNS_CONTAINER_IDENT}] table`, @@ -20,6 +26,7 @@ export class HideColumns { _element; _elementWrapper; _tableUtilContainer; + _tableHiderContainer; headerToHider = new Map(); hiderToHeader = new Map(); @@ -56,6 +63,14 @@ export class HideColumns { hideColumnsContainer.insertBefore(this._tableUtilContainer, tableContainer); } + // get or create table hider container before the table + this._tableHiderContainer = this._element.previousSibling; + if (!this._tableHiderContainer || !this._tableHiderContainer.classList.contains(TABLE_HIDER_CONTAINER_CLASS)) { + this._tableHiderContainer = document.createElement('div'); + this._tableHiderContainer.classList.add(TABLE_HIDER_CONTAINER_CLASS); + this._element.parentElement.insertBefore(this._tableHiderContainer, this._element); + } + this._element.querySelectorAll('th').forEach(th => { const storageKey = this.getStorageKey(th); const previouslyHidden = this._storageManager.load(storageKey); @@ -63,17 +78,42 @@ export class HideColumns { }); } + hideHiderBehindHeader(hider) { + const th = this.hiderToHeader.get(hider); + // move hider right before table (inside any scrolltable element) + this._tableHiderContainer.appendChild(hider); + // reposition hider + const posTH = th.getBoundingClientRect(); + const posH = hider.getBoundingClientRect(); + // TODO move to aux function + let p = { + top: posTH.top, + left: posTH.left, + width: th.offsetWidth || 0, + height: th.offsetHeight || 0, + }; + const hiderCompStyle = window.getComputedStyle(hider); + const x = parseInt(hiderCompStyle.marginLeft) + parseInt(hiderCompStyle.marginRight); + const y = parseInt(hiderCompStyle.marginTop) + parseInt(hiderCompStyle.marginBottom); + const posHParent = hider.parentElement.getBoundingClientRect(); + p.top += -posHParent.top + hider.parentElement.scrollTop + hider.parentElement.offsetTop; + p.left += -posHParent.left - hider.parentElement.scrollLeft + hider.parentElement.offsetLeft; + hider.style.left = (p.left + (p.width/2) - (posH.width/2 + x)) + 'px'; + hider.style.top = (p.top - (hider.offsetHeight + y)) + 'px'; + } + setupHideButton(th, prevHidden) { const hider = document.createElement('span'); - hider.classList.add('table-pill'); const hiderIcon = document.createElement('i'); hiderIcon.classList.add('fas', 'fa-fw'); hider.appendChild(hiderIcon); const hiderContent = document.createElement('span'); - hiderContent.classList.add('table-pill__content'); + hiderContent.classList.add('table-hider__label'); hiderContent.innerHTML = th.innerText; hider.appendChild(hiderContent); + this.addHeaderHider(th, hider); + hider.addEventListener('click', (event) => { event.preventDefault(); this.switchColumnDisplay(th, hider); @@ -81,18 +121,13 @@ export class HideColumns { // TODO fade in / fade out animation in css th.addEventListener('mouseover', () => { - hider.classList.remove('table-pill--hidden'); - const posTH = th.getBoundingClientRect(); - const posH = hider.getBoundingClientRect(); - hider.style.left = (posTH.left + ((posTH.right-posTH.left)/2 - ((posH.right-posH.left)/2))) + 'px'; - hider.style.top = (posTH.top - 50) + 'px'; + // hider.classList.remove(HIDER_HIDDEN_CLASS); }); - th.addEventListener('mouseout', () => { - setTimeout(() => { - if (hider.classList.contains('table-pill--floating')) { - hider.classList.add('table-pill--hidden'); - } - }, HIDE_BUTTON_FADE_DELAY); + th.addEventListener('mouseout', (event) => { + console.log('th mouseout', event); + if (hider.classList.contains(HIDER_FLOATING_CLASS)) { + hider.classList.add(HIDER_HIDE_CLASS); + } }); hider.addEventListener('mouseover', () => { @@ -107,9 +142,12 @@ export class HideColumns { this.updateColumnDisplay(th.cellIndex, prevHidden); this.updateHider(hider, prevHidden); - this.addHeaderHider(th, hider); + if (prevHidden) { + this._tableUtilContainer.appendChild(hider); + } else { + this.hideHiderBehindHeader(hider); + } - this._tableUtilContainer.appendChild(hider); } switchColumnDisplay(th, hider) { @@ -129,9 +167,9 @@ export class HideColumns { const cell = row.cells[columnIndex]; if (cell) { if (hidden) { - cell.classList.add('hide-columns--hidden-cell'); + cell.classList.add(CELL_HIDDEN_CLASS); } else { - cell.classList.remove('hide-columns--hidden-cell'); + cell.classList.remove(CELL_HIDDEN_CLASS); } } }); @@ -139,9 +177,13 @@ export class HideColumns { updateHider(hider, hidden) { if (hidden) { - hider.classList.remove('table-pill--hidden', 'table-pill--floating'); + this._tableUtilContainer.appendChild(hider); + hider.classList.remove(HIDER_HIDDEN_CLASS, HIDER_FLOATING_CLASS, 'table-hider'); + hider.classList.add('table-pill'); } else { - hider.classList.add('table-pill--hidden', 'table-pill--floating'); + + hider.classList.remove('table-pill'); + hider.classList.add(HIDER_HIDDEN_CLASS, HIDER_FLOATING_CLASS, 'table-hider'); } this.updateHiderIcon(hider, hidden); } diff --git a/frontend/src/utils/hide-columns/hide-columns.scss b/frontend/src/utils/hide-columns/hide-columns.scss index 82a39d97c..a6066283d 100644 --- a/frontend/src/utils/hide-columns/hide-columns.scss +++ b/frontend/src/utils/hide-columns/hide-columns.scss @@ -2,6 +2,21 @@ margin-bottom: 20px; line-height: 1.4; max-width: 85vw; +} + + .table-hider { + background-color: #fff; + color: var(--color-link); + padding: 10px; + cursor: pointer; + box-shadow: 0 0 2px 0 rgba(0,0,0,0.6); + margin: 10px 10px 0 0; + position: absolute; + + .table-hider__label { + display: none; + } + } .table-pill { background-color: var(--color-dark); @@ -14,40 +29,27 @@ margin-right: 20px; cursor: pointer; - .table-pill__content { + .table-hider__label { font-size: 16px; font-weight: bold; margin-left: 5px; } } - .table-pill.table-pill--hidden { - animation: fadeout 2s ease-in alternate infinite; - display: none; - } - .table-pill.table-pill--floating { - position: fixed; - .table-pill__content { display: none; } - } - .table-pill.table-pill--hide { - padding-left: 10px; + /* -webkit-animation: fadeout 0.5s linear forwards; */ + /* animation: fadeout 0.5s linear forwards; */ + /* animation-delay: 2s; */ } - .table-pill--unhide { - padding-left: 10px; - } - -} - .hide-columns--hidden-cell { display: none; } @keyframes fadeout { - from: { opacity: 1; } - to: { opacity: 0; display: none; } + 0% { opacity: 1; } + 100% { opacity: 0; } } @keyframes fadein { - from: { opacity: 0; } - to: { opacity: 1; } + 0% { opacity: 0; } + 100% { opacity: 1; } }