/*!
 * Custom elements for Nanopore-Digital Web applications
 */
'use strict';

var index = require('./index-DGttnXif.js');
var renderer = require('./renderer-jVpDRMfV.js');
var dom = require('./dom-Dxk5vXYq.js');
var throttle = require('./throttle-CrRDOkln.js');
var scroll = require('./scroll-C6pO9RvO.js');

const maskedOverflowCss = ":host,*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}@media (prefers-reduced-motion: reduce){:host,*,*::before,*::after{animation-duration:0.01ms !important;animation-iteration-count:1 !important;transition-duration:0.01ms !important;scroll-behavior:auto !important}}:host,*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}@media (prefers-reduced-motion: reduce){:host,*,*::before,*::after{animation-duration:0.01ms !important;animation-iteration-count:1 !important;transition-duration:0.01ms !important;scroll-behavior:auto !important}}:host{--indicator-transition:var(--nano-transition-fast);--indicator-color:var(--nano-color-primary-1000);--indicator-size:3px;--indicator-track-color:var(--nano-color-neutral-300);--indicator-track-size:var(--indicator-size);--scroll-btn-color:var(--nano-color-primary-1200);--scroll-btn-size:1rem;--fade-size:100px;position:relative;z-index:var(--nano-z-index-raised)}:host([orientation=horizontal]){display:block}:host([orientation=vertical]){display:flex}.onav--no-transitions *{transition-duration:0s !important}.onav__nav:has(.onav__scroller:focus-visible){outline:var(--nano-focus-ring);outline-offset:var(--nano-focus-ring-offset)}.onav__scroller{scrollbar-width:thin;overflow:auto;display:flex;transition:var(--nano-transition-fast) ease}.onav__scroller:focus{outline:none}.onnav--hide-scrollbars .onav__scroller{scrollbar-width:none;-ms-overflow-style:none}.onnav--hide-scrollbars .onav__scroller::-webkit-scrollbar{inline-size:0;block-size:0}.onav__items{flex:1 1 auto;position:relative;inline-size:auto;flex-wrap:nowrap;display:flex}.onnav--has-indicator .onav__items::before{content:\"\";background:var(--indicator-track-color);display:block;position:absolute;z-index:1}.onav__active-indicator{position:absolute;z-index:10;transition:var(--indicator-transition) transform ease, var(--indicator-transition) width ease, var(--indicator-transition) height ease}.nano-icon-button.onav__scroll-button{display:flex;align-items:center;justify-content:center;position:absolute;border:unset;z-index:2;transition:var(--nano-transition-fast) ease opacity;opacity:0;color:var(--scroll-btn-color);font-size:var(--scroll-btn-size);pointer-events:none}.nano-icon-button.onav__scroll-button.is-shown{opacity:1;pointer-events:all}.onav--horizontal.onav--has-scroll-controls .onav__scroller{-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-image:linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) calc(var(--fade-size) * 0.2), rgb(0, 0, 0) var(--fade-size), rgb(0, 0, 0) calc(100% - var(--fade-size)), rgba(0, 0, 0, 0) calc(100% - var(--fade-size) * 0.2), rgba(0, 0, 0, 0) 100%);mask-image:linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) calc(var(--fade-size) * 0.2), rgb(0, 0, 0) var(--fade-size), rgb(0, 0, 0) calc(100% - var(--fade-size)), rgba(0, 0, 0, 0) calc(100% - var(--fade-size) * 0.2), rgba(0, 0, 0, 0) 100%)}.onav--horizontal.onav--has-scroll-controls-start .onav__scroller{-webkit-mask-position:0 0;mask-position:0 0;-webkit-mask-size:calc(100% + var(--fade-size) * 2);mask-size:calc(100% + var(--fade-size) * 2)}.onav--horizontal.onav--has-scroll-controls-end .onav__scroller{-webkit-mask-position:calc(var(--fade-size) * -2) 0;mask-position:calc(var(--fade-size) * -2) 0;-webkit-mask-size:calc(100% + var(--fade-size) * 2);mask-size:calc(100% + var(--fade-size) * 2)}.onav--horizontal.onav--has-scroll-controls-start.onav--has-scroll-controls-end .onav__scroller{-webkit-mask-position:0 0;mask-position:0 0;-webkit-mask-size:100%;mask-size:100%}.onav--horizontal .onav__items{flex-direction:row}.onav--horizontal .onav__items::before{inline-size:100%;block-size:var(--indicator-track-size);inset-block-end:0}.onav--horizontal .onav__active-indicator{inset-block-end:0;border-block-end:solid var(--indicator-size) var(--indicator-color)}.onav--horizontal .onav__scroll-button{inset-block:0}.onav--horizontal .onav__scroll-button--start{inset-inline-start:0}.onav--horizontal .onav__scroll-button--end{inset-inline-end:0}.onav--vertical{--fade-size:70px;inline-size:100%;display:flex}.onav--vertical .onav__nav{max-block-size:100%;min-inline-size:100%;display:flex}.onav--vertical .onav__scroller{inline-size:100%;flex-direction:column}.onav--vertical.onav--has-scroll-controls .onav__scroller{-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-image:linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) calc(var(--fade-size) * 0.2), rgb(0, 0, 0) var(--fade-size), rgb(0, 0, 0) calc(100% - var(--fade-size)), rgba(0, 0, 0, 0) calc(100% - var(--fade-size) * 0.2), rgba(0, 0, 0, 0) 100%);mask-image:linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) calc(var(--fade-size) * 0.2), rgb(0, 0, 0) var(--fade-size), rgb(0, 0, 0) calc(100% - var(--fade-size)), rgba(0, 0, 0, 0) calc(100% - var(--fade-size) * 0.2), rgba(0, 0, 0, 0) 100%)}.onav--vertical.onav--has-scroll-controls-start .onav__scroller{-webkit-mask-position:0 0;mask-position:0 0;-webkit-mask-size:100% calc(100% + var(--fade-size) * 2);mask-size:100% calc(100% + var(--fade-size) * 2)}.onav--vertical.onav--has-scroll-controls-end .onav__scroller{-webkit-mask-position:0 calc(var(--fade-size) * -2);mask-position:0 calc(var(--fade-size) * -2);-webkit-mask-size:100% calc(100% + var(--fade-size) * 2);mask-size:100% calc(100% + var(--fade-size) * 2)}.onav--vertical.onav--has-scroll-controls-start.onav--has-scroll-controls-end .onav__scroller{-webkit-mask-position:0 0;mask-position:0 0;-webkit-mask-size:100% 100%;mask-size:100% 100%}.onav--vertical .onav__items{flex-direction:column;inline-size:fit-content}.onav--vertical .onav__items::before{block-size:100%;inline-size:var(--indicator-track-size);inset-inline-start:0}.onav--vertical .onav__active-indicator{inset-inline-start:0;border-inline-start:solid var(--indicator-size) var(--indicator-color)}.onav--vertical .onav__scroll-button{inset-inline:0}.onav--vertical .onav__scroll-button--start{inset-block-start:0}.onav--vertical .onav__scroll-button--end{inset-block-end:0}";

const MaskedOverflow = class {
    // public surface
    /** Used to appropriately label the scrolling element for screen-readers */
    label;
    /** Disables the scroll arrow buttons that appear when content overflows */
    scrollControls = true;
    /** The flex direction of the element */
    orientation = 'horizontal';
    /** Shows a track and a highlight line that automatically moves the currently active item. */
    showIndicator = false;
    /** Show or hide the browser's default scrollbars. Defaults to `true` on vertical orientation and `false` on `horizontal` orientation */
    hideScrollbars;
    watchHideScrollbars() {
        if (this.hideScrollbars === undefined || this.hideScrollbars === null) {
            this.hideScrollbars = this.orientation !== 'vertical';
        }
    }
    /**
     * A function called when an item becomes 'active' (via click or keyboard)
     * @param item - html element currently being assessed
     * @param _index - the index of the html element currently being assessed
     * @returns void */
    activeHandler = (item, _index) => item.classList.add('active');
    /**
     * A function called when an item becomes 'inactive'
     * (because another item was made active)
     * @param item - html element currently being assessed
     * @param _index - the index of the html element currently being assessed
     * @returns void */
    inactiveHandler = (item, _index) => item.classList.remove('active');
    /**
     * A function called to assess an initial, active item
     * @param item - html element currently being assessed
     * @param _index - the index of the html element currently being assessed
     * @returns void */
    isActiveHandler = (item, _index) => item.classList.contains('active');
    watchIsActiveHandler() {
        this.instantReCalc = true;
        this.activeItem = this.allActiveItems.find((el, i) => this.isActiveHandler(el, i));
        setTimeout(() => (this.instantReCalc = false), 300);
    }
    /**
     * Sync up the view to the active item.
     * Use this when the active item changes outside of this component.
     */
    async syncActiveItem() {
        this.activeItem = this.allActiveItems.find((el, i) => this.isActiveHandler(el, i));
    }
    // private state
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.recalculatePositions = throttle.debounce(this.recalculatePositions.bind(this), 80);
    }
    ro;
    nav;
    itemContainer;
    isRtl;
    endBtn;
    startBtn;
    activeIndicator;
    mutationObservers = new WeakMap();
    get scrollProp() {
        return this.orientation === 'horizontal' ? 'scrollWidth' : 'scrollHeight';
    }
    get clientDimensionProp() {
        return this.orientation === 'horizontal' ? 'clientWidth' : 'clientHeight';
    }
    get scrollOffset() {
        return this.orientation === 'horizontal' ? 'scrollLeft' : 'scrollTop';
    }
    get host() { return index.getElement(this); }
    instantReCalc = false;
    hasScrollControls = false;
    watchScrollControls() {
        if (this.hasScrollControls)
            this.handleScroll();
        else
            this.hideControlStart = this.hideControlEnd = true;
    }
    hideControlEnd = true;
    hideEndBtn() {
        if (!this.endBtn)
            return;
        this.activateBtn(this.endBtn, !this.hideControlEnd);
    }
    hideControlStart = true;
    hideStartBtn() {
        if (!this.startBtn)
            return;
        this.activateBtn(this.startBtn, !this.hideControlStart);
    }
    // private logic
    activateBtn(btn, activate = true) {
        if (!activate) {
            btn.tabIndex = -1;
            btn.disabled = true;
            btn.classList.remove('is-shown');
            return;
        }
        btn.removeAttribute('tabindex');
        btn.disabled = false;
        btn.classList.add('is-shown');
    }
    get allActiveItems() {
        return this.allItems.filter((el) => !el.disabled || el.classList.contains('disabled'));
    }
    get allItems() {
        return dom.getDirectChildren(this.host, '*', 'slot');
    }
    get activeItem() {
        return this._activeItem;
    }
    set activeItem(item) {
        if (!item ||
            item === this.activeItem ||
            item.disabled ||
            !this.allActiveItems.includes(item)) {
            return;
        }
        this._activeItem = item;
        this.allActiveItems.forEach((el, i) => {
            if (el === this._activeItem)
                this.activeHandler(el, i);
            else
                this.inactiveHandler(el, i);
        });
        this.recalculatePositions();
    }
    _activeItem;
    get navDim() {
        if (!this.nav)
            return 0;
        const computedStyle = getComputedStyle(this.nav);
        let clientDim = this.nav[this.clientDimensionProp];
        if (this.orientation === 'horizontal') {
            return (clientDim -=
                parseFloat(computedStyle.paddingLeft) +
                    parseFloat(computedStyle.paddingRight));
        }
        else {
            return (clientDim -=
                parseFloat(computedStyle.paddingTop) +
                    parseFloat(computedStyle.paddingBottom));
        }
    }
    scrollToActiveItem() {
        if (!this.nav || !this.activeItem || !this.hasScrollControls)
            return;
        scroll.scrollIntoView(this.activeItem, this.nav, this.orientation, 'center');
    }
    syncActiveItemIndicator() {
        if (!this.activeItem || !this.showIndicator)
            return;
        const item = this.activeItem;
        const width = item.clientWidth || 0;
        const height = item.clientHeight + 2 || 0;
        const offset = dom.getOffset(item, this.itemContainer);
        if (!this.activeIndicator)
            return;
        const offsetTop = offset.top;
        const offsetLeft = offset.left;
        if (this.instantReCalc)
            this.activeIndicator.style.transition = 'none';
        switch (this.orientation) {
            case 'horizontal':
                this.activeIndicator.style.width = `${width}px`;
                this.activeIndicator.style.height = null;
                this.activeIndicator.style.transform = `translateX(${offsetLeft}px)`;
                break;
            case 'vertical':
                this.activeIndicator.style.width = null;
                this.activeIndicator.style.height = `${height}px`;
                this.activeIndicator.style.transform = `translateY(${offsetTop}px)`;
                break;
        }
        setTimeout(() => (this.activeIndicator.style.transition = null), 400);
    }
    updateScrollControls = () => {
        if (!this.nav)
            return;
        this.hasScrollControls =
            this.nav[this.scrollProp] > this.nav[this.clientDimensionProp] &&
                this.nav[this.scrollProp] >= this.itemContainer[this.clientDimensionProp];
        this.handleScroll();
    };
    handleScroll = () => {
        if (!this.hasScrollControls) {
            this.hideControlStart = this.hideControlEnd = true;
            return;
        }
        const finishEnd = this.isRtl
            ? this.nav[this.scrollOffset] === 0
            : Math.abs(this.nav[this.clientDimensionProp] -
                (this.nav[this.scrollProp] - this.nav[this.scrollOffset])) < 2;
        const finishStart = this.isRtl
            ? Math.abs(this.nav[this.scrollProp] +
                this.nav[this.scrollOffset] -
                this.nav[this.clientDimensionProp]) < 2
            : this.nav[this.scrollOffset] === 0;
        if (finishStart) {
            this.hideControlStart = true;
            this.hideControlEnd = false;
        }
        else if (finishEnd) {
            this.hideControlStart = false;
            this.hideControlEnd = true;
        }
        else {
            this.hideControlEnd = false;
            this.hideControlStart = false;
        }
    };
    handleBtnClick = (goEnd = false) => {
        const navDim = this.navDim;
        let scrollAmt;
        if (goEnd)
            scrollAmt = this.nav[this.scrollOffset] + navDim - 20;
        else
            scrollAmt = this.nav[this.scrollOffset] - navDim + 20;
        try {
            this.nav.scroll({
                left: this.orientation === 'horizontal' ? scrollAmt : 0,
                top: this.orientation === 'vertical' ? scrollAmt : 0,
                behavior: 'smooth',
            });
        }
        catch (_e) {
            this.nav[this.scrollOffset] = scrollAmt;
        }
    };
    slotChangeHandler = () => {
        if (this.allActiveItems.length < 2)
            return;
        const item = this.allActiveItems.find((el, i) => this.isActiveHandler(el, i));
        if (item)
            this.activeItem = item;
        this.recalculatePositions();
        if (!this.showIndicator)
            return;
        /** maintain a weakmap of mutation observers to maintain item / indicator position on all changes. */
        this.allActiveItems.forEach((item) => {
            if (this.mutationObservers.get(item))
                return;
            const mo = new MutationObserver(() => this.syncActiveItemIndicator());
            mo.observe(item, {
                characterData: true,
                childList: true,
                subtree: true,
            });
            this.mutationObservers.set(item, mo);
        });
    };
    handleClick = (event) => {
        if (this.allActiveItems.length < 2)
            return;
        const foundItem = event
            .composedPath()
            .find((e) => this.allActiveItems.includes(e));
        if (foundItem)
            this.activeItem = foundItem;
    };
    handleKeyDown = (event) => {
        // Activate a tab
        if (['Enter', ' '].includes(event.key)) {
            const foundItem = event
                .composedPath()
                .find((e) => this.allActiveItems.includes(e));
            if (foundItem)
                this.activeItem = foundItem;
        }
    };
    recalculatePositions = () => {
        this.updateScrollControls();
        this.syncActiveItemIndicator();
        this.scrollToActiveItem();
    };
    // lifecycle
    connectedCallback() {
        this.instantReCalc = true;
        this.isRtl =
            this.orientation === 'horizontal' && !!this.host.closest('[dir="rtl"]');
        if (window['MutationObserver'])
            this.slotChangeHandler();
        if (!window['ResizeObserver'])
            return;
        if (this.ro) {
            this.ro.disconnect();
            this.ro = undefined;
        }
        const ro = (this.ro = new ResizeObserver(this.recalculatePositions));
        ro.observe(this.host);
    }
    componentWillLoad() {
        this.watchHideScrollbars();
    }
    componentDidLoad() {
        this.activeItem = this.allActiveItems.find((el, i) => this.isActiveHandler(el, i));
        this.hideStartBtn();
        this.hideEndBtn();
        requestAnimationFrame(() => (this.instantReCalc = false));
    }
    disconnectedCallback() {
        if (this.ro) {
            this.ro.disconnect();
            this.ro = undefined;
        }
    }
    render() {
        return (renderer.h(index.Host, { key: 'e5c6238730817f0c7036060faa8c344d514a3924', dir: this.isRtl ? 'rtl' : null, class: "nano-masked-overflow", "has-scroll-controls": this.hasScrollControls }, renderer.h("div", { key: '4027acd51b80fd1bf2bb9d66a05ec051802732f3', part: "base", class: {
                onav: true,
                [`onav--${this.orientation}`]: true,
                'onav--has-scroll-controls': this.hasScrollControls,
                'onav--has-scroll-controls-start': !this.hideControlStart,
                'onav--has-scroll-controls-end': !this.hideControlEnd,
                'onav--no-transitions': this.instantReCalc,
                'onnav--has-indicator': this.showIndicator,
                'onnav--hide-scrollbars': this.hideScrollbars && this.hideScrollbars !== 'false',
            }, onClick: this.handleClick, onKeyDown: this.handleKeyDown }, renderer.h("div", { key: 'a552b2e3cdf9f84249655b21ce6f2acb5c330a75', class: "onav__nav" }, this.scrollControls && (renderer.h("nano-icon-button", { key: '5aca29990db29b3d0d00e6bca317cd3870d06d6b', part: "scroll-button scroll-button-prev", class: {
                'onav__scroll-button': true,
                'onav__scroll-button--start': true,
            }, ref: (btn) => (this.startBtn = btn), onClick: () => this.handleBtnClick(false), label: "Click to scroll", iconName: this.orientation === 'horizontal'
                ? 'light/chevron-left'
                : 'light/chevron-up' })), renderer.h("div", { key: '9c2b4c91859b5c6c132ab2eecc01cf56eeec18b9', part: "scroller", ref: (el) => (this.nav = el), class: "onav__scroller", onScroll: this.handleScroll, tabindex: this.hasScrollControls ? 0 : undefined, role: "region", "aria-label": this.label || undefined }, renderer.h("div", { key: 'a77097f7b9a70e08f9a1eb980948c5c92dff760d', part: "items", ref: (el) => (this.itemContainer = el), class: "onav__items" }, this.showIndicator && (renderer.h("div", { key: 'b8661b042f9e195850a33ce3570b75c9bed25d7e', part: "indicator", ref: (el) => (this.activeIndicator = el), class: "onav__active-indicator" })), renderer.h("slot", { key: '54af572f6ef591d8d3cb34221e048ac0e32140bb', onSlotchange: this.slotChangeHandler }))), this.scrollControls && (renderer.h("nano-icon-button", { key: 'e27a06cc2cec7ed373c527e3c6db5a0a56a90b71', part: "scroll-button scroll-button-next", class: {
                'onav__scroll-button': true,
                'onav__scroll-button--end': true,
            }, ref: (btn) => (this.endBtn = btn), onClick: () => this.handleBtnClick(true), label: "Click to scroll", iconName: this.orientation === 'horizontal'
                ? 'light/chevron-right'
                : 'light/chevron-down' }))))));
    }
    static get watchers() { return {
        "hideScrollbars": ["watchHideScrollbars"],
        "isActiveHandler": ["watchIsActiveHandler"],
        "hasScrollControls": ["watchScrollControls"],
        "hideControlEnd": ["hideEndBtn"],
        "hideControlStart": ["hideStartBtn"]
    }; }
};
MaskedOverflow.style = maskedOverflowCss;

exports.nano_masked_overflow = MaskedOverflow;
