{"version":3,"file":"offcanvas.mjs","names":["pkg.version"],"sources":["../../../src/strings/dataBsDismiss.ts","../../../src/strings/dataBsToggle.ts","../../../src/strings/showClass.ts","../../../src/strings/offcanvasString.ts","../../../src/strings/offcanvasComponent.ts","../../../src/strings/modalComponent.ts","../../../src/strings/dataBsTarget.ts","../../../src/strings/dataBsParent.ts","../../../src/strings/dataBsContainer.ts","../../../src/util/getTargetElement.ts","../../../src/util/isVisible.ts","../../../src/strings/fixedTopClass.ts","../../../src/strings/fixedBottomClass.ts","../../../src/strings/stickyTopClass.ts","../../../src/strings/positionStickyClass.ts","../../../src/util/scrollbar.ts","../../../src/util/popupContainer.ts","../../../src/strings/fadeClass.ts","../../../src/strings/modalString.ts","../../../src/util/backdrop.ts","../../../src/util/isDisabled.ts","../../../package.json","../../../src/version.ts","../../../src/components/base-component.ts","../../../src/components/offcanvas.ts"],"sourcesContent":["/**\n * Global namespace for most components `dismiss` option.\n */\nconst dataBsDismiss = \"data-bs-dismiss\";\nexport default dataBsDismiss;\n","/**\n * Global namespace for most components `toggle` option.\n */\nconst dataBsToggle = \"data-bs-toggle\";\nexport default dataBsToggle;\n","/**\n * Global namespace for most components `show` class.\n */\nconst showClass = \"show\";\nexport default showClass;\n","/** @type {string} */\nconst offcanvasString = \"offcanvas\";\nexport default offcanvasString;\n","/** @type {string} */\nconst offcanvasComponent = \"Offcanvas\";\nexport default offcanvasComponent;\n","/** @type {string} */\nconst modalComponent = \"Modal\";\nexport default modalComponent;\n","/**\n * Global namespace for most components `target` option.\n */\nconst dataBsTarget = \"data-bs-target\";\nexport default dataBsTarget;\n","/**\n * Global namespace for most components `parent` option.\n */\nconst dataBsParent = \"data-bs-parent\";\nexport default dataBsParent;\n","/**\n * Global namespace for most components `container` option.\n */\nconst dataBsContainer = \"data-bs-container\";\nexport default dataBsContainer;\n","import {\n closest,\n getAttribute,\n getDocument,\n querySelector,\n} from \"@thednp/shorty\";\n\nimport dataBsTarget from \"../strings/dataBsTarget\";\nimport dataBsParent from \"../strings/dataBsParent\";\nimport dataBsContainer from \"../strings/dataBsContainer\";\n\n/**\n * Returns the `Element` that THIS one targets\n * via `data-bs-target`, `href`, `data-bs-parent` or `data-bs-container`.\n *\n * @param element the target element\n * @returns the query result\n */\nconst getTargetElement = (element: T) => {\n const targetAttr = [dataBsTarget, dataBsParent, dataBsContainer, \"href\"];\n const doc = getDocument(element);\n\n return targetAttr\n .map((att) => {\n const attValue = getAttribute(element, att);\n if (attValue) {\n // istanbul ignore next @preserve\n return att === dataBsParent\n ? closest(element, attValue)\n : querySelector(attValue, doc);\n }\n return null;\n })\n .filter((x) => x)[0];\n};\n\nexport default getTargetElement;\n","import { getElementStyle, isHTMLElement } from \"@thednp/shorty\";\n\n/**\n * @param element target\n * @returns the check result\n */\nconst isVisible = (element: HTMLElement) => {\n return isHTMLElement(element) &&\n getElementStyle(element, \"visibility\") !== \"hidden\" &&\n element.offsetParent !== null;\n};\nexport default isVisible;\n","/**\n * Global namespace for components `fixed-top` class.\n */\nconst fixedTopClass = \"fixed-top\";\nexport default fixedTopClass;\n","/**\n * Global namespace for components `fixed-bottom` class.\n */\nconst fixedBottomClass = \"fixed-bottom\";\nexport default fixedBottomClass;\n","/**\n * Global namespace for components `sticky-top` class.\n */\nconst stickyTopClass = \"sticky-top\";\nexport default stickyTopClass;\n","/**\n * Global namespace for components `position-sticky` class.\n */\nconst positionStickyClass = \"position-sticky\";\nexport default positionStickyClass;\n","import {\n getDocumentBody,\n getDocumentElement,\n getElementsByClassName,\n getElementStyle,\n getWindow,\n hasClass,\n setElementStyle,\n} from \"@thednp/shorty\";\n\nimport fixedTopClass from \"../strings/fixedTopClass\";\nimport fixedBottomClass from \"../strings/fixedBottomClass\";\nimport stickyTopClass from \"../strings/stickyTopClass\";\nimport positionStickyClass from \"../strings/positionStickyClass\";\n\nconst getFixedItems = (parent?: ParentNode) => [\n ...getElementsByClassName(fixedTopClass, parent),\n ...getElementsByClassName(fixedBottomClass, parent),\n ...getElementsByClassName(stickyTopClass, parent),\n ...getElementsByClassName(positionStickyClass, parent),\n ...getElementsByClassName(\"is-fixed\", parent),\n];\n\n/**\n * Removes *padding* and *overflow* from the ``\n * and all spacing from fixed items.\n *\n * @param element the target modal/offcanvas\n */\nexport const resetScrollbar = (element?: Element) => {\n const bd = getDocumentBody(element);\n setElementStyle(bd, {\n paddingRight: \"\",\n overflow: \"\",\n });\n\n const fixedItems = getFixedItems(bd);\n\n // istanbul ignore else @preserve\n if (fixedItems.length) {\n fixedItems.forEach((fixed) => {\n setElementStyle(fixed, {\n paddingRight: \"\",\n marginRight: \"\",\n });\n });\n }\n};\n\n/**\n * Returns the scrollbar width if the body does overflow\n * the window.\n *\n * @param element target element\n * @returns the scrollbar width value\n */\nexport const measureScrollbar = (element: Element) => {\n const { clientWidth } = getDocumentElement(element);\n const { innerWidth } = getWindow(element);\n return Math.abs(innerWidth - clientWidth);\n};\n\n/**\n * Sets the `` and fixed items style when modal / offcanvas\n * is shown to the user.\n *\n * @param element the target modal/offcanvas\n * @param overflow body does overflow or not\n */\nexport const setScrollbar = (element: Element, overflow?: boolean) => {\n const bd = getDocumentBody(element);\n const bodyPad = parseInt(getElementStyle(bd, \"paddingRight\"), 10);\n const isOpen = getElementStyle(bd, \"overflow\") === \"hidden\";\n // istanbul ignore next @preserve\n const sbWidth = isOpen && bodyPad ? 0 : measureScrollbar(element);\n const fixedItems = getFixedItems(bd);\n\n // istanbul ignore if @preserve\n if (!overflow) return;\n\n setElementStyle(bd, {\n overflow: \"hidden\",\n paddingRight: `${bodyPad + sbWidth}px`,\n });\n\n // istanbul ignore if @preserve\n if (!fixedItems.length) return;\n\n fixedItems.forEach((fixed) => {\n const itemPadValue = getElementStyle(fixed, \"paddingRight\");\n fixed.style.paddingRight = `${parseInt(itemPadValue, 10) + sbWidth}px`;\n // istanbul ignore else @preserve\n if (\n [stickyTopClass, positionStickyClass].some((c) => hasClass(fixed, c))\n ) {\n const itemMValue = getElementStyle(fixed, \"marginRight\");\n fixed.style.marginRight = `${parseInt(itemMValue, 10) - sbWidth}px`;\n }\n });\n};\n","import { createElement, getDocumentBody, isNode } from \"@thednp/shorty\";\n\n// the default container for Modal, Offcanvas, Popover and Tooltip\nconst popupContainer = createElement({\n tagName: \"div\",\n className: \"popup-container\",\n}) as HTMLElement;\n\nconst appendPopup = (target: Element, customContainer?: ParentNode) => {\n const containerIsBody = isNode(customContainer) &&\n customContainer.nodeName === \"BODY\";\n const lookup = isNode(customContainer) && !containerIsBody\n ? customContainer\n : popupContainer;\n const BODY = containerIsBody ? customContainer : getDocumentBody(target);\n\n // istanbul ignore else @preserve\n if (isNode(target)) {\n if (lookup === popupContainer) {\n BODY.append(popupContainer);\n }\n lookup.append(target);\n }\n};\n\nconst removePopup = (target: Element, customContainer?: ParentNode) => {\n const containerIsBody = isNode(customContainer) &&\n customContainer.nodeName === \"BODY\";\n const lookup = isNode(customContainer) && !containerIsBody\n ? customContainer\n : popupContainer;\n\n // istanbul ignore else @preserve\n if (isNode(target)) {\n target.remove();\n\n if (lookup === popupContainer && !popupContainer.children.length) {\n popupContainer.remove();\n }\n }\n};\n\nconst hasPopup = (target: Element, customContainer?: ParentNode) => {\n const lookup = isNode(customContainer) && customContainer.nodeName !== \"BODY\"\n ? customContainer\n : popupContainer;\n return isNode(target) && lookup.contains(target);\n};\n\nexport { appendPopup, hasPopup, popupContainer, removePopup };\n","/**\n * Global namespace for most components `fade` class.\n */\nconst fadeClass = \"fade\";\nexport default fadeClass;\n","/** @type {string} */\nconst modalString = \"modal\";\nexport default modalString;\n","import {\n addClass,\n createElement,\n getDocument,\n getDocumentBody,\n hasClass,\n querySelector,\n reflow,\n removeClass,\n} from \"@thednp/shorty\";\n\nimport fadeClass from \"../strings/fadeClass\";\nimport showClass from \"../strings/showClass\";\nimport modalString from \"../strings/modalString\";\nimport offcanvasString from \"../strings/offcanvasString\";\nimport { resetScrollbar } from \"./scrollbar\";\nimport { appendPopup, removePopup } from \"./popupContainer\";\n\nconst backdropString = \"backdrop\";\nconst modalBackdropClass = `${modalString}-${backdropString}`;\nconst offcanvasBackdropClass = `${offcanvasString}-${backdropString}`;\nconst modalActiveSelector = `.${modalString}.${showClass}`;\nconst offcanvasActiveSelector = `.${offcanvasString}.${showClass}`;\n\n// any document would suffice\nconst overlay = createElement(\"div\") as HTMLElement;\n\n/**\n * Returns the current active modal / offcancas element.\n *\n * @param element the context element\n * @returns the requested element\n */\nconst getCurrentOpen = (element?: Element) => {\n return querySelector(\n `${modalActiveSelector},${offcanvasActiveSelector}`,\n getDocument(element),\n );\n};\n\n/**\n * Toogles from a Modal overlay to an Offcanvas, or vice-versa.\n *\n * @param isModal\n */\nconst toggleOverlayType = (isModal?: boolean) => {\n const targetClass = isModal ? modalBackdropClass : offcanvasBackdropClass;\n [modalBackdropClass, offcanvasBackdropClass].forEach((c) => {\n removeClass(overlay, c);\n });\n addClass(overlay, targetClass);\n};\n\n/**\n * Append the overlay to DOM.\n *\n * @param element\n * @param hasFade\n * @param isModal\n */\nconst appendOverlay = (\n element: Element,\n hasFade: boolean,\n isModal?: boolean,\n) => {\n toggleOverlayType(isModal);\n appendPopup(overlay, getDocumentBody(element));\n if (hasFade) addClass(overlay, fadeClass);\n};\n\n/**\n * Shows the overlay to the user.\n */\nconst showOverlay = () => {\n if (!hasClass(overlay, showClass)) {\n addClass(overlay, showClass);\n reflow(overlay);\n }\n};\n\n/**\n * Hides the overlay from the user.\n */\nconst hideOverlay = () => {\n removeClass(overlay, showClass);\n};\n\n/**\n * Removes the overlay from DOM.\n *\n * @param element\n */\nconst removeOverlay = (element?: Element): void => {\n if (!getCurrentOpen(element)) {\n removeClass(overlay, fadeClass);\n removePopup(overlay, getDocumentBody(element));\n resetScrollbar(element);\n }\n};\n\nexport {\n appendOverlay,\n getCurrentOpen,\n hideOverlay,\n modalActiveSelector,\n modalBackdropClass,\n offcanvasActiveSelector,\n offcanvasBackdropClass,\n overlay,\n removeOverlay,\n showOverlay,\n toggleOverlayType,\n};\n","import { getAttribute, hasClass } from \"@thednp/shorty\";\n\n/**\n * Check if interactive element is disabled.\n * @param target either a `