import { Component, ContentChild, ContentChildren, EventEmitter, HostBinding, Input, Optional, Output, Self, ViewChild } from '@angular/core';
import { NgControl } from '@angular/forms';
import { ControlSuffixComponent } from './control-suffix/control-suffix.component';
import { ControlLabelComponent } from './control-label/control-label.component';
import { debounceTime, distinctUntilChanged, map, tap } from 'rxjs/operators';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@angular/common";
import * as i3 from "../validation/validation-errors/validation-errors.component";
import * as i4 from "@angular/cdk/a11y";
import * as i5 from "../../icon/icon.component";
import * as i6 from "@angular/cdk/overlay";
import * as i7 from "./control-suffix/control-suffix.component";
export class ControlComponent {
    constructor(changeDetectorRef, model, modelGroup, form) {
        this.changeDetectorRef = changeDetectorRef;
        this.model = model;
        this.modelGroup = modelGroup;
        this.form = form;
        this.groupValidation = false;
        this.clearing = false;
        this.focusSubject = new EventEmitter();
        this.focused = this.focusSubject.pipe(map(value => !!value), debounceTime(100), distinctUntilChanged(), tap(value => this._focused = value));
        this._focused = false;
    }
    set setClearing(value) {
        this.clearing = coerceBooleanProperty(value);
    }
    ngOnInit() {
    }
    get label() {
        return this.labelComponent?.label || null;
    }
    get hasControlTouched() {
        return this.controls?.some(control => control.touched) || false;
    }
    get hasControlInvalid() {
        return this.controls?.some(control => control.invalid) || false;
    }
    get invalid() {
        return !this._focused &&
            (this.hasControlTouched || this.form?.submitted) &&
            (this.hasControlInvalid || this.model?.invalid || (this.groupValidation && this.modelGroup?.invalid));
    }
    get errors() {
        for (const control of this.controls) {
            if (control.errors) {
                return control.errors;
            }
        }
        if (this.model?.errors) {
            return this.model.errors;
        }
        if (this.groupValidation && this.modelGroup?.errors) {
            return this.modelGroup.errors;
        }
        return null;
    }
    get isFilled() {
        const isEmpty = value => value === '' || value === null || value === undefined || (Array.isArray(value) && !value.length);
        return this.controls?.some(({ value }) => !isEmpty(value)) || false;
    }
    get disabled() {
        const controls = this.controls.toArray();
        return controls.length && controls.every(control => control.disabled);
    }
    get clearingAvailable() {
        return this.clearing && this.isFilled && !this.disabled;
    }
    get hasLabel() {
        return !!this.labelComponent;
    }
    get hasNoLabel() {
        return !this.hasLabel;
    }
    get hasSuffix() {
        return !!this.suffixComponent;
    }
    focusHandler(origin) {
        this.focusSubject.emit(origin);
    }
    clear() {
        if (this.controls) {
            setTimeout(() => {
                this.controls.forEach(({ control }) => {
                    control.setValue(null);
                    control.markAsTouched();
                });
            }, 100);
        }
        this.changeDetectorRef.detectChanges();
    }
}
ControlComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: ControlComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.NgModelGroup, optional: true, self: true }, { token: i1.NgModelGroup, optional: true }, { token: i1.NgForm, optional: true }], target: i0.ɵɵFactoryTarget.Component });
ControlComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.4", type: ControlComponent, selector: "ui-control", inputs: { groupValidation: "groupValidation", setClearing: ["clearing", "setClearing"] }, outputs: { focused: "focused" }, host: { properties: { "class.has-clearing": "this.clearing", "class.no-label": "this.hasNoLabel", "class.has-suffix": "this.hasSuffix" } }, queries: [{ propertyName: "labelComponent", first: true, predicate: ControlLabelComponent, descendants: true }, { propertyName: "suffixComponent", first: true, predicate: ControlSuffixComponent, descendants: true }, { propertyName: "controls", predicate: NgControl, descendants: true }], viewQueries: [{ propertyName: "overlayOrigin", first: true, predicate: ["overlayOrigin"], descendants: true }], ngImport: i0, template: "<div class=\"control\"\n     cdkOverlayOrigin #overlayOrigin=\"cdkOverlayOrigin\"\n     [class.control--focused]=\"focused | async\"\n     [class.control--invalid]=\"invalid\"\n     [class.control--filled]=\"isFilled\"\n     [class.control--disabled]=\"disabled\"\n     [class.control--suffix]=\"hasSuffix\">\n\n  <div class=\"control__wrapper\"\n         cdkMonitorSubtreeFocus\n         (cdkFocusChange)=\"focusHandler($event)\">\n    <div class=\"control__value\"\n          [class.control__value--hidden]=\"!(focused | async) && !isFilled && hasLabel\">\n      <ng-content></ng-content>\n    </div>\n    <div class=\"control__label\" *ngIf=\"hasLabel\"\n          [class.control__label--focused]=\"focused | async\"\n          [class.control__label--filled]=\"isFilled\">\n      <ng-content select=\"ui-control-label\"></ng-content>\n    </div>\n  </div>\n\n  <div class=\"control__suffix\">\n    <ng-container\n      [ngTemplateOutlet]=\"hasSuffix ? suffixTemplate : clearingAvailable ? clearTemplate : null\"></ng-container>\n\n    <ng-template #clearTemplate>\n      <ui-control-suffix>\n        <a href=\"#\" title=\"Clear value\" (click)=\"clear(); $event.preventDefault()\" tabindex=\"-1\" aria-hidden=\"true\">\n          <ui-icon name=\"x\"></ui-icon>\n        </a>\n      </ui-control-suffix>\n    </ng-template>\n\n    <ng-template #suffixTemplate>\n      <ng-content select=\"ui-control-suffix\"></ng-content>\n    </ng-template>\n  </div>\n</div>\n\n<ng-container *ngIf=\"invalid else comment\">\n  <ui-validation-errors [errors]=\"errors\"></ui-validation-errors>\n</ng-container>\n\n<ng-template #comment>\n  <ng-content select=\"ui-control-comment\"></ng-content>\n</ng-template>\n", styles: [".transition{transition:all .5s ease-in}.transition-fast{transition:all .2s ease-in}:root{--value-opacity: 1}:host{display:block;width:100%;color:var(--color-contrast-50)}:host .control{position:relative;display:flex;width:100%;min-height:var(--field-height);padding:var(--field-padding);background:var(--field-bg);border:none;box-sizing:border-box;border-radius:var(--radius-regular);margin:0;line-height:1;outline:none;transition:.2s background ease-in-out}:host .control:after{content:\" \";position:absolute;height:1px;background:transparent;bottom:0;left:1rem;right:1rem}@media not all and (pointer: coarse){:host .control:hover{--field-bg: var(--field-bg-hover)}}:host .control--focused:after{background:var(--color-contrast-100)}:host .control--invalid :host .control__label{color:var(--color-critical)}:host .control--invalid:host .control--filled:after{background:var(--color-error)}:host .control--invalid:after{background:var(--color-error)}:host .control--disabled{--field-bg: var(--field-bg-disabled);--field-label-color: var(--field-label-color-disabled);--field-value-color: var(--field-value-color-disabled);cursor:not-allowed}@media not all and (pointer: coarse){:host .control--disabled:hover{--field-bg: var(--field-bg-disabled)}}:host .control--disabled .control__wrapper{pointer-events:none}:host .control--disabled .control__suffix{opacity:.5;pointer-events:none}:host .control__wrapper{flex:1;position:relative;box-sizing:border-box;display:flex;align-items:stretch;max-width:100%}:host .control__label{position:absolute;font-size:var(--field-font-size);color:var(--field-label-color);max-width:100%;top:var(--field-label-top);left:0;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;transition:transform .25s ease,font-size .25s ease;will-change:transform,font-size;line-height:1}:host .control__label--optional:after{content:\"(optional)\";display:inline;padding-left:.25rem}:host .control__label--filled,:host .control__label--focused{font-size:var(--field-label-focused-font-size);color:var(--color-contrast-40);transform:var(--field-label-focused-translate)}:host .control__value{display:flex;font-size:var(--field-font-size);color:var(--field-value-color);width:100%}:host .control__value--hidden{--value-opacity: 0}:host .control__suffix{flex-shrink:0}:host-context(ui-control-group) :host .control{border-radius:0}:host-context(ui-control-group) :host:first-child .control{border-top-left-radius:var(--radius-regular);border-bottom-left-radius:var(--radius-regular)}:host-context(ui-control-group) :host:last-child .control{border-top-right-radius:var(--radius-regular);border-bottom-right-radius:var(--radius-regular)}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.ValidationErrorsComponent, selector: "ui-validation-errors", inputs: ["errors"] }, { kind: "directive", type: i4.CdkMonitorFocus, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: ["cdkFocusChange"] }, { kind: "component", type: i5.IconComponent, selector: "ui-icon", inputs: ["name", "color", "size", "stroke", "styles"] }, { kind: "directive", type: i6.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: i7.ControlSuffixComponent, selector: "ui-control-suffix" }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: ControlComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ui-control', template: "<div class=\"control\"\n     cdkOverlayOrigin #overlayOrigin=\"cdkOverlayOrigin\"\n     [class.control--focused]=\"focused | async\"\n     [class.control--invalid]=\"invalid\"\n     [class.control--filled]=\"isFilled\"\n     [class.control--disabled]=\"disabled\"\n     [class.control--suffix]=\"hasSuffix\">\n\n  <div class=\"control__wrapper\"\n         cdkMonitorSubtreeFocus\n         (cdkFocusChange)=\"focusHandler($event)\">\n    <div class=\"control__value\"\n          [class.control__value--hidden]=\"!(focused | async) && !isFilled && hasLabel\">\n      <ng-content></ng-content>\n    </div>\n    <div class=\"control__label\" *ngIf=\"hasLabel\"\n          [class.control__label--focused]=\"focused | async\"\n          [class.control__label--filled]=\"isFilled\">\n      <ng-content select=\"ui-control-label\"></ng-content>\n    </div>\n  </div>\n\n  <div class=\"control__suffix\">\n    <ng-container\n      [ngTemplateOutlet]=\"hasSuffix ? suffixTemplate : clearingAvailable ? clearTemplate : null\"></ng-container>\n\n    <ng-template #clearTemplate>\n      <ui-control-suffix>\n        <a href=\"#\" title=\"Clear value\" (click)=\"clear(); $event.preventDefault()\" tabindex=\"-1\" aria-hidden=\"true\">\n          <ui-icon name=\"x\"></ui-icon>\n        </a>\n      </ui-control-suffix>\n    </ng-template>\n\n    <ng-template #suffixTemplate>\n      <ng-content select=\"ui-control-suffix\"></ng-content>\n    </ng-template>\n  </div>\n</div>\n\n<ng-container *ngIf=\"invalid else comment\">\n  <ui-validation-errors [errors]=\"errors\"></ui-validation-errors>\n</ng-container>\n\n<ng-template #comment>\n  <ng-content select=\"ui-control-comment\"></ng-content>\n</ng-template>\n", styles: [".transition{transition:all .5s ease-in}.transition-fast{transition:all .2s ease-in}:root{--value-opacity: 1}:host{display:block;width:100%;color:var(--color-contrast-50)}:host .control{position:relative;display:flex;width:100%;min-height:var(--field-height);padding:var(--field-padding);background:var(--field-bg);border:none;box-sizing:border-box;border-radius:var(--radius-regular);margin:0;line-height:1;outline:none;transition:.2s background ease-in-out}:host .control:after{content:\" \";position:absolute;height:1px;background:transparent;bottom:0;left:1rem;right:1rem}@media not all and (pointer: coarse){:host .control:hover{--field-bg: var(--field-bg-hover)}}:host .control--focused:after{background:var(--color-contrast-100)}:host .control--invalid :host .control__label{color:var(--color-critical)}:host .control--invalid:host .control--filled:after{background:var(--color-error)}:host .control--invalid:after{background:var(--color-error)}:host .control--disabled{--field-bg: var(--field-bg-disabled);--field-label-color: var(--field-label-color-disabled);--field-value-color: var(--field-value-color-disabled);cursor:not-allowed}@media not all and (pointer: coarse){:host .control--disabled:hover{--field-bg: var(--field-bg-disabled)}}:host .control--disabled .control__wrapper{pointer-events:none}:host .control--disabled .control__suffix{opacity:.5;pointer-events:none}:host .control__wrapper{flex:1;position:relative;box-sizing:border-box;display:flex;align-items:stretch;max-width:100%}:host .control__label{position:absolute;font-size:var(--field-font-size);color:var(--field-label-color);max-width:100%;top:var(--field-label-top);left:0;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;transition:transform .25s ease,font-size .25s ease;will-change:transform,font-size;line-height:1}:host .control__label--optional:after{content:\"(optional)\";display:inline;padding-left:.25rem}:host .control__label--filled,:host .control__label--focused{font-size:var(--field-label-focused-font-size);color:var(--color-contrast-40);transform:var(--field-label-focused-translate)}:host .control__value{display:flex;font-size:var(--field-font-size);color:var(--field-value-color);width:100%}:host .control__value--hidden{--value-opacity: 0}:host .control__suffix{flex-shrink:0}:host-context(ui-control-group) :host .control{border-radius:0}:host-context(ui-control-group) :host:first-child .control{border-top-left-radius:var(--radius-regular);border-bottom-left-radius:var(--radius-regular)}:host-context(ui-control-group) :host:last-child .control{border-top-right-radius:var(--radius-regular);border-bottom-right-radius:var(--radius-regular)}\n"] }]
        }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.NgModelGroup, decorators: [{
                    type: Optional
                }, {
                    type: Self
                }] }, { type: i1.NgModelGroup, decorators: [{
                    type: Optional
                }] }, { type: i1.NgForm, decorators: [{
                    type: Optional
                }] }]; }, propDecorators: { controls: [{
                type: ContentChildren,
                args: [NgControl, { descendants: true }]
            }], labelComponent: [{
                type: ContentChild,
                args: [ControlLabelComponent]
            }], suffixComponent: [{
                type: ContentChild,
                args: [ControlSuffixComponent]
            }], overlayOrigin: [{
                type: ViewChild,
                args: ['overlayOrigin']
            }], groupValidation: [{
                type: Input
            }], clearing: [{
                type: HostBinding,
                args: ['class.has-clearing']
            }], setClearing: [{
                type: Input,
                args: ['clearing']
            }], focused: [{
                type: Output
            }], hasNoLabel: [{
                type: HostBinding,
                args: ['class.no-label']
            }], hasSuffix: [{
                type: HostBinding,
                args: ['class.has-suffix']
            }] } });
//# sourceMappingURL=data:application/json;base64, 