From adc866cb3db7ba05b58d7c3169ebc96b5dd89ba1 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sun, 5 May 2019 14:43:26 +0100 Subject: [PATCH] Added ability for dropdown menu to be bottom of dom body - Used when a dropdown is within a scrollable section such as editor toolbar on mobile. - Also made mobile page save button more obvious by increasing size and inverting color. --- resources/assets/js/components/dropdown.js | 36 +++++++++++++++++-- .../assets/js/components/list-sort-control.js | 9 +++-- resources/assets/sass/_lists.scss | 2 +- resources/assets/sass/_pages.scss | 19 +++++----- resources/views/books/show.blade.php | 2 +- resources/views/chapters/show.blade.php | 2 +- resources/views/comments/comment.blade.php | 2 +- resources/views/common/header.blade.php | 2 +- resources/views/pages/form.blade.php | 11 +++--- resources/views/pages/revisions.blade.php | 4 +-- resources/views/pages/show.blade.php | 2 +- resources/views/partials/sort.blade.php | 8 ++--- 12 files changed, 66 insertions(+), 33 deletions(-) diff --git a/resources/assets/js/components/dropdown.js b/resources/assets/js/components/dropdown.js index 400ddb576..ce797bbeb 100644 --- a/resources/assets/js/components/dropdown.js +++ b/resources/assets/js/components/dropdown.js @@ -6,24 +6,54 @@ class DropDown { constructor(elem) { this.container = elem; - this.menu = elem.querySelector('ul, [dropdown-menu]'); + this.menu = elem.querySelector('.dropdown-menu, [dropdown-menu]'); + this.moveMenu = elem.hasAttribute('dropdown-move-menu'); this.toggle = elem.querySelector('[dropdown-toggle]'); + this.body = document.body; this.setupListeners(); } - show() { + show(event) { + this.hide(); + this.menu.style.display = 'block'; this.menu.classList.add('anim', 'menuIn'); - this.container.addEventListener('mouseleave', this.hide.bind(this)); + + if (this.moveMenu) { + // Move to body to prevent being trapped within scrollable sections + this.rect = this.menu.getBoundingClientRect(); + this.body.appendChild(this.menu); + this.menu.style.position = 'fixed'; + this.menu.style.left = `${this.rect.left}px`; + this.menu.style.top = `${this.rect.top}px`; + this.menu.style.width = `${this.rect.width}px`; + } + + // Set listener to hide on mouse leave or window click + this.menu.addEventListener('mouseleave', this.hide.bind(this)); + window.addEventListener('click', event => { + if (!this.menu.contains(event.target)) { + this.hide(); + } + }); // Focus on first input if existing let input = this.menu.querySelector('input'); if (input !== null) input.focus(); + + event.stopPropagation(); } hide() { this.menu.style.display = 'none'; this.menu.classList.remove('anim', 'menuIn'); + if (this.moveMenu) { + this.menu.style.position = ''; + this.menu.style.left = ''; + this.menu.style.top = ''; + this.menu.style.width = ''; + this.container.appendChild(this.menu); + } } setupListeners() { diff --git a/resources/assets/js/components/list-sort-control.js b/resources/assets/js/components/list-sort-control.js index d463ed0b7..23fc64ae6 100644 --- a/resources/assets/js/components/list-sort-control.js +++ b/resources/assets/js/components/list-sort-control.js @@ -6,20 +6,23 @@ class ListSortControl { constructor(elem) { this.elem = elem; + this.menu = elem.querySelector('ul'); this.sortInput = elem.querySelector('[name="sort"]'); this.orderInput = elem.querySelector('[name="order"]'); this.form = elem.querySelector('form'); - this.elem.addEventListener('click', event => { + this.menu.addEventListener('click', event => { if (event.target.closest('[data-sort-value]') !== null) { this.sortOptionClick(event); } + }); + + this.elem.addEventListener('click', event => { if (event.target.closest('[data-sort-dir]') !== null) { this.sortDirectionClick(event); } - }) - + }); } sortOptionClick(event) { diff --git a/resources/assets/sass/_lists.scss b/resources/assets/sass/_lists.scss index dc4dc8816..565c3f0f8 100644 --- a/resources/assets/sass/_lists.scss +++ b/resources/assets/sass/_lists.scss @@ -510,7 +510,7 @@ ul.pagination { position: relative; } -.dropdown-container ul { +.dropdown-menu { display: none; position: absolute; z-index: 999; diff --git a/resources/assets/sass/_pages.scss b/resources/assets/sass/_pages.scss index 969682c3b..e3b1deb5b 100755 --- a/resources/assets/sass/_pages.scss +++ b/resources/assets/sass/_pages.scss @@ -20,7 +20,7 @@ } } -@include smaller-than($l) { +@include smaller-than($m) { .page-edit-toolbar { overflow-x: scroll; overflow-y: visible; @@ -35,18 +35,21 @@ } } -@include smaller-than($l) { +@include smaller-than($m) { .page-edit-toolbar #save-button { position: fixed; z-index: 30; - background-color: #FFF; border-radius: 50%; - width: 42px; - height: 42px; - font-size: 16px; + width: 56px; + height: 56px; + font-size: 24px; right: $-m; - bottom: $-xs; - box-shadow: $bs-med; + bottom: $-s; + box-shadow: $bs-hover; + background-color: currentColor; + svg { + fill: #FFF; + } span { display: none; } diff --git a/resources/views/books/show.blade.php b/resources/views/books/show.blade.php index 3141f5ab2..b709b29dc 100644 --- a/resources/views/books/show.blade.php +++ b/resources/views/books/show.blade.php @@ -126,7 +126,7 @@ @icon('export') {{ trans('entities.export') }} -