{"version":3,"file":"OnComponents.mjs","sources":["../../Scripts/intersectionObserver.ts","../../Scripts/utilities.ts","../../Scripts/topScrolledElement.ts","../../Scripts/index.ts"],"sourcesContent":["import IDisposable from \"./IDisposable\";\n\n/**\n * Adds and creates intersection observers\n * @param {HTMLElement} element The element to observe. Must be a descendent of `root`.\n * @param {HTMLElement | null} root The root element to be intersected with. If not set, the `body` element will be the root.\n * @param {string} handle Handle for the containing element owned by Blazor\n * @param {string} callbackMethodName The function name called back to Blazor when an intersection happens\n * @param {object} dotNet Dotnet handle */\nconst createIntersectionObserver = (element: HTMLElement, root: HTMLElement | null, handle: string, callbackMethodName: string, dotNet: any): IDisposable => {\n const intersectionObserver = new IntersectionObserver(\n (result) => {\n dotNet.invokeMethodAsync(callbackMethodName, handle, result);\n }, {root: root ?? document.body});\n intersectionObserver.observe(element);\n return {\n dispose: () => {\n intersectionObserver.disconnect();\n }\n }\n};\n\nexport default createIntersectionObserver;\n","import IDisposable from \"./IDisposable\";\n\n/**\n * Scrolls the root element to the target element.\n * @param {HTMLElement} root Root element\n * @param {string | HTMLElement} elementOrId\n */\nconst scrollTo = (root: HTMLElement, elementOrId: string | HTMLElement) => {\n const el = typeof elementOrId === \"string\" ? document.getElementById(elementOrId) : elementOrId;\n if (!!el) {\n root.scrollTo({top: el.offsetTop, behavior: \"smooth\"});\n }\n}\n\ntype AnchorBlock = \"top\" | \"bottom\" | \"center\";\ntype AnchorInline = \"left\" | \"right\" | \"center\";\nconst inlineOpposite = (inline: AnchorInline) => inline === \"left\" ? \"right\" : inline === \"right\" ? \"left\" : inline;\nconst blockOpposite = (block: AnchorBlock) => block === \"top\" ? \"bottom\" : block === \"bottom\" ? \"top\" : block;\n\ntype Anchor = `${AnchorBlock}-${AnchorInline}`;\ntype AnchorTuple = [AnchorBlock, AnchorInline];\ntype Relative = {\n el: HTMLElement,\n elementAnchor: Anchor,\n anchor: Anchor\n constrainInView: boolean\n};\ntype Position = {\n x: number,\n y: number,\n anchor: Anchor,\n constrainInView: boolean\n};\n\nconst blockToOffset: Record < AnchorBlock, number > = {\n top: 1,\n center: 0,\n bottom: -1,\n}\n\nconst inlineToOffset: Record < AnchorInline, number > = {\n left: 1,\n center: 0,\n right: -1,\n}\n\nconst getPosition = (rect: DOMRect, elementRect: DOMRect, [selfBlock, selfInline]: AnchorTuple, [elementBlock, elementInline]: AnchorTuple): DOMRect => {\n const {\n width: currentWidth,\n height: currentHeight\n } = rect;\n const {\n x,\n y,\n width: elementWidth,\n height: elementHeight\n } = elementRect;\n return new DOMRect(\n x + currentWidth * (inlineToOffset[selfInline] - 1.0) / 2.0 + elementWidth * (1.0 - inlineToOffset[elementInline]) / 2.0,\n y + currentHeight * (blockToOffset[selfBlock] - 1.0) / 2.0 + elementHeight * (1.0 - blockToOffset[elementBlock]) / 2.0,\n currentWidth,\n currentHeight\n )\n}\n\n\nconst constrainInView = (rect: DOMRect, elementRect: DOMRect, [selfBlock, selfInline]: AnchorTuple, [elementBlock, elementInline]: AnchorTuple) => {\n const screenWidth = window.innerWidth, screenHeight = window.innerHeight;\n let position = DOMRect.fromRect(rect);\n if(rect.width < screenWidth && (rect.left < 0 || rect.right >= screenWidth)) { \n position = getPosition(position, elementRect, [selfBlock, inlineOpposite(selfInline)], [elementBlock, inlineOpposite(elementInline)]); \n }\n if(rect.height < screenHeight && (rect.top < 0 || rect.bottom >= screenHeight)) { \n position = getPosition(position, elementRect, [blockOpposite(selfBlock), selfInline], [blockOpposite(elementBlock), elementInline]); \n }\n return position;\n} \n\nconst setPosition = (el: HTMLElement, position: Position | Relative) => {\n const anchor = position.anchor.split(\"-\") as AnchorTuple;\n const elementAnchor = (\"elementAnchor\" in position ? position.elementAnchor.split(\"-\") : [\"top\", \"left\"]) as AnchorTuple;\n const rect = el.getBoundingClientRect();\n const elementRect = \"el\" in position ? position.el.getBoundingClientRect() : new DOMRect(position.x, position.y, 0, 0);\n \n let calculatedPosition = getPosition(rect, elementRect, anchor, elementAnchor);\n if(position.constrainInView) {\n calculatedPosition = constrainInView(calculatedPosition, elementRect, anchor, elementAnchor);\n }\n \n Object.assign(el.style, {\n left: `${calculatedPosition.x}px`,\n top: `${calculatedPosition.y}px`\n });\n}\n\nconst addEventOutsideListener = (el: HTMLElement | Array, handle: string, callbackMethodName: string, eventName: string, dotNet: any): IDisposable => {\n const eventListener = (event: Event) => {\n const elements = Array.isArray(el) ? el : [el];\n if(elements.find(el => el.contains(event.target as Node))) return;\n dotNet.invokeMethodAsync(callbackMethodName, handle);\n }\n document.addEventListener(eventName, eventListener, true);\n return {\n dispose(): void {\n document.removeEventListener(eventName, eventListener);\n }\n }\n}\n\nexport {\n scrollTo,\n setPosition,\n addEventOutsideListener,\n}","import IDisposable from \"./IDisposable\";\n\n/**\n * Adds a listener for detecting when an element is in view within the root. The targeted element must have the\n * data-attribute ´data-scrollTarget´ set to some string identifier. Further, `data-hasScrollTarget` is set if the\n * element currently is active in view.\n * @param {string} handle Handle for the containing element owned by Blazor\n * @param {HTMLElement} root Container element\n * @param {string} callbackMethodName The function name called back to Blazor when scroll target changes\n * @param {object} dotNet Dotnet handle\n * @returns {(function(): void)|*}\n */\nconst addCurrentTopScrolledElementListener = (handle: string, root: HTMLElement, callbackMethodName: string, dotNet: any): IDisposable => {\n\n const callback = (id: string) => {\n dotNet.invokeMethodAsync(callbackMethodName, handle, id);\n }\n\n /* todo: make this an option and implement relative offset as well. */\n const offsetHeight = 10;\n\n const selectItem = (element: HTMLElement, target: HTMLElement) => (element.offsetTop + offsetHeight) >= target.scrollTop && (element.offsetTop + offsetHeight < target.scrollTop + target.clientHeight);\n\n const current = Array.from(root.children).find((element) => (element.getAttribute(\"data-scrollTarget\") && selectItem(element as HTMLElement, root)));\n if (current) {\n current.setAttribute(\"data-hasScrollTarget\", \"true\");\n callback(current.getAttribute(\"data-scrollTarget\")!);\n }\n\n const isHTMLElement = (eventTarget: EventTarget): eventTarget is HTMLElement => \"children\" in eventTarget && typeof eventTarget.children === \"object\";\n\n const eventListener: EventListener = (event) => {\n const eventTarget = event.target;\n if(!eventTarget || !isHTMLElement(eventTarget)) return;\n const children = Array.from(eventTarget.querySelectorAll(\"[data-scrollTarget]\"));\n const current = children.find(s => s.getAttribute(\"data-hasScrollTarget\"));\n const next = children\n .find((element) => selectItem(element as HTMLElement, eventTarget));\n if (current !== next) {\n current?.removeAttribute(\"data-hasScrollTarget\");\n next?.setAttribute(\"data-hasScrollTarget\", \"true\");\n const nextId = next?.getAttribute(\"data-scrollTarget\");\n if (nextId) {\n callback(nextId);\n }\n }\n };\n\n root.addEventListener(\"scroll\", eventListener);\n \n return {\n dispose: () => {\n root.removeEventListener(\"scroll\", eventListener);\n }\n }\n\n}\n\nexport default addCurrentTopScrolledElementListener;","import intersectionObserver from \"./intersectionObserver\";\nimport * as utilities from \"./utilities\";\nimport topScrolledElement from \"./topScrolledElement\";\n\nconst OnComponents = {\n intersectionObserver,\n utilities,\n topScrolledElement\n};\n\n(window as any).OnComponents = OnComponents;\n\n"],"names":["createIntersectionObserver","element","root","handle","callbackMethodName","dotNet","intersectionObserver","result","scrollTo","elementOrId","el","inlineOpposite","inline","blockOpposite","block","blockToOffset","inlineToOffset","getPosition","rect","elementRect","selfBlock","selfInline","elementBlock","elementInline","currentWidth","currentHeight","x","y","elementWidth","elementHeight","constrainInView","screenWidth","screenHeight","position","setPosition","anchor","elementAnchor","calculatedPosition","addEventOutsideListener","eventName","eventListener","event","addCurrentTopScrolledElementListener","callback","id","selectItem","target","current","isHTMLElement","eventTarget","children","s","next","nextId","OnComponents","utilities","topScrolledElement"],"mappings":"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"}