diff --git a/dist/undernet.bundle.js b/dist/undernet.bundle.js index 0c21d9c2..95135bbe 100644 --- a/dist/undernet.bundle.js +++ b/dist/undernet.bundle.js @@ -6,8 +6,8 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.undernet = {}))); -}(this, (function (exports) { 'use strict'; + (global = global || self, factory(global.undernet = {})); +}(this, function (exports) { 'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { @@ -1046,5 +1046,5 @@ Object.defineProperty(exports, '__esModule', { value: true }); -}))); +})); //# sourceMappingURL=undernet.bundle.js.map diff --git a/dist/undernet.bundle.min.js b/dist/undernet.bundle.min.js index d325b965..60e9398d 100644 --- a/dist/undernet.bundle.min.js +++ b/dist/undernet.bundle.min.js @@ -3,5 +3,5 @@ * Undernet v3.3.2 (https://undernet.io) * Copyright 2017-2019 George Treviranus */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.undernet={})}(this,function(t){"use strict";function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var o=0;o [").concat(P,"] > h").concat(t," [").concat(W,"]")}).join(", ")}},{key:"_getPossibleAccordionHeaderAttrs",value:function(e){return this._headerLevels.map(function(t){return"".concat(e," > h").concat(t)}).join(", ")}},{key:"_getAccordionRowAttr",value:function(t){return"[".concat(P,"='").concat(t,"']")}},{key:"_render",value:function(t){if(t.preventDefault(),this._activeButton=t.target,this._activeAccordionRowId=this._activeButton.getAttribute(W),this._activeRowAttr=this._getAccordionRowAttr(this._activeAccordionRowId),this._activeRow=document.querySelector(this._activeRowAttr),!this._activeButton.getAttribute(q))return console.error(G.NO_PARENT_ERROR(this._activeAccordionRowId));if(this._activeContainerId=this._activeButton.getAttribute(q),this._activeContainerAttr="[".concat(N,"='").concat(this._activeContainerId,"']"),!document.querySelector(this._activeContainerAttr))return console.error(G.NO_ACCORDION_ERROR(this._activeContainerId));this._activeContainer=document.querySelector(this._activeContainerAttr),this._activeContent=document.getElementById(this._activeAccordionRowId);var e=this._activeRow.getAttribute(K);this._activeButtonExpandState="true"===e?"false":"true",this._activeContentHiddenState="false"===this._activeButtonExpandState?"true":"false",this._closeAllIfToggleable(),this._toggleSelectedAccordion()}},{key:"_closeAllIfToggleable",value:function(){var e=this;if(!this._activeContainer.hasAttribute(x)){var t="".concat(this._activeContainerAttr," [").concat(U,"]"),o=this.getElements("".concat(this._activeContainerAttr," [").concat(K,"]")),n=this.getElements(t),i=this._getPossibleAccordionButtonAttrs(this._activeContainerAttr),a=this.getElements(i);n.forEach(function(t){t!==e._activeContent&&(t.style.maxHeight=null)}),this.getFocusableElements(t).forEach(function(t){t.setAttribute(V,"-1")}),this._toggleAttributeInCollection(o,K,"true","false"),this._toggleAttributeInCollection(a,H,"true","false"),this._toggleAttributeInCollection(n,U,"false","true")}}},{key:"_toggleSelectedAccordion",value:function(){var o=this;this._activeRow.setAttribute(K,this._activeButtonExpandState),this._activeButton.setAttribute(H,this._activeButtonExpandState),this._activeContent.setAttribute(U,this._activeContentHiddenState);var t="#".concat(this._activeAccordionRowId);this.getFocusableElements(t).forEach(function(t){var e="true"===o._activeButtonExpandState?"0":"-1";t.setAttribute(V,e)}),this._activeContent.style.maxHeight?this._activeContent.style.maxHeight=null:this._activeContent.style.maxHeight="".concat(this._activeContent.scrollHeight,"px")}},{key:"_toggleAttributeInCollection",value:function(t,e,o,n){t.forEach(function(t){t.hasAttribute(e,o)&&t.setAttribute(e,n)})}}]),e}(),J=9,Q=16,Z=27,$=38,tt=40,et={DATA_DROPDOWN:"data-dropdown",DATA_TARGET:"data-target",DATA_PARENT:"data-parent",DATA_VISIBLE:"data-visible",TABINDEX:"tabindex",ARIA_HASPOPUP:"aria-haspopup",ARIA_CONTROLS:"aria-controls",ARIA_LABELLEDBY:"aria-labelledby",ARIA_EXPANDED:"aria-expanded",ROLE:"role"},ot="keydown",nt="click",it="Could not find dropdown button's [data-parent] attribute.",at=function(t){return"Could not find dropdown container associated with ".concat(t,".")},rt=function(t){return"Could not find menu associated with ".concat(t,".")},st=function(t){function e(){var t;return o(this,e),(t=l(this,r(e).call(this)))._render=t._render.bind(c(c(t))),t._handleFirstTabClose=t._handleFirstTabClose.bind(c(c(t))),t._handleLastTabClose=t._handleLastTabClose.bind(c(c(t))),t._renderWithKeys=t._renderWithKeys.bind(c(c(t))),t._handleClose=t._handleClose.bind(c(c(t))),t._handleEscapeKeyPress=t._handleEscapeKeyPress.bind(c(c(t))),t._handleOffMenuClick=t._handleOffMenuClick.bind(c(c(t))),t._activeDropdownButton=null,t._activeDropdown=null,t._activeDropdownMenu=null,t._activeDropdownLinks=[],t._allowFocusReturn=!0,t._activeDropdownId="",t._activeDropdownAttr="",t._activeDropdownMenuId="",t._dropdownButtons=[],t._dropdowns=[],t._dropdownContainerAttr="[".concat(et.DATA_DROPDOWN,"]"),t._dropdownTargetAttr="[".concat(et.DATA_TARGET,"]"),t}return a(e,b),i(e,[{key:"start",value:function(){var e=this;this._dropdowns=this.getElements("".concat(this._dropdownContainerAttr)),this._dropdownButtons=this.getElements("".concat(this._dropdownContainerAttr," > ").concat(this._dropdownTargetAttr)),this._dropdowns.length&&this._dropdowns.forEach(function(t){return e._setupDropdown(t)}),this._dropdownButtons.forEach(function(t){t.addEventListener(nt,e._render),t.addEventListener(ot,e._renderWithKeys)})}},{key:"stop",value:function(){var e=this;this._dropdownButtons.forEach(function(t){t.removeEventListener(nt,e._render),t.removeEventListener(ot,e._renderWithKeys)})}},{key:"_render",value:function(t,e){var o=this;return e||t.preventDefault(),t.stopPropagation(),this._activeDropdownButton&&(this._allowFocusReturn=!1,this._handleClose(t),this._allowFocusReturn=!0),this._activeDropdownButton=t.target,this._activeDropdownButton.getAttribute(et.DATA_PARENT)?(this._activeDropdownId=this._activeDropdownButton.getAttribute(et.DATA_PARENT),this._activeDropdownAttr="[".concat(et.DATA_DROPDOWN,'="').concat(this._activeDropdownId,'"]'),document.querySelector(this._activeDropdownAttr)?(this._activeDropdown=document.querySelector(this._activeDropdownAttr),this._activeDropdownMenuId=this._activeDropdownButton.getAttribute(et.DATA_TARGET),this._activeDropdownMenu=document.getElementById(this._activeDropdownMenuId),this._activeDropdownButton.setAttribute(et.ARIA_EXPANDED,"true"),this._activeDropdown.setAttribute(et.DATA_VISIBLE,"true"),this._activeDropdownButton.removeEventListener(nt,this._render),this._activeDropdownButton.addEventListener(nt,this._handleClose),document.addEventListener(ot,this._handleEscapeKeyPress),document.addEventListener(nt,this._handleOffMenuClick),this._activeDropdownLinks=this._getDropdownLinks(this._activeDropdownAttr),this.firstDropdownLink=this._activeDropdownLinks[0],this.lastDropdownLink=this._activeDropdownLinks[this._activeDropdownLinks.length-1],this.firstDropdownLink.addEventListener(ot,this._handleFirstTabClose),this.lastDropdownLink.addEventListener(ot,this._handleLastTabClose),e&&e===$?this.lastDropdownLink.focus():this.firstDropdownLink.focus(),this._activeDropdownLinks.forEach(function(t){t.setAttribute(et.TABINDEX,"0"),t.addEventListener(nt,o._handleClose)}),void this.captureFocus("".concat(this._activeDropdownAttr," > ul"),{useArrows:!0})):console.error(at(this._activeDropdownAttr))):console.error(it)}},{key:"_handleFirstTabClose",value:function(t){var e=t.which===Q||t.shiftKey,o=t.which===J;e&&o&&this._handleClose(t)}},{key:"_handleLastTabClose",value:function(t){var e=t.which===Q||t.shiftKey;t.which===J&&!e&&this._handleClose(t)}},{key:"_renderWithKeys",value:function(t){t.which!==$&&t.which!==tt||this._render(t,t.which)}},{key:"_handleClose",value:function(t){var e=this;t.preventDefault(),this.releaseFocus(),this._activeDropdownButton.setAttribute(et.ARIA_EXPANDED,"false"),this._activeDropdown.setAttribute(et.DATA_VISIBLE,"false"),this._activeDropdownLinks.forEach(function(t){t.setAttribute(et.TABINDEX,"-1"),t.removeEventListener(nt,e._handleClose)}),this._activeDropdownButton.removeEventListener(nt,this._handleClose),this._activeDropdownButton.addEventListener(nt,this._render),document.removeEventListener(ot,this._handleEscapeKeyPress),document.removeEventListener(nt,this._handleOffMenuClick),this._allowFocusReturn&&this._handleReturnFocus()}},{key:"_handleEscapeKeyPress",value:function(t){t.which===Z&&this._handleClose(t)}},{key:"_handleOffMenuClick",value:function(t){t.target!==this._activeDropdownButton&&t.target!==this._activeDropdownMenu&&this._handleClose(t)}},{key:"_handleReturnFocus",value:function(){this._activeDropdownButton.setAttribute(et.TAB_INDEX,"-1"),this._activeDropdownButton.focus(),this._activeDropdownButton.removeAttribute(et.TAB_INDEX)}},{key:"_getDropdownLinks",value:function(t){return this.getElements("".concat(t," > ul > li > a, ").concat(t," > ul > li > button"))}},{key:"_setupDropdown",value:function(t){var e=t.getAttribute(et.DATA_DROPDOWN),o="[".concat(et.DATA_DROPDOWN,'="').concat(e,'"]'),n="".concat(o," > ul > li");if(!document.querySelector("".concat(o," > ul")))return console.error(rt(o));var i=document.querySelector("".concat(o," > ul")),a=document.querySelector("".concat(o," > ").concat(this._dropdownTargetAttr));a.setAttribute(et.ARIA_CONTROLS,i.id),a.setAttribute(et.ARIA_HASPOPUP,"true"),a.setAttribute(et.ARIA_EXPANDED,"false"),i.setAttribute(et.ARIA_LABELLEDBY,a.id),this.getElements(n).forEach(function(t){return t.setAttribute(et.ROLE,"none")}),this._getDropdownLinks(o).forEach(function(t){t.setAttribute(et.ROLE,"menuitem"),t.setAttribute(et.TABINDEX,"-1")})}}]),e}(),ct=new e,lt=new z,dt=new st,ut=new b,Undernet={Modals:ct,Accordions:lt,Dropdowns:dt,Utils:ut,start:function(){Undernet.Modals.start(),Undernet.Accordions.start(),Undernet.Dropdowns.start(),Undernet.Utils.enableFocusOutline()},stop:function(){Undernet.Modals.stop(),Undernet.Accordions.stop(),Undernet.Dropdowns.stop(),Undernet.Utils.disableFocusOutline()}};window.Undernet=Undernet,t.default=Undernet,t.Modals=ct,t.Accordions=lt,t.Dropdowns=dt,t.Utils=ut,Object.defineProperty(t,"__esModule",{value:!0})}); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).undernet={})}(this,function(t){"use strict";function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var o=0;o [").concat(P,"] > h").concat(t," [").concat(W,"]")}).join(", ")}},{key:"_getPossibleAccordionHeaderAttrs",value:function(e){return this._headerLevels.map(function(t){return"".concat(e," > h").concat(t)}).join(", ")}},{key:"_getAccordionRowAttr",value:function(t){return"[".concat(P,"='").concat(t,"']")}},{key:"_render",value:function(t){if(t.preventDefault(),this._activeButton=t.target,this._activeAccordionRowId=this._activeButton.getAttribute(W),this._activeRowAttr=this._getAccordionRowAttr(this._activeAccordionRowId),this._activeRow=document.querySelector(this._activeRowAttr),!this._activeButton.getAttribute(q))return console.error(G.NO_PARENT_ERROR(this._activeAccordionRowId));if(this._activeContainerId=this._activeButton.getAttribute(q),this._activeContainerAttr="[".concat(N,"='").concat(this._activeContainerId,"']"),!document.querySelector(this._activeContainerAttr))return console.error(G.NO_ACCORDION_ERROR(this._activeContainerId));this._activeContainer=document.querySelector(this._activeContainerAttr),this._activeContent=document.getElementById(this._activeAccordionRowId);var e=this._activeRow.getAttribute(K);this._activeButtonExpandState="true"===e?"false":"true",this._activeContentHiddenState="false"===this._activeButtonExpandState?"true":"false",this._closeAllIfToggleable(),this._toggleSelectedAccordion()}},{key:"_closeAllIfToggleable",value:function(){var e=this;if(!this._activeContainer.hasAttribute(x)){var t="".concat(this._activeContainerAttr," [").concat(U,"]"),o=this.getElements("".concat(this._activeContainerAttr," [").concat(K,"]")),n=this.getElements(t),i=this._getPossibleAccordionButtonAttrs(this._activeContainerAttr),a=this.getElements(i);n.forEach(function(t){t!==e._activeContent&&(t.style.maxHeight=null)}),this.getFocusableElements(t).forEach(function(t){t.setAttribute(V,"-1")}),this._toggleAttributeInCollection(o,K,"true","false"),this._toggleAttributeInCollection(a,H,"true","false"),this._toggleAttributeInCollection(n,U,"false","true")}}},{key:"_toggleSelectedAccordion",value:function(){var o=this;this._activeRow.setAttribute(K,this._activeButtonExpandState),this._activeButton.setAttribute(H,this._activeButtonExpandState),this._activeContent.setAttribute(U,this._activeContentHiddenState);var t="#".concat(this._activeAccordionRowId);this.getFocusableElements(t).forEach(function(t){var e="true"===o._activeButtonExpandState?"0":"-1";t.setAttribute(V,e)}),this._activeContent.style.maxHeight?this._activeContent.style.maxHeight=null:this._activeContent.style.maxHeight="".concat(this._activeContent.scrollHeight,"px")}},{key:"_toggleAttributeInCollection",value:function(t,e,o,n){t.forEach(function(t){t.hasAttribute(e,o)&&t.setAttribute(e,n)})}}]),e}(),J=9,Q=16,Z=27,$=38,tt=40,et={DATA_DROPDOWN:"data-dropdown",DATA_TARGET:"data-target",DATA_PARENT:"data-parent",DATA_VISIBLE:"data-visible",TABINDEX:"tabindex",ARIA_HASPOPUP:"aria-haspopup",ARIA_CONTROLS:"aria-controls",ARIA_LABELLEDBY:"aria-labelledby",ARIA_EXPANDED:"aria-expanded",ROLE:"role"},ot="keydown",nt="click",it="Could not find dropdown button's [data-parent] attribute.",at=function(t){return"Could not find dropdown container associated with ".concat(t,".")},rt=function(t){return"Could not find menu associated with ".concat(t,".")},st=function(t){function e(){var t;return o(this,e),(t=l(this,r(e).call(this)))._render=t._render.bind(c(c(t))),t._handleFirstTabClose=t._handleFirstTabClose.bind(c(c(t))),t._handleLastTabClose=t._handleLastTabClose.bind(c(c(t))),t._renderWithKeys=t._renderWithKeys.bind(c(c(t))),t._handleClose=t._handleClose.bind(c(c(t))),t._handleEscapeKeyPress=t._handleEscapeKeyPress.bind(c(c(t))),t._handleOffMenuClick=t._handleOffMenuClick.bind(c(c(t))),t._activeDropdownButton=null,t._activeDropdown=null,t._activeDropdownMenu=null,t._activeDropdownLinks=[],t._allowFocusReturn=!0,t._activeDropdownId="",t._activeDropdownAttr="",t._activeDropdownMenuId="",t._dropdownButtons=[],t._dropdowns=[],t._dropdownContainerAttr="[".concat(et.DATA_DROPDOWN,"]"),t._dropdownTargetAttr="[".concat(et.DATA_TARGET,"]"),t}return a(e,b),i(e,[{key:"start",value:function(){var e=this;this._dropdowns=this.getElements("".concat(this._dropdownContainerAttr)),this._dropdownButtons=this.getElements("".concat(this._dropdownContainerAttr," > ").concat(this._dropdownTargetAttr)),this._dropdowns.length&&this._dropdowns.forEach(function(t){return e._setupDropdown(t)}),this._dropdownButtons.forEach(function(t){t.addEventListener(nt,e._render),t.addEventListener(ot,e._renderWithKeys)})}},{key:"stop",value:function(){var e=this;this._dropdownButtons.forEach(function(t){t.removeEventListener(nt,e._render),t.removeEventListener(ot,e._renderWithKeys)})}},{key:"_render",value:function(t,e){var o=this;return e||t.preventDefault(),t.stopPropagation(),this._activeDropdownButton&&(this._allowFocusReturn=!1,this._handleClose(t),this._allowFocusReturn=!0),this._activeDropdownButton=t.target,this._activeDropdownButton.getAttribute(et.DATA_PARENT)?(this._activeDropdownId=this._activeDropdownButton.getAttribute(et.DATA_PARENT),this._activeDropdownAttr="[".concat(et.DATA_DROPDOWN,'="').concat(this._activeDropdownId,'"]'),document.querySelector(this._activeDropdownAttr)?(this._activeDropdown=document.querySelector(this._activeDropdownAttr),this._activeDropdownMenuId=this._activeDropdownButton.getAttribute(et.DATA_TARGET),this._activeDropdownMenu=document.getElementById(this._activeDropdownMenuId),this._activeDropdownButton.setAttribute(et.ARIA_EXPANDED,"true"),this._activeDropdown.setAttribute(et.DATA_VISIBLE,"true"),this._activeDropdownButton.removeEventListener(nt,this._render),this._activeDropdownButton.addEventListener(nt,this._handleClose),document.addEventListener(ot,this._handleEscapeKeyPress),document.addEventListener(nt,this._handleOffMenuClick),this._activeDropdownLinks=this._getDropdownLinks(this._activeDropdownAttr),this.firstDropdownLink=this._activeDropdownLinks[0],this.lastDropdownLink=this._activeDropdownLinks[this._activeDropdownLinks.length-1],this.firstDropdownLink.addEventListener(ot,this._handleFirstTabClose),this.lastDropdownLink.addEventListener(ot,this._handleLastTabClose),e&&e===$?this.lastDropdownLink.focus():this.firstDropdownLink.focus(),this._activeDropdownLinks.forEach(function(t){t.setAttribute(et.TABINDEX,"0"),t.addEventListener(nt,o._handleClose)}),void this.captureFocus("".concat(this._activeDropdownAttr," > ul"),{useArrows:!0})):console.error(at(this._activeDropdownAttr))):console.error(it)}},{key:"_handleFirstTabClose",value:function(t){var e=t.which===Q||t.shiftKey,o=t.which===J;e&&o&&this._handleClose(t)}},{key:"_handleLastTabClose",value:function(t){var e=t.which===Q||t.shiftKey;t.which===J&&!e&&this._handleClose(t)}},{key:"_renderWithKeys",value:function(t){t.which!==$&&t.which!==tt||this._render(t,t.which)}},{key:"_handleClose",value:function(t){var e=this;t.preventDefault(),this.releaseFocus(),this._activeDropdownButton.setAttribute(et.ARIA_EXPANDED,"false"),this._activeDropdown.setAttribute(et.DATA_VISIBLE,"false"),this._activeDropdownLinks.forEach(function(t){t.setAttribute(et.TABINDEX,"-1"),t.removeEventListener(nt,e._handleClose)}),this._activeDropdownButton.removeEventListener(nt,this._handleClose),this._activeDropdownButton.addEventListener(nt,this._render),document.removeEventListener(ot,this._handleEscapeKeyPress),document.removeEventListener(nt,this._handleOffMenuClick),this._allowFocusReturn&&this._handleReturnFocus()}},{key:"_handleEscapeKeyPress",value:function(t){t.which===Z&&this._handleClose(t)}},{key:"_handleOffMenuClick",value:function(t){t.target!==this._activeDropdownButton&&t.target!==this._activeDropdownMenu&&this._handleClose(t)}},{key:"_handleReturnFocus",value:function(){this._activeDropdownButton.setAttribute(et.TAB_INDEX,"-1"),this._activeDropdownButton.focus(),this._activeDropdownButton.removeAttribute(et.TAB_INDEX)}},{key:"_getDropdownLinks",value:function(t){return this.getElements("".concat(t," > ul > li > a, ").concat(t," > ul > li > button"))}},{key:"_setupDropdown",value:function(t){var e=t.getAttribute(et.DATA_DROPDOWN),o="[".concat(et.DATA_DROPDOWN,'="').concat(e,'"]'),n="".concat(o," > ul > li");if(!document.querySelector("".concat(o," > ul")))return console.error(rt(o));var i=document.querySelector("".concat(o," > ul")),a=document.querySelector("".concat(o," > ").concat(this._dropdownTargetAttr));a.setAttribute(et.ARIA_CONTROLS,i.id),a.setAttribute(et.ARIA_HASPOPUP,"true"),a.setAttribute(et.ARIA_EXPANDED,"false"),i.setAttribute(et.ARIA_LABELLEDBY,a.id),this.getElements(n).forEach(function(t){return t.setAttribute(et.ROLE,"none")}),this._getDropdownLinks(o).forEach(function(t){t.setAttribute(et.ROLE,"menuitem"),t.setAttribute(et.TABINDEX,"-1")})}}]),e}(),ct=new e,lt=new z,dt=new st,ut=new b,Undernet={Modals:ct,Accordions:lt,Dropdowns:dt,Utils:ut,start:function(){Undernet.Modals.start(),Undernet.Accordions.start(),Undernet.Dropdowns.start(),Undernet.Utils.enableFocusOutline()},stop:function(){Undernet.Modals.stop(),Undernet.Accordions.stop(),Undernet.Dropdowns.stop(),Undernet.Utils.disableFocusOutline()}};window.Undernet=Undernet,t.default=Undernet,t.Modals=ct,t.Accordions=lt,t.Dropdowns=dt,t.Utils=ut,Object.defineProperty(t,"__esModule",{value:!0})}); //# sourceMappingURL=undernet.bundle.min.js.map diff --git a/dist/undernet.bundle.min.js.map b/dist/undernet.bundle.min.js.map index 39a9fb6a..9b636328 100644 --- a/dist/undernet.bundle.min.js.map +++ b/dist/undernet.bundle.min.js.map @@ -1 +1 @@ -{"version":3,"file":"undernet.bundle.min.js","sources":["../js/src/utils.js","../js/src/components/modal.js","../js/src/components/accordion.js","../js/src/components/dropdown.js","../js/src/index.js","../js/src/index.bundle.js"],"sourcesContent":["\"use strict\"\n\nconst KeyCodes = {\n SHIFT: 16,\n TAB: 9,\n ARROW_UP: 38,\n ARROW_DOWN: 40,\n}\n\nconst Selectors = {\n NOT_VISUALLY_HIDDEN: \":not(.is-visually-hidden)\",\n FOCUSABLE_TAGS: [\"a\", \"button\", \"input\", \"object\", \"select\", \"textarea\", \"[tabindex]\"],\n KEYBOARD_CLASS: \"using-keyboard\",\n}\n\nconst Events = {\n KEYDOWN: \"keydown\",\n CLICK: \"click\",\n}\n\n/**\n * Utility methods for DOM traversal and focus trapping.\n * @module Utils\n */\nexport default class Utils {\n constructor() {\n // events\n this._listenForKeyboard = this._listenForKeyboard.bind(this)\n this._listenForClick = this._listenForClick.bind(this)\n this._handleFocusTrapWithTab = this._handleFocusTrapWithTab.bind(this)\n this._handleFocusTrapWithArrows = this._handleFocusTrapWithArrows.bind(this)\n\n this._focusContainerSelector = \"\"\n this._focusableChildren = []\n this._focusableFirstChild = {}\n this._focusableLastChild = {}\n this._listeningForKeydown = false\n this._trapFocusWithArrows = false\n }\n\n // public\n\n /**\n * Listens to the first and last elements matched from this.getFocusableElements()\n * @param {String} container - The container's class, attribute, etc.\n * @param {Object} options - Optional has hof options.\n */\n captureFocus(container, options) {\n this._focusContainerSelector = container\n this._focusableChildren = this.getFocusableElements(this._focusContainerSelector)\n this._focusableFirstChild = this._focusableChildren[0]\n this._focusableLastChild = this._focusableChildren[this._focusableChildren.length - 1]\n\n if (options) {\n if (options.useArrows) {\n this._trapFocusWithArrows = options.useArrows || this._trapFocusWithArrows\n document.addEventListener(Events.KEYDOWN, this._handleFocusTrapWithArrows)\n }\n } else {\n document.addEventListener(Events.KEYDOWN, this._handleFocusTrapWithTab)\n }\n }\n\n /**\n * Stop trapping focus set in this.captureFocus()\n */\n releaseFocus() {\n if (this._trapFocusWithArrows) {\n document.removeEventListener(Events.KEYDOWN, this._handleFocusTrapWithArrows)\n this._trapFocusWithArrows = false\n } else {\n document.removeEventListener(Events.KEYDOWN, this._handleFocusTrapWithTab)\n }\n }\n\n /**\n * Begin listening to _listenForKeyboard()\n */\n enableFocusOutline() {\n document.addEventListener(Events.KEYDOWN, this._listenForKeyboard)\n }\n\n /**\n * Completely disable focus outline utility.\n */\n disableFocusOutline() {\n if (this._listeningForKeydown) {\n document.removeEventListener(Events.KEYDOWN, this._listenForKeyboard)\n } else {\n document.removeEventListener(Events.CLICK, this._listenForClick)\n }\n }\n\n /**\n * Because IE does not recognize NodeList.forEach(),\n * we use a cross-browser solution for returning an array of DOM nodes every time.\n * @param {String} element - A DOM node's class, attribute, etc., to search the document.\n * @return {Array}\n */\n getElements(element) {\n const nodeList = document.querySelectorAll(element)\n return Array.apply(null, nodeList)\n }\n\n /**\n * Creates a string of element selector patterns using common elements.\n * @param {String} container - The enclosing container's class, attribute, etc.\n * @return {String}\n */\n getFocusableElements(container) {\n const focusables = Selectors.FOCUSABLE_TAGS.map(\n element => `${container} ${element}${Selectors.NOT_VISUALLY_HIDDEN}`,\n ).join(\", \")\n\n return this.getElements(focusables)\n }\n\n // private\n\n /**\n * When a key is pressed, detect if it's tab or shift keys and enable\n * focus outlines on currently focused element(s). Then, remove keydown listener\n * and add click listener on _listenForClick().\n * @param {Object} event - Event (keypress).\n */\n _listenForKeyboard(event) {\n const tabKey = event.which === KeyCodes.TAB\n const shiftKey = event.which === KeyCodes.SHIFT || event.shiftKey\n const arrowUp = event.which === KeyCodes.ARROW_UP\n const arrowDown = event.which === KeyCodes.ARROW_DOWN\n\n if (tabKey || shiftKey || arrowUp || arrowDown) {\n document.body.classList.add(Selectors.KEYBOARD_CLASS)\n document.removeEventListener(Events.KEYDOWN, this._listenForKeyboard)\n document.addEventListener(Events.CLICK, this._listenForClick)\n this._listeningForKeydown = false\n }\n }\n\n /**\n * On click, remove Selectors.KEYBOARD_CLASS and re-add keydown listener.\n * @param {Object} event - Event (keypress).\n */\n _listenForClick(event) {\n document.body.classList.remove(Selectors.KEYBOARD_CLASS)\n document.removeEventListener(Events.CLICK, this._listenForClick)\n document.addEventListener(Events.KEYDOWN, this._listenForKeyboard)\n this._listeningForKeydown = true\n }\n\n /**\n * Handles focus on first or last child in a container, using tab and tab+shift keys.\n * @param {Object} event - Event (keypress)\n */\n _handleFocusTrapWithTab(event) {\n const containerElement = document.querySelector(this._focusContainerSelector)\n const containerActive = document.activeElement === containerElement\n const firstActive = document.activeElement === this._focusableFirstChild\n const lastActive = document.activeElement === this._focusableLastChild\n const tabKey = event.which === KeyCodes.TAB\n const shiftKey = event.which === KeyCodes.SHIFT || event.shiftKey\n const hasShift = shiftKey && tabKey\n const noShift = !shiftKey && tabKey\n\n if (shiftKey && tabKey && (firstActive || containerActive)) {\n event.preventDefault()\n this._focusableLastChild.focus()\n } else if (!shiftKey && tabKey && lastActive) {\n event.preventDefault()\n this._focusableFirstChild.focus()\n }\n }\n\n /**\n * Handles focus on the first, last, next, or previous child in a container, using up and down arrow keys.\n * @param {Object} event - Event (keypress)\n */\n _handleFocusTrapWithArrows(event) {\n const firstActive = document.activeElement === this._focusableFirstChild\n const lastActive = document.activeElement === this._focusableLastChild\n const arrowUp = event.which === KeyCodes.ARROW_UP\n const arrowDown = event.which === KeyCodes.ARROW_DOWN\n\n if (arrowUp || arrowDown) {\n event.preventDefault()\n\n if (firstActive && arrowUp) {\n this._focusableLastChild.focus()\n } else if (lastActive && arrowDown) {\n this._focusableFirstChild.focus()\n } else if (arrowDown) {\n this._focusNextChild()\n } else if (arrowUp) {\n this._focusLastChild()\n }\n }\n }\n\n /**\n * Focus the next child in this._focusableChildren.\n */\n _focusNextChild() {\n for (let i = 0; i < this._focusableChildren.length; i++) {\n if (this._focusableChildren[i] === document.activeElement) {\n this._focusableChildren[i + 1].focus()\n break\n }\n }\n }\n\n /**\n * Focus the previous child in this._focusableChildren.\n */\n _focusLastChild() {\n for (let i = 0; i < this._focusableChildren.length; i++) {\n if (this._focusableChildren[i] === document.activeElement) {\n this._focusableChildren[i - 1].focus()\n break\n }\n }\n }\n}\n","\"use strict\"\n\nimport Utils from \"../utils\"\n\nconst KeyCodes = {\n ESCAPE: 27,\n}\n\nconst Selectors = {\n // unique\n DATA_MODAL: \"data-modal\",\n DATA_MODAL_ID: \"data-modal-id\",\n DATA_MODAL_BUTTON: \"data-modal-button\",\n // common\n DATA_VISIBLE: \"data-visible\",\n DATA_CLOSE: \"data-close\",\n DATA_TARGET: \"data-target\",\n DATA_PARENT: \"data-parent\",\n // accessibility\n ARIA_HIDDEN: \"aria-hidden\",\n ARIA_MODAL: \"aria-modal\",\n ROLE: \"role\",\n TABINDEX: \"tabindex\",\n // classes\n NO_SCROLL: \"no-scroll\",\n}\n\nconst Events = {\n KEYDOWN: \"keydown\",\n CLICK: \"click\",\n RESIZE: \"resize\",\n}\n\nconst Messages = {\n NO_TARGET_ERROR: `Could not find [data-target] attribute associated with a [data-modal-button] element.`,\n NO_PARENT_ERROR: `Could not find [data-parent] attribute associated with a [data-modal] element.`,\n NO_ID_ERROR: id =>\n `Could not find [data-modal-id='${id}'] associated with a [data-modal] element.`,\n}\n\n/**\n * Modal component class.\n * @module Modal\n * @requires Utils\n */\nexport default class Modal extends Utils {\n constructor() {\n super()\n\n // events\n this._render = this._render.bind(this)\n this._handleClose = this._handleClose.bind(this)\n this._handleOverlayClick = this._handleOverlayClick.bind(this)\n this._handleEscapeKeyPress = this._handleEscapeKeyPress.bind(this)\n\n // all modals\n this._modals = []\n this._modalButtons = []\n\n // active modal\n this._activeModalButton = {}\n this._activeModalOverlay = {}\n this._activeModal = {}\n this._activeModalId = \"\"\n this._activeModalOverlayAttr = \"\"\n this._activeModalSelector = \"\"\n this._activeModalCloseButtons = []\n\n // attribute helpers\n this._modalContainerAttr = `[${Selectors.DATA_MODAL}]`\n }\n\n // public\n\n /**\n * Add accessible attributes to modal containers\n * Begin listening to elements with [data-modal-button]\n */\n start() {\n this._modals = this.getElements(this._modalContainerAttr)\n this._modalButtons = this.getElements(`[${Selectors.DATA_MODAL_BUTTON}]`)\n\n this.getFocusableElements(this._modalContainerAttr).forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n\n if (this._modals.length) {\n this._modals.forEach(modal => {\n this._setupModal(modal)\n })\n }\n\n if (this._modalButtons.length) {\n this._modalButtons.forEach(button => {\n button.addEventListener(Events.CLICK, this._render)\n })\n }\n }\n\n /**\n * Stop listening to modal buttons\n */\n stop() {\n this._modalButtons.forEach(button => {\n button.removeEventListener(Events.CLICK, this._render)\n })\n }\n\n // private\n\n /**\n * Find a button through event.target, then render the corresponding modal attribute via matching target id\n * @param {Object} event - The event object\n */\n _render(event) {\n event.preventDefault()\n this._activeModalButton = event.target\n\n if (!this._activeModalButton.getAttribute(Selectors.DATA_TARGET)) {\n return console.error(Messages.NO_TARGET_ERROR)\n }\n\n this._activeModalId = this._activeModalButton.getAttribute(Selectors.DATA_TARGET)\n this._activeModalOverlayAttr = `[${Selectors.DATA_MODAL_ID}=\"${this._activeModalId}\"]`\n\n if (!document.querySelector(this._activeModalOverlayAttr)) {\n return console.error(Messages.NO_ID_ERROR(this._activeModalId))\n }\n\n this._activeModalOverlay = document.querySelector(this._activeModalOverlayAttr)\n\n this._activeModalSelector = `${this._activeModalOverlayAttr} ${this._modalContainerAttr}`\n this._activeModal = document.querySelector(this._activeModalSelector)\n this._activeModalCloseButtons = this.getElements(\n `${this._activeModalOverlayAttr} [${Selectors.DATA_CLOSE}]`,\n )\n\n this.getFocusableElements(this._activeModalSelector).forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"0\")\n })\n\n this._handleScrollStop()\n this.captureFocus(this._activeModalSelector)\n this._activeModalOverlay.setAttribute(Selectors.ARIA_HIDDEN, \"false\")\n this._activeModal.setAttribute(Selectors.TABINDEX, \"-1\")\n this._activeModalOverlay.setAttribute(Selectors.DATA_VISIBLE, \"true\")\n this._activeModal.focus()\n\n // offset slight scroll caused by this._activeModal.focus()\n this._activeModalOverlay.scrollTop = 0\n\n // begin listening to events\n document.addEventListener(Events.KEYDOWN, this._handleEscapeKeyPress)\n document.addEventListener(Events.CLICK, this._handleOverlayClick)\n this._activeModalCloseButtons.forEach(button => {\n button.addEventListener(Events.CLICK, this._handleClose)\n })\n }\n\n _setupModal(modal) {\n let modalId\n if (!modal.getAttribute(Selectors.DATA_PARENT)) {\n return console.error(Messages.NO_PARENT_ERROR)\n } else {\n modalId = modal.getAttribute(Selectors.DATA_PARENT)\n }\n\n let modalWrapper\n if (!document.querySelector(`[${Selectors.DATA_MODAL_ID}='${modalId}']`)) {\n return console.error(Messages.NO_ID_ERROR(modalId))\n } else {\n modalWrapper = document.querySelector(`[${Selectors.DATA_MODAL_ID}='${modalId}']`)\n }\n\n modalWrapper.setAttribute(Selectors.ARIA_HIDDEN, \"true\")\n modalWrapper.setAttribute(Selectors.DATA_VISIBLE, \"false\")\n modal.setAttribute(Selectors.ARIA_MODAL, \"true\")\n modal.setAttribute(Selectors.ROLE, \"dialog\")\n }\n\n /**\n * Turn off event listeners and reset focus to last selected DOM node (button)\n * @param {Object} event - Event (keydown or click)\n */\n _handleClose(event) {\n event.preventDefault()\n this._activeModalOverlay.setAttribute(Selectors.DATA_VISIBLE, \"false\")\n this._handleReturnFocus()\n this._handleScrollRestore()\n this.releaseFocus()\n this._activeModalOverlay.setAttribute(Selectors.ARIA_HIDDEN, \"true\")\n this._activeModal.removeAttribute(Selectors.TABINDEX)\n\n this.getFocusableElements(this._activeModalSelector).forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n\n // stop listening to events\n document.removeEventListener(Events.KEYDOWN, this._handleEscapeKeyPress)\n document.removeEventListener(Events.CLICK, this._handleOverlayClick)\n this._activeModalCloseButtons.forEach(button => {\n button.removeEventListener(Events.CLICK, this._handleClose)\n })\n }\n\n /**\n * Handles click event on the modal background to close it.\n * @param {Object} event - Event (keydown)\n */\n _handleOverlayClick(event) {\n if (event.target === this._activeModalOverlay) {\n this._handleClose(event)\n }\n }\n\n /**\n * Handles escape key event to close the current modal\n * @param {Object} event - Event (keydown)\n */\n _handleEscapeKeyPress(event) {\n if (event.which === KeyCodes.ESCAPE) {\n this._handleClose(event)\n }\n }\n\n /**\n * Returns focus to the last focused element before the modal was called.\n * @param {Object} button - The current modal's corresponding button.\n */\n _handleReturnFocus() {\n this._activeModalButton.setAttribute(Selectors.TABINDEX, \"-1\")\n this._activeModalButton.focus()\n this._activeModalButton.removeAttribute(Selectors.TABINDEX)\n }\n\n /**\n * Restores scroll behavior to and \n */\n _handleScrollRestore() {\n document.body.classList.remove(Selectors.NO_SCROLL)\n document.querySelector(\"html\").classList.remove(Selectors.NO_SCROLL)\n }\n\n /**\n * Prevents scroll behavior on and \n */\n _handleScrollStop() {\n document.body.classList.add(Selectors.NO_SCROLL)\n document.querySelector(\"html\").classList.add(Selectors.NO_SCROLL)\n }\n}\n","\"use strict\"\n\nimport Utils from \"../utils\"\n\nconst Selectors = {\n // unique\n DATA_ACCORDION: \"data-accordion\",\n DATA_ACCORDION_ROW: \"data-accordion-row\",\n // common\n DATA_VISIBLE: \"data-visible\",\n DATA_TARGET: \"data-target\",\n DATA_TOGGLE_MULTIPLE: \"data-toggle-multiple\",\n DATA_PARENT: \"data-parent\",\n // accessibility\n ARIA_EXPANDED: \"aria-expanded\",\n ARIA_CONTROLS: \"aria-controls\",\n ARIA_HIDDEN: \"aria-hidden\",\n ARIA_LABELLEDBY: \"aria-labelledby\",\n TABINDEX: \"tabindex\",\n}\n\nconst Events = {\n CLICK: \"click\",\n KEYDOWN: \"keydown\",\n}\n\nconst Messages = {\n NO_VISIBLE_ERROR: id =>\n `Could not find parent with [data-visible] attribute associated with [data-target='${id}'].`,\n NO_ROW_ERROR: id => `Could not find [data-accordion-row] associated with ${id}.`,\n NO_HEADER_ID_ERROR: id => `Could not find header tag associated with [data-target='${id}'].`,\n NO_PARENT_ERROR: id => `Could not find [data-parent] associated with [data-target='${id}'].`,\n NO_CONTENT_ERROR: id =>\n `Could not find accordion content block with [id] ${id} associated with [data-target='${id}'].`,\n}\n\n/**\n * Accordion component class.\n * @module Accordion\n * @requires Utils\n */\nexport default class Accordion extends Utils {\n constructor() {\n super()\n\n // events\n this._render = this._render.bind(this)\n\n // all accordions\n this._accordionButtons = []\n this._accordionContentsAttr = \"\"\n this._accordionContents = []\n\n // active accordion\n this._activeContainer = {}\n this._activeButton = {}\n this._activeAccordionRowId = \"\"\n this._activeRowAttr = \"\"\n this._activeRow = \"\"\n this._activeContainerId = \"\"\n this._activeContainerAttr = \"\"\n this._activeContent = {}\n this._activeButtonExpandState = \"\"\n this._activeContentHiddenState = \"\"\n\n // other data\n this._headerLevels = [1, 2, 3, 4, 5, 6]\n }\n\n // public\n\n /**\n * Sets up accordion components and listens to buttons for events.\n * Begin listening to [data-accordion-button] elements\n */\n start() {\n const accordionButtonSelector = this._getPossibleAccordionButtonAttrs(\n `[${Selectors.DATA_ACCORDION}]`,\n )\n this._accordionButtons = this.getElements(accordionButtonSelector)\n\n if (this._accordionButtons.length) {\n this._accordionButtons.forEach(button => {\n this._setupAccordion(button)\n button.addEventListener(Events.CLICK, this._render)\n })\n }\n }\n\n /**\n * Stop listening to accordion button events.\n */\n stop() {\n this._accordionButtons.forEach(button => {\n button.removeEventListener(Events.CLICK, this._render)\n })\n }\n\n // private\n\n /**\n * Add initial attributes to accordion elements.\n * @param {Element} button - A button element that triggers an accordion.\n */\n _setupAccordion(button) {\n const buttonId = button.getAttribute(Selectors.DATA_TARGET)\n\n if (!document.getElementById(buttonId)) {\n return console.error(Messages.NO_CONTENT_ERROR(buttonId))\n }\n\n const buttonContent = document.getElementById(buttonId)\n const accordionRowAttr = this._getAccordionRowAttr(buttonId)\n\n if (!document.querySelector(accordionRowAttr)) {\n return console.error(Messages.NO_ROW_ERROR(buttonId))\n }\n\n const accordionRow = document.querySelector(accordionRowAttr)\n const buttonHeaderAttr = this._getPossibleAccordionHeaderAttrs(accordionRowAttr)\n const buttonHeader = this.getElements(buttonHeaderAttr)[0]\n\n if (!buttonHeader || !buttonHeader.id) {\n console.error(Messages.NO_HEADER_ID_ERROR(buttonId))\n }\n\n const buttonContentChildren = this.getFocusableElements(`#${buttonContent.id}`)\n\n button.setAttribute(Selectors.ARIA_CONTROLS, buttonId)\n buttonContent.setAttribute(Selectors.ARIA_LABELLEDBY, buttonHeader.id)\n\n if (!accordionRow.getAttribute(Selectors.DATA_VISIBLE)) {\n return console.error(Messages.NO_VISIBLE_ERROR(buttonId))\n }\n\n const contentShouldExpand = accordionRow.getAttribute(Selectors.DATA_VISIBLE)\n if (contentShouldExpand === \"true\") {\n buttonContent.style.maxHeight = `${buttonContent.scrollHeight}px`\n button.setAttribute(Selectors.ARIA_EXPANDED, \"true\")\n buttonContent.setAttribute(Selectors.ARIA_HIDDEN, \"false\")\n buttonContentChildren.forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"0\")\n })\n } else {\n button.setAttribute(Selectors.ARIA_EXPANDED, \"false\")\n buttonContent.setAttribute(Selectors.ARIA_HIDDEN, \"true\")\n buttonContentChildren.forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n }\n }\n\n /**\n * Build a selector string to match possible accordion buttons\n * @param {String} attr - A unique attribute\n * @return {String} - String of possible button selectors\n */\n _getPossibleAccordionButtonAttrs(attr) {\n return this._headerLevels\n .map(\n num => `${attr} > [${Selectors.DATA_ACCORDION_ROW}] > h${num} [${Selectors.DATA_TARGET}]`,\n )\n .join(\", \")\n }\n\n /**\n * Build a selector string to match possible accordion headers\n * @param {String} attr - A unique attribute\n * @return {String} - String of possible header selectors\n */\n _getPossibleAccordionHeaderAttrs(attr) {\n return this._headerLevels.map(num => `${attr} > h${num}`).join(\", \")\n }\n\n /**\n * Build a unique accordion row attribute selector.\n * @param {String} id - An id value associated with a given Selectors.DATA_TARGET\n * @return {String} - A unique accordion row selector\n */\n _getAccordionRowAttr(id) {\n return `[${Selectors.DATA_ACCORDION_ROW}='${id}']`\n }\n\n /**\n * Open accordion content associated with an accordion button.\n * @param {Object} event - The event object\n */\n _render(event) {\n event.preventDefault()\n\n this._activeButton = event.target\n this._activeAccordionRowId = this._activeButton.getAttribute(Selectors.DATA_TARGET)\n\n this._activeRowAttr = this._getAccordionRowAttr(this._activeAccordionRowId)\n this._activeRow = document.querySelector(this._activeRowAttr)\n\n if (!this._activeButton.getAttribute(Selectors.DATA_PARENT)) {\n return console.error(Messages.NO_PARENT_ERROR(this._activeAccordionRowId))\n }\n\n this._activeContainerId = this._activeButton.getAttribute(Selectors.DATA_PARENT)\n this._activeContainerAttr = `[${Selectors.DATA_ACCORDION}='${this._activeContainerId}']`\n\n if (!document.querySelector(this._activeContainerAttr)) {\n return console.error(Messages.NO_ACCORDION_ERROR(this._activeContainerId))\n }\n\n this._activeContainer = document.querySelector(this._activeContainerAttr)\n this._activeContent = document.getElementById(this._activeAccordionRowId)\n\n const accordionButtonState = this._activeRow.getAttribute(Selectors.DATA_VISIBLE)\n\n this._activeButtonExpandState = accordionButtonState === \"true\" ? \"false\" : \"true\"\n this._activeContentHiddenState = this._activeButtonExpandState === \"false\" ? \"true\" : \"false\"\n\n this._closeAllIfToggleable()\n this._toggleSelectedAccordion()\n }\n\n /**\n * If toggling multiple rows at once isn't enabled, close all rows except the selected one.\n * This ensures the selected one can be closed if it's already open.\n */\n _closeAllIfToggleable() {\n if (this._activeContainer.hasAttribute(Selectors.DATA_TOGGLE_MULTIPLE)) return\n\n const allContentAttr = `${this._activeContainerAttr} [${Selectors.ARIA_HIDDEN}]`\n const allRows = this.getElements(`${this._activeContainerAttr} [${Selectors.DATA_VISIBLE}]`)\n const allContent = this.getElements(allContentAttr)\n\n const accordionButtonSelector = this._getPossibleAccordionButtonAttrs(this._activeContainerAttr)\n const allButtons = this.getElements(accordionButtonSelector)\n\n allContent.forEach(content => {\n if (content !== this._activeContent) content.style.maxHeight = null\n })\n\n this.getFocusableElements(allContentAttr).forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n\n this._toggleAttributeInCollection(allRows, Selectors.DATA_VISIBLE, \"true\", \"false\")\n this._toggleAttributeInCollection(allButtons, Selectors.ARIA_EXPANDED, \"true\", \"false\")\n this._toggleAttributeInCollection(allContent, Selectors.ARIA_HIDDEN, \"false\", \"true\")\n }\n\n /**\n * Toggle the currently selected accordion button's content.\n */\n _toggleSelectedAccordion() {\n this._activeRow.setAttribute(Selectors.DATA_VISIBLE, this._activeButtonExpandState)\n this._activeButton.setAttribute(Selectors.ARIA_EXPANDED, this._activeButtonExpandState)\n this._activeContent.setAttribute(Selectors.ARIA_HIDDEN, this._activeContentHiddenState)\n\n const activeContentBlock = `#${this._activeAccordionRowId}`\n this.getFocusableElements(activeContentBlock).forEach(element => {\n const value = this._activeButtonExpandState === \"true\" ? \"0\" : \"-1\"\n element.setAttribute(Selectors.TABINDEX, value)\n })\n\n if (this._activeContent.style.maxHeight) {\n this._activeContent.style.maxHeight = null\n } else {\n this._activeContent.style.maxHeight = `${this._activeContent.scrollHeight}px`\n }\n }\n\n /**\n * Toggles a single attribute of a series of elements.\n * @param {Array} elements - An array of elements to be operated on.\n * @param {String} attributeName - An attribute to be changed.\n * @param {String} currentValue - The current value of attributeName\n * @param {String} newValue - The new value of attributeName\n */\n _toggleAttributeInCollection(elements, attributeName, currentValue, newValue) {\n elements.forEach(element => {\n if (element.hasAttribute(attributeName, currentValue)) {\n element.setAttribute(attributeName, newValue)\n }\n })\n }\n}\n","\"use strict\"\n\nimport Utils from \"../utils\"\n\nconst KeyCodes = {\n TAB: 9,\n SHIFT: 16,\n ESCAPE: 27,\n ARROW_UP: 38,\n ARROW_DOWN: 40,\n}\n\nconst Selectors = {\n // unique\n DATA_DROPDOWN: \"data-dropdown\",\n // common\n DATA_TARGET: \"data-target\",\n DATA_PARENT: \"data-parent\",\n DATA_VISIBLE: \"data-visible\",\n // accessibility\n TABINDEX: \"tabindex\",\n ARIA_HASPOPUP: \"aria-haspopup\",\n ARIA_CONTROLS: \"aria-controls\",\n ARIA_LABELLEDBY: \"aria-labelledby\",\n ARIA_EXPANDED: \"aria-expanded\",\n ROLE: \"role\",\n}\n\nconst Events = {\n KEYDOWN: \"keydown\",\n CLICK: \"click\",\n}\n\nconst Messages = {\n NO_PARENT_ERROR: `Could not find dropdown button's [data-parent] attribute.`,\n NO_DROPDOWN_ERROR: attr => `Could not find dropdown container associated with ${attr}.`,\n NO_MENU_ERROR: attr => `Could not find menu associated with ${attr}.`,\n}\n\n/**\n * Dropdown component class.\n * @module Dropdown\n * @requires Utils\n */\nexport default class Dropdown extends Utils {\n constructor() {\n super()\n\n // events\n this._render = this._render.bind(this)\n this._handleFirstTabClose = this._handleFirstTabClose.bind(this)\n this._handleLastTabClose = this._handleLastTabClose.bind(this)\n this._renderWithKeys = this._renderWithKeys.bind(this)\n this._handleClose = this._handleClose.bind(this)\n this._handleEscapeKeyPress = this._handleEscapeKeyPress.bind(this)\n this._handleOffMenuClick = this._handleOffMenuClick.bind(this)\n\n // active dropdown\n this._activeDropdownButton = null\n this._activeDropdown = null\n this._activeDropdownMenu = null\n this._activeDropdownLinks = []\n this._allowFocusReturn = true\n this._activeDropdownId = \"\"\n this._activeDropdownAttr = \"\"\n this._activeDropdownMenuId = \"\"\n\n // all dropdowns\n this._dropdownButtons = []\n this._dropdowns = []\n\n // dropdown element selectors\n this._dropdownContainerAttr = `[${Selectors.DATA_DROPDOWN}]`\n this._dropdownTargetAttr = `[${Selectors.DATA_TARGET}]`\n }\n\n // public\n\n /**\n * Find and set up dropdown buttons and menus.\n * Begin listening to dropdowns for events.\n */\n start() {\n this._dropdowns = this.getElements(`${this._dropdownContainerAttr}`)\n this._dropdownButtons = this.getElements(\n `${this._dropdownContainerAttr} > ${this._dropdownTargetAttr}`,\n )\n\n if (this._dropdowns.length) {\n this._dropdowns.forEach(dropdown => this._setupDropdown(dropdown))\n }\n\n this._dropdownButtons.forEach(button => {\n button.addEventListener(Events.CLICK, this._render)\n button.addEventListener(Events.KEYDOWN, this._renderWithKeys)\n })\n }\n\n /**\n * Stop listening for dropdown events.\n */\n stop() {\n this._dropdownButtons.forEach(button => {\n button.removeEventListener(Events.CLICK, this._render)\n button.removeEventListener(Events.KEYDOWN, this._renderWithKeys)\n })\n }\n\n // private\n\n /**\n * Find a button through event.target, then render the corresponding modal attribute via matching target id\n * @param {Object} event - The event object\n * @param {Number} key - The key code that called _render()\n */\n _render(event, key) {\n if (!key) event.preventDefault()\n event.stopPropagation()\n\n if (this._activeDropdownButton) {\n this._allowFocusReturn = false\n this._handleClose(event)\n this._allowFocusReturn = true\n }\n\n // dropdown button / trigger\n this._activeDropdownButton = event.target\n\n if (!this._activeDropdownButton.getAttribute(Selectors.DATA_PARENT)) {\n return console.error(Messages.NO_PARENT_ERROR)\n }\n\n this._activeDropdownId = this._activeDropdownButton.getAttribute(Selectors.DATA_PARENT)\n\n // dropdown container\n this._activeDropdownAttr = `[${Selectors.DATA_DROPDOWN}=\"${this._activeDropdownId}\"]`\n\n if (!document.querySelector(this._activeDropdownAttr)) {\n return console.error(Messages.NO_DROPDOWN_ERROR(this._activeDropdownAttr))\n }\n\n this._activeDropdown = document.querySelector(this._activeDropdownAttr)\n\n // dropdown menu\n this._activeDropdownMenuId = this._activeDropdownButton.getAttribute(Selectors.DATA_TARGET)\n this._activeDropdownMenu = document.getElementById(this._activeDropdownMenuId)\n\n // dropdown button\n this._activeDropdownButton.setAttribute(Selectors.ARIA_EXPANDED, \"true\")\n this._activeDropdown.setAttribute(Selectors.DATA_VISIBLE, \"true\")\n\n // reset button event listener to close the menu, instead of open it\n this._activeDropdownButton.removeEventListener(Events.CLICK, this._render)\n this._activeDropdownButton.addEventListener(Events.CLICK, this._handleClose)\n\n document.addEventListener(Events.KEYDOWN, this._handleEscapeKeyPress)\n document.addEventListener(Events.CLICK, this._handleOffMenuClick)\n\n this._activeDropdownLinks = this._getDropdownLinks(this._activeDropdownAttr)\n\n this.firstDropdownLink = this._activeDropdownLinks[0]\n this.lastDropdownLink = this._activeDropdownLinks[this._activeDropdownLinks.length - 1]\n\n this.firstDropdownLink.addEventListener(Events.KEYDOWN, this._handleFirstTabClose)\n this.lastDropdownLink.addEventListener(Events.KEYDOWN, this._handleLastTabClose)\n\n if (key && key === KeyCodes.ARROW_UP) {\n this.lastDropdownLink.focus()\n } else {\n this.firstDropdownLink.focus()\n }\n\n this._activeDropdownLinks.forEach(link => {\n link.setAttribute(Selectors.TABINDEX, \"0\")\n link.addEventListener(Events.CLICK, this._handleClose)\n })\n\n this.captureFocus(`${this._activeDropdownAttr} > ul`, { useArrows: true })\n }\n\n /**\n * Closes the dropdown if user uses shift and tab keys on the first dropdown element.\n * @param {Object} event - The event object\n */\n _handleFirstTabClose(event) {\n const shiftKey = event.which === KeyCodes.SHIFT || event.shiftKey\n const tabKey = event.which === KeyCodes.TAB\n\n if (shiftKey && tabKey) {\n this._handleClose(event)\n }\n }\n\n /**\n * Closes the dropdown if user uses tab key on the last dropdown element.\n * @param {Object} event - The event object\n */\n _handleLastTabClose(event) {\n const shiftKey = event.which === KeyCodes.SHIFT || event.shiftKey\n const tabKey = event.which === KeyCodes.TAB\n\n if (tabKey && !shiftKey) {\n this._handleClose(event)\n }\n }\n\n /**\n * Renders dropdown if the user uses arrow up or down.\n * @param {Object} event - The event object\n */\n _renderWithKeys(event) {\n if (event.which === KeyCodes.ARROW_UP || event.which === KeyCodes.ARROW_DOWN) {\n this._render(event, event.which)\n }\n }\n\n /**\n * Closes currently open dropdown.\n * @param {Object} event - The event object\n */\n _handleClose(event) {\n event.preventDefault()\n\n this.releaseFocus()\n\n this._activeDropdownButton.setAttribute(Selectors.ARIA_EXPANDED, \"false\")\n this._activeDropdown.setAttribute(Selectors.DATA_VISIBLE, \"false\")\n\n this._activeDropdownLinks.forEach(link => {\n link.setAttribute(Selectors.TABINDEX, \"-1\")\n link.removeEventListener(Events.CLICK, this._handleClose)\n })\n\n this._activeDropdownButton.removeEventListener(Events.CLICK, this._handleClose)\n this._activeDropdownButton.addEventListener(Events.CLICK, this._render)\n\n document.removeEventListener(Events.KEYDOWN, this._handleEscapeKeyPress)\n document.removeEventListener(Events.CLICK, this._handleOffMenuClick)\n\n if (this._allowFocusReturn) {\n this._handleReturnFocus()\n }\n }\n\n /**\n * Use escape key to close dropdown.\n * @param {Object} event - The event object\n */\n _handleEscapeKeyPress(event) {\n if (event.which === KeyCodes.ESCAPE) {\n this._handleClose(event)\n }\n }\n\n /**\n * Closes dropdown\n * @param {Object} event - The event object\n */\n _handleOffMenuClick(event) {\n if (event.target !== this._activeDropdownButton && event.target !== this._activeDropdownMenu) {\n this._handleClose(event)\n }\n }\n\n /**\n * Puts focus on a the active dropdown button.\n */\n _handleReturnFocus() {\n this._activeDropdownButton.setAttribute(Selectors.TAB_INDEX, \"-1\")\n this._activeDropdownButton.focus()\n this._activeDropdownButton.removeAttribute(Selectors.TAB_INDEX)\n }\n\n /**\n * Retrieve possible menu links or buttons as an array\n * @param {String} attr - The unique attribute for a dropdown.\n * @return {String} - Selector for possible menu item links.\n */\n _getDropdownLinks(attr) {\n return this.getElements(`${attr} > ul > li > a, ${attr} > ul > li > button`)\n }\n\n /**\n * Add starting attributes to a dropdown.\n * @param {Element} dropdown - A dropdown element.\n */\n _setupDropdown(dropdown) {\n const dropdownId = dropdown.getAttribute(Selectors.DATA_DROPDOWN)\n const dropdownIdAttr = `[${Selectors.DATA_DROPDOWN}=\"${dropdownId}\"]`\n const dropdownMenuItemsAttr = `${dropdownIdAttr} > ul > li`\n\n if (!document.querySelector(`${dropdownIdAttr} > ul`)) {\n return console.error(Messages.NO_MENU_ERROR(dropdownIdAttr))\n }\n\n const dropdownMenu = document.querySelector(`${dropdownIdAttr} > ul`)\n const dropdownButton = document.querySelector(`${dropdownIdAttr} > ${this._dropdownTargetAttr}`)\n\n dropdownButton.setAttribute(Selectors.ARIA_CONTROLS, dropdownMenu.id)\n dropdownButton.setAttribute(Selectors.ARIA_HASPOPUP, \"true\")\n dropdownButton.setAttribute(Selectors.ARIA_EXPANDED, \"false\")\n dropdownMenu.setAttribute(Selectors.ARIA_LABELLEDBY, dropdownButton.id)\n\n const dropdownMenuItems = this.getElements(dropdownMenuItemsAttr)\n dropdownMenuItems.forEach(item => item.setAttribute(Selectors.ROLE, \"none\"))\n\n this._getDropdownLinks(dropdownIdAttr).forEach(link => {\n link.setAttribute(Selectors.ROLE, \"menuitem\")\n link.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n }\n}\n","\"use strict\"\n\nimport _Modals from \"./components/modal\"\nimport _Accordion from \"./components/accordion\"\nimport _Dropdown from \"./components/dropdown\"\nimport _Utils from \"./utils\"\n\nexport const Modals = new _Modals()\nexport const Accordions = new _Accordion()\nexport const Dropdowns = new _Dropdown()\nexport const Utils = new _Utils()\n\nconst Undernet = {\n // Components\n Modals,\n Accordions,\n Dropdowns,\n\n // Utils\n Utils,\n}\n\nUndernet.start = () => {\n // Components\n Undernet.Modals.start()\n Undernet.Accordions.start()\n Undernet.Dropdowns.start()\n\n // Utils\n Undernet.Utils.enableFocusOutline()\n}\n\nUndernet.stop = () => {\n // Components\n Undernet.Modals.stop()\n Undernet.Accordions.stop()\n Undernet.Dropdowns.stop()\n\n // Utils\n Undernet.Utils.disableFocusOutline()\n}\n\nexport default Undernet\n","import Undernet from \"./index\"\n\nexport default Undernet\nexport { Modals, Accordions, Dropdowns, Utils } from \"./index\"\n\nwindow.Undernet = Undernet\n"],"names":["KeyCodes","Selectors","NOT_VISUALLY_HIDDEN","FOCUSABLE_TAGS","KEYBOARD_CLASS","Events","Utils","_listenForKeyboard","this","bind","_listenForClick","_handleFocusTrapWithTab","_handleFocusTrapWithArrows","_focusContainerSelector","_focusableChildren","_focusableFirstChild","_focusableLastChild","_listeningForKeydown","_trapFocusWithArrows","container","options","getFocusableElements","length","useArrows","document","addEventListener","removeEventListener","element","nodeList","querySelectorAll","Array","apply","focusables","map","join","getElements","event","tabKey","which","shiftKey","arrowUp","arrowDown","body","classList","add","remove","containerElement","querySelector","containerActive","activeElement","firstActive","lastActive","preventDefault","focus","_focusNextChild","_focusLastChild","i","Messages","id","Modal","_render","_this","_handleClose","_handleOverlayClick","_handleEscapeKeyPress","_modals","_modalButtons","_activeModalButton","_activeModalOverlay","_activeModal","_activeModalId","_activeModalOverlayAttr","_activeModalSelector","_activeModalCloseButtons","_modalContainerAttr","forEach","setAttribute","modal","_this2","_setupModal","button","_this3","target","getAttribute","_handleScrollStop","captureFocus","scrollTop","_this4","console","error","modalId","modalWrapper","_handleReturnFocus","_handleScrollRestore","releaseFocus","removeAttribute","_this5","NO_VISIBLE_ERROR","NO_ROW_ERROR","NO_HEADER_ID_ERROR","NO_PARENT_ERROR","NO_CONTENT_ERROR","Accordion","_accordionButtons","_accordionContentsAttr","_accordionContents","_activeContainer","_activeButton","_activeAccordionRowId","_activeRowAttr","_activeRow","_activeContainerId","_activeContainerAttr","_activeContent","_activeButtonExpandState","_activeContentHiddenState","_headerLevels","accordionButtonSelector","_getPossibleAccordionButtonAttrs","_setupAccordion","buttonId","getElementById","buttonContent","accordionRowAttr","_getAccordionRowAttr","accordionRow","buttonHeaderAttr","_getPossibleAccordionHeaderAttrs","buttonHeader","buttonContentChildren","style","maxHeight","scrollHeight","attr","num","NO_ACCORDION_ERROR","accordionButtonState","_closeAllIfToggleable","_toggleSelectedAccordion","hasAttribute","allContentAttr","allRows","allContent","allButtons","content","_toggleAttributeInCollection","activeContentBlock","value","elements","attributeName","currentValue","newValue","DATA_DROPDOWN","DATA_TARGET","DATA_PARENT","DATA_VISIBLE","TABINDEX","ARIA_HASPOPUP","ARIA_CONTROLS","ARIA_LABELLEDBY","ARIA_EXPANDED","ROLE","Dropdown","_handleFirstTabClose","_handleLastTabClose","_renderWithKeys","_handleOffMenuClick","_activeDropdownButton","_activeDropdown","_activeDropdownMenu","_activeDropdownLinks","_allowFocusReturn","_activeDropdownId","_activeDropdownAttr","_activeDropdownMenuId","_dropdownButtons","_dropdowns","_dropdownContainerAttr","_dropdownTargetAttr","dropdown","_setupDropdown","key","stopPropagation","_getDropdownLinks","firstDropdownLink","lastDropdownLink","link","TAB_INDEX","dropdownId","dropdownIdAttr","dropdownMenuItemsAttr","dropdownMenu","dropdownButton","item","Modals","_Modals","Accordions","_Accordion","Dropdowns","_Dropdown","_Utils","Undernet","start","enableFocusOutline","stop","disableFocusOutline","window"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"undernet.bundle.min.js","sources":["../js/src/utils.js","../js/src/components/modal.js","../js/src/components/accordion.js","../js/src/components/dropdown.js","../js/src/index.js","../js/src/index.bundle.js"],"sourcesContent":["\"use strict\"\n\nconst KeyCodes = {\n SHIFT: 16,\n TAB: 9,\n ARROW_UP: 38,\n ARROW_DOWN: 40,\n}\n\nconst Selectors = {\n NOT_VISUALLY_HIDDEN: \":not(.is-visually-hidden)\",\n FOCUSABLE_TAGS: [\"a\", \"button\", \"input\", \"object\", \"select\", \"textarea\", \"[tabindex]\"],\n KEYBOARD_CLASS: \"using-keyboard\",\n}\n\nconst Events = {\n KEYDOWN: \"keydown\",\n CLICK: \"click\",\n}\n\n/**\n * Utility methods for DOM traversal and focus trapping.\n * @module Utils\n */\nexport default class Utils {\n constructor() {\n // events\n this._listenForKeyboard = this._listenForKeyboard.bind(this)\n this._listenForClick = this._listenForClick.bind(this)\n this._handleFocusTrapWithTab = this._handleFocusTrapWithTab.bind(this)\n this._handleFocusTrapWithArrows = this._handleFocusTrapWithArrows.bind(this)\n\n this._focusContainerSelector = \"\"\n this._focusableChildren = []\n this._focusableFirstChild = {}\n this._focusableLastChild = {}\n this._listeningForKeydown = false\n this._trapFocusWithArrows = false\n }\n\n // public\n\n /**\n * Listens to the first and last elements matched from this.getFocusableElements()\n * @param {String} container - The container's class, attribute, etc.\n * @param {Object} options - Optional has hof options.\n */\n captureFocus(container, options) {\n this._focusContainerSelector = container\n this._focusableChildren = this.getFocusableElements(this._focusContainerSelector)\n this._focusableFirstChild = this._focusableChildren[0]\n this._focusableLastChild = this._focusableChildren[this._focusableChildren.length - 1]\n\n if (options) {\n if (options.useArrows) {\n this._trapFocusWithArrows = options.useArrows || this._trapFocusWithArrows\n document.addEventListener(Events.KEYDOWN, this._handleFocusTrapWithArrows)\n }\n } else {\n document.addEventListener(Events.KEYDOWN, this._handleFocusTrapWithTab)\n }\n }\n\n /**\n * Stop trapping focus set in this.captureFocus()\n */\n releaseFocus() {\n if (this._trapFocusWithArrows) {\n document.removeEventListener(Events.KEYDOWN, this._handleFocusTrapWithArrows)\n this._trapFocusWithArrows = false\n } else {\n document.removeEventListener(Events.KEYDOWN, this._handleFocusTrapWithTab)\n }\n }\n\n /**\n * Begin listening to _listenForKeyboard()\n */\n enableFocusOutline() {\n document.addEventListener(Events.KEYDOWN, this._listenForKeyboard)\n }\n\n /**\n * Completely disable focus outline utility.\n */\n disableFocusOutline() {\n if (this._listeningForKeydown) {\n document.removeEventListener(Events.KEYDOWN, this._listenForKeyboard)\n } else {\n document.removeEventListener(Events.CLICK, this._listenForClick)\n }\n }\n\n /**\n * Because IE does not recognize NodeList.forEach(),\n * we use a cross-browser solution for returning an array of DOM nodes every time.\n * @param {String} element - A DOM node's class, attribute, etc., to search the document.\n * @return {Array}\n */\n getElements(element) {\n const nodeList = document.querySelectorAll(element)\n return Array.apply(null, nodeList)\n }\n\n /**\n * Creates a string of element selector patterns using common elements.\n * @param {String} container - The enclosing container's class, attribute, etc.\n * @return {String}\n */\n getFocusableElements(container) {\n const focusables = Selectors.FOCUSABLE_TAGS.map(\n element => `${container} ${element}${Selectors.NOT_VISUALLY_HIDDEN}`,\n ).join(\", \")\n\n return this.getElements(focusables)\n }\n\n // private\n\n /**\n * When a key is pressed, detect if it's tab or shift keys and enable\n * focus outlines on currently focused element(s). Then, remove keydown listener\n * and add click listener on _listenForClick().\n * @param {Object} event - Event (keypress).\n */\n _listenForKeyboard(event) {\n const tabKey = event.which === KeyCodes.TAB\n const shiftKey = event.which === KeyCodes.SHIFT || event.shiftKey\n const arrowUp = event.which === KeyCodes.ARROW_UP\n const arrowDown = event.which === KeyCodes.ARROW_DOWN\n\n if (tabKey || shiftKey || arrowUp || arrowDown) {\n document.body.classList.add(Selectors.KEYBOARD_CLASS)\n document.removeEventListener(Events.KEYDOWN, this._listenForKeyboard)\n document.addEventListener(Events.CLICK, this._listenForClick)\n this._listeningForKeydown = false\n }\n }\n\n /**\n * On click, remove Selectors.KEYBOARD_CLASS and re-add keydown listener.\n * @param {Object} event - Event (keypress).\n */\n _listenForClick(event) {\n document.body.classList.remove(Selectors.KEYBOARD_CLASS)\n document.removeEventListener(Events.CLICK, this._listenForClick)\n document.addEventListener(Events.KEYDOWN, this._listenForKeyboard)\n this._listeningForKeydown = true\n }\n\n /**\n * Handles focus on first or last child in a container, using tab and tab+shift keys.\n * @param {Object} event - Event (keypress)\n */\n _handleFocusTrapWithTab(event) {\n const containerElement = document.querySelector(this._focusContainerSelector)\n const containerActive = document.activeElement === containerElement\n const firstActive = document.activeElement === this._focusableFirstChild\n const lastActive = document.activeElement === this._focusableLastChild\n const tabKey = event.which === KeyCodes.TAB\n const shiftKey = event.which === KeyCodes.SHIFT || event.shiftKey\n const hasShift = shiftKey && tabKey\n const noShift = !shiftKey && tabKey\n\n if (shiftKey && tabKey && (firstActive || containerActive)) {\n event.preventDefault()\n this._focusableLastChild.focus()\n } else if (!shiftKey && tabKey && lastActive) {\n event.preventDefault()\n this._focusableFirstChild.focus()\n }\n }\n\n /**\n * Handles focus on the first, last, next, or previous child in a container, using up and down arrow keys.\n * @param {Object} event - Event (keypress)\n */\n _handleFocusTrapWithArrows(event) {\n const firstActive = document.activeElement === this._focusableFirstChild\n const lastActive = document.activeElement === this._focusableLastChild\n const arrowUp = event.which === KeyCodes.ARROW_UP\n const arrowDown = event.which === KeyCodes.ARROW_DOWN\n\n if (arrowUp || arrowDown) {\n event.preventDefault()\n\n if (firstActive && arrowUp) {\n this._focusableLastChild.focus()\n } else if (lastActive && arrowDown) {\n this._focusableFirstChild.focus()\n } else if (arrowDown) {\n this._focusNextChild()\n } else if (arrowUp) {\n this._focusLastChild()\n }\n }\n }\n\n /**\n * Focus the next child in this._focusableChildren.\n */\n _focusNextChild() {\n for (let i = 0; i < this._focusableChildren.length; i++) {\n if (this._focusableChildren[i] === document.activeElement) {\n this._focusableChildren[i + 1].focus()\n break\n }\n }\n }\n\n /**\n * Focus the previous child in this._focusableChildren.\n */\n _focusLastChild() {\n for (let i = 0; i < this._focusableChildren.length; i++) {\n if (this._focusableChildren[i] === document.activeElement) {\n this._focusableChildren[i - 1].focus()\n break\n }\n }\n }\n}\n","\"use strict\"\n\nimport Utils from \"../utils\"\n\nconst KeyCodes = {\n ESCAPE: 27,\n}\n\nconst Selectors = {\n // unique\n DATA_MODAL: \"data-modal\",\n DATA_MODAL_ID: \"data-modal-id\",\n DATA_MODAL_BUTTON: \"data-modal-button\",\n // common\n DATA_VISIBLE: \"data-visible\",\n DATA_CLOSE: \"data-close\",\n DATA_TARGET: \"data-target\",\n DATA_PARENT: \"data-parent\",\n // accessibility\n ARIA_HIDDEN: \"aria-hidden\",\n ARIA_MODAL: \"aria-modal\",\n ROLE: \"role\",\n TABINDEX: \"tabindex\",\n // classes\n NO_SCROLL: \"no-scroll\",\n}\n\nconst Events = {\n KEYDOWN: \"keydown\",\n CLICK: \"click\",\n RESIZE: \"resize\",\n}\n\nconst Messages = {\n NO_TARGET_ERROR: `Could not find [data-target] attribute associated with a [data-modal-button] element.`,\n NO_PARENT_ERROR: `Could not find [data-parent] attribute associated with a [data-modal] element.`,\n NO_ID_ERROR: id =>\n `Could not find [data-modal-id='${id}'] associated with a [data-modal] element.`,\n}\n\n/**\n * Modal component class.\n * @module Modal\n * @requires Utils\n */\nexport default class Modal extends Utils {\n constructor() {\n super()\n\n // events\n this._render = this._render.bind(this)\n this._handleClose = this._handleClose.bind(this)\n this._handleOverlayClick = this._handleOverlayClick.bind(this)\n this._handleEscapeKeyPress = this._handleEscapeKeyPress.bind(this)\n\n // all modals\n this._modals = []\n this._modalButtons = []\n\n // active modal\n this._activeModalButton = {}\n this._activeModalOverlay = {}\n this._activeModal = {}\n this._activeModalId = \"\"\n this._activeModalOverlayAttr = \"\"\n this._activeModalSelector = \"\"\n this._activeModalCloseButtons = []\n\n // attribute helpers\n this._modalContainerAttr = `[${Selectors.DATA_MODAL}]`\n }\n\n // public\n\n /**\n * Add accessible attributes to modal containers\n * Begin listening to elements with [data-modal-button]\n */\n start() {\n this._modals = this.getElements(this._modalContainerAttr)\n this._modalButtons = this.getElements(`[${Selectors.DATA_MODAL_BUTTON}]`)\n\n this.getFocusableElements(this._modalContainerAttr).forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n\n if (this._modals.length) {\n this._modals.forEach(modal => {\n this._setupModal(modal)\n })\n }\n\n if (this._modalButtons.length) {\n this._modalButtons.forEach(button => {\n button.addEventListener(Events.CLICK, this._render)\n })\n }\n }\n\n /**\n * Stop listening to modal buttons\n */\n stop() {\n this._modalButtons.forEach(button => {\n button.removeEventListener(Events.CLICK, this._render)\n })\n }\n\n // private\n\n /**\n * Find a button through event.target, then render the corresponding modal attribute via matching target id\n * @param {Object} event - The event object\n */\n _render(event) {\n event.preventDefault()\n this._activeModalButton = event.target\n\n if (!this._activeModalButton.getAttribute(Selectors.DATA_TARGET)) {\n return console.error(Messages.NO_TARGET_ERROR)\n }\n\n this._activeModalId = this._activeModalButton.getAttribute(Selectors.DATA_TARGET)\n this._activeModalOverlayAttr = `[${Selectors.DATA_MODAL_ID}=\"${this._activeModalId}\"]`\n\n if (!document.querySelector(this._activeModalOverlayAttr)) {\n return console.error(Messages.NO_ID_ERROR(this._activeModalId))\n }\n\n this._activeModalOverlay = document.querySelector(this._activeModalOverlayAttr)\n\n this._activeModalSelector = `${this._activeModalOverlayAttr} ${this._modalContainerAttr}`\n this._activeModal = document.querySelector(this._activeModalSelector)\n this._activeModalCloseButtons = this.getElements(\n `${this._activeModalOverlayAttr} [${Selectors.DATA_CLOSE}]`,\n )\n\n this.getFocusableElements(this._activeModalSelector).forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"0\")\n })\n\n this._handleScrollStop()\n this.captureFocus(this._activeModalSelector)\n this._activeModalOverlay.setAttribute(Selectors.ARIA_HIDDEN, \"false\")\n this._activeModal.setAttribute(Selectors.TABINDEX, \"-1\")\n this._activeModalOverlay.setAttribute(Selectors.DATA_VISIBLE, \"true\")\n this._activeModal.focus()\n\n // offset slight scroll caused by this._activeModal.focus()\n this._activeModalOverlay.scrollTop = 0\n\n // begin listening to events\n document.addEventListener(Events.KEYDOWN, this._handleEscapeKeyPress)\n document.addEventListener(Events.CLICK, this._handleOverlayClick)\n this._activeModalCloseButtons.forEach(button => {\n button.addEventListener(Events.CLICK, this._handleClose)\n })\n }\n\n _setupModal(modal) {\n let modalId\n if (!modal.getAttribute(Selectors.DATA_PARENT)) {\n return console.error(Messages.NO_PARENT_ERROR)\n } else {\n modalId = modal.getAttribute(Selectors.DATA_PARENT)\n }\n\n let modalWrapper\n if (!document.querySelector(`[${Selectors.DATA_MODAL_ID}='${modalId}']`)) {\n return console.error(Messages.NO_ID_ERROR(modalId))\n } else {\n modalWrapper = document.querySelector(`[${Selectors.DATA_MODAL_ID}='${modalId}']`)\n }\n\n modalWrapper.setAttribute(Selectors.ARIA_HIDDEN, \"true\")\n modalWrapper.setAttribute(Selectors.DATA_VISIBLE, \"false\")\n modal.setAttribute(Selectors.ARIA_MODAL, \"true\")\n modal.setAttribute(Selectors.ROLE, \"dialog\")\n }\n\n /**\n * Turn off event listeners and reset focus to last selected DOM node (button)\n * @param {Object} event - Event (keydown or click)\n */\n _handleClose(event) {\n event.preventDefault()\n this._activeModalOverlay.setAttribute(Selectors.DATA_VISIBLE, \"false\")\n this._handleReturnFocus()\n this._handleScrollRestore()\n this.releaseFocus()\n this._activeModalOverlay.setAttribute(Selectors.ARIA_HIDDEN, \"true\")\n this._activeModal.removeAttribute(Selectors.TABINDEX)\n\n this.getFocusableElements(this._activeModalSelector).forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n\n // stop listening to events\n document.removeEventListener(Events.KEYDOWN, this._handleEscapeKeyPress)\n document.removeEventListener(Events.CLICK, this._handleOverlayClick)\n this._activeModalCloseButtons.forEach(button => {\n button.removeEventListener(Events.CLICK, this._handleClose)\n })\n }\n\n /**\n * Handles click event on the modal background to close it.\n * @param {Object} event - Event (keydown)\n */\n _handleOverlayClick(event) {\n if (event.target === this._activeModalOverlay) {\n this._handleClose(event)\n }\n }\n\n /**\n * Handles escape key event to close the current modal\n * @param {Object} event - Event (keydown)\n */\n _handleEscapeKeyPress(event) {\n if (event.which === KeyCodes.ESCAPE) {\n this._handleClose(event)\n }\n }\n\n /**\n * Returns focus to the last focused element before the modal was called.\n * @param {Object} button - The current modal's corresponding button.\n */\n _handleReturnFocus() {\n this._activeModalButton.setAttribute(Selectors.TABINDEX, \"-1\")\n this._activeModalButton.focus()\n this._activeModalButton.removeAttribute(Selectors.TABINDEX)\n }\n\n /**\n * Restores scroll behavior to and \n */\n _handleScrollRestore() {\n document.body.classList.remove(Selectors.NO_SCROLL)\n document.querySelector(\"html\").classList.remove(Selectors.NO_SCROLL)\n }\n\n /**\n * Prevents scroll behavior on and \n */\n _handleScrollStop() {\n document.body.classList.add(Selectors.NO_SCROLL)\n document.querySelector(\"html\").classList.add(Selectors.NO_SCROLL)\n }\n}\n","\"use strict\"\n\nimport Utils from \"../utils\"\n\nconst Selectors = {\n // unique\n DATA_ACCORDION: \"data-accordion\",\n DATA_ACCORDION_ROW: \"data-accordion-row\",\n // common\n DATA_VISIBLE: \"data-visible\",\n DATA_TARGET: \"data-target\",\n DATA_TOGGLE_MULTIPLE: \"data-toggle-multiple\",\n DATA_PARENT: \"data-parent\",\n // accessibility\n ARIA_EXPANDED: \"aria-expanded\",\n ARIA_CONTROLS: \"aria-controls\",\n ARIA_HIDDEN: \"aria-hidden\",\n ARIA_LABELLEDBY: \"aria-labelledby\",\n TABINDEX: \"tabindex\",\n}\n\nconst Events = {\n CLICK: \"click\",\n KEYDOWN: \"keydown\",\n}\n\nconst Messages = {\n NO_VISIBLE_ERROR: id =>\n `Could not find parent with [data-visible] attribute associated with [data-target='${id}'].`,\n NO_ROW_ERROR: id => `Could not find [data-accordion-row] associated with ${id}.`,\n NO_HEADER_ID_ERROR: id => `Could not find header tag associated with [data-target='${id}'].`,\n NO_PARENT_ERROR: id => `Could not find [data-parent] associated with [data-target='${id}'].`,\n NO_CONTENT_ERROR: id =>\n `Could not find accordion content block with [id] ${id} associated with [data-target='${id}'].`,\n}\n\n/**\n * Accordion component class.\n * @module Accordion\n * @requires Utils\n */\nexport default class Accordion extends Utils {\n constructor() {\n super()\n\n // events\n this._render = this._render.bind(this)\n\n // all accordions\n this._accordionButtons = []\n this._accordionContentsAttr = \"\"\n this._accordionContents = []\n\n // active accordion\n this._activeContainer = {}\n this._activeButton = {}\n this._activeAccordionRowId = \"\"\n this._activeRowAttr = \"\"\n this._activeRow = \"\"\n this._activeContainerId = \"\"\n this._activeContainerAttr = \"\"\n this._activeContent = {}\n this._activeButtonExpandState = \"\"\n this._activeContentHiddenState = \"\"\n\n // other data\n this._headerLevels = [1, 2, 3, 4, 5, 6]\n }\n\n // public\n\n /**\n * Sets up accordion components and listens to buttons for events.\n * Begin listening to [data-accordion-button] elements\n */\n start() {\n const accordionButtonSelector = this._getPossibleAccordionButtonAttrs(\n `[${Selectors.DATA_ACCORDION}]`,\n )\n this._accordionButtons = this.getElements(accordionButtonSelector)\n\n if (this._accordionButtons.length) {\n this._accordionButtons.forEach(button => {\n this._setupAccordion(button)\n button.addEventListener(Events.CLICK, this._render)\n })\n }\n }\n\n /**\n * Stop listening to accordion button events.\n */\n stop() {\n this._accordionButtons.forEach(button => {\n button.removeEventListener(Events.CLICK, this._render)\n })\n }\n\n // private\n\n /**\n * Add initial attributes to accordion elements.\n * @param {Element} button - A button element that triggers an accordion.\n */\n _setupAccordion(button) {\n const buttonId = button.getAttribute(Selectors.DATA_TARGET)\n\n if (!document.getElementById(buttonId)) {\n return console.error(Messages.NO_CONTENT_ERROR(buttonId))\n }\n\n const buttonContent = document.getElementById(buttonId)\n const accordionRowAttr = this._getAccordionRowAttr(buttonId)\n\n if (!document.querySelector(accordionRowAttr)) {\n return console.error(Messages.NO_ROW_ERROR(buttonId))\n }\n\n const accordionRow = document.querySelector(accordionRowAttr)\n const buttonHeaderAttr = this._getPossibleAccordionHeaderAttrs(accordionRowAttr)\n const buttonHeader = this.getElements(buttonHeaderAttr)[0]\n\n if (!buttonHeader || !buttonHeader.id) {\n console.error(Messages.NO_HEADER_ID_ERROR(buttonId))\n }\n\n const buttonContentChildren = this.getFocusableElements(`#${buttonContent.id}`)\n\n button.setAttribute(Selectors.ARIA_CONTROLS, buttonId)\n buttonContent.setAttribute(Selectors.ARIA_LABELLEDBY, buttonHeader.id)\n\n if (!accordionRow.getAttribute(Selectors.DATA_VISIBLE)) {\n return console.error(Messages.NO_VISIBLE_ERROR(buttonId))\n }\n\n const contentShouldExpand = accordionRow.getAttribute(Selectors.DATA_VISIBLE)\n if (contentShouldExpand === \"true\") {\n buttonContent.style.maxHeight = `${buttonContent.scrollHeight}px`\n button.setAttribute(Selectors.ARIA_EXPANDED, \"true\")\n buttonContent.setAttribute(Selectors.ARIA_HIDDEN, \"false\")\n buttonContentChildren.forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"0\")\n })\n } else {\n button.setAttribute(Selectors.ARIA_EXPANDED, \"false\")\n buttonContent.setAttribute(Selectors.ARIA_HIDDEN, \"true\")\n buttonContentChildren.forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n }\n }\n\n /**\n * Build a selector string to match possible accordion buttons\n * @param {String} attr - A unique attribute\n * @return {String} - String of possible button selectors\n */\n _getPossibleAccordionButtonAttrs(attr) {\n return this._headerLevels\n .map(\n num => `${attr} > [${Selectors.DATA_ACCORDION_ROW}] > h${num} [${Selectors.DATA_TARGET}]`,\n )\n .join(\", \")\n }\n\n /**\n * Build a selector string to match possible accordion headers\n * @param {String} attr - A unique attribute\n * @return {String} - String of possible header selectors\n */\n _getPossibleAccordionHeaderAttrs(attr) {\n return this._headerLevels.map(num => `${attr} > h${num}`).join(\", \")\n }\n\n /**\n * Build a unique accordion row attribute selector.\n * @param {String} id - An id value associated with a given Selectors.DATA_TARGET\n * @return {String} - A unique accordion row selector\n */\n _getAccordionRowAttr(id) {\n return `[${Selectors.DATA_ACCORDION_ROW}='${id}']`\n }\n\n /**\n * Open accordion content associated with an accordion button.\n * @param {Object} event - The event object\n */\n _render(event) {\n event.preventDefault()\n\n this._activeButton = event.target\n this._activeAccordionRowId = this._activeButton.getAttribute(Selectors.DATA_TARGET)\n\n this._activeRowAttr = this._getAccordionRowAttr(this._activeAccordionRowId)\n this._activeRow = document.querySelector(this._activeRowAttr)\n\n if (!this._activeButton.getAttribute(Selectors.DATA_PARENT)) {\n return console.error(Messages.NO_PARENT_ERROR(this._activeAccordionRowId))\n }\n\n this._activeContainerId = this._activeButton.getAttribute(Selectors.DATA_PARENT)\n this._activeContainerAttr = `[${Selectors.DATA_ACCORDION}='${this._activeContainerId}']`\n\n if (!document.querySelector(this._activeContainerAttr)) {\n return console.error(Messages.NO_ACCORDION_ERROR(this._activeContainerId))\n }\n\n this._activeContainer = document.querySelector(this._activeContainerAttr)\n this._activeContent = document.getElementById(this._activeAccordionRowId)\n\n const accordionButtonState = this._activeRow.getAttribute(Selectors.DATA_VISIBLE)\n\n this._activeButtonExpandState = accordionButtonState === \"true\" ? \"false\" : \"true\"\n this._activeContentHiddenState = this._activeButtonExpandState === \"false\" ? \"true\" : \"false\"\n\n this._closeAllIfToggleable()\n this._toggleSelectedAccordion()\n }\n\n /**\n * If toggling multiple rows at once isn't enabled, close all rows except the selected one.\n * This ensures the selected one can be closed if it's already open.\n */\n _closeAllIfToggleable() {\n if (this._activeContainer.hasAttribute(Selectors.DATA_TOGGLE_MULTIPLE)) return\n\n const allContentAttr = `${this._activeContainerAttr} [${Selectors.ARIA_HIDDEN}]`\n const allRows = this.getElements(`${this._activeContainerAttr} [${Selectors.DATA_VISIBLE}]`)\n const allContent = this.getElements(allContentAttr)\n\n const accordionButtonSelector = this._getPossibleAccordionButtonAttrs(this._activeContainerAttr)\n const allButtons = this.getElements(accordionButtonSelector)\n\n allContent.forEach(content => {\n if (content !== this._activeContent) content.style.maxHeight = null\n })\n\n this.getFocusableElements(allContentAttr).forEach(element => {\n element.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n\n this._toggleAttributeInCollection(allRows, Selectors.DATA_VISIBLE, \"true\", \"false\")\n this._toggleAttributeInCollection(allButtons, Selectors.ARIA_EXPANDED, \"true\", \"false\")\n this._toggleAttributeInCollection(allContent, Selectors.ARIA_HIDDEN, \"false\", \"true\")\n }\n\n /**\n * Toggle the currently selected accordion button's content.\n */\n _toggleSelectedAccordion() {\n this._activeRow.setAttribute(Selectors.DATA_VISIBLE, this._activeButtonExpandState)\n this._activeButton.setAttribute(Selectors.ARIA_EXPANDED, this._activeButtonExpandState)\n this._activeContent.setAttribute(Selectors.ARIA_HIDDEN, this._activeContentHiddenState)\n\n const activeContentBlock = `#${this._activeAccordionRowId}`\n this.getFocusableElements(activeContentBlock).forEach(element => {\n const value = this._activeButtonExpandState === \"true\" ? \"0\" : \"-1\"\n element.setAttribute(Selectors.TABINDEX, value)\n })\n\n if (this._activeContent.style.maxHeight) {\n this._activeContent.style.maxHeight = null\n } else {\n this._activeContent.style.maxHeight = `${this._activeContent.scrollHeight}px`\n }\n }\n\n /**\n * Toggles a single attribute of a series of elements.\n * @param {Array} elements - An array of elements to be operated on.\n * @param {String} attributeName - An attribute to be changed.\n * @param {String} currentValue - The current value of attributeName\n * @param {String} newValue - The new value of attributeName\n */\n _toggleAttributeInCollection(elements, attributeName, currentValue, newValue) {\n elements.forEach(element => {\n if (element.hasAttribute(attributeName, currentValue)) {\n element.setAttribute(attributeName, newValue)\n }\n })\n }\n}\n","\"use strict\"\n\nimport Utils from \"../utils\"\n\nconst KeyCodes = {\n TAB: 9,\n SHIFT: 16,\n ESCAPE: 27,\n ARROW_UP: 38,\n ARROW_DOWN: 40,\n}\n\nconst Selectors = {\n // unique\n DATA_DROPDOWN: \"data-dropdown\",\n // common\n DATA_TARGET: \"data-target\",\n DATA_PARENT: \"data-parent\",\n DATA_VISIBLE: \"data-visible\",\n // accessibility\n TABINDEX: \"tabindex\",\n ARIA_HASPOPUP: \"aria-haspopup\",\n ARIA_CONTROLS: \"aria-controls\",\n ARIA_LABELLEDBY: \"aria-labelledby\",\n ARIA_EXPANDED: \"aria-expanded\",\n ROLE: \"role\",\n}\n\nconst Events = {\n KEYDOWN: \"keydown\",\n CLICK: \"click\",\n}\n\nconst Messages = {\n NO_PARENT_ERROR: `Could not find dropdown button's [data-parent] attribute.`,\n NO_DROPDOWN_ERROR: attr => `Could not find dropdown container associated with ${attr}.`,\n NO_MENU_ERROR: attr => `Could not find menu associated with ${attr}.`,\n}\n\n/**\n * Dropdown component class.\n * @module Dropdown\n * @requires Utils\n */\nexport default class Dropdown extends Utils {\n constructor() {\n super()\n\n // events\n this._render = this._render.bind(this)\n this._handleFirstTabClose = this._handleFirstTabClose.bind(this)\n this._handleLastTabClose = this._handleLastTabClose.bind(this)\n this._renderWithKeys = this._renderWithKeys.bind(this)\n this._handleClose = this._handleClose.bind(this)\n this._handleEscapeKeyPress = this._handleEscapeKeyPress.bind(this)\n this._handleOffMenuClick = this._handleOffMenuClick.bind(this)\n\n // active dropdown\n this._activeDropdownButton = null\n this._activeDropdown = null\n this._activeDropdownMenu = null\n this._activeDropdownLinks = []\n this._allowFocusReturn = true\n this._activeDropdownId = \"\"\n this._activeDropdownAttr = \"\"\n this._activeDropdownMenuId = \"\"\n\n // all dropdowns\n this._dropdownButtons = []\n this._dropdowns = []\n\n // dropdown element selectors\n this._dropdownContainerAttr = `[${Selectors.DATA_DROPDOWN}]`\n this._dropdownTargetAttr = `[${Selectors.DATA_TARGET}]`\n }\n\n // public\n\n /**\n * Find and set up dropdown buttons and menus.\n * Begin listening to dropdowns for events.\n */\n start() {\n this._dropdowns = this.getElements(`${this._dropdownContainerAttr}`)\n this._dropdownButtons = this.getElements(\n `${this._dropdownContainerAttr} > ${this._dropdownTargetAttr}`,\n )\n\n if (this._dropdowns.length) {\n this._dropdowns.forEach(dropdown => this._setupDropdown(dropdown))\n }\n\n this._dropdownButtons.forEach(button => {\n button.addEventListener(Events.CLICK, this._render)\n button.addEventListener(Events.KEYDOWN, this._renderWithKeys)\n })\n }\n\n /**\n * Stop listening for dropdown events.\n */\n stop() {\n this._dropdownButtons.forEach(button => {\n button.removeEventListener(Events.CLICK, this._render)\n button.removeEventListener(Events.KEYDOWN, this._renderWithKeys)\n })\n }\n\n // private\n\n /**\n * Find a button through event.target, then render the corresponding modal attribute via matching target id\n * @param {Object} event - The event object\n * @param {Number} key - The key code that called _render()\n */\n _render(event, key) {\n if (!key) event.preventDefault()\n event.stopPropagation()\n\n if (this._activeDropdownButton) {\n this._allowFocusReturn = false\n this._handleClose(event)\n this._allowFocusReturn = true\n }\n\n // dropdown button / trigger\n this._activeDropdownButton = event.target\n\n if (!this._activeDropdownButton.getAttribute(Selectors.DATA_PARENT)) {\n return console.error(Messages.NO_PARENT_ERROR)\n }\n\n this._activeDropdownId = this._activeDropdownButton.getAttribute(Selectors.DATA_PARENT)\n\n // dropdown container\n this._activeDropdownAttr = `[${Selectors.DATA_DROPDOWN}=\"${this._activeDropdownId}\"]`\n\n if (!document.querySelector(this._activeDropdownAttr)) {\n return console.error(Messages.NO_DROPDOWN_ERROR(this._activeDropdownAttr))\n }\n\n this._activeDropdown = document.querySelector(this._activeDropdownAttr)\n\n // dropdown menu\n this._activeDropdownMenuId = this._activeDropdownButton.getAttribute(Selectors.DATA_TARGET)\n this._activeDropdownMenu = document.getElementById(this._activeDropdownMenuId)\n\n // dropdown button\n this._activeDropdownButton.setAttribute(Selectors.ARIA_EXPANDED, \"true\")\n this._activeDropdown.setAttribute(Selectors.DATA_VISIBLE, \"true\")\n\n // reset button event listener to close the menu, instead of open it\n this._activeDropdownButton.removeEventListener(Events.CLICK, this._render)\n this._activeDropdownButton.addEventListener(Events.CLICK, this._handleClose)\n\n document.addEventListener(Events.KEYDOWN, this._handleEscapeKeyPress)\n document.addEventListener(Events.CLICK, this._handleOffMenuClick)\n\n this._activeDropdownLinks = this._getDropdownLinks(this._activeDropdownAttr)\n\n this.firstDropdownLink = this._activeDropdownLinks[0]\n this.lastDropdownLink = this._activeDropdownLinks[this._activeDropdownLinks.length - 1]\n\n this.firstDropdownLink.addEventListener(Events.KEYDOWN, this._handleFirstTabClose)\n this.lastDropdownLink.addEventListener(Events.KEYDOWN, this._handleLastTabClose)\n\n if (key && key === KeyCodes.ARROW_UP) {\n this.lastDropdownLink.focus()\n } else {\n this.firstDropdownLink.focus()\n }\n\n this._activeDropdownLinks.forEach(link => {\n link.setAttribute(Selectors.TABINDEX, \"0\")\n link.addEventListener(Events.CLICK, this._handleClose)\n })\n\n this.captureFocus(`${this._activeDropdownAttr} > ul`, { useArrows: true })\n }\n\n /**\n * Closes the dropdown if user uses shift and tab keys on the first dropdown element.\n * @param {Object} event - The event object\n */\n _handleFirstTabClose(event) {\n const shiftKey = event.which === KeyCodes.SHIFT || event.shiftKey\n const tabKey = event.which === KeyCodes.TAB\n\n if (shiftKey && tabKey) {\n this._handleClose(event)\n }\n }\n\n /**\n * Closes the dropdown if user uses tab key on the last dropdown element.\n * @param {Object} event - The event object\n */\n _handleLastTabClose(event) {\n const shiftKey = event.which === KeyCodes.SHIFT || event.shiftKey\n const tabKey = event.which === KeyCodes.TAB\n\n if (tabKey && !shiftKey) {\n this._handleClose(event)\n }\n }\n\n /**\n * Renders dropdown if the user uses arrow up or down.\n * @param {Object} event - The event object\n */\n _renderWithKeys(event) {\n if (event.which === KeyCodes.ARROW_UP || event.which === KeyCodes.ARROW_DOWN) {\n this._render(event, event.which)\n }\n }\n\n /**\n * Closes currently open dropdown.\n * @param {Object} event - The event object\n */\n _handleClose(event) {\n event.preventDefault()\n\n this.releaseFocus()\n\n this._activeDropdownButton.setAttribute(Selectors.ARIA_EXPANDED, \"false\")\n this._activeDropdown.setAttribute(Selectors.DATA_VISIBLE, \"false\")\n\n this._activeDropdownLinks.forEach(link => {\n link.setAttribute(Selectors.TABINDEX, \"-1\")\n link.removeEventListener(Events.CLICK, this._handleClose)\n })\n\n this._activeDropdownButton.removeEventListener(Events.CLICK, this._handleClose)\n this._activeDropdownButton.addEventListener(Events.CLICK, this._render)\n\n document.removeEventListener(Events.KEYDOWN, this._handleEscapeKeyPress)\n document.removeEventListener(Events.CLICK, this._handleOffMenuClick)\n\n if (this._allowFocusReturn) {\n this._handleReturnFocus()\n }\n }\n\n /**\n * Use escape key to close dropdown.\n * @param {Object} event - The event object\n */\n _handleEscapeKeyPress(event) {\n if (event.which === KeyCodes.ESCAPE) {\n this._handleClose(event)\n }\n }\n\n /**\n * Closes dropdown\n * @param {Object} event - The event object\n */\n _handleOffMenuClick(event) {\n if (event.target !== this._activeDropdownButton && event.target !== this._activeDropdownMenu) {\n this._handleClose(event)\n }\n }\n\n /**\n * Puts focus on a the active dropdown button.\n */\n _handleReturnFocus() {\n this._activeDropdownButton.setAttribute(Selectors.TAB_INDEX, \"-1\")\n this._activeDropdownButton.focus()\n this._activeDropdownButton.removeAttribute(Selectors.TAB_INDEX)\n }\n\n /**\n * Retrieve possible menu links or buttons as an array\n * @param {String} attr - The unique attribute for a dropdown.\n * @return {String} - Selector for possible menu item links.\n */\n _getDropdownLinks(attr) {\n return this.getElements(`${attr} > ul > li > a, ${attr} > ul > li > button`)\n }\n\n /**\n * Add starting attributes to a dropdown.\n * @param {Element} dropdown - A dropdown element.\n */\n _setupDropdown(dropdown) {\n const dropdownId = dropdown.getAttribute(Selectors.DATA_DROPDOWN)\n const dropdownIdAttr = `[${Selectors.DATA_DROPDOWN}=\"${dropdownId}\"]`\n const dropdownMenuItemsAttr = `${dropdownIdAttr} > ul > li`\n\n if (!document.querySelector(`${dropdownIdAttr} > ul`)) {\n return console.error(Messages.NO_MENU_ERROR(dropdownIdAttr))\n }\n\n const dropdownMenu = document.querySelector(`${dropdownIdAttr} > ul`)\n const dropdownButton = document.querySelector(`${dropdownIdAttr} > ${this._dropdownTargetAttr}`)\n\n dropdownButton.setAttribute(Selectors.ARIA_CONTROLS, dropdownMenu.id)\n dropdownButton.setAttribute(Selectors.ARIA_HASPOPUP, \"true\")\n dropdownButton.setAttribute(Selectors.ARIA_EXPANDED, \"false\")\n dropdownMenu.setAttribute(Selectors.ARIA_LABELLEDBY, dropdownButton.id)\n\n const dropdownMenuItems = this.getElements(dropdownMenuItemsAttr)\n dropdownMenuItems.forEach(item => item.setAttribute(Selectors.ROLE, \"none\"))\n\n this._getDropdownLinks(dropdownIdAttr).forEach(link => {\n link.setAttribute(Selectors.ROLE, \"menuitem\")\n link.setAttribute(Selectors.TABINDEX, \"-1\")\n })\n }\n}\n","\"use strict\"\n\nimport _Modals from \"./components/modal\"\nimport _Accordion from \"./components/accordion\"\nimport _Dropdown from \"./components/dropdown\"\nimport _Utils from \"./utils\"\n\nexport const Modals = new _Modals()\nexport const Accordions = new _Accordion()\nexport const Dropdowns = new _Dropdown()\nexport const Utils = new _Utils()\n\nconst Undernet = {\n // Components\n Modals,\n Accordions,\n Dropdowns,\n\n // Utils\n Utils,\n}\n\nUndernet.start = () => {\n // Components\n Undernet.Modals.start()\n Undernet.Accordions.start()\n Undernet.Dropdowns.start()\n\n // Utils\n Undernet.Utils.enableFocusOutline()\n}\n\nUndernet.stop = () => {\n // Components\n Undernet.Modals.stop()\n Undernet.Accordions.stop()\n Undernet.Dropdowns.stop()\n\n // Utils\n Undernet.Utils.disableFocusOutline()\n}\n\nexport default Undernet\n","import Undernet from \"./index\"\n\nexport default Undernet\nexport { Modals, Accordions, Dropdowns, Utils } from \"./index\"\n\nwindow.Undernet = Undernet\n"],"names":["KeyCodes","Selectors","NOT_VISUALLY_HIDDEN","FOCUSABLE_TAGS","KEYBOARD_CLASS","Events","Utils","_listenForKeyboard","this","bind","_listenForClick","_handleFocusTrapWithTab","_handleFocusTrapWithArrows","_focusContainerSelector","_focusableChildren","_focusableFirstChild","_focusableLastChild","_listeningForKeydown","_trapFocusWithArrows","container","options","getFocusableElements","length","useArrows","document","addEventListener","removeEventListener","element","nodeList","querySelectorAll","Array","apply","focusables","map","join","getElements","event","tabKey","which","shiftKey","arrowUp","arrowDown","body","classList","add","remove","containerElement","querySelector","containerActive","activeElement","firstActive","lastActive","preventDefault","focus","_focusNextChild","_focusLastChild","i","Messages","id","Modal","_render","_this","_handleClose","_handleOverlayClick","_handleEscapeKeyPress","_modals","_modalButtons","_activeModalButton","_activeModalOverlay","_activeModal","_activeModalId","_activeModalOverlayAttr","_activeModalSelector","_activeModalCloseButtons","_modalContainerAttr","forEach","setAttribute","modal","_this2","_setupModal","button","_this3","target","getAttribute","_handleScrollStop","captureFocus","scrollTop","_this4","console","error","modalId","modalWrapper","_handleReturnFocus","_handleScrollRestore","releaseFocus","removeAttribute","_this5","NO_VISIBLE_ERROR","NO_ROW_ERROR","NO_HEADER_ID_ERROR","NO_PARENT_ERROR","NO_CONTENT_ERROR","Accordion","_accordionButtons","_accordionContentsAttr","_accordionContents","_activeContainer","_activeButton","_activeAccordionRowId","_activeRowAttr","_activeRow","_activeContainerId","_activeContainerAttr","_activeContent","_activeButtonExpandState","_activeContentHiddenState","_headerLevels","accordionButtonSelector","_getPossibleAccordionButtonAttrs","_setupAccordion","buttonId","getElementById","buttonContent","accordionRowAttr","_getAccordionRowAttr","accordionRow","buttonHeaderAttr","_getPossibleAccordionHeaderAttrs","buttonHeader","buttonContentChildren","style","maxHeight","scrollHeight","attr","num","NO_ACCORDION_ERROR","accordionButtonState","_closeAllIfToggleable","_toggleSelectedAccordion","hasAttribute","allContentAttr","allRows","allContent","allButtons","content","_toggleAttributeInCollection","activeContentBlock","value","elements","attributeName","currentValue","newValue","DATA_DROPDOWN","DATA_TARGET","DATA_PARENT","DATA_VISIBLE","TABINDEX","ARIA_HASPOPUP","ARIA_CONTROLS","ARIA_LABELLEDBY","ARIA_EXPANDED","ROLE","Dropdown","_handleFirstTabClose","_handleLastTabClose","_renderWithKeys","_handleOffMenuClick","_activeDropdownButton","_activeDropdown","_activeDropdownMenu","_activeDropdownLinks","_allowFocusReturn","_activeDropdownId","_activeDropdownAttr","_activeDropdownMenuId","_dropdownButtons","_dropdowns","_dropdownContainerAttr","_dropdownTargetAttr","dropdown","_setupDropdown","key","stopPropagation","_getDropdownLinks","firstDropdownLink","lastDropdownLink","link","TAB_INDEX","dropdownId","dropdownIdAttr","dropdownMenuItemsAttr","dropdownMenu","dropdownButton","item","Modals","_Modals","Accordions","_Accordion","Dropdowns","_Dropdown","_Utils","Undernet","start","enableFocusOutline","stop","disableFocusOutline","window"],"mappings":";;;;;woCAEA,IAAMA,EACG,GADHA,EAEC,EAFDA,EAGM,GAHNA,EAIQ,GAGRC,EAAY,CAChBC,oBAAqB,4BACrBC,eAAgB,CAAC,IAAK,SAAU,QAAS,SAAU,SAAU,WAAY,cACzEC,eAAgB,kBAGZC,EACK,UADLA,EAEG,QAOYC,yCAGZC,mBAAqBC,KAAKD,mBAAmBE,KAAKD,WAClDE,gBAAkBF,KAAKE,gBAAgBD,KAAKD,WAC5CG,wBAA0BH,KAAKG,wBAAwBF,KAAKD,WAC5DI,2BAA6BJ,KAAKI,2BAA2BH,KAAKD,WAElEK,wBAA0B,QAC1BC,mBAAqB,QACrBC,qBAAuB,QACvBC,oBAAsB,QACtBC,sBAAuB,OACvBC,sBAAuB,iDAUjBC,EAAWC,QACjBP,wBAA0BM,OAC1BL,mBAAqBN,KAAKa,qBAAqBb,KAAKK,8BACpDE,qBAAuBP,KAAKM,mBAAmB,QAC/CE,oBAAsBR,KAAKM,mBAAmBN,KAAKM,mBAAmBQ,OAAS,GAEhFF,EACEA,EAAQG,iBACLL,qBAAuBE,EAAQG,WAAaf,KAAKU,qBACtDM,SAASC,iBAAiBpB,EAAgBG,KAAKI,6BAGjDY,SAASC,iBAAiBpB,EAAgBG,KAAKG,gEAQ7CH,KAAKU,sBACPM,SAASE,oBAAoBrB,EAAgBG,KAAKI,iCAC7CM,sBAAuB,GAE5BM,SAASE,oBAAoBrB,EAAgBG,KAAKG,sEAQpDa,SAASC,iBAAiBpB,EAAgBG,KAAKD,kEAO3CC,KAAKS,qBACPO,SAASE,oBAAoBrB,EAAgBG,KAAKD,oBAElDiB,SAASE,oBAAoBrB,EAAcG,KAAKE,qDAUxCiB,OACJC,EAAWJ,SAASK,iBAAiBF,UACpCG,MAAMC,MAAM,KAAMH,gDAQNT,OACba,EAAa/B,EAAUE,eAAe8B,IAC1C,SAAAN,mBAAcR,cAAaQ,UAAU1B,EAAUC,uBAC/CgC,KAAK,aAEA1B,KAAK2B,YAAYH,8CAWPI,OACXC,EAASD,EAAME,QAAUtC,EACzBuC,EAAWH,EAAME,QAAUtC,GAAkBoC,EAAMG,SACnDC,EAAUJ,EAAME,QAAUtC,EAC1ByC,EAAYL,EAAME,QAAUtC,GAE9BqC,GAAUE,GAAYC,GAAWC,KACnCjB,SAASkB,KAAKC,UAAUC,IAAI3C,EAAUG,gBACtCoB,SAASE,oBAAoBrB,EAAgBG,KAAKD,oBAClDiB,SAASC,iBAAiBpB,EAAcG,KAAKE,sBACxCO,sBAAuB,2CAQhBmB,GACdZ,SAASkB,KAAKC,UAAUE,OAAO5C,EAAUG,gBACzCoB,SAASE,oBAAoBrB,EAAcG,KAAKE,iBAChDc,SAASC,iBAAiBpB,EAAgBG,KAAKD,yBAC1CU,sBAAuB,kDAONmB,OAChBU,EAAmBtB,SAASuB,cAAcvC,KAAKK,yBAC/CmC,EAAkBxB,SAASyB,gBAAkBH,EAC7CI,EAAc1B,SAASyB,gBAAkBzC,KAAKO,qBAC9CoC,EAAa3B,SAASyB,gBAAkBzC,KAAKQ,oBAC7CqB,EAASD,EAAME,QAAUtC,EACzBuC,EAAWH,EAAME,QAAUtC,GAAkBoC,EAAMG,SAIrDA,GAAYF,IAAWa,GAAeF,IACxCZ,EAAMgB,sBACDpC,oBAAoBqC,UACfd,GAAYF,GAAUc,IAChCf,EAAMgB,sBACDrC,qBAAqBsC,4DAQHjB,OACnBc,EAAc1B,SAASyB,gBAAkBzC,KAAKO,qBAC9CoC,EAAa3B,SAASyB,gBAAkBzC,KAAKQ,oBAC7CwB,EAAUJ,EAAME,QAAUtC,EAC1ByC,EAAYL,EAAME,QAAUtC,GAE9BwC,GAAWC,KACbL,EAAMgB,iBAEFF,GAAeV,OACZxB,oBAAoBqC,QAChBF,GAAcV,OAClB1B,qBAAqBsC,QACjBZ,OACJa,kBACId,QACJe,iEASJ,IAAIC,EAAI,EAAGA,EAAIhD,KAAKM,mBAAmBQ,OAAQkC,OAC9ChD,KAAKM,mBAAmB0C,KAAOhC,SAASyB,cAAe,MACpDnC,mBAAmB0C,EAAI,GAAGH,6DAU9B,IAAIG,EAAI,EAAGA,EAAIhD,KAAKM,mBAAmBQ,OAAQkC,OAC9ChD,KAAKM,mBAAmB0C,KAAOhC,SAASyB,cAAe,MACpDnC,mBAAmB0C,EAAI,GAAGH,wBCpNjCrD,EACI,GAGJC,EAEQ,aAFRA,EAGW,gBAHXA,EAIe,oBAJfA,EAMU,eANVA,EAOQ,aAPRA,EAQS,cARTA,EASS,cATTA,EAWS,cAXTA,EAYQ,aAZRA,EAaE,OAbFA,EAcM,WAdNA,EAgBO,YAGPI,EACK,UADLA,EAEG,QAIHoD,0FAAAA,mFAAAA,EAGS,SAAAC,kDACuBA,iDAQjBC,8EAKZC,QAAUC,EAAKD,QAAQnD,gBACvBqD,aAAeD,EAAKC,aAAarD,gBACjCsD,oBAAsBF,EAAKE,oBAAoBtD,gBAC/CuD,sBAAwBH,EAAKG,sBAAsBvD,gBAGnDwD,QAAU,KACVC,cAAgB,KAGhBC,mBAAqB,KACrBC,oBAAsB,KACtBC,aAAe,KACfC,eAAiB,KACjBC,wBAA0B,KAC1BC,qBAAuB,KACvBC,yBAA2B,KAG3BC,+BAA0BzE,oBAxBAK,sDAkC1B2D,QAAUzD,KAAK2B,YAAY3B,KAAKkE,0BAChCR,cAAgB1D,KAAK2B,uBAAgBlC,aAErCoB,qBAAqBb,KAAKkE,qBAAqBC,QAAQ,SAAAhD,GAC1DA,EAAQiD,aAAa3E,EAAoB,QAGvCO,KAAKyD,QAAQ3C,aACV2C,QAAQU,QAAQ,SAAAE,GACnBC,EAAKC,YAAYF,KAIjBrE,KAAK0D,cAAc5C,aAChB4C,cAAcS,QAAQ,SAAAK,GACzBA,EAAOvD,iBAAiBpB,EAAcyE,EAAKlB,0DAS1CM,cAAcS,QAAQ,SAAAK,GACzBA,EAAOtD,oBAAoBrB,EAAc4E,EAAKrB,2CAU1CxB,qBACNA,EAAMgB,sBACDe,mBAAqB/B,EAAM8C,OAE3B1E,KAAK2D,mBAAmBgB,aAAalF,SAIrCqE,eAAiB9D,KAAK2D,mBAAmBgB,aAAalF,QACtDsE,mCAA8BtE,eAA4BO,KAAK8D,qBAE/D9C,SAASuB,cAAcvC,KAAK+D,+BAI5BH,oBAAsB5C,SAASuB,cAAcvC,KAAK+D,8BAElDC,+BAA0BhE,KAAK+D,oCAA2B/D,KAAKkE,0BAC/DL,aAAe7C,SAASuB,cAAcvC,KAAKgE,2BAC3CC,yBAA2BjE,KAAK2B,sBAChC3B,KAAK+D,qCAA4BtE,aAGjCoB,qBAAqBb,KAAKgE,sBAAsBG,QAAQ,SAAAhD,GAC3DA,EAAQiD,aAAa3E,EAAoB,YAGtCmF,yBACAC,aAAa7E,KAAKgE,2BAClBJ,oBAAoBQ,aAAa3E,EAAuB,cACxDoE,aAAaO,aAAa3E,EAAoB,WAC9CmE,oBAAoBQ,aAAa3E,EAAwB,aACzDoE,aAAahB,aAGbe,oBAAoBkB,UAAY,EAGrC9D,SAASC,iBAAiBpB,EAAgBG,KAAKwD,uBAC/CxC,SAASC,iBAAiBpB,EAAcG,KAAKuD,+BACxCU,yBAAyBE,QAAQ,SAAAK,GACpCA,EAAOvD,iBAAiBpB,EAAckF,EAAKzB,iBA7BpC0B,QAAQC,MAAMhC,EAAqBjD,KAAK8D,kBAPxCkB,QAAQC,MAAMhC,uCAwCboB,OACNa,EAOAC,SANCd,EAAMM,aAAalF,IAGtByF,EAAUb,EAAMM,aAAalF,GAI1BuB,SAASuB,yBAAkB9C,eAA4ByF,WAG1DC,EAAenE,SAASuB,yBAAkB9C,eAA4ByF,UAG3Dd,aAAa3E,EAAuB,QACjD0F,EAAaf,aAAa3E,EAAwB,SAClD4E,EAAMD,aAAa3E,EAAsB,aACzC4E,EAAMD,aAAa3E,EAAgB,WAR1BuF,QAAQC,MAAMhC,EAAqBiC,KAPnCF,QAAQC,MAAMhC,wCAsBZrB,cACXA,EAAMgB,sBACDgB,oBAAoBQ,aAAa3E,EAAwB,cACzD2F,0BACAC,4BACAC,oBACA1B,oBAAoBQ,aAAa3E,EAAuB,aACxDoE,aAAa0B,gBAAgB9F,QAE7BoB,qBAAqBb,KAAKgE,sBAAsBG,QAAQ,SAAAhD,GAC3DA,EAAQiD,aAAa3E,EAAoB,QAI3CuB,SAASE,oBAAoBrB,EAAgBG,KAAKwD,uBAClDxC,SAASE,oBAAoBrB,EAAcG,KAAKuD,0BAC3CU,yBAAyBE,QAAQ,SAAAK,GACpCA,EAAOtD,oBAAoBrB,EAAc2F,EAAKlC,4DAQ9B1B,GACdA,EAAM8C,SAAW1E,KAAK4D,0BACnBN,aAAa1B,iDAQAA,GAChBA,EAAME,QAAUtC,QACb8D,aAAa1B,qDASf+B,mBAAmBS,aAAa3E,EAAoB,WACpDkE,mBAAmBd,aACnBc,mBAAmB4B,gBAAgB9F,kDAOxCuB,SAASkB,KAAKC,UAAUE,OAAO5C,GAC/BuB,SAASuB,cAAc,QAAQJ,UAAUE,OAAO5C,+CAOhDuB,SAASkB,KAAKC,UAAUC,IAAI3C,GAC5BuB,SAASuB,cAAc,QAAQJ,UAAUC,IAAI3C,YCpP3CA,EAEY,iBAFZA,EAGgB,qBAHhBA,EAKU,eALVA,EAMS,cANTA,EAOkB,uBAPlBA,EAQS,cARTA,EAUW,gBAVXA,EAWW,gBAXXA,EAYS,cAZTA,EAaa,kBAbbA,EAcM,WAGNI,EACG,QAIHoD,EAAW,CACfwC,iBAAkB,SAAAvC,qGACqEA,UACvFwC,aAAc,SAAAxC,uEAA6DA,QAC3EyC,mBAAoB,SAAAzC,2EAAiEA,UACrF0C,gBAAiB,SAAA1C,8EAAoEA,UACrF2C,iBAAkB,SAAA3C,oEACoCA,4CAAoCA,WAQvE4C,8EAKZ1C,QAAUC,EAAKD,QAAQnD,gBAGvB8F,kBAAoB,KACpBC,uBAAyB,KACzBC,mBAAqB,KAGrBC,iBAAmB,KACnBC,cAAgB,KAChBC,sBAAwB,KACxBC,eAAiB,KACjBC,WAAa,KACbC,mBAAqB,KACrBC,qBAAuB,KACvBC,eAAiB,KACjBC,yBAA2B,KAC3BC,0BAA4B,KAG5BC,cAAgB,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,gBAzBF9G,iDAmC7B+G,EAA0B7G,KAAK8G,4CAC/BrH,aAEDsG,kBAAoB/F,KAAK2B,YAAYkF,GAEtC7G,KAAK+F,kBAAkBjF,aACpBiF,kBAAkB5B,QAAQ,SAAAK,GAC7BF,EAAKyC,gBAAgBvC,GACrBA,EAAOvD,iBAAiBpB,EAAcyE,EAAKlB,0DAS1C2C,kBAAkB5B,QAAQ,SAAAK,GAC7BA,EAAOtD,oBAAoBrB,EAAc4E,EAAKrB,mDAUlCoB,OACRwC,EAAWxC,EAAOG,aAAalF,OAEhCuB,SAASiG,eAAeD,UACpBhC,QAAQC,MAAMhC,EAAS4C,iBAAiBmB,QAG3CE,EAAgBlG,SAASiG,eAAeD,GACxCG,EAAmBnH,KAAKoH,qBAAqBJ,OAE9ChG,SAASuB,cAAc4E,UACnBnC,QAAQC,MAAMhC,EAASyC,aAAasB,QAGvCK,EAAerG,SAASuB,cAAc4E,GACtCG,EAAmBtH,KAAKuH,iCAAiCJ,GACzDK,EAAexH,KAAK2B,YAAY2F,GAAkB,GAEnDE,GAAiBA,EAAatE,IACjC8B,QAAQC,MAAMhC,EAAS0C,mBAAmBqB,QAGtCS,EAAwBzH,KAAKa,gCAAyBqG,EAAchE,QAE1EsB,EAAOJ,aAAa3E,EAAyBuH,GAC7CE,EAAc9C,aAAa3E,EAA2B+H,EAAatE,KAE9DmE,EAAa1C,aAAalF,UACtBuF,QAAQC,MAAMhC,EAASwC,iBAAiBuB,IAIrB,SADAK,EAAa1C,aAAalF,IAEpDyH,EAAcQ,MAAMC,oBAAeT,EAAcU,mBACjDpD,EAAOJ,aAAa3E,EAAyB,QAC7CyH,EAAc9C,aAAa3E,EAAuB,SAClDgI,EAAsBtD,QAAQ,SAAAhD,GAC5BA,EAAQiD,aAAa3E,EAAoB,SAG3C+E,EAAOJ,aAAa3E,EAAyB,SAC7CyH,EAAc9C,aAAa3E,EAAuB,QAClDgI,EAAsBtD,QAAQ,SAAAhD,GAC5BA,EAAQiD,aAAa3E,EAAoB,kEAUdoI,UACxB7H,KAAK4G,cACTnF,IACC,SAAAqG,mBAAUD,iBAAWpI,kBAAoCqI,eAAQrI,SAElEiC,KAAK,+DAQuBmG,UACxB7H,KAAK4G,cAAcnF,IAAI,SAAAqG,mBAAUD,iBAAWC,KAAOpG,KAAK,mDAQ5CwB,oBACRzD,eAAiCyD,wCAOtCtB,MACNA,EAAMgB,sBAEDuD,cAAgBvE,EAAM8C,YACtB0B,sBAAwBpG,KAAKmG,cAAcxB,aAAalF,QAExD4G,eAAiBrG,KAAKoH,qBAAqBpH,KAAKoG,4BAChDE,WAAatF,SAASuB,cAAcvC,KAAKqG,iBAEzCrG,KAAKmG,cAAcxB,aAAalF,UAC5BuF,QAAQC,MAAMhC,EAAS2C,gBAAgB5F,KAAKoG,gCAGhDG,mBAAqBvG,KAAKmG,cAAcxB,aAAalF,QACrD+G,gCAA2B/G,eAA6BO,KAAKuG,0BAE7DvF,SAASuB,cAAcvC,KAAKwG,6BACxBxB,QAAQC,MAAMhC,EAAS8E,mBAAmB/H,KAAKuG,0BAGnDL,iBAAmBlF,SAASuB,cAAcvC,KAAKwG,2BAC/CC,eAAiBzF,SAASiG,eAAejH,KAAKoG,2BAE7C4B,EAAuBhI,KAAKsG,WAAW3B,aAAalF,QAErDiH,yBAAoD,SAAzBsB,EAAkC,QAAU,YACvErB,0BAA8D,UAAlC3G,KAAK0G,yBAAuC,OAAS,aAEjFuB,6BACAC,0FAQDlI,KAAKkG,iBAAiBiC,aAAa1I,QAEjC2I,YAAoBpI,KAAKwG,kCAAyB/G,OAClD4I,EAAUrI,KAAK2B,sBAAe3B,KAAKwG,kCAAyB/G,QAC5D6I,EAAatI,KAAK2B,YAAYyG,GAE9BvB,EAA0B7G,KAAK8G,iCAAiC9G,KAAKwG,sBACrE+B,EAAavI,KAAK2B,YAAYkF,GAEpCyB,EAAWnE,QAAQ,SAAAqE,GACbA,IAAYzD,EAAK0B,iBAAgB+B,EAAQd,MAAMC,UAAY,aAG5D9G,qBAAqBuH,GAAgBjE,QAAQ,SAAAhD,GAChDA,EAAQiD,aAAa3E,EAAoB,aAGtCgJ,6BAA6BJ,EAAS5I,EAAwB,OAAQ,cACtEgJ,6BAA6BF,EAAY9I,EAAyB,OAAQ,cAC1EgJ,6BAA6BH,EAAY7I,EAAuB,QAAS,4EAOzE6G,WAAWlC,aAAa3E,EAAwBO,KAAK0G,+BACrDP,cAAc/B,aAAa3E,EAAyBO,KAAK0G,+BACzDD,eAAerC,aAAa3E,EAAuBO,KAAK2G,+BAEvD+B,aAAyB1I,KAAKoG,4BAC/BvF,qBAAqB6H,GAAoBvE,QAAQ,SAAAhD,OAC9CwH,EAA0C,SAAlCnD,EAAKkB,yBAAsC,IAAM,KAC/DvF,EAAQiD,aAAa3E,EAAoBkJ,KAGvC3I,KAAKyG,eAAeiB,MAAMC,eACvBlB,eAAeiB,MAAMC,UAAY,UAEjClB,eAAeiB,MAAMC,oBAAe3H,KAAKyG,eAAemB,wEAWpCgB,EAAUC,EAAeC,EAAcC,GAClEH,EAASzE,QAAQ,SAAAhD,GACXA,EAAQgH,aAAaU,EAAeC,IACtC3H,EAAQiD,aAAayE,EAAeE,cCjRtCvJ,EACC,EADDA,EAEG,GAFHA,EAGI,GAHJA,EAIM,GAJNA,GAKQ,GAGRC,GAAY,CAEhBuJ,cAAe,gBAEfC,YAAa,cACbC,YAAa,cACbC,aAAc,eAEdC,SAAU,WACVC,cAAe,gBACfC,cAAe,gBACfC,gBAAiB,kBACjBC,cAAe,gBACfC,KAAM,QAGF5J,GACK,UADLA,GAEG,QAGHoD,+DAAAA,GAEe,SAAA4E,qEAA6DA,QAF5E5E,GAGW,SAAA4E,uDAA+CA,QAQ3C6B,+EAKZtG,QAAUC,EAAKD,QAAQnD,gBACvB0J,qBAAuBtG,EAAKsG,qBAAqB1J,gBACjD2J,oBAAsBvG,EAAKuG,oBAAoB3J,gBAC/C4J,gBAAkBxG,EAAKwG,gBAAgB5J,gBACvCqD,aAAeD,EAAKC,aAAarD,gBACjCuD,sBAAwBH,EAAKG,sBAAsBvD,gBACnD6J,oBAAsBzG,EAAKyG,oBAAoB7J,gBAG/C8J,sBAAwB,OACxBC,gBAAkB,OAClBC,oBAAsB,OACtBC,qBAAuB,KACvBC,mBAAoB,IACpBC,kBAAoB,KACpBC,oBAAsB,KACtBC,sBAAwB,KAGxBC,iBAAmB,KACnBC,WAAa,KAGbC,kCAA6BhL,GAAUuJ,qBACvC0B,+BAA0BjL,GAAUwJ,8BA7BPnJ,sDAuC7B0K,WAAaxK,KAAK2B,sBAAe3B,KAAKyK,8BACtCF,iBAAmBvK,KAAK2B,sBACxB3B,KAAKyK,qCAA4BzK,KAAK0K,sBAGvC1K,KAAKwK,WAAW1J,aACb0J,WAAWrG,QAAQ,SAAAwG,UAAYrG,EAAKsG,eAAeD,UAGrDJ,iBAAiBpG,QAAQ,SAAAK,GAC5BA,EAAOvD,iBAAiBpB,GAAcyE,EAAKlB,SAC3CoB,EAAOvD,iBAAiBpB,GAAgByE,EAAKuF,kEAQ1CU,iBAAiBpG,QAAQ,SAAAK,GAC5BA,EAAOtD,oBAAoBrB,GAAc4E,EAAKrB,SAC9CoB,EAAOtD,oBAAoBrB,GAAgB4E,EAAKoF,mDAW5CjI,EAAOiJ,qBACRA,GAAKjJ,EAAMgB,iBAChBhB,EAAMkJ,kBAEF9K,KAAK+J,6BACFI,mBAAoB,OACpB7G,aAAa1B,QACbuI,mBAAoB,QAItBJ,sBAAwBnI,EAAM8C,OAE9B1E,KAAK+J,sBAAsBpF,aAAalF,GAAUyJ,mBAIlDkB,kBAAoBpK,KAAK+J,sBAAsBpF,aAAalF,GAAUyJ,kBAGtEmB,+BAA0B5K,GAAUuJ,2BAAkBhJ,KAAKoK,wBAE3DpJ,SAASuB,cAAcvC,KAAKqK,2BAI5BL,gBAAkBhJ,SAASuB,cAAcvC,KAAKqK,0BAG9CC,sBAAwBtK,KAAK+J,sBAAsBpF,aAAalF,GAAUwJ,kBAC1EgB,oBAAsBjJ,SAASiG,eAAejH,KAAKsK,4BAGnDP,sBAAsB3F,aAAa3E,GAAU+J,cAAe,aAC5DQ,gBAAgB5F,aAAa3E,GAAU0J,aAAc,aAGrDY,sBAAsB7I,oBAAoBrB,GAAcG,KAAKoD,cAC7D2G,sBAAsB9I,iBAAiBpB,GAAcG,KAAKsD,cAE/DtC,SAASC,iBAAiBpB,GAAgBG,KAAKwD,uBAC/CxC,SAASC,iBAAiBpB,GAAcG,KAAK8J,0BAExCI,qBAAuBlK,KAAK+K,kBAAkB/K,KAAKqK,0BAEnDW,kBAAoBhL,KAAKkK,qBAAqB,QAC9Ce,iBAAmBjL,KAAKkK,qBAAqBlK,KAAKkK,qBAAqBpJ,OAAS,QAEhFkK,kBAAkB/J,iBAAiBpB,GAAgBG,KAAK2J,2BACxDsB,iBAAiBhK,iBAAiBpB,GAAgBG,KAAK4J,qBAExDiB,GAAOA,IAAQrL,OACZyL,iBAAiBpI,aAEjBmI,kBAAkBnI,aAGpBqH,qBAAqB/F,QAAQ,SAAA+G,GAChCA,EAAK9G,aAAa3E,GAAU2J,SAAU,KACtC8B,EAAKjK,iBAAiBpB,GAAckF,EAAKzB,0BAGtCuB,uBAAgB7E,KAAKqK,6BAA4B,CAAEtJ,WAAW,KAvC1DiE,QAAQC,MAAMhC,GAA2BjD,KAAKqK,uBAT9CrF,QAAQC,MAAMhC,iDAuDJrB,OACbG,EAAWH,EAAME,QAAUtC,GAAkBoC,EAAMG,SACnDF,EAASD,EAAME,QAAUtC,EAE3BuC,GAAYF,QACTyB,aAAa1B,+CAQFA,OACZG,EAAWH,EAAME,QAAUtC,GAAkBoC,EAAMG,SAC1CH,EAAME,QAAUtC,IAEhBuC,QACRuB,aAAa1B,2CAQNA,GACVA,EAAME,QAAUtC,GAAqBoC,EAAME,QAAUtC,SAClD4D,QAAQxB,EAAOA,EAAME,4CAQjBF,cACXA,EAAMgB,sBAED0C,oBAEAyE,sBAAsB3F,aAAa3E,GAAU+J,cAAe,cAC5DQ,gBAAgB5F,aAAa3E,GAAU0J,aAAc,cAErDe,qBAAqB/F,QAAQ,SAAA+G,GAChCA,EAAK9G,aAAa3E,GAAU2J,SAAU,MACtC8B,EAAKhK,oBAAoBrB,GAAc2F,EAAKlC,qBAGzCyG,sBAAsB7I,oBAAoBrB,GAAcG,KAAKsD,mBAC7DyG,sBAAsB9I,iBAAiBpB,GAAcG,KAAKoD,SAE/DpC,SAASE,oBAAoBrB,GAAgBG,KAAKwD,uBAClDxC,SAASE,oBAAoBrB,GAAcG,KAAK8J,qBAE5C9J,KAAKmK,wBACF/E,mEAQaxD,GAChBA,EAAME,QAAUtC,QACb8D,aAAa1B,+CAQFA,GACdA,EAAM8C,SAAW1E,KAAK+J,uBAAyBnI,EAAM8C,SAAW1E,KAAKiK,0BAClE3G,aAAa1B,qDAQfmI,sBAAsB3F,aAAa3E,GAAU0L,UAAW,WACxDpB,sBAAsBlH,aACtBkH,sBAAsBxE,gBAAgB9F,GAAU0L,qDAQrCtD,UACT7H,KAAK2B,sBAAekG,6BAAuBA,iEAOrC8C,OACPS,EAAaT,EAAShG,aAAalF,GAAUuJ,eAC7CqC,aAAqB5L,GAAUuJ,2BAAkBoC,QACjDE,YAA2BD,oBAE5BrK,SAASuB,wBAAiB8I,mBACtBrG,QAAQC,MAAMhC,GAAuBoI,QAGxCE,EAAevK,SAASuB,wBAAiB8I,YACzCG,EAAiBxK,SAASuB,wBAAiB8I,gBAAoBrL,KAAK0K,sBAE1Ec,EAAepH,aAAa3E,GAAU6J,cAAeiC,EAAarI,IAClEsI,EAAepH,aAAa3E,GAAU4J,cAAe,QACrDmC,EAAepH,aAAa3E,GAAU+J,cAAe,SACrD+B,EAAanH,aAAa3E,GAAU8J,gBAAiBiC,EAAetI,IAE1ClD,KAAK2B,YAAY2J,GACzBnH,QAAQ,SAAAsH,UAAQA,EAAKrH,aAAa3E,GAAUgK,KAAM,eAE/DsB,kBAAkBM,GAAgBlH,QAAQ,SAAA+G,GAC7CA,EAAK9G,aAAa3E,GAAUgK,KAAM,YAClCyB,EAAK9G,aAAa3E,GAAU2J,SAAU,iBC7S/BsC,GAAS,IAAIC,EACbC,GAAa,IAAIC,EACjBC,GAAY,IAAIC,GAChBjM,GAAQ,IAAIkM,EAEnBC,SAAW,CAEfP,OAAAA,GACAE,WAAAA,GACAE,UAAAA,GAGAhM,MAAAA,GAGFmM,MAAiB,WAEfA,SAASP,OAAOQ,QAChBD,SAASL,WAAWM,QACpBD,SAASH,UAAUI,QAGnBD,SAASnM,MAAMqM,sBAGjBF,KAAgB,WAEdA,SAASP,OAAOU,OAChBH,SAASL,WAAWQ,OACpBH,SAASH,UAAUM,OAGnBH,SAASnM,MAAMuM,wBClCjBC,OAAOL,SAAWA"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e2c4f7e1..bf8fdfac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "undernet", - "version": "3.3.1", + "version": "3.3.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -6730,12 +6730,24 @@ "dev": true }, "jest-worker": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-23.2.0.tgz", - "integrity": "sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.0.0.tgz", + "integrity": "sha512-s64/OThpfQvoCeHG963MiEZOAAxu8kHsaL/rCMF7lpdzo7vgF0CtPml9hfguOMgykgH/eOm4jFP4ibfHLruytg==", "dev": true, "requires": { - "merge-stream": "^1.0.1" + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "js-base64": { @@ -7295,9 +7307,9 @@ "dev": true }, "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", "dev": true }, "md5.js": { @@ -9477,9 +9489,9 @@ } }, "randomatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", - "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "dev": true, "requires": { "is-number": "^4.0.0", @@ -10294,19 +10306,28 @@ } }, "rollup": { - "version": "0.67.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.67.4.tgz", - "integrity": "sha512-AVuP73mkb4BBMUmksQ3Jw0jTrBTU1i7rLiUYjFxLZGb3xiFmtVEg40oByphkZAsiL0bJC3hRAJUQos/e5EBd+w==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.1.2.tgz", + "integrity": "sha512-OkdMxqMl8pWoQc5D8y1cIinYQPPLV8ZkfLgCzL6SytXeNA2P7UHynEQXI9tYxuAjAMsSyvRaWnyJDLHMxq0XAg==", "dev": true, "requires": { "@types/estree": "0.0.39", - "@types/node": "*" + "@types/node": "*", + "acorn": "^6.0.5" + }, + "dependencies": { + "acorn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.6.tgz", + "integrity": "sha512-5M3G/A4uBSMIlfJ+h9W125vJvPFH/zirISsW5qfxF5YzEvXJCtolLoQvM5yZft0DvMcUrPGKPOlgEu55I6iUtA==", + "dev": true + } } }, "rollup-plugin-babel": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.0.3.tgz", - "integrity": "sha512-/PP0MgbPQyRywI4zRIJim6ySjTcOLo4kQbEbROqp9kOR3kHC3FeU++QpBDZhS2BcHtJTVZMVbBV46flbBN5zxQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.3.2.tgz", + "integrity": "sha512-KfnizE258L/4enADKX61ozfwGHoqYauvoofghFJBhFnpH9Sb9dNPpWg8QHOaAfVASUYV8w0mCx430i9z0LJoJg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -10333,15 +10354,23 @@ } }, "rollup-plugin-uglify": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-uglify/-/rollup-plugin-uglify-6.0.0.tgz", - "integrity": "sha512-XtzZd159QuOaXNvcxyBcbUCSoBsv5YYWK+7ZwUyujSmISst8avRfjWlp7cGu8T2O52OJnpEBvl+D4WLV1k1iQQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-uglify/-/rollup-plugin-uglify-6.0.2.tgz", + "integrity": "sha512-qwz2Tryspn5QGtPUowq5oumKSxANKdrnfz7C0jm4lKxvRDsNe/hSGsB9FntUul7UeC4TsZEWKErVgE1qWSO0gw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "jest-worker": "^23.2.0", - "serialize-javascript": "^1.5.0", + "jest-worker": "^24.0.0", + "serialize-javascript": "^1.6.1", "uglify-js": "^3.4.9" + }, + "dependencies": { + "serialize-javascript": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", + "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", + "dev": true + } } }, "rollup-pluginutils": { diff --git a/package.json b/package.json index f5cb37c2..59106efc 100644 --- a/package.json +++ b/package.json @@ -93,10 +93,10 @@ "react-router-dom": "^4.3.1", "react-spinners": "^0.4.5", "resolve-url-loader": "^3.0.0", - "rollup": "^0.67.4", - "rollup-plugin-babel": "^4.0.2", + "rollup": "^1.1.2", + "rollup-plugin-babel": "^4.3.2", "rollup-plugin-node-resolve": "^4.0.0", - "rollup-plugin-uglify": "^6.0.0", + "rollup-plugin-uglify": "^6.0.2", "sass-loader": "^7.1.0", "style-loader": "^0.23.0", "uglify-js": "^3.3.27",