@graupl/core 1.0.0-beta.19 → 1.0.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/component/badge.css +2 -0
- package/dist/css/component/badge.css.map +1 -0
- package/dist/css/component/disclosure.css +2 -0
- package/dist/css/component/disclosure.css.map +1 -0
- package/dist/css/component.css +1 -1
- package/dist/css/component.css.map +1 -1
- package/dist/css/graupl.css +1 -1
- package/dist/css/graupl.css.map +1 -1
- package/dist/css/layout.css +1 -1
- package/dist/css/layout.css.map +1 -1
- package/dist/js/accordion.js +2 -2
- package/dist/js/accordion.js.map +1 -1
- package/dist/js/alert.js.map +1 -1
- package/dist/js/carousel.js +2 -2
- package/dist/js/carousel.js.map +1 -1
- package/dist/js/component/accordion.cjs.js +2 -2
- package/dist/js/component/accordion.cjs.js.map +1 -1
- package/dist/js/component/accordion.es.js +2 -2
- package/dist/js/component/accordion.es.js.map +1 -1
- package/dist/js/component/accordion.iife.js +2 -2
- package/dist/js/component/accordion.iife.js.map +1 -1
- package/dist/js/component/alert.cjs.js.map +1 -1
- package/dist/js/component/alert.es.js.map +1 -1
- package/dist/js/component/alert.iife.js +2 -2
- package/dist/js/component/alert.iife.js.map +1 -1
- package/dist/js/component/carousel.cjs.js +2 -2
- package/dist/js/component/carousel.cjs.js.map +1 -1
- package/dist/js/component/carousel.es.js +2 -2
- package/dist/js/component/carousel.es.js.map +1 -1
- package/dist/js/component/carousel.iife.js +2 -2
- package/dist/js/component/carousel.iife.js.map +1 -1
- package/dist/js/component/disclosure.cjs.js +5 -0
- package/dist/js/component/disclosure.cjs.js.map +1 -0
- package/dist/js/component/disclosure.es.js +5 -0
- package/dist/js/component/disclosure.es.js.map +1 -0
- package/dist/js/component/disclosure.iife.js +5 -0
- package/dist/js/component/disclosure.iife.js.map +1 -0
- package/dist/js/generator/accordion.cjs.js +2 -2
- package/dist/js/generator/accordion.cjs.js.map +1 -1
- package/dist/js/generator/accordion.es.js +2 -2
- package/dist/js/generator/accordion.es.js.map +1 -1
- package/dist/js/generator/accordion.iife.js +2 -2
- package/dist/js/generator/accordion.iife.js.map +1 -1
- package/dist/js/generator/alert.cjs.js.map +1 -1
- package/dist/js/generator/alert.es.js.map +1 -1
- package/dist/js/generator/alert.iife.js +2 -2
- package/dist/js/generator/alert.iife.js.map +1 -1
- package/dist/js/generator/carousel.cjs.js +2 -2
- package/dist/js/generator/carousel.cjs.js.map +1 -1
- package/dist/js/generator/carousel.es.js +2 -2
- package/dist/js/generator/carousel.es.js.map +1 -1
- package/dist/js/generator/carousel.iife.js +2 -2
- package/dist/js/generator/carousel.iife.js.map +1 -1
- package/dist/js/generator/disclosure.cjs.js +5 -0
- package/dist/js/generator/disclosure.cjs.js.map +1 -0
- package/dist/js/generator/disclosure.es.js +5 -0
- package/dist/js/generator/disclosure.es.js.map +1 -0
- package/dist/js/generator/disclosure.iife.js +5 -0
- package/dist/js/generator/disclosure.iife.js.map +1 -0
- package/dist/js/generator/navigation.cjs.js.map +1 -1
- package/dist/js/generator/navigation.es.js.map +1 -1
- package/dist/js/generator/navigation.iife.js +1 -1
- package/dist/js/generator/navigation.iife.js.map +1 -1
- package/dist/js/graupl.js +6 -4
- package/dist/js/graupl.js.map +1 -1
- package/dist/js/navigation.js.map +1 -1
- package/package.json +1 -1
- package/scss/component/badge.scss +3 -0
- package/scss/component/disclosure.scss +3 -0
- package/src/js/TransactionalValue.js +140 -0
- package/src/js/accordion/Accordion.js +4 -4
- package/src/js/carousel/Carousel.js +1 -1
- package/src/js/disclosure/Disclosure.js +1378 -0
- package/src/js/disclosure/generator.js +47 -0
- package/src/js/disclosure/index.js +5 -0
- package/src/js/main.js +2 -0
- package/src/js/validate.js +7 -7
- package/src/scss/_index.scss +8 -8
- package/src/scss/base/_index.scss +4 -4
- package/src/scss/component/_index.scss +10 -8
- package/src/scss/component/badge/_defaults.scss +47 -0
- package/src/scss/component/badge/_index.scss +201 -0
- package/src/scss/component/badge/_variables.scss +112 -0
- package/src/scss/component/disclosure/_defaults.scss +45 -0
- package/src/scss/component/disclosure/_index.scss +214 -0
- package/src/scss/component/disclosure/_variables.scss +205 -0
- package/src/scss/layout/_index.scss +3 -3
- package/src/scss/theme/_index.scss +2 -2
- package/src/scss/utilities/_index.scss +21 -21
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accordion.es.js","names":["isValidInstance","contructor","elements","elementsType","TypeError","key","elementType","name","status","error","isValidType","type","values","valuesType","valueType","isQuerySelector","Error","document","querySelector","isValidClassList","Array","isArray","forEach","value","obj","isValidHoverType","validTypes","includes","join","isTag","tagName","HTMLElement","tag","toLowerCase","check","isValidState","validStates","isValidEvent","validEvents","addClass","className","element","length","classList","add","removeClass","remove","selectAllFocusableElements","context","document","querySelector","elements","Array","from","querySelectorAll","tabbableElements","filter","check","getAttribute","selectFirstFocusableElement","selectLastFocusableElement","selectNextFocusableElement","index","indexOf","selectPreviousFocusableElement","isTag","isValidType","addClass","removeClass","AccordionItem","_dom","item","toggle","header","content","_elements","parentAccordion","_open","_locked","_expandEvent","CustomEvent","bubbles","detail","_collapseEvent","constructor","accordionItemElement","accordionItemToggleElement","accordionItemHeaderElement","accordionItemContentElement","initialize","_setIds","_setAriaAttributes","dom","getAttribute","show","hide","elements","isOpen","isLocked","value","key","index","accordionItems","indexOf","id","setAttribute","emit","transition","closeClass","openClass","transitionClass","openDuration","requestAnimationFrame","style","height","getBoundingClientRect","setTimeout","allowMultipleExpand","unlockSiblings","closeSiblings","allowNoExpand","openAccordionItems","length","lock","dispatchEvent","closeDuration","focus","blur","unlock","removeAttribute","forEach","keyPress","event","key","keyCode","keys","Enter","Space","Escape","ArrowUp","ArrowRight","ArrowDown","ArrowLeft","Home","End","Tab","Object","find","preventEvent","preventDefault","stopPropagation","isValidType","initializeStorage","type","window","Graupl","getStorage","setStorage","data","clearStorage","pushToStorage","key","value","getFromStorage","removeFromStorage","AccordionItem","keyPress","preventEvent","isValidInstance","isValidType","isValidClassList","isQuerySelector","storage","Accordion","_dom","accordion","accordionItems","accordionItemToggles","accordionItemHeaders","accordionItemContents","_domLock","_selectors","_elements","_openClass","_closeClass","_transitionClass","_transitionDuration","_openDuration","_closeDuration","_optionalKeySupport","_allowMultipleExpand","_allowNoExpand","_currentChild","_prefix","_key","_errors","constructor","accordionElement","accordionItemSelector","accordionItemToggleSelector","accordionItemHeaderSelector","accordionItemContentSelector","openClass","closeClass","transitionClass","transitionDuration","openDuration","closeDuration","optionalKeySupport","allowMultipleExpand","allowNoExpand","prefix","key","initialize","_validate","Error","errors","join","_generateKey","_setDOMElements","_setIds","_createChildElements","_handleFocus","_handleClick","_handleKeydown","_handleKeyup","_setTransitionDurations","initializeStorage","pushToStorage","dom","id","error","console","currentChild","elements","selectors","currentAccordionItem","openAccordionItems","filter","item","isOpen","value","length","isArray","every","_accordionItems","_setDOMElementType","elementType","base","overwrite","strict","includes","contructor","name","HTMLElement","domElements","Array","from","querySelectorAll","filteredElements","parentElement","_resetDOMElementType","forEach","accordionItem","regenerate","Math","random","toString","replace","substring","index","accordionItemElement","accordionItemToggleElement","accordionItemHeaderElement","accordionItemContentElement","parentAccordion","push","check","htmlElementChecks","message","querySelectorChecks","openClassCheck","status","closeClassCheck","transitionClassCheck","transitionDurationCheck","openDurationCheck","closeDurationCheck","booleanCheck","keyCheck","prefixCheck","toggle","addEventListener","accordionToggle","event","ToggleKeys","optionalKeys","focusFirstChild","focusLastChild","focusNextChild","focusPreviousChild","style","setProperty","focusCurrentChild","focus","focusChild","blurCurrentChild","blur","openChildren","show","closeChildren","hide"],"sources":["../../../src/js/validate.js","../../../src/js/domHelpers.js","../../../src/js/accordion/AccordionItem.js","../../../src/js/eventHandlers.js","../../../src/js/storage.js","../../../src/js/accordion/Accordion.js"],"sourcesContent":["/**\n * Check to see if the provided elements have a specific contructor.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * This is essentially just a wrapper function around checking instanceof with\n * more descriptive error message to help debugging.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {object} contructor - The constructor to check for.\n * @param {object} elements - The element(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidInstance(contructor, elements) {\n try {\n if (typeof elements !== \"object\") {\n const elementsType = typeof elements;\n\n throw new TypeError(\n `Elements given to isValidInstance() must be inside of an object. \"${elementsType}\" given.`\n );\n }\n\n for (const key in elements) {\n if (!(elements[key] instanceof contructor)) {\n const elementType = typeof elements[key];\n throw new TypeError(\n `${key} must be an instance of ${contructor.name}. \"${elementType}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Check to see if the provided values are of a specific type.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * This is essentially just a wrapper function around checking typeof with\n * more descriptive error message to help debugging.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {string} type - The type to check for.\n * @param {object} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidType(type, values) {\n try {\n if (typeof values !== \"object\") {\n const valuesType = typeof values;\n\n throw new TypeError(\n `Values given to isValidType() must be inside of an object. \"${valuesType}\" given.`\n );\n }\n\n for (const key in values) {\n const valueType = typeof values[key];\n\n if (valueType !== type) {\n throw new TypeError(`${key} must be a ${type}. \"${valueType}\" given.`);\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Checks to see if the provided values are valid query selectors.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isQuerySelector(values) {\n try {\n if (typeof values !== \"object\") {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isQuerySelector() must be inside of an object. \"${type}\" given.`\n );\n }\n\n for (const key in values) {\n try {\n if (values[key] === null) {\n throw new Error();\n }\n\n document.querySelector(values[key]);\n } catch {\n throw new TypeError(\n `${key} must be a valid query selector. \"${values[key]}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Checks to see if the provided value is either a string or an array of strings.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string, string[]>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidClassList(values) {\n try {\n if (typeof values !== \"object\" || Array.isArray(values)) {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isValidClassList() must be inside of an object. \"${type}\" given.`\n );\n }\n\n for (const key in values) {\n const type = typeof values[key];\n\n if (type !== \"string\") {\n if (Array.isArray(values[key])) {\n values[key].forEach((value) => {\n if (typeof value !== \"string\") {\n throw new TypeError(\n `${key} must be a string or an array of strings. An array containing non-strings given.`\n );\n }\n });\n } else {\n throw new TypeError(\n `${key} must be a string or an array of strings. \"${type}\" given.`\n );\n }\n } else {\n const obj = {};\n obj[key] = values[key];\n\n isQuerySelector(obj);\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Check to see if the provided values are valid hover types.\n *\n * Available types are: `\"off\"`, `\"on\"`, and `\"dynamic\"`.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidHoverType(values) {\n try {\n if (typeof values !== \"object\") {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isValidHoverType() must be inside of an object. \"${type}\" given.`\n );\n }\n\n const validTypes = [\"off\", \"on\", \"dynamic\"];\n\n for (const key in values) {\n if (!validTypes.includes(values[key])) {\n throw new TypeError(\n `${key} must be one of the following values: ${validTypes.join(\n \", \"\n )}. \"${values[key]}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Checks to see if the provided elements are using a specific tag.\n *\n * The elements must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `true` if the check is successful.\n *\n * @param {string} tagName - The name of the tag.\n * @param {Object<HTMLElement>} elements - The element(s) to check.\n * @return {boolean} - The result of the check.\n */\nexport function isTag(tagName, elements) {\n if (\n isValidType(\"string\", { tagName }).status &&\n isValidInstance(HTMLElement, elements).status\n ) {\n const tag = tagName.toLowerCase();\n let check = true;\n\n for (const key in elements) {\n if (elements[key].tagName.toLowerCase() !== tag) check = false;\n }\n\n return check;\n } else {\n return false;\n }\n}\n\n/**\n * Check to see if the provided values are valid focus states for a menu.\n *\n * Available states are: `\"none\"`, `\"self\"`, and `\"child\"`.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidState(values) {\n try {\n if (typeof values !== \"object\") {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isValidState() must be inside of an object. \"${type}\" given.`\n );\n }\n\n const validStates = [\"none\", \"self\", \"child\"];\n\n for (const key in values) {\n if (!validStates.includes(values[key])) {\n throw new TypeError(\n `${key} must be one of the following values: ${validStates.join(\n \", \"\n )}. \"${values[key]}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Check to see if the provided values are valid event types for a menu.\n *\n * Available events are: `\"none\"`, `\"mouse\"`, `\"keyboard\"`, and `\"character\"`.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidEvent(values) {\n try {\n if (typeof values !== \"object\") {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isValidEvent() must be inside of an object. \"${type}\" given.`\n );\n }\n\n const validEvents = [\"none\", \"mouse\", \"keyboard\", \"character\"];\n\n for (const key in values) {\n if (!validEvents.includes(values[key])) {\n throw new TypeError(\n `${key} must be one of the following values: ${validEvents.join(\n \", \"\n )}. \"${values[key]}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n","/**\n * Add a class or array of classes to an element.\n *\n * @param {string|string[]} className - The class or classes to add.\n * @param {HTMLElement} element - The element to add the class to.\n */\nexport function addClass(className, element) {\n // Gracefully handle empty strings or arrays.\n if (className === \"\" || className.length === 0) {\n return;\n }\n\n if (typeof className === \"string\") {\n element.classList.add(className);\n } else {\n element.classList.add(...className);\n }\n}\n\n/**\n * Remove a class or array of classes from an element.\n *\n * @param {string|string[]} className - The class or classes to remove.\n * @param {HTMLElement} element - The element to remove the class from.\n */\nexport function removeClass(className, element) {\n // Gracefully handle empty strings or arrays.\n if (className === \"\" || className.length === 0) {\n return;\n }\n\n if (typeof className === \"string\") {\n element.classList.remove(className);\n } else {\n element.classList.remove(...className);\n }\n}\n\n/**\n * Select all focusable elements within a given context.\n *\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement[]} - An array of focusable elements.\n */\nexport function selectAllFocusableElements(context = document) {\n const querySelector =\n \"a[href],area[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),button:not([disabled]),[tabindex]\";\n const elements = Array.from(context.querySelectorAll(querySelector));\n\n const tabbableElements = elements.filter((element) => {\n let check = true;\n\n if (element.getAttribute(\"tabindex\") === \"-1\") check = false;\n\n return check;\n });\n\n return tabbableElements;\n}\n\n/**\n * Select the first focusable element within a given context.\n *\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement|boolean} - The first focusable element or false if none found.\n */\nexport function selectFirstFocusableElement(context = document) {\n const tabbableElements = selectAllFocusableElements(context);\n\n return tabbableElements[0] || false;\n}\n\n/**\n * Select the last focusable element within a given context.\n *\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement|boolean} - The last focusable element or false if none found.\n */\nexport function selectLastFocusableElement(context = document) {\n const tabbableElements = selectAllFocusableElements(context);\n\n return tabbableElements[tabbableElements.length - 1] || false;\n}\n\n/**\n * Select the next focusable element relative to the given element within a context.\n *\n * @param {HTMLElement} element - The reference element.\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement|boolean} - The next focusable element or false if none found.\n */\nexport function selectNextFocusableElement(element, context = document) {\n const tabbableElements = selectAllFocusableElements(context);\n const index = tabbableElements.indexOf(element);\n\n return index === tabbableElements.length - 1\n ? false\n : tabbableElements[index + 1];\n}\n\n/**\n * Select the previous focusable element relative to the given element within a context.\n *\n * @param {HTMLElement} element - The reference element.\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement|boolean} - The previous focusable element or false if none found.\n */\nexport function selectPreviousFocusableElement(element, context = document) {\n const tabbableElements = selectAllFocusableElements(context);\n const index = tabbableElements.indexOf(element);\n\n return index === 0 ? false : tabbableElements[index - 1];\n}\n","/**\n * @file\n * The Accordion Item class.\n */\n\n/* global Accordion */\n\nimport { isTag, isValidType } from \"../validate.js\";\nimport { addClass, removeClass } from \"../domHelpers.js\";\n\n/**\n * Creates a new accordion item.\n *\n * @class\n */\nclass AccordionItem {\n /**\n * The HTML elements for the accordion item in the DOM.\n *\n * @protected\n *\n * @type {Object<HTMLElement>}\n *\n * @property {HTMLElement} item - The accordion item element.\n * @property {HTMLElement} toggle - The controller element.\n * @property {HTMLElement} header - The header element.\n * @property {HTMLElement} content - The content element.\n */\n _dom = {\n item: null,\n toggle: null,\n header: null,\n content: null,\n };\n\n /**\n * The declared graupl accordion elements within the accordion item.\n *\n * @protected\n *\n * @type {Object<Accordion>}\n *\n * @property {Accordion} parentAccordion - The parent accordion containing this item.\n */\n _elements = {\n parentAccordion: null,\n };\n\n /**\n * The open state of the accordion.\n *\n * @protected\n *\n * @type {boolean}\n */\n _open = false;\n\n /**\n * The locked state of the accordions item.\n *\n * If locked, the accordion item cannot be closed.\n *\n * @protected\n *\n * @type {boolean}\n */\n _locked = false;\n\n /**\n * The event that is triggered when the accordion item is shown.\n *\n * @protected\n *\n * @event grauplAccordionItemExpand\n *\n * @type {CustomEvent}\n *\n * @property {boolean} bubbles - A flag to bubble the event.\n * @property {Object<AccordionItem>} detail - The details object containing the Accordion item itself.\n */\n _expandEvent = new CustomEvent(\"grauplAccordionItemExpand\", {\n bubbles: true,\n detail: { item: this },\n });\n\n /**\n * The event that is triggered when the accordion item is hidden.\n *\n * @protected\n *\n * @event grauplAccordionItemCollapse\n *\n * @type {CustomEvent}\n *\n * @property {boolean} bubbles - A flag to bubble the event.\n * @property {Object<AccordionItem>} detail - The details object containing the Accordion item itself.\n */\n _collapseEvent = new CustomEvent(\"grauplAccordionItemCollapse\", {\n bubbles: true,\n detail: { item: this },\n });\n\n /**\n * Constructs a new Accordion item object.\n *\n * @class\n *\n * @param {object} options - The options object.\n * @param {HTMLElement} options.accordionItemElement - The accordion item element.\n * @param {HTMLElement} options.accordionItemToggleElement - The toggle element.\n * @param {HTMLElement} options.accordionItemHeaderElement - The header element.\n * @param {HTMLElement} options.accordionItemContentElement - The content element.\n * @param {Accordion} [options.parentAccordion = null] - The accordion containing this item.\n */\n constructor({\n accordionItemElement,\n accordionItemToggleElement,\n accordionItemHeaderElement,\n accordionItemContentElement,\n parentAccordion = null,\n }) {\n // Set DOM elements.\n this._dom.item = accordionItemElement;\n this._dom.toggle = accordionItemToggleElement;\n this._dom.header = accordionItemHeaderElement;\n this._dom.content = accordionItemContentElement;\n\n // Set the accordion elements.\n this._elements.parentAccordion = parentAccordion;\n }\n\n /**\n * Initializes the accordion item.\n */\n initialize() {\n // Set the IDs for the accordion item and it's elements if they don't exist.\n this._setIds();\n\n // Set the ARIA attributes for the accordion item and it's elements.\n this._setAriaAttributes();\n\n // Set the initial state of the accordion item.\n if (this.dom.toggle.getAttribute(\"aria-expanded\") === \"true\") {\n this.show(false, false);\n } else {\n this.hide(false, false);\n }\n }\n\n /**\n * The HTML elements for the accordion item in the DOM.\n *\n * @readonly\n *\n * @type {object}\n *\n * @see _dom\n */\n get dom() {\n return this._dom;\n }\n\n /**\n * The declared graupl accordion elements within the accordion item.\n *\n * @readonly\n *\n * @type {Object<Accordion>}\n *\n * @see _elements\n */\n get elements() {\n return this._elements;\n }\n\n /**\n * The open state of the accordion.\n *\n * @readonly\n *\n * @type {object}\n *\n * @see _open\n */\n get isOpen() {\n return this._open;\n }\n\n /**\n * The locked state of the accordions item.\n *\n * If locked, the accordion item cannot be closed.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _locked\n */\n get isLocked() {\n return this._locked;\n }\n\n set isOpen(value) {\n isValidType(\"boolean\", { value });\n\n if (this._open !== value) {\n this._open = value;\n }\n }\n\n /**\n * Sets the IDs for the accordion item and it's elements if they don't exist.\n *\n * The generated IDs use the parent accordion's key and follows the pattern:\n * - Accordion item: `accordion-item-{key}-{index}`\n * - Accordion item toggle: `accordion-item-toggle-{key}-{index}`\n * - Accordion item content: `accordion-item-content-{key}-{index}`\n */\n _setIds() {\n // Get the required information for IDs.\n const { key } = this.elements.parentAccordion;\n const index = this.elements.parentAccordion.dom.accordionItems.indexOf(\n this.dom.item\n );\n\n this.dom.item.id = this.dom.item.id || `accordion-item-${key}-${index}`;\n this.dom.toggle.id =\n this.dom.toggle.id || `accordion-item-toggle-${key}-${index}`;\n this.dom.header.id =\n this.dom.header.id || `accordion-item-header-${key}-${index}`;\n this.dom.content.id =\n this.dom.content.id || `accordion-item-content-${key}-${index}`;\n }\n\n /**\n * Sets the ARIA attributes for the accordion item and it's elements.\n */\n _setAriaAttributes() {\n // Set the ARIA attributes for the accordion item toggle.\n // If the toggle is not a button, then set the role to \"button\".\n if (!isTag(\"button\", { toggle: this.dom.toggle })) {\n this.dom.toggle.setAttribute(\"role\", \"button\");\n }\n\n // If aria-expanded is not explicitly set to \"true\", then set it to \"false\".\n if (this.dom.toggle.getAttribute(\"aria-expanded\") !== \"true\") {\n this.dom.toggle.setAttribute(\"aria-expanded\", \"false\");\n }\n\n // Set the aria-controls attribute for the toggle.\n this.dom.toggle.setAttribute(\"aria-controls\", this.dom.content.id);\n\n // Set the ARIA attributes for the accordion item content.\n // If the content is not a section, then set the role to \"region\".\n if (!isTag(\"section\", { content: this.dom.content })) {\n this.dom.content.setAttribute(\"role\", \"region\");\n }\n\n // Set the aria-labelledby attribute for the content.\n this.dom.content.setAttribute(\"aria-labelledby\", this.dom.toggle.id);\n }\n\n /**\n * Shows the accordion item.\n *\n * @public\n *\n * @fires grauplAccordionItemExpand\n *\n * @param {boolean} [emit = true] - Emit the show event once shown.\n * @param {boolean} [transition = true] - Respect the transition class.\n */\n show(emit = true, transition = true) {\n if (this._open) {\n return;\n }\n\n const { closeClass, openClass, transitionClass, openDuration } =\n this.elements.parentAccordion;\n\n // Set aria-expanded to true when hiding accordion item.\n this.dom.toggle.setAttribute(\"aria-expanded\", \"true\");\n\n // If we're dealing with transition classes, then we need to utilize\n // requestAnimationFrame to add the transition class, remove the hide class,\n // add the show class, and finally remove the transition class.\n //\n // If `transition` is false, then it doesn't matter if the transition class\n // is set. Do not use the transition.\n if (transition && transitionClass !== \"\") {\n addClass(transitionClass, this.dom.item);\n\n requestAnimationFrame(() => {\n removeClass(closeClass, this.dom.item);\n\n this.dom.item.style.height = `${this.dom.header.getBoundingClientRect().height}px`;\n\n requestAnimationFrame(() => {\n addClass(openClass, this.dom.item);\n\n this.dom.item.style.height = `${this.dom.header.getBoundingClientRect().height + this.dom.content.getBoundingClientRect().height}px`;\n\n requestAnimationFrame(() => {\n setTimeout(() => {\n removeClass(transitionClass, this.dom.item);\n\n this.dom.item.style.height = \"\";\n }, openDuration);\n });\n });\n });\n } else {\n // Add the show class\n addClass(openClass, this.dom.item);\n\n // Remove the hide class.\n removeClass(closeClass, this.dom.item);\n }\n\n this._open = true;\n\n // If the parent accordion only allows a single item to be open at a time,\n // then close all other items.\n if (!this.elements.parentAccordion.allowMultipleExpand) {\n this.unlockSiblings();\n this.closeSiblings();\n }\n\n // If the parent accordion requires at least one item to be open, and this\n // is the only open item, then lock it. Otherwise, unlock all siblings.\n if (!this.elements.parentAccordion.allowNoExpand) {\n if (this.elements.parentAccordion.openAccordionItems.length <= 1) {\n this.lock();\n } else {\n this.unlockSiblings();\n }\n }\n\n if (emit) {\n this.dom.item.dispatchEvent(this._expandEvent);\n }\n }\n\n /**\n * Hides the accordion item.\n *\n * @public\n *\n * @fires grauplAccordionItemCollapse\n *\n * @param {boolean} [emit = true] - Emit the show event once shown.\n * @param {boolean} [transition = true] - Respect the transition class.\n */\n hide(emit = true, transition = true) {\n if (!this._open) {\n return;\n }\n\n if (\n !this.elements.parentAccordion.allowNoExpand &&\n this.elements.parentAccordion.openAccordionItems.length <= 1\n ) {\n return;\n }\n\n const { closeClass, openClass, transitionClass, closeDuration } =\n this.elements.parentAccordion;\n\n // Set aria-expanded to false when hiding accordion item.\n this.dom.toggle.setAttribute(\"aria-expanded\", \"false\");\n\n // If we're dealing with transition classes, then we need to utilize\n // requestAnimationFrame to add the transition class, remove the show class,\n // add the hide class, and finally remove the transition class.\n //\n // If `transition` is false, then it doesn't matter if the transition class\n // is set. Do not use the transition.\n if (transition && transitionClass !== \"\") {\n addClass(transitionClass, this.dom.item);\n this.dom.item.style.height = `${this.dom.item.getBoundingClientRect().height}px`;\n\n requestAnimationFrame(() => {\n removeClass(openClass, this.dom.item);\n this.dom.item.style.height = `${this.dom.header.getBoundingClientRect().height}px`;\n\n requestAnimationFrame(() => {\n addClass(closeClass, this.dom.item);\n\n requestAnimationFrame(() => {\n setTimeout(() => {\n removeClass(transitionClass, this.dom.item);\n\n this.dom.item.style.height = \"\";\n }, closeDuration);\n });\n });\n });\n } else {\n // Add the hide class\n addClass(closeClass, this.dom.item);\n\n // Remove the show class.\n removeClass(openClass, this.dom.item);\n }\n\n this._open = false;\n\n // If the parent accordion requires at least one item to be open, and this was\n // the second to last open item, then lock to last open item.\n if (\n !this.elements.parentAccordion.allowNoExpand &&\n this.elements.parentAccordion.openAccordionItems.length === 1\n ) {\n this.elements.parentAccordion.openAccordionItems[0].lock();\n }\n\n if (emit) {\n this.dom.item.dispatchEvent(this._collapseEvent);\n }\n }\n\n /**\n * Toggle the accordion item.\n *\n * @public\n */\n toggle() {\n this.isOpen ? this.hide() : this.show();\n }\n\n /**\n * Focuses the accordion item.\n *\n * @public\n */\n focus() {\n this.dom.toggle.focus();\n }\n\n /**\n * Blurs the accordion item.\n *\n * @public\n */\n blur() {\n this.dom.toggle.blur();\n }\n\n /**\n * Locks the accordion item.\n *\n * @public\n */\n lock() {\n this._locked = true;\n this.dom.toggle.setAttribute(\"disabled\", \"true\");\n }\n\n /**\n * Unlocks the accordion item.\n *\n * @public\n */\n unlock() {\n this._locked = false;\n this.dom.toggle.removeAttribute(\"disabled\");\n }\n\n closeSiblings() {\n if (this.elements.parentAccordion) {\n this.elements.parentAccordion.elements.accordionItems.forEach((item) => {\n if (item !== this) {\n item.hide();\n }\n });\n }\n }\n\n /**\n * Unlocks the siblings of the accordion item.\n *\n * @public\n */\n unlockSiblings() {\n if (this.elements.parentAccordion) {\n this.elements.parentAccordion.elements.accordionItems.forEach((item) => {\n if (item !== this) {\n item.unlock();\n }\n });\n }\n }\n}\n\nexport default AccordionItem;\n","/**\n * Retrieves the pressed key from an event.\n *\n * @param {KeyboardEvent} event - The keyboard event.\n * @return {string} - The name of the key or an empty string.\n */\nexport function keyPress(event) {\n try {\n // Use event.key or event.keyCode to support older browsers.\n const key = event.key || event.keyCode;\n const keys = {\n Enter: key === \"Enter\" || key === 13,\n Space: key === \" \" || key === \"Spacebar\" || key === 32,\n Escape: key === \"Escape\" || key === \"Esc\" || key === 27,\n ArrowUp: key === \"ArrowUp\" || key === \"Up\" || key === 38,\n ArrowRight: key === \"ArrowRight\" || key === \"Right\" || key === 39,\n ArrowDown: key === \"ArrowDown\" || key === \"Down\" || key === 40,\n ArrowLeft: key === \"ArrowLeft\" || key === \"Left\" || key === 37,\n Home: key === \"Home\" || key === 36,\n End: key === \"End\" || key === 35,\n Tab: key === \"Tab\" || key === 9,\n };\n\n return Object.keys(keys).find((key) => keys[key] === true) || \"\";\n } catch {\n // Return an empty string if something goes wrong.\n return \"\";\n }\n}\n\n/**\n * Stops an event from taking action.\n *\n * @param {Event} event - The event.\n */\nexport function preventEvent(event) {\n event.preventDefault();\n event.stopPropagation();\n}\n","/**\n * @file\n * Provides a system to get and store Graupl data in the browser.\n */\n\nimport { isValidType } from \"./validate.js\";\n\n/**\n * Initializes the storage system.\n *\n * @param {?string} [type = null] - The type of storage to initialize.\n */\nexport function initializeStorage(type = null) {\n window.Graupl = window.Graupl || {};\n\n if (isValidType(\"string\", { type })) {\n window.Graupl[type] = window.Graupl[type] || {};\n }\n}\n\n/**\n * Get the storage object.\n *\n * @param {?string} type - The type of storage to get.\n * @return {object} - The storage object.\n */\nexport function getStorage(type = null) {\n if (isValidType(\"string\", { type })) {\n return window.Graupl[type];\n }\n\n return window.Graupl;\n}\n\n/**\n * Set the storage object of a given type.\n *\n * @param {string} type - The type of storage to set.\n * @param {object} data - The data to set.\n */\nexport function setStorage(type, data = {}) {\n if (isValidType(\"string\", { type }) && isValidType(\"object\", { data })) {\n window.Graupl[type] = data;\n }\n}\n\n/**\n * Clear the storage object of a given type.\n *\n * @param {string} type - The type of storage to clear.\n */\nexport function clearStorage(type) {\n if (isValidType(\"string\", { type })) {\n window.Graupl[type] = {};\n }\n}\n\n/**\n * Push a value to the storage object.\n *\n * @param {string} type - The type of storage to push to.\n * @param {string} key - The key to use for the value.\n * @param {*} value - The value to store.\n */\nexport function pushToStorage(type, key, value) {\n if (isValidType(\"string\", { type, key })) {\n window.Graupl[type][key] = value;\n }\n}\n\n/**\n * Get a value from the storage object.\n *\n * @param {string }type - The type of storage to get from.\n * @param {string }key - The key to get the value from.\n * @return {*} - The value from the storage object.\n */\nexport function getFromStorage(type, key) {\n if (isValidType(\"string\", { type, key })) {\n return window.Graupl[type][key];\n }\n\n return null;\n}\n\n/**\n * Remove a value from the storage object.\n *\n * @param {string} type - The type of storage to remove from.\n * @param {string} key - The key to remove the value from.\n */\nexport function removeFromStorage(type, key) {\n if (isValidType(\"string\", { type, key })) {\n delete window.Graupl[type][key];\n }\n}\n\nexport default {\n initializeStorage,\n getStorage,\n setStorage,\n clearStorage,\n pushToStorage,\n getFromStorage,\n removeFromStorage,\n};\n","/**\n * @file\n * The Accordion class.\n */\n\nimport AccordionItem from \"./AccordionItem.js\";\nimport { keyPress, preventEvent } from \"../eventHandlers.js\";\nimport {\n isValidInstance,\n isValidType,\n isValidClassList,\n isQuerySelector,\n} from \"../validate.js\";\nimport storage from \"../storage.js\";\n\nclass Accordion {\n /**\n * The DOM elements within the accordion.\n *\n * @protected\n *\n * @type {Object<HTMLElement, HTMLElement[]>}\n *\n * @property {HTMLElement} accordion - The accordion element.\n * @property {HTMLElement[]} accordionItems - An array of accordion items.\n * @property {HTMLElement[]} accordionItemToggles - An array of accordion item toggles.\n * @property {HTMLElement[]} accordionItemHeaders - An array of accordion headers.\n * @property {HTMLElement[]} accordionItemContents - An array of accordion item contents.\n */\n _dom = {\n accordion: null,\n accordionItems: [],\n accordionItemToggles: [],\n accordionItemHeaders: [],\n accordionItemContents: [],\n };\n\n /**\n * The DOM elements within the accordion that cannot be reset or generated by the accordion.\n *\n * @protected\n *\n * @type {string[]}\n */\n _domLock = [\"accordion\"];\n\n /**\n * The query selectors used by the accordion.\n *\n * @protected\n *\n * @type {Object<string>}\n *\n * @property {string} accordionItems - The query selector for accordion items.\n * @property {string} accordionItemToggles - The query selector for accordion toggles.\n * @property {string} accordionItemHeaders - The query selector for accordion headers.\n * @property {string} accordionItemContents - The query selector for accordion contents.\n */\n _selectors = {\n accordionItems: \"\",\n accordionItemToggles: \"\",\n accordionItemHeaders: \"\",\n accordionItemContents: \"\",\n };\n\n /**\n * The list of accordion items.\n *\n * @protected\n *\n * @type {Object<AccordionItem[]>}\n *\n * @property {AccordionItem[]} accordionItems - The list of accordion items.\n */\n _elements = {\n accordionItems: [],\n };\n\n /**\n * The class(es) to apply when the accordion is open.\n *\n * @protected\n *\n * @type {string|string[]}\n */\n _openClass = \"show\";\n\n /**\n * The class(es) to apply when the accordion is closed.\n *\n * @protected\n *\n * @type {string|string[]}\n */\n _closeClass = \"hide\";\n\n /**\n * The class(es) to apply when the accordion is transitioning between states.\n *\n * @protected\n *\n * @type {string|string[]}\n */\n _transitionClass = \"transitioning\";\n\n /**\n * The duration time (in milliseconds) for the transition between open and closed states.\n *\n * @protected\n *\n * @type {number}\n */\n _transitionDuration = 300;\n\n /**\n * The duration time (in milliseconds) for the transition from closed to open states.\n *\n * @protected\n *\n * @type {number}\n */\n _openDuration = -1;\n\n /**\n * The duration time (in milliseconds) for the transition from open to closed states.\n *\n * @protected\n *\n * @type {number}\n */\n _closeDuration = -1;\n\n /**\n * A flag to decide if the accordion items can be navigated by arrows.\n *\n * @protected\n *\n * @type {boolean}\n */\n _optionalKeySupport = true;\n\n /**\n * A flag to decide if multiple accordions can be open at the same time.\n *\n * If set to false, only one accordion can be open at a time.\n *\n * @protected\n *\n * @type {boolean}\n */\n _allowMultipleExpand = true;\n\n /**\n * A flag to decide if no accordions can be opened at the same time.\n *\n * If set to false, at least one accordion must be open at all times.\n *\n * @protected\n *\n * @type {boolean}\n */\n _allowNoExpand = true;\n\n /**\n * The index of the current child node.\n *\n * @protected\n *\n * @type {number}\n */\n _currentChild = 0;\n\n /**\n * The prefix to use for CSS custom properties.\n *\n * @protected\n *\n * @type {string}\n */\n _prefix = \"graupl-\";\n\n /**\n * The key used to generate IDs throughout the accordion.\n *\n * @protected\n *\n * @type {string}\n */\n _key = \"\";\n\n /**\n * errors - The list of errors found during validation.\n *\n * @protected\n *\n * @type {string[]}\n */\n _errors = [];\n\n /**\n * Constructs a new `Accordion`.\n *\n * @param {object} options - The options for generating the accordion.\n * @param {HTMLElement} [options.accordionElement] - The accordion element in the DOM.\n * @param {string} [options.accordionItemSelector = .accordion-item] - The query selector string for accordion items.\n * @param {string} [options.accordionItemToggleSelector = .accordion-item-toggle] - The query selector string for accordion toggle.\n * @param {string} [options.accordionItemHeaderSelector = .accordion-item-header] - The query selector string for accordion header.\n * @param {string} [options.accordionItemContentSelector = .accordion-item-content] - The query selector string for accordion content.\n * @param {?(string|string[])} [options.openClass = show] - The class to apply when a accordion is \"open\".\n * @param {?(string|string[])} [options.closeClass = hide] - The class to apply when a accordion is \"closed\".\n * @param {?(string|string[])} [options.transitionClass = transitioning] - The class to apply when a accordion is transitioning between \"open\" and \"closed\" states.\n * @param {number} [options.transitionDuration = 300] - The duration of the transition between \"open\" and \"closed\" states (in milliseconds).\n * @param {number} [options.openDuration = -1] - The duration of the transition from \"closed\" to \"open\" states (in milliseconds).\n * @param {number} [options.closeDuration = -1] - The duration of the transition from \"open\" to \"closed\" states (in milliseconds).\n * @param {boolean} [options.optionalKeySupport = false] - A flag to determine if accordions can be navigated with arrows.\n * @param {boolean} [options.allowMultipleExpand = true] - A flag to determine if multiple accordions can be open at the same time.\n * @param {boolean} [options.allowNoExpand = true] - A flag to determine if no accordions can be open at the same time.\n * @param {?string} [options.prefix = graupl-] - The prefix to use for CSS custom properties.\n * @param {?string} [options.key = null] - The key used to generate IDs throughout the accordion.\n * @param {boolean} [options.initialize = false] - A flag to initialize the accordion immediately upon creation.\n */\n constructor({\n accordionElement,\n accordionItemSelector = \".accordion-item\",\n accordionItemToggleSelector = \".accordion-item-toggle\",\n accordionItemHeaderSelector = \".accordion-item-header\",\n accordionItemContentSelector = \".accordion-item-content\",\n openClass = \"show\",\n closeClass = \"hide\",\n transitionClass = \"transitioning\",\n transitionDuration = 300,\n openDuration = -1,\n closeDuration = -1,\n optionalKeySupport = false,\n allowMultipleExpand = true,\n allowNoExpand = true,\n prefix = \"graupl-\",\n key = null,\n initialize = false,\n }) {\n // Set DOM elements.\n this._dom.accordion = accordionElement;\n\n // Set DOM selectors.\n this._selectors.accordionItems = accordionItemSelector;\n this._selectors.accordionItemToggles = accordionItemToggleSelector;\n this._selectors.accordionItemHeaders = accordionItemHeaderSelector;\n this._selectors.accordionItemContents = accordionItemContentSelector;\n\n // Set open/close classes.\n this._openClass = openClass || \"\";\n this._closeClass = closeClass || \"\";\n this._transitionClass = transitionClass || \"\";\n\n // Set transition duration.\n this._transitionDuration = transitionDuration;\n this._openDuration = openDuration;\n this._closeDuration = closeDuration;\n\n // Set optional key support.\n this._optionalKeySupport = optionalKeySupport;\n\n // Set expand rules.\n this._allowMultipleExpand = allowMultipleExpand;\n this._allowNoExpand = allowNoExpand;\n\n // Set prefix.\n this._prefix = prefix || \"\";\n\n // Set the key.\n this._key = key || \"\";\n\n if (initialize) {\n this.initialize();\n }\n }\n\n /**\n * Initializes the accordion.\n */\n initialize() {\n try {\n if (!this._validate()) {\n throw new Error(\n `Graupl Accordion: cannot initialize accordion. The following errors have been found:\\n - ${this.errors.join(\n \"\\n - \"\n )}`\n );\n }\n\n // Set up the DOM.\n this._generateKey();\n this._setDOMElements();\n this._setIds();\n\n // Create the child elements.\n this._createChildElements();\n\n // Handle events.\n this._handleFocus();\n this._handleClick();\n this._handleKeydown();\n this._handleKeyup();\n\n // Set the custom props.\n this._setTransitionDurations();\n\n // Set up the storage.\n storage.initializeStorage(\"accordions\");\n storage.pushToStorage(\"accordions\", this.dom.accordion.id, this);\n } catch (error) {\n console.error(error);\n }\n }\n\n /**\n * The class(es) to apply when the accordion is open.\n *\n * @type {string|string[]}\n *\n * @see _openClass\n */\n get openClass() {\n return this._openClass;\n }\n\n /**\n * The class(es) to apply when the accordion is closed.\n *\n * @type {string|string[]}\n *\n * @see _closeClass\n */\n get closeClass() {\n return this._closeClass;\n }\n\n /**\n * The class(es) to apply when the accordion is transitioning between open and closed.\n *\n * @type {string|string[]}\n *\n * @see _transitionClass\n */\n get transitionClass() {\n return this._transitionClass;\n }\n\n /**\n * The duration time (in milliseconds) for the transition between open and closed states.\n *\n * @type {number}\n *\n * @see _transitionDuration\n */\n get transitionDuration() {\n return this._transitionDuration;\n }\n\n /**\n * The duration time (in milliseconds) for the transition from closed to open states.\n *\n * If openDuration is set to -1, the transitionDuration will be used instead.\n *\n * @type {number}\n *\n * @see _openDuration\n */\n get openDuration() {\n return this._openDuration === -1\n ? this.transitionDuration\n : this._openDuration;\n }\n\n /**\n * The duration time (in milliseconds) for the transition from open to closed states.\n *\n * If closeDuration is set to -1, the transitionDuration will be used instead.\n *\n * @type {number}\n *\n * @see _closeDuration\n */\n get closeDuration() {\n return this._closeDuration === -1\n ? this.transitionDuration\n : this._closeDuration;\n }\n\n /**\n * The current index of the accordion item.\n *\n * @readonly\n *\n * @type {number}\n *\n * @see _currentChild\n */\n get currentChild() {\n return this._currentChild;\n }\n\n /**\n * The dom elements of the accordion.\n *\n * @readonly\n *\n * @type {object}\n *\n * @see _dom\n */\n get dom() {\n return this._dom;\n }\n\n /**\n * The elements of the accordion.\n *\n * @readonly\n *\n * @type {object}\n *\n * @see _elements\n */\n get elements() {\n return this._elements;\n }\n\n /**\n * The selectors used for the accordion and accordion items.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _selectors\n */\n get selectors() {\n return this._selectors;\n }\n\n /**\n * A flag to decide if the accordion items can be navigated by arrows.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _optionalKeySupport\n */\n get optionalKeySupport() {\n return this._optionalKeySupport;\n }\n\n /**\n * The currently selected accordion item.\n *\n * @readonly\n *\n * @type {AccordionItem}\n */\n get currentAccordionItem() {\n return this.elements.accordionItems[this.currentChild];\n }\n\n /**\n * The currently open accordion items.\n *\n * @readonly\n *\n * @type {AccordionItem[]}\n */\n get openAccordionItems() {\n return this.elements.accordionItems.filter((item) => item.isOpen);\n }\n\n /**\n * A flag to decide if multiple accordions can be open at the same time.\n *\n * @type {boolean}\n *\n * @see _allowMultipleExpand\n */\n get allowMultipleExpand() {\n return this._allowMultipleExpand;\n }\n\n /**\n * A flag to decide if no accordions can be opened at the same time.\n *\n * @type {boolean}\n *\n * @see _allowNoExpand\n */\n get allowNoExpand() {\n return this._allowNoExpand;\n }\n\n /**\n * The prefix to use for CSS custom properties.\n *\n * @type {string}\n *\n * @see _prefix\n */\n get prefix() {\n return this._prefix;\n }\n\n /**\n * The key used to generate IDs throughout the accordion.\n *\n * @type {string}\n *\n * @see _key\n */\n get key() {\n return this._key;\n }\n\n /**\n * An array to hold error messages.\n *\n * @readonly\n *\n * @type {string[]}\n *\n * @see _errors\n */\n get errors() {\n return this._errors;\n }\n\n set openClass(value) {\n isValidClassList({ openClass: value });\n\n if (this._openClass !== value) {\n this._openClass = value;\n }\n }\n\n set closeClass(value) {\n isValidClassList({ closeClass: value });\n\n if (this._closeClass !== value) {\n this._closeClass = value;\n }\n }\n\n set transitionClass(value) {\n isValidClassList({ transitionClass: value });\n\n if (this._transitionClass !== value) {\n this._transitionClass = value;\n }\n }\n\n set transitionDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._transitionDuration !== value) {\n this._transitionDuration = value;\n this._setTransitionDurations();\n }\n }\n\n set openDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._openDuration !== value) {\n this._openDuration = value;\n this._setTransitionDurations();\n }\n }\n\n set closeDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._closeDuration !== value) {\n this._closeDuration = value;\n this._setTransitionDurations();\n }\n }\n\n set currentChild(value) {\n isValidType(\"number\", { value });\n\n if (\n this._currentChild !== value &&\n value >= 0 &&\n value < this.elements.accordionItems.length\n ) {\n this._currentChild = value;\n }\n }\n\n set accordionItems(value) {\n isValidType(\"object\", { value });\n\n if (\n value?.isArray() &&\n value.every((item) => item instanceof AccordionItem)\n ) {\n this._accordionItems = value;\n }\n }\n\n set allowMultipleExpand(value) {\n isValidType(\"boolean\", { value });\n\n if (this._allowMultipleExpand !== value) {\n this._allowMultipleExpand = value;\n }\n }\n\n set allowNoExpand(value) {\n isValidType(\"boolean\", { value });\n\n if (this._allowNoExpand !== value) {\n this._allowNoExpand = value;\n }\n }\n\n set prefix(value) {\n isValidType(\"string\", { value });\n\n if (this._prefix !== value) {\n this._prefix = value;\n }\n }\n\n set key(value) {\n isValidType(\"string\", { value });\n\n if (this._key !== value) {\n this._key = value;\n }\n }\n\n /**\n * Sets DOM elements.\n *\n * Elements listed in _domLock cannot be set using this method.\n *\n * @protected\n *\n * @param {string} elementType - The type of element to populate.\n * @param {HTMLElement} [base = this.dom.accordion] - The element used as the base for the querySelect.\n * @param {boolean} [overwrite = true] - A flag to set if the existing elements will be overwritten.\n * @param {boolean} [strict = false] - A flag to set if the elements must be direct children of the base.\n */\n _setDOMElementType(\n elementType,\n base = this.dom.accordion,\n overwrite = true,\n strict = false\n ) {\n if (typeof this.selectors[elementType] === \"string\") {\n if (this._domLock.includes(elementType)) {\n throw new Error(\n `Graupl ${this.contructor.name}: \"${elementType}\" element cannot be set through _setDOMElementType.`\n );\n }\n\n if (base !== this.dom.accordion) isValidInstance(HTMLElement, { base });\n\n // Get the all elements matching the selector in the base.\n const domElements = Array.from(\n base.querySelectorAll(this.selectors[elementType])\n );\n\n // Filter the elements so only direct children of the base are kept.\n const filteredElements = domElements.filter((item) =>\n strict ? item.parentElement === base : true\n );\n\n if (overwrite) {\n this._dom[elementType] = filteredElements;\n } else {\n this._dom[elementType] = [\n ...this._dom[elementType],\n ...filteredElements,\n ];\n }\n } else {\n throw new Error(\n `Graupl ${this.contructor.name}: \"${elementType}\" is not a valid element type.`\n );\n }\n }\n\n /**\n * Resets DOM elements.\n *\n * Elements listed in _domLock cannot be reset using this method.\n *\n * @protected\n *\n * @param {string} elementType - The type of element to clear.\n */\n _resetDOMElementType(elementType) {\n if (typeof this.selectors[elementType] === \"string\") {\n if (this._domLock.includes(elementType)) {\n throw new Error(\n `Graupl ${this.contructor.name}: \"${elementType}\" element cannot be reset through _resetDOMElementType.`\n );\n }\n\n if (Array.isArray(this._dom[elementType])) {\n this._dom[elementType] = [];\n } else {\n this._dom[elementType] = null;\n }\n } else {\n throw new Error(\n `Graupl ${this.contructor.name}: \"${elementType}\" is not a valid element type.`\n );\n }\n }\n\n /**\n * Sets all DOM elements within the accordion.\n *\n * Utilizes _setDOMElementType and\n * _resetDOMElementType.\n *\n * @protected\n */\n _setDOMElements() {\n this._setDOMElementType(\"accordionItems\");\n this._resetDOMElementType(\"accordionItemToggles\");\n\n this.dom.accordionItems.forEach((accordionItem) => {\n this._setDOMElementType(\"accordionItemToggles\", accordionItem, false);\n this._setDOMElementType(\"accordionItemHeaders\", accordionItem, false);\n this._setDOMElementType(\"accordionItemContents\", accordionItem, false);\n });\n }\n\n /**\n * Generates a key for the accordion.\n *\n * @param {boolean} [regenerate = false] - A flag to determine if the key should be regenerated.\n */\n _generateKey(regenerate = false) {\n if (this.key === \"\" || regenerate) {\n this.key = Math.random()\n .toString(36)\n .replace(/[^a-z]+/g, \"\")\n .substring(0, 10);\n }\n }\n\n /**\n * Sets the IDs of the accordion and it's children if they do not already exist.\n *\n * The generated IDs use the key and follow the format:\n * - accordion: `accordion-${key}`\n *\n * @protected\n */\n _setIds() {\n this.dom.accordion.id = this.dom.accordion.id || `accordion-${this.key}`;\n }\n\n /**\n * Creates and initializes all accordion items.\n *\n * @protected\n */\n _createChildElements() {\n this.dom.accordionItems.forEach((accordionItem, index) => {\n const item = new AccordionItem({\n accordionItemElement: accordionItem,\n accordionItemToggleElement: this.dom.accordionItemToggles[index],\n accordionItemHeaderElement: this.dom.accordionItemHeaders[index],\n accordionItemContentElement: this.dom.accordionItemContents[index],\n parentAccordion: this,\n });\n\n item.initialize();\n\n this.elements.accordionItems.push(item);\n });\n }\n\n /**\n * Validates all aspects of the accordion item to ensure proper functionality.\n *\n * @protected\n *\n * @return {boolean} - The result of the validation.\n */\n _validate() {\n let check = true;\n\n // HTML element checks.\n const htmlElementChecks = isValidInstance(HTMLElement, {\n accordionElement: this.dom.accordion,\n });\n\n if (!htmlElementChecks) {\n this._errors.push(htmlElementChecks.message);\n check = false;\n }\n\n // Query selector checks.\n const querySelectorChecks = isQuerySelector({\n accordionItemSelector: this._selectors.accordionItems,\n accordionItemToggleSelector: this._selectors.accordionItemToggles,\n accordionItemHeaderSelector: this._selectors.accordionItemHeaders,\n accordionItemContentSelector: this._selectors.accordionItemContents,\n });\n\n if (!querySelectorChecks) {\n this._errors.push(querySelectorChecks.message);\n check = false;\n }\n\n // Class list checks.\n if (this._openClass !== \"\") {\n const openClassCheck = isValidClassList({ openClass: this._openClass });\n\n if (!openClassCheck.status) {\n this._errors.push(openClassCheck.error.message);\n check = false;\n }\n }\n\n if (this._closeClass !== \"\") {\n const closeClassCheck = isValidClassList({\n closeClass: this._closeClass,\n });\n\n if (!closeClassCheck.status) {\n this._errors.push(closeClassCheck.error.message);\n check = false;\n }\n }\n\n if (this._transitionClass !== \"\") {\n const transitionClassCheck = isValidClassList({\n transitionClass: this._transitionClass,\n });\n\n if (!transitionClassCheck.status) {\n this._errors.push(transitionClassCheck.error.message);\n check = false;\n }\n }\n\n // Transition duration check.\n const transitionDurationCheck = isValidType(\"number\", {\n transitionDuration: this._transitionDuration,\n });\n\n if (!transitionDurationCheck.status) {\n this._errors.push(transitionDurationCheck.error.message);\n check = false;\n }\n\n // Open duration check.\n const openDurationCheck = isValidType(\"number\", {\n openDuration: this._openDuration,\n });\n\n if (!openDurationCheck.status) {\n this._errors.push(openDurationCheck.error.message);\n check = false;\n }\n\n // Close duration check.\n const closeDurationCheck = isValidType(\"number\", {\n closeDuration: this._closeDuration,\n });\n\n if (!closeDurationCheck.status) {\n this._errors.push(closeDurationCheck.error.message);\n check = false;\n }\n\n // Boolean checks.\n const booleanCheck = isValidType(\"boolean\", {\n optionalKeySupport: this._optionalKeySupport,\n allowMultipleExpand: this._allowMultipleExpand,\n allowNoExpand: this._allowNoExpand,\n });\n\n if (!booleanCheck.status) {\n this._errors.push(booleanCheck.error.message);\n check = false;\n }\n\n // Key check.\n if (this._key !== \"\") {\n const keyCheck = isValidType(\"string\", { key: this._key });\n\n if (!keyCheck.status) {\n this._errors.push(keyCheck.error.message);\n check = false;\n }\n }\n\n // Prefix check.\n const prefixCheck = isValidType(\"string\", { prefix: this._prefix });\n\n if (!prefixCheck.status) {\n this._errors.push(prefixCheck.error.message);\n check = false;\n }\n\n return check;\n }\n\n /**\n * Handles focus events throughout the accordion for proper use.\n *\n * - Adds a `focus` listener to every accordion item so when it gains focus,\n * it will set the accordion's current child to the index of the item.\n *\n * @protected\n */\n _handleFocus() {\n this.elements.accordionItems.forEach((accordionItem, index) => {\n accordionItem.dom.toggle.addEventListener(\"focus\", () => {\n this.currentChild = index;\n });\n });\n }\n\n /**\n * Handles click events throughout the accordion item for proper use.\n *\n * - Adds a `pointerup` listener to the accordion item toggles that will toggle each accordion item.\n *\n * @protected\n */\n _handleClick() {\n this.elements.accordionItems.forEach((accordionItem, index) => {\n accordionItem.dom.toggle.addEventListener(\"pointerup\", () => {\n this.currentChild = index;\n accordionItem.toggle();\n });\n });\n }\n\n /**\n * Handles keydown events throughout the accordion item for proper use.\n *\n * This method exists to assist the _handleKeyup method.\n *\n * - Adds a `keydown` listener to all accordion item toggles.\n * - Blocks propagation on \"Space\" and \"Enter\" keys.\n * - _If_ optionalKeySupport is enabled, blocks propagation on the following keys:\n * - \"ArrowDown\", \"ArrowUp\", \"Home\", and \"End\".\n */\n _handleKeydown() {\n this.dom.accordionItemToggles.forEach((accordionToggle) => {\n accordionToggle.addEventListener(\"keydown\", (event) => {\n const key = keyPress(event);\n const ToggleKeys = [\"Space\", \"Enter\"];\n\n // Prevent default behavior for space and enter keys.\n if (ToggleKeys.includes(key)) {\n preventEvent(event);\n } else if (this.optionalKeySupport) {\n const optionalKeys = [\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"];\n\n if (optionalKeys.includes(key)) {\n preventEvent(event);\n }\n }\n });\n });\n }\n\n /**\n * Handles keyup events throughout the accordion item for proper use.\n *\n * Adds the follow keybindings (explanations are taken from the WAI ARIA Practices Guide Accordion Pattern):\n *\n * - `Enter` or `Space`:\n * - When focus is on the accordion header for a collapsed panel, expands the associated panel. If the implementation allows only one panel to be expanded, and if another panel is expanded, collapses that panel.\n * - When focus is on the accordion header for an expanded panel, collapses the panel if the implementation supports collapsing. Some implementations require one panel to be expanded at all times and allow only one panel to be expanded; so, they do not support a collapse function.\n * - `Tab`: Moves focus to the next focusable element; all focusable elements in the accordion are included in the page `Tab` sequence.\n * - `Shift + Tab`: Moves focus to the previous focusable element; all focusable elements in the accordion are included in the page `Tab` sequence.\n * - `Down Arrow` (Optional): If focus is on an accordion header, moves focus to the next accordion header. If focus is on the last accordion header, either does nothing or moves focus to the first accordion header.\n * - `Up Arrow` (Optional): If focus is on an accordion header, moves focus to the previous accordion header. If focus is on the first accordion header, either does nothing or moves focus to the last accordion header.\n * - `Home` (Optional): When focus is on an accordion header, moves focus to the first accordion header.\n * - `End` (Optional): When focus is on an accordion header, moves focus to the last accordion header.\n *\n * Note: When the above explanations mention \"accordion header\", they are referring to the accordion item toggle.\n */\n _handleKeyup() {\n this.dom.accordionItemToggles.forEach((accordionToggle) => {\n accordionToggle.addEventListener(\"keyup\", (event) => {\n const key = keyPress(event);\n\n switch (key) {\n case \"Space\":\n case \"Enter\":\n preventEvent(event);\n this.currentAccordionItem.toggle();\n\n break;\n }\n\n if (this.optionalKeySupport) {\n switch (key) {\n case \"Home\":\n preventEvent(event);\n this.focusFirstChild();\n\n break;\n case \"End\":\n preventEvent(event);\n this.focusLastChild();\n\n break;\n case \"ArrowDown\":\n preventEvent(event);\n this.focusNextChild();\n\n break;\n case \"ArrowUp\":\n preventEvent(event);\n this.focusPreviousChild();\n\n break;\n }\n }\n });\n });\n }\n\n /**\n * Sets the transition durations of the accordion as a CSS custom properties.\n *\n * The custom properties are:\n * - `--graupl-accordion-transition-duration`,\n * - `--graupl-accordion-open-transition-duration`, and\n * - `--graupl-accordion-close-transition-duration`.\n *\n * The prefix of `graupl-` can be changed by setting the accordion's prefix value.\n *\n * @protected\n */\n _setTransitionDurations() {\n this.dom.accordion.style.setProperty(\n `--${this.prefix}accordion-transition-duration`,\n `${this.transitionDuration}ms`\n );\n\n this.dom.accordion.style.setProperty(\n `--${this.prefix}accordion-open-transition-duration`,\n `${this.openDuration}ms`\n );\n\n this.dom.accordion.style.setProperty(\n `--${this.prefix}accordion-close-transition-duration`,\n `${this.closeDuration}ms`\n );\n }\n\n /**\n * Focus the accordion's current child.\n *\n * @public\n */\n focusCurrentChild() {\n if (this.currentChild !== -1) {\n this.currentAccordionItem.focus();\n }\n }\n\n /**\n * Focuses the accordion's child at a given index.\n *\n * @public\n *\n * @param {number} index - The index of the child to focus.\n */\n focusChild(index) {\n this.blurCurrentChild();\n this.currentChild = index;\n this.focusCurrentChild();\n }\n\n /**\n * Focuses the accordion's first child.\n *\n * @public\n */\n focusFirstChild() {\n this.focusChild(0);\n }\n\n /**\n * Focus the accordion's last child.\n *\n * @public\n */\n focusLastChild() {\n this.focusChild(this.elements.accordionItems.length - 1);\n }\n\n /**\n * Focus the accordion's next child.\n *\n * @public\n */\n focusNextChild() {\n if (this.currentChild < this.elements.accordionItems.length - 1) {\n this.focusChild(this.currentChild + 1);\n } else {\n this.focusCurrentChild();\n }\n }\n\n /**\n * Focus the accordion's previous child.\n *\n * @public\n */\n focusPreviousChild() {\n if (this.currentChild > 0) {\n this.focusChild(this.currentChild - 1);\n } else {\n this.focusCurrentChild();\n }\n }\n\n /**\n * Blurs the accordion's current child.\n *\n * @public\n */\n blurCurrentChild() {\n if (this.currentChild !== -1) {\n this.currentAccordionItem.blur();\n }\n }\n\n /**\n * Open all accordion items.\n *\n * @public\n */\n openChildren() {\n this.elements.accordionItems.forEach((item) => item.show());\n }\n\n /**\n * Close all accordion items.\n *\n * @public\n */\n closeChildren() {\n this.elements.accordionItems.forEach((item) => item.hide());\n }\n}\n\nexport default Accordion;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"accordion.es.js","names":["isValidInstance","constructor","elements","elementsType","TypeError","key","elementType","name","status","error","isValidType","type","values","valuesType","valueType","isQuerySelector","Error","document","querySelector","isValidClassList","Array","isArray","forEach","value","obj","isValidHoverType","validTypes","includes","join","isTag","tagName","HTMLElement","tag","toLowerCase","check","isValidState","validStates","isValidEvent","validEvents","addClass","className","element","length","classList","add","removeClass","remove","selectAllFocusableElements","context","document","querySelector","elements","Array","from","querySelectorAll","tabbableElements","filter","check","getAttribute","selectFirstFocusableElement","selectLastFocusableElement","selectNextFocusableElement","index","indexOf","selectPreviousFocusableElement","isTag","isValidType","addClass","removeClass","AccordionItem","_dom","item","toggle","header","content","_elements","parentAccordion","_open","_locked","_expandEvent","CustomEvent","bubbles","detail","_collapseEvent","constructor","accordionItemElement","accordionItemToggleElement","accordionItemHeaderElement","accordionItemContentElement","initialize","_setIds","_setAriaAttributes","dom","getAttribute","show","hide","elements","isOpen","isLocked","value","key","index","accordionItems","indexOf","id","setAttribute","emit","transition","closeClass","openClass","transitionClass","openDuration","requestAnimationFrame","style","height","getBoundingClientRect","setTimeout","allowMultipleExpand","unlockSiblings","closeSiblings","allowNoExpand","openAccordionItems","length","lock","dispatchEvent","closeDuration","focus","blur","unlock","removeAttribute","forEach","keyPress","event","key","keyCode","keys","Enter","Space","Escape","ArrowUp","ArrowRight","ArrowDown","ArrowLeft","Home","End","Tab","Object","find","preventEvent","preventDefault","stopPropagation","isValidType","initializeStorage","type","window","Graupl","getStorage","setStorage","data","clearStorage","pushToStorage","key","value","getFromStorage","removeFromStorage","AccordionItem","keyPress","preventEvent","isValidInstance","isValidType","isValidClassList","isQuerySelector","storage","Accordion","_dom","accordion","accordionItems","accordionItemToggles","accordionItemHeaders","accordionItemContents","_domLock","_selectors","_elements","_openClass","_closeClass","_transitionClass","_transitionDuration","_openDuration","_closeDuration","_optionalKeySupport","_allowMultipleExpand","_allowNoExpand","_currentChild","_prefix","_key","_errors","constructor","accordionElement","accordionItemSelector","accordionItemToggleSelector","accordionItemHeaderSelector","accordionItemContentSelector","openClass","closeClass","transitionClass","transitionDuration","openDuration","closeDuration","optionalKeySupport","allowMultipleExpand","allowNoExpand","prefix","key","initialize","_validate","Error","errors","join","_generateKey","_setDOMElements","_setIds","_createChildElements","_handleFocus","_handleClick","_handleKeydown","_handleKeyup","_setTransitionDurations","initializeStorage","pushToStorage","dom","id","error","console","currentChild","elements","selectors","currentAccordionItem","openAccordionItems","filter","item","isOpen","value","length","isArray","every","_accordionItems","_setDOMElementType","elementType","base","overwrite","strict","includes","name","HTMLElement","domElements","Array","from","querySelectorAll","filteredElements","parentElement","_resetDOMElementType","forEach","accordionItem","regenerate","Math","random","toString","replace","substring","index","accordionItemElement","accordionItemToggleElement","accordionItemHeaderElement","accordionItemContentElement","parentAccordion","push","check","htmlElementChecks","message","querySelectorChecks","openClassCheck","status","closeClassCheck","transitionClassCheck","transitionDurationCheck","openDurationCheck","closeDurationCheck","booleanCheck","keyCheck","prefixCheck","toggle","addEventListener","accordionToggle","event","ToggleKeys","optionalKeys","focusFirstChild","focusLastChild","focusNextChild","focusPreviousChild","style","setProperty","focusCurrentChild","focus","focusChild","blurCurrentChild","blur","openChildren","show","closeChildren","hide"],"sources":["../../../src/js/validate.js","../../../src/js/domHelpers.js","../../../src/js/accordion/AccordionItem.js","../../../src/js/eventHandlers.js","../../../src/js/storage.js","../../../src/js/accordion/Accordion.js"],"sourcesContent":["/**\n * Check to see if the provided elements have a specific constructor.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * This is essentially just a wrapper function around checking instanceof with\n * more descriptive error message to help debugging.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {object} constructor - The constructor to check for.\n * @param {object} elements - The element(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidInstance(constructor, elements) {\n try {\n if (typeof elements !== \"object\") {\n const elementsType = typeof elements;\n\n throw new TypeError(\n `Elements given to isValidInstance() must be inside of an object. \"${elementsType}\" given.`\n );\n }\n\n for (const key in elements) {\n if (!(elements[key] instanceof constructor)) {\n const elementType = typeof elements[key];\n throw new TypeError(\n `${key} must be an instance of ${constructor.name}. \"${elementType}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Check to see if the provided values are of a specific type.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * This is essentially just a wrapper function around checking typeof with\n * more descriptive error message to help debugging.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {string} type - The type to check for.\n * @param {object} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidType(type, values) {\n try {\n if (typeof values !== \"object\") {\n const valuesType = typeof values;\n\n throw new TypeError(\n `Values given to isValidType() must be inside of an object. \"${valuesType}\" given.`\n );\n }\n\n for (const key in values) {\n const valueType = typeof values[key];\n\n if (valueType !== type) {\n throw new TypeError(`${key} must be a ${type}. \"${valueType}\" given.`);\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Checks to see if the provided values are valid query selectors.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isQuerySelector(values) {\n try {\n if (typeof values !== \"object\") {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isQuerySelector() must be inside of an object. \"${type}\" given.`\n );\n }\n\n for (const key in values) {\n try {\n if (values[key] === null) {\n throw new Error();\n }\n\n document.querySelector(values[key]);\n } catch {\n throw new TypeError(\n `${key} must be a valid query selector. \"${values[key]}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Checks to see if the provided value is either a string or an array of strings.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string, string[]>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidClassList(values) {\n try {\n if (typeof values !== \"object\" || Array.isArray(values)) {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isValidClassList() must be inside of an object. \"${type}\" given.`\n );\n }\n\n for (const key in values) {\n const type = typeof values[key];\n\n if (type !== \"string\") {\n if (Array.isArray(values[key])) {\n values[key].forEach((value) => {\n if (typeof value !== \"string\") {\n throw new TypeError(\n `${key} must be a string or an array of strings. An array containing non-strings given.`\n );\n }\n });\n } else {\n throw new TypeError(\n `${key} must be a string or an array of strings. \"${type}\" given.`\n );\n }\n } else {\n const obj = {};\n obj[key] = values[key];\n\n isQuerySelector(obj);\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Check to see if the provided values are valid hover types.\n *\n * Available types are: `\"off\"`, `\"on\"`, and `\"dynamic\"`.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidHoverType(values) {\n try {\n if (typeof values !== \"object\") {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isValidHoverType() must be inside of an object. \"${type}\" given.`\n );\n }\n\n const validTypes = [\"off\", \"on\", \"dynamic\"];\n\n for (const key in values) {\n if (!validTypes.includes(values[key])) {\n throw new TypeError(\n `${key} must be one of the following values: ${validTypes.join(\n \", \"\n )}. \"${values[key]}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Checks to see if the provided elements are using a specific tag.\n *\n * The elements must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `true` if the check is successful.\n *\n * @param {string} tagName - The name of the tag.\n * @param {Object<HTMLElement>} elements - The element(s) to check.\n * @return {boolean} - The result of the check.\n */\nexport function isTag(tagName, elements) {\n if (\n isValidType(\"string\", { tagName }).status &&\n isValidInstance(HTMLElement, elements).status\n ) {\n const tag = tagName.toLowerCase();\n let check = true;\n\n for (const key in elements) {\n if (elements[key].tagName.toLowerCase() !== tag) check = false;\n }\n\n return check;\n } else {\n return false;\n }\n}\n\n/**\n * Check to see if the provided values are valid focus states for a menu.\n *\n * Available states are: `\"none\"`, `\"self\"`, and `\"child\"`.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidState(values) {\n try {\n if (typeof values !== \"object\") {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isValidState() must be inside of an object. \"${type}\" given.`\n );\n }\n\n const validStates = [\"none\", \"self\", \"child\"];\n\n for (const key in values) {\n if (!validStates.includes(values[key])) {\n throw new TypeError(\n `${key} must be one of the following values: ${validStates.join(\n \", \"\n )}. \"${values[key]}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n\n/**\n * Check to see if the provided values are valid event types for a menu.\n *\n * Available events are: `\"none\"`, `\"mouse\"`, `\"keyboard\"`, and `\"character\"`.\n *\n * The values must be provided inside of an object\n * so the variable name can be retrieved in case of errors.\n *\n * Will return `{ status: true }` if the check is successful.\n *\n * @param {Object<string>} values - The value(s) to check.\n * @return {Object<boolean, string>} - The result of the check.\n */\nexport function isValidEvent(values) {\n try {\n if (typeof values !== \"object\") {\n const type = typeof values;\n\n throw new TypeError(\n `Values given to isValidEvent() must be inside of an object. \"${type}\" given.`\n );\n }\n\n const validEvents = [\"none\", \"mouse\", \"keyboard\", \"character\"];\n\n for (const key in values) {\n if (!validEvents.includes(values[key])) {\n throw new TypeError(\n `${key} must be one of the following values: ${validEvents.join(\n \", \"\n )}. \"${values[key]}\" given.`\n );\n }\n }\n\n return {\n status: true,\n error: null,\n };\n } catch (error) {\n return {\n status: false,\n error,\n };\n }\n}\n","/**\n * Add a class or array of classes to an element.\n *\n * @param {string|string[]} className - The class or classes to add.\n * @param {HTMLElement} element - The element to add the class to.\n */\nexport function addClass(className, element) {\n // Gracefully handle empty strings or arrays.\n if (className === \"\" || className.length === 0) {\n return;\n }\n\n if (typeof className === \"string\") {\n element.classList.add(className);\n } else {\n element.classList.add(...className);\n }\n}\n\n/**\n * Remove a class or array of classes from an element.\n *\n * @param {string|string[]} className - The class or classes to remove.\n * @param {HTMLElement} element - The element to remove the class from.\n */\nexport function removeClass(className, element) {\n // Gracefully handle empty strings or arrays.\n if (className === \"\" || className.length === 0) {\n return;\n }\n\n if (typeof className === \"string\") {\n element.classList.remove(className);\n } else {\n element.classList.remove(...className);\n }\n}\n\n/**\n * Select all focusable elements within a given context.\n *\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement[]} - An array of focusable elements.\n */\nexport function selectAllFocusableElements(context = document) {\n const querySelector =\n \"a[href],area[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),button:not([disabled]),[tabindex]\";\n const elements = Array.from(context.querySelectorAll(querySelector));\n\n const tabbableElements = elements.filter((element) => {\n let check = true;\n\n if (element.getAttribute(\"tabindex\") === \"-1\") check = false;\n\n return check;\n });\n\n return tabbableElements;\n}\n\n/**\n * Select the first focusable element within a given context.\n *\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement|boolean} - The first focusable element or false if none found.\n */\nexport function selectFirstFocusableElement(context = document) {\n const tabbableElements = selectAllFocusableElements(context);\n\n return tabbableElements[0] || false;\n}\n\n/**\n * Select the last focusable element within a given context.\n *\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement|boolean} - The last focusable element or false if none found.\n */\nexport function selectLastFocusableElement(context = document) {\n const tabbableElements = selectAllFocusableElements(context);\n\n return tabbableElements[tabbableElements.length - 1] || false;\n}\n\n/**\n * Select the next focusable element relative to the given element within a context.\n *\n * @param {HTMLElement} element - The reference element.\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement|boolean} - The next focusable element or false if none found.\n */\nexport function selectNextFocusableElement(element, context = document) {\n const tabbableElements = selectAllFocusableElements(context);\n const index = tabbableElements.indexOf(element);\n\n return index === tabbableElements.length - 1\n ? false\n : tabbableElements[index + 1];\n}\n\n/**\n * Select the previous focusable element relative to the given element within a context.\n *\n * @param {HTMLElement} element - The reference element.\n * @param {HTMLElement} [context = document] - The context in which to search for focusable elements.\n * @return {HTMLElement|boolean} - The previous focusable element or false if none found.\n */\nexport function selectPreviousFocusableElement(element, context = document) {\n const tabbableElements = selectAllFocusableElements(context);\n const index = tabbableElements.indexOf(element);\n\n return index === 0 ? false : tabbableElements[index - 1];\n}\n","/**\n * @file\n * The Accordion Item class.\n */\n\n/* global Accordion */\n\nimport { isTag, isValidType } from \"../validate.js\";\nimport { addClass, removeClass } from \"../domHelpers.js\";\n\n/**\n * Creates a new accordion item.\n *\n * @class\n */\nclass AccordionItem {\n /**\n * The HTML elements for the accordion item in the DOM.\n *\n * @protected\n *\n * @type {Object<HTMLElement>}\n *\n * @property {HTMLElement} item - The accordion item element.\n * @property {HTMLElement} toggle - The controller element.\n * @property {HTMLElement} header - The header element.\n * @property {HTMLElement} content - The content element.\n */\n _dom = {\n item: null,\n toggle: null,\n header: null,\n content: null,\n };\n\n /**\n * The declared graupl accordion elements within the accordion item.\n *\n * @protected\n *\n * @type {Object<Accordion>}\n *\n * @property {Accordion} parentAccordion - The parent accordion containing this item.\n */\n _elements = {\n parentAccordion: null,\n };\n\n /**\n * The open state of the accordion.\n *\n * @protected\n *\n * @type {boolean}\n */\n _open = false;\n\n /**\n * The locked state of the accordions item.\n *\n * If locked, the accordion item cannot be closed.\n *\n * @protected\n *\n * @type {boolean}\n */\n _locked = false;\n\n /**\n * The event that is triggered when the accordion item is shown.\n *\n * @protected\n *\n * @event grauplAccordionItemExpand\n *\n * @type {CustomEvent}\n *\n * @property {boolean} bubbles - A flag to bubble the event.\n * @property {Object<AccordionItem>} detail - The details object containing the Accordion item itself.\n */\n _expandEvent = new CustomEvent(\"grauplAccordionItemExpand\", {\n bubbles: true,\n detail: { item: this },\n });\n\n /**\n * The event that is triggered when the accordion item is hidden.\n *\n * @protected\n *\n * @event grauplAccordionItemCollapse\n *\n * @type {CustomEvent}\n *\n * @property {boolean} bubbles - A flag to bubble the event.\n * @property {Object<AccordionItem>} detail - The details object containing the Accordion item itself.\n */\n _collapseEvent = new CustomEvent(\"grauplAccordionItemCollapse\", {\n bubbles: true,\n detail: { item: this },\n });\n\n /**\n * Constructs a new Accordion item object.\n *\n * @class\n *\n * @param {object} options - The options object.\n * @param {HTMLElement} options.accordionItemElement - The accordion item element.\n * @param {HTMLElement} options.accordionItemToggleElement - The toggle element.\n * @param {HTMLElement} options.accordionItemHeaderElement - The header element.\n * @param {HTMLElement} options.accordionItemContentElement - The content element.\n * @param {Accordion} [options.parentAccordion = null] - The accordion containing this item.\n */\n constructor({\n accordionItemElement,\n accordionItemToggleElement,\n accordionItemHeaderElement,\n accordionItemContentElement,\n parentAccordion = null,\n }) {\n // Set DOM elements.\n this._dom.item = accordionItemElement;\n this._dom.toggle = accordionItemToggleElement;\n this._dom.header = accordionItemHeaderElement;\n this._dom.content = accordionItemContentElement;\n\n // Set the accordion elements.\n this._elements.parentAccordion = parentAccordion;\n }\n\n /**\n * Initializes the accordion item.\n */\n initialize() {\n // Set the IDs for the accordion item and it's elements if they don't exist.\n this._setIds();\n\n // Set the ARIA attributes for the accordion item and it's elements.\n this._setAriaAttributes();\n\n // Set the initial state of the accordion item.\n if (this.dom.toggle.getAttribute(\"aria-expanded\") === \"true\") {\n this.show(false, false);\n } else {\n this.hide(false, false);\n }\n }\n\n /**\n * The HTML elements for the accordion item in the DOM.\n *\n * @readonly\n *\n * @type {object}\n *\n * @see _dom\n */\n get dom() {\n return this._dom;\n }\n\n /**\n * The declared graupl accordion elements within the accordion item.\n *\n * @readonly\n *\n * @type {Object<Accordion>}\n *\n * @see _elements\n */\n get elements() {\n return this._elements;\n }\n\n /**\n * The open state of the accordion.\n *\n * @readonly\n *\n * @type {object}\n *\n * @see _open\n */\n get isOpen() {\n return this._open;\n }\n\n /**\n * The locked state of the accordions item.\n *\n * If locked, the accordion item cannot be closed.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _locked\n */\n get isLocked() {\n return this._locked;\n }\n\n set isOpen(value) {\n isValidType(\"boolean\", { value });\n\n if (this._open !== value) {\n this._open = value;\n }\n }\n\n /**\n * Sets the IDs for the accordion item and it's elements if they don't exist.\n *\n * The generated IDs use the parent accordion's key and follows the pattern:\n * - Accordion item: `accordion-item-{key}-{index}`\n * - Accordion item toggle: `accordion-item-toggle-{key}-{index}`\n * - Accordion item content: `accordion-item-content-{key}-{index}`\n */\n _setIds() {\n // Get the required information for IDs.\n const { key } = this.elements.parentAccordion;\n const index = this.elements.parentAccordion.dom.accordionItems.indexOf(\n this.dom.item\n );\n\n this.dom.item.id = this.dom.item.id || `accordion-item-${key}-${index}`;\n this.dom.toggle.id =\n this.dom.toggle.id || `accordion-item-toggle-${key}-${index}`;\n this.dom.header.id =\n this.dom.header.id || `accordion-item-header-${key}-${index}`;\n this.dom.content.id =\n this.dom.content.id || `accordion-item-content-${key}-${index}`;\n }\n\n /**\n * Sets the ARIA attributes for the accordion item and it's elements.\n */\n _setAriaAttributes() {\n // Set the ARIA attributes for the accordion item toggle.\n // If the toggle is not a button, then set the role to \"button\".\n if (!isTag(\"button\", { toggle: this.dom.toggle })) {\n this.dom.toggle.setAttribute(\"role\", \"button\");\n }\n\n // If aria-expanded is not explicitly set to \"true\", then set it to \"false\".\n if (this.dom.toggle.getAttribute(\"aria-expanded\") !== \"true\") {\n this.dom.toggle.setAttribute(\"aria-expanded\", \"false\");\n }\n\n // Set the aria-controls attribute for the toggle.\n this.dom.toggle.setAttribute(\"aria-controls\", this.dom.content.id);\n\n // Set the ARIA attributes for the accordion item content.\n // If the content is not a section, then set the role to \"region\".\n if (!isTag(\"section\", { content: this.dom.content })) {\n this.dom.content.setAttribute(\"role\", \"region\");\n }\n\n // Set the aria-labelledby attribute for the content.\n this.dom.content.setAttribute(\"aria-labelledby\", this.dom.toggle.id);\n }\n\n /**\n * Shows the accordion item.\n *\n * @public\n *\n * @fires grauplAccordionItemExpand\n *\n * @param {boolean} [emit = true] - Emit the show event once shown.\n * @param {boolean} [transition = true] - Respect the transition class.\n */\n show(emit = true, transition = true) {\n if (this._open) {\n return;\n }\n\n const { closeClass, openClass, transitionClass, openDuration } =\n this.elements.parentAccordion;\n\n // Set aria-expanded to true when hiding accordion item.\n this.dom.toggle.setAttribute(\"aria-expanded\", \"true\");\n\n // If we're dealing with transition classes, then we need to utilize\n // requestAnimationFrame to add the transition class, remove the hide class,\n // add the show class, and finally remove the transition class.\n //\n // If `transition` is false, then it doesn't matter if the transition class\n // is set. Do not use the transition.\n if (transition && transitionClass !== \"\") {\n addClass(transitionClass, this.dom.item);\n\n requestAnimationFrame(() => {\n removeClass(closeClass, this.dom.item);\n\n this.dom.item.style.height = `${this.dom.header.getBoundingClientRect().height}px`;\n\n requestAnimationFrame(() => {\n addClass(openClass, this.dom.item);\n\n this.dom.item.style.height = `${this.dom.header.getBoundingClientRect().height + this.dom.content.getBoundingClientRect().height}px`;\n\n requestAnimationFrame(() => {\n setTimeout(() => {\n removeClass(transitionClass, this.dom.item);\n\n this.dom.item.style.height = \"\";\n }, openDuration);\n });\n });\n });\n } else {\n // Add the show class\n addClass(openClass, this.dom.item);\n\n // Remove the hide class.\n removeClass(closeClass, this.dom.item);\n }\n\n this._open = true;\n\n // If the parent accordion only allows a single item to be open at a time,\n // then close all other items.\n if (!this.elements.parentAccordion.allowMultipleExpand) {\n this.unlockSiblings();\n this.closeSiblings();\n }\n\n // If the parent accordion requires at least one item to be open, and this\n // is the only open item, then lock it. Otherwise, unlock all siblings.\n if (!this.elements.parentAccordion.allowNoExpand) {\n if (this.elements.parentAccordion.openAccordionItems.length <= 1) {\n this.lock();\n } else {\n this.unlockSiblings();\n }\n }\n\n if (emit) {\n this.dom.item.dispatchEvent(this._expandEvent);\n }\n }\n\n /**\n * Hides the accordion item.\n *\n * @public\n *\n * @fires grauplAccordionItemCollapse\n *\n * @param {boolean} [emit = true] - Emit the show event once shown.\n * @param {boolean} [transition = true] - Respect the transition class.\n */\n hide(emit = true, transition = true) {\n if (!this._open) {\n return;\n }\n\n if (\n !this.elements.parentAccordion.allowNoExpand &&\n this.elements.parentAccordion.openAccordionItems.length <= 1\n ) {\n return;\n }\n\n const { closeClass, openClass, transitionClass, closeDuration } =\n this.elements.parentAccordion;\n\n // Set aria-expanded to false when hiding accordion item.\n this.dom.toggle.setAttribute(\"aria-expanded\", \"false\");\n\n // If we're dealing with transition classes, then we need to utilize\n // requestAnimationFrame to add the transition class, remove the show class,\n // add the hide class, and finally remove the transition class.\n //\n // If `transition` is false, then it doesn't matter if the transition class\n // is set. Do not use the transition.\n if (transition && transitionClass !== \"\") {\n addClass(transitionClass, this.dom.item);\n this.dom.item.style.height = `${this.dom.item.getBoundingClientRect().height}px`;\n\n requestAnimationFrame(() => {\n removeClass(openClass, this.dom.item);\n this.dom.item.style.height = `${this.dom.header.getBoundingClientRect().height}px`;\n\n requestAnimationFrame(() => {\n addClass(closeClass, this.dom.item);\n\n requestAnimationFrame(() => {\n setTimeout(() => {\n removeClass(transitionClass, this.dom.item);\n\n this.dom.item.style.height = \"\";\n }, closeDuration);\n });\n });\n });\n } else {\n // Add the hide class\n addClass(closeClass, this.dom.item);\n\n // Remove the show class.\n removeClass(openClass, this.dom.item);\n }\n\n this._open = false;\n\n // If the parent accordion requires at least one item to be open, and this was\n // the second to last open item, then lock to last open item.\n if (\n !this.elements.parentAccordion.allowNoExpand &&\n this.elements.parentAccordion.openAccordionItems.length === 1\n ) {\n this.elements.parentAccordion.openAccordionItems[0].lock();\n }\n\n if (emit) {\n this.dom.item.dispatchEvent(this._collapseEvent);\n }\n }\n\n /**\n * Toggle the accordion item.\n *\n * @public\n */\n toggle() {\n this.isOpen ? this.hide() : this.show();\n }\n\n /**\n * Focuses the accordion item.\n *\n * @public\n */\n focus() {\n this.dom.toggle.focus();\n }\n\n /**\n * Blurs the accordion item.\n *\n * @public\n */\n blur() {\n this.dom.toggle.blur();\n }\n\n /**\n * Locks the accordion item.\n *\n * @public\n */\n lock() {\n this._locked = true;\n this.dom.toggle.setAttribute(\"disabled\", \"true\");\n }\n\n /**\n * Unlocks the accordion item.\n *\n * @public\n */\n unlock() {\n this._locked = false;\n this.dom.toggle.removeAttribute(\"disabled\");\n }\n\n closeSiblings() {\n if (this.elements.parentAccordion) {\n this.elements.parentAccordion.elements.accordionItems.forEach((item) => {\n if (item !== this) {\n item.hide();\n }\n });\n }\n }\n\n /**\n * Unlocks the siblings of the accordion item.\n *\n * @public\n */\n unlockSiblings() {\n if (this.elements.parentAccordion) {\n this.elements.parentAccordion.elements.accordionItems.forEach((item) => {\n if (item !== this) {\n item.unlock();\n }\n });\n }\n }\n}\n\nexport default AccordionItem;\n","/**\n * Retrieves the pressed key from an event.\n *\n * @param {KeyboardEvent} event - The keyboard event.\n * @return {string} - The name of the key or an empty string.\n */\nexport function keyPress(event) {\n try {\n // Use event.key or event.keyCode to support older browsers.\n const key = event.key || event.keyCode;\n const keys = {\n Enter: key === \"Enter\" || key === 13,\n Space: key === \" \" || key === \"Spacebar\" || key === 32,\n Escape: key === \"Escape\" || key === \"Esc\" || key === 27,\n ArrowUp: key === \"ArrowUp\" || key === \"Up\" || key === 38,\n ArrowRight: key === \"ArrowRight\" || key === \"Right\" || key === 39,\n ArrowDown: key === \"ArrowDown\" || key === \"Down\" || key === 40,\n ArrowLeft: key === \"ArrowLeft\" || key === \"Left\" || key === 37,\n Home: key === \"Home\" || key === 36,\n End: key === \"End\" || key === 35,\n Tab: key === \"Tab\" || key === 9,\n };\n\n return Object.keys(keys).find((key) => keys[key] === true) || \"\";\n } catch {\n // Return an empty string if something goes wrong.\n return \"\";\n }\n}\n\n/**\n * Stops an event from taking action.\n *\n * @param {Event} event - The event.\n */\nexport function preventEvent(event) {\n event.preventDefault();\n event.stopPropagation();\n}\n","/**\n * @file\n * Provides a system to get and store Graupl data in the browser.\n */\n\nimport { isValidType } from \"./validate.js\";\n\n/**\n * Initializes the storage system.\n *\n * @param {?string} [type = null] - The type of storage to initialize.\n */\nexport function initializeStorage(type = null) {\n window.Graupl = window.Graupl || {};\n\n if (isValidType(\"string\", { type })) {\n window.Graupl[type] = window.Graupl[type] || {};\n }\n}\n\n/**\n * Get the storage object.\n *\n * @param {?string} type - The type of storage to get.\n * @return {object} - The storage object.\n */\nexport function getStorage(type = null) {\n if (isValidType(\"string\", { type })) {\n return window.Graupl[type];\n }\n\n return window.Graupl;\n}\n\n/**\n * Set the storage object of a given type.\n *\n * @param {string} type - The type of storage to set.\n * @param {object} data - The data to set.\n */\nexport function setStorage(type, data = {}) {\n if (isValidType(\"string\", { type }) && isValidType(\"object\", { data })) {\n window.Graupl[type] = data;\n }\n}\n\n/**\n * Clear the storage object of a given type.\n *\n * @param {string} type - The type of storage to clear.\n */\nexport function clearStorage(type) {\n if (isValidType(\"string\", { type })) {\n window.Graupl[type] = {};\n }\n}\n\n/**\n * Push a value to the storage object.\n *\n * @param {string} type - The type of storage to push to.\n * @param {string} key - The key to use for the value.\n * @param {*} value - The value to store.\n */\nexport function pushToStorage(type, key, value) {\n if (isValidType(\"string\", { type, key })) {\n window.Graupl[type][key] = value;\n }\n}\n\n/**\n * Get a value from the storage object.\n *\n * @param {string }type - The type of storage to get from.\n * @param {string }key - The key to get the value from.\n * @return {*} - The value from the storage object.\n */\nexport function getFromStorage(type, key) {\n if (isValidType(\"string\", { type, key })) {\n return window.Graupl[type][key];\n }\n\n return null;\n}\n\n/**\n * Remove a value from the storage object.\n *\n * @param {string} type - The type of storage to remove from.\n * @param {string} key - The key to remove the value from.\n */\nexport function removeFromStorage(type, key) {\n if (isValidType(\"string\", { type, key })) {\n delete window.Graupl[type][key];\n }\n}\n\nexport default {\n initializeStorage,\n getStorage,\n setStorage,\n clearStorage,\n pushToStorage,\n getFromStorage,\n removeFromStorage,\n};\n","/**\n * @file\n * The Accordion class.\n */\n\nimport AccordionItem from \"./AccordionItem.js\";\nimport { keyPress, preventEvent } from \"../eventHandlers.js\";\nimport {\n isValidInstance,\n isValidType,\n isValidClassList,\n isQuerySelector,\n} from \"../validate.js\";\nimport storage from \"../storage.js\";\n\nclass Accordion {\n /**\n * The DOM elements within the accordion.\n *\n * @protected\n *\n * @type {Object<HTMLElement, HTMLElement[]>}\n *\n * @property {HTMLElement} accordion - The accordion element.\n * @property {HTMLElement[]} accordionItems - An array of accordion items.\n * @property {HTMLElement[]} accordionItemToggles - An array of accordion item toggles.\n * @property {HTMLElement[]} accordionItemHeaders - An array of accordion headers.\n * @property {HTMLElement[]} accordionItemContents - An array of accordion item contents.\n */\n _dom = {\n accordion: null,\n accordionItems: [],\n accordionItemToggles: [],\n accordionItemHeaders: [],\n accordionItemContents: [],\n };\n\n /**\n * The DOM elements within the accordion that cannot be reset or generated by the accordion.\n *\n * @protected\n *\n * @type {string[]}\n */\n _domLock = [\"accordion\"];\n\n /**\n * The query selectors used by the accordion.\n *\n * @protected\n *\n * @type {Object<string>}\n *\n * @property {string} accordionItems - The query selector for accordion items.\n * @property {string} accordionItemToggles - The query selector for accordion toggles.\n * @property {string} accordionItemHeaders - The query selector for accordion headers.\n * @property {string} accordionItemContents - The query selector for accordion contents.\n */\n _selectors = {\n accordionItems: \"\",\n accordionItemToggles: \"\",\n accordionItemHeaders: \"\",\n accordionItemContents: \"\",\n };\n\n /**\n * The list of accordion items.\n *\n * @protected\n *\n * @type {Object<AccordionItem[]>}\n *\n * @property {AccordionItem[]} accordionItems - The list of accordion items.\n */\n _elements = {\n accordionItems: [],\n };\n\n /**\n * The class(es) to apply when the accordion is open.\n *\n * @protected\n *\n * @type {string|string[]}\n */\n _openClass = \"show\";\n\n /**\n * The class(es) to apply when the accordion is closed.\n *\n * @protected\n *\n * @type {string|string[]}\n */\n _closeClass = \"hide\";\n\n /**\n * The class(es) to apply when the accordion is transitioning between states.\n *\n * @protected\n *\n * @type {string|string[]}\n */\n _transitionClass = \"transitioning\";\n\n /**\n * The duration time (in milliseconds) for the transition between open and closed states.\n *\n * @protected\n *\n * @type {number}\n */\n _transitionDuration = 300;\n\n /**\n * The duration time (in milliseconds) for the transition from closed to open states.\n *\n * @protected\n *\n * @type {number}\n */\n _openDuration = -1;\n\n /**\n * The duration time (in milliseconds) for the transition from open to closed states.\n *\n * @protected\n *\n * @type {number}\n */\n _closeDuration = -1;\n\n /**\n * A flag to decide if the accordion items can be navigated by arrows.\n *\n * @protected\n *\n * @type {boolean}\n */\n _optionalKeySupport = true;\n\n /**\n * A flag to decide if multiple accordions can be open at the same time.\n *\n * If set to false, only one accordion can be open at a time.\n *\n * @protected\n *\n * @type {boolean}\n */\n _allowMultipleExpand = true;\n\n /**\n * A flag to decide if no accordions can be opened at the same time.\n *\n * If set to false, at least one accordion must be open at all times.\n *\n * @protected\n *\n * @type {boolean}\n */\n _allowNoExpand = true;\n\n /**\n * The index of the current child node.\n *\n * @protected\n *\n * @type {number}\n */\n _currentChild = 0;\n\n /**\n * The prefix to use for CSS custom properties.\n *\n * @protected\n *\n * @type {string}\n */\n _prefix = \"graupl-\";\n\n /**\n * The key used to generate IDs throughout the accordion.\n *\n * @protected\n *\n * @type {string}\n */\n _key = \"\";\n\n /**\n * errors - The list of errors found during validation.\n *\n * @protected\n *\n * @type {string[]}\n */\n _errors = [];\n\n /**\n * Constructs a new `Accordion`.\n *\n * @param {object} options - The options for generating the accordion.\n * @param {HTMLElement} [options.accordionElement] - The accordion element in the DOM.\n * @param {string} [options.accordionItemSelector = .accordion-item] - The query selector string for accordion items.\n * @param {string} [options.accordionItemToggleSelector = .accordion-item-toggle] - The query selector string for accordion toggle.\n * @param {string} [options.accordionItemHeaderSelector = .accordion-item-header] - The query selector string for accordion header.\n * @param {string} [options.accordionItemContentSelector = .accordion-item-content] - The query selector string for accordion content.\n * @param {?(string|string[])} [options.openClass = show] - The class to apply when a accordion is \"open\".\n * @param {?(string|string[])} [options.closeClass = hide] - The class to apply when a accordion is \"closed\".\n * @param {?(string|string[])} [options.transitionClass = transitioning] - The class to apply when a accordion is transitioning between \"open\" and \"closed\" states.\n * @param {number} [options.transitionDuration = 300] - The duration of the transition between \"open\" and \"closed\" states (in milliseconds).\n * @param {number} [options.openDuration = -1] - The duration of the transition from \"closed\" to \"open\" states (in milliseconds).\n * @param {number} [options.closeDuration = -1] - The duration of the transition from \"open\" to \"closed\" states (in milliseconds).\n * @param {boolean} [options.optionalKeySupport = false] - A flag to determine if accordions can be navigated with arrows.\n * @param {boolean} [options.allowMultipleExpand = true] - A flag to determine if multiple accordions can be open at the same time.\n * @param {boolean} [options.allowNoExpand = true] - A flag to determine if no accordions can be open at the same time.\n * @param {?string} [options.prefix = graupl-] - The prefix to use for CSS custom properties.\n * @param {?string} [options.key = null] - The key used to generate IDs throughout the accordion.\n * @param {boolean} [options.initialize = false] - A flag to initialize the accordion immediately upon creation.\n */\n constructor({\n accordionElement,\n accordionItemSelector = \".accordion-item\",\n accordionItemToggleSelector = \".accordion-item-toggle\",\n accordionItemHeaderSelector = \".accordion-item-header\",\n accordionItemContentSelector = \".accordion-item-content\",\n openClass = \"show\",\n closeClass = \"hide\",\n transitionClass = \"transitioning\",\n transitionDuration = 300,\n openDuration = -1,\n closeDuration = -1,\n optionalKeySupport = false,\n allowMultipleExpand = true,\n allowNoExpand = true,\n prefix = \"graupl-\",\n key = null,\n initialize = false,\n }) {\n // Set DOM elements.\n this._dom.accordion = accordionElement;\n\n // Set DOM selectors.\n this._selectors.accordionItems = accordionItemSelector;\n this._selectors.accordionItemToggles = accordionItemToggleSelector;\n this._selectors.accordionItemHeaders = accordionItemHeaderSelector;\n this._selectors.accordionItemContents = accordionItemContentSelector;\n\n // Set open/close classes.\n this._openClass = openClass || \"\";\n this._closeClass = closeClass || \"\";\n this._transitionClass = transitionClass || \"\";\n\n // Set transition duration.\n this._transitionDuration = transitionDuration;\n this._openDuration = openDuration;\n this._closeDuration = closeDuration;\n\n // Set optional key support.\n this._optionalKeySupport = optionalKeySupport;\n\n // Set expand rules.\n this._allowMultipleExpand = allowMultipleExpand;\n this._allowNoExpand = allowNoExpand;\n\n // Set prefix.\n this._prefix = prefix || \"\";\n\n // Set the key.\n this._key = key || \"\";\n\n if (initialize) {\n this.initialize();\n }\n }\n\n /**\n * Initializes the accordion.\n */\n initialize() {\n try {\n if (!this._validate()) {\n throw new Error(\n `Graupl Accordion: cannot initialize accordion. The following errors have been found:\\n - ${this.errors.join(\n \"\\n - \"\n )}`\n );\n }\n\n // Set up the DOM.\n this._generateKey();\n this._setDOMElements();\n this._setIds();\n\n // Create the child elements.\n this._createChildElements();\n\n // Handle events.\n this._handleFocus();\n this._handleClick();\n this._handleKeydown();\n this._handleKeyup();\n\n // Set the custom props.\n this._setTransitionDurations();\n\n // Set up the storage.\n storage.initializeStorage(\"accordions\");\n storage.pushToStorage(\"accordions\", this.dom.accordion.id, this);\n } catch (error) {\n console.error(error);\n }\n }\n\n /**\n * The class(es) to apply when the accordion is open.\n *\n * @type {string|string[]}\n *\n * @see _openClass\n */\n get openClass() {\n return this._openClass;\n }\n\n /**\n * The class(es) to apply when the accordion is closed.\n *\n * @type {string|string[]}\n *\n * @see _closeClass\n */\n get closeClass() {\n return this._closeClass;\n }\n\n /**\n * The class(es) to apply when the accordion is transitioning between open and closed.\n *\n * @type {string|string[]}\n *\n * @see _transitionClass\n */\n get transitionClass() {\n return this._transitionClass;\n }\n\n /**\n * The duration time (in milliseconds) for the transition between open and closed states.\n *\n * @type {number}\n *\n * @see _transitionDuration\n */\n get transitionDuration() {\n return this._transitionDuration;\n }\n\n /**\n * The duration time (in milliseconds) for the transition from closed to open states.\n *\n * If openDuration is set to -1, the transitionDuration will be used instead.\n *\n * @type {number}\n *\n * @see _openDuration\n */\n get openDuration() {\n return this._openDuration === -1\n ? this.transitionDuration\n : this._openDuration;\n }\n\n /**\n * The duration time (in milliseconds) for the transition from open to closed states.\n *\n * If closeDuration is set to -1, the transitionDuration will be used instead.\n *\n * @type {number}\n *\n * @see _closeDuration\n */\n get closeDuration() {\n return this._closeDuration === -1\n ? this.transitionDuration\n : this._closeDuration;\n }\n\n /**\n * The current index of the accordion item.\n *\n * @readonly\n *\n * @type {number}\n *\n * @see _currentChild\n */\n get currentChild() {\n return this._currentChild;\n }\n\n /**\n * The dom elements of the accordion.\n *\n * @readonly\n *\n * @type {object}\n *\n * @see _dom\n */\n get dom() {\n return this._dom;\n }\n\n /**\n * The elements of the accordion.\n *\n * @readonly\n *\n * @type {object}\n *\n * @see _elements\n */\n get elements() {\n return this._elements;\n }\n\n /**\n * The selectors used for the accordion and accordion items.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _selectors\n */\n get selectors() {\n return this._selectors;\n }\n\n /**\n * A flag to decide if the accordion items can be navigated by arrows.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _optionalKeySupport\n */\n get optionalKeySupport() {\n return this._optionalKeySupport;\n }\n\n /**\n * The currently selected accordion item.\n *\n * @readonly\n *\n * @type {AccordionItem}\n */\n get currentAccordionItem() {\n return this.elements.accordionItems[this.currentChild];\n }\n\n /**\n * The currently open accordion items.\n *\n * @readonly\n *\n * @type {AccordionItem[]}\n */\n get openAccordionItems() {\n return this.elements.accordionItems.filter((item) => item.isOpen);\n }\n\n /**\n * A flag to decide if multiple accordions can be open at the same time.\n *\n * @type {boolean}\n *\n * @see _allowMultipleExpand\n */\n get allowMultipleExpand() {\n return this._allowMultipleExpand;\n }\n\n /**\n * A flag to decide if no accordions can be opened at the same time.\n *\n * @type {boolean}\n *\n * @see _allowNoExpand\n */\n get allowNoExpand() {\n return this._allowNoExpand;\n }\n\n /**\n * The prefix to use for CSS custom properties.\n *\n * @type {string}\n *\n * @see _prefix\n */\n get prefix() {\n return this._prefix;\n }\n\n /**\n * The key used to generate IDs throughout the accordion.\n *\n * @type {string}\n *\n * @see _key\n */\n get key() {\n return this._key;\n }\n\n /**\n * An array to hold error messages.\n *\n * @readonly\n *\n * @type {string[]}\n *\n * @see _errors\n */\n get errors() {\n return this._errors;\n }\n\n set openClass(value) {\n isValidClassList({ openClass: value });\n\n if (this._openClass !== value) {\n this._openClass = value;\n }\n }\n\n set closeClass(value) {\n isValidClassList({ closeClass: value });\n\n if (this._closeClass !== value) {\n this._closeClass = value;\n }\n }\n\n set transitionClass(value) {\n isValidClassList({ transitionClass: value });\n\n if (this._transitionClass !== value) {\n this._transitionClass = value;\n }\n }\n\n set transitionDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._transitionDuration !== value) {\n this._transitionDuration = value;\n this._setTransitionDurations();\n }\n }\n\n set openDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._openDuration !== value) {\n this._openDuration = value;\n this._setTransitionDurations();\n }\n }\n\n set closeDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._closeDuration !== value) {\n this._closeDuration = value;\n this._setTransitionDurations();\n }\n }\n\n set currentChild(value) {\n isValidType(\"number\", { value });\n\n if (\n this._currentChild !== value &&\n value >= 0 &&\n value < this.elements.accordionItems.length\n ) {\n this._currentChild = value;\n }\n }\n\n set accordionItems(value) {\n isValidType(\"object\", { value });\n\n if (\n value?.isArray() &&\n value.every((item) => item instanceof AccordionItem)\n ) {\n this._accordionItems = value;\n }\n }\n\n set allowMultipleExpand(value) {\n isValidType(\"boolean\", { value });\n\n if (this._allowMultipleExpand !== value) {\n this._allowMultipleExpand = value;\n }\n }\n\n set allowNoExpand(value) {\n isValidType(\"boolean\", { value });\n\n if (this._allowNoExpand !== value) {\n this._allowNoExpand = value;\n }\n }\n\n set prefix(value) {\n isValidType(\"string\", { value });\n\n if (this._prefix !== value) {\n this._prefix = value;\n }\n }\n\n set key(value) {\n isValidType(\"string\", { value });\n\n if (this._key !== value) {\n this._key = value;\n }\n }\n\n /**\n * Sets DOM elements.\n *\n * Elements listed in _domLock cannot be set using this method.\n *\n * @protected\n *\n * @param {string} elementType - The type of element to populate.\n * @param {HTMLElement} [base = this.dom.accordion] - The element used as the base for the querySelect.\n * @param {boolean} [overwrite = true] - A flag to set if the existing elements will be overwritten.\n * @param {boolean} [strict = false] - A flag to set if the elements must be direct children of the base.\n */\n _setDOMElementType(\n elementType,\n base = this.dom.accordion,\n overwrite = true,\n strict = false\n ) {\n if (typeof this.selectors[elementType] === \"string\") {\n if (this._domLock.includes(elementType)) {\n throw new Error(\n `Graupl ${this.constructor.name}: \"${elementType}\" element cannot be set through _setDOMElementType.`\n );\n }\n\n if (base !== this.dom.accordion) isValidInstance(HTMLElement, { base });\n\n // Get the all elements matching the selector in the base.\n const domElements = Array.from(\n base.querySelectorAll(this.selectors[elementType])\n );\n\n // Filter the elements so only direct children of the base are kept.\n const filteredElements = domElements.filter((item) =>\n strict ? item.parentElement === base : true\n );\n\n if (overwrite) {\n this._dom[elementType] = filteredElements;\n } else {\n this._dom[elementType] = [\n ...this._dom[elementType],\n ...filteredElements,\n ];\n }\n } else {\n throw new Error(\n `Graupl ${this.constructor.name}: \"${elementType}\" is not a valid element type.`\n );\n }\n }\n\n /**\n * Resets DOM elements.\n *\n * Elements listed in _domLock cannot be reset using this method.\n *\n * @protected\n *\n * @param {string} elementType - The type of element to clear.\n */\n _resetDOMElementType(elementType) {\n if (typeof this.selectors[elementType] === \"string\") {\n if (this._domLock.includes(elementType)) {\n throw new Error(\n `Graupl ${this.constructor.name}: \"${elementType}\" element cannot be reset through _resetDOMElementType.`\n );\n }\n\n if (Array.isArray(this._dom[elementType])) {\n this._dom[elementType] = [];\n } else {\n this._dom[elementType] = null;\n }\n } else {\n throw new Error(\n `Graupl ${this.constructor.name}: \"${elementType}\" is not a valid element type.`\n );\n }\n }\n\n /**\n * Sets all DOM elements within the accordion.\n *\n * Utilizes _setDOMElementType and\n * _resetDOMElementType.\n *\n * @protected\n */\n _setDOMElements() {\n this._setDOMElementType(\"accordionItems\");\n this._resetDOMElementType(\"accordionItemToggles\");\n\n this.dom.accordionItems.forEach((accordionItem) => {\n this._setDOMElementType(\"accordionItemToggles\", accordionItem, false);\n this._setDOMElementType(\"accordionItemHeaders\", accordionItem, false);\n this._setDOMElementType(\"accordionItemContents\", accordionItem, false);\n });\n }\n\n /**\n * Generates a key for the accordion.\n *\n * @param {boolean} [regenerate = false] - A flag to determine if the key should be regenerated.\n */\n _generateKey(regenerate = false) {\n if (this.key === \"\" || regenerate) {\n this.key = Math.random()\n .toString(36)\n .replace(/[^a-z]+/g, \"\")\n .substring(0, 10);\n }\n }\n\n /**\n * Sets the IDs of the accordion and it's children if they do not already exist.\n *\n * The generated IDs use the key and follow the format:\n * - accordion: `accordion-${key}`\n *\n * @protected\n */\n _setIds() {\n this.dom.accordion.id = this.dom.accordion.id || `accordion-${this.key}`;\n }\n\n /**\n * Creates and initializes all accordion items.\n *\n * @protected\n */\n _createChildElements() {\n this.dom.accordionItems.forEach((accordionItem, index) => {\n const item = new AccordionItem({\n accordionItemElement: accordionItem,\n accordionItemToggleElement: this.dom.accordionItemToggles[index],\n accordionItemHeaderElement: this.dom.accordionItemHeaders[index],\n accordionItemContentElement: this.dom.accordionItemContents[index],\n parentAccordion: this,\n });\n\n item.initialize();\n\n this.elements.accordionItems.push(item);\n });\n }\n\n /**\n * Validates all aspects of the accordion item to ensure proper functionality.\n *\n * @protected\n *\n * @return {boolean} - The result of the validation.\n */\n _validate() {\n let check = true;\n\n // HTML element checks.\n const htmlElementChecks = isValidInstance(HTMLElement, {\n accordionElement: this.dom.accordion,\n });\n\n if (!htmlElementChecks) {\n this._errors.push(htmlElementChecks.message);\n check = false;\n }\n\n // Query selector checks.\n const querySelectorChecks = isQuerySelector({\n accordionItemSelector: this._selectors.accordionItems,\n accordionItemToggleSelector: this._selectors.accordionItemToggles,\n accordionItemHeaderSelector: this._selectors.accordionItemHeaders,\n accordionItemContentSelector: this._selectors.accordionItemContents,\n });\n\n if (!querySelectorChecks) {\n this._errors.push(querySelectorChecks.message);\n check = false;\n }\n\n // Class list checks.\n if (this._openClass !== \"\") {\n const openClassCheck = isValidClassList({ openClass: this._openClass });\n\n if (!openClassCheck.status) {\n this._errors.push(openClassCheck.error.message);\n check = false;\n }\n }\n\n if (this._closeClass !== \"\") {\n const closeClassCheck = isValidClassList({\n closeClass: this._closeClass,\n });\n\n if (!closeClassCheck.status) {\n this._errors.push(closeClassCheck.error.message);\n check = false;\n }\n }\n\n if (this._transitionClass !== \"\") {\n const transitionClassCheck = isValidClassList({\n transitionClass: this._transitionClass,\n });\n\n if (!transitionClassCheck.status) {\n this._errors.push(transitionClassCheck.error.message);\n check = false;\n }\n }\n\n // Transition duration check.\n const transitionDurationCheck = isValidType(\"number\", {\n transitionDuration: this._transitionDuration,\n });\n\n if (!transitionDurationCheck.status) {\n this._errors.push(transitionDurationCheck.error.message);\n check = false;\n }\n\n // Open duration check.\n const openDurationCheck = isValidType(\"number\", {\n openDuration: this._openDuration,\n });\n\n if (!openDurationCheck.status) {\n this._errors.push(openDurationCheck.error.message);\n check = false;\n }\n\n // Close duration check.\n const closeDurationCheck = isValidType(\"number\", {\n closeDuration: this._closeDuration,\n });\n\n if (!closeDurationCheck.status) {\n this._errors.push(closeDurationCheck.error.message);\n check = false;\n }\n\n // Boolean checks.\n const booleanCheck = isValidType(\"boolean\", {\n optionalKeySupport: this._optionalKeySupport,\n allowMultipleExpand: this._allowMultipleExpand,\n allowNoExpand: this._allowNoExpand,\n });\n\n if (!booleanCheck.status) {\n this._errors.push(booleanCheck.error.message);\n check = false;\n }\n\n // Key check.\n if (this._key !== \"\") {\n const keyCheck = isValidType(\"string\", { key: this._key });\n\n if (!keyCheck.status) {\n this._errors.push(keyCheck.error.message);\n check = false;\n }\n }\n\n // Prefix check.\n const prefixCheck = isValidType(\"string\", { prefix: this._prefix });\n\n if (!prefixCheck.status) {\n this._errors.push(prefixCheck.error.message);\n check = false;\n }\n\n return check;\n }\n\n /**\n * Handles focus events throughout the accordion for proper use.\n *\n * - Adds a `focus` listener to every accordion item so when it gains focus,\n * it will set the accordion's current child to the index of the item.\n *\n * @protected\n */\n _handleFocus() {\n this.elements.accordionItems.forEach((accordionItem, index) => {\n accordionItem.dom.toggle.addEventListener(\"focus\", () => {\n this.currentChild = index;\n });\n });\n }\n\n /**\n * Handles click events throughout the accordion item for proper use.\n *\n * - Adds a `pointerup` listener to the accordion item toggles that will toggle each accordion item.\n *\n * @protected\n */\n _handleClick() {\n this.elements.accordionItems.forEach((accordionItem, index) => {\n accordionItem.dom.toggle.addEventListener(\"pointerup\", () => {\n this.currentChild = index;\n accordionItem.toggle();\n });\n });\n }\n\n /**\n * Handles keydown events throughout the accordion item for proper use.\n *\n * This method exists to assist the _handleKeyup method.\n *\n * - Adds a `keydown` listener to all accordion item toggles.\n * - Blocks propagation on \"Space\" and \"Enter\" keys.\n * - _If_ optionalKeySupport is enabled, blocks propagation on the following keys:\n * - \"ArrowDown\", \"ArrowUp\", \"Home\", and \"End\".\n */\n _handleKeydown() {\n this.dom.accordionItemToggles.forEach((accordionToggle) => {\n accordionToggle.addEventListener(\"keydown\", (event) => {\n const key = keyPress(event);\n const ToggleKeys = [\"Space\", \"Enter\"];\n\n // Prevent default behavior for space and enter keys.\n if (ToggleKeys.includes(key)) {\n preventEvent(event);\n } else if (this.optionalKeySupport) {\n const optionalKeys = [\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"];\n\n if (optionalKeys.includes(key)) {\n preventEvent(event);\n }\n }\n });\n });\n }\n\n /**\n * Handles keyup events throughout the accordion item for proper use.\n *\n * Adds the follow keybindings (explanations are taken from the WAI ARIA Practices Guide Accordion Pattern):\n *\n * - `Enter` or `Space`:\n * - When focus is on the accordion header for a collapsed panel, expands the associated panel. If the implementation allows only one panel to be expanded, and if another panel is expanded, collapses that panel.\n * - When focus is on the accordion header for an expanded panel, collapses the panel if the implementation supports collapsing. Some implementations require one panel to be expanded at all times and allow only one panel to be expanded; so, they do not support a collapse function.\n * - `Tab`: Moves focus to the next focusable element; all focusable elements in the accordion are included in the page `Tab` sequence.\n * - `Shift + Tab`: Moves focus to the previous focusable element; all focusable elements in the accordion are included in the page `Tab` sequence.\n * - `Down Arrow` (Optional): If focus is on an accordion header, moves focus to the next accordion header. If focus is on the last accordion header, either does nothing or moves focus to the first accordion header.\n * - `Up Arrow` (Optional): If focus is on an accordion header, moves focus to the previous accordion header. If focus is on the first accordion header, either does nothing or moves focus to the last accordion header.\n * - `Home` (Optional): When focus is on an accordion header, moves focus to the first accordion header.\n * - `End` (Optional): When focus is on an accordion header, moves focus to the last accordion header.\n *\n * Note: When the above explanations mention \"accordion header\", they are referring to the accordion item toggle.\n */\n _handleKeyup() {\n this.dom.accordionItemToggles.forEach((accordionToggle) => {\n accordionToggle.addEventListener(\"keyup\", (event) => {\n const key = keyPress(event);\n\n switch (key) {\n case \"Space\":\n case \"Enter\":\n preventEvent(event);\n this.currentAccordionItem.toggle();\n\n break;\n }\n\n if (this.optionalKeySupport) {\n switch (key) {\n case \"Home\":\n preventEvent(event);\n this.focusFirstChild();\n\n break;\n case \"End\":\n preventEvent(event);\n this.focusLastChild();\n\n break;\n case \"ArrowDown\":\n preventEvent(event);\n this.focusNextChild();\n\n break;\n case \"ArrowUp\":\n preventEvent(event);\n this.focusPreviousChild();\n\n break;\n }\n }\n });\n });\n }\n\n /**\n * Sets the transition durations of the accordion as a CSS custom properties.\n *\n * The custom properties are:\n * - `--graupl-accordion-transition-duration`,\n * - `--graupl-accordion-open-transition-duration`, and\n * - `--graupl-accordion-close-transition-duration`.\n *\n * The prefix of `graupl-` can be changed by setting the accordion's prefix value.\n *\n * @protected\n */\n _setTransitionDurations() {\n this.dom.accordion.style.setProperty(\n `--${this.prefix}accordion-transition-duration`,\n `${this.transitionDuration}ms`\n );\n\n this.dom.accordion.style.setProperty(\n `--${this.prefix}accordion-open-transition-duration`,\n `${this.openDuration}ms`\n );\n\n this.dom.accordion.style.setProperty(\n `--${this.prefix}accordion-close-transition-duration`,\n `${this.closeDuration}ms`\n );\n }\n\n /**\n * Focus the accordion's current child.\n *\n * @public\n */\n focusCurrentChild() {\n if (this.currentChild !== -1) {\n this.currentAccordionItem.focus();\n }\n }\n\n /**\n * Focuses the accordion's child at a given index.\n *\n * @public\n *\n * @param {number} index - The index of the child to focus.\n */\n focusChild(index) {\n this.blurCurrentChild();\n this.currentChild = index;\n this.focusCurrentChild();\n }\n\n /**\n * Focuses the accordion's first child.\n *\n * @public\n */\n focusFirstChild() {\n this.focusChild(0);\n }\n\n /**\n * Focus the accordion's last child.\n *\n * @public\n */\n focusLastChild() {\n this.focusChild(this.elements.accordionItems.length - 1);\n }\n\n /**\n * Focus the accordion's next child.\n *\n * @public\n */\n focusNextChild() {\n if (this.currentChild < this.elements.accordionItems.length - 1) {\n this.focusChild(this.currentChild + 1);\n } else {\n this.focusCurrentChild();\n }\n }\n\n /**\n * Focus the accordion's previous child.\n *\n * @public\n */\n focusPreviousChild() {\n if (this.currentChild > 0) {\n this.focusChild(this.currentChild - 1);\n } else {\n this.focusCurrentChild();\n }\n }\n\n /**\n * Blurs the accordion's current child.\n *\n * @public\n */\n blurCurrentChild() {\n if (this.currentChild !== -1) {\n this.currentAccordionItem.blur();\n }\n }\n\n /**\n * Open all accordion items.\n *\n * @public\n */\n openChildren() {\n this.elements.accordionItems.forEach((item) => item.show());\n }\n\n /**\n * Close all accordion items.\n *\n * @public\n */\n closeChildren() {\n this.elements.accordionItems.forEach((item) => item.hide());\n }\n}\n\nexport default Accordion;\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var Accordion=function(){function p(t,e){try{if(typeof e!="object"){const i=typeof e;throw new TypeError(`Elements given to isValidInstance() must be inside of an object. "${i}" given.`)}for(const i in e)if(!(e[i]instanceof t)){const o=typeof e[i];throw new TypeError(`${i} must be an instance of ${t.name}. "${o}" given.`)}return{status:!0,error:null}}catch(i){return{status:!1,error:i}}}function s(t,e){try{if(typeof e!="object"){const i=typeof e;throw new TypeError(`Values given to isValidType() must be inside of an object. "${i}" given.`)}for(const i in e){const o=typeof e[i];if(o!==t)throw new TypeError(`${i} must be a ${t}. "${o}" given.`)}return{status:!0,error:null}}catch(i){return{status:!1,error:i}}}function f(t){try{if(typeof t!="object"){const e=typeof t;throw new TypeError(`Values given to isQuerySelector() must be inside of an object. "${e}" given.`)}for(const e in t)try{if(t[e]===null)throw new Error;document.querySelector(t[e])}catch{throw new TypeError(`${e} must be a valid query selector. "${t[e]}" given.`)}return{status:!0,error:null}}catch(e){return{status:!1,error:e}}}function l(t){try{if(typeof t!="object"||Array.isArray(t)){const e=typeof t;throw new TypeError(`Values given to isValidClassList() must be inside of an object. "${e}" given.`)}for(const e in t){const i=typeof t[e];if(i!=="string")if(Array.isArray(t[e]))t[e].forEach(o=>{if(typeof o!="string")throw new TypeError(`${e} must be a string or an array of strings. An array containing non-strings given.`)});else throw new TypeError(`${e} must be a string or an array of strings. "${i}" given.`);else{const o={};o[e]=t[e],f(o)}}return{status:!0,error:null}}catch(e){return{status:!1,error:e}}}function g(t,e){if(s("string",{tagName:t}).status&&p(HTMLElement,e).status){const i=t.toLowerCase();let o=!0;for(const r in e)e[r].tagName.toLowerCase()!==i&&(o=!1);return o}else return!1}function h(t,e){t===""||t.length===0||(typeof t=="string"?e.classList.add(t):e.classList.add(...t))}function d(t,e){t===""||t.length===0||(typeof t=="string"?e.classList.remove(t):e.classList.remove(...t))}var y=class{_dom={item:null,toggle:null,header:null,content:null};_elements={parentAccordion:null};_open=!1;_locked=!1;_expandEvent=new CustomEvent("grauplAccordionItemExpand",{bubbles:!0,detail:{item:this}});_collapseEvent=new CustomEvent("grauplAccordionItemCollapse",{bubbles:!0,detail:{item:this}});constructor({accordionItemElement:t,accordionItemToggleElement:e,accordionItemHeaderElement:i,accordionItemContentElement:o,parentAccordion:r=null}){this._dom.item=t,this._dom.toggle=e,this._dom.header=i,this._dom.content=o,this._elements.parentAccordion=r}initialize(){this._setIds(),this._setAriaAttributes(),this.dom.toggle.getAttribute("aria-expanded")==="true"?this.show(!1,!1):this.hide(!1,!1)}get dom(){return this._dom}get elements(){return this._elements}get isOpen(){return this._open}get isLocked(){return this._locked}set isOpen(t){s("boolean",{value:t}),this._open!==t&&(this._open=t)}_setIds(){const{key:t}=this.elements.parentAccordion,e=this.elements.parentAccordion.dom.accordionItems.indexOf(this.dom.item);this.dom.item.id=this.dom.item.id||`accordion-item-${t}-${e}`,this.dom.toggle.id=this.dom.toggle.id||`accordion-item-toggle-${t}-${e}`,this.dom.header.id=this.dom.header.id||`accordion-item-header-${t}-${e}`,this.dom.content.id=this.dom.content.id||`accordion-item-content-${t}-${e}`}_setAriaAttributes(){g("button",{toggle:this.dom.toggle})||this.dom.toggle.setAttribute("role","button"),this.dom.toggle.getAttribute("aria-expanded")!=="true"&&this.dom.toggle.setAttribute("aria-expanded","false"),this.dom.toggle.setAttribute("aria-controls",this.dom.content.id),g("section",{content:this.dom.content})||this.dom.content.setAttribute("role","region"),this.dom.content.setAttribute("aria-labelledby",this.dom.toggle.id)}show(t=!0,e=!0){if(this._open)return;const{closeClass:i,openClass:o,transitionClass:r,openDuration:a}=this.elements.parentAccordion;this.dom.toggle.setAttribute("aria-expanded","true"),e&&r!==""?(h(r,this.dom.item),requestAnimationFrame(()=>{d(i,this.dom.item),this.dom.item.style.height=`${this.dom.header.getBoundingClientRect().height}px`,requestAnimationFrame(()=>{h(o,this.dom.item),this.dom.item.style.height=`${this.dom.header.getBoundingClientRect().height+this.dom.content.getBoundingClientRect().height}px`,requestAnimationFrame(()=>{setTimeout(()=>{d(r,this.dom.item),this.dom.item.style.height=""},a)})})})):(h(o,this.dom.item),d(i,this.dom.item)),this._open=!0,this.elements.parentAccordion.allowMultipleExpand||(this.unlockSiblings(),this.closeSiblings()),this.elements.parentAccordion.allowNoExpand||(this.elements.parentAccordion.openAccordionItems.length<=1?this.lock():this.unlockSiblings()),t&&this.dom.item.dispatchEvent(this._expandEvent)}hide(t=!0,e=!0){if(!this._open||!this.elements.parentAccordion.allowNoExpand&&this.elements.parentAccordion.openAccordionItems.length<=1)return;const{closeClass:i,openClass:o,transitionClass:r,closeDuration:a}=this.elements.parentAccordion;this.dom.toggle.setAttribute("aria-expanded","false"),e&&r!==""?(h(r,this.dom.item),this.dom.item.style.height=`${this.dom.item.getBoundingClientRect().height}px`,requestAnimationFrame(()=>{d(o,this.dom.item),this.dom.item.style.height=`${this.dom.header.getBoundingClientRect().height}px`,requestAnimationFrame(()=>{h(i,this.dom.item),requestAnimationFrame(()=>{setTimeout(()=>{d(r,this.dom.item),this.dom.item.style.height=""},a)})})})):(h(i,this.dom.item),d(o,this.dom.item)),this._open=!1,!this.elements.parentAccordion.allowNoExpand&&this.elements.parentAccordion.openAccordionItems.length===1&&this.elements.parentAccordion.openAccordionItems[0].lock(),t&&this.dom.item.dispatchEvent(this._collapseEvent)}toggle(){this.isOpen?this.hide():this.show()}focus(){this.dom.toggle.focus()}blur(){this.dom.toggle.blur()}lock(){this._locked=!0,this.dom.toggle.setAttribute("disabled","true")}unlock(){this._locked=!1,this.dom.toggle.removeAttribute("disabled")}closeSiblings(){this.elements.parentAccordion&&this.elements.parentAccordion.elements.accordionItems.forEach(t=>{t!==this&&t.hide()})}unlockSiblings(){this.elements.parentAccordion&&this.elements.parentAccordion.elements.accordionItems.forEach(t=>{t!==this&&t.unlock()})}},_=y;function C(t){try{const e=t.key||t.keyCode,i={Enter:e==="Enter"||e===13,Space:e===" "||e==="Spacebar"||e===32,Escape:e==="Escape"||e==="Esc"||e===27,ArrowUp:e==="ArrowUp"||e==="Up"||e===38,ArrowRight:e==="ArrowRight"||e==="Right"||e===39,ArrowDown:e==="ArrowDown"||e==="Down"||e===40,ArrowLeft:e==="ArrowLeft"||e==="Left"||e===37,Home:e==="Home"||e===36,End:e==="End"||e===35,Tab:e==="Tab"||e===9};return Object.keys(i).find(o=>i[o]===!0)||""}catch{return""}}function c(t){t.preventDefault(),t.stopPropagation()}function E(t=null){window.Graupl=window.Graupl||{},s("string",{type:t})&&(window.Graupl[t]=window.Graupl[t]||{})}function A(t=null){return s("string",{type:t})?window.Graupl[t]:window.Graupl}function b(t,e={}){s("string",{type:t})&&s("object",{data:e})&&(window.Graupl[t]=e)}function I(t){s("string",{type:t})&&(window.Graupl[t]={})}function k(t,e,i){s("string",{type:t,key:e})&&(window.Graupl[t][e]=i)}function D(t,e){return s("string",{type:t,key:e})?window.Graupl[t][e]:null}function x(t,e){s("string",{type:t,key:e})&&delete window.Graupl[t][e]}var w={initializeStorage:E,getStorage:A,setStorage:b,clearStorage:I,pushToStorage:k,getFromStorage:D,removeFromStorage:x},$=class{_dom={accordion:null,accordionItems:[],accordionItemToggles:[],accordionItemHeaders:[],accordionItemContents:[]};_domLock=["accordion"];_selectors={accordionItems:"",accordionItemToggles:"",accordionItemHeaders:"",accordionItemContents:""};_elements={accordionItems:[]};_openClass="show";_closeClass="hide";_transitionClass="transitioning";_transitionDuration=300;_openDuration=-1;_closeDuration=-1;_optionalKeySupport=!0;_allowMultipleExpand=!0;_allowNoExpand=!0;_currentChild=0;_prefix="graupl-";_key="";_errors=[];constructor({accordionElement:t,accordionItemSelector:e=".accordion-item",accordionItemToggleSelector:i=".accordion-item-toggle",accordionItemHeaderSelector:o=".accordion-item-header",accordionItemContentSelector:r=".accordion-item-content",openClass:a="show",closeClass:u="hide",transitionClass:m="transitioning",transitionDuration:n=300,openDuration:S=-1,closeDuration:M=-1,optionalKeySupport:L=!1,allowMultipleExpand:
|
|
1
|
+
var Accordion=(function(){function p(t,e){try{if(typeof e!="object"){const i=typeof e;throw new TypeError(`Elements given to isValidInstance() must be inside of an object. "${i}" given.`)}for(const i in e)if(!(e[i]instanceof t)){const o=typeof e[i];throw new TypeError(`${i} must be an instance of ${t.name}. "${o}" given.`)}return{status:!0,error:null}}catch(i){return{status:!1,error:i}}}function s(t,e){try{if(typeof e!="object"){const i=typeof e;throw new TypeError(`Values given to isValidType() must be inside of an object. "${i}" given.`)}for(const i in e){const o=typeof e[i];if(o!==t)throw new TypeError(`${i} must be a ${t}. "${o}" given.`)}return{status:!0,error:null}}catch(i){return{status:!1,error:i}}}function f(t){try{if(typeof t!="object"){const e=typeof t;throw new TypeError(`Values given to isQuerySelector() must be inside of an object. "${e}" given.`)}for(const e in t)try{if(t[e]===null)throw new Error;document.querySelector(t[e])}catch{throw new TypeError(`${e} must be a valid query selector. "${t[e]}" given.`)}return{status:!0,error:null}}catch(e){return{status:!1,error:e}}}function l(t){try{if(typeof t!="object"||Array.isArray(t)){const e=typeof t;throw new TypeError(`Values given to isValidClassList() must be inside of an object. "${e}" given.`)}for(const e in t){const i=typeof t[e];if(i!=="string")if(Array.isArray(t[e]))t[e].forEach(o=>{if(typeof o!="string")throw new TypeError(`${e} must be a string or an array of strings. An array containing non-strings given.`)});else throw new TypeError(`${e} must be a string or an array of strings. "${i}" given.`);else{const o={};o[e]=t[e],f(o)}}return{status:!0,error:null}}catch(e){return{status:!1,error:e}}}function g(t,e){if(s("string",{tagName:t}).status&&p(HTMLElement,e).status){const i=t.toLowerCase();let o=!0;for(const r in e)e[r].tagName.toLowerCase()!==i&&(o=!1);return o}else return!1}function h(t,e){t===""||t.length===0||(typeof t=="string"?e.classList.add(t):e.classList.add(...t))}function d(t,e){t===""||t.length===0||(typeof t=="string"?e.classList.remove(t):e.classList.remove(...t))}var y=class{_dom={item:null,toggle:null,header:null,content:null};_elements={parentAccordion:null};_open=!1;_locked=!1;_expandEvent=new CustomEvent("grauplAccordionItemExpand",{bubbles:!0,detail:{item:this}});_collapseEvent=new CustomEvent("grauplAccordionItemCollapse",{bubbles:!0,detail:{item:this}});constructor({accordionItemElement:t,accordionItemToggleElement:e,accordionItemHeaderElement:i,accordionItemContentElement:o,parentAccordion:r=null}){this._dom.item=t,this._dom.toggle=e,this._dom.header=i,this._dom.content=o,this._elements.parentAccordion=r}initialize(){this._setIds(),this._setAriaAttributes(),this.dom.toggle.getAttribute("aria-expanded")==="true"?this.show(!1,!1):this.hide(!1,!1)}get dom(){return this._dom}get elements(){return this._elements}get isOpen(){return this._open}get isLocked(){return this._locked}set isOpen(t){s("boolean",{value:t}),this._open!==t&&(this._open=t)}_setIds(){const{key:t}=this.elements.parentAccordion,e=this.elements.parentAccordion.dom.accordionItems.indexOf(this.dom.item);this.dom.item.id=this.dom.item.id||`accordion-item-${t}-${e}`,this.dom.toggle.id=this.dom.toggle.id||`accordion-item-toggle-${t}-${e}`,this.dom.header.id=this.dom.header.id||`accordion-item-header-${t}-${e}`,this.dom.content.id=this.dom.content.id||`accordion-item-content-${t}-${e}`}_setAriaAttributes(){g("button",{toggle:this.dom.toggle})||this.dom.toggle.setAttribute("role","button"),this.dom.toggle.getAttribute("aria-expanded")!=="true"&&this.dom.toggle.setAttribute("aria-expanded","false"),this.dom.toggle.setAttribute("aria-controls",this.dom.content.id),g("section",{content:this.dom.content})||this.dom.content.setAttribute("role","region"),this.dom.content.setAttribute("aria-labelledby",this.dom.toggle.id)}show(t=!0,e=!0){if(this._open)return;const{closeClass:i,openClass:o,transitionClass:r,openDuration:a}=this.elements.parentAccordion;this.dom.toggle.setAttribute("aria-expanded","true"),e&&r!==""?(h(r,this.dom.item),requestAnimationFrame(()=>{d(i,this.dom.item),this.dom.item.style.height=`${this.dom.header.getBoundingClientRect().height}px`,requestAnimationFrame(()=>{h(o,this.dom.item),this.dom.item.style.height=`${this.dom.header.getBoundingClientRect().height+this.dom.content.getBoundingClientRect().height}px`,requestAnimationFrame(()=>{setTimeout(()=>{d(r,this.dom.item),this.dom.item.style.height=""},a)})})})):(h(o,this.dom.item),d(i,this.dom.item)),this._open=!0,this.elements.parentAccordion.allowMultipleExpand||(this.unlockSiblings(),this.closeSiblings()),this.elements.parentAccordion.allowNoExpand||(this.elements.parentAccordion.openAccordionItems.length<=1?this.lock():this.unlockSiblings()),t&&this.dom.item.dispatchEvent(this._expandEvent)}hide(t=!0,e=!0){if(!this._open||!this.elements.parentAccordion.allowNoExpand&&this.elements.parentAccordion.openAccordionItems.length<=1)return;const{closeClass:i,openClass:o,transitionClass:r,closeDuration:a}=this.elements.parentAccordion;this.dom.toggle.setAttribute("aria-expanded","false"),e&&r!==""?(h(r,this.dom.item),this.dom.item.style.height=`${this.dom.item.getBoundingClientRect().height}px`,requestAnimationFrame(()=>{d(o,this.dom.item),this.dom.item.style.height=`${this.dom.header.getBoundingClientRect().height}px`,requestAnimationFrame(()=>{h(i,this.dom.item),requestAnimationFrame(()=>{setTimeout(()=>{d(r,this.dom.item),this.dom.item.style.height=""},a)})})})):(h(i,this.dom.item),d(o,this.dom.item)),this._open=!1,!this.elements.parentAccordion.allowNoExpand&&this.elements.parentAccordion.openAccordionItems.length===1&&this.elements.parentAccordion.openAccordionItems[0].lock(),t&&this.dom.item.dispatchEvent(this._collapseEvent)}toggle(){this.isOpen?this.hide():this.show()}focus(){this.dom.toggle.focus()}blur(){this.dom.toggle.blur()}lock(){this._locked=!0,this.dom.toggle.setAttribute("disabled","true")}unlock(){this._locked=!1,this.dom.toggle.removeAttribute("disabled")}closeSiblings(){this.elements.parentAccordion&&this.elements.parentAccordion.elements.accordionItems.forEach(t=>{t!==this&&t.hide()})}unlockSiblings(){this.elements.parentAccordion&&this.elements.parentAccordion.elements.accordionItems.forEach(t=>{t!==this&&t.unlock()})}},_=y;function C(t){try{const e=t.key||t.keyCode,i={Enter:e==="Enter"||e===13,Space:e===" "||e==="Spacebar"||e===32,Escape:e==="Escape"||e==="Esc"||e===27,ArrowUp:e==="ArrowUp"||e==="Up"||e===38,ArrowRight:e==="ArrowRight"||e==="Right"||e===39,ArrowDown:e==="ArrowDown"||e==="Down"||e===40,ArrowLeft:e==="ArrowLeft"||e==="Left"||e===37,Home:e==="Home"||e===36,End:e==="End"||e===35,Tab:e==="Tab"||e===9};return Object.keys(i).find(o=>i[o]===!0)||""}catch{return""}}function c(t){t.preventDefault(),t.stopPropagation()}function E(t=null){window.Graupl=window.Graupl||{},s("string",{type:t})&&(window.Graupl[t]=window.Graupl[t]||{})}function A(t=null){return s("string",{type:t})?window.Graupl[t]:window.Graupl}function b(t,e={}){s("string",{type:t})&&s("object",{data:e})&&(window.Graupl[t]=e)}function I(t){s("string",{type:t})&&(window.Graupl[t]={})}function k(t,e,i){s("string",{type:t,key:e})&&(window.Graupl[t][e]=i)}function D(t,e){return s("string",{type:t,key:e})?window.Graupl[t][e]:null}function x(t,e){s("string",{type:t,key:e})&&delete window.Graupl[t][e]}var w={initializeStorage:E,getStorage:A,setStorage:b,clearStorage:I,pushToStorage:k,getFromStorage:D,removeFromStorage:x},$=class{_dom={accordion:null,accordionItems:[],accordionItemToggles:[],accordionItemHeaders:[],accordionItemContents:[]};_domLock=["accordion"];_selectors={accordionItems:"",accordionItemToggles:"",accordionItemHeaders:"",accordionItemContents:""};_elements={accordionItems:[]};_openClass="show";_closeClass="hide";_transitionClass="transitioning";_transitionDuration=300;_openDuration=-1;_closeDuration=-1;_optionalKeySupport=!0;_allowMultipleExpand=!0;_allowNoExpand=!0;_currentChild=0;_prefix="graupl-";_key="";_errors=[];constructor({accordionElement:t,accordionItemSelector:e=".accordion-item",accordionItemToggleSelector:i=".accordion-item-toggle",accordionItemHeaderSelector:o=".accordion-item-header",accordionItemContentSelector:r=".accordion-item-content",openClass:a="show",closeClass:u="hide",transitionClass:m="transitioning",transitionDuration:n=300,openDuration:S=-1,closeDuration:M=-1,optionalKeySupport:L=!1,allowMultipleExpand:O=!0,allowNoExpand:G=!0,prefix:H="graupl-",key:K=null,initialize:j=!1}){this._dom.accordion=t,this._selectors.accordionItems=e,this._selectors.accordionItemToggles=i,this._selectors.accordionItemHeaders=o,this._selectors.accordionItemContents=r,this._openClass=a||"",this._closeClass=u||"",this._transitionClass=m||"",this._transitionDuration=n,this._openDuration=S,this._closeDuration=M,this._optionalKeySupport=L,this._allowMultipleExpand=O,this._allowNoExpand=G,this._prefix=H||"",this._key=K||"",j&&this.initialize()}initialize(){try{if(!this._validate())throw new Error(`Graupl Accordion: cannot initialize accordion. The following errors have been found:
|
|
2
2
|
- ${this.errors.join(`
|
|
3
|
-
- `)}`);this._generateKey(),this._setDOMElements(),this._setIds(),this._createChildElements(),this._handleFocus(),this._handleClick(),this._handleKeydown(),this._handleKeyup(),this._setTransitionDurations(),w.initializeStorage("accordions"),w.pushToStorage("accordions",this.dom.accordion.id,this)}catch(t){console.error(t)}}get openClass(){return this._openClass}get closeClass(){return this._closeClass}get transitionClass(){return this._transitionClass}get transitionDuration(){return this._transitionDuration}get openDuration(){return this._openDuration===-1?this.transitionDuration:this._openDuration}get closeDuration(){return this._closeDuration===-1?this.transitionDuration:this._closeDuration}get currentChild(){return this._currentChild}get dom(){return this._dom}get elements(){return this._elements}get selectors(){return this._selectors}get optionalKeySupport(){return this._optionalKeySupport}get currentAccordionItem(){return this.elements.accordionItems[this.currentChild]}get openAccordionItems(){return this.elements.accordionItems.filter(t=>t.isOpen)}get allowMultipleExpand(){return this._allowMultipleExpand}get allowNoExpand(){return this._allowNoExpand}get prefix(){return this._prefix}get key(){return this._key}get errors(){return this._errors}set openClass(t){l({openClass:t}),this._openClass!==t&&(this._openClass=t)}set closeClass(t){l({closeClass:t}),this._closeClass!==t&&(this._closeClass=t)}set transitionClass(t){l({transitionClass:t}),this._transitionClass!==t&&(this._transitionClass=t)}set transitionDuration(t){s("number",{value:t}),this._transitionDuration!==t&&(this._transitionDuration=t,this._setTransitionDurations())}set openDuration(t){s("number",{value:t}),this._openDuration!==t&&(this._openDuration=t,this._setTransitionDurations())}set closeDuration(t){s("number",{value:t}),this._closeDuration!==t&&(this._closeDuration=t,this._setTransitionDurations())}set currentChild(t){s("number",{value:t}),this._currentChild!==t&&t>=0&&t<this.elements.accordionItems.length&&(this._currentChild=t)}set accordionItems(t){s("object",{value:t}),t?.isArray()&&t.every(e=>e instanceof _)&&(this._accordionItems=t)}set allowMultipleExpand(t){s("boolean",{value:t}),this._allowMultipleExpand!==t&&(this._allowMultipleExpand=t)}set allowNoExpand(t){s("boolean",{value:t}),this._allowNoExpand!==t&&(this._allowNoExpand=t)}set prefix(t){s("string",{value:t}),this._prefix!==t&&(this._prefix=t)}set key(t){s("string",{value:t}),this._key!==t&&(this._key=t)}_setDOMElementType(t,e=this.dom.accordion,i=!0,o=!1){if(typeof this.selectors[t]=="string"){if(this._domLock.includes(t))throw new Error(`Graupl ${this.
|
|
3
|
+
- `)}`);this._generateKey(),this._setDOMElements(),this._setIds(),this._createChildElements(),this._handleFocus(),this._handleClick(),this._handleKeydown(),this._handleKeyup(),this._setTransitionDurations(),w.initializeStorage("accordions"),w.pushToStorage("accordions",this.dom.accordion.id,this)}catch(t){console.error(t)}}get openClass(){return this._openClass}get closeClass(){return this._closeClass}get transitionClass(){return this._transitionClass}get transitionDuration(){return this._transitionDuration}get openDuration(){return this._openDuration===-1?this.transitionDuration:this._openDuration}get closeDuration(){return this._closeDuration===-1?this.transitionDuration:this._closeDuration}get currentChild(){return this._currentChild}get dom(){return this._dom}get elements(){return this._elements}get selectors(){return this._selectors}get optionalKeySupport(){return this._optionalKeySupport}get currentAccordionItem(){return this.elements.accordionItems[this.currentChild]}get openAccordionItems(){return this.elements.accordionItems.filter(t=>t.isOpen)}get allowMultipleExpand(){return this._allowMultipleExpand}get allowNoExpand(){return this._allowNoExpand}get prefix(){return this._prefix}get key(){return this._key}get errors(){return this._errors}set openClass(t){l({openClass:t}),this._openClass!==t&&(this._openClass=t)}set closeClass(t){l({closeClass:t}),this._closeClass!==t&&(this._closeClass=t)}set transitionClass(t){l({transitionClass:t}),this._transitionClass!==t&&(this._transitionClass=t)}set transitionDuration(t){s("number",{value:t}),this._transitionDuration!==t&&(this._transitionDuration=t,this._setTransitionDurations())}set openDuration(t){s("number",{value:t}),this._openDuration!==t&&(this._openDuration=t,this._setTransitionDurations())}set closeDuration(t){s("number",{value:t}),this._closeDuration!==t&&(this._closeDuration=t,this._setTransitionDurations())}set currentChild(t){s("number",{value:t}),this._currentChild!==t&&t>=0&&t<this.elements.accordionItems.length&&(this._currentChild=t)}set accordionItems(t){s("object",{value:t}),t?.isArray()&&t.every(e=>e instanceof _)&&(this._accordionItems=t)}set allowMultipleExpand(t){s("boolean",{value:t}),this._allowMultipleExpand!==t&&(this._allowMultipleExpand=t)}set allowNoExpand(t){s("boolean",{value:t}),this._allowNoExpand!==t&&(this._allowNoExpand=t)}set prefix(t){s("string",{value:t}),this._prefix!==t&&(this._prefix=t)}set key(t){s("string",{value:t}),this._key!==t&&(this._key=t)}_setDOMElementType(t,e=this.dom.accordion,i=!0,o=!1){if(typeof this.selectors[t]=="string"){if(this._domLock.includes(t))throw new Error(`Graupl ${this.constructor.name}: "${t}" element cannot be set through _setDOMElementType.`);e!==this.dom.accordion&&p(HTMLElement,{base:e});const r=Array.from(e.querySelectorAll(this.selectors[t])).filter(a=>o?a.parentElement===e:!0);i?this._dom[t]=r:this._dom[t]=[...this._dom[t],...r]}else throw new Error(`Graupl ${this.constructor.name}: "${t}" is not a valid element type.`)}_resetDOMElementType(t){if(typeof this.selectors[t]=="string"){if(this._domLock.includes(t))throw new Error(`Graupl ${this.constructor.name}: "${t}" element cannot be reset through _resetDOMElementType.`);Array.isArray(this._dom[t])?this._dom[t]=[]:this._dom[t]=null}else throw new Error(`Graupl ${this.constructor.name}: "${t}" is not a valid element type.`)}_setDOMElements(){this._setDOMElementType("accordionItems"),this._resetDOMElementType("accordionItemToggles"),this.dom.accordionItems.forEach(t=>{this._setDOMElementType("accordionItemToggles",t,!1),this._setDOMElementType("accordionItemHeaders",t,!1),this._setDOMElementType("accordionItemContents",t,!1)})}_generateKey(t=!1){(this.key===""||t)&&(this.key=Math.random().toString(36).replace(/[^a-z]+/g,"").substring(0,10))}_setIds(){this.dom.accordion.id=this.dom.accordion.id||`accordion-${this.key}`}_createChildElements(){this.dom.accordionItems.forEach((t,e)=>{const i=new _({accordionItemElement:t,accordionItemToggleElement:this.dom.accordionItemToggles[e],accordionItemHeaderElement:this.dom.accordionItemHeaders[e],accordionItemContentElement:this.dom.accordionItemContents[e],parentAccordion:this});i.initialize(),this.elements.accordionItems.push(i)})}_validate(){let t=!0;const e=p(HTMLElement,{accordionElement:this.dom.accordion});e||(this._errors.push(e.message),t=!1);const i=f({accordionItemSelector:this._selectors.accordionItems,accordionItemToggleSelector:this._selectors.accordionItemToggles,accordionItemHeaderSelector:this._selectors.accordionItemHeaders,accordionItemContentSelector:this._selectors.accordionItemContents});if(i||(this._errors.push(i.message),t=!1),this._openClass!==""){const n=l({openClass:this._openClass});n.status||(this._errors.push(n.error.message),t=!1)}if(this._closeClass!==""){const n=l({closeClass:this._closeClass});n.status||(this._errors.push(n.error.message),t=!1)}if(this._transitionClass!==""){const n=l({transitionClass:this._transitionClass});n.status||(this._errors.push(n.error.message),t=!1)}const o=s("number",{transitionDuration:this._transitionDuration});o.status||(this._errors.push(o.error.message),t=!1);const r=s("number",{openDuration:this._openDuration});r.status||(this._errors.push(r.error.message),t=!1);const a=s("number",{closeDuration:this._closeDuration});a.status||(this._errors.push(a.error.message),t=!1);const u=s("boolean",{optionalKeySupport:this._optionalKeySupport,allowMultipleExpand:this._allowMultipleExpand,allowNoExpand:this._allowNoExpand});if(u.status||(this._errors.push(u.error.message),t=!1),this._key!==""){const n=s("string",{key:this._key});n.status||(this._errors.push(n.error.message),t=!1)}const m=s("string",{prefix:this._prefix});return m.status||(this._errors.push(m.error.message),t=!1),t}_handleFocus(){this.elements.accordionItems.forEach((t,e)=>{t.dom.toggle.addEventListener("focus",()=>{this.currentChild=e})})}_handleClick(){this.elements.accordionItems.forEach((t,e)=>{t.dom.toggle.addEventListener("pointerup",()=>{this.currentChild=e,t.toggle()})})}_handleKeydown(){this.dom.accordionItemToggles.forEach(t=>{t.addEventListener("keydown",e=>{const i=C(e);(["Space","Enter"].includes(i)||this.optionalKeySupport&&["ArrowDown","ArrowUp","Home","End"].includes(i))&&c(e)})})}_handleKeyup(){this.dom.accordionItemToggles.forEach(t=>{t.addEventListener("keyup",e=>{const i=C(e);switch(i){case"Space":case"Enter":c(e),this.currentAccordionItem.toggle();break}if(this.optionalKeySupport)switch(i){case"Home":c(e),this.focusFirstChild();break;case"End":c(e),this.focusLastChild();break;case"ArrowDown":c(e),this.focusNextChild();break;case"ArrowUp":c(e),this.focusPreviousChild();break}})})}_setTransitionDurations(){this.dom.accordion.style.setProperty(`--${this.prefix}accordion-transition-duration`,`${this.transitionDuration}ms`),this.dom.accordion.style.setProperty(`--${this.prefix}accordion-open-transition-duration`,`${this.openDuration}ms`),this.dom.accordion.style.setProperty(`--${this.prefix}accordion-close-transition-duration`,`${this.closeDuration}ms`)}focusCurrentChild(){this.currentChild!==-1&&this.currentAccordionItem.focus()}focusChild(t){this.blurCurrentChild(),this.currentChild=t,this.focusCurrentChild()}focusFirstChild(){this.focusChild(0)}focusLastChild(){this.focusChild(this.elements.accordionItems.length-1)}focusNextChild(){this.currentChild<this.elements.accordionItems.length-1?this.focusChild(this.currentChild+1):this.focusCurrentChild()}focusPreviousChild(){this.currentChild>0?this.focusChild(this.currentChild-1):this.focusCurrentChild()}blurCurrentChild(){this.currentChild!==-1&&this.currentAccordionItem.blur()}openChildren(){this.elements.accordionItems.forEach(t=>t.show())}closeChildren(){this.elements.accordionItems.forEach(t=>t.hide())}},T=$;return T})();
|
|
4
4
|
|
|
5
5
|
//# sourceMappingURL=accordion.iife.js.map
|