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

var index = require('./index-DGttnXif.js');
var renderer = require('./renderer-jVpDRMfV.js');
var dateUtils = require('./date-utils-DqYlulq4.js');
var dom = require('./dom-Dxk5vXYq.js');
var throttle = require('./throttle-CrRDOkln.js');
var formControl = require('./form-control-Bq9Dlz-r.js');

const localization = {
    buttonLabel: 'Choose date',
    placeholder: 'YYYY-MM-DD',
    selectedDateMessage: 'Selected date is',
    prevMonthLabel: 'Previous month',
    nextMonthLabel: 'Next month',
    monthSelectLabel: 'Month',
    yearSelectLabel: 'Year',
    closeLabel: 'Close window',
    keyboardInstruction: 'You can use arrow keys to navigate dates',
    calendarHeading: 'Choose a date',
    dayNames: [
        'Sunday',
        'Monday',
        'Tuesday',
        'Wednesday',
        'Thursday',
        'Friday',
        'Saturday',
    ],
    monthNames: [
        'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December',
    ],
    monthNamesShort: [
        'Jan',
        'Feb',
        'Mar',
        'Apr',
        'May',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Oct',
        'Nov',
        'Dec',
    ],
};

const DatePickerDay = ({ focusedDay, today, day, onDaySelect, onKeyboardNavigation, focusedDayRef, inRange, disabled, isSelected, }) => {
    const isToday = dateUtils.isEqual(day, today);
    const isFocused = dateUtils.isEqual(day, focusedDay);
    const isDisabled = day.getMonth() !== focusedDay.getMonth() || disabled;
    const isOutsideRange = !inRange;
    function handleClick(e) {
        onDaySelect(e, day);
    }
    return (renderer.h("button", { class: {
            'duet-date__day': true,
            'is-outside': isOutsideRange,
            'is-disabled': isDisabled,
            'is-today': isToday,
        }, tabIndex: isFocused ? 0 : -1, onClick: handleClick, onKeyDown: onKeyboardNavigation, disabled: isOutsideRange, type: "button", "aria-pressed": isSelected ? 'true' : 'false', ref: (el) => {
            if (isFocused && el && focusedDayRef) {
                focusedDayRef(el);
            }
        } },
        renderer.h("span", { "aria-hidden": "true" }, day.getDate()),
        renderer.h("span", { class: "duet-date__vhidden" }, day.toLocaleDateString(undefined, { day: 'numeric', month: 'long' }))));
};

function chunk(array, chunkSize) {
    const result = [];
    for (let i = 0; i < array.length; i += chunkSize) {
        result.push(array.slice(i, i + chunkSize));
    }
    return result;
}
function mapWithOffset(array, startingOffset, mapFn) {
    return array.map((_, i) => {
        const adjustedIndex = (i + startingOffset) % array.length;
        return mapFn(array[adjustedIndex]);
    });
}
const DatePickerMonth = ({ selectedDate, focusedDate, labelledById, localization, firstDayOfWeek, min, max, onDateSelect, onKeyboardNavigation, focusedDayRef, onMouseDown, onFocusIn, isDateDisabled, }) => {
    const today = new Date();
    const days = dateUtils.getViewOfMonth(focusedDate, firstDayOfWeek);
    return (renderer.h("table", { class: "duet-date__table", role: "grid", "aria-labelledby": labelledById, onFocusin: onFocusIn, onMouseDown: onMouseDown },
        renderer.h("thead", null,
            renderer.h("tr", null, mapWithOffset(localization.dayNames, firstDayOfWeek, (dayName) => (renderer.h("th", { class: "duet-date__table-header", scope: "col" },
                renderer.h("span", { "aria-hidden": "true" }, dayName.substring(0, 2)),
                renderer.h("span", { class: "duet-date__vhidden" }, dayName)))))),
        renderer.h("tbody", null, chunk(days, 7).map((week) => (renderer.h("tr", { class: "duet-date__row" }, week.map((day) => (renderer.h("td", { class: "duet-date__cell", role: "gridcell", "aria-selected": dateUtils.isEqual(day, selectedDate) ? 'true' : undefined },
            renderer.h(DatePickerDay, { day: day, today: today, focusedDay: focusedDate, inRange: dateUtils.inRange(day, min, max), onDaySelect: onDateSelect, onKeyboardNavigation: onKeyboardNavigation, focusedDayRef: focusedDayRef, disabled: isDateDisabled(day), isSelected: dateUtils.isEqual(day, selectedDate) }))))))))));
};

const datePickerCss = ":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{--active-color:var(--nano-color-primary-1000);--active-text-color:var(--nano-color-base-0);--inactive-color:var(--nano-color-neutral-300);display:block;font-size:16px;background:var(--nano-color-neutral-50)}.duet-date *,.duet-date *::before,.duet-date *::after{box-sizing:border-box;margin:0}.duet-date{box-sizing:border-box;color:currentcolor;display:block;margin:0;position:relative;text-align:start;inline-size:100%}.duet-date__dialog{display:flex;inset-block-start:100%;max-inline-size:100%;inline-size:100%}.duet-date__dialog.is-left{inset-inline:auto 0;inline-size:auto}.duet-date__dialog-content{min-inline-size:290px;padding:var(--nano-spacing-md);position:relative;transform:none;max-inline-size:100%;inline-size:100%}.duet-date__table{border-collapse:collapse;border-spacing:0;font-size:1em;line-height:1;text-align:center;inline-size:100%}.duet-date__table-header{font-size:0.75em;font-weight:600;letter-spacing:1px;line-height:1;padding-block-end:8px;text-decoration:none;text-transform:uppercase}.duet-date__cell{text-align:center;padding:0 0 3px}.duet-date__day{appearance:none;background:transparent;border:0;border-radius:50%;cursor:pointer;display:inline-block;font-size:0.875em;font-variant-numeric:tabular-nums;line-height:1;position:relative;text-align:center;vertical-align:middle;z-index:1;block-size:2.5em;inline-size:2.5em}.duet-date__day.is-today{box-shadow:0 0 0 1px var(--active-color);position:relative}.duet-date__day:hover::before,.duet-date__day.is-today::before{content:\"\";background:var(--active-color);border-radius:50%;opacity:0.16;position:absolute;inset:0}[aria-selected=true] .duet-date__day{background:var(--active-color) !important;color:var(--active-text-color);box-shadow:none;outline:0}.duet-date__day:not(.is-disabled):active{background:color-mix(in srgb, var(--active-color), black 20%);color:var(--active-text-color)}.duet-date__day:focus-visible{outline:var(--nano-focus-ring);outline-offset:-1px;z-index:2}.duet-date__day.is-disabled{background:transparent;box-shadow:none;cursor:default;opacity:0.5}.duet-date__day.is-disabled::before{display:none}.duet-date__day.is-outside{background:var(--inactive-color);box-shadow:none;cursor:default;opacity:0.8;pointer-events:none}.duet-date__day.is-outside::before{display:none}.duet-date__header{align-items:center;display:flex;justify-content:space-between;margin-block-end:var(--nano-spacing-md);inline-size:100%}.duet-date__nav{white-space:nowrap}.duet-date__prev,.duet-date__next{background:var(--inactive-color);align-items:center;appearance:none;border:0;border-radius:50%;cursor:pointer;display:inline-flex;justify-content:space-around;margin-inline-start:8px;padding:0;font-size:0.9em;block-size:2.2em;inline-size:2.2em}.duet-date__prev:focus-visible,.duet-date__next:focus-visible{outline:var(--nano-focus-ring);outline-offset:var(--nano-focus-ring-offset)}.duet-date__prev:active,.duet-date__next:active{background:color-mix(in srgb, var(--inactive-color), black 20%)}.duet-date__prev:disabled,.duet-date__next:disabled{cursor:default;opacity:0.7}.duet-date__prev .nano-icon,.duet-date__next .nano-icon{margin-block:0;margin-inline:auto}.duet-date__select{display:inline-flex;margin-block-start:4px;position:relative}.duet-date__select span{margin-inline-end:4px}.duet-date__select select{cursor:pointer;font-size:1em;block-size:100%;inset-inline-start:0;opacity:0;position:absolute;inset-block-start:0;inline-size:100%;z-index:2}.duet-date__select select:focus-visible:focus+.duet-date__select-label{outline:var(--nano-focus-ring);outline-offset:var(--nano-focus-ring-offset)}.duet-date__select-label{align-items:center;display:flex;font-size:1.25em;font-weight:600;line-height:1;padding-block:0;padding-inline:8px 4px;pointer-events:none;position:relative;inline-size:100%;z-index:1}.duet-date__select-label .nano-icon{font-size:0.55em}.duet-date__vhidden{border:0;clip:rect(1px, 1px, 1px, 1px);block-size:1px;overflow:hidden;padding:0;position:absolute;inset-block-start:0;inline-size:1px}";

function range(from, to) {
    const result = [];
    for (let i = from; i <= to; i++) {
        result.push(i);
    }
    return result;
}
let dateIds = 0;
const NanoDatePicker = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.nanoDatePicked = index.createEvent(this, "nanoDatePicked", 7);
    }
    dateId = `nano-datepicker-${dateIds++}`;
    monthSelectId = this.dateId + '-' + 'month';
    yearSelectId = this.dateId + '-' + 'year';
    dialogLabelId = this.dateId + '-' + 'dialog';
    firstFocusableElement;
    monthSelectNode;
    focusedDayNode;
    focusTimeoutId;
    initialTouchX = null;
    initialTouchY = null;
    get host() { return index.getElement(this); }
    activeFocus = false;
    focusedDay = new Date();
    // Public Property API
    _selectedDate = '';
    /** Selected Date. Must be in IS0-8601 format: YYYY-MM-DD. */
    get selectedDate() {
        return this._selectedDate;
    }
    set selectedDate(value) {
        if (typeof value !== 'string') {
            this._selectedDate = '';
            return;
        }
        value = value.split('T')[0]; // remove time part if present
        this._selectedDate = value;
    }
    /** Minimum date allowed to be picked. Must be in IS0-8601 format: YYYY-MM-DD.
     * This setting can be used alone or together with the max property. */
    min = '';
    /** Maximum date allowed to be picked. Must be in IS0-8601 format: YYYY-MM-DD.
     * This setting can be used alone or together with the min property. */
    max = '';
    /** Which day is considered first day of the week. `0` for Sunday, `1` for Monday, etc.
     * Default is Monday. */
    firstDayOfWeek = dateUtils.DaysOfWeek.Monday;
    /** Button labels, day names, month names, etc, used for localization.
     * Default is English. */
    localization = localization;
    /**
     * Controls which days are disabled and therefore disallowed.
     * For example, this can be used to disallow selection of weekends.
     * @returns `false` for not disabled and `true` for disabled
     */
    isDateDisabled = () => false;
    /** Controls whether the picker is within a modal control and will therefore keep focus within the control */
    isModal = false;
    /** @internal First focusable element. Relevant for keeping focus within the control */
    firstFocusEle;
    // Events
    /** Event emitted when a date is selected. */
    nanoDatePicked;
    // Public methods API
    /** Focus to the calendar
     * @param day - focus to the current selected day
     */
    async setFocus(day = false) {
        this.setFocusedDay(dateUtils.parseISODate(this.selectedDate) || new Date());
        if (day) {
            setTimeout((_) => this.focusedDayNode.focus({ preventScroll: true }), 20);
            return;
        }
        clearTimeout(this.focusTimeoutId);
        this.focusTimeoutId = setTimeout(() => {
            this.monthSelectNode.focus({ preventScroll: true });
        }, 20);
    }
    handleSelectedDateChange() {
        this.setFocus(true);
    }
    // Local methods.
    enableActiveFocus = () => {
        this.activeFocus = true;
    };
    disableActiveFocus = () => {
        this.activeFocus = false;
    };
    addDays(days) {
        this.setFocusedDay(dateUtils.addDays(this.focusedDay, days));
    }
    addMonths(months) {
        this.setMonth(this.focusedDay.getMonth() + months);
    }
    addYears(years) {
        this.setYear(this.focusedDay.getFullYear() + years);
    }
    startOfWeek() {
        this.setFocusedDay(dateUtils.startOfWeek(this.focusedDay, this.firstDayOfWeek));
    }
    endOfWeek() {
        this.setFocusedDay(dateUtils.endOfWeek(this.focusedDay, this.firstDayOfWeek));
    }
    setMonth(month) {
        const min = dateUtils.setMonth(dateUtils.startOfMonth(this.focusedDay), month);
        const max = dateUtils.endOfMonth(min);
        const date = dateUtils.setMonth(this.focusedDay, month);
        this.setFocusedDay(dateUtils.dateClamp(date, min, max));
    }
    setYear(year) {
        const min = dateUtils.setYear(dateUtils.startOfMonth(this.focusedDay), year);
        const max = dateUtils.endOfMonth(min);
        const date = dateUtils.setYear(this.focusedDay, year);
        this.setFocusedDay(dateUtils.dateClamp(date, min, max));
    }
    setFocusedDay(day) {
        this.focusedDay = dateUtils.dateClamp(day, dateUtils.parseISODate(this.min), dateUtils.parseISODate(this.max));
    }
    handleTouchStart = (event) => {
        const touch = event.changedTouches[0];
        this.initialTouchX = touch.pageX;
        this.initialTouchY = touch.pageY;
    };
    handleTouchMove = (event) => {
        event.preventDefault();
    };
    handleTouchEnd = (event) => {
        const touch = event.changedTouches[0];
        const distX = touch.pageX - this.initialTouchX; // get horizontal dist traveled
        const distY = touch.pageY - this.initialTouchY; // get vertical dist traveled
        const threshold = 70;
        const isHorizontalSwipe = Math.abs(distX) >= threshold && Math.abs(distY) <= threshold;
        if (isHorizontalSwipe) {
            this.addMonths(distX < 0 ? 1 : -1);
        }
        this.initialTouchY = null;
        this.initialTouchX = null;
    };
    handleNextMonthClick = (event) => {
        event.preventDefault();
        this.addMonths(1);
    };
    handlePreviousMonthClick = (event) => {
        event.preventDefault();
        this.addMonths(-1);
    };
    handleKeyboardNavigation = (event) => {
        // handle tab separately, since it needs to be treated
        // differently to other keyboard interactions
        if (event.key === 'Tab' && !event.shiftKey && this.isModal) {
            event.preventDefault();
            const ele = this.firstFocusEle || this.firstFocusableElement;
            if (ele['setFocus'])
                ele.setFocus();
            else
                ele.focus();
            return;
        }
        let handled = true;
        switch (event.key) {
            case 'ArrowRight':
                this.addDays(1);
                break;
            case 'ArrowLeft':
                this.addDays(-1);
                break;
            case 'ArrowDown':
                this.addDays(7);
                break;
            case 'ArrowUp':
                this.addDays(-7);
                break;
            case 'PageUp':
                if (event.shiftKey) {
                    this.addYears(-1);
                }
                else {
                    this.addMonths(-1);
                }
                break;
            case 'PageDown':
                if (event.shiftKey) {
                    this.addYears(1);
                }
                else {
                    this.addMonths(1);
                }
                break;
            case 'Home':
                this.startOfWeek();
                break;
            case 'End':
                this.endOfWeek();
                break;
            default:
                handled = false;
        }
        if (handled) {
            event.preventDefault();
            this.enableActiveFocus();
        }
    };
    handleDaySelect = (_event, day) => {
        const isAllowed = !this.isDateDisabled(day);
        const isInRange = dateUtils.inRange(day, dateUtils.parseISODate(this.min), dateUtils.parseISODate(this.max));
        if (!isInRange || !isAllowed) {
            return;
        }
        if (day.getMonth() === this.focusedDay.getMonth()) {
            this.setValue(day);
        }
        else {
            this.setFocusedDay(day);
        }
    };
    handleMonthSelect = (e) => {
        this.setMonth(parseInt(e.target.value, 10));
    };
    handleYearSelect = (e) => {
        this.setYear(parseInt(e.target.value, 10));
    };
    setValue(date) {
        this.selectedDate = dateUtils.printISODate(date);
        this.nanoDatePicked.emit({
            value: this.selectedDate,
            valueAsDate: date,
        });
    }
    processFocusedDayNode = (element) => {
        this.focusedDayNode = element;
        if (this.activeFocus) {
            setTimeout(() => element.focus({ preventScroll: true }), 0);
        }
    };
    componentWillLoad() {
        this.handleSelectedDateChange();
    }
    render() {
        const valueAsDate = dateUtils.parseISODate(this.selectedDate);
        const selectedYear = (valueAsDate || this.focusedDay).getFullYear();
        const focusedMonth = this.focusedDay.getMonth();
        const focusedYear = this.focusedDay.getFullYear();
        const minDate = dateUtils.parseISODate(this.min);
        const maxDate = dateUtils.parseISODate(this.max);
        const prevMonthDisabled = minDate != null &&
            minDate.getMonth() === focusedMonth &&
            minDate.getFullYear() === focusedYear;
        const nextMonthDisabled = maxDate != null &&
            maxDate.getMonth() === focusedMonth &&
            maxDate.getFullYear() === focusedYear;
        let minYear = selectedYear - 10;
        let maxYear = selectedYear + 10;
        if (minDate)
            minYear = minDate.getFullYear();
        if (maxDate)
            maxYear = maxDate.getFullYear();
        return (renderer.h(index.Host, { key: 'd3b992532815f40dbd9fcb7b0ddfaa27d703899b', class: "nano-date-picker" }, renderer.h("div", { key: 'c1be847528fac0224c54110aa77a7b471969c34d', class: "duet-date" }, renderer.h("div", { key: '8aa8dceea4d272bf171924bfbf59a4f645bed23d', class: {
                'duet-date__dialog': true,
                'is-active': true,
            }, onTouchMove: this.handleTouchMove, onTouchStart: this.handleTouchStart, onTouchEnd: this.handleTouchEnd }, renderer.h("div", { key: '374d34c706b3972971ebfc05d32d4f2cfb8721de', class: "duet-date__dialog-content" }, renderer.h("div", { key: '4713d41d66ae2bc7057ec337080cd54700b51033', class: "duet-date__vhidden duet-date__instructions", "aria-live": "polite" }, this.localization.keyboardInstruction), renderer.h("div", { key: 'b602d630814a176a066dab67645178fd15a7ca22', class: "duet-date__header", onFocusin: this.disableActiveFocus }, renderer.h("div", { key: '2cc00317d6468c2ea5c477249774eec83f5b94da' }, renderer.h("h2", { key: '0f420e58b51e50d6d973330665c508ca8167f3c3', id: this.dialogLabelId, class: "duet-date__vhidden", "aria-live": "polite" }, this.localization.monthNames[focusedMonth], ' ', this.focusedDay.getFullYear()), renderer.h("label", { key: '56192f5d51880678b86137cca89cb4a98515e03e', htmlFor: this.monthSelectId, class: "duet-date__vhidden" }, this.localization.monthSelectLabel), renderer.h("div", { key: '900c7995f2a3c51b5d22fee6176518940e7efc27', class: "duet-date__select" }, renderer.h("select", { key: '22bef19a74a42e7864d6cff32707adc7c0cc52b6', id: this.monthSelectId, class: "duet-date__select--month", ref: (element) => (this.firstFocusableElement = this.monthSelectNode =
                element), onChange: this.handleMonthSelect }, this.localization.monthNames.map((month, i) => (renderer.h("option", { key: month, value: i, selected: i === focusedMonth, disabled: !dateUtils.inRange(new Date(focusedYear, i, 1), minDate ? dateUtils.startOfMonth(minDate) : null, maxDate ? dateUtils.endOfMonth(maxDate) : null) }, month)))), renderer.h("div", { key: 'ba1108c781547bbaba8da184f07fd7d36b12cb4c', class: "duet-date__select-label", "aria-hidden": "true" }, renderer.h("span", { key: '8cd8018d9b68129e69219b9bffcd978a394269a5' }, this.localization.monthNamesShort[focusedMonth]), renderer.h("nano-icon", { key: 'e2b440b6adf599930d20e584c92c5f66d52564fd', name: "light/chevron-down" }))), renderer.h("label", { key: '043530523830f9c5a67682c47cfb6dc0464f3133', htmlFor: this.yearSelectId, class: "duet-date__vhidden" }, this.localization.yearSelectLabel), renderer.h("div", { key: 'e2e43ad2280255eb46cf06b9328af9bbefbe96a5', class: "duet-date__select" }, renderer.h("select", { key: 'eaaa7a64a034d1723c20b42cf14c8cea0f8c78b1', id: this.yearSelectId, class: "duet-date__select--year", onChange: this.handleYearSelect }, range(minYear, maxYear).map((year) => (renderer.h("option", { key: year, selected: year === focusedYear }, year)))), renderer.h("div", { key: 'c6ce7ec0f073caad0bd6ab09d03f1e20f5433e97', class: "duet-date__select-label", "aria-hidden": "true" }, renderer.h("span", { key: '3f985ad9b631cb140f4e551ab2f20cbdef88da6a' }, this.focusedDay.getFullYear()), renderer.h("nano-icon", { key: '1b06f5e08b8b33bcc7d641abe122e3bb0fad05ba', name: "light/chevron-down" })))), renderer.h("div", { key: '4ea6d2f63406af47b4aba3b137c778aa9fed2524', class: "duet-date__nav" }, renderer.h("button", { key: '6cd94d90c91aa0ccbd74a9ba361b7d894ef9fccf', class: "duet-date__prev", onClick: this.handlePreviousMonthClick, disabled: prevMonthDisabled, type: "button" }, renderer.h("nano-icon", { key: '83d33e3779d7249634afbd8f1cd1c6476bad4697', name: "light/chevron-left" }), renderer.h("span", { key: '2318ef1d137f42a93240efc4caa15b376f079909', class: "duet-date__vhidden" }, this.localization.prevMonthLabel)), renderer.h("button", { key: 'f8c400b9e644687ce1279a70e6fc5c0b1aec6aac', class: "duet-date__next", onClick: this.handleNextMonthClick, disabled: nextMonthDisabled, type: "button" }, renderer.h("nano-icon", { key: 'a4ef19900fdfee3cc340ab6bba83dcf782e9b21a', name: "light/chevron-right" }), renderer.h("span", { key: 'da03dc579aeb3dc5a00b2c647f78b71186cc7d74', class: "duet-date__vhidden" }, this.localization.nextMonthLabel)))), renderer.h("div", { key: 'ec82cee96b94f0b4a36993d42bae2eb02a392522' }, renderer.h(DatePickerMonth, { key: 'e84697f87540abe1e8cfd47903655ac8b68ba08d', selectedDate: valueAsDate, focusedDate: this.focusedDay, onDateSelect: this.handleDaySelect, onKeyboardNavigation: this.handleKeyboardNavigation, labelledById: this.dialogLabelId, localization: this.localization, firstDayOfWeek: this.firstDayOfWeek, focusedDayRef: this.processFocusedDayNode, min: minDate, max: maxDate, isDateDisabled: this.isDateDisabled })))))));
    }
    static get watchers() { return {
        "selectedDate": ["handleSelectedDateChange"]
    }; }
};
NanoDatePicker.style = datePickerCss;

const inputCss = ".sc-nano-input-h, *.sc-nano-input, *.sc-nano-input::before, *.sc-nano-input::after {\n  box-sizing: border-box;\n}\n[hidden].sc-nano-input {\n  display: none !important;\n}\n@media (prefers-reduced-motion: reduce) {\n    .sc-nano-input-h, *.sc-nano-input, *.sc-nano-input::before, *.sc-nano-input::after {\n      animation-duration: 0.01ms !important;\n      animation-iteration-count: 1 !important;\n      transition-duration: 0.01ms !important;\n      scroll-behavior: auto !important;\n    }\n  }.sc-nano-input-h, *.sc-nano-input, *.sc-nano-input::before, *.sc-nano-input::after {\n  box-sizing: border-box;\n}\n[hidden].sc-nano-input {\n  display: none !important;\n}\n@media (prefers-reduced-motion: reduce) {\n    .sc-nano-input-h, *.sc-nano-input, *.sc-nano-input::before, *.sc-nano-input::after {\n      animation-duration: 0.01ms !important;\n      animation-iteration-count: 1 !important;\n      transition-duration: 0.01ms !important;\n      scroll-behavior: auto !important;\n    }\n  }slot-fb.sc-nano-input {\n  display: contents !important;\n}\n\n[disabled].sc-nano-input-h:not([disabled=false]) {\n  opacity: 0.5;\n  position: relative;\n}\n[disabled].sc-nano-input-h:not([disabled=false])::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  cursor: not-allowed;\n}\n\n.form-ctrl.sc-nano-input {\n  min-inline-size: 100%;\n  display: block;\n}\n.form-ctrl.has-helper-end.sc-nano-input {\n  display: flex;\n  gap: 1rem;\n  container-type: inline-size;\n}\n.form-ctrl.has-helper-end.sc-nano-input .form-ctrl__wrapper.sc-nano-input {\n  flex: 1 1 100%;\n}\n.form-ctrl.has-helper-end.sc-nano-input .form-ctrl__helper-end.sc-nano-input {\n  display: none;\n}\n@container (min-width: 350px) {\n  .form-ctrl.has-helper-end .form-ctrl__helper-end {\n    display: block !important;\n  }\n  .form-ctrl.has-helper-end .form-ctrl__helper {\n    display: none !important;\n  }\n}\n\n.form-ctrl__wrapper.sc-nano-input {\n  display: block;\n}\n\nlabel.sc-nano-input, .form-ctrl__more.sc-nano-input, .form-ctrl__error.sc-nano-input, .form-ctrl__helper.sc-nano-input {\n  display: block;\n}\nlabel.visually-hide.sc-nano-input, .form-ctrl__more.visually-hide.sc-nano-input, .form-ctrl__error.visually-hide.sc-nano-input, .form-ctrl__helper.visually-hide.sc-nano-input {\n  clip-path: inset(50%);\n  block-size: 1px;\n  overflow: hidden;\n  position: absolute;\n  white-space: nowrap;\n  inline-size: 1px;\n}\n\n.form-ctrl__float-label.sc-nano-input {\n  padding-block: 0;\n  padding-inline: var(--padding-start) 0;\n  color: var(--label-color);\n  position: absolute;\n  font-size: 1em;\n  transform: translateY(-50%);\n  inset-block-start: 50%;\n  transition: all 0.125s ease-in;\n  opacity: 1;\n}\n.has-focus.sc-nano-input-h .form-ctrl__float-label.sc-nano-input, .has-value.sc-nano-input-h .form-ctrl__float-label.sc-nano-input {\n  transform: none;\n  font-size: 0.75em;\n  opacity: 0.7;\n  inset-block-start: var(--padding-top);\n}\n.form-ctrl__float-label.sc-nano-input .form-ctrl__label-charcount.sc-nano-input {\n  opacity: 0;\n  transition: opacity 0.125s ease-in;\n}\n.has-focus.sc-nano-input-h .form-ctrl__float-label.sc-nano-input .form-ctrl__label-charcount.sc-nano-input, .has-value.sc-nano-input-h .form-ctrl__float-label.sc-nano-input .form-ctrl__label-charcount.sc-nano-input {\n  opacity: 1;\n}\n\n.form-ctrl__label.sc-nano-input {\n  color: var(--label-color);\n  font-size: var(--label-font-size);\n  padding-block-end: var(--padding-bottom);\n  line-height: 1;\n  display: flex;\n  align-items: center;\n}\n.form-ctrl__label.sc-nano-input .form-ctrl__label-wrap.sc-nano-input {\n  flex: 1;\n  overflow-x: clip;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n}\n.form-ctrl__label.sc-nano-input .form-ctrl__label-placeholder.sc-nano-input {\n  margin-block: unset;\n  margin-inline: 0 5px;\n  opacity: 0;\n  appearance: none;\n  transition: 0.3s ease opacity;\n  font-size: 0.85em;\n}\n.form-ctrl__label.sc-nano-input .form-ctrl__label-charcount.sc-nano-input {\n  margin-block: unset;\n  margin-inline: auto 0;\n  font-size: var(--nano-font-size-2xs);\n  opacity: 0.5;\n}\n.has-value.sc-nano-input-h .form-ctrl__label.sc-nano-input .form-ctrl__label-placeholder.sc-nano-input {\n  opacity: 0.5;\n}\n\n.has-float-label.sc-nano-input .select__multi-input.sc-nano-input, .has-float-label.sc-nano-input .select__native-input.sc-nano-input, .has-float-label.sc-nano-input .input__native-ctrl.sc-nano-input {\n  opacity: 0;\n  transition: opacity 0.125s ease-in;\n}\n.has-focus.sc-nano-input-h .has-float-label.sc-nano-input .select__multi-input.sc-nano-input, .has-value.sc-nano-input-h .has-float-label.sc-nano-input .select__multi-input.sc-nano-input, .has-focus.sc-nano-input-h .has-float-label.sc-nano-input .select__native-input.sc-nano-input, .has-value.sc-nano-input-h .has-float-label.sc-nano-input .select__native-input.sc-nano-input, .has-focus.sc-nano-input-h .has-float-label.sc-nano-input .input__native-ctrl.sc-nano-input, .has-value.sc-nano-input-h .has-float-label.sc-nano-input .input__native-ctrl.sc-nano-input {\n  opacity: 1;\n}\n\n.form-ctrl__more.sc-nano-input {\n  position: relative;\n  margin-block: var(--padding-bottom) 0;\n  margin-inline: 0;\n  opacity: 0;\n  display: none;\n  transition: all var(--nano-transition-fast) ease;\n  transition-behavior: allow-discrete;\n}\n.form-ctrl__more.sc-nano-input > *.sc-nano-input {\n  grid-column: 1;\n  grid-row: 1;\n}\n.has-helper.sc-nano-input .form-ctrl__more.sc-nano-input, .has-error.sc-nano-input .form-ctrl__more.sc-nano-input {\n  display: grid;\n  opacity: 1;\n}\n\n.form-ctrl__helper.sc-nano-input, .form-ctrl__error.sc-nano-input {\n  font-size: var(--more-font-size);\n  line-height: 1.2;\n  transition: 0.3s ease-out opacity;\n}\n\n.form-ctrl__helper.sc-nano-input {\n  font-style: italic;\n  color: var(--help-msg-color);\n}\n[show-inline-error].sc-nano-input-h:not([show-inline-error=false]).is-invalid .form-ctrl__helper.sc-nano-input {\n  opacity: 0;\n}\n\n.form-ctrl__helper-end.sc-nano-input {\n  flex: 1 1 30%;\n  min-inline-size: 150px;\n  font-size: var(--invalid-msg-font-size);\n  color: var(--help-msg-color);\n  font-style: italic;\n}\n\n.form-ctrl__error.sc-nano-input {\n  opacity: 0;\n  color: var(--invalid-msg-color);\n  font-style: italic;\n}\n.is-invalid.sc-nano-input-h:not([disabled]) .form-ctrl__error.sc-nano-input {\n  opacity: 1;\n}\n\n.form-ctrl__input.sc-nano-input {\n  font-family: inherit;\n  font-size: inherit;\n  font-stretch: inherit;\n  font-style: inherit;\n  font-weight: inherit;\n  letter-spacing: inherit;\n  text-decoration: inherit;\n  text-overflow: inherit;\n  text-transform: inherit;\n  text-align: inherit;\n  white-space: inherit;\n  color: inherit;\n  border-radius: var(--input-border-radius);\n  inline-size: 100%;\n  padding: 0 !important;\n  position: relative;\n  flex: 1 0 auto;\n  display: flex;\n  background: var(--input-bg-color);\n  border: var(--input-border-style) var(--input-border-width);\n  font-size: var(--input-font-size);\n  padding-inline-start: calc(var(--input-invalid-border-hint-width) - var(--input-border-width)) !important;\n}\n.form-ctrl__input.sc-nano-input:focus-visible, .form-ctrl__input.sc-nano-input:focus-within, .has-focus.sc-nano-input-h .form-ctrl__input.sc-nano-input {\n  outline: var(--nano-focus-ring-color) solid 3px;\n  outline-offset: -2px;\n}\n.is-invalid.sc-nano-input-h:not([disabled]) .form-ctrl__input.sc-nano-input {\n  border-inline-start: solid var(--color-invalid) var(--input-invalid-border-hint-width);\n  padding-inline-start: 0 !important;\n}\n.is-invalid.has-focus.sc-nano-input-h:not([disabled]) .form-ctrl__input.sc-nano-input {\n  border-color: var(--color-invalid);\n  border-inline-start: solid var(--color-invalid) var(--input-invalid-border-hint-width);\n  padding-inline-start: 0 !important;\n}\n\n.form-ctrl__input-wrap.sc-nano-input {\n  display: flex;\n  flex: 1;\n  max-inline-size: 100%;\n  align-items: center;\n}\n[type=textarea].sc-nano-input-h .form-ctrl__input-wrap.sc-nano-input {\n  align-items: start;\n}\n\n.form-ctrl__clear-btn.sc-nano-input, .form-ctrl__slot-end.sc-nano-input, .form-ctrl__slot-start.sc-nano-input, .form-ctrl__slot-value-end.sc-nano-input {\n  margin-block: 0;\n  margin-inline: 0;\n  font-size: 1em;\n  border: 0;\n  outline: none;\n  background-color: transparent;\n  background-repeat: no-repeat;\n  display: flex;\n  align-items: center;\n  inline-size: auto;\n  padding-inline-end: var(--padding-end);\n  padding-block: var(--padding-top) var(--padding-bottom);\n}\n.form-ctrl__clear-btn.sc-nano-input:empty, .form-ctrl__slot-end.sc-nano-input:empty, .form-ctrl__slot-start.sc-nano-input:empty, .form-ctrl__slot-value-end.sc-nano-input:empty {\n  display: none;\n}\n\n.form-ctrl__slot-end.sc-nano-input {\n  padding-block: calc(var(--padding-top) / 2) calc(var(--padding-bottom) / 2);\n}\n\n.form-ctrl__slot-start.sc-nano-input {\n  padding-inline-end: 0;\n}\n.has-float-label.sc-nano-input .form-ctrl__slot-start.sc-nano-input {\n  display: none;\n}\n\n.form-ctrl__slot-start.sc-nano-input-s > *, .form-ctrl__slot-start.sc-nano-input-s > *, .form-ctrl__slot-start .sc-nano-input-s > *, .form-ctrl__slot-end.sc-nano-input-s > *, .form-ctrl__slot-end .sc-nano-input-s > *, .form-ctrl__slot-value-end.sc-nano-input-s > :not(slot-fb), .form-ctrl__slot-value-end .sc-nano-input-s > :not(slot-fb) {\n  padding-inline: unset;\n  align-items: center;\n  display: flex;\n  block-size: 100%;\n  z-index: 1;\n}\n.sc-nano-input-h[disabled]:not([disabled=false]) .form-ctrl__slot-start.sc-nano-input-s > *, .form-ctrl__slot-start.sc-nano-input-s > *, .form-ctrl__slot-start .sc-nano-input-s > *, .sc-nano-input-h[disabled]:not([disabled=false]) .form-ctrl__slot-end.sc-nano-input-s > *, .form-ctrl__slot-end .sc-nano-input-s > *, .sc-nano-input-h[disabled]:not([disabled=false]) .form-ctrl__slot-value-end.sc-nano-input-s > :not(slot-fb), .form-ctrl__slot-value-end .sc-nano-input-s > :not(slot-fb) {\n  pointer-events: none;\n}\n\n.form-ctrl__slot-start.sc-nano-input-s > *, .form-ctrl__slot-start.sc-nano-input-s > *, .form-ctrl__slot-start .sc-nano-input-s > * {\n  margin-inline: var(--padding-start) 0;\n}\n\n.form-ctrl__slot-value-end.sc-nano-input-s > *, .form-ctrl__slot-value-end.sc-nano-input-s > *, .form-ctrl__slot-value-end .sc-nano-input-s > *, .form-ctrl__slot-value-end.sc-nano-input *.sc-nano-input {\n  pointer-events: none;\n}\n\n.form-ctrl__clear-btn.sc-nano-input {\n  color: var(--clear-btn-color);\n  padding: 0;\n  opacity: 0;\n  inline-size: 0;\n  appearance: none;\n  align-items: center;\n  overflow: hidden;\n  padding-block: var(--padding-top) var(--padding-bottom);\n}\n.is-invalid.sc-nano-input-h .form-ctrl__clear-btn.sc-nano-input {\n  color: var(--clear-btn-color--invalid);\n}\n.has-value.sc-nano-input-h .form-ctrl__clear-btn.sc-nano-input {\n  padding-inline: 0 var(--padding-end);\n  opacity: 1;\n  inline-size: auto;\n}\n.form-ctrl__clear-btn.sc-nano-input:hover {\n  color: var(--clear-btn-color--hover);\n}\n\n.form-ctrl__validation-icon.sc-nano-input {\n  padding-block: var(--padding-top) var(--padding-bottom);\n  padding-inline-end: var(--padding-end);\n  display: grid;\n  grid-template-areas: \"overlay\";\n}\n.sc-nano-input-h:not(.is-invalid .form-ctrl__validation-icon.sc-nano-input, .is-valid).sc-nano-input-h .form-ctrl__validation-icon.sc-nano-input {\n  display: none;\n}\n\n.form-ctrl__error-icon.sc-nano-input, .form-ctrl__success-icon.sc-nano-input {\n  color: var(--color-valid);\n  opacity: 0;\n  transition: 0.3s ease-out opacity;\n  grid-area: overlay;\n}\n\n.is-valid.sc-nano-input-h .form-ctrl__success-icon.sc-nano-input {\n  opacity: 1;\n}\n\n.form-ctrl__error-icon.sc-nano-input {\n  color: var(--color-invalid);\n}\n.is-invalid.sc-nano-input-h .form-ctrl__error-icon.sc-nano-input {\n  opacity: 1;\n}\n\n.sc-nano-input-h {\n  \n  --placeholder-color: var(--nano-color-neutral-1000);\n  --padding-top: var(--nano-spacing-sm);\n  --padding-end: var(--nano-spacing-sm);\n  --padding-bottom: var(--nano-spacing-sm);\n  --padding-start: var(--nano-spacing-sm);\n  --color-invalid: var(--nano-color-danger-1100);\n  --color-valid: var(--nano-color-success-1000);\n  --input-font-size: var(--nano-font-size-sm);\n  --input-text-color: var(--nano-color-base-1000);\n  --input-border-width: 1px;\n  --input-border-color: var(--nano-color-neutral-300);\n  --input-border-radius: 0px;\n  --input-invalid-border-hint-width: 2px;\n  --input-border-style: solid var(--input-border-color);\n  --input-border-style--focus: solid var(--input-border-width) var(--nano-color-primary-700);\n  --input-bg-color: var(--nano-color-base-0);\n  --invalid-msg-color: var(--color-invalid);\n  --help-msg-color: var(--nano-color-base-1000);\n  --more-font-size: var(--nano-font-size-2xs);\n  --clear-btn-color: rgb(var(--nano-color-base-rgb-1000) / 60%);\n  --clear-btn-color--hover: rgb(var(--nano-color-base-rgb-1000) / 100%);\n  --clear-btn-color--invalid: rgb(var(--color-invalid) / 100%);\n  --label-color: var(--nano-color-base-1000);\n  --label-font-size: var(--nano-font-size-xs);\n  position: relative;\n  inline-size: 100%;\n  padding: 0 !important;\n  color: currentcolor;\n  display: block;\n}\n\n[type=date].sc-nano-input-h .input__date-trigger.sc-nano-input {\n  color: var(--nano-color-primary-1200);\n}\n[type=date].sc-nano-input-h .input__date-dropdown.sc-nano-input {\n  --overflow: visible;\n}\n[type=date].sc-nano-input-h .input__date-close.sc-nano-input {\n  position: absolute;\n  inset-inline-end: 0;\n  inset-block: 0;\n  opacity: 0;\n  z-index: 2;\n}\n[type=date].sc-nano-input-h .input__date-close.sc-nano-input:focus {\n  opacity: 1;\n}\n@supports selector(::-moz-placeholder) {\n  [type=date].sc-nano-input-h .form-ctrl__input-wrap.sc-nano-input {\n    justify-content: end;\n    min-block-size: 2.5em;\n  }\n  [type=date].sc-nano-input-h .input__native-ctrl.sc-nano-input {\n    position: absolute;\n    inset-inline-start: 0;\n    inset-block-start: 0;\n  }\n  [type=date].sc-nano-input-h .input__date-dropdown.sc-nano-input {\n    background-color: var(--nano-color-base-0);\n  }\n}\n\n.input__native-ctrl.sc-nano-input {\n  font-family: inherit;\n  font-size: inherit;\n  font-stretch: inherit;\n  font-style: inherit;\n  font-weight: inherit;\n  letter-spacing: inherit;\n  text-decoration: inherit;\n  text-overflow: inherit;\n  text-transform: inherit;\n  text-align: inherit;\n  white-space: inherit;\n  color: inherit;\n  appearance: none;\n  -webkit-rtl-ordering: logical;\n  padding-block: 0;\n  padding-inline: var(--padding-start) var(--padding-end);\n  border-radius: var(--input-border-radius);\n  text-overflow: ellipsis;\n  color: var(--input-text-color);\n  display: inline-block;\n  flex: 1;\n  inline-size: 100%;\n  max-inline-size: 100%;\n  max-block-size: 100%;\n  border: 0;\n  outline: none;\n  background: transparent;\n  margin: 0;\n  box-sizing: border-box;\n  resize: none;\n  overflow: hidden;\n  line-height: 2.5em;\n  min-block-size: 2.5em;\n  \n}\n.has-float-label.sc-nano-input .input__native-ctrl.sc-nano-input {\n  line-height: 2.1em;\n  min-block-size: 2.1em;\n  padding-block-start: 1.4em;\n}\n.input__native-ctrl.sc-nano-input::placeholder {\n  color: var(--placeholder-color);\n  font-family: inherit;\n  font-style: initial;\n  font-weight: initial;\n  line-height: inherit;\n  min-block-size: initial;\n}\n.input__native-ctrl.sc-nano-input::-moz-placeholder {\n  line-height: 2.8em;\n  text-overflow: ellipsis;\n}\n.input__native-ctrl.sc-nano-input:-webkit-autofill {\n  background-color: transparent;\n}\n.input__native-ctrl.sc-nano-input::-webkit-search-decoration, .input__native-ctrl.sc-nano-input::-webkit-search-cancel-button, .input__native-ctrl.sc-nano-input::-webkit-search-results-button, .input__native-ctrl.sc-nano-input::-webkit-search-results-decoration {\n  appearance: none;\n}\n.input__native-ctrl.sc-nano-input::-webkit-calendar-picker-indicator {\n  display: none;\n}\n.input__native-ctrl.sc-nano-input::-webkit-datetime-edit {\n  display: block;\n  padding: 0;\n}\n.input__native-ctrl.sc-nano-input:invalid {\n  box-shadow: none;\n}\n.input__native-ctrl.sc-nano-input::-ms-clear, .input__native-ctrl.sc-nano-input::-ms-reveal {\n  display: none;\n}\n.input__native-ctrl.input__resizable.sc-nano-input {\n  resize: vertical;\n  overflow: auto;\n}\n.form-ctrl__textarea.sc-nano-input .input__native-ctrl.sc-nano-input {\n  line-height: 1.5em;\n  padding-block: calc(var(--padding-top) - 3px) 0.5em;\n  white-space: pre-wrap;\n}\n.form-ctrl__textarea.sc-nano-input .input__native-ctrl.sc-nano-input::placeholder {\n  line-height: 1.5em;\n}\n.has-float-label.sc-nano-input .form-ctrl__textarea.sc-nano-input .input__native-ctrl.sc-nano-input {\n  padding-block-start: 1.75em;\n}\n[readonly].sc-nano-input-h:not([readonly=false]) .input__native-ctrl.sc-nano-input {\n  -webkit-user-select: none;\n          user-select: none;\n}";

let inputIds = 0;
const Input = class {
    nativeInput;
    inputId = `nano-input-${inputIds++}`;
    didBlurAfterEdit = false;
    rtl = false;
    mo;
    charCount = 0;
    hasRendered = false;
    pickerDropdown;
    picker;
    pickerCloseBtn;
    shouldValidate = false;
    // we don't want these rendered eles decorated with @State
    // because that will cause re-renders. User get/set to set datalist options
    _nativeInputWrap;
    get nativeInputWrap() {
        return this._nativeInputWrap;
    }
    set nativeInputWrap(ele) {
        if (this._nativeInputWrap === ele)
            return;
        this._nativeInputWrap = ele;
        this.setDataListOpts();
    }
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.nanoInput = index.createEvent(this, "nanoInput", 7);
        this.nanoChange = index.createEvent(this, "nanoChange", 7);
        this.nanoBlur = index.createEvent(this, "nanoBlur", 7);
        this.nanoFocus = index.createEvent(this, "nanoFocus", 7);
        this.nanoDidLoad = index.createEvent(this, "nanoDidLoad", 7);
        this.nanoDidUnload = index.createEvent(this, "nanoDidUnload", 7);
        this.nanoValidate = index.createEvent(this, "nanoValidate", 7);
        this.handleBlur = this.handleBlur.bind(this);
    }
    hasFocus = false;
    hasLabelSlot = false;
    hasHelperSlot = false;
    hasHelperEndSlot = false;
    errorMessage = '';
    datalist = null;
    setDataListOpts() {
        if (!this.datalist)
            return;
        const currDWConfig = this.datalist.dropDownConfig || {};
        this.datalist.dropDownConfig = {
            distance: 10,
            ...currDWConfig,
            skidding: -1,
            tetherTo: this.nativeInputWrap,
        };
    }
    get el() { return index.getElement(this); }
    /**
     * This will be true when the control is in an invalid state.
     * Validity is determined by the `required` prop. Or if custom validity message is set. @readonly
     */
    get invalid() {
        return this._invalid;
    }
    _invalid = null;
    /**
     * Current validation message - if any. @readonly
     */
    get validityMessage() {
        if (!this.nativeInput)
            return '';
        return this.nativeInput.validationMessage;
    }
    /**
     * If the value of the type attribute is `"file"`, then this attribute will indicate the types of files that the server accepts, otherwise it will be ignored. The value must be a comma-separated list of unique content type specifiers.
     */
    accept;
    /**
     * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
     */
    autocapitalise = 'none';
    /**
     * Indicates whether the value of the control can be automatically completed by the browser.
     */
    autocomplete = 'off';
    /**
     * Whether auto correction should be enabled when the user is entering/editing the text value.
     */
    autocorrect = 'off';
    /**
     * This Boolean attribute lets you specify that a form control should have input focus when the page loads.
     */
    autofocus = false;
    /**
     * If `true`, a clear icon will appear in the input when there is a value. Clicking it clears the input.
     */
    clearable = false;
    /**
     * If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types.
     */
    clearOnEdit;
    /**
     * Set the amount of time, in milliseconds, to wait to trigger the `nanoChange` event after each keystroke.
     */
    debounce = 0;
    debounceChanged() {
        this.nanoChange = throttle.debounceEvent(this.nanoChange, this.debounce);
    }
    /**
     * If `true`, the user cannot interact with the input.
     */
    disabled = false;
    /**
     * A hint to the browser for which keyboard to display.
     * Possible values: `"none"`, `"text"`, `"tel"`, `"url"`,
     * `"email"`, `"numeric"`, `"decimal"`, and `"search"`.
     */
    inputmode;
    /**
     * When should the field perform validation
     */
    validateOn = 'submitThenDirty';
    /**
     * Whether to show validation errors underneath input
     */
    showInlineError = true;
    _label = '';
    /**
     * String to place within a label element. Alternatively you may use a label slot.
     */
    get label() {
        return this.required && !this._label.endsWith('*')
            ? this._label + ' *'
            : this._label;
    }
    set label(value) {
        this._label = value;
    }
    /**
     * Sometimes it can be helpful to always show the placeholder, even when the input has a value.
     * For example a postcode field could have a placeholder `e.g. LD1 1AA` which is helpful to show.
     */
    alwaysShowPlaceholder = false;
    /**
     * Visually hide the label - but make it accessible.
     */
    hideLabel = false;
    /**
     * Enable floating label behaviour. Will disable placeholder if set.
     */
    floatLabel = false;
    /**
     * The maximum value, which must not be less than its minimum (min attribute) value.
     */
    max;
    /**
     * If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the maximum number of characters that the user can enter.
     */
    maxlength;
    /**
     * The minimum value, which must not be greater than its maximum (max attribute) value.
     */
    min;
    /**
     * If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the minimum number of characters that the user can enter.
     */
    minlength;
    /**
     * If `true`, the user can enter more than one value. This attribute applies when the type attribute is set to `"email"` or `"file"`, otherwise it is ignored.
     */
    multiple;
    /**
     * The name of the control, which is submitted with the form data.
     */
    name = this.inputId;
    /**
     * A regular expression that the value is checked against. The pattern must match the entire value, not just some subset. Use the title attribute to describe the pattern to help the user. This attribute applies when the value of the type attribute is `"text"`, `"search"`, `"tel"`, `"url"`, `"email"`, or `"password"`, otherwise it is ignored.
     */
    pattern;
    /**
     * Instructional text that shows before the input has a value.
     */
    placeholder;
    /**
     * If `true`, the user cannot modify the value.
     */
    readonly = false;
    /**
     * If `true`, the user must fill in a value before submitting a form.
     * By default, setting this will also add an asterisk to the label.
     */
    required = false;
    /**
     * If `true`, the element will have its spelling and grammar checked.
     */
    spellcheck = false;
    /**
     * Works with the min and max attributes to limit the increments at which a value can be set.
     * Possible values are: `"any"` or a positive floating point number.
     */
    step;
    /**
     * The initial size of the control. This value is in pixels unless the value of the type attribute
     * is `"text"` or `"password"`, in which case it is an integer number of characters.
     * This attribute applies only when the `type` attribute is set to `"text"`, `"search"`, `"tel"`, `"url"`, `"email"`, or `"password"`, otherwise it is ignored.
     */
    size;
    /**
     * The type of control to display. The default type is text.
     */
    type = 'text';
    /**
     * The form element to associate the input with (its form owner). Must be the id of a form.
     */
    form;
    /**
     * The value of the input.
     */
    value = '';
    /**
     * Update the native input element when the value changes
     */
    valueChanged() {
        this.nanoChange.emit({ value: this.value });
        this.charCount = this.value?.length || 0;
        if (this.type === 'textarea' && this.resize === 'auto') {
            this.nativeInput.style.height = 'auto';
            if (this.value?.length)
                this.nativeInput.style.height = this.nativeInput.scrollHeight + 'px';
        }
        if (this.type === 'date') {
            if (this.isDateDisabled(this.valueAsDate)) {
                this.nativeInput.setCustomValidity('Date selected is not available.');
            }
            else if (this.nativeInput.validationMessage === 'Date selected is not available.') {
                this.nativeInput.setCustomValidity('');
            }
        }
        this.shouldValidate = true;
    }
    /** Represents the value of the input or NaN if numeric conversion is impossible */
    get valueAsNumber() {
        if (this.type === 'textarea')
            return NaN;
        return this.nativeInput?.valueAsNumber || NaN;
    }
    /** Represents the current value of the input as a Date, or null if conversion is not possible */
    get valueAsDate() {
        if (this.type === 'textarea')
            return null;
        return new Date(this.value);
    }
    /**
     * Whether to show a character count / remaining count when using the `maxlength` attribute.
     */
    showCharCount = false;
    handleValidatePropChange() {
        if (!this.hasRendered)
            return;
        this.shouldValidate = true;
    }
    ///// TYPE SPECIFIC PROPS /////
    /**
     * relevant to `type="textarea"`. Vertical resizing - enable / disable or make automatic.
     */
    resize = 'auto';
    /**
     * relevant to `type="textarea"`. Default number of rows to show
     */
    rows = 2;
    /**
     * relevant to `type="date"`. Whether to show a date picker.
     * Date pickers are not very useful if the potential input is too far in the distance or past e.g. Birthdays
     */
    showPicker = true;
    /** relevant to `type="date"`. Controls which days are disabled and therefore disallowed.
     * For example, this can be used to disallow selection of weekends.
     * @returns `false` for not disabled and `true` for disabled */
    isDateDisabled = () => false;
    /**
     * relevant to `type="date"`. Initial picker date. Defaults to `value` if set and today's date if not.
     * Must be in IS0-8601 format: YYYY-MM-DD.
     */
    initialPickerDate;
    /**
     * relevant to `type="date"`. If `true`, the input will close after a date is picked.
     */
    closeAfterPicked = true;
    /**
     * relevant to `type="date"`. Other options to pass to the date picker.
     * See the `nano-date-picker` docs for more information.
     */
    pickerOptions = {};
    /**
     * Emitted when a keyboard input occurred.
     */
    nanoInput;
    /**
     * Emitted when the value has changed.
     */
    nanoChange;
    /**
     * Emitted when the input loses focus.
     */
    nanoBlur;
    /**
     * Emitted when the input has focus.
     */
    nanoFocus;
    /**
     * Emitted when the input has been created.
     * @internal
     */
    nanoDidLoad;
    /**
     * Emitted when the input has been removed.
     * @internal
     */
    nanoDidUnload;
    /**
     * Called when validation is performed (which depends on `validateOn`).
     * @returns event.detail: `{ isValid: boolean, errorMessage: string, originalEvent: Event }`.
     */
    nanoValidate;
    /**
     * Get the current state of the control.
     * @param validateFirst - perform validation first before reporting
     * @returns `{ isValid: boolean, errorMessage: string }`
     */
    async reportValidity(validateFirst) {
        return new Promise((resolve) => {
            if (validateFirst)
                this.validate();
            setTimeout(() => {
                resolve({
                    isValid: !this._invalid,
                    errorMessage: this.nativeInput.validationMessage,
                });
            }, 50);
        });
    }
    /**
     * Sets focus on the specified `nano-input`. Use this method instead of the global
     * `input.focus()`.
     */
    async setFocus() {
        if (this.nativeInput) {
            this.nativeInput.focus();
            this.nativeInput.click();
        }
    }
    /**
     * Sets focus and select the text on the specified `nano-input`. Use this method instead of the global
     * `input.select()`.
     */
    async select() {
        if (this.nativeInput) {
            this.nativeInput.select();
        }
    }
    /**
     * @returns the native `<input>` element used under the hood.
     */
    getInputElement() {
        return Promise.resolve(this.nativeInput);
    }
    /**
     * Invalidate the field and show a custom error message. To clear the error you will need to re-call this method with an empty string.
     */
    async showError(message) {
        if (this.nativeInput) {
            this.nativeInput.setCustomValidity(message);
            this.validate();
        }
    }
    onReset(e) {
        const form = this.form
            ? document.querySelector('#' + this.form)
            : this.el.closest('form');
        if (!form || e.target !== this.el.closest('form'))
            return;
        this.value = '';
    }
    handleBlur(e) {
        if (!this.hasFocus)
            return;
        const kev = e;
        let target;
        requestAnimationFrame(() => {
            if (e instanceof KeyboardEvent && kev.key) {
                if (kev.key !== 'Tab')
                    return;
                target = document.activeElement;
            }
            else if (e instanceof FocusEvent) {
                target = document.activeElement;
            }
            else
                target = e.target;
            if (dom.closestElement(this.el.tagName.toLowerCase(), target) !== this.el) {
                this.onBlur();
            }
        });
    }
    shouldClearOnEdit() {
        const { type, clearOnEdit } = this;
        return clearOnEdit === undefined ? type === 'password' : clearOnEdit;
    }
    getValue() {
        return this.value || '';
    }
    validate = (ev) => {
        if (this.validateOn === 'submitThenDirty')
            this.validateOn = 'dirty';
        if (!this.nativeInput.validity?.valid) {
            if (this.showInlineError) {
                if (ev)
                    ev.preventDefault();
                this.errorMessage = this.nativeInput.validationMessage;
            }
            this._invalid = true;
        }
        else
            this._invalid = false;
        this.nanoValidate.emit({
            isValid: !this._invalid,
            errorMessage: this.nativeInput.validationMessage,
            originalEvent: ev,
        });
    };
    onInput = (ev) => {
        const input = ev.target;
        this.value = input?.value || '';
        this.nanoInput.emit(ev);
    };
    onBlur = () => {
        this.hasFocus = false;
        this.focusChanged();
        if (this.validateOn === 'dirty')
            this.validate();
        this.nanoBlur.emit();
    };
    onFocus = (e) => {
        if (this.type === 'date') {
            // fix to stop native date picker from showing
            e.preventDefault();
        }
        this.hasFocus = true;
        this.focusChanged();
        this.nanoFocus.emit();
    };
    onKeydown = (e) => {
        if (this.type === 'date' && [' '].includes(e.key)) {
            // fix to stop native date picker from showing
            e.preventDefault();
            if (this.showPicker) {
                this.pickerDropdown?.show();
            }
        }
        if (this.shouldClearOnEdit()) {
            // Did the input value change after it was blurred and edited?
            if (this.didBlurAfterEdit && this.hasValue()) {
                // Clear the input
                this.clearTextInput();
            }
            // Reset the flag
            this.didBlurAfterEdit = false;
        }
    };
    clearTextInput = (ev) => {
        if (this.clearable && !this.readonly && !this.disabled && ev) {
            ev.preventDefault();
            ev.stopPropagation();
        }
        this.value = '';
        this.nativeInput.value = '';
        const event = new window.Event('change');
        this.nativeInput.dispatchEvent(event);
    };
    focusChanged() {
        // If clearOnEdit is enabled and the input blurred but has a value, set a flag
        if (!this.hasFocus && this.shouldClearOnEdit() && this.hasValue()) {
            this.didBlurAfterEdit = true;
        }
    }
    hasValue() {
        return this.getValue().length > 0;
    }
    slotChangeObserver() {
        if (this.mo)
            this.mo.disconnect();
        const mo = (this.mo = new MutationObserver(() => this.processSlottedContent()));
        mo.observe(this.el, { childList: true, subtree: true });
    }
    processSlottedContent() {
        // see if we have label / button content
        this.hasLabelSlot = !!this.el.querySelectorAll('[slot="label"]');
        this.hasHelperSlot = !!this.el.querySelector('[slot="helper"]');
        this.hasHelperEndSlot = !!this.el.querySelector('[slot="helper-end"]');
        this.datalist = this.el.querySelector(`${renderer.transformTag('nano-datalist')}:not([slot])`);
    }
    connectedCallback() {
        this.debounceChanged();
        {
            this.el.dispatchEvent(new CustomEvent('nanoDidLoad', {
                detail: this.el,
            }));
        }
    }
    disconnectedCallback() {
        {
            document.dispatchEvent(new CustomEvent('nanoDidUnload', {
                detail: this.el,
            }));
        }
        if (this.mo)
            this.mo.disconnect();
    }
    componentDidLoad() {
        this.slotChangeObserver();
        this.hasRendered = true;
        if (this.autofocus)
            setTimeout((_) => this.setFocus(), 300);
    }
    componentWillLoad() {
        this.processSlottedContent();
    }
    componentDidRender() {
        if (this.shouldValidate) {
            this.validate();
            this.shouldValidate = false;
        }
    }
    render() {
        const value = this.getValue();
        const labelId = this.inputId + '-lbl';
        const moreId = this.showInlineError || this.hasHelperSlot ? this.inputId + '-more' : '';
        const helperEndId = this.hasHelperEndSlot ? this.inputId + '-helper' : '';
        this.rtl = this.el.ownerDocument.dir === 'rtl';
        const compWrapOptions = (({ el, floatLabel, label, alwaysShowPlaceholder, errorMessage, type, showInlineError, hasHelperSlot, hasLabelSlot, hideLabel, placeholder, maxlength, charCount, showCharCount, rtl, hasHelperEndSlot, }) => ({
            el,
            floatLabel,
            label,
            alwaysShowPlaceholder,
            errorMessage,
            type,
            showInlineError,
            hasHelperSlot,
            hasLabelSlot,
            hideLabel,
            placeholder,
            maxlength,
            charCount,
            showCharCount,
            rtl,
            hasHelperEndSlot,
        }))(this);
        const wrapOptions = {
            ...compWrapOptions,
            labelId,
            moreId,
            helperEndId,
            hasValue: this.hasValue(),
            controlId: this.inputId,
        };
        const controlOptions = (({ clearable, readonly, disabled }) => ({
            clearable,
            readonly,
            disabled,
            clearControl: this.clearable,
        }))(this);
        return (renderer.h(index.Host, { key: '636d7624bcfe136a0e93b55cf9fc38e272f7aed6', "aria-disabled": this.disabled ? 'true' : null, class: {
                'has-value': this.hasValue(),
                'has-focus': this.hasFocus,
                'is-invalid': this._invalid === true,
                'is-valid': this._invalid === false,
                'nano-input': true,
            } }, renderer.h("div", { key: '942db1636f7d08dd581359b66df66ebf080d23ae', style: { width: '100%' } }, renderer.h(formControl.FormControlWrap, { key: 'd944b897545398b51ab0a76e1f8d62c57cd85843', ...wrapOptions, class: {
                'has-helper': this.hasHelperSlot,
                'has-error': !!this.errorMessage &&
                    this.showInlineError &&
                    this._invalid === true,
            } }, renderer.h(formControl.FormControl, { key: 'efd29f841ff0724228fc47754a5aad8d82f88d49', ...controlOptions, onClearText: this.clearTextInput, control: this.el, ref: (el) => (this.nativeInputWrap = el), showInlineError: this.showInlineError, endSlot: this.showPicker &&
                this.type === 'date' &&
                !this.readonly &&
                !this.disabled && [
                renderer.h("nano-dropdown", { slot: "end", dialogTitle: "Choose a date", class: "input__date-dropdown", part: "date__dropdown", placement: "bottom-end", skidding: 10, distance: 12, ref: (dd) => (this.pickerDropdown = dd), onNanoAfterShow: () => this.picker.setFocus(true) }, renderer.h("nano-icon-button", { label: "Open date picker", iconName: "light/calendar-days", slot: "trigger", class: "input__date-trigger" }), renderer.h("div", null, renderer.h("div", { class: "date-field__close-bar" }, renderer.h("nano-icon-button", { label: "Close date picker", iconName: "light/xmark", class: "input__date-close", onClick: (e) => {
                        e.target
                            .closest('nano-dropdown')
                            ?.hide();
                    }, ref: (btn) => (this.pickerCloseBtn = btn) })), renderer.h("nano-date-picker", { part: "date__picker", ref: (dp) => {
                        this.picker = dp;
                        this.picker.firstFocusEle = this.pickerCloseBtn;
                    }, ...this.pickerOptions, isDateDisabled: this.isDateDisabled, onNanoDatePicked: (e) => {
                        this.value = e.detail.value;
                        this.pickerDropdown?.hide();
                    }, min: this.min, max: this.max, "is-modal": true, selectedDate: this.value || this.initialPickerDate || undefined }))),
            ] }, this.type !== 'textarea' && (renderer.h("input", { key: 'ce5547777de11926717b27712f7d687171d0dde7', id: this.inputId, class: "input__native-ctrl", ref: (input) => (this.nativeInput = input), "aria-labelledby": labelId + ' ' + moreId + ' ' + helperEndId, disabled: this.disabled, accept: this.accept, autoCapitalize: this.autocapitalise, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, inputMode: this.inputmode, form: this.form, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder, readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, size: this.size, type: this.type, value: value, onInput: this.onInput, onClick: (e) => e.preventDefault(), onChange: this.onInput, onFocus: this.onFocus, onBlur: this.handleBlur, onKeyDown: this.onKeydown, onInvalid: this.validate })), this.type === 'textarea' && (renderer.h("textarea", { key: 'e1dc2377200cdccda85cdbb6cda08a49d8459c1e', rows: this.floatLabel ? 1 : this.rows, id: this.inputId, class: {
                'input__native-ctrl': true,
                input__resizable: this.resize === 'true',
            }, ref: (input) => (this.nativeInput = input), "aria-labelledby": labelId + ' ' + moreId + ' ' + helperEndId, disabled: this.disabled, autoCapitalize: this.autocapitalise, autoCorrect: this.autocorrect, autoFocus: this.autofocus, inputMode: this.inputmode, form: this.form, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder, readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, value: value, onInput: this.onInput, onChange: this.onInput, onFocus: this.onFocus, onKeyDown: this.onKeydown, onInvalid: this.validate, onBlur: this.handleBlur })))), renderer.h("slot", { key: '564511c369dc13eb85cbf7e1c48b5d5fbbea8679' }))));
    }
    static get watchers() { return {
        "datalist": ["setDataListOpts"],
        "debounce": ["debounceChanged"],
        "value": ["valueChanged"],
        "minlength": ["handleValidatePropChange"],
        "maxlength": ["handleValidatePropChange"],
        "min": ["handleValidatePropChange"],
        "max": ["handleValidatePropChange"],
        "required": ["handleValidatePropChange"],
        "disabled": ["handleValidatePropChange"],
        "readonly": ["handleValidatePropChange"],
        "pattern": ["handleValidatePropChange"],
        "inputmode": ["handleValidatePropChange"],
        "type": ["handleValidatePropChange"]
    }; }
};
Input.style = inputCss;

exports.nano_date_picker = NanoDatePicker;
exports.nano_input = Input;
