summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2017-08-01 08:49:03 +0100
committerPhil Hughes <me@iamphill.com>2017-08-01 08:49:03 +0100
commit20bfc4f679bd63f71af716d4910c5c22e33180c0 (patch)
tree77875dc518481f280051ecf9a2703006d4059ab8 /app
parentf20a48494a4d60ddf311b85ce51ba0cb788390be (diff)
downloadgitlab-ce-20bfc4f679bd63f71af716d4910c5c22e33180c0.tar.gz
added mouseleave timeout with JS
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/fly_out_nav.js90
-rw-r--r--app/assets/stylesheets/new_sidebar.scss3
2 files changed, 74 insertions, 19 deletions
diff --git a/app/assets/javascripts/fly_out_nav.js b/app/assets/javascripts/fly_out_nav.js
index f2151396d43..93101f123b5 100644
--- a/app/assets/javascripts/fly_out_nav.js
+++ b/app/assets/javascripts/fly_out_nav.js
@@ -1,3 +1,16 @@
+let hideTimeoutInterval = 0;
+let hideTimeout;
+let subitems;
+
+export const getHideTimeoutInterval = () => hideTimeoutInterval;
+
+export const hideAllSubItems = () => {
+ subitems.forEach((el) => {
+ el.parentNode.classList.remove('is-over');
+ el.style.display = 'none'; // eslint-disable-line no-param-reassign
+ });
+};
+
export const calculateTop = (boundingRect, outerHeight) => {
const windowHeight = window.innerHeight;
const bottomOverflow = windowHeight - (boundingRect.top + outerHeight);
@@ -6,23 +19,64 @@ export const calculateTop = (boundingRect, outerHeight) => {
boundingRect.top;
};
+export const showSubLevelItems = (el) => {
+ const $subitems = el.querySelector('.sidebar-sub-level-items');
+
+ if (!$subitems) return;
+
+ hideAllSubItems();
+
+ if (el.classList.contains('is-over')) {
+ clearTimeout(hideTimeout);
+ } else {
+ $subitems.style.display = 'block';
+ el.classList.add('is-over');
+ }
+
+ const boundingRect = el.getBoundingClientRect();
+ const top = calculateTop(boundingRect, $subitems.offsetHeight);
+ const isAbove = top < boundingRect.top;
+
+ $subitems.style.transform = `translate3d(0, ${top}px, 0)`;
+
+ if (isAbove) {
+ $subitems.classList.add('is-above');
+ }
+};
+
+export const hideSubLevelItems = (el) => {
+ const $subitems = el.querySelector('.sidebar-sub-level-items');
+ const hideFn = () => {
+ el.classList.remove('is-over');
+ $subitems.style.display = 'none';
+ $subitems.classList.remove('is-above');
+
+ hideTimeoutInterval = 0;
+ };
+
+ if ($subitems && hideTimeoutInterval) {
+ hideTimeout = setTimeout(hideFn, hideTimeoutInterval);
+ } else if ($subitems) {
+ hideFn();
+ }
+};
+
+export const setMouseOutTimeout = (el) => {
+ if (el.closest('.sidebar-sub-level-items')) {
+ hideTimeoutInterval = 250;
+ } else {
+ hideTimeoutInterval = 0;
+ }
+};
+
export default () => {
- $('.sidebar-top-level-items > li:not(.active)').on('mouseover', (e) => {
- const $this = e.currentTarget;
- const $subitems = $('.sidebar-sub-level-items', $this).show();
-
- if ($subitems.length) {
- const boundingRect = $this.getBoundingClientRect();
- const top = calculateTop(boundingRect, $subitems.outerHeight());
- const isAbove = top < boundingRect.top;
-
- $subitems.css({
- transform: `translate3d(0, ${top}px, 0)`,
- });
-
- if (isAbove) {
- $subitems.addClass('is-above');
- }
- }
- }).on('mouseout', e => $('.sidebar-sub-level-items', e.currentTarget).hide().removeClass('is-above'));
+ const items = [...document.querySelectorAll('.sidebar-top-level-items > li:not(.active)')];
+ subitems = [...document.querySelectorAll('.sidebar-top-level-items > li:not(.active) .sidebar-sub-level-items')];
+
+ items.forEach((el) => {
+ el.addEventListener('mouseenter', e => showSubLevelItems(e.currentTarget));
+ el.addEventListener('mouseleave', e => hideSubLevelItems(e.currentTarget));
+ });
+
+ subitems.forEach(el => el.addEventListener('mouseleave', e => setMouseOutTimeout(e.target)));
};
diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss
index 05b72e9f425..72c12413aba 100644
--- a/app/assets/stylesheets/new_sidebar.scss
+++ b/app/assets/stylesheets/new_sidebar.scss
@@ -292,7 +292,8 @@ $new-sidebar-width: 220px;
}
&:not(.active):hover > a,
- > a:hover {
+ > a:hover,
+ &.is-over > a {
background-color: $white-light;
}
}