import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
import { _ as __decorate, a as __metadata } from './tslib.es6.js';
import { a as ariaBooleanToString } from './aria.js';
import { i as inheritAttributes } from './attributes.js';
import { B as BEM } from './bem.js';
import { d as defaultBalAriaForm } from './form.js';
import { h as hasValueChanged, i as inputSetFocus, a as inputSetBlur } from './form-input.js';
import { u as hasParent } from './helpers.js';
import { L as Logger } from './log.js';
import { N as NUMBER_KEYS } from './keys.constant.js';
import { I as INVALID_VALUE } from './mask-util.js';
import { d as dateSeparator, B as BalDate } from './date.js';
import { L as ListenToConfig } from './config.decorator.js';

class MaskPosition {
    constructor(_options) {
        this._options = _options;
        this._position = 0;
        this._positionEnd = 0;
        this._isRangeSelection = false;
        if (_options.component && _options.component.nativeInput) {
            this._position = _options.component.nativeInput.selectionStart || 0;
            this._positionEnd = _options.component.nativeInput.selectionEnd || 0;
            this._isRangeSelection = this._position !== this._positionEnd;
        }
    }
    get isRangeSelection() {
        return this._isRangeSelection;
    }
    get value() {
        if (this._options.isBackspace && this._position > 0) {
            return this._position - 1;
        }
        return this._position;
    }
    set value(index) {
        const validatedIndex = index < 0 ? 0 : index > this._options.mask.maxLength ? this._options.mask.maxLength : index;
        this._position = validatedIndex;
    }
    toStart() {
        this.value = 0;
    }
    toEnd() {
        const target = this.getTarget();
        if (target) {
            this.value = target.value.length;
        }
    }
    next(next = 1) {
        const newPosition = this._position + next;
        if (newPosition <= this._options.mask.maxLength) {
            this._position = newPosition;
        }
        return this._position;
    }
    previous(previous = 1) {
        const newPosition = this._position - previous;
        if (newPosition >= 0) {
            this._position = newPosition;
        }
        else {
            this._position = 0;
        }
        return this._position;
    }
    submit() {
        const target = this.getTarget();
        if (target && target.selectionStart !== this._position && target.selectionEnd !== this._position) {
            target.selectionStart = this._position;
            target.selectionEnd = this._position;
        }
    }
    getTarget() {
        if (this._options.component && this._options.component.nativeInput) {
            return this._options.component.nativeInput;
        }
        return undefined;
    }
}

class MaskContext {
    constructor(_options) {
        this._options = _options;
        this._value = '';
        if (this._options.component && this._options.component.nativeInput) {
            this._value = this._options.component.nativeInput.value;
        }
        this.position = new MaskPosition(this._options);
        this.component = this._options.component;
    }
    get target() {
        if (this._options.component && this._options.component.nativeInput) {
            return this._options.component.nativeInput;
        }
        return undefined;
    }
    get value() {
        return this._value;
    }
    set value(newValue) {
        this._value = newValue;
    }
    get focused() {
        return this._options.component.focused;
    }
    isValueEmpty() {
        return this.value === '' || this.value === undefined || this.value === null;
    }
    preventDefault() {
        if (this._options.event.preventDefault) {
            this._options.event.preventDefault();
        }
    }
    stopPropagation() {
        this.preventDefault();
        if (this._options.event.stopPropagation) {
            this._options.event.stopPropagation();
        }
    }
    async submit(eventType = 'input', parsedValue) {
        if (this.target) {
            this.target.value = this.value;
            if (eventType !== 'blur' && eventType !== 'tab') {
                this.position.submit();
            }
            if (this._options.component) {
                if (eventType === 'input' || eventType === 'tab') {
                    this._options.component.balInput.emit(this.value);
                }
                if ((eventType === 'change' || eventType === 'blur') && parsedValue !== undefined) {
                    if (hasValueChanged(this._options.component.value, parsedValue)) {
                        this._options.component.value = parsedValue;
                        this._options.component.balChange.emit(parsedValue);
                    }
                }
            }
        }
    }
}

class MaskClipboardContext extends MaskContext {
    get clipboardData() {
        var _a;
        return (_a = this._options.event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text');
    }
}

class MaskFocusContext extends MaskContext {
}

class MaskKeyboardContext extends MaskContext {
    get key() {
        return this._options.event.key;
    }
    get isCtrlOrCommandKey() {
        return this._options.event.metaKey || this._options.event.ctrlKey;
    }
    get isBackspaceKey() {
        return this._options.event.key === 'Backspace';
    }
    get isTabKey() {
        return this._options.event.key === 'Tab';
    }
    get isWhiteSpaceKey() {
        return this._options.event.key === ' ';
    }
    get isDeleteKey() {
        return this._options.event.key === 'Delete' || this._options.event.key === 'Del';
    }
    get isNumberKey() {
        return MaskKeyboardContext.NUMBER_KEYS.includes(this._options.event.key);
    }
    get isNavigationKey() {
        return MaskKeyboardContext.NAVIGATION_KEYS.includes(this._options.event.key);
    }
    get isSelectAllCommand() {
        return (this._options.event.ctrlKey || this._options.event.metaKey) && this.key === 'a';
    }
    get isCopyCommand() {
        return (this._options.event.ctrlKey || this._options.event.metaKey) && this.key === 'c';
    }
    get isPasteCommand() {
        return (this._options.event.ctrlKey || this._options.event.metaKey) && this.key === 'v';
    }
    getCharAt(position = this.position.value) {
        return this.value.charAt(position);
    }
    getCharAtBackspacePosition() {
        return this.getCharAt(this.position.value - 1);
    }
    setChar(char = this._options.event.key, position = this.position.value) {
        this.value = this.value.substring(0, position) + char + this.value.substring(position + 1);
    }
}
MaskKeyboardContext.NUMBER_KEYS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
MaskKeyboardContext.NAVIGATION_KEYS = [
    'Home',
    'End',
    'ArrowLeft',
    'Left',
    'ArrowRight',
    'Right',
    'Tab',
    'Enter',
    'Esc',
    'Escape',
];

class MaskLocaleContext extends MaskContext {
    get locale() {
        return this._options.event.locale;
    }
}

class MaskMouseContext extends MaskContext {
}

class MaskValueChangedContext extends MaskContext {
    get newValue() {
        return this._options.event.newValue;
    }
    get oldValue() {
        return this._options.event.oldValue;
    }
    get didValueChange() {
        return this.newValue !== this.oldValue;
    }
}

class MaskBlock {
    constructor(option) {
        this._isSeparator = false;
        this._allowedKeys = [];
        this._locale = 'de-CH';
        this._from = option.from || 0;
        this._to = option.to || 0;
        this._isSeparator = option.isSeparator === undefined ? false : option.isSeparator;
        this._mask = option.mask || '_';
        this._allowedKeys = option.allowedKeys ? option.allowedKeys : this.allowedKeys;
        this._format = option.format;
    }
    format(value) {
        if (this._format) {
            return this._format(value.replace(this.mask, ''), this._locale, this.mask);
        }
        return value;
    }
    get isSeparator() {
        return this._isSeparator;
    }
    get to() {
        return this._to;
    }
    get from() {
        return this._from;
    }
    get mask() {
        if (typeof this._mask === 'function') {
            return this._mask(this._locale);
        }
        return this._mask;
    }
    get allowedKeys() {
        return this._allowedKeys;
    }
    onI18nChange(locale) {
        this._locale = locale;
    }
    getValueOfTheBlock(value) {
        return value.slice(this._from, this._to);
    }
    isTouched(value) {
        const blockValue = this.getValueOfTheBlock(value);
        return !blockValue.split('').every(char => char === this.mask);
    }
    verifyAllowedKeyHits(key) {
        if (this.isSeparator && key === this.mask) {
            return true;
        }
        else if (this.allowedKeys.indexOf(key) >= 0) {
            return true;
        }
        else {
            // context.stopPropagation()
            return false;
        }
    }
}

class MaskBlockList {
    constructor(_list = []) {
        this._list = _list;
    }
    get lastPosition() {
        return this._list[this._list.length - 1].to;
    }
    get list() {
        return this._list;
    }
    set list(list) {
        this._list = list;
    }
    clone() {
        return new MaskBlockList([...this._list]);
    }
    findByIndex(index, blocks = this.list) {
        return blocks.find(block => block.from <= index && index < block.to);
    }
    getPlaceholderMask() {
        const placeholder = [];
        this.list.forEach(block => {
            const length = block.to - block.from;
            for (let index = 0; index < length; index++) {
                placeholder.push(block.mask);
            }
        });
        return placeholder.join('');
    }
    getRawValueWithoutMaskByContext(context) {
        return this.getRawValueWithoutMask(context.value);
    }
    getRawValueWithoutMask(value) {
        if (value) {
            let rawValue = [];
            const chars = value.split('');
            for (let index = 0; index < chars.length; index++) {
                const char = chars[index];
                const block = this.findByIndex(index);
                if (block && !block.isSeparator) {
                    rawValue.push(char.replace(block.mask, ''));
                }
                else {
                    rawValue.push(char);
                }
            }
            rawValue = rawValue.filter(v => v);
            const amountSeparators = this.list.filter(block => block.isSeparator).length;
            if (amountSeparators === rawValue.length) {
                return '';
            }
            return rawValue.join('');
        }
        return '';
    }
    formatBlocks(value, activeBlockIndex) {
        let newValue = `${value}`;
        for (let index = 0; index < this.list.length; index++) {
            const block = this.list[index];
            if (activeBlockIndex !== index && !block.isSeparator && block.isTouched(newValue)) {
                const blockValue = block.getValueOfTheBlock(newValue);
                const newBlockValue = block.format(blockValue);
                newValue = newValue.substring(0, block.from) + newBlockValue + newValue.substring(block.to);
            }
        }
        return newValue;
    }
    getBlockIndexFromPosition(position) {
        const length = this.list.reduce((acc, block) => acc + block.to - block.from, 0);
        if (position === length) {
            return this.list.length - 1;
        }
        const index = this.list.findIndex(block => block.from <= position && position < block.to);
        return index < 0 ? undefined : Math.min(length, index);
    }
    verifyCallOfNextSeparator(key, index) {
        if (this.list.length - 1 > index) {
            const nextBlock = this.list[index + 1];
            if (nextBlock.isSeparator && nextBlock.mask === key) {
                return true;
            }
        }
        return false;
    }
}

class AbstractMask {
    constructor(blocks = []) {
        this.inputMode = 'text';
        this.locale = 'de-CH';
        this.blocks = new MaskBlockList(blocks);
    }
    /**
     * ABSTRACT EVENT METHODS
     * ------------------------------------------------------
     */
    onLocaleChange(context, _oldLocale, oldBlocks) {
        if (context.target) {
            const value = context.value;
            const chars = value.split('');
            for (let index = 0; index < chars.length; index++) {
                const char = chars[index];
                const newBlock = this.blocks.findByIndex(index);
                const oldBlock = oldBlocks.findByIndex(index);
                if (newBlock && oldBlock) {
                    if (newBlock.isSeparator) {
                        chars[index] = newBlock.mask;
                    }
                    else if (char === oldBlock.mask) {
                        chars[index] = newBlock.mask;
                    }
                }
            }
            context.value = chars.join('');
        }
    }
    onFocus(_context) {
        // empty placeholder
    }
    onBlur(_context) {
        // empty placeholder
    }
    onChange(context) {
        context.submit('change', this.onParseValue(context.value));
    }
    onNavigationDown(_context, _block, _index) {
        // empty placeholder
    }
    onSelectAll(_context, _block, _index) {
        // empty placeholder
    }
    onPaste(context, _block, _index) {
        const value = context.clipboardData || '';
        context.value = value;
        context.position.toEnd();
    }
    onBlockChange(context, block, index) {
        context.setChar();
        context.position.next();
        const nextBlock = this.blocks.list[index + 1];
        if (context.position.value === block.to && nextBlock && nextBlock.isSeparator) {
            context.position.next();
        }
    }
    onBackspaceDown(context, block, index) {
        context.position.previous();
        if (!block.isSeparator) {
            context.setChar(block.mask);
            const previousBlock = this.blocks.list[index - 1];
            if (context.position.value === block.from && previousBlock && previousBlock.isSeparator) {
                context.position.previous();
            }
        }
    }
    onDeleteDown(context, block, index) {
        context.setChar(block.mask);
        context.position.next();
        const nextBlock = this.blocks.list[index + 1];
        if (context.position.value === block.to && nextBlock && nextBlock.isSeparator) {
            context.position.next();
        }
    }
    onValueChanged(context) {
        const formattedValue = this.onFormatValue(context.newValue);
        const inputValue = context.focused && formattedValue === '' ? this.blocks.getPlaceholderMask() : formattedValue;
        context.value = inputValue;
        context.position.toEnd();
    }
    onParseValue(inputValue, options = { allowInvalidValue: false }) {
        if (inputValue) {
            return inputValue.trim();
        }
        return inputValue || '';
    }
    onFormatValue(rawValue) {
        if (rawValue) {
            return rawValue.trim();
        }
        return rawValue || '';
    }
    /**
     * UTILS
     * ------------------------------------------------------
     */
    toParsedValue(inputValue) {
        return this.onParseValue(inputValue);
    }
    toFormattedValue(inputValue) {
        return this.onFormatValue(inputValue);
    }
    /**
     * FIRE EVENT METHODS
     * ------------------------------------------------------
     */
    fireI18nChange(context) {
        const oldBlocks = this.blocks.clone();
        const oldLocale = `${context.locale}`;
        this.locale = context.locale;
        this.blocks.list.forEach(block => block.onI18nChange(context.locale));
        this.onLocaleChange(context, oldLocale, oldBlocks);
    }
    fireValueChanged(context) {
        if (context.didValueChange) {
            this.onValueChanged(context);
        }
    }
    firePaste(context) {
        const index = this.blocks.getBlockIndexFromPosition(context.position.value);
        if (index !== undefined) {
            const currentBlock = this.blocks.list[index];
            this.onPaste(context, currentBlock, index);
            this.onChange(context);
        }
    }
    fireClick(context) {
        const maskPlaceholder = this.blocks.getPlaceholderMask();
        if (maskPlaceholder === context.value) {
            context.position.toStart();
        }
    }
    fireFocus(context) {
        if (context.target && context.isValueEmpty()) {
            this.resetInputValueWithMask(context);
        }
        this.onFocus(context);
    }
    fireBlur(context) {
        if (context.target) {
            if (this.isValueEmptyMask(context)) {
                this.emptyInputValue(context);
            }
            else {
                this.onBlur(context);
                context.submit('blur', this.onParseValue(context.value, { allowInvalidValue: context.component.allowInvalidValue }));
            }
        }
    }
    fireKeyDown(context) {
        const position = context.isBackspaceKey ? Math.max(0, context.position.value - 1) : context.position.value;
        const index = this.blocks.getBlockIndexFromPosition(position);
        // prevent of adding more chars than possible
        if (position >= this.blocks.lastPosition && !context.isNavigationKey && !context.isSelectAllCommand) {
            context.preventDefault();
            context.stopPropagation();
            return;
        }
        if (index !== undefined && !context.position.isRangeSelection) {
            const currentBlock = this.blocks.list[index];
            //
            // Navigation keys like arrows and tabs
            if (context.isNavigationKey) {
                this.onNavigationDown(context, currentBlock, index);
                //
                // Select the whole value of the input
            }
            else if (context.isSelectAllCommand) {
                this.onSelectAll(context, currentBlock, index);
                //
                // On copy a the value
            }
            else if (context.isCopyCommand) ;
            else if (context.isPasteCommand) ;
            else if (context.isBackspaceKey) {
                context.preventDefault();
                this.onBackspaceDown(context, currentBlock, index);
                //
                // On delete to remove a next char
            }
            else if (context.isDeleteKey) {
                context.preventDefault();
                this.onDeleteDown(context, currentBlock, index);
                //
                // On double space key hit only happens on mac
            }
            else if (context.isWhiteSpaceKey) {
                context.preventDefault();
                const lastWrittenChar = context.value[context.position.value];
                if (lastWrittenChar === '.') {
                    context.stopPropagation();
                    const value = context.value;
                    context.value = value.substring(0, context.position.value) + '_' + value.substring(context.position.value + 1);
                }
                //
                // On a normal key down with the allowed key hits
            }
            else if (currentBlock.verifyAllowedKeyHits(context.key)) {
                context.preventDefault();
                this.onBlockChange(context, currentBlock, index);
                //
                // if the user hits the next separator we jump to the next user block
            }
            else if (this.blocks.verifyCallOfNextSeparator(context.key, index)) {
                context.preventDefault();
                const activeBlock = this.blocks.list[index];
                if (context.position.value > activeBlock.from) {
                    const nextBlock = this.blocks.list[index + 1];
                    const value = context.value;
                    const blockValue = currentBlock.getValueOfTheBlock(value);
                    const newBlockValue = currentBlock.format(blockValue);
                    context.value = value.substring(0, currentBlock.from) + newBlockValue + value.substring(currentBlock.to);
                    context.position.value = nextBlock.to;
                }
            }
            //
            // format all blocks where the cursor is not active
            const newIndex = this.blocks.getBlockIndexFromPosition(context.position.value);
            if (newIndex && !context.isBackspaceKey) {
                const newFormattedValue = this.blocks.formatBlocks(context.value, newIndex);
                const position = context.position.value;
                context.value = newFormattedValue;
                context.position.value = position;
            }
            //
            // hit a range of chars
        }
        else {
            if (!context.isTabKey) {
                context.preventDefault();
            }
            if (context.isBackspaceKey || context.isDeleteKey) {
                this.resetInputValueWithMask(context);
            }
            else if (this.blocks.list[0].verifyAllowedKeyHits(context.key)) {
                this.onBlockChange(context, this.blocks.list[0], 0);
            }
        }
    }
    /**
     * PROTECTED HELPER METHODS
     * ------------------------------------------------------
     */
    resetInputValueWithMask(context) {
        context.value = this.blocks.getPlaceholderMask();
        context.position.toStart();
    }
    isValueEmptyMask(context) {
        const placeholder = this.blocks.getPlaceholderMask();
        return placeholder === context.value;
    }
    emptyInputValue(context) {
        context.value = '';
        context.submit('blur', context.value);
    }
}

class DateMask extends AbstractMask {
    constructor() {
        super([
            new MaskBlock({
                from: 0,
                to: 2,
                allowedKeys: [...NUMBER_KEYS],
                format: (value, _locale, mask) => {
                    if (Number.isNaN(parseInt(value, 10))) {
                        return `${mask}${mask}`;
                    }
                    return value.padStart(2, '0');
                },
                mask: locale => {
                    return this.dayMask[locale.split('-')[0]] || this.dayMask['de'];
                },
            }),
            new MaskBlock({ from: 2, to: 3, mask: locale => dateSeparator(locale), isSeparator: true }),
            new MaskBlock({
                from: 3,
                to: 5,
                allowedKeys: [...NUMBER_KEYS],
                format: (value, _locale, mask) => {
                    if (Number.isNaN(parseInt(value, 10))) {
                        return `${mask}${mask}`;
                    }
                    return value.padStart(2, '0');
                },
                mask: locale => this.monthMask[locale.split('-')[0]] || this.monthMask['de'],
            }),
            new MaskBlock({ from: 5, to: 6, mask: locale => dateSeparator(locale), isSeparator: true }),
            new MaskBlock({
                from: 6,
                to: 10,
                allowedKeys: [...NUMBER_KEYS],
                mask: locale => this.yearMask[locale.split('-')[0]] || this.yearMask['de'],
            }),
        ]);
        this.maxLength = 10;
        this.minLength = 10;
        this.inputMode = 'decimal';
        this.dayMask = {
            de: 'T',
            en: 'D',
            fr: 'J',
            it: 'G',
            nl: 'D',
            es: 'D',
            pl: 'D',
            pt: 'D',
            sv: 'D',
            fi: 'M',
        };
        this.monthMask = {
            de: 'M',
            en: 'M',
            fr: 'M',
            it: 'M',
            nl: 'M',
            es: 'M',
            pl: 'M',
            pt: 'M',
            sv: 'M',
            fi: 'K',
        };
        this.yearMask = {
            de: 'J',
            en: 'Y',
            fr: 'A',
            it: 'A',
            nl: 'J',
            es: 'A',
            pl: 'R',
            pt: 'A',
            sv: 'Å',
            fi: 'V',
        };
    }
    onParseValue(inputValue, options = { allowInvalidValue: false }) {
        if (inputValue) {
            const date = BalDate.fromAnyFormat(this.blocks.getRawValueWithoutMask(inputValue));
            if (date.isValid) {
                return date.toISODate();
            }
            else if (options && options.allowInvalidValue) {
                return INVALID_VALUE;
            }
        }
        return '';
    }
    onFormatValue(isoDate) {
        if (isoDate) {
            const date = BalDate.fromISO(isoDate);
            if (date.isValid) {
                return date.toFormat();
            }
        }
        return '';
    }
    onPaste(context, _block, _index) {
        const value = context.clipboardData || '';
        const date = BalDate.fromAnyFormat(value);
        if (date.isValid) {
            context.value = date.toFormat();
            context.position.toEnd();
        }
    }
    onBlur(context) {
        const rawValue = this.blocks.getRawValueWithoutMaskByContext(context);
        const date = BalDate.fromAnyFormat(rawValue);
        if (date.isValid) {
            const formattedDate = date.toFormat();
            if (formattedDate !== context.value) {
                context.value = formattedDate;
            }
        }
        else if (context.component.allowInvalidValue) {
            if (rawValue !== context.value) {
                context.value = rawValue;
            }
        }
    }
}

class MaskComponentAdapter {
    constructor(mask) {
        this.mask = mask;
    }
    get attributes() {
        return {
            inputMode: this.mask.inputMode,
            maxLength: this.mask.maxLength,
            minLength: this.mask.minLength,
            type: 'text',
            autoCapitalize: 'off',
            autoCorrect: 'off',
            spellcheck: false,
        };
    }
    bindComponent(component) {
        this.component = component;
    }
    bindComponentDidLoad() {
        if (this.component && this.component.nativeInput) {
            this.component.nativeInput.value = this.component.value || '';
        }
        this.bindValueChanged(this.component.value, undefined);
    }
    bindConfigChanged(config) {
        const { component, mask } = this;
        const context = new MaskLocaleContext({
            component,
            mask,
            event: {
                locale: `${config.language}-${config.region}`,
            },
        });
        this.mask.fireI18nChange(context);
        context.submit();
    }
    bindValueChanged(newValue, oldValue) {
        const { component, mask } = this;
        const context = new MaskValueChangedContext({
            component,
            mask,
            event: { newValue, oldValue },
        });
        this.mask.fireValueChanged(context);
        context.submit('blur');
    }
    bindKeyDown(event) {
        if (this.isComponentAccessible) {
            const { component, mask } = this;
            const context = new MaskKeyboardContext({ event, component, mask });
            this.mask.fireKeyDown(context);
            const isTabKey = event.key === 'Tab';
            context.submit(isTabKey ? 'tab' : 'input');
            component.balKeyPress.emit(event);
        }
    }
    bindFocus(event) {
        if (this.isComponentAccessible) {
            const { component, mask } = this;
            component.focused = true;
            const context = new MaskFocusContext({ event, component, mask });
            this.mask.fireFocus(context);
            context.submit();
            component.balFocus.emit(event);
        }
    }
    bindBlur(event) {
        if (this.isComponentAccessible) {
            const { component, mask } = this;
            component.focused = false;
            const context = new MaskFocusContext({ event, component, mask });
            this.mask.fireBlur(context);
            context.submit('blur');
            component.balBlur.emit(event);
        }
    }
    bindPaste(event) {
        if (this.isComponentAccessible) {
            const { component, mask } = this;
            const context = new MaskClipboardContext({ event, component, mask });
            this.mask.firePaste(context);
            context.submit();
        }
    }
    bindFormReset(event) {
        const formElement = event.target;
        if (formElement && (formElement === this.component.el || formElement.contains(this.component.el))) {
            this.component.value = this.component.initialValue;
            this.component.inputValue = this.component.initialValue;
            clearTimeout(this.resetHandlerTimer);
            this.resetHandlerTimer = setTimeout(() => {
                if (this.component.nativeInput) {
                    this.component.nativeInput.value = this.mask.toFormattedValue(this.component.value || '');
                }
            });
        }
    }
    bindClick(event) {
        if (this.isComponentAccessible) {
            const { component, mask } = this;
            const context = new MaskMouseContext({ event, component, mask });
            this.mask.fireClick(context);
            context.submit();
        }
    }
    bindHostClick(event) {
        if (!this.isComponentAccessible) {
            event.preventDefault();
            event.stopPropagation();
        }
    }
    bindGlobalClick(event) {
        if (!this.isComponentAccessible) {
            if (event.target && event.target === this.component.el) {
                event.preventDefault();
                event.stopPropagation();
            }
        }
    }
    get isComponentAccessible() {
        return !this.component.disabled && !this.component.readonly;
    }
}

const balInputDateCss = ".bal-input-date{display:block;width:100%;-ms-flex:1;flex:1}.bal-input-date input:not(:-moz-placeholder-shown){letter-spacing:.4px}.bal-input-date input:not(:-ms-input-placeholder){letter-spacing:.4px}.bal-input-date input:not(:placeholder-shown){letter-spacing:.4px}.bal-input-date__native{position:absolute !important;left:0;top:0;margin:0;padding:0;opacity:0;outline:0;border:none;width:1px;height:1px;clip:rect(1px, 1px, 1px, 1px);overflow:hidden}";

const InputDate = /*@__PURE__*/ proxyCustomElement(class InputDate extends HTMLElement {
    constructor(registerHost) {
        super();
        if (registerHost !== false) {
            this.__registerHost();
        }
        this.balKeyPress = createEvent(this, "balKeyPress", 7);
        this.balChange = createEvent(this, "balChange", 7);
        this.balInput = createEvent(this, "balInput", 7);
        this.balBlur = createEvent(this, "balBlur", 7);
        this.balFocus = createEvent(this, "balFocus", 7);
        this.inputId = `bal-i-date-${inputDateIds++}`;
        this.inheritedAttributes = {};
        this.maskAdapter = new MaskComponentAdapter(new DateMask());
        this.focused = false;
        this.isGrouped = false;
        this.ariaForm = defaultBalAriaForm;
        /**
         * PUBLIC PROPERTY API
         * ------------------------------------------------------
         */
        /**
         * The name of the control, which is submitted with the form data.
         */
        this.name = this.inputId;
        /**
         * If `true` the component gets a invalid style.
         */
        this.invalid = false;
        /**
         * If `true` the attribute required is added to the native input.
         */
        this.required = false;
        /**
         * If `true`, the element is not mutable, focusable, or even submitted with the form. The user can neither edit nor focus on the control, nor its form control descendants.
         */
        this.disabled = false;
        /**
         * If `true` the element can not mutated, meaning the user can not edit the control.
         */
        this.readonly = false;
        /**
         * If `true` the input gets a clickable cursor style
         */
        this.clickable = false;
        /**
         * Indicates whether the value of the control can be automatically completed by the browser.
         */
        this.autocomplete = 'off';
        /**
         * @internal
         * If `true` the input will get some right padding.
         */
        this.hasIconRight = false;
        /**
         * The value of the form field, which accepts ISO 8601 date strings (YYYY-MM-DD).
         */
        this.value = undefined;
        this.inputValue = this.value;
        this.initialValue = this.value || '';
        /**
         * If `true`, in Angular reactive forms the control will not be set invalid
         */
        this.autoInvalidOff = false;
        /**
         * If `true`, it returns the string `INVALID_VALUE` within the balChange event if the input provided is not valid.
         */
        this.allowInvalidValue = false;
    }
    createLogger(log) {
        this.log = log;
    }
    valueChanged(newValue, oldValue) {
        this.maskAdapter.bindValueChanged(newValue, oldValue);
    }
    /**
     * LIFECYCLE
     * ------------------------------------------------------
     */
    connectedCallback() {
        this.maskAdapter.bindComponent(this);
        this.isGrouped = hasParent('bal-input-group', this.el);
    }
    componentDidLoad() {
        this.maskAdapter.bindComponentDidLoad();
    }
    componentWillRender() {
        this.inheritedAttributes = inheritAttributes(this.el, ['aria-label', 'tabindex', 'title', 'data-hj-allow']);
    }
    /**
     * LISTENERS
     * ------------------------------------------------------
     */
    /**
     * @internal define config for the component
     */
    async configChanged(config) {
        this.maskAdapter.bindConfigChanged(config);
    }
    resetHandler(event) {
        this.maskAdapter.bindFormReset(event);
    }
    listenOnClick(event) {
        this.maskAdapter.bindGlobalClick(event);
    }
    /**
     * PUBLIC METHODS
     * ------------------------------------------------------
     */
    /**
     * Sets focus on the native `input` in `bal-input`. Use this method instead of the global
     * `input.focus()`.
     */
    async setFocus() {
        inputSetFocus(this);
    }
    /**
     * Sets blur on the native `input` in `bal-input`. Use this method instead of the global
     * `input.blur()`.
     * @internal
     */
    async setBlur() {
        inputSetBlur(this);
    }
    /**
     * Returns the native `<input>` element used under the hood.
     */
    getInputElement() {
        return Promise.resolve(this.nativeInput);
    }
    /**
     * @internal
     */
    async setAriaForm(ariaForm) {
        this.ariaForm = Object.assign({}, ariaForm);
    }
    /**
     * RENDER
     * ------------------------------------------------------
     */
    render() {
        const block = BEM.block('input-date');
        const native = block.element('native');
        return (h(Host, { key: '49ea7a0000fe4b32077a9f4615dc27dc323c1f9c', onClick: (event) => this.maskAdapter.bindHostClick(event), class: Object.assign({}, block.class()) }, h("input", Object.assign({ key: '337864d4fefa8918d6ac0cfd86520575f66ba191', class: {
                'input': true,
                'is-disabled': this.disabled || this.readonly,
                'is-danger': this.invalid,
                'is-clickable': this.clickable && !(this.disabled || this.readonly),
                'bal-focusable': !this.disabled,
                'has-icon-right': this.hasIconRight,
            }, "data-testid": "bal-date-input", ref: el => (this.nativeInput = el), id: this.ariaForm.controlId || this.inputId, "aria-labelledby": this.ariaForm.labelId, "aria-describedby": this.ariaForm.messageId, "aria-invalid": this.invalid === true ? 'true' : 'false', "aria-disabled": ariaBooleanToString(this.disabled), required: this.required, disabled: this.disabled, readonly: this.readonly, autoComplete: this.autocomplete }, this.maskAdapter.attributes, this.inheritedAttributes, { placeholder: this.placeholder, value: this.inputValue, onKeyDown: event => this.maskAdapter.bindKeyDown(event), onClick: event => this.maskAdapter.bindClick(event), onFocus: event => this.maskAdapter.bindFocus(event), onBlur: event => this.maskAdapter.bindBlur(event), onPaste: event => this.maskAdapter.bindPaste(event) })), h("input", { key: '825df1bb8dd5ddd9d2f6b6b7a242f1ab674d003c', type: "date", class: Object.assign({}, native.class()), name: this.name, min: this.min, max: this.max, value: this.value, tabindex: -1, "aria-hidden": "true" })));
    }
    get el() { return this; }
    static get watchers() { return {
        "value": ["valueChanged"]
    }; }
    static get style() { return balInputDateCss; }
}, [256, "bal-input-date", {
        "name": [1],
        "invalid": [4],
        "required": [4],
        "disabled": [4],
        "readonly": [4],
        "placeholder": [1],
        "clickable": [4],
        "min": [1025],
        "max": [1025],
        "autocomplete": [1],
        "hasIconRight": [4, "has-icon-right"],
        "value": [1025],
        "autoInvalidOff": [516, "auto-invalid-off"],
        "allowInvalidValue": [4, "allow-invalid-value"],
        "focused": [32],
        "isGrouped": [32],
        "ariaForm": [32],
        "configChanged": [64],
        "setFocus": [64],
        "setBlur": [64],
        "getInputElement": [64],
        "setAriaForm": [64]
    }, [[6, "reset", "resetHandler"], [6, "click", "listenOnClick"]], {
        "value": ["valueChanged"]
    }]);
__decorate([
    Logger('bal-input-date'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Function]),
    __metadata("design:returntype", void 0)
], InputDate.prototype, "createLogger", null);
__decorate([
    ListenToConfig(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], InputDate.prototype, "configChanged", null);
let inputDateIds = 0;
function defineCustomElement() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["bal-input-date"];
    components.forEach(tagName => { switch (tagName) {
        case "bal-input-date":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, InputDate);
            }
            break;
    } });
}

export { InputDate as I, defineCustomElement as d };
