import { __decorate } from "tslib";
import { attr, html } from '@ni/fast-element';
import { DesignSystem, NumberField as FoundationNumberField } from '@ni/fast-foundation';
import { styles } from './styles';
import { NumberFieldAppearance } from './types';
import { errorTextTemplate } from '../patterns/error/template';
import { mixinErrorPattern } from '../patterns/error/types';
import { buttonTag } from '../button';
import { iconMinusWideTag } from '../icons/minus-wide';
import { iconAddTag } from '../icons/add';
import { iconExclamationMarkTag } from '../icons/exclamation-mark';
import { numericDecrementLabel, numericIncrementLabel } from '../label-provider/core/label-tokens';
import { template } from './template';
import { mixinRequiredVisiblePattern } from '../patterns/required-visible/types';
import { lang } from '../theme-provider';
/**
 * A nimble-styled HTML number input
 */
export class NumberField extends mixinErrorPattern(mixinRequiredVisiblePattern(FoundationNumberField)) {
    constructor() {
        super(...arguments);
        this.appearance = NumberFieldAppearance.underline;
        this.fullBleed = false;
        this.appearanceReadOnly = false;
        this.decimalSeparator = '.';
        this.inputFilterRegExp = this.buildFilterRegExp(this.decimalSeparator);
        this.langSubscriber = {
            handleChange: () => this.updateDecimalSeparatorAndInputFilter()
        };
    }
    connectedCallback() {
        super.connectedCallback();
        // This is a workaround for FAST issue: https://github.com/microsoft/fast/issues/6148
        this.control.setAttribute('role', 'spinbutton');
        this.updateDecimalSeparatorAndInputFilter();
        lang.subscribe(this.langSubscriber, this);
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        lang.unsubscribe(this.langSubscriber, this);
    }
    sanitizeInput(inputText) {
        return inputText.replace(this.inputFilterRegExp, '');
    }
    // this.value <-- this.control.value
    syncValueFromInnerControl() {
        this.value = this.decimalSeparator !== '.'
            ? this.control.value.replace(this.decimalSeparator, '.')
            : this.control.value;
    }
    // this.value --> this.control.value
    syncValueToInnerControl() {
        this.control.value = this.decimalSeparator !== '.'
            ? this.value.replace('.', this.decimalSeparator)
            : this.value;
    }
    updateDecimalSeparatorAndInputFilter() {
        const previousSeparator = this.decimalSeparator;
        this.decimalSeparator = this.getSeparatorForLanguange(lang.getValueFor(this));
        if (this.decimalSeparator !== previousSeparator) {
            this.inputFilterRegExp = this.buildFilterRegExp(this.decimalSeparator);
            this.control.value = this.control.value.replace(previousSeparator, this.decimalSeparator);
        }
    }
    getSeparatorForLanguange(language) {
        return Intl.NumberFormat(language)
            .formatToParts(1.1)
            .find(x => x.type === 'decimal').value;
    }
    buildFilterRegExp(decimalSeparator) {
        return new RegExp(`[^0-9\\-+e${decimalSeparator}]`, 'g');
    }
}
__decorate([
    attr
], NumberField.prototype, "appearance", void 0);
__decorate([
    attr({ attribute: 'full-bleed', mode: 'boolean' })
], NumberField.prototype, "fullBleed", void 0);
__decorate([
    attr({ attribute: 'appearance-readonly', mode: 'boolean' })
], NumberField.prototype, "appearanceReadOnly", void 0);
/**
 * A function that returns a number-field registration for configuring the component with a DesignSystem.
 *
 * @public
 * @remarks
 * Generates HTML Element: \<nimble-number-field\>
 *
 */
const nimbleNumberField = NumberField.compose({
    baseName: 'number-field',
    baseClass: FoundationNumberField,
    template,
    styles,
    shadowOptions: {
        delegatesFocus: true
    },
    stepDownGlyph: html `
        <${buttonTag}
            class="step-up-down-button"
            appearance="ghost"
            content-hidden
            tabindex="-1"
            aria-hidden="true"
        >
            ${x => numericDecrementLabel.getValueFor(x)}
            <${iconMinusWideTag}
                slot="start"
            >
            </${iconMinusWideTag}>
        </${buttonTag}>
    `,
    stepUpGlyph: html `
        <${buttonTag}
            class="step-up-down-button"
            appearance="ghost"
            content-hidden
            tabindex="-1"
            aria-hidden="true"
        >
            ${x => numericIncrementLabel.getValueFor(x)}
            <${iconAddTag}
                slot="start">
            </${iconAddTag}>
        </${buttonTag}>
    `,
    end: html `
        <${iconExclamationMarkTag}
            severity="error"
            class="error-icon"
        ></${iconExclamationMarkTag}>
        ${errorTextTemplate}
    `
});
DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleNumberField());
export const numberFieldTag = 'nimble-number-field';
//# sourceMappingURL=index.js.map