{"version":3,"sources":["components/ads-horizontal-tabs/ads-horizontal-tabs.types.ts","../node_modules/@fortawesome/pro-regular-svg-icons/faCircleXmark.js","../node_modules/@fortawesome/pro-regular-svg-icons/faTimesCircle.js","components/ads-horizontal-tabs/components/ads-horizontal-tabs-tab/ads-horizontal-tabs-tab.tsx","components/ads-horizontal-tabs/ads-horizontal-tabs.tsx","components/ads-horizontal-tabs/ads-horizontal-tabs.scss?tag=ads-horizontal-tabs&encapsulation=shadow","components/core/global/pipeline.ts","components/core/utils/pipeline.ts","components/core/utils/components.ts","utils/imageHelper.tsx","utils/breakpointHelper.ts","utils/resizeHelper.ts","utils/DOMHelper.ts","components/core/interfaces/Icon.ts","utils/focusHelper.ts","utils/eventHelper.ts"],"names":["AdsHorizontalTabsErrors","Object","defineProperty","exports","value","aliases","svgPathData","prefix","iconName","icon","definition","source","width","height","unicode","AdsHorizontalTabsTab","tabsId","id","isActive","label","dismissible","isFirst","isLast","onSelect","onBlur","onClose","onFocus","selectHandler","blurHandler","closeHandler","focusHandler","attributes","buttonAttrs","role","toString","buttonClasses","push","$closeButton","class","onClick","evt","stopImmediatePropagation","emit","tabIndex","data","iconObj","classIcon","active","$icon","join","onKeyUp","code","key","preventDefault","AdsHorizontalTabs","firstRender","onDirChange","navigationEl","getNavigationContainer","classList","add","updateActiveLine","setTimeout","remove","getFirstTabIdentifier","length","setActiveTabState","newActiveTab","activeTabInternal","activeTab","getActiveTabElement","activeTabClientRect","getBoundingClientRect","$container","el","shadowRoot","querySelector","style","setProperty","left","x","XL","this","setAttribute","identifier","component","newValue","changeActiveTab","detail","every","tab","Promise","resolve","focusSlottedContent","slottedContentElements","newActiveTabEl","find","slotElement","getAttribute","TAB_DOESNT_EXIST","$slottedContentElements","map","$slotElement","slotElementIdentifier","mutationObs","updateSlottedContentActiveStates","Pipeline.addComponent","Pipeline.removeComponent","disconnect","index","tabSelect","tabSelectHandler","tabBlur","tabBlurHandler","tabClose","tabCloseHandler","tabFocus","tabFocusHandler","$tabElements","renderTabs","srLabel","navigationClasses","breakpoint","$navigation","$content","name","window","pipeline","set","tagName","toLowerCase","config","getBoolean","trackEvent","COMPONENT_REGISTER","componentId","environment","version","host","location","err","console","log","sendCustomEvent","addComponent","Pipeline.add","removeComponent","delete","Pipeline.remove","generateId","namespace","generateRandomString","Math","random","substr","getClassFromSize","size","MEDIUM","SMALL","getClassFromLevel","level","PRIMARY","SECONDARY","TERTIARY","getMediaQueryBreakpointClassUp","bp","getMediaQueryBreakpointClassDown","showErrorMessage","message","ADS_CONSOLE_ERROR","warn","generateSVGImage","className","xmlns","viewBox","d","MediaTypes","getBreakpointInPixels","parseInt","breakpoints","mediaQueryLists","addMatchMedia","mediaType","listenerFunction","foundMatchMedia","m","media","newMatchMedia","matchMedia","addEventListener","removeMatchMedia","removeEventListener","callbacks","onresize","cb","timeout","callback","duration","subscribeToWindowResize","timeoutDuration","unSubscribeToWindowResize","findIndex","clearTimeout","splice","getContentFromSlotElementsRecursively","slotElements","reduce","acc","currentValue","assignedElements","isElementChildOfComponent","componentEl","element","maxIterations","tmpElement","parentElement","getSlottedElements","slotName","selector","Array","from","querySelectorAll","assignedNodes","flat","getAllElementsWithSlotAttribute","filter","getIsElementDescendantOfElement","el1","el2","getParentInDom","assignedSlot","getRootNode","currentIteration","currentParent","getIsElementRTL","elem","RTL","document","documentElement","LTR","getHtmlDirObserver","onDirMutationCallback","obs","MutationObserver","mutationList","htmlDirMutation","ml","target","nodeName","attributeName","observe","childList","subtree","getIconObject","src","isIcon","inactive","getSVGIconObject","isSVGIcon","toBeDetermined","getFocusableSelector","getFocusableElements","container","getFirstFocusableElement","focusable","focusElement","focus","firstFocusableInShadowRoot","focusElementInShadowRoot","observeContainer","onIntersectionCallback","intersectionObserver","IntersectionObserver","entries","entry","isIntersecting","unobserve","focusArea","containerElement","onFocusOutCallback","startFromEnd","unshift","lastFocusable","firstFocusable","onEdgeElementBlur","nextElement","relatedTarget","setFocusOnArea","areaContainer","observedElement","isKeyboardClickEvent","KeyboardEvent","MouseEvent","clientX","clientY"],"mappings":"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","file":"static/js/9.87f1c8d5.chunk.js","sourcesContent":["import { Icon, SVGIcon } from '../core/interfaces/Icon';\n\nexport enum AdsHorizontalTabsErrors {\n TAB_DOESNT_EXIST = \"No tab matching prop 'activeTab' value\",\n}\n\n/**\n * An interface for the horizontal Tab\n * @docs\n */\nexport interface HorizontalTab {\n id: string;\n icon?: Icon | SVGIcon;\n label: string;\n dismissible?: boolean;\n attributes?: any;\n}\n\n/**\n * An interface for the `TabSelectEvent` event\n * @docs\n */\nexport interface TabSelectEvent {\n evt: Event;\n id: string;\n}\n\n/**\n * An interface that describes the tab selection handler\n */\nexport type TabSelectHandler = (evt: TabSelectEvent) => void;\n\n/**\n * An interface that describes the tab close event\n * @docs\n */\nexport interface TabCloseEvent {\n evt: MouseEvent;\n id: string;\n}\n\n/**\n * An interface that describes the tab close handler\n */\nexport type TabCloseHandler = (evt: TabCloseEvent) => void;\n\n/**\n * An interface that describes the tab blur event\n * @docs\n */\nexport interface TabBlurEvent {\n evt: FocusEvent;\n id: string;\n}\n\n/**\n * An interface that describes the tab blur handler\n */\nexport type TabBlurHandler = (evt: TabBlurEvent) => void;\n\n/**\n * An interface that describes the tab focus event\n * @docs\n */\nexport interface TabFocusEvent {\n evt: FocusEvent;\n id: string;\n}\n\n/**\n * An interface that describes the tab focus handler\n */\nexport type TabFocusHandler = (evt: TabFocusEvent) => void;\n","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'circle-xmark';\nvar width = 512;\nvar height = 512;\nvar aliases = [61532,\"times-circle\",\"xmark-circle\"];\nvar unicode = 'f057';\nvar svgPathData = 'M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c-9.4 9.4-9.4 24.6 0 33.9l47 47-47 47c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l47-47 47 47c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-47-47 47-47c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-47 47-47-47c-9.4-9.4-24.6-9.4-33.9 0z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n aliases,\n unicode,\n svgPathData\n ]};\n\nexports.faCircleXmark = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = aliases;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;\nexports.aliases = aliases;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar source = require('./faCircleXmark');\nexports.definition = {\n prefix: source.prefix,\n iconName: source.iconName,\n icon: [\n source.width,\n source.height,\n source.aliases,\n source.unicode,\n source.svgPathData\n ]};\n\nexports.faTimesCircle = exports.definition;\nexports.prefix = source.prefix;\nexports.iconName = source.iconName;\nexports.width = source.width;\nexports.height = source.height;\nexports.ligatures = source.aliases;\nexports.unicode = source.unicode;\nexports.svgPathData = source.svgPathData;\nexports.aliases = source.aliases;","import { EventEmitter, FunctionalComponent, VNode, h } from '@stencil/core';\nimport { Icon, SVGIcon, getIconObject } from 'src/components/core/interfaces/Icon';\nimport {\n TabBlurEvent,\n TabBlurHandler,\n TabCloseEvent,\n TabCloseHandler,\n TabFocusEvent,\n TabFocusHandler,\n TabSelectEvent,\n TabSelectHandler,\n} from '../../ads-horizontal-tabs.types';\nimport { generateSVGImage } from 'utils/imageHelper';\nimport { height, svgPathData, width } from '@fortawesome/pro-regular-svg-icons/faTimesCircle';\nimport { isNullOrUndefined } from 'utils/collection';\n\ninterface AdsHorizontalTabsTabProps {\n tabsId: string;\n id: string;\n isActive: boolean;\n icon?: Icon | SVGIcon;\n label: string;\n dismissible?: boolean;\n isFirst: boolean;\n isLast: boolean;\n onSelect: EventEmitter<TabSelectEvent>;\n selectHandler?: TabSelectHandler;\n onBlur: EventEmitter<TabBlurEvent>;\n blurHandler?: TabBlurHandler;\n onClose: EventEmitter<TabCloseEvent>;\n closeHandler?: TabCloseHandler;\n onFocus: EventEmitter<TabFocusEvent>;\n focusHandler?: TabFocusHandler;\n attributes?: any;\n}\n\nexport const AdsHorizontalTabsTab: FunctionalComponent<AdsHorizontalTabsTabProps> = ({\n tabsId,\n id,\n isActive,\n icon,\n label,\n dismissible,\n isFirst,\n isLast,\n onSelect,\n onBlur,\n onClose,\n onFocus,\n selectHandler,\n blurHandler,\n closeHandler,\n focusHandler,\n attributes,\n}) => {\n const blur = (evt: FocusEvent): void => {\n onBlur.emit({ evt: evt, id: id });\n if (!isNullOrUndefined(blurHandler)) {\n blurHandler({ evt: evt, id: id });\n }\n };\n const close = (evt: MouseEvent): void => {\n evt.stopImmediatePropagation();\n onClose.emit({ evt: evt, id: id });\n if (!isNullOrUndefined(closeHandler)) {\n closeHandler({ evt: evt, id: id });\n }\n };\n const focus = (evt: FocusEvent): void => {\n onFocus.emit({ evt: evt, id: id });\n if (!isNullOrUndefined(focusHandler)) {\n focusHandler({ evt: evt, id: id });\n }\n };\n const click = (evt: MouseEvent): void => {\n onSelect.emit({ evt: evt, id: id });\n if (!isNullOrUndefined(selectHandler)) {\n selectHandler({ evt: evt, id: id });\n }\n };\n const keyUp = (evt: KeyboardEvent): void => {\n if (evt.code === 'Enter' || evt.code === 'Space' || evt.key === 'Enter' || evt.key === 'Spacebar') {\n evt.preventDefault();\n onSelect.emit({ evt: evt, id: id });\n if (!isNullOrUndefined(selectHandler)) {\n selectHandler({ evt: evt, id: id });\n }\n }\n };\n\n let buttonAttrs = {\n role: 'tab',\n 'aria-controls': `tabs:${tabsId}:panel:${id}`,\n 'aria-describedby': `tabs:${tabsId}:panel:${id}`,\n 'aria-label': label,\n 'aria-selected': (!!isActive).toString(),\n 'data-track': 'true',\n 'data-track-value': label,\n };\n\n // Update the button attributes if additional attributes are provided\n buttonAttrs = typeof attributes === 'object' ? { ...buttonAttrs, ...attributes } : buttonAttrs;\n\n const buttonClasses = ['c-horizontal-tabs__tab__btn'];\n if (isActive) {\n buttonClasses.push('is-active');\n }\n if (isFirst) {\n buttonClasses.push('is-first');\n }\n if (isLast) {\n buttonClasses.push('is-last');\n }\n\n const $closeButton = dismissible\n ? ((\n <button class={'c-horizontal-tabs__tab__close'} onClick={close} tabIndex={0} role=\"button\">\n {generateSVGImage({ data: svgPathData, height, width })}\n </button>\n ) as VNode)\n : null;\n\n const iconObj = getIconObject(icon as Icon);\n const classIcon = iconObj?.active;\n const $icon = classIcon ? <span class={`${classIcon} c-horizontal-tabs__tab__btn__icon`}></span> : null;\n\n return (\n <div role=\"none\" class={`c-horizontal-tabs__tab`} data-active={isActive} data-slot={id}>\n <button\n id={`tabs:${tabsId}:tab:${id}`}\n class={buttonClasses.join(' ')}\n onClick={click}\n onBlur={blur}\n onFocus={focus}\n onKeyUp={keyUp}\n {...buttonAttrs}\n tabIndex={0}\n >\n <div>\n <span>\n {$icon}\n <span>{label}</span>\n </span>\n </div>\n </button>\n {$closeButton}\n </div>\n ) as VNode;\n};\n","import * as Pipeline from '../core/utils/pipeline';\nimport {\n AdsHorizontalTabsErrors,\n HorizontalTab,\n TabBlurEvent,\n TabBlurHandler,\n TabCloseEvent,\n TabCloseHandler,\n TabFocusEvent,\n TabFocusHandler,\n TabSelectEvent,\n TabSelectHandler,\n} from './ads-horizontal-tabs.types';\nimport { AdsHorizontalTabsTab } from './components/ads-horizontal-tabs-tab/ads-horizontal-tabs-tab';\nimport { BaseComponent } from '../core/interfaces/BaseComponent';\nimport { Breakpoint, Breakpoints } from '../core/types/globalTypes';\nimport { Component, Element, Event, EventEmitter, Listen, Method, Prop, State, VNode, Watch, h } from '@stencil/core';\nimport { Theme } from '../core/types/globalTypes';\nimport { generateId, getMediaQueryBreakpointClassUp, showErrorMessage } from '../core/utils/components';\nimport {\n getHtmlDirObserver,\n getSlottedElements,\n isKeyboardClickEvent,\n isNil,\n isNullOrUndefined,\n isNullOrUndefinedOrEmpty,\n setFocusOnArea,\n} from 'utils/index';\n\n/**\n * Tabs are used to navigate between views within the same context. Tabs are best used to separate content into smaller groups of related information. As default one tab will already be selected and its related content will be visible. Only one tab can be selected at a time.\n * @tag `<ads-horizontal-tabs>`\n * @slot content - The content associated with a tab\n * @example <ads-horizontal-tabs><div slot=\"content\" data-id=\"slot-1\">slot-1 text</div><div slot=\"content\" data-id=\"slot-2\">slot-2 text</div></ads-horizontal-tabs>\n */\n@Component({\n tag: 'ads-horizontal-tabs',\n styleUrl: 'ads-horizontal-tabs.scss',\n shadow: true,\n})\nexport class AdsHorizontalTabs implements BaseComponent {\n public component: string;\n\n private firstRender = true;\n\n private mutationObs: MutationObserver;\n\n constructor() {\n this.el.setAttribute('id', this.identifier || generateId('ads-horizontal-tabs'));\n this.component = 'ads-horizontal-tabs';\n }\n\n @Element() private el: HTMLAdsHorizontalTabsElement;\n\n /**\n * @hidden\n */\n @State() activeTabInternal: string;\n\n /**\n * The unique identifier (optional)\n */\n @Prop({ attribute: 'id' }) identifier?: string;\n\n /**\n * The dir attribute (optional)\n */\n @Prop({ attribute: 'dir' }) direction?: string;\n\n /**\n * The theme for this component instance (optional)\n * Values: \"default\", \"dark\"\n */\n @Prop({ reflect: true }) theme?: Theme;\n\n /**\n * The breakpoint for the components responsiveness (optional)\n * @default \"xl\"\n */\n @Prop({ reflect: true }) breakpoint: Breakpoint = Breakpoints.XL;\n\n /**\n * The currently active tab (optional)\n */\n @Prop({ reflect: true }) activeTab?: string;\n\n /**\n * The data that defines the tabs\n */\n @Prop() data: HorizontalTab[];\n\n /**\n * Text to display as the aria-label of the component (optional)\n */\n @Prop({ reflect: true }) srLabel?: string;\n\n /**\n * Callback function triggered on tab selection (optional)\n */\n @Prop() tabSelectHandler?: TabSelectHandler;\n\n /**\n * Callback function triggered on tab blur (optional)\n */\n @Prop() tabBlurHandler?: TabBlurHandler;\n\n /**\n * Callback function triggered on tab close (optional)\n */\n @Prop() tabCloseHandler?: TabCloseHandler;\n\n /**\n * Callback function triggered on tab focus (optional)\n */\n @Prop() tabFocusHandler?: TabFocusHandler;\n\n /**\n * Emits 'tabBlur' custom event.\n * Usage: `document.querySelector('ads-horizontal-tabs').addEventListener('tabBlur', function(evt) {});`\n * @event\n */\n @Event({ bubbles: false }) tabBlur: EventEmitter<TabBlurEvent>;\n\n /**\n * Emits 'tabClose' custom event.\n * Usage: `document.querySelector('ads-horizontal-tabs').addEventListener('tabClose', function(evt) {});`\n * @event\n */\n @Event({ bubbles: false }) tabClose: EventEmitter<TabCloseEvent>;\n\n /**\n * Emits 'tabFocus' custom event.\n * Usage: `document.querySelector('ads-horizontal-tabs').addEventListener('tabFocus', function(evt) {});`\n * @event\n */\n @Event({ bubbles: false }) tabFocus: EventEmitter<TabFocusEvent>;\n\n /**\n * Emits 'tabSelect' custom event.\n * Usage: `document.querySelector('ads-horizontal-tabs').addEventListener('tabSelect', function(evt) {});`\n * @event\n */\n @Event({ bubbles: false }) tabSelect: EventEmitter<TabSelectEvent>;\n\n /**\n * Handle identifier property changes\n * @param {string} newValue The new value for \"identifier\"\n * @hidden\n */\n @Watch('identifier')\n handleIdentifierChange(newValue: string): void {\n this.el.setAttribute('id', newValue || generateId('ads-horizontal-tabs'));\n }\n\n /**\n * Handle direction property changes\n */\n @Watch('direction')\n handleDirectionChange(): void {\n this.onDirChange();\n }\n\n /**\n * Listen to tabSelect event. (triggered by the tab component)\n * @param {CustomEvent} evt the selection event\n * @returns {void}\n * @hidden\n */\n @Listen('tabSelect')\n protected onTabSelected(evt: CustomEvent<TabSelectEvent>): void {\n if (isNullOrUndefinedOrEmpty(this.activeTab)) {\n this.changeActiveTab(evt.detail.id, isKeyboardClickEvent(evt.detail.evt));\n }\n }\n\n /**\n * Watch for activeTab prop change.\n * @param {string} newValue the new prop value\n * @returns {void}\n * @hidden\n */\n @Watch('activeTab')\n onActiveTabChanged(newValue: string): void {\n if (!isNullOrUndefinedOrEmpty(newValue)) {\n this.changeActiveTab(newValue);\n }\n }\n\n /**\n * Watch for data prop change.\n * @param {HorizontalTab[]} newValue the new prop value\n * @returns {void}\n * @hidden\n */\n @Watch('data')\n onDataChanged(newValue: HorizontalTab[]): void {\n if (isNullOrUndefined(newValue)) {\n return;\n }\n if (\n isNullOrUndefinedOrEmpty(this.activeTab) &&\n (isNullOrUndefinedOrEmpty(this.activeTabInternal) || newValue.every((tab: HorizontalTab) => tab.id !== this.activeTabInternal))\n ) {\n this.setActiveTabState(this.getFirstTabIdentifier(newValue));\n } else {\n setTimeout(() => {\n this.updateActiveLine();\n }, 100);\n }\n }\n\n /**\n * Returns the id of the current active tab\n * @return {Promise<string>} The active tab id\n */\n @Method()\n value(): Promise<string> {\n return Promise.resolve(this.activeTabInternal);\n }\n\n /**\n * Updates underline with transition\n */\n private onDirChange = () => {\n const navigationEl = this.getNavigationContainer();\n navigationEl?.classList.add('no-transition');\n this.updateActiveLine();\n setTimeout(() => {\n navigationEl?.classList.remove('no-transition');\n }, 50);\n };\n\n /**\n * Gets the first tab id\n * @param {HorizontalTab[]} data the data to go through\n * @returns {string} the fist id\n */\n private getFirstTabIdentifier = (data: HorizontalTab[]): string => {\n return !isNullOrUndefined(data) && !isNil(data.length) ? data[0].id : '';\n };\n\n /**\n * Sets the active tab state\n * @param {string} newActiveTab The new active tab value\n */\n private setActiveTabState = (newActiveTab: string): void => {\n this.activeTabInternal = newActiveTab;\n this.updateActiveLine();\n };\n\n /**\n * Update the css props that drive the underline\n */\n private updateActiveLine = (): void => {\n const activeTab = this.getActiveTabElement();\n if (!isNullOrUndefined(activeTab)) {\n const activeTabClientRect = activeTab.getBoundingClientRect();\n const $container = this.el.shadowRoot.querySelector('.c-horizontal-tabs__navigation');\n this.el.style.setProperty('--ads-horizontal-tabs-active-width', `${activeTabClientRect.width}px`);\n this.el.style.setProperty('--ads-horizontal-tabs-active-left', `${activeTabClientRect.left - $container.getBoundingClientRect().x}px`);\n }\n };\n\n /**\n * Gets the active tab element\n * @returns {Element} The active tab element\n */\n private getActiveTabElement = (): Element => this.el.shadowRoot.querySelector(`[data-slot=\"${this.activeTabInternal}\"]`);\n\n /**\n * Gets the navigation container element\n * @returns {HTMLElement} The navigation container element\n */\n private getNavigationContainer = (): HTMLElement => this.el.shadowRoot.querySelector('.c-horizontal-tabs__navigation');\n\n /**\n * Sets the current active tab\n * @param {string} id The tab id to set as active\n * @param {boolean} focusSlottedContent Should focus slotted content\n */\n private changeActiveTab(id: string, focusSlottedContent = false): void {\n const slottedContentElements = getSlottedElements(this.el, 'content');\n const newActiveTabEl = slottedContentElements.find((slotElement: HTMLElement) => slotElement.getAttribute('data-id') === id);\n if (!isNullOrUndefined(newActiveTabEl)) {\n if (focusSlottedContent) {\n setFocusOnArea(newActiveTabEl);\n }\n this.setActiveTabState(id);\n } else {\n // if customer defined active tab doesn't exist, show error message\n if (!isNullOrUndefinedOrEmpty(this.activeTab) && !this.firstRender) {\n showErrorMessage(AdsHorizontalTabsErrors.TAB_DOESNT_EXIST, this.el);\n }\n }\n }\n\n /**\n * Updates the content attributes based on active tab\n */\n private updateSlottedContentActiveStates(): void {\n const $slottedContentElements = getSlottedElements(this.el, 'content');\n if (isNil($slottedContentElements.length)) {\n return;\n }\n $slottedContentElements.map(($slotElement: HTMLElement) => {\n const slotElementIdentifier = $slotElement.getAttribute('data-id');\n $slotElement.setAttribute('id', `tabs:${this.identifier}:panel:${slotElementIdentifier}`);\n $slotElement.setAttribute('role', 'tabpanel');\n $slotElement.classList.remove('active');\n if (slotElementIdentifier === this.activeTabInternal) {\n $slotElement.classList.add('active');\n }\n });\n }\n\n protected componentWillLoad(): void {\n if (isNullOrUndefinedOrEmpty(this.activeTab)) {\n this.setActiveTabState(this.getFirstTabIdentifier(this.data));\n } else {\n this.setActiveTabState(this.activeTab);\n }\n this.mutationObs = getHtmlDirObserver(this.onDirChange);\n }\n\n protected componentDidLoad(): void {\n this.updateSlottedContentActiveStates();\n this.updateActiveLine();\n Pipeline.addComponent(this.el);\n this.firstRender = false;\n setTimeout(() => {\n this.getNavigationContainer()?.classList.remove('no-transition');\n }, 50);\n }\n\n protected disconnectedCallback(): void {\n Pipeline.removeComponent(this.el);\n this.mutationObs?.disconnect();\n }\n\n /**\n * Renders the tabs sub-components\n * @returns {VNode} the tab elements\n */\n private renderTabs() {\n return !isNullOrUndefined(this.data) && this.data.length > 0\n ? this.data.map((tab: HorizontalTab, index) => {\n return (\n <AdsHorizontalTabsTab\n tabsId={this.identifier}\n id={tab.id}\n isActive={tab.id === this.activeTabInternal}\n icon={tab.icon}\n label={tab.label}\n dismissible={tab.dismissible}\n isFirst={index === 0}\n isLast={this.data.length === index + 1}\n onSelect={this.tabSelect}\n selectHandler={this.tabSelectHandler}\n onBlur={this.tabBlur}\n blurHandler={this.tabBlurHandler}\n onClose={this.tabClose}\n closeHandler={this.tabCloseHandler}\n onFocus={this.tabFocus}\n focusHandler={this.tabFocusHandler}\n attributes={tab.attributes}\n />\n ) as VNode;\n })\n : null;\n }\n\n protected render(): VNode {\n if (isNullOrUndefined(this.data)) {\n return;\n }\n\n this.updateSlottedContentActiveStates();\n const $tabElements = this.renderTabs();\n const attributes = {\n 'aria-label': this.srLabel,\n 'aria-orientation': 'horizontal',\n };\n\n const cssVars: { 'background-color'?: string } = {};\n\n const navigationClasses = ['c-horizontal-tabs__navigation', `${getMediaQueryBreakpointClassUp(this.breakpoint)}`];\n if (this.firstRender) {\n navigationClasses.push('no-transition');\n }\n\n const $navigation = (\n <div class={navigationClasses.join(' ')} role=\"tablist\" {...attributes}>\n {$tabElements}\n </div>\n ) as HTMLElement;\n\n const $content = (\n <div class=\"c-horizontal-tabs__content js-horizontal-tabs-content\" style={cssVars}>\n <slot name=\"content\" />\n </div>\n ) as HTMLElement;\n\n return (\n <div class=\"c-horizontal-tabs js-horizontal-tabs\">\n <div class={`c-horizontal-tabs__tab-container ${getMediaQueryBreakpointClassUp(this.breakpoint)}`}>\n <div class={`c-horizontal-tabs__navigation-wrapper ${getMediaQueryBreakpointClassUp(this.breakpoint)}`}>{$navigation}</div>\n </div>\n {$content}\n </div>\n ) as VNode;\n }\n}\n","@import 'core';\n\n@import '@fortawesome/fontawesome-pro/scss/fontawesome.scss';\n@import '@fortawesome/fontawesome-pro/scss/brands.scss';\n@import '@fortawesome/fontawesome-pro/scss/light.scss';\n@import '@fortawesome/fontawesome-pro/scss/regular.scss';\n@import '@fortawesome/fontawesome-pro/scss/solid.scss';\n\n@import 'components/ads-horizontal-tabs-tab/ads-horizontal-tabs-tab.scss';\n\n/**\n * @prop --ads-horizontal-tabs-gradient-transparency: Top level transparency for border image gradient\n * @prop --ads-horizontal-tabs-navigation-background-color: Default top level background color\n * @prop --ads-horizontal-tabs-navigation-border-gradient: Top level border image gradient\n * @prop --ads-horizontal-tabs-tab-background-color: Default tab background color\n * @prop --ads-horizontal-tabs-tab-border-color: Default tab border color\n * @prop --ads-horizontal-tabs-tab-color: Default tab font color\n * @prop --ads-horizontal-tabs-tab-color-active: Tab font color on active\n * @prop --ads-horizontal-tabs-tab-color-hover: Tab font color on hover\n * @prop --ads-horizontal-tabs-tab-container-position: Tab container position behaviour\n * @prop --ads-horizontal-tabs-tab-container-top: Tab container vertical positioning\n * @prop --ads-horizontal-tabs-tab-content-background-color: Tab content color\n * @prop --ads-horizontal-tabs-underline-color: Tab border color on active\n * @prop --ads-horizontal-tabs-wrapper-left: Left element of wrapper\n * @prop --ads-horizontal-tabs-close-fill-color: Color of close icon\n * @prop --ads-horizontal-tabs-close-fill-color-hover: Hover color of close icon\n */\n\n$ads-horizontal-tabs-active-left: 0;\n$ads-horizontal-tabs-active-width: 0;\n\n::slotted(*) {\n display: none !important;\n}\n\n::slotted(.active) {\n box-sizing: border-box !important;\n display: block !important;\n min-height: 100%;\n padding: 0 !important;\n width: 100%;\n}\n\n:host {\n --ads-horizontal-tabs-active-left: #{$ads-horizontal-tabs-active-left};\n --ads-horizontal-tabs-active-width: #{$ads-horizontal-tabs-active-width};\n display: block;\n height: 100%;\n width: 100%;\n}\n\n:host([theme='default']) {\n @include ads-vars-component-horizontal-tabs-default;\n @include ads-vars-component-paragraph-default;\n @include ads-vars-component-heading-default;\n}\n\n:host([theme='dark']) {\n @include ads-vars-component-horizontal-tabs-dark;\n @include ads-vars-component-paragraph-dark;\n @include ads-vars-component-heading-dark;\n}\n\n:host([dir='ltr']) {\n @include ads-vars-component-horizontal-tabs-ltr;\n}\n\n:host([dir='rtl']) {\n @include ads-vars-component-horizontal-tabs-rtl;\n}\n\n.c-horizontal-tabs {\n background: var(--ads-horizontal-tabs-tab-content-background-color, $ads-horizontal-tabs-tab-content-background-color);\n font-family: var(--ads-font-family);\n\n &__content {\n background-color: var(--ads-horizontal-tabs-tab-content-background-color, $ads-horizontal-tabs-tab-content-background-color);\n }\n\n &__navigation {\n display: grid;\n gap: 2rem;\n grid-auto-columns: max-content;\n grid-auto-flow: column;\n padding-right: 1rem;\n position: relative;\n\n @include breakpoints-up() {\n padding-right: 0;\n }\n\n &::after {\n background-color: var(--ads-horizontal-tabs-underline-color, $ads-horizontal-tabs-underline-color);\n bottom: 0;\n content: '';\n height: 1px;\n left: var(--ads-horizontal-tabs-active-left, $ads-horizontal-tabs-active-left);\n position: absolute;\n transition: width 0.3s ease-in-out, left 0.3s ease-in-out;\n width: var(--ads-horizontal-tabs-active-width, $ads-horizontal-tabs-active-width);\n }\n\n &.no-transition::after {\n transition: none !important;\n }\n }\n\n &__tab-container {\n background-color: var(--ads-horizontal-tabs-navigation-background-color, $ads-horizontal-tabs-navigation-background-color);\n border: 0;\n border-bottom: 3px solid;\n border-image: var(--ads-horizontal-tabs-navigation-border-gradient, $ads-horizontal-tabs-navigation-border-gradient);\n border-image-slice: 1;\n display: flex;\n margin: 0 0 -1px 0;\n overflow-x: auto;\n position: var(--ads-horizontal-tabs-tab-container-position, $ads-horizontal-tabs-tab-container-position);\n top: var(--ads-horizontal-tabs-tab-container-top, $ads-horizontal-tabs-tab-container-top);\n z-index: $layer-4;\n\n &::before {\n background: linear-gradient(\n var(--ads-horizontal-tabs-gradient-rotation, $ads-horizontal-tabs-gradient-rotation-ltr),\n var(--ads-horizontal-tabs-gradient-transparency, $ads-horizontal-tabs-gradient-transparency) 75%,\n var(--ads-horizontal-tabs-navigation-background-color, $ads-horizontal-tabs-navigation-background-color) 100%\n );\n content: '';\n display: inline-block;\n flex-shrink: 0;\n height: 40px;\n left: 0;\n pointer-events: none;\n position: sticky;\n right: 0;\n width: 100%;\n z-index: $layer-12;\n }\n }\n\n &__navigation-wrapper {\n left: var(--ads-horizontal-tabs-wrapper-left, $ads-horizontal-tabs-wrapper-left);\n position: absolute;\n padding-right: 30px;\n\n @include breakpoints-up() {\n left: 0;\n }\n }\n}\n","import { EventTypes, environment, version } from './AppInsights/constants';\nimport { WindowGlobal } from '../types/globalTypes';\n\n/**\n * Send custom event to AppInsights\n * @param {string} component The reference to the component\n * @returns {void}\n * @hidden\n */\nconst sendCustomEvent = (component: HTMLElement): void => {\n try {\n (window as WindowGlobal)['AppInsights'].trackEvent(\n {\n name: EventTypes.COMPONENT_REGISTER,\n },\n {\n component: component.tagName.toLowerCase(),\n componentId: component.id,\n environment,\n version,\n host: window.location.host,\n }\n );\n } catch (err) {\n // eslint-disable-next-line no-console\n console.log('[APP INSIGHTS] Could not send event', err);\n }\n};\n\n/**\n * Add the component to the pipeline and send component events to AppInsights\n * @param {HTMLElement} component The component element\n * @returns {void}\n * @hidden\n */\nexport function add(component: HTMLElement): void {\n (window as WindowGlobal)['ArmDesignSystem'].pipeline.set(component.id, component.tagName.toLowerCase());\n\n // Disable sending events to AppInsights during unit tests\n if (!(window as WindowGlobal)['ArmDesignSystem'].config.getBoolean('_isTesting')) {\n sendCustomEvent(component);\n }\n}\n\n/**\n * Remove the component from the pipeline\n * @param {HTMLElement} component The component element\n * @returns {void}\n * @hidden\n */\nexport function remove(component: HTMLElement): void {\n (window as WindowGlobal)['ArmDesignSystem'].pipeline.delete(component.id);\n}\n","import * as Pipeline from '../global/pipeline';\n\n/**\n * Add a component to the ADS pipeline\n * @param {HTMLElement} component The component element\n * @return {void}\n */\nexport const addComponent = (component: HTMLElement): void => {\n Pipeline.add(component);\n};\n\n/**\n * Remove a component from the ADS pipeline\n * @param {HTMLElement} component The component element\n * @return {void}\n */\nexport const removeComponent = (component: HTMLElement): void => {\n Pipeline.remove(component);\n};\n","import { Breakpoint, ButtonLevel, ButtonLevels, ButtonSize, ButtonSizes, WindowGlobal } from '../types/globalTypes';\nimport { EventTypes, environment, version } from '../global/AppInsights/constants';\n\nexport type ShadowRootLegacy = ShadowRoot & { tagName: string };\n\n/**\n * Generates a unique component ID\n * @param {string} namespace The unique id's namespace (e.g. ads)\n * @returns {string} A generated random id (e.g. ads-1234)\n */\nexport const generateId = (namespace = 'ads'): string => {\n return `${namespace}-${generateRandomString()}`;\n};\n\n/**\n * Generates a randon string\n * @returns {string} A generated random string\n */\nexport const generateRandomString = (): string => {\n return Math.random().toString(36).substr(2, 16);\n};\n\n/**\n * Generates a size class based on a button size\n * @param {ButtonSize} size The size of the button (e.g. ButtonSizes.SMALL)\n * @returns {string} The button size class (e.g. 'is-small')\n */\nexport const getClassFromSize = (size: ButtonSize): string => {\n switch (size) {\n case ButtonSizes.MEDIUM:\n return 'is-medium';\n case ButtonSizes.SMALL:\n return 'is-small';\n default:\n return '';\n }\n};\n\n/**\n * Generates a level class based on button a level\n * @param {ButtonLevel} level The level of the button (e.g. ButtonLevels.PRIMARY)\n * @returns {string} The button level class (e.g. 'is-primary')\n */\nexport const getClassFromLevel = (level: ButtonLevel): string => {\n switch (level) {\n case ButtonLevels.PRIMARY:\n return 'is-primary';\n case ButtonLevels.SECONDARY:\n return 'is-secondary';\n case ButtonLevels.TERTIARY:\n return 'is-tertiary';\n default:\n return '';\n }\n};\n\n/**\n * Given a breakpoint it will return the appropriate class for the media-queries (breakpoints-up).\n * @param {Breakpoint} bp The breakpoint.\n * @returns {string} The class.\n */\nexport const getMediaQueryBreakpointClassUp = (bp: Breakpoint): string => `${bp.toString()}-up`;\n\n/**\n * Given a breakpoint it will return the appropriate class for the media-queries (breakpoints-down).\n * @param {Breakpoint} bp The breakpoint.\n * @returns {string} The class.\n */\nexport const getMediaQueryBreakpointClassDown = (bp: Breakpoint): string => `${bp.toString()}-down`;\n\n/**\n * Display an ADS warning with the given message\n * @param {string} message The error message to show\n * @param {string} component The reference to the component\n * @returns {void}\n */\nexport const showErrorMessage = (message: string, component: HTMLElement): void => {\n try {\n (window as WindowGlobal)['AppInsights'].trackEvent(\n {\n name: EventTypes.ADS_CONSOLE_ERROR as string,\n },\n {\n component: component.tagName.toLowerCase(),\n componentId: component.id,\n message: message,\n environment,\n version,\n host: window.location.host,\n }\n );\n } catch (err) {\n // eslint-disable-next-line no-console\n console.log('[APP INSIGHTS] Could not send console error', err);\n }\n // eslint-disable-next-line no-console\n console.warn(`ADS-Warning: ${message}`);\n};\n","import { SVGIconData } from '../components/core/interfaces/Icon';\nimport { h } from '@stencil/core';\n\n/**\n * Generates an SVG image\n * @param {IconData} icon The SVG image properties\n * @param {string} className The SVG image class name\n * @returns {HTMLElement} The generated SVG image\n */\nexport const generateSVGImage = (icon: SVGIconData, className?: string): HTMLElement => {\n return (\n <svg class={className ? className : null} xmlns=\"http://www.w3.org/2000/svg\" viewBox={`0 0 ${icon.width} ${icon.height}`}>\n <path d={icon.data} />\n </svg>\n ) as HTMLElement;\n};\n","import { Breakpoint } from '../components/core/types/globalTypes';\nimport { isNullOrUndefined } from './collection';\nimport config from './../styles/settings/configs/breakpoints-config.json';\n\n/**\n * Match media types\n */\nexport enum MediaTypes {\n minWidth = 'min-width',\n maxWidth = 'max-width',\n}\n\n/**\n * Returns the list all of breakpoint keys\n * @returns {Breakpoint[]} The list of breakpoints\n */\nexport const getBreakpoints = (): Breakpoint[] => Object.keys(config.breakpoints) as Breakpoint[];\n\n/**\n * Returns the breakpoint in pixels\n * @param {Breakpoint} breakpoint The breakpoint\n * @returns {number} The breakpoint value in pixels\n */\nexport const getBreakpointInPixels = (breakpoint: Breakpoint): number => parseInt(config.breakpoints[breakpoint], 10);\n\n/**\n * Returns the breakpoint key for given pixels\n * @param {number} pixels The pixels of the breakpoint\n * @returns {Breakpoint} The breakpoint key\n */\nexport const getBreakpointFromPixels = (pixels: number): Breakpoint =>\n Object.keys(config.breakpoints)[\n Object.values(config.breakpoints)\n .map((bp) => parseInt(bp, 10))\n .findIndex((bpPixels) => bpPixels === pixels)\n ] as Breakpoint;\n\nconst mediaQueryLists: MediaQueryList[] = [];\n\n/**\n * Adds matchMedia to window with the given properties.\n * @param {MediaTypes} mediaType The type of media\n * @param {Sizes} breakpoint The media size\n * @param {Function} listenerFunction Callback function for the listener\n */\nexport const addMatchMedia = (\n mediaType: MediaTypes,\n breakpoint: Breakpoint,\n listenerFunction: (this: MediaQueryList, ev: MediaQueryListEvent) => unknown\n): void => {\n const foundMatchMedia = mediaQueryLists.find((m) => m.media === `(${mediaType}: ${config.breakpoints[breakpoint]})`);\n if (!isNullOrUndefined(foundMatchMedia)) {\n foundMatchMedia.addEventListener('change', listenerFunction);\n } else {\n const newMatchMedia = window.matchMedia(`(${mediaType}: ${config.breakpoints[breakpoint]})`);\n mediaQueryLists.push(newMatchMedia);\n newMatchMedia.addEventListener('change', listenerFunction);\n }\n};\n\n/**\n * Removes matchMedia from window with the given properties.\n * @param {MediaTypes} mediaType The type of media\n * @param {Sizes} breakpoint The media size\n * @param {Function} listenerFunction Callback function to be removed from the listener\n */\nexport const removeMatchMedia = (\n mediaType: MediaTypes,\n breakpoint: Breakpoint,\n listenerFunction: (this: MediaQueryList, ev: MediaQueryListEvent) => unknown\n): void => {\n mediaQueryLists.find((m) => m.media === `(${mediaType}: ${config.breakpoints[breakpoint]})`)?.removeEventListener('change', listenerFunction);\n};\n\n/**\n * Matches the current window with the given media type and breakpoint\n * @param {MediaTypes} mediaType The media type\n * @param {Breakpoint} breakpoint The breakpoint\n * @returns {boolean} True if it matches, false otherwise\n */\nexport const mediaMatchingBreakpoint = (mediaType: MediaTypes, breakpoint: Breakpoint): boolean => {\n const foundMatchMedia = mediaQueryLists.find((m) => m.media === `(${mediaType}: ${config.breakpoints[breakpoint]})`);\n if (!isNullOrUndefined(foundMatchMedia)) {\n return foundMatchMedia.matches;\n }\n const newMatchMedia = window.matchMedia(`(${mediaType}: ${config.breakpoints[breakpoint]})`);\n mediaQueryLists.push(newMatchMedia);\n return newMatchMedia.matches;\n};\n","import { isNullOrUndefined } from './collection';\n\ninterface ResizeCallback {\n callback: () => void;\n duration: number;\n timeout?: NodeJS.Timeout;\n}\n\nconst defaultTimeout = 50;\n\nconst callbacks: ResizeCallback[] = [];\n\nwindow.onresize = () => {\n callbacks.map((cb: ResizeCallback) => {\n if (isNullOrUndefined(cb.timeout)) {\n cb.callback();\n cb.timeout = setTimeout(() => {\n cb.timeout = null;\n }, cb.duration);\n }\n });\n};\n\n/**\n * Subscribe to the resize listener\n * @param {function} callback The callback function to run on resize\n * @param {number} timeoutDuration The throttle timeout duration\n */\nexport const subscribeToWindowResize = (callback: () => void, timeoutDuration: number = defaultTimeout): void => {\n callbacks.push({ callback, duration: timeoutDuration });\n};\n\n/**\n * Unsubscribe to the resize listener\n * @param {function} callback The callback function to unsubscribe\n */\nexport const unSubscribeToWindowResize = (callback: () => void): void => {\n const index = callbacks.findIndex((cb: ResizeCallback) => cb.callback === callback);\n if (index >= 0) {\n if (!isNullOrUndefined(callbacks[index].timeout)) {\n clearTimeout(callbacks[index].timeout);\n }\n callbacks.splice(index, 1);\n }\n};\n","import { Directions } from '../components/core/types/globalTypes';\nimport { isNullOrUndefined } from './collection';\n\n/**\n * Goes through the provided list of elements recursively and returns the underlying content from slot elements\n * @param {HTMLElement[]} slotElements A list of elements to go through\n * @returns {HTMLElement[]} The underlying content\n */\nexport const getContentFromSlotElementsRecursively = (slotElements: HTMLElement[]): HTMLElement[] => {\n return slotElements.reduce((acc: HTMLElement[], currentValue) => {\n if (currentValue.tagName && currentValue.tagName.toLowerCase() === 'slot') {\n const tmpSlotElement = currentValue as HTMLSlotElement;\n return getContentFromSlotElementsRecursively(tmpSlotElement.assignedElements() as HTMLElement[]);\n }\n acc.push(currentValue);\n return acc;\n }, []);\n};\n\n/**\n * Going up the chain of elements, it will return true if the given element is a child of the root node and false if it sits under an other (slotted) element\n * @param {HTMLElement} componentEl The root element (parent)\n * @param {HTMLElement} element The element in question\n * @param {number} maxIterations Optional. Number of steps to find the parent. Default: 10\n * @returns {boolean} Whether or not the given element is a child of the root node\n */\nconst isElementChildOfComponent = (componentEl: HTMLElement, element: HTMLElement, maxIterations = 10): boolean => {\n {\n let tmpElement = element;\n for (let index = 0; index < maxIterations; index++) {\n if (tmpElement.parentElement === componentEl) {\n return true;\n }\n if (!tmpElement.parentElement || tmpElement.parentElement.getAttribute('slot')) {\n return false;\n }\n\n tmpElement = tmpElement.parentElement;\n }\n }\n};\n\n/**\n * Returns the content elements of the slots within a component\n * If browser doesn't support slots, it will return all the elements that are assigned to the space where the slot should be\n * @param {HTMLElement} element The parent element\n * @param {string} slotName Optional slot name for filtering results\n * @returns {Element[]} The content elements of the slots within a component\n */\nexport const getSlottedElements = (element: HTMLElement, slotName = ''): Element[] => {\n const selector = slotName ? `slot[name=${slotName}]` : 'slot';\n\n return getContentFromSlotElementsRecursively(\n Array.from(element.shadowRoot.querySelectorAll(selector))\n .map((slotElement: HTMLSlotElement) => slotElement.assignedNodes() as HTMLElement[])\n .flat()\n );\n};\n\n/**\n * Returns all the child elements within a slot property, regardless of them being in an actual slot or not\n * @param {HTMLElement} element The parent element\n * @param {string} slotName Optional slot name for filtering results\n * @returns {Element[]} The child elements within a slot\n */\nexport const getAllElementsWithSlotAttribute = (element: HTMLElement, slotName = ''): Element[] => {\n const selector = slotName ? `[slot=${slotName}]` : '[slot]';\n return Array.from(element.querySelectorAll(selector)).filter((el: HTMLElement) => isElementChildOfComponent(element, el));\n};\n\n/**\n * Going up the chain of elements, it returns the first element with the given attribute\n * @param {HTMLElement} el The src element\n * @param {string} attribute The attribute to look for\n * @param {string} attributeValue The attribute value to look for\n * @param {number} maxIterations Max iterations. Default 10\n * @returns {HTMLElement} The first element with the given attribute\n */\nexport const getFirstParentWithAttribute = (el: HTMLElement, attribute: string, attributeValue: string, maxIterations = 10): HTMLElement => {\n if (el.getAttribute(attribute) === attributeValue) {\n return el;\n }\n let currentEl = el;\n let currentIteration = 0;\n while (currentEl && currentEl.parentElement && currentIteration <= maxIterations) {\n const parentAttr = currentEl.parentElement.getAttribute(attribute);\n if (parentAttr && parentAttr.toString().toLowerCase() === attributeValue.toString().toLowerCase()) {\n return currentEl.parentElement;\n }\n currentEl = currentEl.parentElement;\n currentIteration++;\n }\n return null;\n};\n\n/**\n * Starting from the given element, goes upwards in the dom accounting for slots and shadowRoot, it will return if the given element sits under an other element\n * @param {Element} el1 The descendant element\n * @param {Element} el2 The parent element\n * @param {number} maxIterations max iterations. Default = 20\n * @returns {boolean} True if element one is a descendant (in the DOM) of element two\n */\nexport const getIsElementDescendantOfElement = (el1: Element, el2: Element, maxIterations = 20): boolean => {\n const getParentInDom = (el: Element): Element => {\n // if it's under a slot, go to the slot\n if (el.assignedSlot) {\n return el.assignedSlot;\n // if not under slot get the normal parent\n } else if (el.parentElement) {\n return el.parentElement;\n // if there is no parent try and find the shadowroot host that contains the element\n } else if (el.getRootNode()) {\n const rootNode = el.getRootNode() as ShadowRoot;\n return rootNode.host;\n }\n };\n\n let currentIteration = 0;\n let currentParent: Element = getParentInDom(el1);\n\n while (currentParent && currentIteration <= maxIterations) {\n if (currentParent === el2) {\n return true;\n }\n currentParent = getParentInDom(currentParent);\n currentIteration++;\n }\n return false;\n};\n\n/**\n * Given an element, calculate whether it should render in RTL mode\n * @param {Element} elem The element in question\n * @returns {boolean} Whether the element should render in RTL mode\n */\nexport const getIsElementRTL = (elem: Element): boolean => {\n return (\n elem.getAttribute('dir') === Directions.RTL ||\n (document.documentElement.getAttribute('dir') === Directions.RTL && elem.getAttribute('dir') !== Directions.LTR)\n );\n};\n\n/**\n * Sets a MutationObserver to detect dir change on the HTML element\n * @param {Function} onDirMutationCallback Callback to be executed when dir changes\n * @returns {MutationObserver} The mutation observer obj\n */\nexport const getHtmlDirObserver = (onDirMutationCallback: (htmlDirMutation?: MutationRecord) => void): MutationObserver => {\n const config = { attributes: true, childList: false, subtree: false };\n const obs = new MutationObserver((mutationList) => {\n const htmlDirMutation = mutationList.find((ml) => ml.target.nodeName.toLowerCase() === 'html' && ml.attributeName === 'dir');\n if (!isNullOrUndefined(htmlDirMutation)) {\n onDirMutationCallback(htmlDirMutation);\n }\n });\n obs.observe(document.documentElement, config);\n return obs;\n};\n","import { isNullOrUndefined, isNullOrUndefinedOrEmpty } from 'utils/collection';\n\n/**\n * An interface for an icon object\n */\nexport interface IconObject {\n active: string;\n inactive: string;\n}\n\n/**\n * An interface for an svg icon object\n */\nexport interface SvgIconObject {\n active: SVGIconData;\n inactive: SVGIconData;\n}\n\n/**\n * An interface for an SVG image\n */\nexport interface SVGIconData {\n /* the path data for the SVG image */\n data: string;\n\n /* the height of the image */\n height: number;\n\n /* the width of the image */\n width: number;\n}\n\n/**\n * Describes an icon type.\n * @docs\n * @global\n */\nexport type Icon = IconObject | string;\n\n/**\n * Describes an icon type.\n * @docs\n * @global\n */\nexport type SVGIcon = SvgIconObject | SVGIconData;\n\n/**\n * Given an icon object or string (src), this function will return the full object that describes an icon type.\n * That way we can \"combine\" the two possible inputs (string or obj) and work with objects as a result.\n * @param {Icon} src The icon type\n * @returns {IconObject} The icon object\n */\nexport const getIconObject = (src: Icon): IconObject => {\n if (!isIcon(src)) {\n return undefined;\n }\n if (typeof src === 'string') {\n return {\n active: src,\n inactive: src,\n };\n }\n\n return src;\n};\n\n/**\n * Given a single svg icon object or an active-inactive combination, this function will return a full combination.\n * @param {SVGIcon} src The icon type\n * @returns {SvgIconObject} The icon object\n */\nexport const getSVGIconObject = (src: SVGIcon): SvgIconObject => {\n if (!isSVGIcon(src)) {\n return undefined;\n }\n if (!isNullOrUndefined((src as SVGIconData)?.data)) {\n return {\n active: src as SVGIconData,\n inactive: src as SVGIconData,\n };\n }\n return src as SvgIconObject;\n};\n\n/**\n * Determines if value is of type Icon (Type Guard)\n * @param {Icon | SVGIcon} toBeDetermined The value to check\n * @returns {boolean} True if value is of type \"Icon\". False otherwise\n */\nexport const isIcon = (toBeDetermined: Icon | SVGIcon): toBeDetermined is Icon => {\n if (\n !isNullOrUndefinedOrEmpty(toBeDetermined as string) ||\n (!isNullOrUndefinedOrEmpty((toBeDetermined as IconObject)?.active) && !isNullOrUndefinedOrEmpty((toBeDetermined as IconObject)?.inactive))\n ) {\n return true;\n }\n return false;\n};\n\n/**\n * Determines if value is of type SVGIcon (Type Guard)\n * @param {Icon | SVGIcon} toBeDetermined The value to check\n * @returns {boolean} True if value is of type \"SVGIcon\". False otherwise\n */\nexport const isSVGIcon = (toBeDetermined: Icon | SVGIcon): toBeDetermined is SVGIcon => {\n if (\n !isNullOrUndefinedOrEmpty((toBeDetermined as SVGIconData)?.data) ||\n (!isNullOrUndefinedOrEmpty((toBeDetermined as SvgIconObject)?.active?.data) &&\n !isNullOrUndefinedOrEmpty((toBeDetermined as SvgIconObject)?.inactive?.data))\n ) {\n return true;\n }\n return false;\n};\n","import { getIsElementDescendantOfElement } from './DOMHelper';\nimport { isNullOrUndefined } from './collection';\n\n/**\n * @returns {string} The selector to be used to find all focusables\n */\nexport const getFocusableSelector = (): string => {\n return 'ads-search:not([data-disabled]), ads-button:not([data-disabled]), ads-cta-button:not([data-disabled]), ads-dropdown:not([data-disabled]), ads-vertical-tabs:not([data-disabled]), [href],button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n};\n\n/**\n * Returns all the focusable elements under the given container\n * @param {Element | ShadowRoot} container The container element\n * @returns {Element[]} Focusable elements\n */\nexport const getFocusableElements = (container: Element | ShadowRoot): Element[] => {\n // get all tabbable elements in the container\n return Array.from(container.querySelectorAll(getFocusableSelector()));\n};\n\n/**\n * Returns the first focusable element in the container element\n * @param {Element | ShadowRoot} container The container element\n * @returns {Element} First focusable element\n */\nexport const getFirstFocusableElement = (container: Element | ShadowRoot): Element => {\n const focusable = getFocusableElements(container);\n return focusable.length > 0 ? focusable[0] : null;\n};\n\n/**\n * Returns the last focusable element in the container element\n * @param {Element | ShadowRoot} container The container element\n * @returns {Element} Last focusable element\n */\nexport const getLastFocusableElement = (container: Element | ShadowRoot): Element => {\n const focusable = getFocusableElements(container);\n return focusable.length > 0 ? focusable[focusable.length - 1] : null;\n};\n\n/**\n * Sets focus to the first focusable element in a shadowroot\n * @param {ShadowRoot} shadowRoot Shadowroot\n */\nconst focusElementInShadowRoot = (shadowRoot: ShadowRoot): void => {\n const firstFocusableInShadowRoot = getFirstFocusableElement(shadowRoot) as HTMLElement;\n !isNullOrUndefined(firstFocusableInShadowRoot) ? firstFocusableInShadowRoot.focus() : null;\n};\n\n/**\n * Sets focus on the given element. If the element has a shadowroot it will set focus to the first focusable element in the shadowroot\n * @param {HTMLElement} element Element\n */\nconst focusElement = (element: HTMLElement): void => {\n if (!isNullOrUndefined(element.shadowRoot)) {\n focusElementInShadowRoot(element.shadowRoot);\n } else {\n element.focus();\n }\n};\n\n/**\n * Observer that observes the given element and fires a callback when it becoes visible\n * If IntersectionObserver is not supported by the browser it will use a timeout\n * @param {Element} element to observe\n * @param {Function} onIntersectionCallback Callback when element becomes visible\n */\nexport const observeContainer = (element: Element, onIntersectionCallback: (observedElement: Element) => void): void => {\n if ('IntersectionObserver' in window) {\n const intersectionObserver = new IntersectionObserver((entries) => {\n entries.map((entry) => {\n if (entry.isIntersecting) {\n onIntersectionCallback(entry.target);\n intersectionObserver.unobserve(element);\n }\n });\n });\n intersectionObserver.observe(element);\n } else {\n setTimeout(() => {\n onIntersectionCallback(element);\n }, 50);\n }\n};\n\n/**\n * Given a container element, it will set focus on the first tabbable element and fire callback when tabbing out of the container. Respects shift+tab\n * @param {Element} containerElement The container element for focus\n * @param {Function} onFocusOutCallback Callback when \"focusout\" triggers when leaving the container\n * @param {boolean} startFromEnd Optional: Passing true will focus the last element\n */\nconst focusArea = (containerElement: Element, onFocusOutCallback?: (event: FocusEvent) => void, startFromEnd = false): void => {\n // get all tabbable elements in the container\n const focusable = getFocusableElements(containerElement) as HTMLElement[];\n\n // add the container to the array if it has tabIndex\n if (parseInt(containerElement.getAttribute('tabIndex'), 10) >= 0) {\n focusable.unshift(containerElement as HTMLElement);\n }\n // get last tabbable element in container\n const lastFocusable = focusable[focusable.length - 1];\n // get first tabbable element in container\n const firstFocusable = focusable[0];\n\n if (focusable.length > 0) {\n if (startFromEnd) {\n focusElement(lastFocusable);\n } else {\n focusElement(firstFocusable);\n }\n\n // we need a function reference to be used for the even listener so we can remove it when it's over.\n const onEdgeElementBlur = (evt: FocusEvent): void => {\n const nextElement = evt.relatedTarget as Element;\n //check if the next element is within the container still\n if (isNullOrUndefined(nextElement) || getIsElementDescendantOfElement(nextElement, containerElement)) {\n return;\n }\n lastFocusable.removeEventListener('blur', onEdgeElementBlur);\n firstFocusable.removeEventListener('blur', onEdgeElementBlur);\n if (!isNullOrUndefined(onFocusOutCallback)) {\n onFocusOutCallback(evt);\n }\n };\n\n lastFocusable.addEventListener('blur', onEdgeElementBlur);\n firstFocusable.addEventListener('blur', onEdgeElementBlur);\n }\n};\n\n/**\n * Sets focus on the first tabbable element in a container when it becomes visible. Executes the callback function when the user is tabbing out of the container. Respects shift+tab\n * @param {Element} areaContainer Container to focus on\n * @param {Function} onFocusOutCallback Fires when \"focusout\" triggers on the last tabbable element\n * @param {boolean} startFromEnd Optional: Passing true will focus the last element\n */\nexport const setFocusOnArea = (areaContainer: Element, onFocusOutCallback?: (event: FocusEvent) => void, startFromEnd = false): void => {\n observeContainer(areaContainer, (observedElement: Element) => {\n focusArea(observedElement, onFocusOutCallback, startFromEnd);\n });\n};\n","import { isNullOrUndefined } from './collection';\n\n/**\n * Given a \"click\" event, it will return true if the event is coming from a keyboard interaction, false otherwise\n * @param {Event} evt The event\n * @returns {boolean} True if keyboard, false if mouse\n */\nexport const isKeyboardClickEvent = (evt: Event): boolean =>\n evt instanceof KeyboardEvent ||\n (evt instanceof MouseEvent &&\n (evt.detail === 0 || isNullOrUndefined(evt.detail)) &&\n (evt.clientX === 0 || isNullOrUndefined(evt.clientX)) &&\n (evt.clientY === 0 || isNullOrUndefined(evt.clientY)));\n"],"sourceRoot":""}