/node_modules/foundation-sites/dist/plugins/foundation.accordionMenu.js
JavaScript | 307 lines | 192 code | 41 blank | 74 comment | 27 complexity | 4c00059d6b87879837b8063b05384c9f MD5 | raw file
- 'use strict';
- var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- !function ($) {
- /**
- * AccordionMenu module.
- * @module foundation.accordionMenu
- * @requires foundation.util.keyboard
- * @requires foundation.util.motion
- * @requires foundation.util.nest
- */
- var AccordionMenu = function () {
- /**
- * Creates a new instance of an accordion menu.
- * @class
- * @fires AccordionMenu#init
- * @param {jQuery} element - jQuery object to make into an accordion menu.
- * @param {Object} options - Overrides to the default plugin settings.
- */
- function AccordionMenu(element, options) {
- _classCallCheck(this, AccordionMenu);
- this.$element = element;
- this.options = $.extend({}, AccordionMenu.defaults, this.$element.data(), options);
- Foundation.Nest.Feather(this.$element, 'accordion');
- this._init();
- Foundation.registerPlugin(this, 'AccordionMenu');
- Foundation.Keyboard.register('AccordionMenu', {
- 'ENTER': 'toggle',
- 'SPACE': 'toggle',
- 'ARROW_RIGHT': 'open',
- 'ARROW_UP': 'up',
- 'ARROW_DOWN': 'down',
- 'ARROW_LEFT': 'close',
- 'ESCAPE': 'closeAll',
- 'TAB': 'down',
- 'SHIFT_TAB': 'up'
- });
- }
- /**
- * Initializes the accordion menu by hiding all nested menus.
- * @private
- */
- _createClass(AccordionMenu, [{
- key: '_init',
- value: function _init() {
- this.$element.find('[data-submenu]').not('.is-active').slideUp(0); //.find('a').css('padding-left', '1rem');
- this.$element.attr({
- 'role': 'tablist',
- 'aria-multiselectable': this.options.multiOpen
- });
- this.$menuLinks = this.$element.find('.is-accordion-submenu-parent');
- this.$menuLinks.each(function () {
- var linkId = this.id || Foundation.GetYoDigits(6, 'acc-menu-link'),
- $elem = $(this),
- $sub = $elem.children('[data-submenu]'),
- subId = $sub[0].id || Foundation.GetYoDigits(6, 'acc-menu'),
- isActive = $sub.hasClass('is-active');
- $elem.attr({
- 'aria-controls': subId,
- 'aria-expanded': isActive,
- 'role': 'tab',
- 'id': linkId
- });
- $sub.attr({
- 'aria-labelledby': linkId,
- 'aria-hidden': !isActive,
- 'role': 'tabpanel',
- 'id': subId
- });
- });
- var initPanes = this.$element.find('.is-active');
- if (initPanes.length) {
- var _this = this;
- initPanes.each(function () {
- _this.down($(this));
- });
- }
- this._events();
- }
- /**
- * Adds event handlers for items within the menu.
- * @private
- */
- }, {
- key: '_events',
- value: function _events() {
- var _this = this;
- this.$element.find('li').each(function () {
- var $submenu = $(this).children('[data-submenu]');
- if ($submenu.length) {
- $(this).children('a').off('click.zf.accordionMenu').on('click.zf.accordionMenu', function (e) {
- e.preventDefault();
- _this.toggle($submenu);
- });
- }
- }).on('keydown.zf.accordionmenu', function (e) {
- var $element = $(this),
- $elements = $element.parent('ul').children('li'),
- $prevElement,
- $nextElement,
- $target = $element.children('[data-submenu]');
- $elements.each(function (i) {
- if ($(this).is($element)) {
- $prevElement = $elements.eq(Math.max(0, i - 1)).find('a').first();
- $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1)).find('a').first();
- if ($(this).children('[data-submenu]:visible').length) {
- // has open sub menu
- $nextElement = $element.find('li:first-child').find('a').first();
- }
- if ($(this).is(':first-child')) {
- // is first element of sub menu
- $prevElement = $element.parents('li').first().find('a').first();
- } else if ($prevElement.children('[data-submenu]:visible').length) {
- // if previous element has open sub menu
- $prevElement = $prevElement.find('li:last-child').find('a').first();
- }
- if ($(this).is(':last-child')) {
- // is last element of sub menu
- $nextElement = $element.parents('li').first().next('li').find('a').first();
- }
- return;
- }
- });
- Foundation.Keyboard.handleKey(e, 'AccordionMenu', {
- open: function () {
- if ($target.is(':hidden')) {
- _this.down($target);
- $target.find('li').first().find('a').first().focus();
- }
- },
- close: function () {
- if ($target.length && !$target.is(':hidden')) {
- // close active sub of this item
- _this.up($target);
- } else if ($element.parent('[data-submenu]').length) {
- // close currently open sub
- _this.up($element.parent('[data-submenu]'));
- $element.parents('li').first().find('a').first().focus();
- }
- },
- up: function () {
- $prevElement.attr('tabindex', -1).focus();
- return true;
- },
- down: function () {
- $nextElement.attr('tabindex', -1).focus();
- return true;
- },
- toggle: function () {
- if ($element.children('[data-submenu]').length) {
- _this.toggle($element.children('[data-submenu]'));
- }
- },
- closeAll: function () {
- _this.hideAll();
- },
- handled: function (preventDefault) {
- if (preventDefault) {
- e.preventDefault();
- }
- e.stopImmediatePropagation();
- }
- });
- }); //.attr('tabindex', 0);
- }
- /**
- * Closes all panes of the menu.
- * @function
- */
- }, {
- key: 'hideAll',
- value: function hideAll() {
- this.$element.find('[data-submenu]').slideUp(this.options.slideSpeed);
- }
- /**
- * Toggles the open/close state of a submenu.
- * @function
- * @param {jQuery} $target - the submenu to toggle
- */
- }, {
- key: 'toggle',
- value: function toggle($target) {
- if (!$target.is(':animated')) {
- if (!$target.is(':hidden')) {
- this.up($target);
- } else {
- this.down($target);
- }
- }
- }
- /**
- * Opens the sub-menu defined by `$target`.
- * @param {jQuery} $target - Sub-menu to open.
- * @fires AccordionMenu#down
- */
- }, {
- key: 'down',
- value: function down($target) {
- var _this = this;
- if (!this.options.multiOpen) {
- this.up(this.$element.find('.is-active').not($target.parentsUntil(this.$element).add($target)));
- }
- $target.addClass('is-active').attr({ 'aria-hidden': false }).parent('.is-accordion-submenu-parent').attr({ 'aria-expanded': true });
- //Foundation.Move(this.options.slideSpeed, $target, function() {
- $target.slideDown(_this.options.slideSpeed, function () {
- /**
- * Fires when the menu is done opening.
- * @event AccordionMenu#down
- */
- _this.$element.trigger('down.zf.accordionMenu', [$target]);
- });
- //});
- }
- /**
- * Closes the sub-menu defined by `$target`. All sub-menus inside the target will be closed as well.
- * @param {jQuery} $target - Sub-menu to close.
- * @fires AccordionMenu#up
- */
- }, {
- key: 'up',
- value: function up($target) {
- var _this = this;
- //Foundation.Move(this.options.slideSpeed, $target, function(){
- $target.slideUp(_this.options.slideSpeed, function () {
- /**
- * Fires when the menu is done collapsing up.
- * @event AccordionMenu#up
- */
- _this.$element.trigger('up.zf.accordionMenu', [$target]);
- });
- //});
- var $menus = $target.find('[data-submenu]').slideUp(0).addBack().attr('aria-hidden', true);
- $menus.parent('.is-accordion-submenu-parent').attr('aria-expanded', false);
- }
- /**
- * Destroys an instance of accordion menu.
- * @fires AccordionMenu#destroyed
- */
- }, {
- key: 'destroy',
- value: function destroy() {
- this.$element.find('[data-submenu]').slideDown(0).css('display', '');
- this.$element.find('a').off('click.zf.accordionMenu');
- Foundation.Nest.Burn(this.$element, 'accordion');
- Foundation.unregisterPlugin(this);
- }
- }]);
- return AccordionMenu;
- }();
- AccordionMenu.defaults = {
- /**
- * Amount of time to animate the opening of a submenu in ms.
- * @option
- * @example 250
- */
- slideSpeed: 250,
- /**
- * Allow the menu to have multiple open panes.
- * @option
- * @example true
- */
- multiOpen: true
- };
- // Window exports
- Foundation.plugin(AccordionMenu, 'AccordionMenu');
- }(jQuery);