import { r as registerInstance, c as createEvent, h, g as getElement, H as Host } from './core-58de451e.js';
import { D as DragController, b as DropController } from './drop.controller-1d933db3.js';
import { T as Tunnel } from './i18n.provider-f50e5e6a.js';
import { S as STANDARD_LOCALES } from './translations-c4959f9b.js';

const Calendar = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        /**
         * If true, display a calendar view, otherwise show yearly
         */
        this.monthMode = true;
        this.anjCalendarDaySelect = createEvent(this, "anjCalendarDaySelect", 7);
    }
    onDateChange() {
        if (!this.date) {
            return;
        }
        this.month = this.adapter.month(this.date);
        this.year = this.adapter.year(this.date);
        this.setHeaderData();
        this.updateMonth();
    }
    componentWillLoad() {
        this.weekdays = this.adapter.weekdays();
        this.months = this.adapter.months();
    }
    setHeaderData() {
        this.displayYear = this.adapter.prepHeaderYear(this.date);
        this.displayDate = this.adapter.prepHeaderDate(this.date);
    }
    displayActiveDay({ detail }) {
        this.displayYear = detail.year.toString();
        this.displayDate = this.adapter.prepHeaderDate(this.adapter.newDateFromArray(detail.year, detail.month, detail.day));
    }
    toggleMonthMode({ detail }) {
        this.monthMode = detail;
        this.controlsEl.focus();
    }
    updateYear({ detail }) {
        // Make increments in year
        this.year = this.year + detail;
        // Update current date to be first of the current month in the newly selected year
        this.date = this.adapter.newDateFromArray(this.year, this.month, 1);
    }
    selectMonth({ detail }) {
        // Update current date to be first of the newly selected month in the current year
        this.date = this.adapter.newDateFromArray(this.year, detail, 1);
        this.month = detail;
        this.monthMode = true;
        this.controlsEl.focus();
    }
    updateMonth(event = 0) {
        const change = isNaN(event) ? event.detail : event;
        // Make increments in month/year
        this.month = this.month + change;
        if (this.month < 0) {
            this.month = 11;
            this.year--;
        }
        if (this.month > 11) {
            this.month = 0;
            this.year++;
        }
        // Establish date info for previous, current and following month
        const lastMonth = {
            date: this.getMonthInfo(-1),
            days: this.getDaysInMonth(-1)
        };
        const thisMonth = {
            date: this.getMonthInfo(),
            days: this.getDaysInMonth(),
            dayOfFirst: this.getDayOfFirst()
        };
        const nextMonth = {
            date: this.getMonthInfo(1),
            dayOfFirst: this.getDayOfFirst(1)
        };
        // Establish dates for display on calendar for current month, including padded days.
        const prefix = Array.from(this.createRange(lastMonth.days - thisMonth.dayOfFirst + 1, lastMonth.days, lastMonth.date));
        const currentMonthDays = Array.from(this.createRange(1, thisMonth.days, thisMonth.date));
        let postfix = [];
        if (nextMonth.dayOfFirst > 0) {
            postfix = Array.from(this.createRange(1, 7 - nextMonth.dayOfFirst, nextMonth.date));
        }
        this.days = [].concat(prefix, currentMonthDays, postfix);
        this.package = {
            adapter: this.adapter,
            year: this.year,
            months: this.months,
            month: this.month,
            days: this.days,
            date: this.date,
            weekdays: this.weekdays
        };
    }
    selectDay({ detail }) {
        const selection = this.adapter.newDateFromArray(detail.year, detail.month, detail.day);
        this.date = selection;
        this.anjCalendarDaySelect.emit(selection);
    }
    focusControls() {
        return new Promise(resolve => {
            window.setTimeout(() => {
                this.controlsEl.focus();
                resolve();
            }, 100);
        });
    }
    componentDidLoad() {
        this.onDateChange();
    }
    getDayOfFirst(varianceFromCurrentMonth = 0) {
        const evaluatedMonth = this.month + varianceFromCurrentMonth;
        return this.adapter.dayOfFirst(this.year, evaluatedMonth);
    }
    getDaysInMonth(varianceFromCurrentMonth = 0) {
        const evaluatedMonth = this.month + varianceFromCurrentMonth;
        return this.adapter.daysInMonth(this.year, evaluatedMonth);
    }
    getMonthInfo(varianceFromCurrentMonth = 0) {
        const evaluatedMonth = this.month + varianceFromCurrentMonth;
        return this.adapter.getMonthInfo(this.year, evaluatedMonth);
    }
    createRange(start, end, dateInfo) {
        const rangeArray = [];
        for (let i = start; i <= end; i++) {
            rangeArray.push({
                day: i,
                month: this.adapter.month(dateInfo),
                year: this.adapter.year(dateInfo)
            });
        }
        return rangeArray;
    }
    render() {
        if (!this.package) {
            return;
        }
        return [
            h("div", { class: "anj-picker-header" }, h("p", { class: "anj-display-year" }, this.displayYear), h("p", { class: "anj-display-date" }, this.displayDate)),
            h("div", { class: "anj-date-controls", ref: r => this.controlsEl = r, tabindex: "0" }, this.monthMode
                ? h("anj-date-picker-month-view", { package: this.package, rangeParams: this.rangeParams })
                : h("anj-date-picker-year-view", { package: this.package }))
        ];
    }
    get element() { return getElement(this); }
    static get watchers() { return {
        "date": ["onDateChange"]
    }; }
    static get style() { return ".sc-anj-calendar-h{display:block;font-size:.875rem;font-family:var(--anj-font-family);font-weight:400;line-height:1.5;outline:none;background-color:var(--anj-light);background-clip:border-box;border:1px solid var(--anj-highlight);border-radius:.25rem;color:var(--anj-neutral-dark);width:16rem;z-index:1060}.sc-anj-calendar-h, .sc-anj-calendar-h:after, .sc-anj-calendar-h:before{-webkit-box-sizing:border-box;box-sizing:border-box;outline:none}.sc-anj-calendar-h:active, .sc-anj-calendar-h .sc-anj-calendar:active, .sc-anj-calendar-h:focus, .sc-anj-calendar-h .sc-anj-calendar:focus{outline:none}.sc-anj-calendar-h .anj-picker-header.sc-anj-calendar{background-color:var(--anj-primary);border-radius:calc(.25rem - 1);color:var(--anj-light);padding:.75rem .75rem .75rem 1.5rem}.sc-anj-calendar-h .anj-picker-header.sc-anj-calendar p.sc-anj-calendar{margin:0}.sc-anj-calendar-h .anj-picker-header.sc-anj-calendar .anj-display-year.sc-anj-calendar{font-size:1.1rem}.sc-anj-calendar-h .anj-picker-header.sc-anj-calendar .anj-display-date.sc-anj-calendar{font-size:1rem;font-weight:200}.sc-anj-calendar-h .anj-date-controls.sc-anj-calendar{outline:none}"; }
};

class DatePickerService {
    constructor(locale, language, timezone, format) {
        this.locale = locale;
        this.language = language;
        this.timezone = timezone;
        this.format = format;
        if (!this.locale) {
            this.locale = 'en-US';
        }
        this.locale = safeLocale(this.locale);
        if (!this.format) {
            this.format = (STANDARD_LOCALES[this.locale]) ? STANDARD_LOCALES[this.locale] : 'dd/MM/yyyy';
        }
        if (!this.language) {
            this.language = this.locale.split('-')[0];
        }
        this.timezone = timezone;
    }
    // Timezone-override aware date conversion
    convertToDate(input) {
        if (!input || !this.newDateFromValue(input)) {
            return null;
        }
        if (!this.timezone) {
            return new Date(input);
        }
        const localDateString = new Date(input).toLocaleDateString();
        const tzTime = new Date(localDateString).toLocaleString(undefined, { timeZone: this.timezone });
        const localDate = Number(new Date(input));
        const tzDate = Number(new Date(tzTime));
        let convertedDate;
        if (localDate >= tzDate) {
            const variance = localDate - tzDate;
            convertedDate = new Date(localDate + variance);
        }
        else {
            const variance = tzDate - localDate;
            convertedDate = new Date(localDate - variance);
        }
        return convertedDate;
    }
    dayOfFirst(year, month) {
        return new Date(year, month, 1).getDay();
    }
    daysInMonth(year, month) {
        return new Date(year, month + 1, 0).getDate();
    }
    isDisabled(evalDate, dateRangeParams) {
        if (!dateRangeParams) {
            return false;
        }
        const dayIsBeforeMinDate = (dateRangeParams.minDate) ? evalDate < dateRangeParams.minDate : false;
        const dayIsAfterMaxDate = (dateRangeParams.maxDate) ? evalDate > dateRangeParams.maxDate : false;
        return dayIsBeforeMinDate || dayIsAfterMaxDate;
    }
    getCalendarDate(value, rangeParams) {
        if (rangeParams && rangeParams.minDate
            && (!value || isNaN(value.valueOf()) || value.valueOf() < rangeParams.minDate.valueOf())) {
            value = this.newDateFromValue(rangeParams.minDate);
        }
        else if (rangeParams && rangeParams.maxDate
            && (!value || isNaN(value.valueOf()) || value.valueOf() > rangeParams.maxDate.valueOf())) {
            value = this.newDateFromValue(rangeParams.maxDate);
        }
        else if (!value || isNaN(value.valueOf())) {
            value = this.newDateFromValue();
        }
        return value;
    }
    getMonthInfo(year, month) {
        return new Date(year, month, 15);
    }
    month(date) {
        return date.getMonth();
    }
    newDateFromArray(year, month, day) {
        return new Date(year, month, day);
    }
    newDateFromValue(value) {
        const newValue = (value) ? new Date(value) : new Date();
        return (newValue.toString() === 'Invalid Date') ? null : newValue;
    }
    prepHeaderDate(date) {
        return localize(this.locale, date, { weekday: 'short', month: 'short', day: 'numeric' });
    }
    prepHeaderYear(date) {
        return localize(this.locale, date, { year: 'numeric' });
    }
    sameDay(_calendarDay, _comparator) {
        return _calendarDay.day === _comparator.getDate()
            && _calendarDay.month === _comparator.getMonth()
            && _calendarDay.year === _comparator.getFullYear();
    }
    year(date) {
        return date.getFullYear();
    }
    weekdays() {
        return getWeekdays(this.language);
    }
    months() {
        return getMonths(this.language);
    }
    localize(date) {
        return new Date(date).toLocaleDateString(this.locale, { month: '2-digit', day: '2-digit', year: 'numeric' });
    }
    prepDateStringOutput(input) {
        if (!input) {
            return null;
        }
        else if (typeof input === 'string') {
            return input;
        }
        else if (this.timezone) {
            // Timezone-override aware formatting
            const tzTime = new Date(input).toLocaleString(undefined, { timeZone: this.timezone });
            return this.localize(new Date(tzTime));
        }
        else {
            return this.localize(input);
        }
    }
    processDateInput(input) {
        if (!input) {
            return null;
        }
        if (typeof input === 'string') {
            // Remove any time notation by splitting on spaces or commas
            const regexSplit = input.split(/[ ,]+/g).filter(Boolean);
            const dateSegments = parseInput(regexSplit[0], this.format);
            if (dateSegments && Array.isArray(dateSegments.splitDate) && dateSegments.splitDate.length === 3 && dateSegments.year) {
                return new Date(parseInt(dateSegments.year, 10), parseInt(dateSegments.month, 10) - 1, parseInt(dateSegments.day, 10));
            }
            else {
                return new Date(input);
            }
        }
        else {
            return input;
        }
    }
}
function getWeekdays(locale) {
    const weekdays = [];
    for (let i = 0; i < 7; i++) {
        const date = new Date();
        const testDate = date.setDate(date.getDate() - date.getDay() + i);
        weekdays.push(localize(locale, new Date(testDate), { weekday: 'short' }));
    }
    return weekdays;
}
function getMonths(locale) {
    const months = [];
    for (let i = 0; i < 12; i++) {
        const testDate = new Date().setMonth(i);
        months.push(localize(locale, new Date(testDate), { month: 'short' }));
    }
    return months;
}
function localize(locale = 'en-US', date, options) {
    return new Intl.DateTimeFormat(locale, options).format(date);
}
/* Currently only support shortDate strings (with non-alphanumeric separators) of:
    {
        Month-Day-Year: if included in locale STANDARD_LOCALES,
        Year-Month-Day: if included in locale STANDARD_LOCALES,
        Day-Month-Year: for all locales outside of locale STANDARD_LOCALES
    }
 */
function parseInput(input, format) {
    // Split string on any non-alphanumeric characters, not including spaces
    const splitDate = input.split(/[^\w\s]+/g).filter(Boolean);
    if (splitDate.length <= 1 && input.length <= 8) {
        // Using best guess at a digit-only string evaluation
        return parseDigitOnlyDate(input, format);
    }
    else {
        // Using regex provided segments (or simply pass-through of ISO string)
        const dateSegments = {
            splitDate,
            year: '',
            month: '',
            day: ''
        };
        const splitDateCp = splitDate.slice(0);
        // Set year
        const { derivedYear, assumedDay } = setYearSegment(splitDateCp);
        dateSegments.year = derivedYear;
        // Set Day and Month
        Object.assign(dateSegments, setMonthAndDaySegments(splitDateCp, format, assumedDay));
        return dateSegments;
    }
}
function parseDigitOnlyDate(input, format) {
    const dateCreateTests = [];
    const testsFeeder = [];
    // Manipulate string to have the year at the beginning
    const s2DigYear = (format === 'yyyy/M/d') ? input : input.slice(input.length - 2).concat(input.slice(0, input.length - 2));
    const s4DigYear = (format === 'yyyy/M/d') ? input : input.slice(input.length - 4).concat(input.slice(0, input.length - 4));
    // Separate the Year from the Day/Month(dm)
    if (input.length === 8) {
        // YYYYxxxx, xxxxYYYY
        testsFeeder.push({ year: s4DigYear.slice(0, 4), dm: [s4DigYear.slice(4, 6), s4DigYear.slice(6)] });
    }
    else if (input.length === 7) {
        // YYYYxxx, xxxYYYY
        testsFeeder.push({ year: s4DigYear.slice(0, 4), dm: [s4DigYear.slice(4, 6), s4DigYear.slice(6)] });
        testsFeeder.push({ year: s4DigYear.slice(0, 4), dm: [s4DigYear.slice(4, 5), s4DigYear.slice(5)] });
    }
    else if (input.length === 6) {
        // YYYYxx, xxYYYY
        testsFeeder.push({ year: s4DigYear.slice(0, 4), dm: [s4DigYear.slice(4, 5), s4DigYear.slice(5)] });
        // YYxxxx, YYxxxx
        testsFeeder.push({ year: `20${s2DigYear.slice(0, 2)}`, dm: [s2DigYear.slice(2, 4), s2DigYear.slice(4)] });
    }
    else if (input.length === 5) {
        // YYxxx, xxxYY
        testsFeeder.push({ year: `20${s2DigYear.slice(0, 2)}`, dm: [s2DigYear.slice(2, 3), s2DigYear.slice(3)] });
        testsFeeder.push({ year: `20${s2DigYear.slice(0, 2)}`, dm: [s2DigYear.slice(2, 4), s2DigYear.slice(4)] });
    }
    else if (input.length === 4) {
        // YYxx, xxYY
        testsFeeder.push({ year: `20${s2DigYear.slice(0, 2)}`, dm: [s2DigYear.slice(2, 3), s2DigYear.slice(3)] });
    }
    // Intelligently guess which is day/month from dm
    testsFeeder.forEach(set => {
        if (format === 'dd/MM/yyyy') {
            dateCreateTests.push({ year: set.year, month: set.dm[1], day: set.dm[0] });
        }
        else {
            // 'yyyy/M/d', 'M/d/yyyy'
            dateCreateTests.push({ year: set.year, month: set.dm[0], day: set.dm[1] });
        }
    });
    // Filter out unlikely dates
    const unlikelyFilter = t => t.day <= 31 && t.month <= 11 && (t.year > 1900 && t.year < 2200);
    const segments = dateCreateTests.filter(unlikelyFilter)[0];
    if (segments) {
        switch (format) {
            case 'yyyy/M/d':
                segments.splitDate = [segments.year, segments.month, segments.day];
                break;
            case 'dd/MM/yyyy':
                segments.splitDate = [segments.month, segments.day, segments.year];
                break;
            case 'M/d/yyyy':
                segments.splitDate = [segments.month, segments.day, segments.year];
                break;
        }
    }
    return segments;
}
function setYearSegment(splitDateArray) {
    // Find year
    const year = splitDateArray.find(segment => segment.length === 4);
    // Remove year from working array
    const yearIndex = splitDateArray.indexOf(year);
    splitDateArray.splice(yearIndex, 1);
    // If first segment is year, we can safely assume that it was a YYYY-MM-DD format, grab last segment as assumedDay
    const assumedDay = (yearIndex === 0) ? splitDateArray[splitDateArray.length - 1] : undefined;
    return {
        derivedYear: year,
        assumedDay
    };
}
function setMonthAndDaySegments(splitDateArray, format, assumedDay) {
    const segments = {
        day: '',
        month: ''
    };
    // See if we can determine which segment is the days segment
    assumedDay = assumedDay || splitDateArray.find(segment => parseInt(segment, 10) > 12);
    if (assumedDay) {
        segments.day = assumedDay;
        const dayIndex = splitDateArray.indexOf(assumedDay);
        splitDateArray.splice(dayIndex, 1);
        segments.month = splitDateArray[0];
        // Otherwise, make a reasonable guess
    }
    else {
        switch (format) {
            case 'M/d/yyyy':
            case 'yyyy/M/d':
                segments.month = splitDateArray[0];
                segments.day = splitDateArray[1];
                break;
            // Assume 'dd/MM/yyyy' for anything else
            default:
                segments.month = splitDateArray[1];
                segments.day = splitDateArray[0];
                break;
        }
    }
    return segments;
}
function safeLocale(locale) {
    const shortLocale = locale.split(/-|_/)[0];
    const overrides = {
        no: 'nb'
    };
    return (overrides[shortLocale]) ? overrides[shortLocale] : locale;
}

function minValidator(min) {
    return {
        validate: (value) => {
            const valueAsNum = Number(value);
            const minAsNum = Number(min);
            if (isNaN(valueAsNum) || isNaN(minAsNum)) {
                return true;
            }
            return (valueAsNum < minAsNum) ? { min: { valid: false } } : undefined;
        }
    };
}

function maxValidator(max) {
    return {
        validate: (value) => {
            const valueAsNum = Number(value);
            const maxAsNum = Number(max);
            if (isNaN(valueAsNum) || isNaN(maxAsNum)) {
                return true;
            }
            return (valueAsNum > maxAsNum) ? { max: { valid: false } } : undefined;
        }
    };
}

var ValidatorsName;
(function (ValidatorsName) {
    ValidatorsName["min"] = "min";
    ValidatorsName["max"] = "max";
})(ValidatorsName || (ValidatorsName = {}));
function getValidator(list) {
    return (list || [])
        .map(v => {
        if (typeof v === 'string') {
            return validatorFactory(v, null);
        }
        else {
            return validatorFactory(v.name, v.options);
        }
    })
        .reduce(combineValidator, defaultValidator);
}
function combineValidator(v1, v2) {
    let combined;
    combined = { validate: (x) => {
            const res1 = v1.validate(x);
            const res2 = v2.validate(x);
            return Object.assign({}, res1, res2);
        } };
    return combined;
}
function validatorFactory(name, options) {
    switch (name) {
        case (ValidatorsName.max):
            return maxValidator(options.max);
        case (ValidatorsName.min):
            return minValidator(options.min);
        default:
            return defaultValidator;
    }
}
const defaultValidator = {
    validate: (_x) => null
};

let inputId = 0;
const DatePicker = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.calendarListener = ({ detail }) => this.handleCalendarSelection(detail);
        this.inputBlurListener = (e) => this.handleBlur(e);
        this.inputKeyListener = (e) => this.handleInputKey(e);
        this.toggleClickListener = () => this.open();
        this.overlayListener = () => this.close();
        /**
         * The date picker id
         */
        this.inputId = `'anj-date-picker-${inputId++}`;
        /**
         * How to align the overlay when it opens.
         * Options are `"bottom-end"` or `"bottom-start"` which is the default.
         */
        this.placement = 'bottom-end';
        this.anjDateChange = createEvent(this, "anjDateChange", 7);
        this.anjInputControlDidLoad = createEvent(this, "anjInputControlDidLoad", 7);
    }
    get date() {
        const date = (this.innerDateValue) ? new Date(this.innerDateValue) : new Date();
        return this.adapter.getCalendarDate(date, this.rangeParams);
    }
    injectedPropWatcher() {
        this.assignAdapter();
    }
    connectedCallback() {
        this.assignAdapter();
        this.input = this.element.parentElement;
        this.input.addEventListener('anjInput', this.inputKeyListener);
        this.input.addEventListener('anjBlur', this.inputBlurListener);
        this.connectToggle(this.input.querySelector('anj-date-picker-toggle'));
        this.configureValidationParameters();
    }
    componentDidLoad() {
        this.anjInputControlDidLoad.emit();
    }
    disconnectedCallback() {
        this.unbindCalendar();
        if (this.overlay) {
            this.overlay.removeEventListener('anjWillDismiss', this.overlayListener);
            this.overlay = null;
        }
        if (this.input) {
            this.input.removeEventListener('anjInput', this.inputKeyListener);
            this.input.removeEventListener('anjBlur', this.inputBlurListener);
        }
        const toggle = this.input.querySelector('anj-date-picker-toggle');
        if (toggle) {
            toggle.removeEventListener('click', this.toggleClickListener);
        }
    }
    /**
     * open the date picker
     */
    async open() {
        if (this.calendar)
            return;
        if (!this.overlay) {
            this.bindOverlay(this.element.querySelector('anj-overlay'));
        }
        this.bindCalendar();
        const popper = await this.overlay.popper();
        const d = this.innerDateValue || this.input.value;
        if (!popper) {
            this.configureValidationParameters();
            this.processInputValue(d ? d : '');
            this.calendar.monthMode = true;
            this.calendar.date = this.date;
            this.calendar.rangeParams = this.rangeParams;
            await this.overlay.open(this.element);
        }
        this.previouslyActiveElement = this.input.querySelector('anj-date-picker-toggle button');
        return this.calendar.focusControls();
    }
    /**
     * close the date picker
     */
    async close() {
        if (this.previouslyActiveElement) {
            await this.input.setFocus();
            this.previouslyActiveElement.focus();
            this.previouslyActiveElement = undefined;
        }
        await this.overlay.close();
        this.unbindCalendar();
    }
    /**
     * handle changes from the anj-input
     */
    processInputValue(inputValue) {
        this.innerDateValue = this.adapter.processDateInput(inputValue);
        this.outerValue = this.adapter.prepDateStringOutput(this.innerDateValue);
        if (inputValue) {
            this.anjDateChange.emit({ inner: this.adapter.convertToDate(this.innerDateValue), outer: this.outerValue });
        }
        else {
            this.anjDateChange.emit({});
        }
    }
    /**
     * handle changes from the angular directive
     */
    async setInputValue(inputValue) {
        const inputDate = (typeof inputValue === 'string') ? this.adapter.convertToDate(this.adapter.processDateInput(inputValue)) : this.adapter.processDateInput(inputValue);
        this.outerValue = this.adapter.prepDateStringOutput(inputDate);
        this.innerDateValue = this.adapter.processDateInput(this.outerValue);
        this.anjDateChange.emit({ inner: inputValue, outer: this.outerValue, refreshOuter: true });
    }
    /**
     * formatter, passed to anj-input, which supports conversion to short-date
     */
    inputFormatter(inputValue) {
        return Promise.resolve(this.adapter.prepDateStringOutput(inputValue));
    }
    /**
     * comparator, passed to anj-input, which compares two dates of various formats for parity
     */
    hasValueChanged(newVal, oldVal) {
        return Promise.resolve(this.adapter.prepDateStringOutput(newVal) !== this.adapter.prepDateStringOutput(oldVal));
    }
    async innerValue() {
        return this.innerDateValue;
    }
    // VALIDATION BLOCK
    async remoteCustomValidator(valueString) {
        const valueDate = this.adapter.processDateInput(valueString);
        return this.updateCustomValidity(valueDate);
    }
    configureValidationParameters() {
        this.rangeParams = {};
        if (this.input.min) {
            this.min = this.adapter.processDateInput(this.input.min);
            this.rangeParams.minDate = this.min;
        }
        if (this.input.max) {
            this.max = this.adapter.processDateInput(this.input.max);
            this.rangeParams.maxDate = this.max;
        }
        this.setCustomValidator();
    }
    setCustomValidator() {
        this.validator = getValidator([
            { name: 'min', options: { min: this.min } },
            { name: 'max', options: { max: this.max } }
        ]);
    }
    updateCustomValidity(value) {
        let response = {};
        if (this.validator) {
            response = this.validator.validate(value);
        }
        return response;
    }
    assignAdapter() {
        this.adapter = new DatePickerService(this.locale, this.language, this.timezoneOverride, this.dateFormat);
    }
    connectToggle(toggle) {
        if (toggle) {
            toggle.addEventListener('click', this.toggleClickListener);
        }
    }
    handleBlur({ target }) {
        if (target.tagName === 'ANJ-INPUT') {
            this.processInputValue(target.value);
        }
    }
    handleCalendarSelection(dateSelection) {
        this.innerDateValue = dateSelection;
        this.outerValue = this.adapter.localize(this.innerDateValue);
        this.input.value = this.outerValue;
        this.anjDateChange.emit({ inner: this.adapter.convertToDate(this.innerDateValue), outer: this.outerValue, refreshOuter: true });
        this.close();
    }
    handleInputKey({ target }) {
        this.processInputValue(target.value);
        this.input.checkValidity();
    }
    bindOverlay(el) {
        if (el) {
            this.overlay = el;
            this.overlay.addEventListener('anjWillDismiss', this.overlayListener);
        }
    }
    bindCalendar() {
        this.calendar = document.createElement('anj-calendar');
        this.overlay.appendChild(this.calendar);
        this.calendar.date = this.date;
        this.calendar.adapter = this.adapter;
        this.calendar.rangeParams = this.rangeParams;
        this.calendar.addEventListener('anjCalendarDaySelect', this.calendarListener);
    }
    unbindCalendar() {
        if (this.calendar) {
            this.calendar.removeEventListener('anjCalendarDaySelect', this.calendarListener);
            this.calendar.remove();
            this.calendar = null;
        }
    }
    render() {
        return (h("anj-overlay", { class: "anj-dropdown-menu anj-date-picker-menu", placement: this.placement, trapFocus: true }));
    }
    get element() { return getElement(this); }
    static get watchers() { return {
        "locale": ["injectedPropWatcher"],
        "language": ["injectedPropWatcher"],
        "timezoneOverride": ["injectedPropWatcher"],
        "dateFormat": ["injectedPropWatcher"]
    }; }
    static get style() { return "anj-date-picker{bottom:0;display:inline-block;position:absolute;right:0;-webkit-transition:z-index 1s .5s;transition:z-index 1s .5s;z-index:1}.anj-date-picker-menu{background-color:transparent;border:none;float:right;margin:0;padding:0}"; }
};
Tunnel.injectProps(DatePicker, ['locale', 'language', 'timezoneOverride', 'dateFormat']);

const Day = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.anjMouseOut = createEvent(this, "anjMouseOut", 7);
        this.anjMouseOver = createEvent(this, "anjMouseOver", 7);
        this.anjDaySelect = createEvent(this, "anjDaySelect", 7);
    }
    dayHandler() {
        this.evaluateDay();
    }
    componentWillLoad() {
        this.evaluateDay();
    }
    equalToDatePickerDay(date = this.adapter.newDateFromValue()) {
        return this.adapter.sameDay(this.day, date);
    }
    evaluateDay() {
        this.dayAsDate = this.adapter.newDateFromArray(this.day.year, this.day.month, this.day.day);
    }
    daySelectedHandler() {
        this.anjDaySelect.emit(this.day);
    }
    mouseOverHandler() {
        this.anjMouseOver.emit(this.day);
    }
    mouseOutHandler() {
        this.anjMouseOut.emit();
    }
    render() {
        const disabled = this.adapter.isDisabled(this.dayAsDate, this.rangeParams);
        const hostClasses = {
            'anj-selected': this.equalToDatePickerDay(this.date),
            'anj-diff-month': this.day.month !== this.month,
            'anj-today': this.equalToDatePickerDay(),
            'anj-disabled': disabled
        };
        return (h(Host, { class: hostClasses }, this.day.month === this.month ?
            h("button", { type: "button", disabled: disabled, onClick: () => this.daySelectedHandler(), onBlur: () => this.mouseOutHandler(), onMouseOver: () => this.mouseOverHandler(), onMouseOut: () => this.mouseOutHandler(), onFocus: () => this.mouseOverHandler() }, this.day.day) : this.day.day));
    }
    static get watchers() { return {
        "day": ["dayHandler"]
    }; }
    static get style() { return ".sc-anj-date-picker-day-h{border-radius:50%;color:var(--anj-neutral-dark);cursor:pointer;display:block;font-size:.75rem;line-height:1;text-align:center;-webkit-transition:background-color .2s ease;transition:background-color .2s ease;width:14.285%}.sc-anj-date-picker-day-h:hover{background-color:var(--anj-highlight-overlay)}.sc-anj-date-picker-day-h:focus-within{background-color:#bed6ec}.anj-today.sc-anj-date-picker-day-h{background-color:var(--anj-highlight-overlay);color:var(--anj-dark);font-weight:700}.anj-today.sc-anj-date-picker-day-h:hover{background-color:#bed6ec}.anj-today.sc-anj-date-picker-day-h:focus-within{background-color:#93badf}.anj-selected.sc-anj-date-picker-day-h{color:var(--anj-light)}.anj-selected.sc-anj-date-picker-day-h, .anj-selected.sc-anj-date-picker-day-h:hover{background:var(--anj-highlight)}.anj-disabled.sc-anj-date-picker-day-h{background-color:var(--anj-background);border-radius:0;color:var(--anj-neutral);cursor:not-allowed}.anj-diff-month.sc-anj-date-picker-day-h{cursor:default;opacity:0}.anj-today.anj-disabled.sc-anj-date-picker-day-h{color:var(--anj-neutral-dark)}.anj-selected.anj-disabled.sc-anj-date-picker-day-h{color:var(--anj-danger)}.sc-anj-date-picker-day-h button.sc-anj-date-picker-day{background-color:inherit;border:inherit;border-radius:50%;color:inherit;height:31.72px;padding:0;width:31.72px}.sc-anj-date-picker-day-h button.sc-anj-date-picker-day:focus{-webkit-box-shadow:none;box-shadow:none}"; }
};

const Month = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
    }
    render() {
        return h(Host, { class: { 'anj-selected': this.selected } }, h("button", { type: "button" }, this.month));
    }
    static get style() { return ".sc-anj-date-picker-month-h{border-radius:.25rem;color:var(--anj-neutral-dark);cursor:pointer;display:block;font-size:.75rem;line-height:1;text-align:center;-webkit-transition:background-color .2s ease;transition:background-color .2s ease;width:25%}.sc-anj-date-picker-month-h:hover{background-color:var(--anj-highlight-overlay)}.sc-anj-date-picker-month-h:focus-within{background-color:#bed6ec}.anj-today.sc-anj-date-picker-month-h{background-color:var(--anj-highlight-overlay);color:var(--anj-dark);font-weight:700}.anj-today.sc-anj-date-picker-month-h:hover{background-color:#bed6ec}.anj-today.sc-anj-date-picker-month-h:focus-within{background-color:#93badf}.anj-selected.sc-anj-date-picker-month-h{color:var(--anj-light)}.anj-selected.sc-anj-date-picker-month-h, .anj-selected.sc-anj-date-picker-month-h:hover{background:var(--anj-highlight)}.anj-disabled.sc-anj-date-picker-month-h{background-color:var(--anj-background);border-radius:0;color:var(--anj-neutral);cursor:not-allowed}.anj-diff-month.sc-anj-date-picker-month-h{cursor:default;opacity:0}.anj-today.anj-disabled.sc-anj-date-picker-month-h{color:var(--anj-neutral-dark)}.anj-selected.anj-disabled.sc-anj-date-picker-month-h{color:var(--anj-danger)}.sc-anj-date-picker-month-h button.sc-anj-date-picker-month{border-radius:.25rem;background-color:inherit;border:inherit;border-radius:50%;color:inherit;height:2.25rem;text-transform:uppercase}.sc-anj-date-picker-month-h button.sc-anj-date-picker-month:focus{-webkit-box-shadow:none;box-shadow:none}"; }
};

var AttributeTitles;
(function (AttributeTitles) {
    AttributeTitles["CHANGE_MONTH"] = "Change Month";
    AttributeTitles["PREV_MONTH"] = "Previous Month";
    AttributeTitles["TODAY"] = "Today";
    AttributeTitles["NEXT_MONTH"] = "Next Month";
})(AttributeTitles || (AttributeTitles = {}));
const MonthView = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.today = new Date();
        this.anjToggleMonthMode = createEvent(this, "anjToggleMonthMode", 7);
        this.anjMonthUpdated = createEvent(this, "anjMonthUpdated", 7);
        this.anjDaySelect = createEvent(this, "anjDaySelect", 7);
    }
    monthUpdateHandler(value) {
        this.anjMonthUpdated.emit(value);
    }
    modeChangeHandler(value) {
        this.anjToggleMonthMode.emit(value);
    }
    modeChangeText() {
        const month = this.package.months[this.package.month] || '';
        const year = this.package.year;
        return `${month.slice(0, 3)} ${year}`;
    }
    onToday() {
        this.anjDaySelect.emit({
            day: this.today.getDate(),
            month: this.package.adapter.month(this.today),
            year: this.package.adapter.year(this.today)
        });
    }
    render() {
        const todayDisabled = this.package.adapter.isDisabled(this.today, this.rangeParams);
        return [
            h("div", { class: "anj-calendar-top" }, h("anj-button", { context: "text", class: "anj-current", title: this.translator(AttributeTitles.CHANGE_MONTH), onClick: () => this.modeChangeHandler(false) }, h("span", null, this.modeChangeText()), h("anj-icon-opener", { slot: "end" })), h("div", { class: "anj-date-nav" }, h("anj-button", { context: "icon", title: this.translator(AttributeTitles.PREV_MONTH), "aria-label": this.translator(AttributeTitles.PREV_MONTH), onClick: () => this.monthUpdateHandler(-1) }, h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }))), h("anj-button", { context: "icon", disabled: todayDisabled, title: this.translator(AttributeTitles.TODAY), "aria-label": this.translator(AttributeTitles.TODAY), onClick: () => this.onToday() }, h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("circle", { cx: "12", cy: "12", r: "6" }))), h("anj-button", { context: "icon", title: this.translator(AttributeTitles.NEXT_MONTH), "aria-label": this.translator(AttributeTitles.NEXT_MONTH), onClick: () => this.monthUpdateHandler(1) }, h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }))))),
            h("div", { class: "anj-week-container" }, this.package.weekdays.map(label => h("span", null, label[0]))),
            h("div", { class: "anj-calendar-inner" }, this.package.days.map(day => h("anj-date-picker-day", { adapter: this.package.adapter, day: day, month: this.package.month, date: this.package.date, rangeParams: this.rangeParams })))
        ];
    }
    static get style() { return ".sc-anj-date-picker-month-view-h{display:block}.sc-anj-date-picker-month-view-h .anj-current.sc-anj-date-picker-month-view{--anj-link:--anj-text;margin-left:-.6rem;position:relative;top:2px}.sc-anj-date-picker-month-view-h .anj-date-nav.sc-anj-date-picker-month-view{margin-right:-.25rem}.sc-anj-date-picker-month-view-h .anj-calendar-top.sc-anj-date-picker-month-view{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;padding:.75rem 1.25rem}.sc-anj-date-picker-month-view-h .anj-calendar-top.sc-anj-date-picker-month-view .anj-current.sc-anj-date-picker-month-view{color:var(--anj-primary)}.sc-anj-date-picker-month-view-h anj-icon-opener.sc-anj-date-picker-month-view{margin-left:.25rem;position:relative;top:-2px}.sc-anj-date-picker-month-view-h .anj-calendar-inner.sc-anj-date-picker-month-view{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;padding:.5rem 1rem}.sc-anj-date-picker-month-view-h .anj-week-container.sc-anj-date-picker-month-view{display:-ms-flexbox;display:flex;font-size:.75rem;padding:0 1rem;width:100%}.sc-anj-date-picker-month-view-h .anj-week-container.sc-anj-date-picker-month-view span.sc-anj-date-picker-month-view{display:block;-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%;text-align:center;width:calc(100% / 7)}"; }
};
Tunnel.injectProps(MonthView, ['translator']);

const DatePickerToggle = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
    }
    render() {
        return (h(Host, { slot: "end" }, h("anj-button", { context: "free", "aria-label": "Toggle Date Picker" }, h("svg", { slot: "icon-only", viewBox: "0 0 24 24", height: "24px", width: "24px" }, h("path", { d: "M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z" })))));
    }
};

var AttributeTitles$1;
(function (AttributeTitles) {
    AttributeTitles["CHANGE_DAY"] = "Change Day";
    AttributeTitles["PREV_YEAR"] = "Previous Year";
    AttributeTitles["TODAY"] = "Today";
    AttributeTitles["NEXT_YEAR"] = "Next Year";
})(AttributeTitles$1 || (AttributeTitles$1 = {}));
const YearView = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.anjToggleMonthMode = createEvent(this, "anjToggleMonthMode", 7);
        this.anjMonthChanged = createEvent(this, "anjMonthChanged", 7);
        this.anjYearChanged = createEvent(this, "anjYearChanged", 7);
    }
    yearChangeHandler(year) {
        this.anjYearChanged.emit(year);
    }
    monthChangeHandler(value) {
        this.anjMonthChanged.emit(value);
    }
    modeChangeHandler(value) {
        this.anjToggleMonthMode.emit(value);
    }
    render() {
        return [
            h("div", { class: "anj-calendar-top" }, h("anj-button", { context: "text", class: "anj-current", title: this.translator(AttributeTitles$1.CHANGE_DAY), onClick: () => this.modeChangeHandler(true) }, h("span", null, this.package.year), h("anj-icon-opener", { slot: "end", open: true })), h("div", { class: "anj-date-nav" }, h("anj-button", { context: "icon", title: this.translator(AttributeTitles$1.PREV_YEAR), "aria-label": this.translator(AttributeTitles$1.PREV_YEAR), onClick: () => this.yearChangeHandler(-1) }, h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }))), h("anj-button", { context: "icon", title: this.translator(AttributeTitles$1.TODAY), "aria-label": this.translator(AttributeTitles$1.TODAY), onClick: () => this.modeChangeHandler(true) }, h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("circle", { cx: "12", cy: "12", r: "6" }))), h("anj-button", { context: "icon", title: this.translator(AttributeTitles$1.NEXT_YEAR), "aria-label": this.translator(AttributeTitles$1.NEXT_YEAR), onClick: () => this.yearChangeHandler(1) }, h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }))))),
            h("div", { class: "anj-calendar-inner" }, this.package.months.map((month, index) => h("anj-date-picker-month", { month: month, selected: this.package.month === index, onClick: () => this.monthChangeHandler(index) })))
        ];
    }
    static get style() { return ".sc-anj-date-picker-year-view-h{display:block}.sc-anj-date-picker-year-view-h .anj-current.sc-anj-date-picker-year-view{--anj-link:--anj-text;margin-left:-.6rem;position:relative;top:2px}.sc-anj-date-picker-year-view-h .anj-date-nav.sc-anj-date-picker-year-view{margin-right:-.25rem}.sc-anj-date-picker-year-view-h .anj-calendar-top.sc-anj-date-picker-year-view{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;padding:.75rem 1.25rem}.sc-anj-date-picker-year-view-h .anj-calendar-top.sc-anj-date-picker-year-view .anj-current.sc-anj-date-picker-year-view{color:var(--anj-primary)}.sc-anj-date-picker-year-view-h anj-icon-opener.sc-anj-date-picker-year-view{margin-left:.25rem;position:relative;top:-2px}.sc-anj-date-picker-year-view-h .anj-calendar-inner.sc-anj-date-picker-year-view{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;padding:.5rem 1rem;padding:0 .5rem .5rem}"; }
};
Tunnel.injectProps(YearView, ['translator']);

class TimePickerService {
    static getInputLabel(language, isMinutes) {
        const languageMap = {
            en: {
                'Minutes': 'Minutes',
                'Hour': 'Hour'
            },
            fr: {
                'Minutes': 'Minutes',
                'Hour': 'Heure'
            },
            de: {
                'Minutes': 'Minuten',
                'Hour': 'Stunde'
            },
            ja: {
                'Minutes': '分',
                'Hour': '時間'
            },
            es: {
                'Minutes': 'Minutos',
                'Hour': 'Hora'
            }
        };
        const languageKey = languageMap[language] || languageMap['en'];
        return languageKey[(isMinutes) ? 'Minutes' : 'Hour'];
    }
    // Convert input string to best-guess time format
    static parseTime(timeString) {
        if (timeString === '') {
            return null;
        }
        // Find hours/minutes in string
        const time = timeString.match(/(\d+)(:(\d\d))?\s*(p?)/i);
        if (time === null) {
            return null;
        }
        const hour = time[1];
        const minutes = time[3];
        if (!hour || !minutes) {
            return null;
        }
        // Find AM/PM in string, or default based on hour value
        const controlParse = timeString.match(/am|pm/gi);
        let control = (parseInt(hour, 10) > 12) ? 'PM' : 'AM';
        if (Array.isArray(controlParse)) {
            control = controlParse[0].toUpperCase();
        }
        return {
            hour,
            minutes,
            control
        };
    }
    static parseToTimeFields(input = '') {
        const time = TimePickerService.parseTime(input);
        const timeFields = {
            meridiem: {
                hour: '',
                minutes: '',
                control: ''
            },
            military: {
                hour: '',
                minutes: '',
                control: ''
            }
        };
        if (time) {
            const hours = parseInt(time.hour, 10);
            const minutes = time.minutes;
            timeFields.meridiem.hour = (hours > 12) ? TimePickerService.padZero((hours - 12)) : TimePickerService.padZero(hours);
            timeFields.meridiem.minutes = TimePickerService.padZero(minutes);
            timeFields.meridiem.control = time.control;
            timeFields.military.hour = (time.control === 'PM' && hours <= 12 && hours > 0)
                ? timeFields.military.hour = TimePickerService.padZero(hours + 12)
                : timeFields.military.hour = TimePickerService.padZero(time.hour);
            timeFields.military.minutes = TimePickerService.padZero(minutes);
        }
        return timeFields;
    }
    static padZero(inputString) {
        let transformedString = (inputString) ? inputString.toString() : '';
        if (transformedString.length === 1) {
            transformedString = `0${transformedString}`;
        }
        return transformedString;
    }
    static stringifyParsedTime(parsedTime, timezone) {
        if (!parsedTime) {
            return '';
        }
        const valueHour = parsedTime.hour || '12';
        const valueMinutes = parsedTime.minutes || '00';
        const valueControl = parsedTime.control || '';
        const timeString = `${valueHour}:${valueMinutes} ${valueControl}`.trim();
        return (timezone) ? timeString + ` (${timezone})` : timeString;
    }
}
class MeridiemTimeDisplay {
    constructor(locale, language) {
        this.locale = locale;
        this.language = language;
        this.language = this.language ? this.language : this.locale ? this.locale.split('-')[0] : 'en';
    }
    getInputLabel(isMinutes) {
        return TimePickerService.getInputLabel(this.language, isMinutes);
    }
    genPlaceHolder(parsedTime) {
        if (!parsedTime) {
            return 'hh:mm:am/pm';
        }
        const displayHour = parsedTime.hour || 'hh';
        const displayMinutes = parsedTime.minutes || 'mm';
        const displayControl = (parsedTime.control) ? ` ${parsedTime.control}` : ':am/pm';
        return `${displayHour}:${displayMinutes}${displayControl}`;
    }
    getRegex(isMinutes) {
        return (isMinutes) ? '^[0-5]?[0-9]$' : '^(0?[1-9]|1[012])$';
    }
    getHourRange() {
        return '1-12';
    }
    autoTab(value) {
        return !isNaN(value) && [0, 1].indexOf(value) === -1;
    }
    minmaxHandler(minmax) {
        const timeSegments = TimePickerService.parseToTimeFields(minmax)['military'];
        return {
            boundary: timeSegments.hour.concat(timeSegments.minutes)
        };
    }
    parseToTimeFields(input = '') {
        const parsedTime = TimePickerService.parseToTimeFields(input);
        return parsedTime.meridiem;
    }
    useControl() {
        return true;
    }
    stringifyParsedTime(parsedTime, timezone) {
        parsedTime.control = parsedTime.control || 'AM';
        return TimePickerService.stringifyParsedTime(parsedTime, timezone);
    }
}
class MilitaryTimeDisplay {
    constructor(locale, language) {
        this.locale = locale;
        this.language = language;
        this.language = this.language ? this.language : this.locale ? this.locale.split('-')[0] : 'en';
    }
    getInputLabel(isMinutes) {
        return TimePickerService.getInputLabel(this.language, isMinutes);
    }
    genPlaceHolder(parsedTime) {
        if (!parsedTime) {
            return 'hh:mm';
        }
        const displayHour = parsedTime.hour || 'hh';
        const displayMinutes = parsedTime.minutes || 'mm';
        return `${displayHour}:${displayMinutes}`;
    }
    getRegex(isMinutes) {
        return (isMinutes) ? '^[0-5]?[0-9]$' : '^([01]?[0-9]|2[0-3])$';
    }
    getHourRange() {
        return '0-23';
    }
    autoTab(value) {
        return !isNaN(value) && [0, 1, 2].indexOf(value) === -1;
    }
    minmaxHandler(minmax) {
        const timeSegments = TimePickerService.parseToTimeFields(minmax)['military'];
        return {
            boundary: timeSegments.hour.concat(timeSegments.minutes)
        };
    }
    parseToTimeFields(input = '') {
        const parsedTime = TimePickerService.parseToTimeFields(input);
        return parsedTime.military;
    }
    useControl() {
        return false;
    }
    stringifyParsedTime(parsedTime, timezone) {
        parsedTime.hour = parsedTime.hour || '00';
        return TimePickerService.stringifyParsedTime({ hour: parsedTime.hour, minutes: parsedTime.minutes }, timezone);
    }
}

class DatetimePickerService {
    static addTime(date, time) {
        if (!date) {
            return date;
        }
        const mins = (time.minutes) ? Number(time.minutes) : 0;
        let hrs = 0;
        if (time.hour && Number(time.hour) === 12) {
            hrs = (time.control && time.control === 'AM') ? 0 : Number(12);
        }
        else if (time.hour) {
            const controlOffset = (time.control && time.control === 'PM') ? 12 : 0;
            hrs = Number(time.hour) + controlOffset;
        }
        const adjustedDateTime = date.getTime() + (mins * 60000) + (hrs * 3600000);
        return new Date(adjustedDateTime);
    }
    static getNoTimeDate(date) {
        const d = new Date(date);
        d.setHours(0, 0, 0, 0);
        return d;
    }
    static localizeForOuterValue(date, locale, meridiem) {
        if (!date) {
            return undefined;
        }
        const options = { hour12: !!meridiem, month: '2-digit', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' };
        return new Intl.DateTimeFormat(locale, options).format(date);
    }
    // Brittle, but only effective way to uniformly derive time from an international string, because js
    static replacer(inputString) {
        /* tslint:disable:no-irregular-whitespace */
        // Identifies if am/pm in another language exists
        const amRegex = new RegExp('a..m.|午前');
        const pmRegex = new RegExp('p..m.|午後');
        const am = amRegex.test(inputString);
        const pm = pmRegex.test(inputString);
        const cleaned = inputString
            // remove anything that will make Date evaluation fail
            .replace(',', '')
            .replace('à', '')
            // remove language-specific am/pm notation
            .replace(amRegex, '')
            .replace(pmRegex, '');
        // Re-identify AM/PM appropriately
        if (am) {
            return cleaned.concat(' AM');
        }
        else if (pm) {
            return cleaned.concat(' PM');
        }
        else {
            return cleaned;
        }
    }
}

let inputId$1 = 0;
const DatetimePicker = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.clockListener = ({ detail }) => this.handleTimeChange(detail);
        this.calendarListener = ({ detail }) => this.handleDateChange(detail);
        this.inputBlurListener = (e) => this.handleBlur(e);
        this.overlayListener = () => this.close();
        this.toggleClickListener = () => this.open();
        /**
         * Bool to display time in meridiem or military
         */
        this.meridiem = true;
        /**
         * The date picker id
         */
        this.inputId = `anj-datetime-picker-${inputId$1++}`;
        /**
         * Passthrough, allows for targeted handling of nested overlays
         */
        this.nested = false;
        /**
         * How to align the overlay when it opens.
         * Options are `"bottom-end"` or `"bottom-start"` which is the default.
         */
        this.placement = 'bottom-end';
        this.anjDatetimeChange = createEvent(this, "anjDatetimeChange", 7);
        this.anjInputControlDidLoad = createEvent(this, "anjInputControlDidLoad", 7);
    }
    injectedPropWatcher() {
        this.assignAdapter();
    }
    meridiemHandler(value) {
        this.strategy = (value) ? new MeridiemTimeDisplay(this.locale, this.language) : new MilitaryTimeDisplay(this.locale, this.language);
    }
    async connectedCallback() {
        this.assignAdapter();
        this.input = this.element.parentElement;
        this.input.addEventListener('anjBlur', this.inputBlurListener);
        this.meridiemHandler(this.meridiem);
        this.connectToggle(this.input.querySelector('anj-datetime-picker-toggle'));
        this.configureValidationParameters();
    }
    componentDidLoad() {
        this.anjInputControlDidLoad.emit();
    }
    disconnectedCallback() {
        this.unbindCalendar();
        this.unbindClock();
        if (this.overlay) {
            this.overlay.removeEventListener('anjWillDismiss', this.overlayListener);
            this.overlay = null;
        }
        if (this.input) {
            this.input.removeEventListener('anjBlur', this.inputBlurListener);
        }
        const toggle = this.input.querySelector('anj-datetime-picker-toggle');
        if (toggle) {
            toggle.removeEventListener('click', this.toggleClickListener);
        }
    }
    /**
     * open the date picker
     */
    async open() {
        if (this.calendar)
            return;
        if (!this.overlay) {
            this.bindOverlay(this.element.querySelector('anj-overlay'));
        }
        this.bindClock();
        this.bindCalendar();
        const popper = await this.overlay.popper();
        if (!popper) {
            this.configureValidationParameters();
            this.setInputValue((this.input.value) ? this.input.value : '');
            this.calendar.monthMode = true;
            this.calendar.date = this.adapter.getCalendarDate(this.noTimeDate, this.rangeParams);
            this.calendar.rangeParams = this.rangeParams;
            this.clock.value = this.timeString;
            await this.overlay.open(this.element);
        }
        this.previouslyActiveElement = this.input.querySelector('anj-datetime-picker-toggle button');
        return this.calendar.focusControls();
    }
    /**
     * close the date picker
     */
    async close() {
        if (this.previouslyActiveElement) {
            this.previouslyActiveElement.focus();
            this.previouslyActiveElement = undefined;
        }
        if (await this.overlay.popper()) {
            this.anjDatetimeChange.emit({ inner: this.timeDate, outer: this.outerString, refreshOuter: true });
        }
        await this.overlay.close();
        this.unbindCalendar();
        this.unbindClock();
    }
    /**
     * handle changes from the angular directive
     */
    async setInputValue(inputValue) {
        if (!this.strategy) {
            this.strategy = (this.meridiem) ? new MeridiemTimeDisplay(this.locale, this.language) : new MilitaryTimeDisplay(this.locale, this.language);
        }
        const { shortDate, time } = (typeof inputValue === 'string')
            ? this.parseInputString(inputValue)
            : this.parseInputString(DatetimePickerService.localizeForOuterValue(inputValue, this.locale, this.meridiem));
        this.processTimeInput(time);
        this.timeDate = this.processDateInput(shortDate);
        this.noTimeDate = DatetimePickerService.getNoTimeDate(this.timeDate);
        this.outerString = DatetimePickerService.localizeForOuterValue(this.timeDate, this.locale, this.meridiem);
        if (inputValue) {
            this.anjDatetimeChange.emit({ inner: this.timeDate, outer: this.outerString, refreshOuter: true });
        }
        else {
            this.anjDatetimeChange.emit({ inner: null, outer: null, refreshOuter: true });
        }
    }
    /**
     * formatter, passed to anj-input, currently a pass-through
     */
    inputFormatter(inputValue) {
        return Promise.resolve(inputValue);
    }
    /**
     * comparator, passed to anj-input, which compares two datetime strings for parity
     */
    hasValueChanged(newVal, oldVal) {
        return Promise.resolve(newVal !== oldVal);
    }
    async innerValue() {
        return this.timeDate;
    }
    // VALIDATION BLOCK
    async remoteCustomValidator(valueString) {
        const valueDate = this.adapter.processDateInput(valueString);
        return this.updateCustomValidity(valueDate);
    }
    configureValidationParameters() {
        this.rangeParams = {};
        if (this.input.min) {
            this.min = this.adapter.processDateInput(this.input.min);
            this.rangeParams.minDate = this.min;
        }
        if (this.input.max) {
            this.max = this.adapter.processDateInput(this.input.max);
            this.rangeParams.maxDate = this.max;
        }
        this.setCustomValidator();
    }
    setCustomValidator() {
        this.validator = getValidator([
            { name: 'min', options: { min: this.min } },
            { name: 'max', options: { max: this.max } }
        ]);
    }
    updateCustomValidity(value) {
        let response = {};
        if (this.validator) {
            response = this.validator.validate(value);
        }
        return response;
    }
    assignAdapter() {
        this.adapter = new DatePickerService(this.locale, this.language, undefined, this.dateFormat);
    }
    // TOGGLE BLOCK
    connectToggle(toggle) {
        if (toggle) {
            toggle.addEventListener('click', this.toggleClickListener);
        }
    }
    // DATETIME BLOCK
    getDisplayMeridiem() {
        return (this.timeString) ? this.timeString.trim().split(' ')[1] : '';
    }
    getDisplayTime() {
        return (this.timeString) ? this.timeString.trim().split(' ')[0] : '';
    }
    handleBlur({ target }) {
        if (target.tagName === 'ANJ-INPUT') {
            this.setInputValue(target.value);
        }
    }
    handleDateChange(dateSelection) {
        this.noTimeDate = dateSelection;
        this.manageDateRepresentations();
    }
    handleTimeChange({ parsedValue }) {
        this.time = parsedValue;
        this.timeString = (this.time) ? ` ${this.strategy.stringifyParsedTime(this.time)}` : '';
        this.manageDateRepresentations();
    }
    manageDateRepresentations() {
        this.timeDate = DatetimePickerService.addTime(this.noTimeDate, this.time);
        this.outerString = DatetimePickerService.localizeForOuterValue(this.timeDate, this.locale, this.meridiem);
        this.input.value = this.outerString;
    }
    parseInputString(inputValue) {
        if (!inputValue) {
            inputValue = DatetimePickerService.localizeForOuterValue(new Date(), this.locale, this.meridiem);
        }
        const inputSplit = DatetimePickerService.replacer(inputValue.toString()).split(/ (.*)/).filter(Boolean);
        const shortDate = inputSplit[0];
        const time = inputSplit[1];
        return { shortDate, time };
    }
    processDateInput(shortDate) {
        const noTimeDate = this.adapter.processDateInput(shortDate);
        return DatetimePickerService.addTime(noTimeDate, this.time);
    }
    processTimeInput(time) {
        this.time = this.strategy.parseToTimeFields(new Date(`1/1/2007 ${time}`).toLocaleString(this.locale, { hour12: false, hour: '2-digit', minute: '2-digit' }));
        this.timeString = (this.time) ? ` ${this.strategy.stringifyParsedTime(this.time)}` : '';
    }
    bindOverlay(el) {
        if (el) {
            this.overlay = el;
            this.overlay.addEventListener('anjWillDismiss', this.overlayListener);
        }
    }
    bindCalendar() {
        this.calendar = document.createElement('anj-calendar');
        this.overlay.querySelector('.pickers-container').prepend(this.calendar);
        this.calendar.date = this.adapter.getCalendarDate(this.noTimeDate, this.rangeParams);
        this.calendar.adapter = this.adapter;
        this.calendar.rangeParams = this.rangeParams;
        this.calendar.addEventListener('anjCalendarDaySelect', this.calendarListener);
    }
    unbindCalendar() {
        if (this.calendar) {
            this.calendar.removeEventListener('anjCalendarDaySelect', this.calendarListener);
            this.calendar.remove();
            this.calendar = null;
        }
    }
    bindClock() {
        this.clock = document.createElement('anj-time-picker-clock');
        this.overlay.querySelector('.time-picker-container').append(this.clock);
        this.clock.context = 'vertical';
        this.clock.locale = this.locale;
        this.clock.meridiem = this.meridiem;
        this.clock.value = this.timeString;
        this.clock.addEventListener('anjTimeChanged', this.clockListener);
    }
    unbindClock() {
        if (this.clock) {
            this.clock.removeEventListener('anjTimeChanged', this.clockListener);
            this.clock.remove();
            this.clock = null;
        }
    }
    render() {
        return (h("anj-overlay", { class: "anj-datetime-picker-menu anj-dropdown-menu", placement: this.placement, nested: this.nested, trapFocus: true }, h("div", { class: "pickers-container" }, h("div", { class: "time-picker-container" }, h("div", { class: "anj-picker-header" }, h("p", { class: "anj-display-meridiem" }, this.getDisplayMeridiem()), h("p", { class: "anj-display-time" }, this.getDisplayTime()))))));
    }
    get element() { return getElement(this); }
    static get watchers() { return {
        "locale": ["injectedPropWatcher"],
        "language": ["injectedPropWatcher"],
        "dateFormat": ["injectedPropWatcher"],
        "meridiem": ["meridiemHandler"]
    }; }
    static get style() { return "anj-datetime-picker{bottom:0;display:inline-block;position:absolute;right:0;-webkit-transition:z-index 1s .5s;transition:z-index 1s .5s;z-index:1}.anj-datetime-picker-menu{background-color:transparent;border:none;float:right;margin:0;padding:0}.anj-datetime-picker-menu .pickers-container{display:-ms-flexbox;display:flex;background-color:var(--anj-light)}.anj-datetime-picker-menu .pickers-container anj-calendar{border-right:none;border-radius:.25rem 0 0 .25rem}.anj-datetime-picker-menu .pickers-container .time-picker-container{border:1px solid var(--anj-highlight);border-left:none;border-radius:0 .25rem .25rem 0}.anj-datetime-picker-menu .pickers-container .time-picker-container .anj-picker-header{background-color:var(--anj-primary);color:var(--anj-light);padding:.75rem 1rem}.anj-datetime-picker-menu .pickers-container .time-picker-container .anj-picker-header p{margin:0}.anj-datetime-picker-menu .pickers-container .time-picker-container .anj-picker-header .anj-display-meridiem{font-size:1.1rem;min-height:1.6rem}.anj-datetime-picker-menu .pickers-container .time-picker-container .anj-picker-header .anj-display-time{font-size:1rem;font-weight:200}"; }
};
Tunnel.injectProps(DatetimePicker, ['locale', 'language', 'dateFormat']);

const DatetimePickerToggle = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
    }
    render() {
        return (h(Host, { slot: "end" }, h("anj-button", { context: "free", "aria-label": "Toggle Date Time Picker" }, h("svg", { slot: "icon-only", viewBox: "0 0 24 24", height: "24px", width: "24px" }, h("path", { d: "M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z" })))));
    }
};

const List = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.content = '';
        this.hideLabels = false;
        this.value = [];
        this.anjChange = createEvent(this, "anjChange", 7);
        this.anjInvalid = createEvent(this, "anjInvalid", 7);
    }
    invalidWatcher(newVal) {
        this.anjInvalid.emit(newVal);
    }
    onBlur() {
        // Aids with inferred key tracking on the this.value iteration in render()
        this.value = this.value.slice(0);
    }
    onDrop({ detail, target }) {
        detail['targetIndex'] = (Number.isInteger(detail.targetIndex)) ? detail.targetIndex : target.index;
        const movingValue = this.value[detail.currentIndex];
        this.value.splice(detail.currentIndex, 1);
        this.value.splice(detail.targetIndex, 0, movingValue);
        this.value = this.value.slice(0);
    }
    onToolTipHover({ detail }) {
        clearTimeout(this.timer);
        this.content = this.translator(detail.action);
        this.popoverControl.display(detail.target);
    }
    onToolTipHoverEnd() {
        this.timer = window.setTimeout(() => {
            this.popoverControl.hide();
        }, 250);
    }
    onRowAdd({ detail }) {
        if (this.canAdd()) {
            this.value.splice(detail + 1, 0, null);
            this.value = this.value.slice(0);
        }
        this.emitListChange();
    }
    onRowRemove({ detail }) {
        if (this.canRemove()) {
            this.value.splice(detail, 1);
            this.value = this.value.slice(0);
        }
        this.emitListChange();
    }
    onItemChange({ detail }) {
        this.value.splice(detail.index, 1, detail.value);
        this.emitListChange();
    }
    componentWillLoad() {
        this.setArray();
    }
    emitListChange() {
        clearTimeout(this.debounceTimer);
        this.debounceTimer = window.setTimeout(() => {
            this.popoverControl.hide();
            this.anjChange.emit(this.value);
        }, 50);
    }
    canAdd() {
        return (!this.max || this.value.length < this.max);
    }
    canRemove() {
        return ((!this.min || this.value.length > this.min) && this.value.length > 1);
    }
    // Setup list at minimum required fields
    setArray() {
        const lessThanMin = (this.min) ? this.min - this.value.length : 0;
        const lessThanOne = 1 - this.value.length;
        if (lessThanMin > 0 || lessThanOne > 0) {
            for (let i = 0; i < Math.max(lessThanOne, lessThanMin); i++) {
                this.value.push(null);
            }
        }
    }
    render() {
        return [
            h("anj-form-group", { class: "anj-schema-list-label" }, (!this.hideLabels) ? h("anj-label", null, this.label) : undefined),
            this.value.map((item, index) => h("anj-list-item", { canAdd: this.canAdd(), canRemove: this.canRemove(), index: index, options: this.options, type: this.type, value: item })),
            h("anj-popover", { placement: "bottom", ref: r => this.popoverControl = r }, this.content)
        ];
    }
    static get watchers() { return {
        "invalid": ["invalidWatcher"]
    }; }
    static get style() { return "anj-list .anj-schema-list-label{margin-top:1rem}anj-list .list-item{display:-ms-flexbox;display:flex}anj-list .list-item .form-group{-ms-flex:1;flex:1}"; }
};
Tunnel.injectProps(List, ['translator']);

var ListTranslations;
(function (ListTranslations) {
    ListTranslations["ADD"] = "Add an item below";
    ListTranslations["REMOVE"] = "Remove this item";
})(ListTranslations || (ListTranslations = {}));

var ListItemTranslations;
(function (ListItemTranslations) {
    ListItemTranslations["DRAG_INSTRUCTION"] = "Draggable item. Press up or down to move.";
})(ListItemTranslations || (ListItemTranslations = {}));
const ListItem = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.handleFocused = false;
        this.hideLabels = false;
        this.anjDrop = createEvent(this, "anjDrop", 7);
        this.anjHover = createEvent(this, "anjHover", 7);
        this.anjHoverEnd = createEvent(this, "anjHoverEnd", 7);
        this.anjRowAdd = createEvent(this, "anjRowAdd", 7);
        this.anjRowRemove = createEvent(this, "anjRowRemove", 7);
        this.anjListItemChange = createEvent(this, "anjListItemChange", 7);
    }
    onBlur() {
        this.handleFocused = false;
    }
    onChange(event) {
        event.stopPropagation();
        this.anjListItemChange.emit({
            value: event.detail.innerValue || event.detail.value,
            index: this.index
        });
    }
    onFocus() {
        this.handleFocused = true;
    }
    connectedCallback() {
        this.dragController = new DragController(this.element, this.getDropData.bind(this));
        this.dropController = new DropController(this.element);
        this.dropController.connect();
    }
    disconnectedCallback() {
        this.dropController.disconnect();
    }
    addRow() {
        this.anjRowAdd.emit(this.index);
    }
    getDropData() {
        return {
            currentIndex: this.index
        };
    }
    handleHover({ target }, action) {
        this.anjHover.emit({ target, action });
    }
    handleHoverEnd() {
        this.anjHoverEnd.emit();
    }
    onKeydown(ev) {
        if (this.handleFocused && (ev.key === 'ArrowDown' || ev.key === 'ArrowUp')) {
            ev.preventDefault();
            const detail = this.getDropData();
            detail['targetIndex'] = (ev.key === 'ArrowDown') ? detail.currentIndex + 1 : detail.currentIndex - 1;
            if (detail['targetIndex'] < 0) {
                return;
            }
            this.anjDrop.emit(detail);
        }
    }
    removeRow() {
        this.anjRowRemove.emit(this.index);
    }
    renderInput() {
        switch (this.type) {
            case 'select':
                return (h("anj-select", { value: this.value }, this.options.map((option) => (h("anj-option", { value: option }, option)))));
            case 'number':
                return (h("anj-input", { value: this.value, type: "number" }, h("anj-number-stepper", null)));
            case 'text':
            default:
                return (h("anj-input", { value: this.value }));
        }
    }
    render() {
        return (h(Host, { draggable: this.handleFocused, class: { 'anj-handle-focused': this.handleFocused }, onMouseEnter: () => this.onFocus(), onMouseLeave: () => this.onBlur() }, h("anj-form-group", null, this.renderInput()), h("anj-button", { context: "icon", "aria-label": "Add", disabled: !this.canAdd, onClick: () => this.addRow(), onMouseEnter: (event) => this.handleHover(event, ListTranslations.ADD), onMouseLeave: () => this.handleHoverEnd() }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("path", { fill: "none", d: "M0 0h24v24H0V0z" }), h("path", { d: "M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" }))), h("anj-button", { context: "icon", "aria-label": "Remove", disabled: !this.canRemove, onClick: () => this.removeRow(), onMouseEnter: (event) => this.handleHover(event, ListTranslations.REMOVE), onMouseLeave: () => this.handleHoverEnd() }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("path", { fill: "none", d: "M0 0h24v24H0V0z" }), h("path", { d: "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM8 9h8v10H8V9zm7.5-5l-1-1h-5l-1 1H5v2h14V4h-3.5z" }))), h("anj-button", { "aria-label": this.translator(ListItemTranslations.DRAG_INSTRUCTION), context: "free", onMouseDown: () => this.dragController.connect(), onMouseUp: () => this.dragController.disconnect(), onKeyDown: (e) => this.onKeydown(e) }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("path", { d: "M20 9H4v2h16V9zM4 15h16v-2H4v2z" })))));
    }
    get element() { return getElement(this); }
    static get style() { return "anj-list-item{display:-ms-flexbox;display:flex}anj-list-item.anj-handle-focused anj-button[context=free],anj-list-item:hover anj-button[context=free]{opacity:1}anj-list-item anj-button[context=free]{opacity:0}anj-list-item anj-form-group{width:200px}"; }
};
Tunnel.injectProps(ListItem, ['translator']);

let inputId$2 = 0;
const TimePicker = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.clockListener = ({ detail }) => this.valueChangeHandler(detail);
        this.overlayListener = () => this.close();
        this.toggleClickListener = () => this.open();
        /**
         * The time picker id
         */
        this.inputId = `anj-time-picker-${inputId$2++}`;
        /**
         * Bool to display time in meridiem or military
         */
        this.meridiem = true;
        /**
         * How to align the overlay when it opens.
         * Options are `"bottom-end"` or `"bottom-start"` which is the default.
         */
        this.placement = 'bottom-end';
        this.anjClockSelection = createEvent(this, "anjClockSelection", 7);
        this.anjInputControlDidLoad = createEvent(this, "anjInputControlDidLoad", 7);
    }
    injectedPropWatcher() {
        this.assignStrategy();
    }
    valueHandler(newValue, oldValue) {
        if (newValue !== oldValue) {
            this.updateCustomValidity(newValue);
        }
    }
    connectedCallback() {
        this.input = this.element.parentElement;
        this.assignStrategy();
        this.connectToggle(this.input.querySelector('anj-time-picker-toggle'));
        this.setValues(this.input.value);
        this.configureValidationParameters();
    }
    componentDidLoad() {
        this.anjInputControlDidLoad.emit();
    }
    disconnectedCallback() {
        if (this.overlay) {
            this.overlay.removeEventListener('anjWillDismiss', this.overlayListener);
            this.overlay = null;
        }
        if (this.clock) {
            this.clock.removeEventListener('anjTimeChanged', this.clockListener);
            this.clock = null;
        }
        const toggle = this.input.querySelector('anj-time-picker-toggle');
        if (toggle) {
            toggle.removeEventListener('click', this.toggleClickListener);
        }
    }
    /**
     * open the time picker
     */
    async open() {
        if (!this.overlay) {
            this.bindOverlay(this.element.querySelector('anj-overlay'));
            this.bindClock(this.element.querySelector('anj-time-picker-clock'));
        }
        const popper = await this.overlay.popper();
        if (!popper) {
            this.configureValidationParameters();
            await this.overlay.open(this.element);
            setTimeout(() => this.clock.focusHour(), 100);
        }
        this.setValues(this.input.value);
    }
    /**
     * close the time picker
     */
    async close() {
        await this.overlay.close();
        this.updateInputValue();
    }
    /**
     * formatter, passed to anj-input, currently a pass-through
     */
    inputFormatter(inputValue) {
        this.input.placeholder = this.strategy.genPlaceHolder(null);
        return Promise.resolve(inputValue);
    }
    /**
     * comparator, passed to anj-input, which compares two time strings for parity
     */
    hasValueChanged(newVal, oldVal) {
        this.input.placeholder = this.strategy.genPlaceHolder(null);
        return Promise.resolve(newVal !== oldVal);
    }
    async innerValue() {
        return this.value;
    }
    async remoteCustomValidator(valueString) {
        const militaryTimeSegments = TimePickerService.parseToTimeFields(valueString)['military'];
        const valueAsNum = militaryTimeSegments.hour.concat(militaryTimeSegments.minutes);
        return this.updateCustomValidity(valueAsNum);
    }
    assignStrategy() {
        this.strategy = (this.meridiem) ? new MeridiemTimeDisplay(this.locale, this.language) : new MilitaryTimeDisplay(this.locale, this.language);
    }
    configureValidationParameters() {
        if (this.input.min) {
            const { boundary } = this.strategy.minmaxHandler(this.input.min);
            this.min = boundary;
        }
        if (this.input.max) {
            const { boundary } = this.strategy.minmaxHandler(this.input.max);
            this.max = boundary;
        }
        this.setCustomValidator();
    }
    connectToggle(toggle) {
        if (toggle) {
            toggle.addEventListener('click', this.toggleClickListener);
        }
    }
    setCustomValidator() {
        this.validator = getValidator([
            { name: 'min', options: { min: this.min } },
            { name: 'max', options: { max: this.max } }
        ]);
    }
    setValues(value) {
        if (value && value === '') {
            this.value = undefined;
        }
        else if (value) {
            this.value = value.toString();
        }
    }
    updateCustomValidity(value) {
        let response = {};
        if (this.validator) {
            response = this.validator.validate(value);
        }
        return response;
    }
    updateInputValue() {
        this.input.value = (this.value) ? this.value : '';
        this.anjClockSelection.emit(this.value);
    }
    valueChangeHandler({ parsedValue }) {
        this.input.placeholder = this.strategy.genPlaceHolder(parsedValue);
        if (parsedValue && parsedValue.hour && parsedValue.minutes) {
            this.value = this.strategy.stringifyParsedTime(parsedValue, this.timezone);
        }
    }
    bindOverlay(el) {
        if (el) {
            this.overlay = el;
            this.overlay.addEventListener('anjWillDismiss', this.overlayListener);
        }
    }
    bindClock(el) {
        if (el) {
            this.clock = el;
            this.clock.addEventListener('anjTimeChanged', this.clockListener);
        }
    }
    render() {
        const overlayClasses = this.meridiem ? 'anj-time-picker-menu anj-dropdown-menu' : 'anj-time-picker-menu anj-dropdown-menu anj-no-control';
        return (h("anj-overlay", { class: overlayClasses, placement: this.placement }, h("anj-time-picker-clock", { context: 'horizontal', locale: this.locale, language: this.language, meridiem: this.meridiem, value: this.value })));
    }
    get element() { return getElement(this); }
    static get watchers() { return {
        "locale": ["injectedPropWatcher"],
        "language": ["injectedPropWatcher"],
        "value": ["valueHandler"]
    }; }
    static get style() { return "anj-time-picker{bottom:0}.anj-time-picker-menu,anj-time-picker{display:block;position:absolute;right:0}.anj-time-picker-menu{font-size:.875rem;font-family:var(--anj-font-family);font-weight:400;line-height:1.5;outline:none;border-top:solid var(--anj-highlight) 1px;float:right;margin:0;min-width:0!important;max-width:250px;padding:0;top:0}.anj-time-picker-menu,.anj-time-picker-menu:after,.anj-time-picker-menu:before{-webkit-box-sizing:border-box;box-sizing:border-box;outline:none}.anj-time-picker-menu:active,.anj-time-picker-menu :active,.anj-time-picker-menu:focus,.anj-time-picker-menu :focus{outline:none}.anj-time-picker-menu.anj-no-control{width:175px}"; }
};
Tunnel.injectProps(TimePicker, ['locale', 'language']);

const TimePickerClock = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.meridiemOptions = [
            { label: '-', value: '' },
            { label: 'AM', value: 'AM' },
            { label: 'PM', value: 'PM' }
        ];
        this.parsedTime = { hour: '', minutes: '', control: '' };
        this.context = 'horizontal';
        /**
         * Bool to display time in meridiem or military
         */
        this.meridiem = true;
        this.anjTimeChanged = createEvent(this, "anjTimeChanged", 7);
    }
    injectedPropWatcher() {
        this.assignStrategy();
    }
    valueHandler(newValue) {
        this.parseTime(newValue);
    }
    // Prevent the events from bubbling up to the parent form group
    onFormElementLoaded(event) {
        event.stopPropagation();
    }
    componentWillLoad() {
        this.assignStrategy();
        this.parseTime(this.value);
    }
    /**
     * Blur from our child inputs will propogate value
     */
    onAnjBlur() {
        this.anjTimeChanged.emit({ parsedValue: this.parsedTime });
    }
    /**
     * Listens for hour update.
     */
    onAnjHourChange(event) {
        this.parsedTime.hour = event.detail;
    }
    /**
     * Listens for hour autotab instruction.
     */
    onAnjHourTab() {
        this.minInput.focusNativeInput();
    }
    /**
     * Listens for hour update.
     */
    onAnjMinuteChange(event) {
        this.parsedTime.minutes = event.detail;
    }
    async focusHour() {
        this.hourInput.focusNativeInput();
    }
    assignStrategy() {
        this.strategy = (this.meridiem) ? new MeridiemTimeDisplay(this.locale, this.language) : new MilitaryTimeDisplay(this.locale, this.language);
    }
    controlSelected(event) {
        this.parsedTime.control = event.detail.value;
        this.anjTimeChanged.emit({ parsedValue: this.parsedTime });
    }
    parseTime(value) {
        this.parsedTime = this.strategy.parseToTimeFields(value);
    }
    render() {
        return (h("div", { class: (this.strategy.useControl()) ? 'anj-time-picker' : 'anj-time-picker anj-no-control' }, h("div", { class: "anj-time-controls" }, h("div", { class: "anj-time-block" }, h("anj-time-picker-input", { strategy: this.strategy, value: this.parsedTime.hour, ref: r => this.hourInput = r })), h("div", { class: "anj-time-block" }, h("anj-time-picker-input", { strategy: this.strategy, minutes: true, value: this.parsedTime.minutes, ref: r => this.minInput = r })), (this.strategy.useControl()) ?
            h("div", { class: "anj-time-block" }, h("anj-form-group", { class: "anj-meridian" }, h("anj-label", null, "AM/PM"), h("anj-select", { onAnjChange: e => this.controlSelected(e), value: this.parsedTime.control }, this.meridiemOptions.map(option => h("anj-option", { value: option.value }, option.label)))))
            : undefined)));
    }
    static get watchers() { return {
        "locale": ["injectedPropWatcher"],
        "language": ["injectedPropWatcher"],
        "value": ["valueHandler"]
    }; }
    static get style() { return "[context=horizontal].sc-anj-time-picker-clock-h .anj-time-picker.sc-anj-time-picker-clock{width:250px}[context=horizontal].sc-anj-time-picker-clock-h .anj-time-picker.anj-no-control.sc-anj-time-picker-clock{width:175px}[context=horizontal].sc-anj-time-picker-clock-h .anj-time-picker.sc-anj-time-picker-clock .anj-meridian.sc-anj-time-picker-clock{width:65px}[context=horizontal].sc-anj-time-picker-clock-h .anj-time-controls.sc-anj-time-picker-clock{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}[context=vertical].sc-anj-time-picker-clock-h .anj-time-controls.sc-anj-time-picker-clock{display:block;-ms-flex-wrap:nowrap;flex-wrap:nowrap;width:105px}.sc-anj-time-picker-clock-h .anj-time-block.sc-anj-time-picker-clock{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;margin-top:1rem;max-width:100%;padding:0 15px}"; }
};

const TimePickerInput = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.minutes = false;
        this.anjHourChanged = createEvent(this, "anjHourChanged", 7);
        this.anjHourTab = createEvent(this, "anjHourTab", 7);
        this.anjMinuteChanged = createEvent(this, "anjMinuteChanged", 7);
    }
    strategyWatcher() {
        this.assignLabel();
    }
    valueHandler(newValue) {
        this.digits = TimePickerService.padZero(newValue);
    }
    /**
     * Listens for input blur.
     */
    onAnjBlur() {
        this.debounceErrors();
        (this.minutes) ? this.minuteChangedHandler(this.digits) : this.hourChangedHandler(this.digits);
    }
    /**
     * Listens for input update.
     */
    onAnjInput(event) {
        this.digits = TimePickerService.padZero(event.detail.target.value);
        this.checkTab();
    }
    /**
     * Listens for child input focus, then highlights all input text
     * Typically used when an autotab is forced from the hour input to the minute input, to select all minute input text
     */
    onAnjFocus(event) {
        setTimeout(() => {
            const anjInput = event.target;
            anjInput.firstElementChild.select();
        }, 100);
    }
    /**
     * Allows input focus to be set from an external source
     * Typically used when opening the picker to set the focus to the hour input
     */
    async focusNativeInput() {
        this.input.setFocus();
    }
    componentWillLoad() {
        this.digits = TimePickerService.padZero(this.value);
        this.assignLabel();
        this.placeholderText = (this.minutes) ? 'mm' : 'hh';
        this.regexPattern = this.strategy.getRegex(this.minutes);
    }
    componentDidUpdate() {
        this.selectInput();
    }
    assignLabel() {
        this.label = this.strategy.getInputLabel(this.minutes);
    }
    checkTab() {
        const numDigits = Number(this.digits);
        if (!this.minutes && this.strategy.autoTab(numDigits)) {
            this.anjHourTab.emit();
        }
    }
    displayErrors(invalid) {
        const errorMessage = (this.minutes) ? `(1-59)` : `(${this.strategy.getHourRange()})`;
        this.displayError = (invalid) ? errorMessage : '';
    }
    debounceErrors() {
        window.clearTimeout(this.errorsTimer);
        this.errorsTimer = window.setTimeout(() => {
            this.displayErrors(this.input.invalid);
        }, 100);
    }
    minuteChangedHandler(val) {
        this.anjMinuteChanged.emit(val);
    }
    hourChangedHandler(val) {
        this.anjHourChanged.emit(val);
    }
    selectInput() {
        const nativeInput = this.input.firstElementChild;
        if (this.element.firstElementChild.classList.contains('anj-focused')) {
            nativeInput.select();
        }
    }
    render() {
        return (h("anj-form-group", null, h("anj-label", null, this.label), h("anj-input", { ref: r => this.input = r, value: this.digits, pattern: this.regexPattern, placeholder: this.placeholderText, minlength: 1, maxlength: 2, type: "text" }), h("anj-form-error", null, this.displayError)));
    }
    get element() { return getElement(this); }
    static get watchers() { return {
        "strategy": ["strategyWatcher"],
        "value": ["valueHandler"]
    }; }
};

const TimePickerToggle = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
    }
    render() {
        return (h(Host, { slot: "end" }, h("anj-button", { context: "free", "aria-label": "Toggle Time Picker" }, h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" }, h("path", { "fill-opacity": ".9", d: "M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zM12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z" })))));
    }
};

export { Calendar as anj_calendar, DatePicker as anj_date_picker, Day as anj_date_picker_day, Month as anj_date_picker_month, MonthView as anj_date_picker_month_view, DatePickerToggle as anj_date_picker_toggle, YearView as anj_date_picker_year_view, DatetimePicker as anj_datetime_picker, DatetimePickerToggle as anj_datetime_picker_toggle, List as anj_list, ListItem as anj_list_item, TimePicker as anj_time_picker, TimePickerClock as anj_time_picker_clock, TimePickerInput as anj_time_picker_input, TimePickerToggle as anj_time_picker_toggle };
