{"version":3,"names":["ScrollSpy","this","collapseTriggerWidth","listElementId","guid","isDesignMode","collapseHTML","disableCollapse","h","class","type","ref","el","menuElement","menuTitle","id","navItems","map","item","index","arr","href","onClick","evt","handleLinkClick","title","length","afterMenuElement","name","handleResize","collapseable","window","innerWidth","handleScroll","event","preventDefault","url","URL","target","targetId","hash","slice","setTimeout","document","getElementById","scrollIntoView","behavior","block","inline","innerHTML","getSafeTitle","text","toLowerCase","replace","filterAnchorItems","anchor","closest","setupWithHeadings","headings","scrollElement","querySelectorAll","Array","from","filter","reduce","carry","heading","innerTextArray","innerText","split","getAttribute","setAttribute","style","scrollMarginTop","dataset","spyTitle","tagName","join","setupWithClasses","anchors","componentDidLoad","useHeadings","menuTitleSlotElement","trim","menuTitleSlotElementClone","cloneNode","haveSlotTitle","componentDidRender","jQuery","scrollspy","offset","render","Host","flex","heroElement","horizontal","container","listElement"],"sources":["./src/components/scroll-spy/scroll-spy.tsx"],"sourcesContent":["import { Component, Host, h, Prop, State, Element, Listen } from '@stencil/core'; \r\nimport { guid } from '../../utils/utils';\r\n \r\ndeclare global {\r\n\tinterface Window { \r\n\t\tisDesignMode: boolean;\r\n\t\tisAdminLoggedIn: boolean; \r\n\t}\r\n}\r\n\r\n/**\r\n * @devnote this component relies on Bootstrap JS and jQuery\r\n * to update nav-link states on scroll and to handle\r\n * mobile collapse functionality\r\n */\r\ndeclare var jQuery;\r\n\r\n@Component({\r\n\ttag: 'bs-scroll-spy',\r\n\tshadow: false,\r\n})\r\nexport class ScrollSpy {\r\n\t@Prop() useHeadings: boolean = true;\r\n\r\n\t@Prop() horizontal: boolean = false;\r\n\r\n\t@Prop() menuTitle: string;\r\n\r\n\t@Prop() disableCollapse: boolean = false;\r\n\r\n\t@State() haveSlotTitle: boolean = false;\r\n\r\n\t@State() navItems: { title: string; href: string }[] = [];\r\n\r\n\t@State() collapseable = false;\r\n\r\n\t@State() collapsed = true;\r\n\r\n\t@Element() el: HTMLElement;\r\n\r\n\t@Listen('resize', { target: 'window', passive: true, capture: true })\r\n\thandleResize() {\r\n\t\tlet collapseable = window.innerWidth < this.collapseTriggerWidth;\r\n\t\tif (this.collapseable !== collapseable) {\r\n\t\t\tthis.collapseable = collapseable;\r\n\t\t}\r\n\t}\r\n\t@Listen('scroll', { target: 'window', passive: true, capture: true })\r\n\thandleScroll() {\r\n\t\t//if (!window.isDesignMode) {\r\n\t\t//\tlet rectList = this.listElement.getBoundingClientRect();\r\n\t\t//\tlet rectAfter = this.afterMenuElement.getBoundingClientRect();\r\n\t\t//\tthis.afterMenuElement.style.top = rectList.bottom + \"px\";\r\n\t\t//\tif (rectAfter.top < rectList.bottom\t-5 ) {\r\n\t\t//\t\tthis.afterMenuElement.style.opacity = \"0\";\r\n\t\t//\t} else {\r\n\t\t//\t\tthis.afterMenuElement.style.opacity = \"1\";\r\n\t\t//\t}\r\n\t\t//}\r\n }\r\n\r\n\tcollapseTriggerWidth = 992;\r\n\r\n\tlistElementId: string = 'scroll-spy-nav-' + guid();\r\n\r\n\tlistElement: HTMLElement;\r\n\r\n\tscrollElement: HTMLElement;\r\n\r\n\tmenuTitleSlotElement: HTMLElement;\r\n\r\n\tafterMenuElement: HTMLElement;\r\n\r\n\tmenuElement: HTMLElement;\r\n\r\n\theroElement: HTMLElement;\r\n\r\n\tisDesignMode: boolean = false;\r\n\r\n\thandleLinkClick(event: Event) {\r\n\t\tevent.preventDefault();\r\n\r\n\t\tconst url = new URL((event.target as HTMLAnchorElement).href);\r\n\t\tlet targetId = url.hash.slice(1);\r\n\t\tsetTimeout(() => {\r\n\t\t\tdocument.getElementById(targetId).scrollIntoView({ behavior: 'smooth',block: 'start', inline: 'nearest' });\r\n\t\t\tthis.menuElement.innerHTML = document.getElementById(targetId).innerHTML;\r\n\t\t}, 250);\r\n\t\t\r\n\t}\r\n\r\n\tgetSafeTitle(text: string) {\r\n\t\treturn text\r\n\t\t\t.toLowerCase()\r\n\t\t\t.replace(/\\s/g, '-')\r\n\t\t\t.replace(/[+()!?,.\"'%&:;]/g, '');\r\n\t}\r\n\r\n\tfilterAnchorItems(anchor: HTMLElement): boolean {\r\n\t\tif (anchor.closest('[data-spy-ignore]') || anchor.closest('.spy-ignore')) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n\r\n\tsetupWithHeadings() {\r\n\t\tconst headings = this.scrollElement.querySelectorAll('h1,h2');\r\n\t\tconst navItems = Array.from(headings)\r\n\t\t\t.filter(this.filterAnchorItems)\r\n\t\t\t.reduce((carry, heading: HTMLElement) => {\r\n\t\t\t\tlet innerTextArray = heading.innerText.split(' ');\r\n\t\t\t\tif (null == heading.getAttribute('id')) {\r\n\t\t\t\t\theading.setAttribute('id', this.getSafeTitle(heading.innerText));\r\n\t\t\t\t\t// @ts-ignore\r\n\t\t\t\t\theading.style.scrollMarginTop = this.collapseable ? '120px' : '70px';\r\n\t\t\t\t}\r\n\t\t\t\treturn [\r\n\t\t\t\t\t...carry,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\ttitle:\r\n\t\t\t\t\t\t\theading.dataset.spyTitle ||\r\n\t\t\t\t\t\t\t(heading.tagName.toLowerCase() == 'h1'\r\n\t\t\t\t\t\t\t\t? 'Overview'\r\n\t\t\t\t\t\t\t\t: innerTextArray.length > 10 ? innerTextArray.slice(0, 10).join(' ') + '...' : heading.innerText),\r\n\t\t\t\t\t\thref: `#${heading.getAttribute('id')}`,\r\n\t\t\t\t\t},\r\n\t\t\t\t];\r\n\t\t\t}, []);\r\n\t\tthis.navItems = [...navItems];\r\n\t}\r\n\r\n\tsetupWithClasses() {\r\n\t\tconst anchors = this.scrollElement.querySelectorAll('.scroll-spy-anchor');\r\n\t\tconst navItems = Array.from(anchors)\r\n\t\t\t.filter(this.filterAnchorItems)\r\n\t\t\t.reduce((carry, anchor: HTMLElement) => {\r\n\t\t\t\tif (null == anchor.getAttribute('id')) {\r\n\t\t\t\t\tanchor.setAttribute('id', this.getSafeTitle(anchor.dataset.spyTitle));\r\n\t\t\t\t}\r\n\t\t\t\treturn [\r\n\t\t\t\t\t...carry,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\ttitle: anchor.dataset.spyTitle || anchor.innerText,\r\n\t\t\t\t\t\thref: `#${anchor.getAttribute('id')}`,\r\n\t\t\t\t\t},\r\n\t\t\t\t];\r\n\t\t\t}, []);\r\n\t\tthis.navItems = [...navItems];\r\n\t}\r\n\r\n\r\n\tmenuTitleSlotElementClone: HTMLElement;\r\n\tcomponentDidLoad() {\r\n\t\tthis.useHeadings ? this.setupWithHeadings() : this.setupWithClasses();\r\n\t\tthis.handleResize();\r\n\t\t\r\n\t\tthis.handleScroll();\r\n\r\n\t\tif (this.menuTitleSlotElement.innerText.trim()) {\r\n\t\t\tthis.menuTitleSlotElementClone = (this.menuTitleSlotElement.cloneNode(true) as HTMLElement);\r\n\t\t\tthis.menuTitle = this.menuTitleSlotElementClone.innerText;\r\n\t\t\tthis.haveSlotTitle = true;\r\n\t\t}\r\n\r\n\t\t\r\n\r\n\t\tif (window.isDesignMode) {\r\n\t\t\t// don't leave menu-after\r\n\t\t\tthis.isDesignMode = true;\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\tcomponentDidRender() {\r\n\t\tsetTimeout(() => {\r\n\t\t\tjQuery('body').scrollspy({ target: `#${this.listElementId}`, offset: 250 });\r\n\t\t});\r\n\t}\r\n\r\n\tcollapseHTML = () => \r\n\t\t!this.disableCollapse && (\r\n\t\t\t