Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@steven-prybylynskyi
Last active March 27, 2019 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steven-prybylynskyi/010a5afe7cc59cf7d5ab16893cfadce9 to your computer and use it in GitHub Desktop.
Save steven-prybylynskyi/010a5afe7cc59cf7d5ab16893cfadce9 to your computer and use it in GitHub Desktop.
import {extendBootstrap} from 'util/obb-extend-bootstrap';
/**
* Make hovered dropdown toggler to behave as clickable link
*/
extendBootstrap(
'dropdown',
'toggle',
function dropdownTogglePre() {
const $dropdownToggle = $(this);
const $dropdown = $dropdownToggle.closest('.dropdown');
const $dropdownMenu = $dropdown.find('> .dropdown-menu');
const isActive = $dropdown.is('.open');
const shouldOpenOnHover = $dropdownToggle.data('hover');
// Remove `hidden` class before showing the dropdown
// (CRUD dropdowns has it for unknown reason)
if (!isActive) {
$dropdownMenu.removeClass('hidden');
}
// Clear former fading state
if (shouldOpenOnHover) {
$dropdownMenu.removeData('fadedOut');
}
},
function dropdownTogglePost() {
const $dropdownToggle = $(this);
const $dropdown = $dropdownToggle.closest('.dropdown');
const $dropdownMenu = $dropdown.find('> .dropdown-menu');
const $dropdownBackdrop = $dropdown.find('> .dropdown-backdrop');
const isActive = $dropdown.is('.open');
const isClickableLink = $dropdownToggle.is('[data-link-is-clickable]');
const isTouchDevice = 'ontouchstart' in document.documentElement;
const shouldOpenOnHover = $dropdownToggle.data('hover');
if (shouldOpenOnHover) {
if (!isActive) {
// Hide menu after transition
let transitionDuration = 0;
const transitionProperty = $dropdownMenu.css('transition') ? 'transition' : 'transition-duration';
if ($dropdownMenu.css(transitionProperty)) {
const durations = $dropdownMenu.css(transitionProperty).match(/[\d.]+s/g);
if (durations.length > 1) {
transitionDuration = parseFloat(durations[1]) * 1000;
}
}
setTimeout(function dropdownFadeoutCallback() {
// Check if dropdown is still closed
if (!$dropdown.is('.open')) {
if (transitionDuration) {
$dropdownMenu.data('fadedOut', true);
} else {
$dropdownMenu.addClass('hidden');
}
}
}, transitionDuration);
}
if (isClickableLink) {
if (isTouchDevice) {
// In Bootstrap's `dropdown.js` a backdrop is created when the dropdown is not in a `navbar-nav`
// The backdrop captures the click event and that prevents clickable links to succeed
$dropdownBackdrop.remove();
}
// Don't prevent default action
// by overriding Bootstrap `dropdown.js` `toggle` method's return value
return true;
}
}
}
);
// Reattach click event handler
$(document)
.off('click.bs.dropdown.data-api', '[data-toggle="dropdown"]')
.on('click.obb.bs.dropdown.data-api', '[data-toggle="dropdown"]', $.fn.dropdown.Constructor.prototype.toggle)
;
import {extendBootstrap} from 'util/obb-extend-bootstrap';
/**
* Sticky sections padding when modal is open
*
* @description
* The scrollbars are hidden when the modal appears and a padding is added to the body
* Set padding also for fixed sections like sticky header
*/
extendBootstrap('modal', 'setScrollbar', function() {
const modal = this;
$('.sticky-header').each(function() {
const $sticky = $(this);
const stickyPaddingRight = parseInt($sticky.css('padding-right') || 0, 10);
if (modal.bodyIsOverflowing) {
$sticky.css('padding-right', stickyPaddingRight + modal.scrollbarWidth);
}
});
});
extendBootstrap('modal', 'resetScrollbar', function() {
$('.sticky-header').each(function() {
const $sticky = $(this);
$sticky.css('padding-right', '');
});
});
/**
* Extend Bootstrap's jQuery functions
*
* @description
* event handlers for the new function should be redefined as in original library
*/
export function extendBootstrap(jqPlugin, publicMethod, callbackPre, callbackPost) {
const _super = $.fn[jqPlugin].Constructor.prototype[publicMethod];
// override public method
$.fn[jqPlugin].Constructor.prototype[publicMethod] = function() {
if (typeof callbackPre === 'function') {
callbackPre.apply(this, arguments);
}
let result = _super.apply(this, arguments);
if (typeof callbackPost === 'function') {
const callbackResult = callbackPost.apply(this, arguments);
if (callbackResult !== undefined) {
result = callbackResult;
}
}
return result;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment