import * as i6 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { EventEmitter, Component, ChangeDetectionStrategy, Self, Optional, Output, HostBinding, Input, ViewChild, NgModule } from '@angular/core';
import * as i2 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import * as i5 from '@angular/material/input';
import { MatInputModule } from '@angular/material/input';
import * as i1 from '@deja-js/component/core';
import { _MatInputMixinBase, DejaChildValidatorDirective, DejaChildValidatorModule, DejaTextMetricsModule } from '@deja-js/component/core';
import { coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion';
import { MatFormFieldControl } from '@angular/material/form-field';
import { Subject } from 'rxjs';
import * as i3 from '@angular/cdk/a11y';
import * as i4 from '@angular/material/core';

const createCounterRangeValidator = (comp) => (c) => {
    const err = {
        rangeError: {
            given: c.value,
            max: comp.max,
            min: comp.min
        }
    };
    if (c.value === null || c.value === undefined) {
        return null;
    }
    return comp.isOffLimits ? err : null;
};
// eslint-disable-next-line @angular-eslint/no-conflicting-lifecycle
class DejaNumericStepperComponent extends _MatInputMixinBase {
    constructor(dejaTextMetricsService, elementRef, changeDetectorRef, ngControl, fm, _parentForm, _parentFormGroup, _defaultErrorStateMatcher) {
        super(_defaultErrorStateMatcher, _parentForm, _parentFormGroup, ngControl);
        this.dejaTextMetricsService = dejaTextMetricsService;
        this.elementRef = elementRef;
        this.changeDetectorRef = changeDetectorRef;
        this.ngControl = ngControl;
        this.fm = fm;
        /** Output to get the event when the value is modified (no validation)  */
        this.textChange = new EventEmitter();
        this.id = `deja-numeric-stepper-${DejaNumericStepperComponent.nextId++}`;
        this.describedBy = '';
        this._disabled = null;
        this.controlType = 'deja-numeric-stepper';
        this.errorState = false;
        this.size = 0;
        // eslint-disable-next-line rxjs/finnish
        this.stateChanges = new Subject();
        this.focused = false;
        this._max = null;
        this._min = null;
        this._step = 1;
        this._hideSteppers = false;
        this._required = false;
        // NgModel implementation
        this.onTouchedCallback = () => undefined;
        this.onChangeCallback = (_) => undefined;
        this.onValidatorChangeCallback = () => undefined;
        console.warn('@deja-js/component/numeric-stepper is deprecated, and will be removed in a further version. Please use @deja-js/component/v2/numeric-stepper instead.');
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
        // eslint-disable-next-line rxjs-angular/prefer-takeuntil
        this.fm.monitor(elementRef.nativeElement, true).subscribe(origin => {
            this.focused = !!origin;
            if (!this.focused) {
                this.onTouchedCallback();
            }
            this.stateChanges.next();
        });
    }
    get shouldLabelFloat() {
        return this.focused || !this.empty || this._alwaysDisplayUnit;
    }
    /** InputElement of stepper */
    set inputElementRef(element) {
        if (element) {
            this.inputElement = element.nativeElement;
        }
    }
    /** Max value of stepper */
    get max() {
        return this._max;
    }
    set max(value) {
        this._max = coerceNumberProperty(value, null);
        this.changeDetectorRef.markForCheck();
    }
    /** Min value of stepper */
    get min() {
        return this._min;
    }
    set min(value) {
        this._min = coerceNumberProperty(value, null);
        this.changeDetectorRef.markForCheck();
    }
    get isOffLimits() {
        return (this.min !== null && this.value < this.min) || (this.max !== null && this.value > this.max);
    }
    /** Step for stepper : default 1 */
    get step() {
        return this._step;
    }
    set step(value) {
        this._step = coerceNumberProperty(value, 1);
        this.changeDetectorRef.markForCheck();
    }
    /** hide the steppers */
    get hideSteppers() {
        return this._hideSteppers;
    }
    set hideSteppers(value) {
        this._hideSteppers = coerceBooleanProperty(value);
        this.changeDetectorRef.markForCheck();
    }
    set inputValidatorDirective(value) {
        if (value) {
            value.parentControl = this.ngControl;
        }
    }
    /**
     * Placeholder of the input
     */
    get placeholder() {
        return this._placeholder;
    }
    set placeholder(plh) {
        this._placeholder = plh;
        this.stateChanges.next();
    }
    /** unit always visible */
    get alwaysDisplayUnit() {
        return this._alwaysDisplayUnit;
    }
    set alwaysDisplayUnit(value) {
        this._alwaysDisplayUnit = coerceBooleanProperty(value);
    }
    get empty() {
        return !this._value && this._value !== 0;
    }
    /**
 * Get disable value
 */
    get disabled() {
        return this.ngControl ? this.ngControl.disabled : this._disabled;
    }
    /** Allow to disabled the component */
    set disabled(value) {
        const disabled = coerceBooleanProperty(value);
        this._disabled = disabled || null;
        this.changeDetectorRef.markForCheck();
    }
    get required() {
        return this._required;
    }
    set required(req) {
        this._required = coerceBooleanProperty(req);
        this.stateChanges.next();
    }
    // eslint-disable-next-line @angular-eslint/no-conflicting-lifecycle, @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
    ngOnChanges(changes) {
        // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
        if (changes.min || changes.max) {
            this.validateFn = createCounterRangeValidator(this);
            if (this.ngControl?.control) {
                const validators = [this.validateFn];
                if (this.ngControl.control.validator) {
                    validators.push(this.ngControl.control.validator);
                }
                this.ngControl.control.setValidators(validators);
            }
        }
    }
    // eslint-disable-next-line @angular-eslint/no-conflicting-lifecycle
    ngDoCheck() {
        if (this.ngControl) {
            // We need to re-evaluate this on every change detection cycle, because there are some
            // error triggers that we can't subscribe to (e.g. parent form submissions). This means
            // that whatever logic is in here has to be super lean or we risk destroying the performance.
            this.updateErrorState();
        }
    }
    // eslint-disable-next-line @angular-eslint/no-conflicting-lifecycle
    ngOnDestroy() {
        this.stateChanges.complete();
        this.fm.stopMonitoring(this.elementRef.nativeElement);
    }
    validate(c) {
        return this.validateFn(c) || c.validator?.(c);
    }
    setDescribedByIds(ids) {
        this.describedBy = ids.join(' ');
    }
    onContainerClick(event) {
        if (event.target.tagName.toLowerCase() !== 'input') {
            this.elementRef.nativeElement.querySelector('input').focus();
        }
    }
    /** Give focus to this component */
    setFocus() {
        if (this.inputElement) {
            this.inputElement.focus();
        }
    }
    // ************* ControlValueAccessor Implementation **************
    get value() {
        return this._value;
    }
    set value(val) {
        this.writeValue(val);
        this.onChangeCallback(val);
        this.onTouchedCallback();
        this.stateChanges.next();
    }
    writeValue(value) {
        if (value === null || value === undefined) {
            this._value = value;
        }
        else {
            this._value = isNaN(value) ? null : +value;
        }
        this.checkSize(value);
        this.changeDetectorRef.markForCheck();
        this.textChange.emit(value);
    }
    registerOnChange(fn) {
        this.onChangeCallback = fn;
    }
    registerOnTouched(fn) {
        this.onTouchedCallback = fn;
    }
    setDisabledState(isDisabled) {
        this.disabled = isDisabled;
    }
    // ************* End of ControlValueAccessor Implementation **************
    checkSize(value) {
        this.size = this.dejaTextMetricsService.getTextWidth((value || this.value || 0).toString(), this.elementRef.nativeElement);
    }
}
// eslint-disable-next-line @typescript-eslint/naming-convention
DejaNumericStepperComponent.nextId = 0;
DejaNumericStepperComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaNumericStepperComponent, deps: [{ token: i1.DejaTextMetricsService }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i2.NgControl, optional: true, self: true }, { token: i3.FocusMonitor }, { token: i2.NgForm, optional: true }, { token: i2.FormGroupDirective, optional: true }, { token: i4.ErrorStateMatcher }], target: i0.ɵɵFactoryTarget.Component });
DejaNumericStepperComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.1", type: DejaNumericStepperComponent, selector: "deja-numeric-stepper", inputs: { unit: "unit", max: "max", min: "min", step: "step", hideSteppers: "hideSteppers", placeholder: "placeholder", alwaysDisplayUnit: "alwaysDisplayUnit", disabled: "disabled", required: "required" }, outputs: { textChange: "textChange" }, host: { properties: { "id": "this.id", "class.floating": "this.shouldLabelFloat", "attr.aria-describedby": "this.describedBy", "attr.disabled": "this._disabled" } }, providers: [{ provide: MatFormFieldControl, useExisting: DejaNumericStepperComponent }], viewQueries: [{ propertyName: "inputElementRef", first: true, predicate: ["inputStepper"], descendants: true }, { propertyName: "inputValidatorDirective", first: true, predicate: DejaChildValidatorDirective, descendants: true, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<input deja-child-validator matInput [class.off-limits]=\"isOffLimits\" [disabled]=\"disabled\" #inputStepper type=\"number\" [(ngModel)]=\"value\" [min]=\"_min\" [max]=\"_max\" [step]=\"_step\" [style.width.px]=\"size\" />\n<span class=\"unit\" *ngIf=\"unit && shouldLabelFloat\">{{ unit }}</span>\n\n<span class=\"steppers\" *ngIf=\"!hideSteppers\">\n    <button [disabled]=\"disabled || value === _min\" (click)=\"value = ((value || 0) * 10000 - _step * 10000) / 10000\" type=\"button\" tabindex=\"-1\">remove_circle_outline</button>\n    <button [disabled]=\"disabled || value === _max\" (click)=\"value = ((value || 0) * 10000 + _step * 10000) / 10000\" type=\"button\" tabindex=\"-1\">add_circle_outline</button>\n</span>\n", styles: [":host{display:flex;padding-right:3rem;position:relative}:host input{border:none;background:none;font:inherit;min-width:2px;outline:none;padding:0 2px 0 0;text-align:center}:host .unit{color:#0000008c}:host input::-webkit-inner-spin-button,:host input::-webkit-outer-spin-button{-webkit-appearance:none!important;margin:0!important;-moz-appearance:textfield!important}:host .steppers{flex:0 0 auto;display:flex;flex-direction:row;position:absolute;align-items:center;right:0;bottom:0;top:0}:host .steppers>span{font-family:Material Icons;font-size:1.2rem}:host .steppers button{background:none;border:none;box-shadow:none;cursor:pointer;font-family:Material Icons;font-size:1.5rem;justify-content:center;line-height:initial;min-width:initial;outline:none;padding:0;transition:color .2s ease;white-space:nowrap;word-wrap:normal}:host[disabled] .steppers button{cursor:not-allowed}\n"], directives: [{ type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl],      input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i2.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1.DejaChildValidatorDirective, selector: "[deja-child-validator]" }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaNumericStepperComponent, decorators: [{
            type: Component,
            args: [{ changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: MatFormFieldControl, useExisting: DejaNumericStepperComponent }], selector: 'deja-numeric-stepper', template: "<input deja-child-validator matInput [class.off-limits]=\"isOffLimits\" [disabled]=\"disabled\" #inputStepper type=\"number\" [(ngModel)]=\"value\" [min]=\"_min\" [max]=\"_max\" [step]=\"_step\" [style.width.px]=\"size\" />\n<span class=\"unit\" *ngIf=\"unit && shouldLabelFloat\">{{ unit }}</span>\n\n<span class=\"steppers\" *ngIf=\"!hideSteppers\">\n    <button [disabled]=\"disabled || value === _min\" (click)=\"value = ((value || 0) * 10000 - _step * 10000) / 10000\" type=\"button\" tabindex=\"-1\">remove_circle_outline</button>\n    <button [disabled]=\"disabled || value === _max\" (click)=\"value = ((value || 0) * 10000 + _step * 10000) / 10000\" type=\"button\" tabindex=\"-1\">add_circle_outline</button>\n</span>\n", styles: [":host{display:flex;padding-right:3rem;position:relative}:host input{border:none;background:none;font:inherit;min-width:2px;outline:none;padding:0 2px 0 0;text-align:center}:host .unit{color:#0000008c}:host input::-webkit-inner-spin-button,:host input::-webkit-outer-spin-button{-webkit-appearance:none!important;margin:0!important;-moz-appearance:textfield!important}:host .steppers{flex:0 0 auto;display:flex;flex-direction:row;position:absolute;align-items:center;right:0;bottom:0;top:0}:host .steppers>span{font-family:Material Icons;font-size:1.2rem}:host .steppers button{background:none;border:none;box-shadow:none;cursor:pointer;font-family:Material Icons;font-size:1.5rem;justify-content:center;line-height:initial;min-width:initial;outline:none;padding:0;transition:color .2s ease;white-space:nowrap;word-wrap:normal}:host[disabled] .steppers button{cursor:not-allowed}\n"] }]
        }], ctorParameters: function () { return [{ type: i1.DejaTextMetricsService }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i2.NgControl, decorators: [{
                    type: Self
                }, {
                    type: Optional
                }] }, { type: i3.FocusMonitor }, { type: i2.NgForm, decorators: [{
                    type: Optional
                }] }, { type: i2.FormGroupDirective, decorators: [{
                    type: Optional
                }] }, { type: i4.ErrorStateMatcher }]; }, propDecorators: { textChange: [{
                type: Output
            }], id: [{
                type: HostBinding
            }], shouldLabelFloat: [{
                type: HostBinding,
                args: ['class.floating']
            }], describedBy: [{
                type: HostBinding,
                args: ['attr.aria-describedby']
            }], _disabled: [{
                type: HostBinding,
                args: ['attr.disabled']
            }], unit: [{
                type: Input
            }], inputElementRef: [{
                type: ViewChild,
                args: ['inputStepper']
            }], max: [{
                type: Input
            }], min: [{
                type: Input
            }], step: [{
                type: Input
            }], hideSteppers: [{
                type: Input
            }], inputValidatorDirective: [{
                type: ViewChild,
                args: [DejaChildValidatorDirective, { static: true }]
            }], placeholder: [{
                type: Input
            }], alwaysDisplayUnit: [{
                type: Input
            }], disabled: [{
                type: Input
            }], required: [{
                type: Input
            }] } });

/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
class DejaNumericStepperModule {
}
DejaNumericStepperModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaNumericStepperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
DejaNumericStepperModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaNumericStepperModule, declarations: [DejaNumericStepperComponent], imports: [CommonModule,
        DejaChildValidatorModule,
        DejaTextMetricsModule,
        FormsModule,
        MatButtonModule,
        MatIconModule,
        MatInputModule], exports: [DejaNumericStepperComponent] });
DejaNumericStepperModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaNumericStepperModule, imports: [[
            CommonModule,
            DejaChildValidatorModule,
            DejaTextMetricsModule,
            FormsModule,
            MatButtonModule,
            MatIconModule,
            MatInputModule
        ]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaNumericStepperModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        CommonModule,
                        DejaChildValidatorModule,
                        DejaTextMetricsModule,
                        FormsModule,
                        MatButtonModule,
                        MatIconModule,
                        MatInputModule
                    ],
                    exports: [
                        DejaNumericStepperComponent
                    ],
                    declarations: [
                        DejaNumericStepperComponent
                    ]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { DejaNumericStepperComponent, DejaNumericStepperModule, createCounterRangeValidator };
//# sourceMappingURL=deja-js-component-numeric-stepper.mjs.map
