UNPKG

@primeuix/utils

Version:

Utility functions and helpers for PrimeUI Libraries

1 lines 76 kB
{"version":3,"sources":["../../src/dom/methods/hasClass.ts","../../src/dom/methods/addClass.ts","../../src/dom/methods/calculateBodyScrollbarWidth.ts","../../src/dom/helpers/blockBodyScroll.ts","../../src/dom/helpers/saveAs.ts","../../src/dom/helpers/exportCSV.ts","../../src/dom/methods/removeClass.ts","../../src/dom/helpers/unblockBodyScroll.ts","../../src/dom/methods/getCSSVariableByRegex.ts","../../src/dom/methods/getHiddenElementDimensions.ts","../../src/dom/methods/getViewport.ts","../../src/dom/methods/getScrollLeft.ts","../../src/dom/methods/getWindowScrollLeft.ts","../../src/dom/methods/getWindowScrollTop.ts","../../src/dom/methods/isRTL.ts","../../src/dom/methods/absolutePosition.ts","../../src/dom/methods/addStyle.ts","../../src/dom/methods/getOuterWidth.ts","../../src/dom/methods/relativePosition.ts","../../src/dom/methods/alignOverlay.ts","../../src/dom/methods/getParentNode.ts","../../src/dom/methods/isExist.ts","../../src/dom/methods/isElement.ts","../../src/dom/methods/toElement.ts","../../src/dom/methods/getTargetElement.ts","../../src/dom/methods/appendChild.ts","../../src/dom/methods/calculateScrollbarHeight.ts","../../src/dom/methods/calculateScrollbarWidth.ts","../../src/dom/methods/clearSelection.ts","../../src/dom/methods/setAttributes.ts","../../src/dom/methods/createElement.ts","../../src/dom/methods/createStyleMarkup.ts","../../src/dom/methods/createStyleAsString.ts","../../src/dom/methods/createStyleElement.ts","../../src/dom/methods/createStyleTag.ts","../../src/dom/methods/fadeIn.ts","../../src/dom/methods/fadeOut.ts","../../src/dom/methods/find.ts","../../src/dom/methods/findSingle.ts","../../src/dom/methods/focus.ts","../../src/dom/methods/getAttribute.ts","../../src/dom/methods/resolveUserAgent.ts","../../src/dom/methods/getBrowser.ts","../../src/dom/methods/getBrowserLanguage.ts","../../src/dom/methods/getCSSProperty.ts","../../src/dom/methods/getCursorOffset.ts","../../src/dom/methods/getFocusableElements.ts","../../src/dom/methods/getFirstFocusableElement.ts","../../src/dom/methods/getHeight.ts","../../src/dom/methods/getHiddenElementOuterHeight.ts","../../src/dom/methods/getHiddenElementOuterWidth.ts","../../src/dom/methods/getIndex.ts","../../src/dom/methods/getInnerWidth.ts","../../src/dom/methods/getLastFocusableElement.ts","../../src/dom/methods/getNextElementSibling.ts","../../src/dom/methods/getNextFocusableElement.ts","../../src/dom/methods/getOffset.ts","../../src/dom/methods/getOuterHeight.ts","../../src/dom/methods/getParents.ts","../../src/dom/methods/getPreviousElementSibling.ts","../../src/dom/methods/getScrollableParents.ts","../../src/dom/methods/getSelection.ts","../../src/dom/methods/getUserAgent.ts","../../src/dom/methods/getWidth.ts","../../src/dom/methods/hasCSSAnimation.ts","../../src/dom/methods/hasCSSTransition.ts","../../src/dom/methods/invokeElementMethod.ts","../../src/dom/methods/isAndroid.ts","../../src/dom/methods/isAttributeEquals.ts","../../src/dom/methods/isAttributeNotEquals.ts","../../src/dom/methods/isClickable.ts","../../src/dom/methods/isClient.ts","../../src/dom/methods/isFocusableElement.ts","../../src/dom/methods/isVisible.ts","../../src/dom/methods/isHidden.ts","../../src/dom/methods/isIOS.ts","../../src/dom/methods/isPrefersReducedMotion.ts","../../src/dom/methods/isServer.ts","../../src/dom/methods/isTouchDevice.ts","../../src/dom/methods/nestedPosition.ts","../../src/dom/methods/nextFrame.ts","../../src/dom/methods/remove.ts","../../src/dom/methods/removeChild.ts","../../src/dom/methods/removeStyleTag.ts","../../src/dom/methods/scrollInView.ts","../../src/dom/methods/setAttribute.ts","../../src/dom/methods/setCSSProperty.ts"],"sourcesContent":["export default function hasClass(element: Element, className: string): boolean {\n if (element) {\n if (element.classList) return element.classList.contains(className);\n else return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className);\n }\n\n return false;\n}\n","import hasClass from './hasClass';\n\nexport default function addClass(element: Element, className: string | undefined | null | (string | undefined | null)[]): void {\n if (element && className) {\n const fn = (_className: string) => {\n if (!hasClass(element, _className)) {\n if (element.classList) element.classList.add(_className);\n else element.className += ' ' + _className;\n }\n };\n\n [className]\n .flat()\n .filter(Boolean)\n .forEach((_classNames) => (_classNames as string).split(' ').forEach(fn));\n }\n}\n","export default function calculateBodyScrollbarWidth(): number {\n return window.innerWidth - document.documentElement.offsetWidth;\n}\n","import addClass from '../methods/addClass';\nimport calculateBodyScrollbarWidth from '../methods/calculateBodyScrollbarWidth';\n\nexport interface BlockBodyScrollOptions {\n className?: string;\n variableName?: string;\n}\n\nexport default function blockBodyScroll(option: string | BlockBodyScrollOptions | undefined): void {\n if (typeof option === 'string') {\n addClass(document.body, option || 'p-overflow-hidden');\n } else {\n option?.variableName && document.body.style.setProperty(option.variableName, calculateBodyScrollbarWidth() + 'px');\n addClass(document.body, option?.className || 'p-overflow-hidden');\n }\n}\n","export default function saveAs(file: { name: string; src: string }): boolean {\n if (file) {\n const link = document.createElement('a');\n\n if (link.download !== undefined) {\n const { name, src } = file;\n\n link.setAttribute('href', src);\n link.setAttribute('download', name);\n link.style.display = 'none';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n return true;\n }\n }\n\n return false;\n}\n","import saveAs from './saveAs';\n\nexport default function exportCSV(csv: any, filename: string): void {\n const blob = new Blob([csv], {\n type: 'application/csv;charset=utf-8;'\n });\n\n if ((window.navigator as any).msSaveOrOpenBlob) {\n (navigator as any).msSaveOrOpenBlob(blob, filename + '.csv');\n } else {\n const isDownloaded = saveAs({ name: filename + '.csv', src: URL.createObjectURL(blob) });\n\n if (!isDownloaded) {\n csv = 'data:text/csv;charset=utf-8,' + csv;\n window.open(encodeURI(csv));\n }\n }\n}\n","export default function removeClass(element: Element, className: string | undefined | null | (string | undefined | null)[]): void {\n if (element && className) {\n const fn = (_className: string) => {\n if (element.classList) element.classList.remove(_className);\n else element.className = element.className.replace(new RegExp('(^|\\\\b)' + _className.split(' ').join('|') + '(\\\\b|$)', 'gi'), ' ');\n };\n\n [className]\n .flat()\n .filter(Boolean)\n .forEach((_classNames) => (_classNames as string).split(' ').forEach(fn));\n }\n}\n","import removeClass from '../methods/removeClass';\n\nexport interface UnblockBodyScrollOptions {\n className?: string;\n variableName?: string;\n}\n\nexport default function unblockBodyScroll(option: string | UnblockBodyScrollOptions | undefined): void {\n if (typeof option === 'string') {\n removeClass(document.body, option || 'p-overflow-hidden');\n } else {\n if (option?.variableName) document.body.style.removeProperty(option.variableName);\n removeClass(document.body, option?.className || 'p-overflow-hidden');\n }\n}\n","export default function getCSSVariableByRegex(variableRegex: RegExp): { name: string | undefined; value: string | undefined } | null {\n for (const sheet of document?.styleSheets) {\n try {\n for (const rule of sheet?.cssRules) {\n for (const property of (rule as CSSStyleRule)?.style) {\n if (variableRegex.test(property)) {\n return { name: property, value: (rule as CSSStyleRule).style.getPropertyValue(property).trim() };\n }\n }\n }\n } catch {}\n }\n\n return null;\n}\n","export default function getHiddenElementDimensions(element?: HTMLElement): { width: number; height: number } {\n const dimensions: { width: number; height: number } = { width: 0, height: 0 };\n\n if (element) {\n const [visibility, display] = [element.style.visibility, element.style.display];\n\n // Temporarily hide the element to get its dimensions\n element.style.visibility = 'hidden';\n element.style.display = 'block';\n dimensions.width = element.offsetWidth;\n dimensions.height = element.offsetHeight;\n element.style.display = display;\n element.style.visibility = visibility;\n }\n\n return dimensions;\n}\n","export default function getViewport(): { width: number; height: number } {\n const win = window,\n d = document,\n e = d.documentElement,\n g = d.getElementsByTagName('body')[0],\n w = win.innerWidth || e.clientWidth || g.clientWidth,\n h = win.innerHeight || e.clientHeight || g.clientHeight;\n\n return { width: w, height: h };\n}\n","export default function getScrollLeft(element?: HTMLElement): number {\n // for RTL scrollLeft should be negative\n return element ? Math.abs(element.scrollLeft) : 0;\n}\n","import getScrollLeft from './getScrollLeft';\n\nexport default function getWindowScrollLeft(): number {\n const doc = document.documentElement;\n\n return (window.pageXOffset || getScrollLeft(doc)) - (doc.clientLeft || 0);\n}\n","export default function getWindowScrollTop(): number {\n const doc = document.documentElement;\n\n return (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);\n}\n","export default function isRTL(element?: HTMLElement): boolean {\n return element ? getComputedStyle(element).direction === 'rtl' : false;\n}\n","import getCSSVariableByRegex from './getCSSVariableByRegex';\nimport getHiddenElementDimensions from './getHiddenElementDimensions';\nimport getViewport from './getViewport';\nimport getWindowScrollLeft from './getWindowScrollLeft';\nimport getWindowScrollTop from './getWindowScrollTop';\nimport isRTL from './isRTL';\n\nexport default function absolutePosition(element: HTMLElement, target: HTMLElement, gutter: boolean = true): void {\n if (element) {\n const elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : getHiddenElementDimensions(element);\n const elementOuterHeight = elementDimensions.height;\n const elementOuterWidth = elementDimensions.width;\n const targetOuterHeight = target.offsetHeight;\n const targetOuterWidth = target.offsetWidth;\n const targetOffset = target.getBoundingClientRect();\n const windowScrollTop = getWindowScrollTop();\n const windowScrollLeft = getWindowScrollLeft();\n const viewport = getViewport();\n let top,\n left,\n origin = 'top';\n\n if (targetOffset.top + targetOuterHeight + elementOuterHeight > viewport.height) {\n top = targetOffset.top + windowScrollTop - elementOuterHeight;\n origin = 'bottom';\n\n if (top < 0) {\n top = windowScrollTop;\n }\n } else {\n top = targetOuterHeight + targetOffset.top + windowScrollTop;\n }\n\n if (targetOffset.left + elementOuterWidth > viewport.width) left = Math.max(0, targetOffset.left + windowScrollLeft + targetOuterWidth - elementOuterWidth);\n else left = targetOffset.left + windowScrollLeft;\n\n if (isRTL(element)) {\n element.style.insetInlineEnd = left + 'px';\n } else {\n element.style.insetInlineStart = left + 'px';\n }\n\n element.style.top = top + 'px';\n element.style.transformOrigin = origin;\n if (gutter) element.style.marginTop = origin === 'bottom' ? `calc(${getCSSVariableByRegex(/-anchor-gutter$/)?.value ?? '2px'} * -1)` : (getCSSVariableByRegex(/-anchor-gutter$/)?.value ?? '');\n }\n}\n","export default function addStyle(element: HTMLElement, style: string | object): void {\n if (element) {\n if (typeof style === 'string') {\n element.style.cssText = style;\n } else {\n Object.entries(style || {}).forEach(([key, value]: [string, string]) => ((element.style as any)[key] = value));\n }\n }\n}\n","export default function getOuterWidth(element: unknown, margin?: boolean): number {\n if (element instanceof HTMLElement) {\n let width = element.offsetWidth;\n\n if (margin) {\n const style = getComputedStyle(element);\n\n width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);\n }\n\n return width;\n }\n\n return 0;\n}\n","import getCSSVariableByRegex from './getCSSVariableByRegex';\nimport getHiddenElementDimensions from './getHiddenElementDimensions';\nimport getViewport from './getViewport';\n\nexport default function relativePosition(element: HTMLElement, target: HTMLElement, gutter: boolean = true, fixedOrigin: 'top' | 'bottom' | undefined = undefined): void {\n if (element) {\n const elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : getHiddenElementDimensions(element);\n const targetHeight = target.offsetHeight;\n const targetOffset = target.getBoundingClientRect();\n const viewport = getViewport();\n let top,\n left,\n origin = fixedOrigin ?? 'top';\n\n if (!fixedOrigin && targetOffset.top + targetHeight + elementDimensions.height > viewport.height) {\n top = -1 * elementDimensions.height;\n origin = 'bottom';\n\n if (targetOffset.top + top < 0) {\n top = -1 * targetOffset.top;\n }\n } else {\n top = targetHeight;\n }\n\n if (elementDimensions.width > viewport.width) {\n // element wider then viewport and cannot fit on screen (align at left side of viewport)\n left = targetOffset.left * -1;\n } else if (targetOffset.left + elementDimensions.width > viewport.width) {\n // element wider then viewport but can be fit on screen (align at right side of viewport)\n left = (targetOffset.left + elementDimensions.width - viewport.width) * -1;\n } else {\n // element fits on screen (align with target)\n left = 0;\n }\n\n element.style.top = top + 'px';\n element.style.insetInlineStart = left + 'px';\n element.style.transformOrigin = origin;\n\n if (gutter) {\n const gutterValue = getCSSVariableByRegex(/-anchor-gutter$/)?.value;\n\n element.style.marginTop = origin === 'bottom' ? `calc(${gutterValue ?? '2px'} * -1)` : (gutterValue ?? '');\n }\n }\n}\n","import absolutePosition from './absolutePosition';\nimport getOuterWidth from './getOuterWidth';\nimport relativePosition from './relativePosition';\n\nexport default function alignOverlay(overlay: HTMLElement, target: HTMLElement, appendTo: string, calculateMinWidth: boolean = true) {\n if (overlay && target) {\n if (appendTo === 'self') {\n relativePosition(overlay, target);\n } else {\n if (calculateMinWidth) overlay.style.minWidth = getOuterWidth(target) + 'px';\n absolutePosition(overlay, target);\n }\n }\n}\n","export default function getParentNode(element: Node): ParentNode | null {\n if (element) {\n let parent = element.parentNode;\n\n if (parent && parent instanceof ShadowRoot && parent.host) {\n parent = parent.host;\n }\n\n return parent;\n }\n\n return null;\n}\n","import getParentNode from './getParentNode';\n\nexport default function isExist(element: Node): boolean {\n return !!(element !== null && typeof element !== 'undefined' && element.nodeName && getParentNode(element));\n}\n","export default function isElement(element: unknown): element is Element {\n return typeof Element !== 'undefined' ? element instanceof Element : element !== null && typeof element === 'object' && (element as Element).nodeType === 1 && typeof (element as Element).nodeName === 'string';\n}\n","import isElement from './isElement';\n\ntype ReactElement = { current: Element | null | undefined };\ntype VueElement = { el: Element | null | undefined };\ntype AngularElement = { el: { nativeElement: Element | undefined } };\n\nexport default function toElement(element: unknown): Element | null | undefined {\n let target = element;\n\n if (element && typeof element === 'object') {\n if (Object.hasOwn(element, 'current')) {\n // For React\n target = (element as ReactElement).current;\n } else if (Object.hasOwn(element, 'el')) {\n if (Object.hasOwn((element as AngularElement).el, 'nativeElement')) {\n // For Angular\n target = (element as AngularElement).el.nativeElement;\n } else {\n // For Vue\n target = (element as VueElement).el;\n }\n }\n }\n\n return isElement(target) ? target : undefined;\n}\n","import isExist from './isExist';\nimport toElement from './toElement';\n\nexport default function getTargetElement(target: unknown, currentElement?: Element): Window | Document | Element | null | undefined {\n if (!target) return undefined;\n\n switch (target) {\n case 'document':\n return document;\n case 'window':\n return window;\n case 'body':\n return document.body;\n case '@next':\n return currentElement?.nextElementSibling;\n case '@prev':\n return currentElement?.previousElementSibling;\n case '@first':\n return currentElement?.firstElementChild;\n case '@last':\n return currentElement?.lastElementChild;\n case '@child':\n return currentElement?.children?.[0];\n case '@parent':\n return currentElement?.parentElement;\n case '@grandparent':\n return currentElement?.parentElement?.parentElement;\n\n default: {\n if (typeof target === 'string') {\n // child selector\n const match = target.match(/^@child\\[(\\d+)]/);\n\n if (match) {\n return currentElement?.children?.[parseInt(match[1], 10)] || null;\n }\n\n return document.querySelector(target) || null;\n }\n\n const isFunction = (value: unknown): value is (...args: unknown[]) => unknown => typeof value === 'function' && 'call' in value && 'apply' in value;\n const computedTarget = isFunction(target) ? target() : target;\n const element = toElement(computedTarget);\n\n return isExist(element as Element) ? (element as Element) : (computedTarget as Document)?.nodeType === 9 ? (computedTarget as Document) : undefined;\n }\n }\n}\n","import getTargetElement from './getTargetElement';\n\nexport default function appendChild(element: unknown, child: Node | Element) {\n const target: Document | Element | null | undefined = getTargetElement(element, child as Element) as Exclude<ReturnType<typeof getTargetElement>, Window>;\n\n if (target) target.appendChild(child);\n else throw new Error('Cannot append ' + child + ' to ' + element);\n}\n","import addStyle from './addStyle';\n\nlet calculatedScrollbarHeight: number | undefined = undefined;\n\nexport default function calculateScrollbarHeight(element?: HTMLElement): number {\n if (element) {\n const style = getComputedStyle(element);\n\n return element.offsetHeight - element.clientHeight - parseFloat(style.borderTopWidth) - parseFloat(style.borderBottomWidth);\n } else {\n if (calculatedScrollbarHeight != null) return calculatedScrollbarHeight;\n\n const scrollDiv = document.createElement('div');\n\n addStyle(scrollDiv, {\n width: '100px',\n height: '100px',\n overflow: 'scroll',\n position: 'absolute',\n top: '-9999px'\n });\n document.body.appendChild(scrollDiv);\n\n const scrollbarHeight = scrollDiv.offsetHeight - scrollDiv.clientHeight;\n\n document.body.removeChild(scrollDiv);\n\n calculatedScrollbarHeight = scrollbarHeight;\n\n return scrollbarHeight;\n }\n}\n","import addStyle from './addStyle';\n\nlet calculatedScrollbarWidth: number | undefined = undefined;\n\nexport default function calculateScrollbarWidth(element?: HTMLElement): number {\n if (element) {\n const style = getComputedStyle(element);\n\n return element.offsetWidth - element.clientWidth - parseFloat(style.borderLeftWidth) - parseFloat(style.borderRightWidth);\n } else {\n if (calculatedScrollbarWidth != null) return calculatedScrollbarWidth;\n\n const scrollDiv = document.createElement('div');\n\n addStyle(scrollDiv, {\n width: '100px',\n height: '100px',\n overflow: 'scroll',\n position: 'absolute',\n top: '-9999px'\n });\n document.body.appendChild(scrollDiv);\n\n const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;\n\n document.body.removeChild(scrollDiv);\n\n calculatedScrollbarWidth = scrollbarWidth;\n\n return scrollbarWidth;\n }\n}\n","export default function clearSelection(): void {\n if (window.getSelection) {\n const selection: any = window.getSelection() || {};\n\n if (selection.empty) {\n selection.empty();\n } else if (selection.removeAllRanges && selection.rangeCount > 0 && selection.getRangeAt(0).getClientRects().length > 0) {\n selection.removeAllRanges();\n }\n }\n}\n","import isElement from './isElement';\n\nexport default function setAttributes(element: HTMLElement, attributes: { [key: string]: any } = {}): void {\n if (isElement(element)) {\n const computedStyles = (rule: string, value: any): string[] => {\n const styles = (element as any)?.$attrs?.[rule] ? [(element as any)?.$attrs?.[rule]] : [];\n\n return [value].flat().reduce((cv, v) => {\n if (v !== null && v !== undefined) {\n const type = typeof v;\n\n if (type === 'string' || type === 'number') {\n cv.push(v);\n } else if (type === 'object') {\n const _cv = Array.isArray(v) ? computedStyles(rule, v) : Object.entries(v).map(([_k, _v]) => (rule === 'style' && (!!_v || _v === 0) ? `${_k.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()}:${_v}` : _v ? _k : undefined));\n\n cv = _cv.length ? cv.concat(_cv.filter((c) => !!c)) : cv;\n }\n }\n\n return cv;\n }, styles);\n };\n\n Object.entries(attributes).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n const matchedEvent = key.match(/^on(.+)/);\n\n if (matchedEvent) {\n element.addEventListener(matchedEvent[1].toLowerCase(), value);\n } else if (key === 'p-bind' || key === 'pBind') {\n setAttributes(element, value);\n } else {\n value = key === 'class' ? [...new Set(computedStyles('class', value))].join(' ').trim() : key === 'style' ? computedStyles('style', value).join(';').trim() : value;\n ((element as any).$attrs = (element as any).$attrs || {}) && ((element as any).$attrs[key] = value);\n element.setAttribute(key, value);\n }\n }\n });\n }\n}\n","import setAttributes from './setAttributes';\n\nexport default function createElement(type: string, attributes: Record<string, unknown> = {}, ...children: (string | Node)[]): HTMLElement | undefined {\n if (type) {\n const element = document.createElement(type);\n\n setAttributes(element, attributes);\n element.append(...children);\n\n return element;\n }\n\n return undefined;\n}\n","export default function createStyleMarkup(css?: string, attributes: Record<string, unknown> = {}): string {\n return css ? `<style${Object.entries(attributes).reduce((s, [k, v]) => s + ` ${k}=\"${v}\"`, '')}>${css}</style>` : '';\n}\n","import createStyleMarkup from './createStyleMarkup';\n\n/**\n * @deprecated Use `createStyleMarkup` instead.\n */\nexport default function createStyleAsString(css?: string, options: Record<string, unknown> = {}) {\n return createStyleMarkup(css, options);\n}\n","import createElement from './createElement';\n\nexport default function createStyleElement(css: string, attributes: Record<string, unknown> = {}, container?: Element): HTMLStyleElement {\n const element = createElement('style', attributes, css)! as HTMLStyleElement;\n\n container?.appendChild(element);\n\n return element;\n}\n","import createStyleElement from './createStyleElement';\n\n/**\n * @deprecated Use `createStyleElement` instead.\n */\nexport default function createStyleTag(attributes: Record<string, unknown> = {}, container?: Element): HTMLStyleElement {\n return createStyleElement('', attributes, container || document.head);\n}\n","export default function fadeIn(element: HTMLElement, duration: number): void {\n if (element) {\n element.style.opacity = '0';\n\n let last = +new Date();\n let opacity = '0';\n\n const tick = function () {\n opacity = `${+element.style.opacity + (new Date().getTime() - last) / duration}`;\n element.style.opacity = opacity;\n last = +new Date();\n\n if (+opacity < 1) {\n if ('requestAnimationFrame' in window) requestAnimationFrame(tick);\n else setTimeout(tick, 16);\n }\n };\n\n tick();\n }\n}\n","export default function fadeOut(element: HTMLElement, duration: number): void {\n if (element) {\n let opacity = 1;\n const interval = 50;\n const gap = interval / duration;\n\n const fading = setInterval(() => {\n opacity -= gap;\n\n if (opacity <= 0) {\n opacity = 0;\n clearInterval(fading);\n }\n\n element.style.opacity = opacity.toString();\n }, interval);\n }\n}\n","import isElement from './isElement';\n\nexport default function find(element: Element, selector: string): Element[] {\n return isElement(element) ? Array.from(element.querySelectorAll(selector)) : [];\n}\n","import isElement from './isElement';\n\nexport default function findSingle(element: Element, selector: string): Element | null {\n return isElement(element) ? (element.matches(selector) ? element : element.querySelector(selector)) : null;\n}\n","export default function focus(element: HTMLElement, options?: FocusOptions): void {\n if (element && document.activeElement !== element) element.focus(options);\n}\n","import isElement from './isElement';\n\nexport default function getAttribute(element: Element, name: string): any {\n if (isElement(element)) {\n const value = element.getAttribute(name);\n\n if (!isNaN(value as any)) {\n return +(value as string);\n }\n\n if (value === 'true' || value === 'false') {\n return value === 'true';\n }\n\n return value;\n }\n\n return undefined;\n}\n","export default function resolveUserAgent(): { browser: string | undefined; version: string | undefined } {\n const ua = navigator.userAgent.toLowerCase();\n const match = /(chrome)[ ]([\\w.]+)/.exec(ua) || /(webkit)[ ]([\\w.]+)/.exec(ua) || /(opera)(?:.*version|)[ ]([\\w.]+)/.exec(ua) || /(msie) ([\\w.]+)/.exec(ua) || (ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec(ua)) || [];\n\n return {\n browser: match[1] || '',\n version: match[2] || '0'\n };\n}\n","import resolveUserAgent from './resolveUserAgent';\n\ntype BrowserType = {\n [key: string]: string | boolean | undefined;\n};\n\nlet browser: BrowserType | null = null;\n\nexport default function getBrowser(): BrowserType {\n if (!browser) {\n browser = {};\n\n const matched = resolveUserAgent();\n\n if (matched.browser) {\n browser[matched.browser] = true;\n browser['version'] = matched.version;\n }\n\n if (browser['chrome']) {\n browser['webkit'] = true;\n } else if (browser['webkit']) {\n browser['safari'] = true;\n }\n }\n\n return browser;\n}\n","export default function getBrowserLanguage(): string {\n return (navigator.languages && navigator.languages.length && navigator.languages[0]) || navigator.language || 'en';\n}\n","export default function getCSSProperty(element?: HTMLElement, property?: string, inline?: boolean): string | null {\n if (element && property) {\n return inline ? element?.style?.getPropertyValue(property) : getComputedStyle(element).getPropertyValue(property);\n }\n\n return null;\n}\n","export default function getCursorOffset(element: Element, prevText: string, nextText: string, currentText: string): { top: number | string; left: number | string } {\n if (element) {\n const style = getComputedStyle(element);\n const ghostDiv = document.createElement('div');\n\n ghostDiv.style.position = 'absolute';\n ghostDiv.style.top = '0px';\n ghostDiv.style.left = '0px';\n ghostDiv.style.visibility = 'hidden';\n ghostDiv.style.pointerEvents = 'none';\n ghostDiv.style.overflow = style.overflow;\n ghostDiv.style.width = style.width;\n ghostDiv.style.height = style.height;\n ghostDiv.style.padding = style.padding;\n ghostDiv.style.border = style.border;\n ghostDiv.style.overflowWrap = style.overflowWrap;\n ghostDiv.style.whiteSpace = style.whiteSpace;\n ghostDiv.style.lineHeight = style.lineHeight;\n ghostDiv.innerHTML = prevText.replace(/\\r\\n|\\r|\\n/g, '<br />');\n\n const ghostSpan = document.createElement('span');\n\n ghostSpan.textContent = currentText;\n ghostDiv.appendChild(ghostSpan);\n\n const text = document.createTextNode(nextText);\n\n ghostDiv.appendChild(text);\n document.body.appendChild(ghostDiv);\n\n const { offsetLeft, offsetTop, clientHeight } = ghostSpan;\n\n document.body.removeChild(ghostDiv);\n\n return {\n left: Math.abs(offsetLeft - element.scrollLeft),\n top: Math.abs(offsetTop - element.scrollTop) + clientHeight\n };\n }\n\n return {\n top: 'auto',\n left: 'auto'\n };\n}\n","import find from './find';\n\nexport default function getFocusableElements(element: Element, selector: string = ''): Element[] {\n const focusableElements = find(\n element,\n `button:not([tabindex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n [href]:not([tabindex = \"-1\"]):not([style*=\"display:none\"]):not([hidden])${selector},\n input:not([tabindex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n select:not([tabindex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n textarea:not([tabindex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n [tabIndex]:not([tabIndex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n [contenteditable]:not([tabIndex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector}`\n );\n\n const visibleFocusableElements: Element[] = [];\n\n for (const focusableElement of focusableElements) {\n if (getComputedStyle(focusableElement).display != 'none' && getComputedStyle(focusableElement).visibility != 'hidden') visibleFocusableElements.push(focusableElement);\n }\n\n return visibleFocusableElements;\n}\n","import getFocusableElements from './getFocusableElements';\n\nexport default function getFirstFocusableElement(element: Element, selector?: string): Element | null {\n const focusableElements = getFocusableElements(element, selector);\n\n return focusableElements.length > 0 ? focusableElements[0] : null;\n}\n","export default function getHeight(element: HTMLElement): number {\n if (element) {\n let height = element.offsetHeight;\n const style = getComputedStyle(element);\n\n height -= parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) + parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);\n\n return height;\n }\n\n return 0;\n}\n","export default function getHiddenElementOuterHeight(element: HTMLElement): number {\n if (element) {\n const [visibility, display] = [element.style.visibility, element.style.display];\n\n // Temporarily hide the element to get its outer height\n element.style.visibility = 'hidden';\n element.style.display = 'block';\n const elementHeight = element.offsetHeight;\n\n element.style.display = display;\n element.style.visibility = visibility;\n\n return elementHeight;\n }\n\n return 0;\n}\n","export default function getHiddenElementOuterWidth(element: HTMLElement): number {\n if (element) {\n const [visibility, display] = [element.style.visibility, element.style.display];\n\n // Temporarily hide the element to get its outer width\n element.style.visibility = 'hidden';\n element.style.display = 'block';\n const elementWidth = element.offsetWidth;\n\n element.style.display = display;\n element.style.visibility = visibility;\n\n return elementWidth;\n }\n\n return 0;\n}\n","import getParentNode from './getParentNode';\n\nexport default function getIndex(element: HTMLElement): number {\n if (element) {\n const children = getParentNode(element)?.childNodes;\n let num = 0;\n\n if (children) {\n for (let i = 0; i < children.length; i++) {\n if (children[i] === element) return num;\n if (children[i].nodeType === 1) num++;\n }\n }\n }\n\n return -1;\n}\n","export default function getInnerWidth(element: HTMLElement): number {\n if (element) {\n let width = element.offsetWidth;\n const style = getComputedStyle(element);\n\n width -= parseFloat(style.borderLeft) + parseFloat(style.borderRight);\n\n return width;\n }\n\n return 0;\n}\n","import getFocusableElements from './getFocusableElements';\n\nexport default function getLastFocusableElement(element: Element, selector?: string): Element | null {\n const focusableElements = getFocusableElements(element, selector);\n\n return focusableElements.length > 0 ? focusableElements[focusableElements.length - 1] : null;\n}\n","export default function getNextElementSibling(element: Element, selector: string): Element | null {\n let nextElement = element.nextElementSibling;\n\n while (nextElement) {\n if (nextElement.matches(selector)) {\n return nextElement;\n } else {\n nextElement = nextElement.nextElementSibling;\n }\n }\n\n return null;\n}\n","import getFocusableElements from './getFocusableElements';\n\nexport default function getNextFocusableElement(container: Element, element: Element, selector?: string): Element | null {\n const focusableElements: Element[] = getFocusableElements(container, selector);\n const index = focusableElements.length > 0 ? focusableElements.findIndex((el) => el === element) : -1;\n const nextIndex = index > -1 && focusableElements.length >= index + 1 ? index + 1 : -1;\n\n return nextIndex > -1 ? focusableElements[nextIndex] : null;\n}\n","import getScrollLeft from './getScrollLeft';\n\nexport default function getOffset(element?: Element | null): { top: number | string; left: number | string } {\n if (element) {\n const rect = element.getBoundingClientRect();\n\n return {\n top: rect.top + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0),\n left: rect.left + (window.pageXOffset || getScrollLeft(document.documentElement) || getScrollLeft(document.body) || 0)\n };\n }\n\n return {\n top: 'auto',\n left: 'auto'\n };\n}\n","export default function getOuterHeight(element: HTMLElement, margin?: boolean): number {\n if (element) {\n let height = element.offsetHeight;\n\n if (margin) {\n const style = getComputedStyle(element);\n\n height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);\n }\n\n return height;\n }\n\n return 0;\n}\n","import getParentNode from './getParentNode';\n\nexport default function getParents(element: Node, parents: ParentNode[] = []): ParentNode[] {\n const parent = getParentNode(element);\n\n return parent === null ? parents : getParents(parent, parents.concat([parent]));\n}\n","export default function getPreviousElementSibling(element: Element, selector: string): Element | null {\n let previousElement = element.previousElementSibling;\n\n while (previousElement) {\n if (previousElement.matches(selector)) {\n return previousElement;\n } else {\n previousElement = previousElement.previousElementSibling;\n }\n }\n\n return null;\n}\n","import findSingle from './findSingle';\nimport getParents from './getParents';\n\nexport default function getScrollableParents(element: Element): Element[] {\n const scrollableParents = [];\n\n if (element) {\n const parents = getParents(element) as HTMLElement[];\n const overflowRegex = /(auto|scroll)/;\n\n const overflowCheck = (node: Element) => {\n try {\n const styleDeclaration = window['getComputedStyle'](node, null);\n\n return overflowRegex.test(styleDeclaration.getPropertyValue('overflow')) || overflowRegex.test(styleDeclaration.getPropertyValue('overflowX')) || overflowRegex.test(styleDeclaration.getPropertyValue('overflowY'));\n } catch {\n return false;\n }\n };\n\n for (const parent of parents) {\n const scrollSelectors = parent.nodeType === 1 && parent.dataset['scrollselectors'];\n\n if (scrollSelectors) {\n const selectors = scrollSelectors.split(',');\n\n for (const selector of selectors) {\n const el = findSingle(parent, selector);\n\n if (el && overflowCheck(el)) {\n scrollableParents.push(el);\n }\n }\n }\n\n if (parent.nodeType !== 9 && overflowCheck(parent)) {\n scrollableParents.push(parent);\n }\n }\n }\n\n return scrollableParents;\n}\n","export default function getSelection(): string | undefined {\n if (window.getSelection) return (window.getSelection() as any).toString();\n else if (document.getSelection) return (document.getSelection() as any).toString();\n\n return undefined;\n}\n","export default function getUserAgent(): string {\n return navigator.userAgent;\n}\n","export default function getWidth(element: HTMLElement): number {\n if (element) {\n let width = element.offsetWidth;\n const style = getComputedStyle(element);\n\n width -= parseFloat(style.paddingLeft) + parseFloat(style.paddingRight) + parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);\n\n return width;\n }\n\n return 0;\n}\n","export default function hasCSSAnimation(element: Element): boolean {\n if (element) {\n const style = getComputedStyle(element);\n const animationDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');\n\n return animationDuration > 0;\n }\n\n return false;\n}\n","export default function hasCSSTransition(element: Element): boolean {\n if (element) {\n const style = getComputedStyle(element);\n const transitionDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');\n\n return transitionDuration > 0;\n }\n\n return false;\n}\n","export default function invokeElementMethod<T extends keyof Element>(element: Element, methodName: T, args?: unknown[]): void {\n const method = element[methodName];\n\n if (typeof method === 'function') {\n (method as (...args: unknown[]) => void).apply(element, args ?? []);\n }\n}\n","export default function isAndroid(): boolean {\n return /(android)/i.test(navigator.userAgent);\n}\n","import getAttribute from './getAttribute';\nimport isElement from './isElement';\n\nexport default function isAttributeEquals(element: Element, name: string, value: any): boolean {\n return isElement(element) ? getAttribute(element, name) === value : false;\n}\n","import isAttributeEquals from './isAttributeEquals';\n\nexport default function isAttributeNotEquals(element: Element, name: string, value: any): boolean {\n return !isAttributeEquals(element, name, value);\n}\n","export default function isClickable(element: Element): boolean {\n if (element) {\n const targetNode = element.nodeName;\n const parentNode = element.parentElement && element.parentElement.nodeName;\n\n return (\n targetNode === 'INPUT' ||\n targetNode === 'TEXTAREA' ||\n targetNode === 'BUTTON' ||\n targetNode === 'A' ||\n parentNode === 'INPUT' ||\n parentNode === 'TEXTAREA' ||\n parentNode === 'BUTTON' ||\n parentNode === 'A' ||\n !!element.closest('.p-button, .p-checkbox, .p-radiobutton') // @todo Add [data-pc-section=\"button\"]\n );\n }\n\n return false;\n}\n","export default function isClient(): boolean {\n return !!(typeof window !== 'undefined' && window.document && window.document.createElement);\n}\n","import isElement from './isElement';\n\nexport default function isFocusableElement(element: unknown, selector: string = ''): boolean {\n return isElement(element)\n ? (element as Element).matches(`button:not([tabindex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n [href][clientHeight][clientWidth]:not([tabindex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n input:not([tabindex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n select:not([tabindex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n textarea:not([tabindex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n [tabIndex]:not([tabIndex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector},\n [contenteditable]:not([tabIndex = \"-1\"]):not([disabled]):not([style*=\"display:none\"]):not([hidden])${selector}`)\n : false;\n}\n","export default function isVisible(element?: HTMLElement): boolean {\n return !!(element && element.offsetParent != null);\n}\n","import isVisible from './isVisible';\n\nexport default function isHidden(element: HTMLElement): boolean {\n return !isVisible(element);\n}\n","export default function isIOS(): boolean {\n return /iPad|iPhone|iPod/.test(navigator.userAgent) && !('MSStream' in window);\n}\n","export default function isPrefersReducedMotion(): boolean {\n if (typeof window === 'undefined' || !window.matchMedia) {\n return false;\n }\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n\n return mediaQuery.matches;\n}\n","import isClient from './isClient';\n\nexport default function isServer(): boolean {\n return !isClient();\n}\n","export default function isTouchDevice(): boolean {\n return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || (navigator as Partial<Navigator & { msMaxTouchPoints?: number }>).msMaxTouchPoints! > 0;\n}\n","import calculateScrollbarWidth from './calculateScrollbarWidth';\nimport getHiddenElementOuterHeight from './getHiddenElementOuterHeight';\nimport getHiddenElementOuterWidth from './getHiddenElementOuterWidth';\nimport getOffset from './getOffset';\nimport getOuterHeight from './getOuterHeight';\nimport getOuterWidth from './getOuterWidth';\nimport getViewport from './getViewport';\n\nexport default function nestedPosition(element: HTMLElement, level: number): void {\n if (element) {\n const parentItem = element.parentElement;\n const elementOffset = getOffset(parentItem);\n const viewport = getViewport();\n const sublistWidth = element.offsetParent ? element.offsetWidth : getHiddenElementOuterWidth(element);\n const sublistHeight = element.offsetParent ? element.offsetHeight : getHiddenElementOuterHeight(element);\n const itemOuterWidth = getOuterWidth(parentItem?.children?.[0]);\n const itemOuterHeight = getOuterHeight(parentItem?.children?.[0] as HTMLElement);\n\n let left: string = '';\n let top: string = '';\n\n if ((elementOffset.left as number) + itemOuterWidth + sublistWidth > viewport.width - calculateScrollbarWidth()) {\n if ((elementOffset.left as number) < sublistWidth) {\n // for too small screens\n if (level % 2 === 1) {\n left = (elementOffset.left as number) ? '-' + (elementOffset.left as number) + 'px' : '100%';\n } else if (level % 2 === 0) {\n left = viewport.width - sublistWidth - calculateScrollbarWidth() + 'px';\n }\n } else {\n left = '-100%';\n }\n } else {\n left = '100%';\n }\n\n // getBoundingClientRect returns a top position from the current visible viewport area\n if (element.getBoundingClientRect().top + itemOuterHeight + sublistHeight > viewport.height) {\n top = `-${sublistHeight - itemOuterHeight}px`;\n } else {\n top = '0px';\n }\n\n element.style.top = top;\n element.style.insetInlineStart = left;\n }\n}\n","export default function nextFrame(): Promise<void> {\n return new Promise((resolve) => {\n requestAnimationFrame(() => {\n requestAnimationFrame(resolve as () => void);\n });\n });\n}\n","export default function remove(element: Element) {\n if (element) {\n if (!('remove' in Element.prototype)) element.parentNode?.removeChild(element);\n else element.remove();\n }\n}\n","import toElement from './toElement';\n\nexport default function removeChild(element: unknown, child: Node) {\n const target = toElement(element);\n\n if (target) target.removeChild(child);\n else throw new Error('Cannot remove ' + child + ' from ' + element);\n}\n","import isExist from './isExist';\n\nexport default function removeStyleTag(element: Node): Node | null {\n if (isExist(element)) {\n try {\n element.parentNode?.removeChild(element);\n } catch {\n // style element may have already been removed in a fast refresh\n }\n\n return null;\n }\n\n return element;\n}\n","import getOuterHeight from './getOuterHeight';\n\nexport default function scrollInView(container: HTMLElement, item: HTMLElement): void {\n const borderTopValue = getComputedStyle(container).getPropertyValue('borderTopWidth');\n const borderTop = borderTopValue ? parseFloat(borderTopValue) : 0;\n const paddingTopValue = getComputedStyle(container).getPropertyValue('paddingTop');\n const paddingTop = paddingTopValue ? parseFloat(paddingTopValue) : 0;\n const containerRect = container.getBoundingClientRect();\n const itemRect = item.getBoundingClientRect();\n const offset = itemRect.top + document.body.scrollTop - (containerRect.top + document.body.scrollTop) - borderTop - paddingTop;\n const scroll = container.scrollTop;\n const elementHeight = container.clientHeight;\n const itemHeight = getOuterHeight(item);\n\n if (offset < 0) {\n container.scrollTop = scroll + offset;\n } else if (offset + itemHeight > elementHeight) {\n container.scrollTop = scroll + offset - elementHeight + itemHeight;\n }\n}\n","import isElement from './isElement';\n\nexport default function setAttribute(element: HTMLElement, attribute: string = '', value: any): void {\n if (isElement(element) && value !== null && value !== undefined) {\n element.setAttribute(attribute, value);\n }\n}\n","export default function setCSSProperty(element?: HTMLElement, property?: string, value: any = null, priority?: string