@graupl/core 1.0.0-beta.22 → 1.0.0-beta.24
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/base/button.css +2 -2
- package/dist/css/base/button.css.map +1 -1
- package/dist/css/base/form.css +2 -2
- package/dist/css/base/form.css.map +1 -1
- package/dist/css/base/link.css +2 -2
- package/dist/css/base/link.css.map +1 -1
- package/dist/css/base/table.css +2 -2
- package/dist/css/base/table.css.map +1 -1
- package/dist/css/base.css +2 -2
- package/dist/css/base.css.map +1 -1
- package/dist/css/component/accordion.css +2 -5
- package/dist/css/component/accordion.css.map +1 -1
- package/dist/css/component/alert.css +2 -2
- package/dist/css/component/alert.css.map +1 -1
- package/dist/css/component/badge.css +2 -2
- package/dist/css/component/badge.css.map +1 -1
- package/dist/css/component/card.css +2 -2
- package/dist/css/component/card.css.map +1 -1
- package/dist/css/component/carousel.css +2 -2
- package/dist/css/component/carousel.css.map +1 -1
- package/dist/css/component/disclosure.css +2 -2
- package/dist/css/component/disclosure.css.map +1 -1
- package/dist/css/component/input-group.css +2 -2
- package/dist/css/component/input-group.css.map +1 -1
- package/dist/css/component/list.css +2 -2
- package/dist/css/component/list.css.map +1 -1
- package/dist/css/component/menu.css +2 -2
- package/dist/css/component/menu.css.map +1 -1
- package/dist/css/component/navigation.css +2 -2
- package/dist/css/component/navigation.css.map +1 -1
- package/dist/css/component.css +2 -5
- package/dist/css/component.css.map +1 -1
- package/dist/css/graupl.css +2 -5
- package/dist/css/graupl.css.map +1 -1
- package/dist/css/init.css +2 -2
- package/dist/css/init.css.map +1 -1
- package/dist/css/layout/columns.css +2 -2
- package/dist/css/layout/columns.css.map +1 -1
- package/dist/css/layout/container.css +2 -2
- package/dist/css/layout/container.css.map +1 -1
- package/dist/css/layout/flex-columns.css +2 -2
- package/dist/css/layout/flex-columns.css.map +1 -1
- package/dist/css/layout.css +2 -5
- package/dist/css/layout.css.map +1 -1
- package/dist/css/normalize.css +2 -2
- package/dist/css/normalize.css.map +1 -1
- package/dist/css/state/focus.css +2 -2
- package/dist/css/state/focus.css.map +1 -1
- package/dist/css/state.css +2 -2
- package/dist/css/state.css.map +1 -1
- package/dist/css/theme/color.css +2 -2
- package/dist/css/theme/color.css.map +1 -1
- package/dist/css/theme/typography.css +2 -2
- package/dist/css/theme/typography.css.map +1 -1
- package/dist/css/theme.css +2 -2
- package/dist/css/theme.css.map +1 -1
- package/dist/css/utilities/alignment.css +1 -1
- package/dist/css/utilities/alignment.css.map +1 -1
- package/dist/css/utilities/background.css +2 -2
- package/dist/css/utilities/background.css.map +1 -1
- package/dist/css/utilities/border.css +2 -2
- package/dist/css/utilities/border.css.map +1 -1
- package/dist/css/utilities/color.css +2 -2
- package/dist/css/utilities/color.css.map +1 -1
- package/dist/css/utilities/container.css +1 -1
- package/dist/css/utilities/container.css.map +1 -1
- package/dist/css/utilities/display.css +2 -2
- package/dist/css/utilities/display.css.map +1 -1
- package/dist/css/utilities/flex.css +2 -2
- package/dist/css/utilities/flex.css.map +1 -1
- package/dist/css/utilities/gradient.css +2 -2
- package/dist/css/utilities/gradient.css.map +1 -1
- package/dist/css/utilities/height.css +2 -2
- package/dist/css/utilities/height.css.map +1 -1
- package/dist/css/utilities/inset.css +2 -2
- package/dist/css/utilities/inset.css.map +1 -1
- package/dist/css/utilities/justification.css +1 -1
- package/dist/css/utilities/justification.css.map +1 -1
- package/dist/css/utilities/list.css +1 -1
- package/dist/css/utilities/list.css.map +1 -1
- package/dist/css/utilities/order.css +2 -2
- package/dist/css/utilities/order.css.map +1 -1
- package/dist/css/utilities/position.css +2 -2
- package/dist/css/utilities/position.css.map +1 -1
- package/dist/css/utilities/ratio.css +2 -2
- package/dist/css/utilities/ratio.css.map +1 -1
- package/dist/css/utilities/spacing.css +2 -2
- package/dist/css/utilities/spacing.css.map +1 -1
- package/dist/css/utilities/typography.css +2 -2
- package/dist/css/utilities/typography.css.map +1 -1
- package/dist/css/utilities/visibility.css +2 -2
- package/dist/css/utilities/visibility.css.map +1 -1
- package/dist/css/utilities/visually-hidden.css +2 -2
- package/dist/css/utilities/visually-hidden.css.map +1 -1
- package/dist/css/utilities/width.css +2 -2
- package/dist/css/utilities/width.css.map +1 -1
- package/dist/css/utilities/z-index.css +1 -1
- package/dist/css/utilities/z-index.css.map +1 -1
- package/dist/css/utilities.css +2 -2
- package/dist/css/utilities.css.map +1 -1
- package/dist/js/accordion.js.map +1 -1
- package/dist/js/alert.js.map +1 -1
- package/dist/js/carousel.js.map +1 -1
- package/dist/js/component/accordion.cjs.js.map +1 -1
- package/dist/js/component/accordion.es.js.map +1 -1
- 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.map +1 -1
- package/dist/js/component/carousel.cjs.js.map +1 -1
- package/dist/js/component/carousel.es.js.map +1 -1
- package/dist/js/component/carousel.iife.js.map +1 -1
- package/dist/js/component/disclosure.cjs.js +2 -2
- package/dist/js/component/disclosure.cjs.js.map +1 -1
- package/dist/js/component/disclosure.es.js +2 -2
- package/dist/js/component/disclosure.es.js.map +1 -1
- package/dist/js/component/disclosure.iife.js +2 -2
- package/dist/js/component/disclosure.iife.js.map +1 -1
- package/dist/js/component/tabs.cjs.js +5 -0
- package/dist/js/component/tabs.cjs.js.map +1 -0
- package/dist/js/component/tabs.es.js +5 -0
- package/dist/js/component/tabs.es.js.map +1 -0
- package/dist/js/component/tabs.iife.js +5 -0
- package/dist/js/component/tabs.iife.js.map +1 -0
- package/dist/js/disclosure.js +2 -2
- package/dist/js/disclosure.js.map +1 -1
- package/dist/js/generator/accordion.cjs.js.map +1 -1
- package/dist/js/generator/accordion.es.js.map +1 -1
- 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.map +1 -1
- package/dist/js/generator/carousel.cjs.js.map +1 -1
- package/dist/js/generator/carousel.es.js.map +1 -1
- package/dist/js/generator/carousel.iife.js.map +1 -1
- package/dist/js/generator/disclosure.cjs.js +2 -2
- package/dist/js/generator/disclosure.cjs.js.map +1 -1
- package/dist/js/generator/disclosure.es.js +2 -2
- package/dist/js/generator/disclosure.es.js.map +1 -1
- package/dist/js/generator/disclosure.iife.js +2 -2
- package/dist/js/generator/disclosure.iife.js.map +1 -1
- 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.map +1 -1
- package/dist/js/generator/tabs.cjs.js +5 -0
- package/dist/js/generator/tabs.cjs.js.map +1 -0
- package/dist/js/generator/tabs.es.js +5 -0
- package/dist/js/generator/tabs.es.js.map +1 -0
- package/dist/js/generator/tabs.iife.js +5 -0
- package/dist/js/generator/tabs.iife.js.map +1 -0
- package/dist/js/graupl.js +5 -5
- package/dist/js/graupl.js.map +1 -1
- package/dist/js/navigation.js.map +1 -1
- package/dist/js/tabs.js +5 -0
- package/dist/js/tabs.js.map +1 -0
- package/package.json +4 -3
- package/src/js/disclosure/Disclosure.js +25 -45
- package/src/js/domHelpers.js +39 -22
- package/src/js/tabs/TabToggle.js +378 -0
- package/src/js/tabs/Tabs.js +1091 -0
- package/src/js/tabs/generator.js +32 -0
- package/src/js/tabs/index.js +5 -0
- package/src/scss/_defaults.scss +21 -88
- package/src/scss/_variables.scss +70 -0
- package/src/scss/base/button/_defaults.scss +2 -24
- package/src/scss/base/button/_index.scss +53 -52
- package/src/scss/base/button/_mixins.scss +24 -58
- package/src/scss/base/button/_variables.scss +139 -0
- package/src/scss/base/form/_defaults.scss +72 -2
- package/src/scss/base/form/_index.scss +196 -70
- package/src/scss/base/form/_variables.scss +166 -0
- package/src/scss/base/link/_defaults.scss +31 -0
- package/src/scss/base/link/_index.scss +177 -172
- package/src/scss/base/link/_variables.scss +215 -0
- package/src/scss/base/table/_defaults.scss +1 -11
- package/src/scss/base/table/_index.scss +126 -117
- package/src/scss/base/table/_variables.scss +214 -3
- package/src/scss/component/_index.scss +1 -0
- package/src/scss/component/accordion/_defaults.scss +73 -22
- package/src/scss/component/accordion/_index.scss +437 -62
- package/src/scss/component/accordion/_variables.scss +527 -101
- package/src/scss/component/alert/_defaults.scss +23 -32
- package/src/scss/component/alert/_index.scss +236 -30
- package/src/scss/component/alert/_variables.scss +155 -6
- package/src/scss/component/badge/_defaults.scss +1 -0
- package/src/scss/component/badge/_index.scss +25 -28
- package/src/scss/component/badge/_variables.scss +66 -2
- package/src/scss/component/card/_defaults.scss +64 -13
- package/src/scss/component/card/_index.scss +276 -30
- package/src/scss/component/card/_variables.scss +132 -0
- package/src/scss/component/carousel/_defaults.scss +73 -15
- package/src/scss/component/carousel/_index.scss +357 -41
- package/src/scss/component/carousel/_variables.scss +391 -0
- package/src/scss/component/disclosure/_index.scss +4 -4
- package/src/scss/component/disclosure/_variables.scss +127 -2
- package/src/scss/component/input-group/_defaults.scss +10 -3
- package/src/scss/component/input-group/_index.scss +72 -4
- package/src/scss/component/input-group/_variables.scss +37 -0
- package/src/scss/component/list/_defaults.scss +35 -2
- package/src/scss/component/list/_index.scss +159 -5
- package/src/scss/component/list/_variables.scss +152 -0
- package/src/scss/component/menu/_defaults.scss +49 -7
- package/src/scss/component/menu/_index.scss +325 -99
- package/src/scss/component/menu/_variables.scss +484 -1
- package/src/scss/component/navigation/_defaults.scss +45 -3
- package/src/scss/component/navigation/_index.scss +249 -98
- package/src/scss/component/navigation/_variables.scss +334 -5
- package/src/scss/component/tabs/_defaults.scss +82 -0
- package/src/scss/component/tabs/_index.scss +497 -0
- package/src/scss/component/tabs/_variables.scss +974 -0
- package/src/scss/layout/columns/_defaults.scss +5 -3
- package/src/scss/layout/columns/_index.scss +27 -21
- package/src/scss/layout/columns/_variables.scss +13 -0
- package/src/scss/layout/container/_defaults.scss +28 -11
- package/src/scss/layout/container/_index.scss +305 -161
- package/src/scss/layout/container/_variables.scss +148 -15
- package/src/scss/layout/flex-columns/_defaults.scss +5 -3
- package/src/scss/layout/flex-columns/_index.scss +28 -20
- package/src/scss/layout/flex-columns/_variables.scss +9 -0
- package/src/scss/mixins/_state.scss +37 -0
- package/src/scss/mixins/_theme.scss +36 -1
- package/src/scss/state/focus/_index.scss +17 -12
- package/src/scss/state/focus/_variables.scss +30 -4
- package/src/scss/theme/color/_defaults.scss +6 -35
- package/src/scss/theme/color/_index.scss +167 -1
- package/src/scss/theme/color/_variables.scss +155 -0
- package/src/scss/theme/typography/_defaults.scss +26 -19
- package/src/scss/theme/typography/_index.scss +176 -20
- package/src/scss/theme/typography/_variables.scss +186 -0
- package/src/scss/utilities/_template/_index.scss +0 -1
- package/src/scss/utilities/alignment/_defaults.scss +0 -33
- package/src/scss/utilities/alignment/_index.scss +24 -25
- package/src/scss/utilities/background/_defaults.scss +0 -77
- package/src/scss/utilities/background/_index.scss +32 -37
- package/src/scss/utilities/border/_defaults.scss +0 -33
- package/src/scss/utilities/border/_index.scss +25 -26
- package/src/scss/utilities/color/_defaults.scss +0 -19
- package/src/scss/utilities/color/_index.scss +22 -22
- package/src/scss/utilities/container/_defaults.scss +0 -11
- package/src/scss/utilities/container/_index.scss +20 -19
- package/src/scss/utilities/display/_defaults.scss +0 -11
- package/src/scss/utilities/display/_index.scss +20 -19
- package/src/scss/utilities/flex/_defaults.scss +0 -55
- package/src/scss/utilities/flex/_index.scss +28 -31
- package/src/scss/utilities/gradient/_defaults.scss +0 -28
- package/src/scss/utilities/gradient/_index.scss +27 -28
- package/src/scss/utilities/gradient/_variables.scss +15 -0
- package/src/scss/utilities/height/_defaults.scss +0 -8
- package/src/scss/utilities/height/_index.scss +22 -21
- package/src/scss/utilities/inset/_defaults.scss +0 -16
- package/src/scss/utilities/inset/_index.scss +20 -20
- package/src/scss/utilities/justification/_defaults.scss +0 -33
- package/src/scss/utilities/justification/_index.scss +24 -25
- package/src/scss/utilities/list/_defaults.scss +0 -22
- package/src/scss/utilities/list/_index.scss +22 -22
- package/src/scss/utilities/order/_defaults.scss +0 -8
- package/src/scss/utilities/order/_index.scss +20 -19
- package/src/scss/utilities/position/_defaults.scss +0 -11
- package/src/scss/utilities/position/_index.scss +20 -19
- package/src/scss/utilities/ratio/_defaults.scss +0 -8
- package/src/scss/utilities/ratio/_index.scss +22 -21
- package/src/scss/utilities/ratio/_variables.scss +6 -0
- package/src/scss/utilities/spacing/_defaults.scss +0 -11
- package/src/scss/utilities/spacing/_index.scss +18 -17
- package/src/scss/utilities/typography/_defaults.scss +0 -22
- package/src/scss/utilities/typography/_index.scss +27 -26
- package/src/scss/utilities/visibility/_defaults.scss +0 -11
- package/src/scss/utilities/visibility/_index.scss +19 -18
- package/src/scss/utilities/visually-hidden/_index.scss +19 -17
- package/src/scss/utilities/width/_defaults.scss +0 -8
- package/src/scss/utilities/width/_index.scss +21 -20
- package/src/scss/utilities/z-index/_defaults.scss +0 -11
- package/src/scss/utilities/z-index/_index.scss +19 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disclosure.iife.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","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","TransactionalValue","constructor","initialValue","options","_equals","equals","Object","is","_current","_committed","value","val","committed","isDirty","commit","reset","update","fn","isValidInstance","isValidClassList","isValidType","isValidState","isValidEvent","isTag","isQuerySelector","addClass","removeClass","keyPress","preventEvent","storage","TransactionalValue","Disclosure","_dom","controller","disclosure","content","_domLock","_selectors","_classes","open","close","transition","initialize","_durations","_focusState","_currentEvent","_open","_shouldOpen","_closeOnBlur","_breakpointWidth","_observer","_expandEvent","CustomEvent","bubbles","detail","_collapseEvent","_prefix","_key","_errors","constructor","disclosureElement","controllerElement","disclosureContentSelector","openClass","closeClass","transitionClass","transitionDuration","openDuration","closeDuration","closeOnBlur","minWidth","autoOpen","prefix","initializeClass","_validate","Error","errors","join","dom","_generateKey","_setDOMElements","_setIds","_setAriaAttributes","_handleFocus","_handleClick","_handleKeydown","_handleKeyup","_handleResize","_setTransitionDurations","initializeStorage","pushToStorage","id","getAttribute","shouldOpen","window","matchMedia","openQuery","matches","_expand","emit","_collapse","requestAnimationFrame","error","console","selectors","value","focusState","currentEvent","isOpen","hasOpened","committed","closeQuery","shouldFocus","check","key","htmlElementChecks","HTMLElement","status","push","message","querySelectors","querySelector","Object","keys","querySelectorChecks","classes","className","classListChecks","durations","durationName","durationChecks","prefixCheck","regenerate","Math","random","toString","replace","substring","setAttribute","style","setProperty","_setDOMElementType","elementType","base","overwrite","strict","includes","name","domElements","Array","from","querySelectorAll","filteredElements","filter","item","parentElement","isArray","_resetDOMElementType","transitionlass","setTimeout","removeAttribute","dispatchEvent","innert","width","ResizeObserver","entries","entry","boxSize","contentBoxSize","inlineSize","contentRect","belowBreakpoint","aboveBreakpoint","preserveState","observe","document","body","addEventListener","event","relatedTarget","contains","button","toggle","target","force","commit","preview"],"sources":["../../../src/js/validate.js","../../../src/js/domHelpers.js","../../../src/js/eventHandlers.js","../../../src/js/storage.js","../../../src/js/TransactionalValue.js","../../../src/js/disclosure/Disclosure.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 * 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 * A utility class that maintains a \"current\" value and a \"committed\" value.\n *\n * Useful when you need to:\n * - Track in-progress edits and revert to the last saved state.\n * - Compare pending and committed states.\n * - Know if a value has changed since last commit.\n *\n * @example\n * // Managing a form field\n * const username = new TransactionalValue(\"Nick\");\n * username.value = \"NickDJM\";\n * if (username.isDirty) {\n * console.log(\"Unsaved changes detected\");\n * username.commit(); // saves the new value\n * }\n *\n * @example\n * // Reverting edits\n * const counter = new TransactionalValue(10);\n * counter.value = 15;\n * counter.reset(); // reverts to 10\n */\nexport class TransactionalValue {\n /**\n * Creates a new TransactionalValue instance.\n *\n * @param {*} initialValue - The starting (and initially committed) value.\n * @param {{ equals?: function(*, *): boolean }} [options] - Optional config.\n * @param {function(*, *): boolean} [options.equals] - Custom equality comparator. Defaults to `Object.is`.\n */\n constructor(initialValue, options = {}) {\n /**\n * A comparator function used to check equality between\n * the current and committed values.\n *\n * @private\n *\n * @type {function(*, *): boolean}\n */\n this._equals = options.equals || Object.is;\n\n /**\n * The current, editable value.\n *\n * @private\n *\n * @type {*}\n */\n this._current = initialValue;\n\n /**\n * The last committed (baseline) value.\n *\n * @private\n *\n * @type {*}\n */\n this._committed = initialValue;\n }\n\n /**\n * Gets the current editable value.\n *\n * @return {*} The current value.\n *\n * @see _current\n */\n get value() {\n return this._current;\n }\n\n /**\n * Sets the current editable value.\n *\n * @param {*} val - The new value.\n */\n set value(val) {\n this._current = val;\n }\n\n /**\n * Gets the last committed (baseline) value.\n *\n * @readonly\n *\n * @return {*} The last committed value.\n *\n * @see _committed\n */\n get committed() {\n return this._committed;\n }\n\n /**\n * Checks whether the current value differs from the committed one.\n *\n * @readonly\n *\n * @return {boolean} `true` if current and committed values differ.\n */\n get isDirty() {\n return !this._equals(this._current, this._committed);\n }\n\n /**\n * Commits the current value, setting it as the new baseline.\n *\n * @return {TransactionalValue} The current instance.\n */\n commit() {\n this._committed = this._current;\n return this;\n }\n\n /**\n * Resets the current value to the committed baseline.\n *\n * @return {TransactionalValue} The current instance.\n */\n reset() {\n this._current = this._committed;\n return this;\n }\n\n /**\n * Applies a functional update to the current value.\n *\n * @param {function(*): *} fn - A function that receives the previous value and returns the new one.\n * @return {TransactionalValue} The current instance.\n *\n * @example\n * const t = new TransactionalValue(1);\n * t.update(n => n + 1); // 2\n */\n update(fn) {\n this._current = fn(this._current);\n return this;\n }\n}\n","/**\n * @file\n * The Disclosure class.\n */\n\nimport {\n isValidInstance,\n isValidClassList,\n isValidType,\n isValidState,\n isValidEvent,\n isTag,\n isQuerySelector,\n} from \"../validate.js\";\nimport { addClass, removeClass } from \"../domHelpers.js\";\nimport { keyPress, preventEvent } from \"../eventHandlers.js\";\nimport storage from \"../storage.js\";\nimport { TransactionalValue } from \"../TransactionalValue.js\";\n\nclass Disclosure {\n /**\n * The DOM elements within the disclosure.\n *\n * @protected\n *\n * @type {Object<HTMLElement>}\n *\n * @property {HTMLElement} controller - The disclosure toggle element.\n * @property {HTMLElement} disclosure - The disclosure element.\n * @property {HTMLElement} content - The disclosure content element.\n */\n _dom = {\n controller: null,\n disclosure: null,\n content: null,\n };\n\n /**\n * The DOM elements within the disclosure that cannot be reset or generated by the disclosure itself.\n *\n * @protected\n *\n * @type {string[]}\n */\n _domLock = [\"controller\", \"disclosure\"];\n\n /**\n * The query selectors used by the disclosure.\n *\n * @protected\n *\n * @type {Object<string>}\n *\n * @property {string} content - The query selector for the disclosure content.\n */\n _selectors = {\n content: \"\",\n };\n\n /**\n * The classes to apply when the disclosure is in various states.\n *\n * @protected\n *\n * @type {Object<string, string[]>}\n *\n * @property {string|string[]} open - The class(es) to apply when the disclosure is open.\n * @property {string|string[]} close - The class(es) to apply when the disclousre is closed.\n * @property {string|string[]} tranistion - The class(es) to apply when the disclosure is transitioning between states.\n * @property {string|string[]} initialize - The class(es) to apply when the disclosure is initializing.\n */\n _classes = {\n open: \"show\",\n close: \"hide\",\n transition: \"transitioning\",\n initialize: \"initializing\",\n };\n\n /**\n * The duration times (in milliseconds) for various things throughout the disclosure.\n *\n * @protected\n *\n * @type {Object<number>}\n *\n * @property {number} transition - The duration time (in milliseconds) for the transition between open and closed states.\n * @property {number} open - The duration time (in milliseconds) for the transition from closed to open states.\n * @property {number} close - The duration time (in milliseconds) for the transition from open to closed states.\n */\n _durations = {\n transition: 5000,\n open: -1,\n close: -1,\n };\n\n /**\n * The current state of the disclosure's focus.\n *\n * @protected\n *\n * @type {string}\n */\n _focusState = \"none\";\n\n /**\n * This last event triggered on the disclosure.\n *\n * @protected\n *\n * @type {string}\n */\n _currentEvent = \"none\";\n\n /**\n * The open state of the disclosure.\n *\n * @protected\n *\n * @type {TransactionalValue<boolean>}\n */\n _open = new TransactionalValue(false);\n\n /**\n * A value to force the disclosure open when the breakpoint width is passed.\n *\n * @protected\n *\n * @type {boolean}\n */\n _shouldOpen = false;\n\n /**\n * Whether or not to close the disclosure when it loses focus in the DOM.\n *\n * @protected\n *\n * @type {boolean}\n */\n _closeOnBlur = false;\n\n /**\n * The width of the screen (in pixels) that the disclosure will automatically open/close itself.\n *\n * @protected\n *\n * @type {number}\n */\n _breakpointWidth = -1;\n\n /**\n * This ResizeObserver for the disclosure.\n *\n * @protected\n *\n * @type {ResizeObserver|null}\n */\n _observer = null;\n\n /**\n * The event that is triggered when the disclosure expands.\n *\n * @protected\n *\n * @event grauplDisclosureExpand\n *\n * @type {CustomEvent}\n *\n * @property {boolean} bubbles - A flag to bubble the event.\n * @property {Object<Disclosure>} details - The details object containing the Disclosure itself.\n */\n _expandEvent = new CustomEvent(\"grauplDisclosureExpand\", {\n bubbles: true,\n detail: { disclosure: this },\n });\n\n /**\n * The event that is triggered when the disclosure collapses.\n *\n * @protected\n *\n * @event grauplDisclosureCollapse\n *\n * @type {CustomEvent}\n *\n * @property {boolean} bubbles - A flag to bubble the event.\n * @property {Object<Disclosure>} details - The details object containing the Disclosure itself.\n */\n _collapseEvent = new CustomEvent(\"grauplDisclosureCollapse\", {\n bubbles: true,\n detail: { disclosure: this },\n });\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 disclosure.\n *\n * @protected\n *\n * @type {string}\n */\n _key = \"\";\n\n /**\n * An array of error messages generated by the disclosure.\n *\n * @protected\n *\n * @type {string[]}\n */\n _errors = [];\n\n /**\n * Constructs a new `Disclosure`.\n *\n * @param {object} options - The options for generating the disclosure.\n * @param {HTMLElement} options.disclosureElement - The disclosure element in the DOM.\n * @param {HTMLElement} options.controllerElement - The disclosure toggle element in the DOM.\n * @param {string} [options.disclosureContentSelector = .disclosure-content] - The query selector string for the disclosure content.\n * @param {?(string|string[])} [options.openClass = show] - The class to apply when a disclosure is \"open\".\n * @param {?(string|string[])} [options.closeClass = hide] - The class to apply when a disclosure is \"closed\".\n * @param {?(string|string[])} [options.transitionClass = transitioning] - The class to apply when a disclosure is transitioning between \"open\" and \"closed\" states.\n * @param {number} [options.transitionDuration = 250] - The duration of the transition between \"open\" and \"closed\" states (in milliseconds).\n * @param {boolean} [options.openDuration = -1] - The duration of the transition from \"closed\" to \"open\" states (in milliseconds).\n * @param {boolean} [options.closeDuration = -1] - The duration of the transition from \"open\" to \"closed\" states (in milliseconds).\n * @param {boolean} [options.closeOnBlur = false] - Whether to close the disclosure when it loses focus in the dom.\n * @param {boolean} [options.minWidth = -1] - The width of the screen (in pixels) that the disclosure will automatically open/close itself.\n * @param {boolean} [options.autoOpen = false] - Whether to automatically open when above the minWidth.\n * @param {?string} [options.prefix = graupl-] - The prefix to use for CSS custom properties.\n * @param {?(string|string[])} [options.initializeClass = initializing] - The class to apply when a disclosure is initialzing.\n * @param {boolean} [options.initialize = false] - Whether to initialize the disclosure upon construction.\n */\n constructor({\n disclosureElement,\n controllerElement,\n disclosureContentSelector = \".disclosure-content\",\n openClass = \"show\",\n closeClass = \"hide\",\n transitionClass = \"transitioning\",\n transitionDuration = 250,\n openDuration = -1,\n closeDuration = -1,\n closeOnBlur = false,\n minWidth = -1,\n autoOpen = false,\n prefix = \"graupl-\",\n initializeClass = \"initializing\",\n initialize = false,\n }) {\n // Set the DOM elements.\n this._dom.disclosure = disclosureElement;\n this._dom.controller = controllerElement;\n\n // Set the DOM selectors.\n this._selectors.content = disclosureContentSelector;\n\n // Set the classes.\n this._classes.open = openClass || \"\";\n this._classes.close = closeClass || \"\";\n this._classes.transition = transitionClass || \"\";\n this._classes.initialize = initializeClass || \"\";\n\n // Set the transition durations.\n this._durations.transition = transitionDuration;\n this._durations.open = openDuration;\n this._durations.close = closeDuration;\n\n // Set close on blur.\n this._closeOnBlur = closeOnBlur;\n\n // Set collapse width and auto open functionality.\n this._breakpointWidth = minWidth;\n this._shouldOpen = autoOpen;\n\n // Set the prefix.\n this._prefix = prefix;\n\n if (initialize) {\n this.initialize();\n }\n }\n\n /**\n * Initializes the disclosure.\n */\n initialize() {\n try {\n if (!this._validate()) {\n throw new Error(\n `Graupl Disclosure: cannot initialize disclosure. The following errors have been found:\\n - ${this.errors.join(\n \"\\n - \"\n )}`\n );\n }\n\n addClass(this._classes.initialize, this.dom.disclosure);\n\n // Set up the DOM.\n this._generateKey();\n this._setDOMElements();\n this._setIds();\n this._setAriaAttributes();\n\n // Handle events.\n this._handleFocus();\n this._handleClick();\n this._handleKeydown();\n this._handleKeyup();\n this._handleResize();\n\n // Set the custom props.\n this._setTransitionDurations();\n\n // Set up the storage.\n storage.initializeStorage(\"disclosures\");\n storage.pushToStorage(\"disclosures\", this.dom.disclosure.id, this);\n\n if (\n this.dom.controller.getAttribute(\"aria-expanded\") === \"true\" ||\n (this.shouldOpen && window.matchMedia(this.openQuery).matches)\n ) {\n this._expand({ emit: false, transition: false });\n } else {\n this._collapse({ emit: false, transition: false });\n }\n\n requestAnimationFrame(() => {\n removeClass(this._classes.initialize, this.dom.disclosure);\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n /**\n * The DOM elements within the disclosure.\n *\n * @readonly\n *\n * @type {Object<HTMLElement>}\n *\n * @see _dom\n */\n get dom() {\n return this._dom;\n }\n\n /**\n * The query selectors used by the disclosure.\n *\n * @readonly\n *\n * @type {Object<string>}\n *\n * @see _selectors\n */\n get selectors() {\n return this._selectors;\n }\n\n /**\n * The class(es) to apply when the disclosure is open.\n *\n * @type {string|string[]}\n *\n * @see _classes.open\n */\n get openClass() {\n return this._classes.open;\n }\n\n set openClass(value) {\n isValidClassList({ openClass: value });\n\n if (this._classes.open !== value) {\n this._classes.open = value;\n }\n }\n\n /**\n * The class(es) to apply when the disclosure is closed.\n *\n * @type {string|string[]}\n *\n * @see _classes.close\n */\n get closeClass() {\n return this._classes.close;\n }\n\n set closeClass(value) {\n isValidClassList({ closeClass: value });\n\n if (this._classes.close !== value) {\n this._classes.close = value;\n }\n }\n\n /**\n * The class(es) to apply when the disclosure is transitioning between open and closed.\n *\n * @type {string|string[]}\n *\n * @see _classes.transition\n */\n get transitionClass() {\n return this._classes.transition;\n }\n\n set transitionClass(value) {\n isValidClassList({ transitionClass: value });\n\n if (this._classes.transition !== value) {\n this._classes.transition = value;\n }\n }\n\n /**\n * The class(es) to apply to the shelf when the disclosure is initializing.\n *\n * @type {string|string[]}\n *\n * @see _classes\n */\n get initializeClass() {\n return this._classes.initialize;\n }\n\n set initializeClass(value) {\n isValidClassList({ initializeClass: value });\n\n if (this._classes.initialize !== value) {\n this._classes.initialize = value;\n }\n }\n\n /**\n * The duration time (in milliseconds) for the transition between open and closed states.\n *\n * Setting this value will also set the --graupl-transition-duration CSS custom property on the disclosure.\n *\n * @type {number}\n *\n * @see _durations.transition\n */\n get transitionDuration() {\n return this._durations.transition;\n }\n\n set transitionDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._durations.transition !== value) {\n this._durations.transition = value;\n this._setTransitionDurations();\n }\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 value will be used instead.\n *\n * Setting this value will also set the --graupl-open-transition-duration CSS custom property on the disclosure.\n *\n * @type {number}\n *\n * @see _durations.open\n */\n get openDuration() {\n if (this._durations.open === -1) return this.transitionDuration;\n\n return this._durations.open;\n }\n\n set openDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._durations.open !== value) {\n this._durations.open = value;\n this._setTransitionDurations();\n }\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 value will be used instead.\n *\n * Setting this value will also set the --graupl-close-transition-duration CSS custom property on the disclosure.\n *\n * @type {number}\n *\n * @see _durations.close\n */\n get closeDuration() {\n if (this._durations.close === -1) return this.transitionDuration;\n\n return this._durations.close;\n }\n\n set closeDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._durations.close !== value) {\n this._durations.close = value;\n this._setTransitionDurations();\n }\n }\n\n /**\n * The width of the screen (in pixels) that the disclosure will automatically open/close itself.\n *\n * @type {number}\n *\n * @see _breakpointWidth\n */\n get minWidth() {\n return this._breakpointWidth;\n }\n\n set minWidth(value) {\n isValidType(\"number\", { value });\n\n if (this._breakpointWidth !== value) {\n this._breakpointWidth = value;\n }\n }\n\n /**\n * Whether to close the disclosure when it loses focus in the DOM.\n *\n * @type {boolean}\n *\n * @see _closeOnBlur\n */\n get closeOnBlur() {\n return this._closeOnBlur;\n }\n\n set closeOnBlur(value) {\n isValidType(\"boolean\", { value });\n\n if (this._closeOnBlur !== value) {\n this._closeOnBlur = value;\n }\n }\n\n /**\n * The current state of the disclosure's focus.\n *\n * @type {string}\n *\n * @see _focusState\n */\n get focusState() {\n return this._focusState;\n }\n\n set focusState(value) {\n isValidState({ value });\n\n if (this._focusState !== value) {\n this._focusState = value;\n }\n }\n\n /**\n * The last event triggered on the disclosure.\n *\n * @type {string}\n *\n * @see _currentEvent\n */\n get currentEvent() {\n return this._currentEvent;\n }\n\n set currentEvent(value) {\n isValidEvent({ value });\n\n if (this._currentEvent !== value) {\n this._currentEvent = value;\n }\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 set prefix(value) {\n isValidType(\"string\", { value });\n\n if (this._prefix !== value) {\n this._prefix = value;\n this._setTransitionDurations();\n }\n }\n\n /**\n * The open state of the disclosure.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _open\n */\n get isOpen() {\n return this._open.value;\n }\n\n /**\n * The open state of the disclosure that the user specifically triggered.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _open\n */\n get hasOpened() {\n return this._open.committed;\n }\n\n /**\n * A value to force opening reguardless of user interaction.\n *\n * @type {boolean}\n *\n * @see _shouldOpen\n */\n get shouldOpen() {\n return this._shouldOpen;\n }\n\n set shouldOpen(value) {\n isValidType(\"boolean\", { value });\n\n if (this._shouldOpen !== value) {\n this._shouldOpen = value;\n }\n }\n\n /**\n * A media query for when the disclosure should open.\n *\n * Will return an empty string if no min width is set.\n *\n * @readonly\n *\n * @type {string}\n */\n get openQuery() {\n if (this.minWidth === -1) {\n return \"\";\n }\n\n return `(width > ${this.minWidth}px)`;\n }\n\n /**\n * A media query for when the disclosure should close.\n *\n * Will return an empty string if no min width is set.\n *\n * @readonly\n *\n * @type {string}\n */\n get closeQuery() {\n if (this.minWidth === -1) {\n return \"\";\n }\n\n return `(width <= ${this.minWidth}px)`;\n }\n\n /**\n * A flag to check if the disclosure's focus methods should _actually_ move the focus in the DOM.\n *\n * This will be `false` unless any of the following criteria are met:\n * - The disclosure's current event is \"keyboard\".\n *\n * @readonly\n *\n * @type {boolean}\n */\n get shouldFocus() {\n let check = false;\n\n if (this.currentEvent === \"keyboard\") {\n check = true;\n }\n\n return check;\n }\n\n /**\n * The key used to generate IDs throughout the disclosure.\n *\n * @type {string}\n *\n * @see _key\n */\n get key() {\n return this._key;\n }\n\n /**\n * An array of error messages generated by the disclosure.\n *\n * @readonly\n *\n * @type {string[]}\n *\n * @see _errors\n */\n get errors() {\n return this._errors;\n }\n\n /**\n * Validates all aspects on the disclosure 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 disclosureElement: this._dom.disclosure,\n controllerElement: this._dom.controller,\n });\n\n if (!htmlElementChecks.status) {\n this._errors.push(htmlElementChecks.error.message);\n check = false;\n }\n\n // Query selector checks.\n const querySelectors = {};\n\n for (const querySelector of Object.keys(this._selectors)) {\n querySelectors[`${querySelector}Selector`] =\n this._selectors[querySelector];\n }\n\n const querySelectorChecks = isQuerySelector(querySelectors);\n\n if (!querySelectorChecks) {\n this._errors.push(querySelectorChecks.message);\n check = false;\n }\n\n // Class list checks.\n const classes = {};\n\n for (const className of Object.keys(this._classes)) {\n if (this._classes[className] === \"\") {\n continue;\n }\n\n classes[`${className}Class`] = this._classes[className];\n }\n\n const classListChecks = isValidClassList(classes);\n\n if (!classListChecks.status) {\n this._errors.push(classListChecks.error.message);\n check = false;\n }\n\n // Duration checks.\n const durations = {};\n\n for (const durationName of Object.keys(this._durations)) {\n durations[`${durationName}Duration`] = this._durations[durationName];\n }\n\n const durationChecks = isValidType(\"number\", durations);\n\n if (!durationChecks.status) {\n this._errors.push(durationChecks.error.message);\n check = false;\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 * Generates a key for the tabs.\n *\n * @param {Object<boolean>} [options = {}] - Options for generating the key.\n * @param {boolean} [options.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 disclosure and it's controller if they do not already exist.\n *\n * The generated IDs use the key and follow the format:\n * - disclosure: `disclosure-${key}`\n * - controller: `disclosure-controller-${key}`\n *\n * @protected\n */\n _setIds() {\n this.dom.disclosure.id = this.dom.disclosure.id || `disclosure-${this.key}`;\n this.dom.controller.id =\n this.dom.controller.id || `disclosure-controller-${this.key}`;\n }\n\n /**\n * Sets the ARIA attributes on the disclosure and its controller.\n *\n * The first steps are to ensure that the controlled has `aria-expanded` set to \"false\"\n * if it's not already explicity set to \"true\".\n *\n * Then, set the `aria-controls` attribute on the controller to the disclosure's ID.\n *\n * Finally, ensure the controller element has a role of \"button\" if it is not a native button element.\n *\n * @protected\n */\n _setAriaAttributes() {\n // If the controller element doesn't have aria-expanded set to true, set it to false.\n if (this.dom.controller.getAttribute(\"aria-expanded\") !== \"true\") {\n this.dom.controller.setAttribute(\"aria-expanded\", \"false\");\n }\n\n // Set the aria-controls attribute on the controller to the disclosure's ID.\n this.dom.controller.setAttribute(\"aria-controls\", this.dom.disclosure.id);\n\n // If the controller element is not a button, set its role to button.\n if (!isTag(\"button\", { controller: this.dom.controller })) {\n this.dom.controller.setAttribute(\"role\", \"button\");\n }\n }\n\n /**\n * Sets the transition durations of the disclosure as a CSS custom properties.\n *\n * The custom properties are:\n * - `--graupl-disclosure-transition-duration`,\n * - `--graupl-disclosure-open-transition-duration`, and\n * - `--graupl-disclosure-close-transition-duration`.\n *\n * The prefix of `graupl-` can be changed by setting the disclosure's prefix value.\n *\n * @protected\n */\n _setTransitionDurations() {\n this.dom.disclosure.style.setProperty(\n `--${this.prefix}disclosure-transition-duration`,\n `${this.transitionDuration}ms`\n );\n\n this.dom.disclosure.style.setProperty(\n `--${this.prefix}disclosure-open-transition-duration`,\n `${this.openDuration}ms`\n );\n\n this.dom.disclosure.style.setProperty(\n `--${this.prefix}disclosure-close-transition-duration`,\n `${this.closeDuration}ms`\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 {Object<HTMLElement,boolean>} [options = {}] - The options for setting the DOM element type.\n * @param {HTMLElement} [options.base = this.dom.disclosure] - The element used as the base for the querySelector.\n * @param {boolean} [options.overwrite = true] - A flag to set if the existing elements will be overwritten.\n * @param {boolean} [options.strict = true] - A flag to set if the elements must be direct children of the base.\n */\n _setDOMElementType(\n elementType,\n { base = this.dom.disclosure, overwrite = true, strict = true } = {}\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.disclosure) 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 if (Array.isArray(this._dom[elementType])) {\n this._dom[elementType] = filteredElements;\n } else {\n this._dom[elementType] = filteredElements[0] || null;\n }\n } else {\n if (Array.isArray(this._dom[elementType])) {\n this._dom[elementType] = [\n ...this._dom[elementType],\n ...filteredElements,\n ];\n } else {\n this._dom[elementType] = filteredElements[0] || null;\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 disclosure.\n *\n * Utilizes _setDOMElementType and\n * _resetDOMElementType.\n *\n * @protected\n */\n _setDOMElements() {\n this._resetDOMElementType(\"content\");\n this._setDOMElementType(\"content\");\n }\n\n /**\n * Expands the disclosure.\n *\n * Sets the controller's `aria-expanded` to \"true\", adds the\n * open class to the disclosure, and removes the closed class from the disclosure.\n *\n * @protected\n *\n * @fires grauplDisclosureExpand\n *\n * @param {Object<boolean>} [options = {}] - Options for expanding the disclosure.\n * @param {boolean} [options.emit = true] - Emit the expand event once expanded.\n * @param {boolean} [options.transition = true] - Respect the transition class.\n */\n _expand({ emit = true, transition = true } = {}) {\n this.dom.controller.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 close class,\n // add the open class, and finally remove the transition class.\n if (transition && this.transitionlass !== \"\") {\n addClass(this.transitionClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n removeClass(this.closeClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n addClass(this.openClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n setTimeout(() => {\n removeClass(this.transitionClass, this.dom.disclosure);\n }, this.openDuration);\n });\n });\n });\n } else {\n // Add the open class\n addClass(this.openClass, this.dom.disclosure);\n\n // Remove the close class.\n removeClass(this.closeClass, this.dom.disclosure);\n }\n\n this.dom.content.removeAttribute(\"inert\");\n\n if (emit) {\n this.dom.controller.dispatchEvent(this._expandEvent);\n }\n }\n\n /**\n * Collapses the disclosure.\n *\n * Sets the controller's `aria-expanded` to \"false\", adds the\n * close class to the disclosure, and removes the open class from the disclosure.\n *\n * @protected\n *\n * @fires grauplDisclosureCollapse\n *\n * @param {Object<boolean>} [options = {}] - Options for collapsing the disclosure.\n * @param {boolean} [options.emit = true] - Emit the collapse event once collapsed.\n * @param {boolean} [options.transition = true] - Respect the transition class.\n */\n _collapse({ emit = true, transition = true } = {}) {\n this.dom.controller.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 open class,\n // add the close class, and finally remove the transition class.\n if (transition && this.transitionClass !== \"\") {\n addClass(this.transitionClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n removeClass(this.openClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n addClass(this.closeClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n setTimeout(() => {\n removeClass(this.transitionClass, this.dom.disclosure);\n\n this.dom.content.innert = true;\n }, this.closeDuration);\n });\n });\n });\n } else {\n // Add the close class\n addClass(this.closeClass, this.dom.disclosure);\n\n // Remove the open class.\n removeClass(this.openClass, this.dom.disclosure);\n }\n\n this.dom.content.setAttribute(\"inert\", \"true\");\n\n if (emit) {\n this.dom.controller.dispatchEvent(this._collapseEvent);\n }\n }\n\n _handleResize() {\n if (this._breakpointWidth <= 0) {\n return;\n }\n\n let width = 0;\n\n this._observer = new ResizeObserver((entries) => {\n requestAnimationFrame(() => {\n for (const entry of entries) {\n const boxSize = Array.isArray(entry.contentBoxSize)\n ? entry.contentBoxSize[0]\n : entry.contentBoxSize;\n const inlineSize =\n boxSize && typeof boxSize.inlineSize === \"number\"\n ? boxSize.inlineSize\n : entry.contentRect.width;\n\n if (typeof inlineSize !== \"number\") continue;\n\n if (width === inlineSize) continue;\n\n const belowBreakpoint = inlineSize <= this.minWidth;\n const aboveBreakpoint = inlineSize > this.minWidth;\n\n if (belowBreakpoint && this.isOpen) {\n this.close({ preserveState: true });\n } else if (\n aboveBreakpoint &&\n !this.isOpen &&\n (this.hasOpened || this.shouldOpen)\n ) {\n this.open();\n }\n\n width = inlineSize;\n }\n });\n });\n this._observer.observe(document.body);\n }\n\n /**\n * Handles focus events throughout the disclosure.\n *\n * - Adds a `focusout` listener to the disclosure so when the disclosure loses focus it will close.\n */\n _handleFocus() {\n this.dom.disclosure.addEventListener(\"focusout\", (event) => {\n if (\n !this.closeOnBlur ||\n this.currentEvent !== \"keyboard\" ||\n event.relatedTarget === null ||\n this.dom.disclosure.contains(event.relatedTarget) ||\n this.dom.controller === event.relatedTarget\n ) {\n return;\n }\n\n this.close();\n });\n }\n\n /**\n * Handles click events throughout the disclosure.\n *\n * - Adds a `pointerup` listener to the controller that toggles the disclosure.\n * - Adds a `pointerup` listener to the `document` so if the user clicks outside the disclosure it will close.\n */\n _handleClick() {\n this.dom.controller.addEventListener(\"pointerup\", (event) => {\n this.currentEvent = \"mouse\";\n\n if (event.button !== 0) return;\n\n preventEvent(event);\n this.toggle();\n });\n\n document.addEventListener(\"pointerup\", (event) => {\n if (this.focusState !== \"self\" || !this.closeOnBlur) return;\n\n this.currentEvent = \"mouse\";\n\n if (\n !this.dom.disclosure.contains(event.target) &&\n this.dom.controller !== event.target\n ) {\n this.close();\n }\n });\n }\n\n /**\n * Handles keydown events throughout the disclosure.\n *\n * This method exists to assist the _handleKeyup method.\n *\n * - Adds a `keydown` listener to the controller.\n * - Blocks propagation on \"Space\" and \"Enter\" keys.\n * - Adds a `keydown` listener to the disclosure.\n * - Blocks propagation on \"Escape\" keys.\n */\n _handleKeydown() {\n this.dom.controller.addEventListener(\"keydown\", (event) => {\n this.currentEvent = \"keyboard\";\n\n const key = keyPress(event);\n\n switch (key) {\n case \"Space\":\n case \"Enter\":\n preventEvent(event);\n\n break;\n }\n });\n\n this.dom.disclosure.addEventListener(\"keydown\", (event) => {\n this.currentEvent = \"keyboard\";\n\n const key = keyPress(event);\n\n switch (key) {\n case \"Escape\":\n preventEvent(event);\n\n break;\n }\n });\n }\n\n /**\n * Handles keyup events throughout the disclosure.\n *\n * - Adds a `keyup` listener to the controller.\n * - Toggles the disclosure on \"Space\" and \"Enter\" keys.\n * - Adds a `keyup` listener to the disclosure.\n * - Closes the disclosure on \"Escape\" keys.\n */\n _handleKeyup() {\n this.dom.controller.addEventListener(\"keyup\", (event) => {\n this.currentEvent = \"keyboard\";\n\n const key = keyPress(event);\n\n switch (key) {\n case \"Space\":\n case \"Enter\":\n this.toggle();\n\n preventEvent(event);\n\n break;\n }\n });\n\n this.dom.disclosure.addEventListener(\"keyup\", (event) => {\n this.currentEvent = \"keyboard\";\n\n const key = keyPress(event);\n\n switch (key) {\n case \"Escape\":\n this.close();\n\n preventEvent(event);\n\n break;\n }\n });\n }\n\n /**\n * Opens the disclosure.\n *\n * Sets the disclosure's focus state to \"self\", calls expand, and sets isOpen to `true`.\n *\n * @public\n *\n * @param {Object<boolean>} [options = {}] - Options for opening the disclosure.\n * @param {boolean} [options.force = false] - Whether to force the open action.\n * @param {boolean} [options.preserveState = false] - Whether to preserve the open state.\n */\n open({ force = false, preserveState = false } = {}) {\n if (this.isOpen && !force) return;\n\n // Set the focus state.\n this.focusState = \"self\";\n\n // Expand the disclosure.\n this._expand();\n\n // Set the open state.\n this._open.value = true;\n\n if (!preserveState) {\n this._open.commit();\n }\n }\n\n /**\n * Opens the disclosure without entering it.\n *\n * Sets the disclosure's focus state to \"none\", calls expand, and sets isOpen to `true`.\n *\n * @public\n *\n * @param {Object<boolean>} [options = {}] - Options for previewing the disclosure.\n * @param {boolean} [options.force = false] - Whether to force the preview action.\n * @param {boolean} [options.preserveState = false] - Whether to preserve the open state.\n */\n preview({ force = false, preserveState = false } = {}) {\n if (this.isOpen && !force) return;\n\n // Set the focus state.\n this.focusState = \"none\";\n\n // Expand the disclosure.\n this._expand();\n\n // Set the open state.\n this._open.value = true;\n\n if (!preserveState) {\n this._open.commit();\n }\n }\n\n /**\n * Closes the disclosure.\n *\n * Sets the disclosure's focus state to \"none\", calls collapse, and sets isOpen to `false`.\n *\n * @public\n *\n * @param {Object<boolean>} [options = {}] - Options for closing the disclosure.\n * @param {boolean} [options.force = false] - Whether to force the close action.\n * @param {boolean} [options.preserveState = false] - Whether to preserve the open state.\n */\n close({ force = false, preserveState = false } = {}) {\n if (!this.isOpen && !force) return;\n\n // Set the focus state.\n this.focusState = \"none\";\n\n // Collapse the disclosure.\n this._collapse();\n\n // Set the open state.\n this._open.value = false;\n\n if (!preserveState) {\n this._open.commit();\n }\n }\n\n /**\n * Toggles the open state of the disclosure.\n *\n * @public\n *\n * @param {Object<boolean>} [options = {}] - Options for toggling the disclosure.\n * @param {boolean} [options.force = false] - Whether to force the open or close action.\n * @param {boolean} [options.preserveState = false] - Whether to preserve the open state.\n */\n toggle({ force = false, preserveState = false } = {}) {\n if (this.isOpen) {\n this.close({ force, preserveState });\n } else {\n this.open({ force, preserveState });\n }\n }\n}\n\nexport default Disclosure;\n"],"mappings":"2BAeA,SAAgBqH,EAAgByC,EAAa3G,EAAU,CACrD,GAAI,CACF,GAAI,OAAOA,GAAa,SAAU,CAChC,MAAMhD,EAAe,OAAOgD,EAE5B,MAAM,IAAI/C,UACR,qEAAqED,CAAAA,UAAY,EAIrF,UAAWkN,KAAOlK,EAChB,GAAI,EAAEA,EAASkK,CAAAA,YAAgBvD,GAAc,CAC3C,MAAMmF,EAAc,OAAO9L,EAASkK,CAAAA,EACpC,MAAM,IAAIjN,UACR,GAAGiN,CAAAA,2BAA8BvD,EAAYwF,IAAAA,MAAUL,CAAAA,UAAW,EAKxE,MAAO,CACLzB,OAAQ,GACRf,MAAO,YAEFA,EAAO,CACd,MAAO,CACLe,OAAQ,GACRf,MAAAA,IAoBN,SAAgBlF,EAAYhC,EAAM3E,EAAQ,CACxC,GAAI,CACF,GAAI,OAAOA,GAAW,SAAU,CAC9B,MAAMC,EAAa,OAAOD,EAE1B,MAAM,IAAIR,UACR,+DAA+DS,CAAAA,UAAU,EAI7E,UAAWwM,KAAOzM,EAAQ,CACxB,MAAME,EAAY,OAAOF,EAAOyM,CAAAA,EAEhC,GAAIvM,IAAcyE,EAChB,MAAM,IAAInF,UAAU,GAAGiN,CAAAA,cAAiB9H,CAAAA,MAAUzE,CAAAA,UAAS,EAI/D,MAAO,CACL0M,OAAQ,GACRf,MAAO,YAEFA,EAAO,CACd,MAAO,CACLe,OAAQ,GACRf,MAAAA,IAgBN,SAAgB9E,EAAgB/G,EAAQ,CACtC,GAAI,CACF,GAAI,OAAOA,GAAW,SAAU,CAC9B,MAAM2E,EAAO,OAAO3E,EAEpB,MAAM,IAAIR,UACR,mEAAmEmF,CAAAA,UAAI,EAI3E,UAAW8H,KAAOzM,EAChB,GAAI,CACF,GAAIA,EAAOyM,CAAAA,IAAS,KAClB,MAAM,IAAIvC,MAGZoG,SAAStD,cAAchN,EAAOyM,CAAAA,CAAAA,OACxB,CACN,MAAM,IAAIjN,UACR,GAAGiN,CAAAA,qCAAwCzM,EAAOyM,CAAAA,CAAAA,UAAI,EAK5D,MAAO,CACLG,OAAQ,GACRf,MAAO,YAEFA,EAAO,CACd,MAAO,CACLe,OAAQ,GACRf,MAAAA,IAgBN,SAAgBnF,EAAiB1G,EAAQ,CACvC,GAAI,CACF,GAAI,OAAOA,GAAW,UAAY4O,MAAMO,QAAQnP,CAAAA,EAAS,CACvD,MAAM2E,EAAO,OAAO3E,EAEpB,MAAM,IAAIR,UACR,oEAAoEmF,CAAAA,UAAI,EAI5E,UAAW8H,KAAOzM,EAAQ,CACxB,MAAM2E,EAAO,OAAO3E,EAAOyM,CAAAA,EAE3B,GAAI9H,IAAS,SACX,GAAIiK,MAAMO,QAAQnP,EAAOyM,CAAAA,CAAAA,EACvBzM,EAAOyM,CAAAA,EAAK/L,QAASsL,GAAU,CAC7B,GAAI,OAAOA,GAAU,SACnB,MAAM,IAAIxM,UACR,GAAGiN,CAAAA,kFAAG,QAKZ,OAAM,IAAIjN,UACR,GAAGiN,CAAAA,8CAAiD9H,CAAAA,UAAI,MAGvD,CACL,MAAM/D,EAAM,CAAA,EACZA,EAAI6L,CAAAA,EAAOzM,EAAOyM,CAAAA,EAElB1F,EAAgBnG,CAAAA,GAIpB,MAAO,CACLgM,OAAQ,GACRf,MAAO,YAEFA,EAAO,CACd,MAAO,CACLe,OAAQ,GACRf,MAAAA,IAgEN,SAAgB/E,EAAM5F,EAASqB,EAAU,CACvC,GACEoE,EAAY,SAAU,CAAEzF,QAAAA,CAAAA,CAAS,EAAE0L,QACnCnG,EAAgBkG,YAAapK,CAAAA,EAAUqK,OACvC,CACA,MAAMxL,EAAMF,EAAQG,YAAAA,EACpB,IAAImL,EAAQ,GAEZ,UAAWC,KAAOlK,EACZA,EAASkK,CAAAA,EAAKvL,QAAQG,YAAAA,IAAkBD,IAAKoL,EAAQ,IAG3D,OAAOA,MAEP,OAAO,GAiBX,SAAgB5F,EAAa5G,EAAQ,CACnC,GAAI,CACF,GAAI,OAAOA,GAAW,SAAU,CAC9B,MAAM2E,EAAO,OAAO3E,EAEpB,MAAM,IAAIR,UACR,gEAAgEmF,CAAAA,UAAI,EAIxE,MAAMnD,EAAc,CAAC,OAAQ,OAAQ,SAErC,UAAWiL,KAAOzM,EAChB,GAAI,CAACwB,EAAYiN,SAASzO,EAAOyM,CAAAA,CAAAA,EAC/B,MAAM,IAAIjN,UACR,GAAGiN,CAAAA,yCAA4CjL,EAAY4I,KACzD,IAAA,CACD,MAAMpK,EAAOyM,CAAAA,CAAAA,UAAI,EAKxB,MAAO,CACLG,OAAQ,GACRf,MAAO,YAEFA,EAAO,CACd,MAAO,CACLe,OAAQ,GACRf,MAAAA,IAkBN,SAAgBhF,EAAa7G,EAAQ,CACnC,GAAI,CACF,GAAI,OAAOA,GAAW,SAAU,CAC9B,MAAM2E,EAAO,OAAO3E,EAEpB,MAAM,IAAIR,UACR,gEAAgEmF,CAAAA,UAAI,EAIxE,MAAMjD,EAAc,CAAC,OAAQ,QAAS,WAAY,aAElD,UAAW+K,KAAOzM,EAChB,GAAI,CAAC0B,EAAY+M,SAASzO,EAAOyM,CAAAA,CAAAA,EAC/B,MAAM,IAAIjN,UACR,GAAGiN,CAAAA,yCAA4C/K,EAAY0I,KACzD,IAAA,CACD,MAAMpK,EAAOyM,CAAAA,CAAAA,UAAI,EAKxB,MAAO,CACLG,OAAQ,GACRf,MAAO,YAEFA,EAAO,CACd,MAAO,CACLe,OAAQ,GACRf,MAAAA,ICpWN,SAAgB7E,EAASqG,EAAWxL,EAAS,CAEvCwL,IAAc,IAAMA,EAAUvL,SAAW,IAIzC,OAAOuL,GAAc,SACvBxL,EAAQE,UAAUC,IAAIqL,CAAAA,EAEtBxL,EAAQE,UAAUC,IAAI,GAAGqL,CAAAA,GAU7B,SAAgBpG,EAAYoG,EAAWxL,EAAS,CAE1CwL,IAAc,IAAMA,EAAUvL,SAAW,IAIzC,OAAOuL,GAAc,SACvBxL,EAAQE,UAAUG,OAAOmL,CAAAA,EAEzBxL,EAAQE,UAAUG,OAAO,GAAGmL,CAAAA,GC5BhC,SAAgBnG,EAASuJ,EAAO,CAC9B,GAAI,CAEF,MAAMhE,EAAMgE,EAAMhE,KAAOgE,EAAMjN,QACzB0J,EAAO,CACXxJ,MAAO+I,IAAQ,SAAWA,IAAQ,GAClC9I,MAAO8I,IAAQ,KAAOA,IAAQ,YAAcA,IAAQ,GACpD7I,OAAQ6I,IAAQ,UAAYA,IAAQ,OAASA,IAAQ,GACrD5I,QAAS4I,IAAQ,WAAaA,IAAQ,MAAQA,IAAQ,GACtD3I,WAAY2I,IAAQ,cAAgBA,IAAQ,SAAWA,IAAQ,GAC/D1I,UAAW0I,IAAQ,aAAeA,IAAQ,QAAUA,IAAQ,GAC5DzI,UAAWyI,IAAQ,aAAeA,IAAQ,QAAUA,IAAQ,GAC5DxI,KAAMwI,IAAQ,QAAUA,IAAQ,GAChCvI,IAAKuI,IAAQ,OAASA,IAAQ,GAC9BtI,IAAKsI,IAAQ,OAASA,IAAQ,GAGhC,OAAOQ,OAAOC,KAAKA,CAAAA,EAAM7I,KAAMoI,GAAQS,EAAKT,CAAAA,IAAS,EAAA,GAAS,QACxD,CAEN,MAAO,IASX,SAAgBtF,EAAasJ,EAAO,CAClCA,EAAMlM,eAAAA,EACNkM,EAAMjM,gBAAAA,ECzBR,SAAgBwG,EAAkBrG,EAAO,KAAM,CAC7C0G,OAAOxG,OAASwG,OAAOxG,QAAU,CAAA,EAE7B8B,EAAY,SAAU,CAAEhC,KAAAA,CAAAA,CAAM,IAChC0G,OAAOxG,OAAOF,CAAAA,EAAQ0G,OAAOxG,OAAOF,CAAAA,GAAS,CAAA,GAUjD,SAAgBG,EAAWH,EAAO,KAAM,CACtC,OAAIgC,EAAY,SAAU,CAAEhC,KAAAA,CAAAA,CAAM,EACzB0G,OAAOxG,OAAOF,CAAAA,EAGhB0G,OAAOxG,OAShB,SAAgBE,EAAWJ,EAAMK,EAAO,CAAA,EAAI,CACtC2B,EAAY,SAAU,CAAEhC,KAAAA,CAAAA,CAAM,GAAKgC,EAAY,SAAU,CAAE3B,KAAAA,CAAAA,CAAM,IACnEqG,OAAOxG,OAAOF,CAAAA,EAAQK,GAS1B,SAAgBC,EAAaN,EAAM,CAC7BgC,EAAY,SAAU,CAAEhC,KAAAA,CAAAA,CAAM,IAChC0G,OAAOxG,OAAOF,CAAAA,EAAQ,CAAA,GAW1B,SAAgBsG,EAActG,EAAM8H,EAAKT,EAAO,CAC1CrF,EAAY,SAAU,CAAEhC,KAAAA,EAAM8H,IAAAA,EAAK,IACrCpB,OAAOxG,OAAOF,CAAAA,EAAM8H,CAAAA,EAAOT,GAW/B,SAAgB3G,EAAeV,EAAM8H,EAAK,CACxC,OAAI9F,EAAY,SAAU,CAAEhC,KAAAA,EAAM8H,IAAAA,EAAK,EAC9BpB,OAAOxG,OAAOF,CAAAA,EAAM8H,CAAAA,EAGtB,KAST,SAAgBnH,EAAkBX,EAAM8H,EAAK,CACvC9F,EAAY,SAAU,CAAEhC,KAAAA,EAAM8H,IAAAA,EAAK,GACrC,OAAOpB,OAAOxG,OAAOF,CAAAA,EAAM8H,CAAAA,EAI/B,IAAA,EAAe,CACbzB,kBAAAA,EACAlG,WAAAA,EACAC,WAAAA,EACAE,aAAAA,EACAgG,cAAAA,EACA5F,eAAAA,EACAC,kBAAAA,GCjFW+B,EAAb,KAAgC,CAQ9B6B,YAAYzD,EAAcC,EAAU,CAAA,EAAI,CAStC,KAAKC,QAAUD,EAAQE,QAAUqH,OAAOnH,GASxC,KAAKC,SAAWN,EAShB,KAAKO,WAAaP,EAUpB,IAAIuG,OAAQ,CACV,OAAO,KAAKjG,SAQd,IAAIiG,MAAM9F,EAAK,CACb,KAAKH,SAAWG,EAYlB,IAAImG,WAAY,CACd,OAAO,KAAKrG,WAUd,IAAII,SAAU,CACZ,MAAO,CAAC,KAAKT,QAAQ,KAAKI,SAAU,KAAKC,UAAAA,EAQ3CgL,QAAS,CACP,YAAKhL,WAAa,KAAKD,SAChB,KAQTO,OAAQ,CACN,YAAKP,SAAW,KAAKC,WACd,KAaTO,OAAOC,EAAI,CACT,YAAKT,SAAWS,EAAG,KAAKT,QAAAA,EACjB,OCtHLuB,EAAN,KAAiB,CAYfC,KAAO,CACLC,WAAY,KACZC,WAAY,KACZC,QAAS,MAUXC,SAAW,CAAC,aAAc,YAAA,EAW1BC,WAAa,CACXF,QAAS,EAAA,EAeXG,SAAW,CACTC,KAAM,OACNC,MAAO,OACPC,WAAY,gBACZC,WAAY,gBAcdC,WAAa,CACXF,WAAY,IACZF,KAAM,GACNC,MAAO,IAUTI,YAAc,OASdC,cAAgB,OAShBC,MAAQ,IAAIhB,EAAmB,EAAA,EAS/BiB,YAAc,GASdC,aAAe,GASfC,iBAAmB,GASnBC,UAAY,KAcZC,aAAe,IAAIC,YAAY,yBAA0B,CACvDC,QAAS,GACTC,OAAQ,CAAEpB,WAAY,IAAA,EACvB,EAcDqB,eAAiB,IAAIH,YAAY,2BAA4B,CAC3DC,QAAS,GACTC,OAAQ,CAAEpB,WAAY,IAAA,EACvB,EASDsB,QAAU,UASVC,KAAO,GASPC,QAAU,CAAA,EAsBVC,YAAY,CACVC,kBAAAA,EACAC,kBAAAA,EACAC,0BAAAA,EAA4B,sBAC5BC,UAAAA,EAAY,OACZC,WAAAA,EAAa,OACbC,gBAAAA,EAAkB,gBAClBC,mBAAAA,EAAqB,IACrBC,aAAAA,EAAe,GACfC,cAAAA,EAAgB,GAChBC,YAAAA,EAAc,GACdC,SAAAA,EAAW,GACXC,SAAAA,EAAW,GACXC,OAAAA,EAAS,UACTC,gBAAAA,EAAkB,eAClB/B,WAAAA,EAAa,EAAA,EACZ,CAED,KAAKV,KAAKE,WAAa0B,EACvB,KAAK5B,KAAKC,WAAa4B,EAGvB,KAAKxB,WAAWF,QAAU2B,EAG1B,KAAKxB,SAASC,KAAOwB,GAAa,GAClC,KAAKzB,SAASE,MAAQwB,GAAc,GACpC,KAAK1B,SAASG,WAAawB,GAAmB,GAC9C,KAAK3B,SAASI,WAAa+B,GAAmB,GAG9C,KAAK9B,WAAWF,WAAayB,EAC7B,KAAKvB,WAAWJ,KAAO4B,EACvB,KAAKxB,WAAWH,MAAQ4B,EAGxB,KAAKpB,aAAeqB,EAGpB,KAAKpB,iBAAmBqB,EACxB,KAAKvB,YAAcwB,EAGnB,KAAKf,QAAUgB,EAEX9B,GACF,KAAKA,WAAAA,EAOTA,YAAa,CACX,GAAI,CACF,GAAI,CAAC,KAAKgC,UAAAA,EACR,MAAM,IAAIC,MACR;AAAA,KAA8F,KAAKC,OAAOC,KACxG;AAAA,IAAA,CACD,EAAA,EAILpD,EAAS,KAAKa,SAASI,WAAY,KAAKoC,IAAI5C,UAAAA,EAG5C,KAAK6C,aAAAA,EACL,KAAKC,gBAAAA,EACL,KAAKC,QAAAA,EACL,KAAKC,mBAAAA,EAGL,KAAKC,aAAAA,EACL,KAAKC,aAAAA,EACL,KAAKC,eAAAA,EACL,KAAKC,aAAAA,EACL,KAAKC,cAAAA,EAGL,KAAKC,wBAAAA,EAGL3D,EAAQ4D,kBAAkB,aAAA,EAC1B5D,EAAQ6D,cAAc,cAAe,KAAKZ,IAAI5C,WAAWyD,GAAI,IAAA,EAG3D,KAAKb,IAAI7C,WAAW2D,aAAa,eAAA,IAAqB,QACrD,KAAKC,YAAcC,OAAOC,WAAW,KAAKC,SAAAA,EAAWC,QAEtD,KAAKC,QAAQ,CAAEC,KAAM,GAAO1D,WAAY,GAAO,EAE/C,KAAK2D,UAAU,CAAED,KAAM,GAAO1D,WAAY,GAAO,EAGnD4D,sBAAAA,IAA4B,CAC1B3E,EAAY,KAAKY,SAASI,WAAY,KAAKoC,IAAI5C,UAAAA,UAE1CoE,EAAO,CACdC,QAAQD,MAAMA,CAAAA,GAalB,IAAIxB,KAAM,CACR,OAAO,KAAK9C,KAYd,IAAIwE,WAAY,CACd,OAAO,KAAKnE,WAUd,IAAI0B,WAAY,CACd,OAAO,KAAKzB,SAASC,KAGvB,IAAIwB,UAAU0C,EAAO,CACnBtF,EAAiB,CAAE4C,UAAW0C,CAAAA,CAAO,EAEjC,KAAKnE,SAASC,OAASkE,IACzB,KAAKnE,SAASC,KAAOkE,GAWzB,IAAIzC,YAAa,CACf,OAAO,KAAK1B,SAASE,MAGvB,IAAIwB,WAAWyC,EAAO,CACpBtF,EAAiB,CAAE6C,WAAYyC,CAAAA,CAAO,EAElC,KAAKnE,SAASE,QAAUiE,IAC1B,KAAKnE,SAASE,MAAQiE,GAW1B,IAAIxC,iBAAkB,CACpB,OAAO,KAAK3B,SAASG,WAGvB,IAAIwB,gBAAgBwC,EAAO,CACzBtF,EAAiB,CAAE8C,gBAAiBwC,CAAAA,CAAO,EAEvC,KAAKnE,SAASG,aAAegE,IAC/B,KAAKnE,SAASG,WAAagE,GAW/B,IAAIhC,iBAAkB,CACpB,OAAO,KAAKnC,SAASI,WAGvB,IAAI+B,gBAAgBgC,EAAO,CACzBtF,EAAiB,CAAEsD,gBAAiBgC,CAAAA,CAAO,EAEvC,KAAKnE,SAASI,aAAe+D,IAC/B,KAAKnE,SAASI,WAAa+D,GAa/B,IAAIvC,oBAAqB,CACvB,OAAO,KAAKvB,WAAWF,WAGzB,IAAIyB,mBAAmBuC,EAAO,CAC5BrF,EAAY,SAAU,CAAEqF,MAAAA,CAAAA,CAAO,EAE3B,KAAK9D,WAAWF,aAAegE,IACjC,KAAK9D,WAAWF,WAAagE,EAC7B,KAAKjB,wBAAAA,GAeT,IAAIrB,cAAe,CACjB,OAAI,KAAKxB,WAAWJ,OAAS,GAAW,KAAK2B,mBAEtC,KAAKvB,WAAWJ,KAGzB,IAAI4B,aAAasC,EAAO,CACtBrF,EAAY,SAAU,CAAEqF,MAAAA,CAAAA,CAAO,EAE3B,KAAK9D,WAAWJ,OAASkE,IAC3B,KAAK9D,WAAWJ,KAAOkE,EACvB,KAAKjB,wBAAAA,GAeT,IAAIpB,eAAgB,CAClB,OAAI,KAAKzB,WAAWH,QAAU,GAAW,KAAK0B,mBAEvC,KAAKvB,WAAWH,MAGzB,IAAI4B,cAAcqC,EAAO,CACvBrF,EAAY,SAAU,CAAEqF,MAAAA,CAAAA,CAAO,EAE3B,KAAK9D,WAAWH,QAAUiE,IAC5B,KAAK9D,WAAWH,MAAQiE,EACxB,KAAKjB,wBAAAA,GAWT,IAAIlB,UAAW,CACb,OAAO,KAAKrB,iBAGd,IAAIqB,SAASmC,EAAO,CAClBrF,EAAY,SAAU,CAAEqF,MAAAA,CAAAA,CAAO,EAE3B,KAAKxD,mBAAqBwD,IAC5B,KAAKxD,iBAAmBwD,GAW5B,IAAIpC,aAAc,CAChB,OAAO,KAAKrB,aAGd,IAAIqB,YAAYoC,EAAO,CACrBrF,EAAY,UAAW,CAAEqF,MAAAA,CAAAA,CAAO,EAE5B,KAAKzD,eAAiByD,IACxB,KAAKzD,aAAeyD,GAWxB,IAAIC,YAAa,CACf,OAAO,KAAK9D,YAGd,IAAI8D,WAAWD,EAAO,CACpBpF,EAAa,CAAEoF,MAAAA,CAAAA,CAAO,EAElB,KAAK7D,cAAgB6D,IACvB,KAAK7D,YAAc6D,GAWvB,IAAIE,cAAe,CACjB,OAAO,KAAK9D,cAGd,IAAI8D,aAAaF,EAAO,CACtBnF,EAAa,CAAEmF,MAAAA,CAAAA,CAAO,EAElB,KAAK5D,gBAAkB4D,IACzB,KAAK5D,cAAgB4D,GAWzB,IAAIjC,QAAS,CACX,OAAO,KAAKhB,QAGd,IAAIgB,OAAOiC,EAAO,CAChBrF,EAAY,SAAU,CAAEqF,MAAAA,CAAAA,CAAO,EAE3B,KAAKjD,UAAYiD,IACnB,KAAKjD,QAAUiD,EACf,KAAKjB,wBAAAA,GAaT,IAAIoB,QAAS,CACX,OAAO,KAAK9D,MAAM2D,MAYpB,IAAII,WAAY,CACd,OAAO,KAAK/D,MAAMgE,UAUpB,IAAIjB,YAAa,CACf,OAAO,KAAK9C,YAGd,IAAI8C,WAAWY,EAAO,CACpBrF,EAAY,UAAW,CAAEqF,MAAAA,CAAAA,CAAO,EAE5B,KAAK1D,cAAgB0D,IACvB,KAAK1D,YAAc0D,GAavB,IAAIT,WAAY,CACd,OAAI,KAAK1B,WAAa,GACb,GAGF,YAAY,KAAKA,QAAAA,MAY1B,IAAIyC,YAAa,CACf,OAAI,KAAKzC,WAAa,GACb,GAGF,aAAa,KAAKA,QAAAA,MAa3B,IAAI0C,aAAc,CAChB,IAAIC,EAAQ,GAEZ,OAAI,KAAKN,eAAiB,aACxBM,EAAQ,IAGHA,EAUT,IAAIC,KAAM,CACR,OAAO,KAAKzD,KAYd,IAAImB,QAAS,CACX,OAAO,KAAKlB,QAUdgB,WAAY,CACV,IAAIuC,EAAQ,GAGZ,MAAME,EAAoBjG,EAAgBkG,YAAa,CACrDxD,kBAAmB,KAAK5B,KAAKE,WAC7B2B,kBAAmB,KAAK7B,KAAKC,WAC9B,EAEIkF,EAAkBE,SACrB,KAAK3D,QAAQ4D,KAAKH,EAAkBb,MAAMiB,OAAAA,EAC1CN,EAAQ,IAIV,MAAMO,EAAiB,CAAA,EAEvB,UAAWC,KAAiBC,OAAOC,KAAK,KAAKtF,UAAAA,EAC3CmF,EAAe,GAAGC,CAAAA,UAAa,EAC7B,KAAKpF,WAAWoF,CAAAA,EAGpB,MAAMG,EAAsBpG,EAAgBgG,CAAAA,EAEvCI,IACH,KAAKlE,QAAQ4D,KAAKM,EAAoBL,OAAAA,EACtCN,EAAQ,IAIV,MAAMY,EAAU,CAAA,EAEhB,UAAWC,KAAaJ,OAAOC,KAAK,KAAKrF,QAAAA,EACnC,KAAKA,SAASwF,CAAAA,IAAe,KAIjCD,EAAQ,GAAGC,CAAAA,OAAS,EAAW,KAAKxF,SAASwF,CAAAA,GAG/C,MAAMC,EAAkB5G,EAAiB0G,CAAAA,EAEpCE,EAAgBV,SACnB,KAAK3D,QAAQ4D,KAAKS,EAAgBzB,MAAMiB,OAAAA,EACxCN,EAAQ,IAIV,MAAMe,EAAY,CAAA,EAElB,UAAWC,KAAgBP,OAAOC,KAAK,KAAKhF,UAAAA,EAC1CqF,EAAU,GAAGC,CAAAA,UAAY,EAAc,KAAKtF,WAAWsF,CAAAA,EAGzD,MAAMC,EAAiB9G,EAAY,SAAU4G,CAAAA,EAExCE,EAAeb,SAClB,KAAK3D,QAAQ4D,KAAKY,EAAe5B,MAAMiB,OAAAA,EACvCN,EAAQ,IAIV,MAAMkB,EAAc/G,EAAY,SAAU,CAAEoD,OAAQ,KAAKhB,OAAAA,CAAS,EAElE,OAAK2E,EAAYd,SACf,KAAK3D,QAAQ4D,KAAKa,EAAY7B,MAAMiB,OAAAA,EACpCN,EAAQ,IAGHA,EASTlC,aAAa,CAAEqD,WAAAA,EAAa,EAAA,EAAU,CAAA,EAAI,EACpC,KAAKlB,MAAQ,IAAMkB,KACrB,KAAK3E,KAAO4E,KAAKC,OAAAA,EACdC,SAAS,EAAA,EACTC,QAAQ,WAAY,EAAA,EACpBC,UAAU,EAAG,EAAA,GAapBxD,SAAU,CACR,KAAKH,IAAI5C,WAAWyD,GAAK,KAAKb,IAAI5C,WAAWyD,IAAM,cAAc,KAAKuB,GAAAA,GACtE,KAAKpC,IAAI7C,WAAW0D,GAClB,KAAKb,IAAI7C,WAAW0D,IAAM,yBAAyB,KAAKuB,GAAAA,GAe5DhC,oBAAqB,CAEf,KAAKJ,IAAI7C,WAAW2D,aAAa,eAAA,IAAqB,QACxD,KAAKd,IAAI7C,WAAWyG,aAAa,gBAAiB,OAAA,EAIpD,KAAK5D,IAAI7C,WAAWyG,aAAa,gBAAiB,KAAK5D,IAAI5C,WAAWyD,EAAAA,EAGjEpE,EAAM,SAAU,CAAEU,WAAY,KAAK6C,IAAI7C,UAAAA,CAAY,GACtD,KAAK6C,IAAI7C,WAAWyG,aAAa,OAAQ,QAAA,EAgB7ClD,yBAA0B,CACxB,KAAKV,IAAI5C,WAAWyG,MAAMC,YACxB,KAAK,KAAKpE,MAAAA,iCACV,GAAG,KAAKN,kBAAAA,IAAkB,EAG5B,KAAKY,IAAI5C,WAAWyG,MAAMC,YACxB,KAAK,KAAKpE,MAAAA,sCACV,GAAG,KAAKL,YAAAA,IAAY,EAGtB,KAAKW,IAAI5C,WAAWyG,MAAMC,YACxB,KAAK,KAAKpE,MAAAA,uCACV,GAAG,KAAKJ,aAAAA,IAAa,EAiBzByE,mBACEC,EACA,CAAEC,KAAAA,EAAO,KAAKjE,IAAI5C,WAAY8G,UAAAA,EAAY,GAAMC,OAAAA,EAAS,EAAA,EAAS,CAAA,EAClE,CACA,GAAI,OAAO,KAAKzC,UAAUsC,CAAAA,GAAiB,SAAU,CACnD,GAAI,KAAK1G,SAAS8G,SAASJ,CAAAA,EACzB,MAAM,IAAInE,MACR,UAAU,KAAKhB,YAAYwF,IAAAA,MAAUL,CAAAA,qDAAW,EAIhDC,IAAS,KAAKjE,IAAI5C,YAAYhB,EAAgBkG,YAAa,CAAE2B,KAAAA,CAAAA,CAAM,EAQvE,MAAMS,EALcH,MAAMC,KACxBP,EAAKQ,iBAAiB,KAAK/C,UAAUsC,CAAAA,CAAAA,CACvC,EAGqCW,OAAQC,GAC3CT,EAASS,EAAKC,gBAAkBZ,EAAO,EAAA,EAGrCC,EACEK,MAAMO,QAAQ,KAAK5H,KAAK8G,CAAAA,CAAAA,EAC1B,KAAK9G,KAAK8G,CAAAA,EAAeU,EAEzB,KAAKxH,KAAK8G,CAAAA,EAAeU,EAAiB,CAAA,GAAM,KAG9CH,MAAMO,QAAQ,KAAK5H,KAAK8G,CAAAA,CAAAA,EAC1B,KAAK9G,KAAK8G,CAAAA,EAAe,CACvB,GAAG,KAAK9G,KAAK8G,CAAAA,EACb,GAAGU,CAAAA,EAGL,KAAKxH,KAAK8G,CAAAA,EAAeU,EAAiB,CAAA,GAAM,SAIpD,OAAM,IAAI7E,MACR,UAAU,KAAKhB,YAAYwF,IAAAA,MAAUL,CAAAA,gCAAW,EActDe,qBAAqBf,EAAa,CAChC,GAAI,OAAO,KAAKtC,UAAUsC,CAAAA,GAAiB,SAAU,CACnD,GAAI,KAAK1G,SAAS8G,SAASJ,CAAAA,EACzB,MAAM,IAAInE,MACR,UAAU,KAAKhB,YAAYwF,IAAAA,MAAUL,CAAAA,yDAAW,EAIhDO,MAAMO,QAAQ,KAAK5H,KAAK8G,CAAAA,CAAAA,EAC1B,KAAK9G,KAAK8G,CAAAA,EAAe,CAAA,EAEzB,KAAK9G,KAAK8G,CAAAA,EAAe,SAG3B,OAAM,IAAInE,MACR,UAAU,KAAKhB,YAAYwF,IAAAA,MAAUL,CAAAA,gCAAW,EAatD9D,iBAAkB,CAChB,KAAK6E,qBAAqB,SAAA,EAC1B,KAAKhB,mBAAmB,SAAA,EAiB1B3C,QAAQ,CAAEC,KAAAA,EAAO,GAAM1D,WAAAA,EAAa,EAAA,EAAS,CAAA,EAAI,CAC/C,KAAKqC,IAAI7C,WAAWyG,aAAa,gBAAiB,MAAA,EAK9CjG,GAAc,KAAKqH,iBAAmB,IACxCrI,EAAS,KAAKwC,gBAAiB,KAAKa,IAAI5C,UAAAA,EAExCmE,sBAAAA,IAA4B,CAC1B3E,EAAY,KAAKsC,WAAY,KAAKc,IAAI5C,UAAAA,EAEtCmE,sBAAAA,IAA4B,CAC1B5E,EAAS,KAAKsC,UAAW,KAAKe,IAAI5C,UAAAA,EAElCmE,sBAAAA,IAA4B,CAC1B0D,WAAAA,IAAiB,CACfrI,EAAY,KAAKuC,gBAAiB,KAAKa,IAAI5C,UAAAA,GAC1C,KAAKiC,YAAAA,UAMd1C,EAAS,KAAKsC,UAAW,KAAKe,IAAI5C,UAAAA,EAGlCR,EAAY,KAAKsC,WAAY,KAAKc,IAAI5C,UAAAA,GAGxC,KAAK4C,IAAI3C,QAAQ6H,gBAAgB,OAAA,EAE7B7D,GACF,KAAKrB,IAAI7C,WAAWgI,cAAc,KAAK9G,YAAAA,EAkB3CiD,UAAU,CAAED,KAAAA,EAAO,GAAM1D,WAAAA,EAAa,EAAA,EAAS,CAAA,EAAI,CACjD,KAAKqC,IAAI7C,WAAWyG,aAAa,gBAAiB,OAAA,EAK9CjG,GAAc,KAAKwB,kBAAoB,IACzCxC,EAAS,KAAKwC,gBAAiB,KAAKa,IAAI5C,UAAAA,EAExCmE,sBAAAA,IAA4B,CAC1B3E,EAAY,KAAKqC,UAAW,KAAKe,IAAI5C,UAAAA,EAErCmE,sBAAAA,IAA4B,CAC1B5E,EAAS,KAAKuC,WAAY,KAAKc,IAAI5C,UAAAA,EAEnCmE,sBAAAA,IAA4B,CAC1B0D,WAAAA,IAAiB,CACfrI,EAAY,KAAKuC,gBAAiB,KAAKa,IAAI5C,UAAAA,EAE3C,KAAK4C,IAAI3C,QAAQ+H,OAAS,IACzB,KAAK9F,aAAAA,UAMd3C,EAAS,KAAKuC,WAAY,KAAKc,IAAI5C,UAAAA,EAGnCR,EAAY,KAAKqC,UAAW,KAAKe,IAAI5C,UAAAA,GAGvC,KAAK4C,IAAI3C,QAAQuG,aAAa,QAAS,MAAA,EAEnCvC,GACF,KAAKrB,IAAI7C,WAAWgI,cAAc,KAAK1G,cAAAA,EAI3CgC,eAAgB,CACd,GAAI,KAAKtC,kBAAoB,EAC3B,OAGF,IAAIkH,EAAQ,EAEZ,KAAKjH,UAAY,IAAIkH,eAAgBC,GAAY,CAC/ChE,sBAAAA,IAA4B,CAC1B,UAAWiE,KAASD,EAAS,CAC3B,MAAME,EAAUlB,MAAMO,QAAQU,EAAME,cAAAA,EAChCF,EAAME,eAAe,CAAA,EACrBF,EAAME,eACJC,EACJF,GAAW,OAAOA,EAAQE,YAAe,SACrCF,EAAQE,WACRH,EAAMI,YAAYP,MAIxB,GAFI,OAAOM,GAAe,UAEtBN,IAAUM,EAAY,SAE1B,MAAME,EAAkBF,GAAc,KAAKnG,SACrCsG,EAAkBH,EAAa,KAAKnG,SAEtCqG,GAAmB,KAAK/D,OAC1B,KAAKpE,MAAM,CAAEqI,cAAe,EAAA,CAAM,EAElCD,GACA,CAAC,KAAKhE,SACL,KAAKC,WAAa,KAAKhB,aAExB,KAAKtD,KAAAA,EAGP4H,EAAQM,OAId,KAAKvH,UAAU4H,QAAQC,SAASC,IAAAA,EAQlC7F,cAAe,CACb,KAAKL,IAAI5C,WAAW+I,iBAAiB,WAAaC,GAAU,CAExD,CAAC,KAAK7G,aACN,KAAKsC,eAAiB,YACtBuE,EAAMC,gBAAkB,MACxB,KAAKrG,IAAI5C,WAAWkJ,SAASF,EAAMC,aAAAA,GACnC,KAAKrG,IAAI7C,aAAeiJ,EAAMC,eAKhC,KAAK3I,MAAAA,IAUT4C,cAAe,CACb,KAAKN,IAAI7C,WAAWgJ,iBAAiB,YAAcC,GAAU,CAC3D,KAAKvE,aAAe,QAEhBuE,EAAMG,SAAW,IAErBzJ,EAAasJ,CAAAA,EACb,KAAKI,OAAAA,KAGPP,SAASE,iBAAiB,YAAcC,GAAU,CAC5C,KAAKxE,aAAe,QAAU,CAAC,KAAKrC,cAExC,KAAKsC,aAAe,QAGlB,CAAC,KAAK7B,IAAI5C,WAAWkJ,SAASF,EAAMK,MAAAA,GACpC,KAAKzG,IAAI7C,aAAeiJ,EAAMK,QAE9B,KAAK/I,MAAAA,KAeX6C,gBAAiB,CACf,KAAKP,IAAI7C,WAAWgJ,iBAAiB,UAAYC,GAAU,CAKzD,OAJA,KAAKvE,aAAe,WAERhF,EAASuJ,CAAAA,EAErB,CACE,IAAK,QACL,IAAK,QACHtJ,EAAasJ,CAAAA,EAEb,SAIN,KAAKpG,IAAI5C,WAAW+I,iBAAiB,UAAYC,GAAU,CAKzD,OAJA,KAAKvE,aAAe,WAERhF,EAASuJ,CAAAA,EAErB,CACE,IAAK,SACHtJ,EAAasJ,CAAAA,EAEb,SAaR5F,cAAe,CACb,KAAKR,IAAI7C,WAAWgJ,iBAAiB,QAAUC,GAAU,CAKvD,OAJA,KAAKvE,aAAe,WAERhF,EAASuJ,CAAAA,EAErB,CACE,IAAK,QACL,IAAK,QACH,KAAKI,OAAAA,EAEL1J,EAAasJ,CAAAA,EAEb,SAIN,KAAKpG,IAAI5C,WAAW+I,iBAAiB,QAAUC,GAAU,CAKvD,OAJA,KAAKvE,aAAe,WAERhF,EAASuJ,CAAAA,EAErB,CACE,IAAK,SACH,KAAK1I,MAAAA,EAELZ,EAAasJ,CAAAA,EAEb,SAgBR3I,KAAK,CAAEiJ,MAAAA,EAAQ,GAAOX,cAAAA,EAAgB,EAAA,EAAU,CAAA,EAAI,CAC9C,KAAKjE,QAAU,CAAC4E,IAGpB,KAAK9E,WAAa,OAGlB,KAAKR,QAAAA,EAGL,KAAKpD,MAAM2D,MAAQ,GAEdoE,GACH,KAAK/H,MAAM2I,OAAAA,GAefC,QAAQ,CAAEF,MAAAA,EAAQ,GAAOX,cAAAA,EAAgB,EAAA,EAAU,CAAA,EAAI,CACjD,KAAKjE,QAAU,CAAC4E,IAGpB,KAAK9E,WAAa,OAGlB,KAAKR,QAAAA,EAGL,KAAKpD,MAAM2D,MAAQ,GAEdoE,GACH,KAAK/H,MAAM2I,OAAAA,GAefjJ,MAAM,CAAEgJ,MAAAA,EAAQ,GAAOX,cAAAA,EAAgB,EAAA,EAAU,CAAA,EAAI,CAC/C,CAAC,KAAKjE,QAAU,CAAC4E,IAGrB,KAAK9E,WAAa,OAGlB,KAAKN,UAAAA,EAGL,KAAKtD,MAAM2D,MAAQ,GAEdoE,GACH,KAAK/H,MAAM2I,OAAAA,GAafH,OAAO,CAAEE,MAAAA,EAAQ,GAAOX,cAAAA,EAAgB,EAAA,EAAU,CAAA,EAAI,CAChD,KAAKjE,OACP,KAAKpE,MAAM,CAAEgJ,MAAAA,EAAOX,cAAAA,EAAe,EAEnC,KAAKtI,KAAK,CAAEiJ,MAAAA,EAAOX,cAAAA,EAAe,IAKxC,EAAe9I"}
|
|
1
|
+
{"version":3,"file":"disclosure.iife.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","fn","querySelector","elements","Array","from","querySelectorAll","tabbableElements","filter","check","getAttribute","selectFirstFocusableElement","selectLastFocusableElement","selectNextFocusableElement","index","indexOf","selectPreviousFocusableElement","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","TransactionalValue","constructor","initialValue","options","_equals","equals","Object","is","_current","_committed","value","val","committed","isDirty","commit","reset","update","fn","isValidInstance","isValidClassList","isValidType","isValidState","isValidEvent","isTag","isQuerySelector","addClass","removeClass","keyPress","preventEvent","storage","TransactionalValue","Disclosure","_dom","controller","disclosure","content","_domLock","_selectors","_classes","open","close","transition","initialize","_durations","_focusState","_currentEvent","_open","_shouldOpen","_closeOnBlur","_breakpointWidth","_mediaQueryList","_expandEvent","CustomEvent","bubbles","detail","_collapseEvent","_prefix","_key","_errors","constructor","disclosureElement","controllerElement","disclosureContentSelector","openClass","closeClass","transitionClass","transitionDuration","openDuration","closeDuration","closeOnBlur","minWidth","autoOpen","prefix","initializeClass","_validate","Error","errors","join","dom","_generateKey","_setDOMElements","_setIds","_setAriaAttributes","_handleFocus","_handleClick","_handleKeydown","_handleKeyup","_handleResize","_setTransitionDurations","initializeStorage","pushToStorage","id","getAttribute","shouldOpen","window","matchMedia","openQuery","matches","_expand","emit","_collapse","requestAnimationFrame","error","console","selectors","value","focusState","currentEvent","isOpen","hasOpened","committed","closeQuery","shouldFocus","check","key","htmlElementChecks","HTMLElement","status","push","message","querySelectors","querySelector","Object","keys","querySelectorChecks","classes","className","classListChecks","durations","durationName","durationChecks","prefixCheck","regenerate","Math","random","toString","replace","substring","setAttribute","style","setProperty","_setDOMElementType","elementType","base","overwrite","strict","includes","name","domElements","Array","from","querySelectorAll","filteredElements","filter","item","parentElement","isArray","_resetDOMElementType","transitionlass","setTimeout","removeAttribute","dispatchEvent","innert","addEventListener","event","preserveState","relatedTarget","contains","button","toggle","document","target","force","commit","preview"],"sources":["../../../src/js/validate.js","../../../src/js/domHelpers.js","../../../src/js/eventHandlers.js","../../../src/js/storage.js","../../../src/js/TransactionalValue.js","../../../src/js/disclosure/Disclosure.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 * @param {?function(HTMLElement): boolean} [fn = null] - An optional addition filter function to process out focusable elements.\n * @return {HTMLElement[]} - An array of focusable elements.\n */\nexport function selectAllFocusableElements(context = document, fn = null) {\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 if (fn !== null) {\n return tabbableElements.filter(fn);\n } else {\n return tabbableElements;\n }\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 * @param {?function(HTMLElement): boolean} [fn = null] - An optional addition filter function to process out focusable elements.\n * @return {HTMLElement|boolean} - The first focusable element or false if none found.\n */\nexport function selectFirstFocusableElement(context = document, fn = null) {\n const tabbableElements = selectAllFocusableElements(context, fn);\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 * @param {?function(HTMLElement): boolean} [fn = null] - An optional addition filter function to process out focusable elements.\n * @return {HTMLElement|boolean} - The last focusable element or false if none found.\n */\nexport function selectLastFocusableElement(context = document, fn = null) {\n const tabbableElements = selectAllFocusableElements(context, fn);\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 * @param {?function(HTMLElement): boolean} [fn = null] - An optional addition filter function to process out focusable elements.\n * @return {HTMLElement|boolean} - The next focusable element or false if none found.\n */\nexport function selectNextFocusableElement(\n element,\n context = document,\n fn = null\n) {\n const tabbableElements = selectAllFocusableElements(context, fn);\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 * @param {?function(HTMLElement): boolean} [fn = null] - An optional addition filter function to process out focusable elements.\n * @return {HTMLElement|boolean} - The previous focusable element or false if none found.\n */\nexport function selectPreviousFocusableElement(\n element,\n context = document,\n fn = null\n) {\n const tabbableElements = selectAllFocusableElements(context, fn);\n const index = tabbableElements.indexOf(element);\n\n return index === 0 ? false : tabbableElements[index - 1];\n}\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 * A utility class that maintains a \"current\" value and a \"committed\" value.\n *\n * Useful when you need to:\n * - Track in-progress edits and revert to the last saved state.\n * - Compare pending and committed states.\n * - Know if a value has changed since last commit.\n *\n * @example\n * // Managing a form field\n * const username = new TransactionalValue(\"Nick\");\n * username.value = \"NickDJM\";\n * if (username.isDirty) {\n * console.log(\"Unsaved changes detected\");\n * username.commit(); // saves the new value\n * }\n *\n * @example\n * // Reverting edits\n * const counter = new TransactionalValue(10);\n * counter.value = 15;\n * counter.reset(); // reverts to 10\n */\nexport class TransactionalValue {\n /**\n * Creates a new TransactionalValue instance.\n *\n * @param {*} initialValue - The starting (and initially committed) value.\n * @param {{ equals?: function(*, *): boolean }} [options] - Optional config.\n * @param {function(*, *): boolean} [options.equals] - Custom equality comparator. Defaults to `Object.is`.\n */\n constructor(initialValue, options = {}) {\n /**\n * A comparator function used to check equality between\n * the current and committed values.\n *\n * @private\n *\n * @type {function(*, *): boolean}\n */\n this._equals = options.equals || Object.is;\n\n /**\n * The current, editable value.\n *\n * @private\n *\n * @type {*}\n */\n this._current = initialValue;\n\n /**\n * The last committed (baseline) value.\n *\n * @private\n *\n * @type {*}\n */\n this._committed = initialValue;\n }\n\n /**\n * Gets the current editable value.\n *\n * @return {*} The current value.\n *\n * @see _current\n */\n get value() {\n return this._current;\n }\n\n /**\n * Sets the current editable value.\n *\n * @param {*} val - The new value.\n */\n set value(val) {\n this._current = val;\n }\n\n /**\n * Gets the last committed (baseline) value.\n *\n * @readonly\n *\n * @return {*} The last committed value.\n *\n * @see _committed\n */\n get committed() {\n return this._committed;\n }\n\n /**\n * Checks whether the current value differs from the committed one.\n *\n * @readonly\n *\n * @return {boolean} `true` if current and committed values differ.\n */\n get isDirty() {\n return !this._equals(this._current, this._committed);\n }\n\n /**\n * Commits the current value, setting it as the new baseline.\n *\n * @return {TransactionalValue} The current instance.\n */\n commit() {\n this._committed = this._current;\n return this;\n }\n\n /**\n * Resets the current value to the committed baseline.\n *\n * @return {TransactionalValue} The current instance.\n */\n reset() {\n this._current = this._committed;\n return this;\n }\n\n /**\n * Applies a functional update to the current value.\n *\n * @param {function(*): *} fn - A function that receives the previous value and returns the new one.\n * @return {TransactionalValue} The current instance.\n *\n * @example\n * const t = new TransactionalValue(1);\n * t.update(n => n + 1); // 2\n */\n update(fn) {\n this._current = fn(this._current);\n return this;\n }\n}\n","/**\n * @file\n * The Disclosure class.\n */\n\nimport {\n isValidInstance,\n isValidClassList,\n isValidType,\n isValidState,\n isValidEvent,\n isTag,\n isQuerySelector,\n} from \"../validate.js\";\nimport { addClass, removeClass } from \"../domHelpers.js\";\nimport { keyPress, preventEvent } from \"../eventHandlers.js\";\nimport storage from \"../storage.js\";\nimport { TransactionalValue } from \"../TransactionalValue.js\";\n\nclass Disclosure {\n /**\n * The DOM elements within the disclosure.\n *\n * @protected\n *\n * @type {Object<HTMLElement>}\n *\n * @property {HTMLElement} controller - The disclosure toggle element.\n * @property {HTMLElement} disclosure - The disclosure element.\n * @property {HTMLElement} content - The disclosure content element.\n */\n _dom = {\n controller: null,\n disclosure: null,\n content: null,\n };\n\n /**\n * The DOM elements within the disclosure that cannot be reset or generated by the disclosure itself.\n *\n * @protected\n *\n * @type {string[]}\n */\n _domLock = [\"controller\", \"disclosure\"];\n\n /**\n * The query selectors used by the disclosure.\n *\n * @protected\n *\n * @type {Object<string>}\n *\n * @property {string} content - The query selector for the disclosure content.\n */\n _selectors = {\n content: \"\",\n };\n\n /**\n * The classes to apply when the disclosure is in various states.\n *\n * @protected\n *\n * @type {Object<string, string[]>}\n *\n * @property {string|string[]} open - The class(es) to apply when the disclosure is open.\n * @property {string|string[]} close - The class(es) to apply when the disclousre is closed.\n * @property {string|string[]} tranistion - The class(es) to apply when the disclosure is transitioning between states.\n * @property {string|string[]} initialize - The class(es) to apply when the disclosure is initializing.\n */\n _classes = {\n open: \"show\",\n close: \"hide\",\n transition: \"transitioning\",\n initialize: \"initializing\",\n };\n\n /**\n * The duration times (in milliseconds) for various things throughout the disclosure.\n *\n * @protected\n *\n * @type {Object<number>}\n *\n * @property {number} transition - The duration time (in milliseconds) for the transition between open and closed states.\n * @property {number} open - The duration time (in milliseconds) for the transition from closed to open states.\n * @property {number} close - The duration time (in milliseconds) for the transition from open to closed states.\n */\n _durations = {\n transition: 5000,\n open: -1,\n close: -1,\n };\n\n /**\n * The current state of the disclosure's focus.\n *\n * @protected\n *\n * @type {string}\n */\n _focusState = \"none\";\n\n /**\n * This last event triggered on the disclosure.\n *\n * @protected\n *\n * @type {string}\n */\n _currentEvent = \"none\";\n\n /**\n * The open state of the disclosure.\n *\n * @protected\n *\n * @type {TransactionalValue<boolean>}\n */\n _open = new TransactionalValue(false);\n\n /**\n * A value to force the disclosure open when the breakpoint width is passed.\n *\n * @protected\n *\n * @type {boolean}\n */\n _shouldOpen = false;\n\n /**\n * Whether or not to close the disclosure when it loses focus in the DOM.\n *\n * @protected\n *\n * @type {boolean}\n */\n _closeOnBlur = false;\n\n /**\n * The width of the screen that the disclosure will automatically open/close itself.\n *\n * @protected\n *\n * @type {string}\n */\n _breakpointWidth = \"\";\n\n /**\n * This MediaQueryList for the disclosure.\n *\n * @protected\n *\n * @type {MediaQueryList|null}\n */\n _mediaQueryList = null;\n\n /**\n * The event that is triggered when the disclosure expands.\n *\n * @protected\n *\n * @event grauplDisclosureExpand\n *\n * @type {CustomEvent}\n *\n * @property {boolean} bubbles - A flag to bubble the event.\n * @property {Object<Disclosure>} details - The details object containing the Disclosure itself.\n */\n _expandEvent = new CustomEvent(\"grauplDisclosureExpand\", {\n bubbles: true,\n detail: { disclosure: this },\n });\n\n /**\n * The event that is triggered when the disclosure collapses.\n *\n * @protected\n *\n * @event grauplDisclosureCollapse\n *\n * @type {CustomEvent}\n *\n * @property {boolean} bubbles - A flag to bubble the event.\n * @property {Object<Disclosure>} details - The details object containing the Disclosure itself.\n */\n _collapseEvent = new CustomEvent(\"grauplDisclosureCollapse\", {\n bubbles: true,\n detail: { disclosure: this },\n });\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 disclosure.\n *\n * @protected\n *\n * @type {string}\n */\n _key = \"\";\n\n /**\n * An array of error messages generated by the disclosure.\n *\n * @protected\n *\n * @type {string[]}\n */\n _errors = [];\n\n /**\n * Constructs a new `Disclosure`.\n *\n * @param {object} options - The options for generating the disclosure.\n * @param {HTMLElement} options.disclosureElement - The disclosure element in the DOM.\n * @param {HTMLElement} options.controllerElement - The disclosure toggle element in the DOM.\n * @param {string} [options.disclosureContentSelector = .disclosure-content] - The query selector string for the disclosure content.\n * @param {?(string|string[])} [options.openClass = show] - The class to apply when a disclosure is \"open\".\n * @param {?(string|string[])} [options.closeClass = hide] - The class to apply when a disclosure is \"closed\".\n * @param {?(string|string[])} [options.transitionClass = transitioning] - The class to apply when a disclosure is transitioning between \"open\" and \"closed\" states.\n * @param {number} [options.transitionDuration = 250] - The duration of the transition between \"open\" and \"closed\" states (in milliseconds).\n * @param {boolean} [options.openDuration = -1] - The duration of the transition from \"closed\" to \"open\" states (in milliseconds).\n * @param {boolean} [options.closeDuration = -1] - The duration of the transition from \"open\" to \"closed\" states (in milliseconds).\n * @param {boolean} [options.closeOnBlur = false] - Whether to close the disclosure when it loses focus in the dom.\n * @param {?string} [options.minWidth = \"\"] - The width of the screen that the disclosure will automatically open/close itself.\n * @param {boolean} [options.autoOpen = false] - Whether to automatically open when above the minWidth.\n * @param {?string} [options.prefix = graupl-] - The prefix to use for CSS custom properties.\n * @param {?(string|string[])} [options.initializeClass = initializing] - The class to apply when a disclosure is initialzing.\n * @param {boolean} [options.initialize = false] - Whether to initialize the disclosure upon construction.\n */\n constructor({\n disclosureElement,\n controllerElement,\n disclosureContentSelector = \".disclosure-content\",\n openClass = \"show\",\n closeClass = \"hide\",\n transitionClass = \"transitioning\",\n transitionDuration = 250,\n openDuration = -1,\n closeDuration = -1,\n closeOnBlur = false,\n minWidth = \"\",\n autoOpen = false,\n prefix = \"graupl-\",\n initializeClass = \"initializing\",\n initialize = false,\n }) {\n // Set the DOM elements.\n this._dom.disclosure = disclosureElement;\n this._dom.controller = controllerElement;\n\n // Set the DOM selectors.\n this._selectors.content = disclosureContentSelector;\n\n // Set the classes.\n this._classes.open = openClass || \"\";\n this._classes.close = closeClass || \"\";\n this._classes.transition = transitionClass || \"\";\n this._classes.initialize = initializeClass || \"\";\n\n // Set the transition durations.\n this._durations.transition = transitionDuration;\n this._durations.open = openDuration;\n this._durations.close = closeDuration;\n\n // Set close on blur.\n this._closeOnBlur = closeOnBlur;\n\n // Set collapse width and auto open functionality.\n this._breakpointWidth = minWidth || \"\";\n this._shouldOpen = autoOpen;\n\n // Set the prefix.\n this._prefix = prefix;\n\n if (initialize) {\n this.initialize();\n }\n }\n\n /**\n * Initializes the disclosure.\n */\n initialize() {\n try {\n if (!this._validate()) {\n throw new Error(\n `Graupl Disclosure: cannot initialize disclosure. The following errors have been found:\\n - ${this.errors.join(\n \"\\n - \"\n )}`\n );\n }\n\n addClass(this._classes.initialize, this.dom.disclosure);\n\n // Set up the DOM.\n this._generateKey();\n this._setDOMElements();\n this._setIds();\n this._setAriaAttributes();\n\n // Handle events.\n this._handleFocus();\n this._handleClick();\n this._handleKeydown();\n this._handleKeyup();\n this._handleResize();\n\n // Set the custom props.\n this._setTransitionDurations();\n\n // Set up the storage.\n storage.initializeStorage(\"disclosures\");\n storage.pushToStorage(\"disclosures\", this.dom.disclosure.id, this);\n\n if (\n this.dom.controller.getAttribute(\"aria-expanded\") === \"true\" ||\n (this.shouldOpen && window.matchMedia(this.openQuery).matches)\n ) {\n this._expand({ emit: false, transition: false });\n } else {\n this._collapse({ emit: false, transition: false });\n }\n\n requestAnimationFrame(() => {\n removeClass(this._classes.initialize, this.dom.disclosure);\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n /**\n * The DOM elements within the disclosure.\n *\n * @readonly\n *\n * @type {Object<HTMLElement>}\n *\n * @see _dom\n */\n get dom() {\n return this._dom;\n }\n\n /**\n * The query selectors used by the disclosure.\n *\n * @readonly\n *\n * @type {Object<string>}\n *\n * @see _selectors\n */\n get selectors() {\n return this._selectors;\n }\n\n /**\n * The class(es) to apply when the disclosure is open.\n *\n * @type {string|string[]}\n *\n * @see _classes.open\n */\n get openClass() {\n return this._classes.open;\n }\n\n set openClass(value) {\n isValidClassList({ openClass: value });\n\n if (this._classes.open !== value) {\n this._classes.open = value;\n }\n }\n\n /**\n * The class(es) to apply when the disclosure is closed.\n *\n * @type {string|string[]}\n *\n * @see _classes.close\n */\n get closeClass() {\n return this._classes.close;\n }\n\n set closeClass(value) {\n isValidClassList({ closeClass: value });\n\n if (this._classes.close !== value) {\n this._classes.close = value;\n }\n }\n\n /**\n * The class(es) to apply when the disclosure is transitioning between open and closed.\n *\n * @type {string|string[]}\n *\n * @see _classes.transition\n */\n get transitionClass() {\n return this._classes.transition;\n }\n\n set transitionClass(value) {\n isValidClassList({ transitionClass: value });\n\n if (this._classes.transition !== value) {\n this._classes.transition = value;\n }\n }\n\n /**\n * The class(es) to apply to the shelf when the disclosure is initializing.\n *\n * @type {string|string[]}\n *\n * @see _classes\n */\n get initializeClass() {\n return this._classes.initialize;\n }\n\n set initializeClass(value) {\n isValidClassList({ initializeClass: value });\n\n if (this._classes.initialize !== value) {\n this._classes.initialize = value;\n }\n }\n\n /**\n * The duration time (in milliseconds) for the transition between open and closed states.\n *\n * Setting this value will also set the --graupl-transition-duration CSS custom property on the disclosure.\n *\n * @type {number}\n *\n * @see _durations.transition\n */\n get transitionDuration() {\n return this._durations.transition;\n }\n\n set transitionDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._durations.transition !== value) {\n this._durations.transition = value;\n this._setTransitionDurations();\n }\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 value will be used instead.\n *\n * Setting this value will also set the --graupl-open-transition-duration CSS custom property on the disclosure.\n *\n * @type {number}\n *\n * @see _durations.open\n */\n get openDuration() {\n if (this._durations.open === -1) return this.transitionDuration;\n\n return this._durations.open;\n }\n\n set openDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._durations.open !== value) {\n this._durations.open = value;\n this._setTransitionDurations();\n }\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 value will be used instead.\n *\n * Setting this value will also set the --graupl-close-transition-duration CSS custom property on the disclosure.\n *\n * @type {number}\n *\n * @see _durations.close\n */\n get closeDuration() {\n if (this._durations.close === -1) return this.transitionDuration;\n\n return this._durations.close;\n }\n\n set closeDuration(value) {\n isValidType(\"number\", { value });\n\n if (this._durations.close !== value) {\n this._durations.close = value;\n this._setTransitionDurations();\n }\n }\n\n /**\n * The width of the screen that the disclosure will automatically open/close itself.\n *\n * @type {number}\n *\n * @see _breakpointWidth\n */\n get minWidth() {\n return this._breakpointWidth;\n }\n\n set minWidth(value) {\n isValidType(\"string\", { value });\n\n if (this._breakpointWidth !== value) {\n this._breakpointWidth = value;\n }\n }\n\n /**\n * Whether to close the disclosure when it loses focus in the DOM.\n *\n * @type {boolean}\n *\n * @see _closeOnBlur\n */\n get closeOnBlur() {\n return this._closeOnBlur;\n }\n\n set closeOnBlur(value) {\n isValidType(\"boolean\", { value });\n\n if (this._closeOnBlur !== value) {\n this._closeOnBlur = value;\n }\n }\n\n /**\n * The current state of the disclosure's focus.\n *\n * @type {string}\n *\n * @see _focusState\n */\n get focusState() {\n return this._focusState;\n }\n\n set focusState(value) {\n isValidState({ value });\n\n if (this._focusState !== value) {\n this._focusState = value;\n }\n }\n\n /**\n * The last event triggered on the disclosure.\n *\n * @type {string}\n *\n * @see _currentEvent\n */\n get currentEvent() {\n return this._currentEvent;\n }\n\n set currentEvent(value) {\n isValidEvent({ value });\n\n if (this._currentEvent !== value) {\n this._currentEvent = value;\n }\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 set prefix(value) {\n isValidType(\"string\", { value });\n\n if (this._prefix !== value) {\n this._prefix = value;\n this._setTransitionDurations();\n }\n }\n\n /**\n * The open state of the disclosure.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _open\n */\n get isOpen() {\n return this._open.value;\n }\n\n /**\n * The open state of the disclosure that the user specifically triggered.\n *\n * @readonly\n *\n * @type {boolean}\n *\n * @see _open\n */\n get hasOpened() {\n return this._open.committed;\n }\n\n /**\n * A value to force opening reguardless of user interaction.\n *\n * @type {boolean}\n *\n * @see _shouldOpen\n */\n get shouldOpen() {\n return this._shouldOpen;\n }\n\n set shouldOpen(value) {\n isValidType(\"boolean\", { value });\n\n if (this._shouldOpen !== value) {\n this._shouldOpen = value;\n }\n }\n\n /**\n * A media query for when the disclosure should open.\n *\n * Will return an empty string if no min width is set.\n *\n * @readonly\n *\n * @type {string}\n */\n get openQuery() {\n if (this.minWidth === -1) {\n return \"\";\n }\n\n return `(width > ${this.minWidth}px)`;\n }\n\n /**\n * A media query for when the disclosure should close.\n *\n * Will return an empty string if no min width is set.\n *\n * @readonly\n *\n * @type {string}\n */\n get closeQuery() {\n if (this.minWidth === -1) {\n return \"\";\n }\n\n return `(width <= ${this.minWidth}px)`;\n }\n\n /**\n * A flag to check if the disclosure's focus methods should _actually_ move the focus in the DOM.\n *\n * This will be `false` unless any of the following criteria are met:\n * - The disclosure's current event is \"keyboard\".\n *\n * @readonly\n *\n * @type {boolean}\n */\n get shouldFocus() {\n let check = false;\n\n if (this.currentEvent === \"keyboard\") {\n check = true;\n }\n\n return check;\n }\n\n /**\n * The key used to generate IDs throughout the disclosure.\n *\n * @type {string}\n *\n * @see _key\n */\n get key() {\n return this._key;\n }\n\n /**\n * An array of error messages generated by the disclosure.\n *\n * @readonly\n *\n * @type {string[]}\n *\n * @see _errors\n */\n get errors() {\n return this._errors;\n }\n\n /**\n * Validates all aspects on the disclosure 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 disclosureElement: this._dom.disclosure,\n controllerElement: this._dom.controller,\n });\n\n if (!htmlElementChecks.status) {\n this._errors.push(htmlElementChecks.error.message);\n check = false;\n }\n\n // Query selector checks.\n const querySelectors = {};\n\n for (const querySelector of Object.keys(this._selectors)) {\n querySelectors[`${querySelector}Selector`] =\n this._selectors[querySelector];\n }\n\n const querySelectorChecks = isQuerySelector(querySelectors);\n\n if (!querySelectorChecks) {\n this._errors.push(querySelectorChecks.message);\n check = false;\n }\n\n // Class list checks.\n const classes = {};\n\n for (const className of Object.keys(this._classes)) {\n if (this._classes[className] === \"\") {\n continue;\n }\n\n classes[`${className}Class`] = this._classes[className];\n }\n\n const classListChecks = isValidClassList(classes);\n\n if (!classListChecks.status) {\n this._errors.push(classListChecks.error.message);\n check = false;\n }\n\n // Duration checks.\n const durations = {};\n\n for (const durationName of Object.keys(this._durations)) {\n durations[`${durationName}Duration`] = this._durations[durationName];\n }\n\n const durationChecks = isValidType(\"number\", durations);\n\n if (!durationChecks.status) {\n this._errors.push(durationChecks.error.message);\n check = false;\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 * Generates a key for the tabs.\n *\n * @param {Object<boolean>} [options = {}] - Options for generating the key.\n * @param {boolean} [options.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 disclosure and it's controller if they do not already exist.\n *\n * The generated IDs use the key and follow the format:\n * - disclosure: `disclosure-${key}`\n * - controller: `disclosure-controller-${key}`\n *\n * @protected\n */\n _setIds() {\n this.dom.disclosure.id = this.dom.disclosure.id || `disclosure-${this.key}`;\n this.dom.controller.id =\n this.dom.controller.id || `disclosure-controller-${this.key}`;\n }\n\n /**\n * Sets the ARIA attributes on the disclosure and its controller.\n *\n * The first steps are to ensure that the controlled has `aria-expanded` set to \"false\"\n * if it's not already explicity set to \"true\".\n *\n * Then, set the `aria-controls` attribute on the controller to the disclosure's ID.\n *\n * Finally, ensure the controller element has a role of \"button\" if it is not a native button element.\n *\n * @protected\n */\n _setAriaAttributes() {\n // If the controller element doesn't have aria-expanded set to true, set it to false.\n if (this.dom.controller.getAttribute(\"aria-expanded\") !== \"true\") {\n this.dom.controller.setAttribute(\"aria-expanded\", \"false\");\n }\n\n // Set the aria-controls attribute on the controller to the disclosure's ID.\n this.dom.controller.setAttribute(\"aria-controls\", this.dom.disclosure.id);\n\n // If the controller element is not a button, set its role to button.\n if (!isTag(\"button\", { controller: this.dom.controller })) {\n this.dom.controller.setAttribute(\"role\", \"button\");\n }\n }\n\n /**\n * Sets the transition durations of the disclosure as a CSS custom properties.\n *\n * The custom properties are:\n * - `--graupl-disclosure-transition-duration`,\n * - `--graupl-disclosure-open-transition-duration`, and\n * - `--graupl-disclosure-close-transition-duration`.\n *\n * The prefix of `graupl-` can be changed by setting the disclosure's prefix value.\n *\n * @protected\n */\n _setTransitionDurations() {\n this.dom.disclosure.style.setProperty(\n `--${this.prefix}disclosure-transition-duration`,\n `${this.transitionDuration}ms`\n );\n\n this.dom.disclosure.style.setProperty(\n `--${this.prefix}disclosure-open-transition-duration`,\n `${this.openDuration}ms`\n );\n\n this.dom.disclosure.style.setProperty(\n `--${this.prefix}disclosure-close-transition-duration`,\n `${this.closeDuration}ms`\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 {Object<HTMLElement,boolean>} [options = {}] - The options for setting the DOM element type.\n * @param {HTMLElement} [options.base = this.dom.disclosure] - The element used as the base for the querySelector.\n * @param {boolean} [options.overwrite = true] - A flag to set if the existing elements will be overwritten.\n * @param {boolean} [options.strict = true] - A flag to set if the elements must be direct children of the base.\n */\n _setDOMElementType(\n elementType,\n { base = this.dom.disclosure, overwrite = true, strict = true } = {}\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.disclosure) 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 if (Array.isArray(this._dom[elementType])) {\n this._dom[elementType] = filteredElements;\n } else {\n this._dom[elementType] = filteredElements[0] || null;\n }\n } else {\n if (Array.isArray(this._dom[elementType])) {\n this._dom[elementType] = [\n ...this._dom[elementType],\n ...filteredElements,\n ];\n } else {\n this._dom[elementType] = filteredElements[0] || null;\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 disclosure.\n *\n * Utilizes _setDOMElementType and\n * _resetDOMElementType.\n *\n * @protected\n */\n _setDOMElements() {\n this._resetDOMElementType(\"content\");\n this._setDOMElementType(\"content\");\n }\n\n /**\n * Expands the disclosure.\n *\n * Sets the controller's `aria-expanded` to \"true\", adds the\n * open class to the disclosure, and removes the closed class from the disclosure.\n *\n * @protected\n *\n * @fires grauplDisclosureExpand\n *\n * @param {Object<boolean>} [options = {}] - Options for expanding the disclosure.\n * @param {boolean} [options.emit = true] - Emit the expand event once expanded.\n * @param {boolean} [options.transition = true] - Respect the transition class.\n */\n _expand({ emit = true, transition = true } = {}) {\n this.dom.controller.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 close class,\n // add the open class, and finally remove the transition class.\n if (transition && this.transitionlass !== \"\") {\n addClass(this.transitionClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n removeClass(this.closeClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n addClass(this.openClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n setTimeout(() => {\n removeClass(this.transitionClass, this.dom.disclosure);\n }, this.openDuration);\n });\n });\n });\n } else {\n // Add the open class\n addClass(this.openClass, this.dom.disclosure);\n\n // Remove the close class.\n removeClass(this.closeClass, this.dom.disclosure);\n }\n\n this.dom.content.removeAttribute(\"inert\");\n\n if (emit) {\n this.dom.controller.dispatchEvent(this._expandEvent);\n }\n }\n\n /**\n * Collapses the disclosure.\n *\n * Sets the controller's `aria-expanded` to \"false\", adds the\n * close class to the disclosure, and removes the open class from the disclosure.\n *\n * @protected\n *\n * @fires grauplDisclosureCollapse\n *\n * @param {Object<boolean>} [options = {}] - Options for collapsing the disclosure.\n * @param {boolean} [options.emit = true] - Emit the collapse event once collapsed.\n * @param {boolean} [options.transition = true] - Respect the transition class.\n */\n _collapse({ emit = true, transition = true } = {}) {\n this.dom.controller.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 open class,\n // add the close class, and finally remove the transition class.\n if (transition && this.transitionClass !== \"\") {\n addClass(this.transitionClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n removeClass(this.openClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n addClass(this.closeClass, this.dom.disclosure);\n\n requestAnimationFrame(() => {\n setTimeout(() => {\n removeClass(this.transitionClass, this.dom.disclosure);\n\n this.dom.content.innert = true;\n }, this.closeDuration);\n });\n });\n });\n } else {\n // Add the close class\n addClass(this.closeClass, this.dom.disclosure);\n\n // Remove the open class.\n removeClass(this.openClass, this.dom.disclosure);\n }\n\n this.dom.content.setAttribute(\"inert\", \"true\");\n\n if (emit) {\n this.dom.controller.dispatchEvent(this._collapseEvent);\n }\n }\n\n _handleResize() {\n if (this._breakpointWidth === \"\") {\n return;\n }\n\n this._mediaQueryList = window.matchMedia(\n `(width <= ${this._breakpointWidth})`\n );\n\n this._mediaQueryList.addEventListener(\"change\", (event) => {\n if (event.matches && this.isOpen) {\n this.close({ preserveState: true });\n } else if (\n !event.matches &&\n !this.isOpen &&\n (this.hasOpened || this.shouldOpen)\n ) {\n this.open();\n }\n });\n }\n\n /**\n * Handles focus events throughout the disclosure.\n *\n * - Adds a `focusout` listener to the disclosure so when the disclosure loses focus it will close.\n */\n _handleFocus() {\n this.dom.disclosure.addEventListener(\"focusout\", (event) => {\n if (\n !this.closeOnBlur ||\n this.currentEvent !== \"keyboard\" ||\n event.relatedTarget === null ||\n this.dom.disclosure.contains(event.relatedTarget) ||\n this.dom.controller === event.relatedTarget\n ) {\n return;\n }\n\n this.close();\n });\n }\n\n /**\n * Handles click events throughout the disclosure.\n *\n * - Adds a `pointerup` listener to the controller that toggles the disclosure.\n * - Adds a `pointerup` listener to the `document` so if the user clicks outside the disclosure it will close.\n */\n _handleClick() {\n this.dom.controller.addEventListener(\"pointerup\", (event) => {\n this.currentEvent = \"mouse\";\n\n if (event.button !== 0) return;\n\n preventEvent(event);\n this.toggle();\n });\n\n document.addEventListener(\"pointerup\", (event) => {\n if (this.focusState !== \"self\" || !this.closeOnBlur) return;\n\n this.currentEvent = \"mouse\";\n\n if (\n !this.dom.disclosure.contains(event.target) &&\n this.dom.controller !== event.target\n ) {\n this.close();\n }\n });\n }\n\n /**\n * Handles keydown events throughout the disclosure.\n *\n * This method exists to assist the _handleKeyup method.\n *\n * - Adds a `keydown` listener to the controller.\n * - Blocks propagation on \"Space\" and \"Enter\" keys.\n * - Adds a `keydown` listener to the disclosure.\n * - Blocks propagation on \"Escape\" keys.\n */\n _handleKeydown() {\n this.dom.controller.addEventListener(\"keydown\", (event) => {\n this.currentEvent = \"keyboard\";\n\n const key = keyPress(event);\n\n switch (key) {\n case \"Space\":\n case \"Enter\":\n preventEvent(event);\n\n break;\n }\n });\n\n this.dom.disclosure.addEventListener(\"keydown\", (event) => {\n this.currentEvent = \"keyboard\";\n\n const key = keyPress(event);\n\n switch (key) {\n case \"Escape\":\n preventEvent(event);\n\n break;\n }\n });\n }\n\n /**\n * Handles keyup events throughout the disclosure.\n *\n * - Adds a `keyup` listener to the controller.\n * - Toggles the disclosure on \"Space\" and \"Enter\" keys.\n * - Adds a `keyup` listener to the disclosure.\n * - Closes the disclosure on \"Escape\" keys.\n */\n _handleKeyup() {\n this.dom.controller.addEventListener(\"keyup\", (event) => {\n this.currentEvent = \"keyboard\";\n\n const key = keyPress(event);\n\n switch (key) {\n case \"Space\":\n case \"Enter\":\n this.toggle();\n\n preventEvent(event);\n\n break;\n }\n });\n\n this.dom.disclosure.addEventListener(\"keyup\", (event) => {\n this.currentEvent = \"keyboard\";\n\n const key = keyPress(event);\n\n switch (key) {\n case \"Escape\":\n this.close();\n\n preventEvent(event);\n\n break;\n }\n });\n }\n\n /**\n * Opens the disclosure.\n *\n * Sets the disclosure's focus state to \"self\", calls expand, and sets isOpen to `true`.\n *\n * @public\n *\n * @param {Object<boolean>} [options = {}] - Options for opening the disclosure.\n * @param {boolean} [options.force = false] - Whether to force the open action.\n * @param {boolean} [options.preserveState = false] - Whether to preserve the open state.\n */\n open({ force = false, preserveState = false } = {}) {\n if (this.isOpen && !force) return;\n\n // Set the focus state.\n this.focusState = \"self\";\n\n // Expand the disclosure.\n this._expand();\n\n // Set the open state.\n this._open.value = true;\n\n if (!preserveState) {\n this._open.commit();\n }\n }\n\n /**\n * Opens the disclosure without entering it.\n *\n * Sets the disclosure's focus state to \"none\", calls expand, and sets isOpen to `true`.\n *\n * @public\n *\n * @param {Object<boolean>} [options = {}] - Options for previewing the disclosure.\n * @param {boolean} [options.force = false] - Whether to force the preview action.\n * @param {boolean} [options.preserveState = false] - Whether to preserve the open state.\n */\n preview({ force = false, preserveState = false } = {}) {\n if (this.isOpen && !force) return;\n\n // Set the focus state.\n this.focusState = \"none\";\n\n // Expand the disclosure.\n this._expand();\n\n // Set the open state.\n this._open.value = true;\n\n if (!preserveState) {\n this._open.commit();\n }\n }\n\n /**\n * Closes the disclosure.\n *\n * Sets the disclosure's focus state to \"none\", calls collapse, and sets isOpen to `false`.\n *\n * @public\n *\n * @param {Object<boolean>} [options = {}] - Options for closing the disclosure.\n * @param {boolean} [options.force = false] - Whether to force the close action.\n * @param {boolean} [options.preserveState = false] - Whether to preserve the open state.\n */\n close({ force = false, preserveState = false } = {}) {\n if (!this.isOpen && !force) return;\n\n // Set the focus state.\n this.focusState = \"none\";\n\n // Collapse the disclosure.\n this._collapse();\n\n // Set the open state.\n this._open.value = false;\n\n if (!preserveState) {\n this._open.commit();\n }\n }\n\n /**\n * Toggles the open state of the disclosure.\n *\n * @public\n *\n * @param {Object<boolean>} [options = {}] - Options for toggling the disclosure.\n * @param {boolean} [options.force = false] - Whether to force the open or close action.\n * @param {boolean} [options.preserveState = false] - Whether to preserve the open state.\n */\n toggle({ force = false, preserveState = false } = {}) {\n if (this.isOpen) {\n this.close({ force, preserveState });\n } else {\n this.open({ force, preserveState });\n }\n }\n}\n\nexport default Disclosure;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
function h(t,e){t===""||t.length===0||(typeof t=="string"?e.classList.add(t):e.classList.add(...t))}function l(t,e){t===""||t.length===0||(typeof t=="string"?e.classList.remove(t):e.classList.remove(...t))}var A=class{constructor(t,e={}){this._equals=e.equals||Object.is,this._current=t,this._committed=t}get value(){return this._current}set value(t){this._current=t}get committed(){return this._committed}get isDirty(){return!this._equals(this._current,this._committed)}commit(){return this._committed=this._current,this}reset(){return this._current=this._committed,this}update(t){return this._current=t(this._current),this}},k=class{_dom={toggle:null,content:null};_elements={parent:null};_active=new A(!1);_activateEvent=new CustomEvent("grauplTabToggleActivate",{bubbles:!0,detail:{item:this}});_deactivateEvent=new CustomEvent("grauplTabToggleDeactivate",{bubbles:!0,detail:{item:this}});constructor({toggleElement:t,contentElement:e,parentTab:s}){this._dom.toggle=t,this._dom.content=e,this._elements.parent=s}initialize(){this._setIds(),this._setAriaAttributes(),this.dom.toggle.getAttribute("aria-selected")==="true"?this.show():this._deactivate({emit:!1,transition:!1})}get dom(){return this._dom}get elements(){return this._elements}get isActive(){return this._active.value}_setIds(){const{key:t}=this.elements.parent,e=this.elements.parent.dom.tabToggle.indexOf(this.dom.toggle);this.dom.toggle.id=this.dom.toggle.id||`tab-toggle-${t}-${e}`,this.dom.content.id=this.dom.content.id||`tab-content-${t}-${e}`}_setAriaAttributes(){this.dom.toggle.setAttribute("role","tab"),this.dom.toggle.getAttribute("aria-selected")!=="true"&&this.dom.toggle.setAttribute("aria-selected","false"),this.dom.toggle.setAttribute("aria-controls",this.dom.content.id),this.dom.content.setAttribute("role","tabpanel")}_activate({emit:t=!0,transition:e=!0}={}){const{closeClass:s,openClass:i,transitionClass:o,openDuration:a}=this.elements.parent;this.dom.toggle.setAttribute("aria-selected","true"),e&&o!==""?(h(o,this.dom.content),requestAnimationFrame(()=>{l(s,this.dom.content),requestAnimationFrame(()=>{h(i,this.dom.content),requestAnimationFrame(()=>{setTimeout(()=>{l(o,this.dom.content)},a)})})})):(h(i,this.dom.content),l(s,this.dom.content)),t&&this.dom.toggle.dispatchEvent(this._activateEvent)}_deactivate({emit:t=!0,transition:e=!0}={}){const{closeClass:s,openClass:i,transitionClass:o,closeDuration:a}=this.elements.parent;this.dom.toggle.setAttribute("aria-selected","false"),e&&o!==""?(h(o,this.dom.content),requestAnimationFrame(()=>{l(i,this.dom.content),requestAnimationFrame(()=>{h(s,this.dom.content),requestAnimationFrame(()=>{setTimeout(()=>{l(o,this.dom.content)},a)})})})):(h(s,this.dom.content),l(i,this.dom.content)),t&&this.dom.toggle.dispatchEvent(this._deactivateEvent)}show({force:t=!1,preserveState:e=!1}={}){this.isActive&&!t||(this.elements.parent.focusState="self",this._activate(),this._active.value=!0,e||this._active.commit(),this.dom.toggle.setAttribute("tabindex","0"),this.deactivateSiblings())}hide({force:t=!1,preserveState:e=!1}={}){!this.isActive&&!t||(this.elements.parent.focusState="none",this._deactivate(),this._active.value=!1,e||this._active.commit(),this.dom.toggle.setAttribute("tabindex","-1"))}focus(){this.dom.toggle.focus()}blur(){this.dom.toggle.blur()}deactivateSiblings(){this.elements.parent&&this.elements.parent.elements.tabToggle.forEach(t=>{t!==this&&t.hide()})}},$=k;function _(t,e){try{if(typeof e!="object"){const s=typeof e;throw new TypeError(`Elements given to isValidInstance() must be inside of an object. "${s}" given.`)}for(const s in e)if(!(e[s]instanceof t)){const i=typeof e[s];throw new TypeError(`${s} must be an instance of ${t.name}. "${i}" given.`)}return{status:!0,error:null}}catch(s){return{status:!1,error:s}}}function r(t,e){try{if(typeof e!="object"){const s=typeof e;throw new TypeError(`Values given to isValidType() must be inside of an object. "${s}" given.`)}for(const s in e){const i=typeof e[s];if(i!==t)throw new TypeError(`${s} must be a ${t}. "${i}" given.`)}return{status:!0,error:null}}catch(s){return{status:!1,error:s}}}function b(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 m(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 s=typeof t[e];if(s!=="string")if(Array.isArray(t[e]))t[e].forEach(i=>{if(typeof i!="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. "${s}" given.`);else{const i={};i[e]=t[e],b(i)}}return{status:!0,error:null}}catch(e){return{status:!1,error:e}}}function v(t){try{if(typeof t!="object"){const s=typeof t;throw new TypeError(`Values given to isValidState() must be inside of an object. "${s}" given.`)}const e=["none","self","child"];for(const s in t)if(!e.includes(t[s]))throw new TypeError(`${s} must be one of the following values: ${e.join(", ")}. "${t[s]}" given.`);return{status:!0,error:null}}catch(e){return{status:!1,error:e}}}function D(t){try{if(typeof t!="object"){const s=typeof t;throw new TypeError(`Values given to isValidEvent() must be inside of an object. "${s}" given.`)}const e=["none","mouse","keyboard","character"];for(const s in t)if(!e.includes(t[s]))throw new TypeError(`${s} must be one of the following values: ${e.join(", ")}. "${t[s]}" given.`);return{status:!0,error:null}}catch(e){return{status:!1,error:e}}}function p(t){try{const e=t.key||t.keyCode,s={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(s).find(i=>s[i]===!0)||""}catch{return""}}function c(t){t.preventDefault(),t.stopPropagation()}function S(t=null){window.Graupl=window.Graupl||{},r("string",{type:t})&&(window.Graupl[t]=window.Graupl[t]||{})}function L(t=null){return r("string",{type:t})?window.Graupl[t]:window.Graupl}function j(t,e={}){r("string",{type:t})&&r("object",{data:e})&&(window.Graupl[t]=e)}function x(t){r("string",{type:t})&&(window.Graupl[t]={})}function O(t,e,s){r("string",{type:t,key:e})&&(window.Graupl[t][e]=s)}function q(t,e){return r("string",{type:t,key:e})?window.Graupl[t][e]:null}function G(t,e){r("string",{type:t,key:e})&&delete window.Graupl[t][e]}var y={initializeStorage:S,getStorage:L,setStorage:j,clearStorage:x,pushToStorage:O,getFromStorage:q,removeFromStorage:G},M=class{_dom={tabs:null,tabList:null,tabToggle:[],tabContent:[]};_domLock=["tab"];_selectors={tabList:"",tabToggle:"",tabContent:""};_elements={tabToggle:[]};_classes={open:"show",close:"hide",transition:"transitioning",initialize:"initializing"};_durations={transition:250,open:-1,close:-1};_focusState="none";_currentEvent="none";_automatic=!1;_currentChild=0;_prefix="graupl-";_key="";_errors=[];constructor({tabsElement:t,tabListSelector:e=".tab-list",tabToggleSelector:s=".tab-toggle",tabContentSelector:i=".tab-content",openClass:o="show",closeClass:a="hide",transitionClass:u=null,transitionDuration:d=300,openDuration:f=-1,closeDuration:g=-1,automaticActivation:n=!1,prefix:w="graupl-",key:E=null,initializeClass:C="initializing",initialize:T=!1}){this._dom.tabs=t,this._selectors.tabList=e,this._selectors.tabToggle=s,this._selectors.tabContent=i,this._classes.open=o||"",this._classes.close=a||"",this._classes.transition=u||"",this._classes.initialize=C||"",this._durations.transition=d,this._durations.open=f,this._durations.close=g,this._automatic=n,this._prefix=w||"",this._key=E||"",T&&this.initialize()}initialize(){try{if(!this._validate())throw new Error(`Graupl Tab: cannot initialize tab. The following errors have been found:
|
|
2
|
+
- ${this.errors.join(`
|
|
3
|
+
- `)}`);h(this._classes.initialize,this.dom.tabs),this._generateKey(),this._setDOMElements(),this._setIds(),this._setAriaAttributes(),this._createChildElements(),this._handleFocus(),this._handleClick(),this._handleKeydown(),this._handleKeyup(),this._setTransitionDurations(),y.initializeStorage("tabs"),y.pushToStorage("tabs",this.dom.tabs.id,this),this.elements.tabToggle.filter(t=>t.isActive).length===0&&this.elements.tabToggle[0].show(),requestAnimationFrame(()=>{l(this._classes.initialize,this.dom.tabs)})}catch(t){console.error(t)}}get dom(){return this._dom}get elements(){return this._elements}get selectors(){return this._selectors}get openClass(){return this._classes.open}set openClass(t){m({openClass:t}),this._classes.open!==t&&(this._classes.open=t)}get closeClass(){return this._classes.close}set closeClass(t){m({closeClass:t}),this._classes.close!==t&&(this._classes.close=t)}get transitionClass(){return this._classes.transition}set transitionClass(t){m({transitionClass:t}),this._classes.transition!==t&&(this._classes.transition=t)}get transitionDuration(){return this._durations.transition}set transitionDuration(t){r("number",{value:t}),this._durations.transition!==t&&(this._durations.transition=t,this._setTransitionDurations())}get openDuration(){return this._durations.open===-1?this.transitionDuration:this._durations.open}set openDuration(t){r("number",{value:t}),this._durations.open!==t&&(this._durations.open=t,this._setTransitionDurations())}get closeDuration(){return this._durations.close===-1?this.transitionDuration:this._durations.close}set closeDuration(t){r("number",{value:t}),this._durations.close!==t&&(this._durations.close=t,this._setTransitionDurations())}get isAutomatic(){return this._automatic}set isAutomatic(t){r("boolean",{value:t}),this._automatic!==t&&(this._automatic=t)}get currentChild(){return this._currentChild}set currentChild(t){r("number",{value:t}),this._currentChild!==t&&t>=0&&t<this.elements.tabToggle.length&&(this._currentChild=t)}get currentTabToggle(){return this.elements.tabToggle[this.currentChild]}get focusState(){return this._focusState}set focusState(t){v({value:t}),this._focusState!==t&&(this._focusState=t)}get currentEvent(){return this._currentEvent}set currentEvent(t){D({value:t}),this._currentEvent!==t&&(this._currentEvent=t)}get prefix(){return this._prefix}set prefix(t){r("string",{value:t}),this._prefix!==t&&(this._prefix=t)}get key(){return this._key}get errors(){return this._errors}_validate(){let t=!0;const e=_(HTMLElement,{tabsElement:this.dom.tabs});e||(this._errors.push(e.message),t=!1);const s={};for(const n of Object.keys(this._selectors))s[`${n}Selector`]=this._selectors[n];const i=b(s);i||(this._errors.push(i.message),t=!1);const o={};for(const n of Object.keys(this._classes))this._classes[n]!==""&&(o[`${n}Class`]=this._classes[n]);const a=m(o);a.status||(this._errors.push(a.error.message),t=!1);const u={};for(const n of Object.keys(this._durations))u[`${n}Duration`]=this._durations[n];const d=r("number",u);d.status||(this._errors.push(d.error.message),t=!1);const f=r("boolean",{automaticActivation:this._automatic});if(f.status||(this._errors.push(f.error.message),t=!1),this._key!==""){const n=r("string",{key:this._key});n.status||(this._errors.push(n.error.message),t=!1)}const g=r("string",{prefix:this._prefix});return g.status||(this._errors.push(g.error.message),t=!1),t}_generateKey({regenerate:t=!1}={}){(this.key===""||t)&&(this._key=Math.random().toString(36).replace(/[^a-z]+/g,"").substring(0,10))}_setIds(){this.dom.tabs.id=this.dom.tabs.id||`tabs-${this.key}`,this.dom.tabList.id=this.dom.tabList.id||`tab-list-${this.key}`}_setAriaAttributes(){this.dom.tabList.setAttribute("role","tablist")}_setTransitionDurations(){this.dom.tabs.style.setProperty(`--${this.prefix}tabs-transition-duration`,`${this.transitionDuration}ms`),this.dom.tabs.style.setProperty(`--${this.prefix}tabs-open-transition-duration`,`${this.openDuration}ms`),this.dom.tabs.style.setProperty(`--${this.prefix}tabs-close-transition-duration`,`${this.closeDuration}ms`)}_setDOMElementType(t,{base:e=this.dom.tabs,overwrite:s=!0,strict:i=!0}={}){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.tabs&&_(HTMLElement,{base:e});const o=Array.from(e.querySelectorAll(this.selectors[t])).filter(a=>i?a.parentElement===e:!0);s?Array.isArray(this._dom[t])?this._dom[t]=o:this._dom[t]=o[0]||null:Array.isArray(this._dom[t])?this._dom[t]=[...this._dom[t],...o]:this._dom[t]=o[0]||null}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._resetDOMElementType("tabList"),this._setDOMElementType("tabList"),this.dom.tabList&&(this._resetDOMElementType("tabToggle"),this._setDOMElementType("tabToggle",{base:this.dom.tabList})),this._resetDOMElementType("tabContent"),this._setDOMElementType("tabContent")}_createChildElements(){this.dom.tabToggle.forEach((t,e)=>{const s=new $({toggleElement:t,contentElement:this.dom.tabContent[e],parentTab:this});s.initialize(),this._elements.tabToggle.push(s)})}_handleFocus(){this.elements.tabToggle.forEach((t,e)=>{t.dom.toggle.addEventListener("focus",()=>{this.currentChild=e,this.isAutomatic&&this.currentTabToggle.show()})})}_handleClick(){this.elements.tabToggle.forEach((t,e)=>{t.dom.toggle.addEventListener("pointerup",()=>{this.currentChild=e,t.show()})})}_handleKeydown(){this.dom.tabToggle.forEach(t=>{t.addEventListener("keydown",e=>{const s=p(e);["Space","Enter","ArrowRight","ArrowLeft","Home","End"].includes(s)&&c(e)})})}_handleKeyup(){this.dom.tabToggle.forEach(t=>{t.addEventListener("keyup",e=>{switch(p(e)){case"Space":case"Enter":c(e),this.currentTabToggle.show();break;case"Home":c(e),this.focusFirstChild();break;case"End":c(e),this.focusLastChild();break;case"ArrowRight":c(e),this.focusNextChild();break;case"ArrowLeft":c(e),this.focusPreviousChild();break}})})}focusCurrentChild(){this.currentChild!==-1&&this.currentTabToggle.focus()}focusChild(t){this.blurCurrentChild(),this.currentChild=t,this.focusCurrentChild()}focusFirstChild(){this.focusChild(0)}focusLastChild(){this.focusChild(this.elements.tabToggle.length-1)}focusNextChild(){this.currentChild<this.elements.tabToggle.length-1?this.focusChild(this.currentChild+1):this.focusFirstChild()}focusPreviousChild(){this.currentChild>0?this.focusChild(this.currentChild-1):this.focusLastChild()}blurCurrentChild(){this.currentChild!==-1&&this.currentTabToggle.blur()}},V=M;module.exports=V;
|
|
4
|
+
|
|
5
|
+
//# sourceMappingURL=tabs.cjs.js.map
|