UNPKG

@r00t80y/primary-navigation

Version:

An overlay Menu with a collection of effects and styles using CSS transitions.

324 lines (257 loc) 8.41 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); require('custom-event-polyfill'); require('element-closest-polyfill'); var throttleDebounce = require('throttle-debounce'); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** * @author r00t80y<https://github.com/R00T80Y> * @file Utils used in plugin * @since 09-02-2022 * @updated 10-04-2022 */ var Utils = { // Data Type type: function type(data) { return Object.prototype.toString.call(data).replace(/^\[object (.+)\]$/, '$1').toLowerCase(); }, isFunction: function isFunction(func) { return Utils.type(func) === 'function'; }, uniqId: function uniqId() { var date = Date.now().toString(36); var number = Math.random().toString(36).substring(2); return date + number; } }; var defaultOptions = { breakpointClose: 756, overflowHidden: true, stateControlSelector: '.navigation__state-control', panelSelector: '.navigation__panel', buttonSelector: '.navigation__button.navigation__button--burger', focus: false, init: false, open: false, close: false }; function Plugin($rootElement, pluginOptions) { var $checkbox = $rootElement.querySelector(pluginOptions.stateControlSelector); var $button = $rootElement.querySelector(pluginOptions.buttonSelector); var $labelsList = $rootElement.querySelectorAll("label[for=\"".concat($checkbox.id, "\"]")); var $panel = $rootElement.querySelector(pluginOptions.panelSelector); var uniqName = function () { var name; do { name = "primary-navigation-".concat(Utils.uniqId()); } while (document.getElementById(name)); return name; }(); $rootElement.setAttribute('data-plugin-name-uniq', uniqName); $rootElement.setAttribute('data-plugin-name', 'primary-navigation'); // Menu opened or not function isOpen() { return !!$checkbox.checked; } // Open menu function _open() { if (!isOpen()) { $checkbox.checked = true; $checkbox.dispatchEvent(new CustomEvent('change')); } } // Close menu function _close() { if (isOpen()) { $checkbox.checked = false; $checkbox.dispatchEvent(new CustomEvent('change')); } } // Close All opened menus function closeAll() { var $menuList = document.querySelectorAll('[data-plugin-name="primary-navigation"]'); if ($menuList) { for (var i = 0, l = $menuList.length; i < l; i += 1) { var $menuCheckbox = $menuList[i].querySelector(pluginOptions.stateControlSelector); if ($menuCheckbox) { var isChecked = !!$menuCheckbox.checked; if (isChecked === true) { $menuCheckbox.checked = false; $menuCheckbox.dispatchEvent(new CustomEvent('change')); } } } } } function onKeydown(e) { e.stopPropagation(); // Enter, Space if (e.keyCode === 32 || e.keyCode === 13) { e.preventDefault(); if (isOpen()) { _close(); } else { closeAll(); _open(); } // Esc } else if (e.keyCode === 27) { e.preventDefault(); closeAll(); } } function onKeydownEsc(e) { // Esc if (e.keyCode === 27) { closeAll(); } } // Close the menu by clicking on the page function onClickDocument(event) { // If the menu is closed, then exit the function if (!isOpen()) return; // Ignore click inside the menu if (event.target.closest("[data-plugin-name-uniq=\"".concat(uniqName, "\"]"))) { return; } // Close menu closeAll(); } function onStateModify(event) { // Is the menu open or not? if (event.target.checked) { if (pluginOptions.overflowHidden) { document.querySelector('html').style.overflow = 'hidden'; } for (var i = 0, l = $labelsList.length; i < l; i += 1) { $labelsList[i].setAttribute('aria-expanded', 'true'); } $panel.setAttribute('data-visible', 'true'); if (pluginOptions.focus) { setTimeout(function () { $panel.querySelector('a').focus(); }, 400); } if (Utils.isFunction(pluginOptions.open)) { pluginOptions.open(); } } else { if (pluginOptions.overflowHidden) { document.querySelector('html').style.overflow = 'auto'; } for (var _i = 0, _l = $labelsList.length; _i < _l; _i += 1) { $labelsList[_i].setAttribute('aria-expanded', 'false'); } $panel.setAttribute('data-visible', 'false'); if (pluginOptions.focus) { $button.focus(); } if (Utils.isFunction(pluginOptions.close)) { pluginOptions.close(); } } } var onResizeWindow = throttleDebounce.throttle(200, function () { // Close the menu if the window is resized if (isOpen()) { if (document.body.clientWidth >= pluginOptions.breakpointClose) { _close(); } } }); function createEvents() { if (pluginOptions.breakpointClose !== false) { window.addEventListener('resize', onResizeWindow); } $checkbox.addEventListener('change', onStateModify); for (var i = 0, l = $labelsList.length; i < l; i += 1) { $labelsList[i].addEventListener('keydown', onKeydown); } document.addEventListener('keydown', onKeydownEsc); document.addEventListener('click', onClickDocument, true); } function removeEvents() { window.removeEventListener('resize', onResizeWindow); $checkbox.removeEventListener('change', onStateModify); for (var i = 0, l = $labelsList.length; i < l; i += 1) { $labelsList[i].removeEventListener('keydown', onKeydown); } document.removeEventListener('keydown', onKeydownEsc); document.removeEventListener('click', onClickDocument); } function destroy() { removeEvents(); } // When the page loads, close the menu _close(); createEvents(); if (Utils.isFunction(pluginOptions.init)) { pluginOptions.init(); } return { get options() { return pluginOptions; }, isOpen: isOpen, open: function open() { _open(); }, close: function close() { _close(); }, destroy: destroy }; } function createPrimaryNavigation(element, customOptions) { var nodeList = []; var instances = []; return function init() { if (element && element instanceof HTMLElement) { nodeList.push(element); } else if (element && typeof element === 'string') { var elementsList = document.querySelectorAll(element); for (var i = 0, l = elementsList.length; i < l; i += 1) { if (elementsList[i] instanceof HTMLElement) { nodeList.push(elementsList[i]); } } } else if (element && element.length) { for (var _i2 = 0, _l2 = element.length; _i2 < _l2; _i2 += 1) { if (element[_i2] instanceof HTMLElement) { nodeList.push(element[_i2]); } } } for (var _i3 = 0, _l3 = nodeList.length; _i3 < _l3; _i3 += 1) { instances.push(new Plugin(nodeList[_i3], _objectSpread2(_objectSpread2(_objectSpread2({}, defaultOptions), customOptions), {}, { name: 'ToggleButton' }))); } return instances; }(); } exports.createPrimaryNavigation = createPrimaryNavigation; //# sourceMappingURL=index.js.map