diff options
-rw-r--r-- | app/assets/javascripts/merge_request_tabs.js | 11 | ||||
-rw-r--r-- | app/assets/javascripts/sticky_tabs.js | 32 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/merge_requests.scss | 25 | ||||
-rw-r--r-- | app/views/projects/merge_requests/_nav.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/merge_requests/_show.html.haml | 4 |
5 files changed, 65 insertions, 9 deletions
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 71ac0c1840e..1bcdc38ef3f 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -7,6 +7,7 @@ import Cookies from 'js-cookie'; import './breakpoints'; import './flash'; import BlobForkSuggestion from './blob/blob_fork_suggestion'; +import StickyTabs from './sticky_tabs'; /* eslint-disable max-len */ // MergeRequestTabs @@ -60,7 +61,7 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion'; class MergeRequestTabs { - constructor({ action, setUrl, stubLocation } = {}) { + constructor({ action, setUrl, stubLocation, stickyTabs, unstickyTabs } = {}) { this.diffsLoaded = false; this.pipelinesLoaded = false; this.commitsLoaded = false; @@ -71,6 +72,8 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion'; this.tabShown = this.tabShown.bind(this); this.showTab = this.showTab.bind(this); + if (stickyTabs && unstickyTabs) this.stickyTabs = new StickyTabs(stickyTabs, unstickyTabs); + if (stubLocation) { location = stubLocation; } @@ -86,6 +89,8 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion'; $('.merge-request-tabs a[data-toggle="tab"]') .on('click', this.clickTab); + + if (this.stickyTabs) this.stickyTabs.bindEvents(); } // Used in tests @@ -96,6 +101,8 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion'; $('.merge-request-tabs a[data-toggle="tab"]') .off('click', this.clickTab); + + if (this.stickyTabs) this.stickyTabs.unbindEvents(); } destroyPipelinesView() { @@ -156,7 +163,7 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion'; if (location.hash) { const offset = 0 - ( $('.navbar-gitlab').outerHeight() + - $('.js-sticky-tabs').outerHeight() + (this.stickyTabs ? this.stickyTabs.unstickyTabsHeight : $('.js-tabs-affix').outerHeight()) ); const $el = $(`${container} ${location.hash}:not(.match)`); if ($el.length) { diff --git a/app/assets/javascripts/sticky_tabs.js b/app/assets/javascripts/sticky_tabs.js new file mode 100644 index 00000000000..ec81cfbae0d --- /dev/null +++ b/app/assets/javascripts/sticky_tabs.js @@ -0,0 +1,32 @@ +class StickyTabs { + constructor(stickyTabs, unstickyTabs) { + this.stickyTabs = stickyTabs; + this.unstickyTabs = unstickyTabs; + + this.unstickyTabsHeight = this.unstickyTabs.offsetHeight; + + this.eventListeners = {}; + } + + bindEvents() { + this.eventListeners.handleStickyTabs = this.handleStickyTabs.bind(this); + + document.addEventListener('scroll', this.eventListeners.handleStickyTabs); + } + + unbindEvents() { + document.removeEventListener('scroll', this.eventListeners.handleStickyTabs); + } + + handleStickyTabs() { + if (this.unstickyTabs.getBoundingClientRect().top <= this.unstickyTabsHeight) { + this.unstickyTabs.classList.add('invisible'); + this.stickyTabs.classList.remove('hide'); + } else { + this.unstickyTabs.classList.remove('invisible'); + this.stickyTabs.classList.add('hide'); + } + } +} + +export default StickyTabs; diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 5f8018be0d2..abc4e8d02af 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -730,12 +730,15 @@ } .merge-request-tabs-holder { - top: $header-height; z-index: 100; background-color: $white-light; border-bottom: 1px solid $border-color; + position: relative; + top: 0; + left: 0; - @media(min-width: $screen-sm-min) { + &.sticky { + top: $header-height; position: sticky; position: -webkit-sticky; @@ -758,7 +761,7 @@ padding: 0; } -.content-limit-container-width.merge-request-tabs-holder { +.content-limit-container-width.merge-request-tabs-holder.sticky { width: calc(100% - #{$gutter_collapsed_width}); .merge-request-tabs-container { @@ -768,8 +771,20 @@ } } -.right-sidebar-expanded .merge-request-tabs-holder { - width: calc(100% - #{$gutter_width}); +@media (min-width: $screen-sm-max) { + .right-sidebar-expanded .merge-request-tabs-holder.sticky { + width: calc(100% - #{$gutter_width}); + } +} + +@media (max-width: $screen-xs-max) { + .merge-request-tabs-holder.sticky { + display: none; + } + + .merge-request-tabs-holder:not(.sticky) { + visibility: visible; + } } .merge-request-tabs-container { diff --git a/app/views/projects/merge_requests/_nav.html.haml b/app/views/projects/merge_requests/_nav.html.haml index 6a4fb6fb2f3..f06f1d18764 100644 --- a/app/views/projects/merge_requests/_nav.html.haml +++ b/app/views/projects/merge_requests/_nav.html.haml @@ -1,6 +1,6 @@ - is_sticky = local_assigns.fetch(:is_sticky, false) -.merge-request-tabs-holder.js-sticky-tabs{ class: content_class_ref } +.merge-request-tabs-holder.js-sticky-tabs{ class: "#{content_class_ref} #{'sticky hide' if is_sticky}" } .merge-request-tabs-container .scrolling-tabs-container.inner-page-scroll-tabs.is-smaller .fade-left= icon('angle-left') diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 746f1f3bfc1..a02a8ea441f 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -58,6 +58,8 @@ :javascript $(function () { window.mergeRequest = new MergeRequest({ - action: "#{controller.action_name}" + action: "#{controller.action_name}", + unstickyTabs: document.querySelector('.js-sticky-tabs:not(.sticky)'), + stickyTabs: document.querySelector('.js-sticky-tabs.sticky') }); }); |