import * as i0 from '@angular/core';
import { InjectionToken, inject, Injectable, input, computed, viewChildren, Component, ChangeDetectionStrategy, ViewEncapsulation, Injector, booleanAttribute, output, signal, Directive, NgModule } from '@angular/core';
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
import * as i1 from '@angular/forms';
import { FormGroup, FormControl, NG_VALUE_ACCESSOR, NG_VALIDATORS, ReactiveFormsModule, NgControl } from '@angular/forms';
import * as i3$1 from '@koobiq/components/button';
import { KbqButtonModule } from '@koobiq/components/button';
import { DateAdapter, DateFormatter, ruRULocaleData, KBQ_LOCALE_SERVICE, PopUpSizes, PopUpPlacements } from '@koobiq/components/core';
import * as i2$2 from '@koobiq/components/popover';
import { KbqPopoverTrigger, KbqPopoverModule } from '@koobiq/components/popover';
import { NgTemplateOutlet } from '@angular/common';
import * as i2 from '@koobiq/components/datepicker';
import { KbqDatepickerModule } from '@koobiq/components/datepicker';
import * as i3 from '@koobiq/components/form-field';
import { KbqFieldset, KbqFieldsetItem, KbqFormFieldModule, KbqFormFieldControl } from '@koobiq/components/form-field';
import * as i2$1 from '@koobiq/components/icon';
import { KbqIcon, KbqIconModule } from '@koobiq/components/icon';
import * as i5 from '@koobiq/components/radio';
import { KbqRadioModule } from '@koobiq/components/radio';
import * as i4 from '@koobiq/components/timepicker';
import { KbqTimepicker, TimeFormats, KbqTimepickerModule } from '@koobiq/components/timepicker';
import { merge, Subject } from 'rxjs';
import { map, distinctUntilChanged } from 'rxjs/operators';
import * as i1$1 from '@koobiq/components/link';
import { KbqLinkModule } from '@koobiq/components/link';

/** Preset of selectable time ranges, provided by DI. */
const KBQ_DEFAULT_TIME_RANGE_TYPES = new InjectionToken('KBQ_DEFAULT_TIME_RANGE_TYPES');
/** Preset of custom time ranges, provided by DI. */
const KBQ_CUSTOM_TIME_RANGE_TYPES = new InjectionToken('KBQ_CUSTOM_TIME_RANGE_TYPES');
/** Time range types in range editor if nothing provided */
const defaultTimeRangeTypes = [
    'lastHour',
    'last24Hours',
    'last3Days',
    'last7Days',
    'last14Days',
    'currentQuarter',
    'currentYear',
    'allTime',
    'range'
];
/** @docs-private */
function createMissingDateImplError(componentName, provider) {
    return Error(`${componentName}: No provider found for ${provider}. You must import one of the existing ` +
        `modules at your application root or provide a custom implementation or use exists ones.`);
}
/**
 * Validates that the 'from' date-time is not greater than the 'to' date-time in a range form.
 * Returns an error if the start date-time occurs after the end date-time.
 *
 * @param timeRangeService - Service used to manipulate date-time values.
 */
const rangeValidator = (timeRangeService) => {
    return (control) => {
        const form = control.value;
        if (!form.fromTime || !form.fromDate || !form.toTime || !form.toDate) {
            return null;
        }
        const fromDateTime = timeRangeService.combineDateAndTime(form.fromDate, form.fromTime);
        const toDateTime = timeRangeService.combineDateAndTime(form.toDate, form.toTime);
        return timeRangeService.dateAdapter.compareDate(fromDateTime, toDateTime) > 0
            ? { fromIsGreaterThanTo: fromDateTime }
            : null;
    };
};

class KbqTimeRangeService {
    constructor() {
        this.dateAdapter = inject(DateAdapter);
        this.dateFormatter = inject(DateFormatter);
        this.providedDefaultTimeRangeTypes = inject(KBQ_DEFAULT_TIME_RANGE_TYPES, { optional: true }) || defaultTimeRangeTypes;
        this.customTimeRangeTypes = inject(KBQ_CUSTOM_TIME_RANGE_TYPES, { optional: true });
        this.DEFAULT_RANGE_TYPE = 'lastHour';
        this.timeRangeConfig = {
            lastMinute: { units: { minutes: -1 }, translationType: 'minutes' },
            last5Minutes: { units: { minutes: -5 }, translationType: 'minutes' },
            last15Minutes: { units: { minutes: -15 }, translationType: 'minutes' },
            last30Minutes: { units: { minutes: -30 }, translationType: 'minutes' },
            lastHour: { units: { hours: -1 }, translationType: 'hours' },
            last24Hours: { units: { hours: -24 }, translationType: 'hours' },
            last3Days: { units: { days: -3 }, translationType: 'days' },
            last7Days: { units: { days: -7 }, translationType: 'days' },
            last14Days: { units: { days: -14 }, translationType: 'days' },
            last30Days: { units: { days: -30 }, translationType: 'days' },
            last3Months: { units: { months: -3 }, translationType: 'months' },
            last12Months: { units: { months: -12 }, translationType: 'months' },
            allTime: { units: {}, translationType: 'other' },
            currentQuarter: { units: {}, translationType: 'other' },
            currentYear: { units: {}, translationType: 'other' },
            range: { units: {}, translationType: 'other' }
        };
        this.lastUnitsRange = (unitsInfo) => KbqTimeRangeService.range(this.dateAdapter.toIso8601(this.dateAdapter.addCalendarUnits(this.dateAdapter.today(), unitsInfo)));
        if (!this.dateAdapter) {
            throw createMissingDateImplError('KbqTimeRange', 'DateAdapter');
        }
        this.customTimeRangeTypes
            ?.filter(({ type }) => {
            return !this.timeRangeConfig[type];
        })
            .forEach((type) => this.add(type));
    }
    static { this.range = (dateTimeISOString) => ({
        startDateTime: dateTimeISOString
    }); }
    add({ type, ...customTimeRangeConfig }) {
        this.timeRangeConfig[type] = customTimeRangeConfig;
    }
    getTimeRangeTypeUnits(type) {
        return this.timeRangeConfig[type].units;
    }
    getTimeRangeUnitByType(type) {
        return this.timeRangeConfig[type].translationType;
    }
    getDefaultRangeValue() {
        const from = this.dateAdapter.addCalendarUnits(this.dateAdapter.today(), { days: -1 });
        const to = this.dateAdapter.today();
        return {
            fromTime: this.omitMilliseconds(from),
            fromDate: this.omitMilliseconds(from),
            toTime: this.omitMilliseconds(to),
            toDate: this.omitMilliseconds(to)
        };
    }
    getTimeRangeDefaultValue(rangeValue, availableTimeRangeTypes = []) {
        const defaultType = availableTimeRangeTypes[0] ?? this.providedDefaultTimeRangeTypes[0] ?? this.DEFAULT_RANGE_TYPE;
        return {
            ...this.calculateTimeRange(defaultType, rangeValue || this.getDefaultRangeValue()),
            type: defaultType
        };
    }
    calculateTimeRange(type, rangeValue) {
        if (!type) {
            return {};
        }
        if (type === 'range') {
            const checkedRangeValue = rangeValue || this.getDefaultRangeValue();
            return {
                startDateTime: checkedRangeValue.fromDate && checkedRangeValue.fromTime
                    ? this.dateAdapter.toIso8601(this.combineDateAndTime(checkedRangeValue.fromDate, checkedRangeValue.fromTime))
                    : '',
                endDateTime: checkedRangeValue.toDate && checkedRangeValue.toTime
                    ? this.dateAdapter.toIso8601(this.combineDateAndTime(checkedRangeValue.toDate, checkedRangeValue.toTime))
                    : ''
            };
        }
        switch (this.getTimeRangeUnitByType(type)) {
            case 'other': {
                switch (type) {
                    case 'currentQuarter':
                        return KbqTimeRangeService.range(this.dateAdapter.toIso8601(this.dateAdapter.startOf(this.dateAdapter.today(), 'quarter')));
                    case 'currentYear':
                        return KbqTimeRangeService.range(this.dateAdapter.toIso8601(this.dateAdapter.startOf(this.dateAdapter.today(), 'year')));
                    case 'allTime':
                    default: {
                        return this.timeRangeConfig[type].range ?? {};
                    }
                }
            }
            default: {
                return this.lastUnitsRange(this.getTimeRangeTypeUnits(type));
            }
        }
    }
    combineDateAndTime(date, time) {
        return this.dateAdapter.createDateTime(this.dateAdapter.getYear(date), this.dateAdapter.getMonth(date), this.dateAdapter.getDate(date), this.dateAdapter.getHours(time), this.dateAdapter.getMinutes(time), this.dateAdapter.getSeconds(time), this.dateAdapter.getMilliseconds(time));
    }
    checkAndCorrectTimeRangeValue(value, availableTimeRangeTypes, rangeValue) {
        let result = value && (!availableTimeRangeTypes.length || availableTimeRangeTypes.includes(value.type))
            ? value
            : this.getTimeRangeDefaultValue(rangeValue, availableTimeRangeTypes);
        if (!result.startDateTime || (result.type === 'range' && (!result.startDateTime || !result.endDateTime))) {
            result = {
                ...this.calculateTimeRange(result.type, rangeValue),
                type: result.type
            };
        }
        return result;
    }
    omitMilliseconds(date) {
        return this.dateAdapter.createDateTime(this.dateAdapter.getYear(date), this.dateAdapter.getMonth(date), this.dateAdapter.getDate(date), this.dateAdapter.getHours(date), this.dateAdapter.getMinutes(date), this.dateAdapter.getSeconds(date), 0);
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeService, decorators: [{
            type: Injectable
        }], ctorParameters: () => [] });

class RangeErrorStateMatcher {
    isErrorState(control, form) {
        return !!form?.invalid || !!control?.invalid;
    }
}
/** @docs-private */
class KbqTimeRangeEditor {
    constructor() {
        this.timeRangeService = inject(KbqTimeRangeService);
        /** The maximum selectable date. */
        this.maxDate = input(null);
        /** The minimum selectable date. */
        this.minDate = input(null);
        /** Preset of selectable ranges */
        this.availableTimeRangeTypes = input(this.timeRangeService.providedDefaultTimeRangeTypes);
        /** Provided value of selected range */
        this.rangeValue = input(this.timeRangeService.getDefaultRangeValue());
        this.showRangeAsDefault = input.required();
        this.localeConfiguration = input.required();
        /** Customizable option output */
        this.optionTemplate = input();
        /** @docs-private */
        this.isRangeVisible = computed(() => this.showRangeAsDefault() || this.availableTimeRangeTypes().includes('range'));
        /** @docs-private */
        this.timeRangeTypesWithoutRange = computed(() => {
            const localeConfig = this.localeConfiguration();
            return this.availableTimeRangeTypes()
                .filter((type) => type !== 'range')
                .map((type) => ({
                type,
                translationType: this.timeRangeService.getTimeRangeUnitByType(type),
                units: this.timeRangeService.getTimeRangeTypeUnits(type),
                formattedValue: this.getFormattedOption(type, localeConfig)
            }));
        });
        /** @docs-private */
        this.timepickerList = viewChildren(KbqTimepicker);
        /** @docs-private */
        this.timepickerFormat = TimeFormats.HHmmss;
        /** @docs-private */
        this.rangeStateMatcher = new RangeErrorStateMatcher();
        this.lastValidationErrorOnEmit = null;
        /** @docs-private */
        this.onChange = (_value) => { };
        /** @docs-private */
        this.onTouch = () => { };
        const defaultRangeValue = this.rangeValue();
        this.form = new FormGroup({
            type: new FormControl(this.timeRangeService.DEFAULT_RANGE_TYPE, {
                nonNullable: true
            }),
            fromTime: new FormControl(defaultRangeValue.fromTime, { nonNullable: true }),
            fromDate: new FormControl(defaultRangeValue.fromDate, { nonNullable: true }),
            toTime: new FormControl(defaultRangeValue.toTime, { nonNullable: true }),
            toDate: new FormControl(defaultRangeValue.toDate, { nonNullable: true })
        }, { validators: rangeValidator(this.timeRangeService) });
        const rangeControls = [
            this.form.controls.fromTime,
            this.form.controls.fromDate,
            this.form.controls.toTime,
            this.form.controls.toDate
        ];
        merge(...rangeControls.map((control) => control.statusChanges))
            .pipe(takeUntilDestroyed())
            .subscribe(() => (this.lastValidationErrorOnEmit = this.concatControlValidationErrors()));
        this.form.valueChanges
            .pipe(map((formValue) => formValue.type), distinctUntilChanged(), takeUntilDestroyed())
            .subscribe((type) => {
            const isDisabled = type !== 'range';
            rangeControls.forEach((control) => {
                if (isDisabled) {
                    control.disable({ emitEvent: false });
                }
                else {
                    control.enable({ emitEvent: false });
                }
            });
        });
        this.form.valueChanges.pipe(takeUntilDestroyed()).subscribe((formValue) => {
            const range = this.mapTimeRange(formValue);
            if (range)
                this.onChange(range);
        });
        this.form.statusChanges.pipe(takeUntilDestroyed()).subscribe((status) => {
            const timepickerList = this.timepickerList();
            if (timepickerList.at(0)) {
                timepickerList.at(0).errorState = status === 'INVALID';
            }
        });
    }
    ngOnInit() {
        const defaultRangeValue = this.rangeValue();
        const availableTimeRangeTypes = this.availableTimeRangeTypes();
        this.form.setValue({
            type: (availableTimeRangeTypes.length && availableTimeRangeTypes[0]) || 'range',
            fromTime: defaultRangeValue.fromTime,
            fromDate: defaultRangeValue.fromDate,
            toTime: defaultRangeValue.toTime,
            toDate: defaultRangeValue.toDate
        });
    }
    /** @docs-private */
    validate() {
        return this.form.errors || this.lastValidationErrorOnEmit;
    }
    /** Implemented as part of ControlValueAccessor */
    writeValue(value) {
        if (!value)
            return;
        const corrected = this.timeRangeService.checkAndCorrectTimeRangeValue(value, this.availableTimeRangeTypes(), this.form.value);
        this.form.controls.type.setValue(corrected.type);
        if (corrected.type === 'range' && corrected.startDateTime && corrected.endDateTime) {
            const from = this.timeRangeService.dateAdapter.deserialize(corrected.startDateTime);
            const to = this.timeRangeService.dateAdapter.deserialize(corrected.endDateTime);
            this.form.patchValue({
                fromTime: from,
                fromDate: from,
                toTime: to,
                toDate: to
            });
        }
    }
    /** Implemented as part of ControlValueAccessor */
    registerOnChange(fn) {
        this.onChange = fn;
    }
    /** Implemented as part of ControlValueAccessor */
    registerOnTouched(fn) {
        this.onTouch = fn;
    }
    mapTimeRange({ type }) {
        if (!type)
            return;
        return {
            type,
            ...this.timeRangeService.calculateTimeRange(type, {
                // use control.value, since via form.value control values can be undefined
                fromTime: this.form.controls.fromTime.value,
                fromDate: this.form.controls.fromDate.value,
                toDate: this.form.controls.toTime.value,
                toTime: this.form.controls.toTime.value
            })
        };
    }
    getFormattedOption(type, localeConfig) {
        const translationType = this.timeRangeService.getTimeRangeUnitByType(type);
        if (translationType === 'other')
            return '';
        const range = this.timeRangeService.calculateTimeRange(type);
        return this.timeRangeService.dateFormatter.duration(this.timeRangeService.dateAdapter.deserialize(range.startDateTime), this.timeRangeService.dateAdapter.today(), [translationType], false, localeConfig.durationTemplate.option);
    }
    concatControlValidationErrors() {
        let result = this.form.errors;
        Object.values(this.form.controls).forEach((control) => {
            if (control.errors) {
                result = {
                    ...result,
                    ...control.errors
                };
            }
        });
        return result;
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeEditor, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: KbqTimeRangeEditor, isStandalone: true, selector: "kbq-time-range-editor", inputs: { maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, availableTimeRangeTypes: { classPropertyName: "availableTimeRangeTypes", publicName: "availableTimeRangeTypes", isSignal: true, isRequired: false, transformFunction: null }, rangeValue: { classPropertyName: "rangeValue", publicName: "rangeValue", isSignal: true, isRequired: false, transformFunction: null }, showRangeAsDefault: { classPropertyName: "showRangeAsDefault", publicName: "showRangeAsDefault", isSignal: true, isRequired: true, transformFunction: null }, localeConfiguration: { classPropertyName: "localeConfiguration", publicName: "localeConfiguration", isSignal: true, isRequired: true, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "kbq-time-range__editor" }, providers: [
            {
                multi: true,
                provide: NG_VALUE_ACCESSOR,
                useExisting: KbqTimeRangeEditor
            },
            {
                multi: true,
                provide: NG_VALIDATORS,
                useExisting: KbqTimeRangeEditor
            }
        ], viewQueries: [{ propertyName: "timepickerList", predicate: KbqTimepicker, descendants: true, isSignal: true }], ngImport: i0, template: "<form [formGroup]=\"form\">\n    <kbq-radio-group class=\"kbq-time-range-editor__container\" [formControl]=\"form.controls.type\">\n        @let types = timeRangeTypesWithoutRange();\n\n        @if (types.length) {\n            <div class=\"kbq-time-range-editor__predefined\">\n                @for (type of types; track type) {\n                    <kbq-radio-button class=\"kbq-time-range-editor__predefined-option\" [value]=\"type.type\">\n                        <ng-container\n                            *ngTemplateOutlet=\"optionTemplate() || defaultOptionTemplate; context: { $implicit: type }\"\n                        />\n                    </kbq-radio-button>\n                }\n            </div>\n        }\n\n        @if (isRangeVisible()) {\n            @let localeConfig = localeConfiguration();\n\n            <div class=\"kbq-time-range-editor__range\" role=\"group\">\n                @if (types.length) {\n                    <kbq-radio-button [value]=\"'range'\">{{ localeConfig.editor.rangeLabel }}</kbq-radio-button>\n                }\n\n                <div class=\"kbq-time-range-editor__date-time\">\n                    <span class=\"kbq-time-range-editor__date-time-prefix\" [attr.aria-label]=\"localeConfig.editor.from\">\n                        {{ localeConfig.editor.from }}\n                    </span>\n                    <kbq-fieldset>\n                        <kbq-form-field kbqFieldsetItem>\n                            <i kbq-icon=\"kbq-clock_16\" kbqPrefix [autoColor]=\"true\"></i>\n                            <input kbqTimepicker [format]=\"timepickerFormat\" [formControl]=\"form.controls.fromTime\" />\n                        </kbq-form-field>\n\n                        <kbq-form-field>\n                            <input\n                                [min]=\"minDate()\"\n                                [max]=\"maxDate()\"\n                                [kbqDatepicker]=\"datepickerFrom\"\n                                [formControl]=\"form.controls.fromDate\"\n                                [errorStateMatcher]=\"rangeStateMatcher\"\n                            />\n                            <kbq-datepicker-toggle-icon kbqSuffix [for]=\"datepickerFrom\" />\n                            <kbq-datepicker #datepickerFrom [minDate]=\"minDate()\" [maxDate]=\"maxDate()\" />\n                        </kbq-form-field>\n                    </kbq-fieldset>\n                </div>\n\n                <div class=\"kbq-time-range-editor__date-time\">\n                    <span class=\"kbq-time-range-editor__date-time-prefix\" [attr.aria-label]=\"localeConfig.editor.to\">\n                        {{ localeConfig.editor.to }}\n                    </span>\n                    <kbq-fieldset>\n                        <kbq-form-field kbqFieldsetItem>\n                            <i kbq-icon=\"kbq-clock_16\" kbqPrefix [autoColor]=\"true\"></i>\n                            <input kbqTimepicker [format]=\"timepickerFormat\" [formControl]=\"form.controls.toTime\" />\n                        </kbq-form-field>\n\n                        <kbq-form-field>\n                            <input\n                                [min]=\"minDate()\"\n                                [max]=\"maxDate()\"\n                                [kbqDatepicker]=\"datepickerTo\"\n                                [formControl]=\"form.controls.toDate\"\n                                [errorStateMatcher]=\"rangeStateMatcher\"\n                            />\n                            <kbq-datepicker-toggle-icon kbqSuffix [for]=\"datepickerTo\" />\n                            <kbq-datepicker #datepickerTo [minDate]=\"minDate()\" [maxDate]=\"maxDate()\" />\n                        </kbq-form-field>\n                    </kbq-fieldset>\n                </div>\n            </div>\n        }\n    </kbq-radio-group>\n</form>\n\n<ng-template #defaultOptionTemplate let-context>\n    @let localeConfig = localeConfiguration();\n    @switch (context.translationType) {\n        @case ('other') {\n            @switch (context.type) {\n                @case ('allTime') {\n                    {{ localeConfig.editor.allTime }}\n                }\n                @case ('currentQuarter') {\n                    {{ localeConfig.editor.currentQuarter }}\n                }\n                @case ('currentYear') {\n                    {{ localeConfig.editor.currentYear }}\n                }\n            }\n        }\n        @default {\n            {{ context.formattedValue }}\n        }\n    }\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: KbqFieldset, selector: "kbq-fieldset" }, { kind: "directive", type: KbqFieldsetItem, selector: "[kbqFieldsetItem]" }, { kind: "ngmodule", type: KbqDatepickerModule }, { kind: "component", type: i2.KbqDatepicker, selector: "kbq-datepicker", inputs: ["hasBackdrop", "startAt", "disabled", "opened", "minDate", "maxDate", "panelClass", "dateClass", "backdropClass"], outputs: ["yearSelected", "monthSelected", "opened", "closed"], exportAs: ["kbqDatepicker"] }, { kind: "directive", type: i2.KbqDatepickerInput, selector: "input[kbqDatepicker], input[kbqCalendar]", inputs: ["errorStateMatcher", "placeholder", "required", "kbqDatepicker", "kbqCalendar", "kbqDatepickerFilter", "value", "min", "max", "disabled", "id", "kbqValidationTooltip"], outputs: ["incorrectInput", "dateChange", "dateInput"], exportAs: ["kbqDatepickerInput"] }, { kind: "component", type: i2.KbqDatepickerToggleIconComponent, selector: "kbq-datepicker-toggle-icon", inputs: ["disabled", "for"] }, { kind: "component", type: i3.KbqFormField, selector: "kbq-form-field", inputs: ["noBorders"], exportAs: ["kbqFormField"] }, { kind: "directive", type: i3.KbqPrefix, selector: "[kbqPrefix]", exportAs: ["kbqPrefix"] }, { kind: "directive", type: i3.KbqSuffix, selector: "[kbqSuffix]" }, { kind: "directive", type: i3.KbqValidateDirective, selector: "        input[kbqInput],        input[kbqNumberInput],        input[kbqInputPassword],        input[kbqTimepicker],        input[kbqDatepicker],        textarea[kbqTextarea],        kbq-select,        kbq-tree-select,        kbq-tag-list    ", exportAs: ["KbqValidate"] }, { kind: "ngmodule", type: KbqFormFieldModule }, { kind: "ngmodule", type: KbqTimepickerModule }, { kind: "directive", type: i4.KbqTimepicker, selector: "input[kbqTimepicker]", inputs: ["placeholder", "disabled", "id", "required", "format", "min", "max", "value", "kbqValidationTooltip"], outputs: ["incorrectInput"], exportAs: ["kbqTimepicker"] }, { kind: "ngmodule", type: KbqRadioModule }, { kind: "directive", type: i5.KbqRadioGroup, selector: "kbq-radio-group", inputs: ["big", "name", "labelPosition", "value", "selected", "disabled", "required"], outputs: ["change"], exportAs: ["kbqRadioGroup"] }, { kind: "component", type: i5.KbqRadioButton, selector: "kbq-radio-button", inputs: ["checked", "value", "disabled", "tabIndex", "required", "labelPosition", "name", "isFocused", "id"], outputs: ["change"], exportAs: ["kbqRadioButton"] }, { kind: "component", type: KbqIcon, selector: "[kbq-icon]", inputs: ["small", "autoColor", "kbq-icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeEditor, decorators: [{
            type: Component,
            args: [{ selector: 'kbq-time-range-editor', standalone: true, imports: [
                        NgTemplateOutlet,
                        ReactiveFormsModule,
                        KbqFieldset,
                        KbqFieldsetItem,
                        KbqDatepickerModule,
                        KbqFormFieldModule,
                        KbqTimepickerModule,
                        KbqRadioModule,
                        KbqIcon
                    ], host: {
                        class: 'kbq-time-range__editor'
                    }, providers: [
                        {
                            multi: true,
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: KbqTimeRangeEditor
                        },
                        {
                            multi: true,
                            provide: NG_VALIDATORS,
                            useExisting: KbqTimeRangeEditor
                        }
                    ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<form [formGroup]=\"form\">\n    <kbq-radio-group class=\"kbq-time-range-editor__container\" [formControl]=\"form.controls.type\">\n        @let types = timeRangeTypesWithoutRange();\n\n        @if (types.length) {\n            <div class=\"kbq-time-range-editor__predefined\">\n                @for (type of types; track type) {\n                    <kbq-radio-button class=\"kbq-time-range-editor__predefined-option\" [value]=\"type.type\">\n                        <ng-container\n                            *ngTemplateOutlet=\"optionTemplate() || defaultOptionTemplate; context: { $implicit: type }\"\n                        />\n                    </kbq-radio-button>\n                }\n            </div>\n        }\n\n        @if (isRangeVisible()) {\n            @let localeConfig = localeConfiguration();\n\n            <div class=\"kbq-time-range-editor__range\" role=\"group\">\n                @if (types.length) {\n                    <kbq-radio-button [value]=\"'range'\">{{ localeConfig.editor.rangeLabel }}</kbq-radio-button>\n                }\n\n                <div class=\"kbq-time-range-editor__date-time\">\n                    <span class=\"kbq-time-range-editor__date-time-prefix\" [attr.aria-label]=\"localeConfig.editor.from\">\n                        {{ localeConfig.editor.from }}\n                    </span>\n                    <kbq-fieldset>\n                        <kbq-form-field kbqFieldsetItem>\n                            <i kbq-icon=\"kbq-clock_16\" kbqPrefix [autoColor]=\"true\"></i>\n                            <input kbqTimepicker [format]=\"timepickerFormat\" [formControl]=\"form.controls.fromTime\" />\n                        </kbq-form-field>\n\n                        <kbq-form-field>\n                            <input\n                                [min]=\"minDate()\"\n                                [max]=\"maxDate()\"\n                                [kbqDatepicker]=\"datepickerFrom\"\n                                [formControl]=\"form.controls.fromDate\"\n                                [errorStateMatcher]=\"rangeStateMatcher\"\n                            />\n                            <kbq-datepicker-toggle-icon kbqSuffix [for]=\"datepickerFrom\" />\n                            <kbq-datepicker #datepickerFrom [minDate]=\"minDate()\" [maxDate]=\"maxDate()\" />\n                        </kbq-form-field>\n                    </kbq-fieldset>\n                </div>\n\n                <div class=\"kbq-time-range-editor__date-time\">\n                    <span class=\"kbq-time-range-editor__date-time-prefix\" [attr.aria-label]=\"localeConfig.editor.to\">\n                        {{ localeConfig.editor.to }}\n                    </span>\n                    <kbq-fieldset>\n                        <kbq-form-field kbqFieldsetItem>\n                            <i kbq-icon=\"kbq-clock_16\" kbqPrefix [autoColor]=\"true\"></i>\n                            <input kbqTimepicker [format]=\"timepickerFormat\" [formControl]=\"form.controls.toTime\" />\n                        </kbq-form-field>\n\n                        <kbq-form-field>\n                            <input\n                                [min]=\"minDate()\"\n                                [max]=\"maxDate()\"\n                                [kbqDatepicker]=\"datepickerTo\"\n                                [formControl]=\"form.controls.toDate\"\n                                [errorStateMatcher]=\"rangeStateMatcher\"\n                            />\n                            <kbq-datepicker-toggle-icon kbqSuffix [for]=\"datepickerTo\" />\n                            <kbq-datepicker #datepickerTo [minDate]=\"minDate()\" [maxDate]=\"maxDate()\" />\n                        </kbq-form-field>\n                    </kbq-fieldset>\n                </div>\n            </div>\n        }\n    </kbq-radio-group>\n</form>\n\n<ng-template #defaultOptionTemplate let-context>\n    @let localeConfig = localeConfiguration();\n    @switch (context.translationType) {\n        @case ('other') {\n            @switch (context.type) {\n                @case ('allTime') {\n                    {{ localeConfig.editor.allTime }}\n                }\n                @case ('currentQuarter') {\n                    {{ localeConfig.editor.currentQuarter }}\n                }\n                @case ('currentYear') {\n                    {{ localeConfig.editor.currentYear }}\n                }\n            }\n        }\n        @default {\n            {{ context.formattedValue }}\n        }\n    }\n</ng-template>\n" }]
        }], ctorParameters: () => [] });

/** @docs-private */
class KbqTimeRangeTitle {
    constructor() {
        this.timeRangeService = inject(KbqTimeRangeService);
        this.popover = inject(KbqPopoverTrigger, { host: true });
        this.injector = inject(Injector);
        this.timeRange = input.required();
        this.localeConfiguration = input.required();
        this.titleTemplate = input();
        this.context = computed(() => {
            const timeRange = this.timeRange();
            if (!timeRange)
                return undefined;
            return {
                ...timeRange,
                ...this.timeRangeService.getTimeRangeTypeUnits(timeRange.type)
            };
        });
        this.titleContext = computed(() => {
            const context = this.context();
            const formattedDate = this.formattedDate();
            let customizableTitleContext = { formattedDate, popover: this.popover };
            if (context) {
                customizableTitleContext = { ...context, ...customizableTitleContext };
            }
            return {
                $implicit: customizableTitleContext,
                ...customizableTitleContext
            };
        });
        this.formattedDate = computed(() => {
            const context = this.context();
            const localeConfiguration = this.localeConfiguration();
            if (!context) {
                return localeConfiguration.title.placeholder;
            }
            const timeRangeUnit = this.timeRangeService.getTimeRangeUnitByType(context.type);
            if (timeRangeUnit === 'other') {
                switch (context.type) {
                    case 'range': {
                        return (localeConfiguration.title.for +
                            ' ' +
                            this.timeRangeService.dateFormatter.rangeLongDate(this.timeRangeService.dateAdapter.deserialize(context.startDateTime ?? ''), this.timeRangeService.dateAdapter.deserialize(context.endDateTime ?? '')));
                    }
                    case 'allTime': {
                        return localeConfiguration.editor.allTime;
                    }
                    case 'currentQuarter': {
                        return localeConfiguration.editor.currentQuarter;
                    }
                    case 'currentYear': {
                        return localeConfiguration.editor.currentYear;
                    }
                    default: {
                        return '';
                    }
                }
            }
            if (!context.startDateTime)
                return '';
            return (localeConfiguration.title.for +
                ' ' +
                this.timeRangeService.dateFormatter.duration(this.timeRangeService.dateAdapter.deserialize(context.startDateTime), this.timeRangeService.dateAdapter.today(), [timeRangeUnit], false, localeConfiguration.durationTemplate.title));
        });
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeTitle, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: KbqTimeRangeTitle, isStandalone: true, selector: "kbq-time-range-title", inputs: { timeRange: { classPropertyName: "timeRange", publicName: "timeRange", isSignal: true, isRequired: true, transformFunction: null }, localeConfiguration: { classPropertyName: "localeConfiguration", publicName: "localeConfiguration", isSignal: true, isRequired: true, transformFunction: null }, titleTemplate: { classPropertyName: "titleTemplate", publicName: "titleTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
        @if (titleTemplate()) {
            <ng-container *ngTemplateOutlet="titleTemplate()!; context: titleContext() ?? null; injector: injector" />
        } @else {
            <a kbq-link pseudo>
                <span class="kbq-link__text">{{ formattedDate() }}</span>

                <i kbq-icon="kbq-calendar-o_16"></i>
            </a>
        }
    `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: KbqLinkModule }, { kind: "directive", type: i1$1.KbqLink, selector: "[kbq-link]", inputs: ["disabled", "tabIndex", "pseudo", "noUnderline", "big", "compact", "useVisited", "print"], exportAs: ["kbqLink"] }, { kind: "ngmodule", type: KbqIconModule }, { kind: "component", type: i2$1.KbqIcon, selector: "[kbq-icon]", inputs: ["small", "autoColor", "kbq-icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeTitle, decorators: [{
            type: Component,
            args: [{
                    standalone: true,
                    selector: 'kbq-time-range-title',
                    imports: [
                        NgTemplateOutlet,
                        KbqLinkModule,
                        KbqIconModule
                    ],
                    template: `
        @if (titleTemplate()) {
            <ng-container *ngTemplateOutlet="titleTemplate()!; context: titleContext() ?? null; injector: injector" />
        } @else {
            <a kbq-link pseudo>
                <span class="kbq-link__text">{{ formattedDate() }}</span>

                <i kbq-icon="kbq-calendar-o_16"></i>
            </a>
        }
    `,
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }] });

/** Localization configuration provider. */
const KBQ_TIME_RANGE_LOCALE_CONFIGURATION = new InjectionToken('KBQ_TIME_RANGE_LOCALE_CONFIGURATION', { factory: () => ruRULocaleData.timeRange });
/** Utility provider for `KBQ_TIME_RANGE_LOCALE_CONFIGURATION`. */
const kbqTimeRangeLocaleConfigurationProvider = (configuration) => ({
    provide: KBQ_TIME_RANGE_LOCALE_CONFIGURATION,
    useValue: configuration
});
class KbqTimeRange {
    constructor() {
        this.timeRangeService = inject(KbqTimeRangeService);
        this.localeService = inject(KBQ_LOCALE_SERVICE, { optional: true });
        /** @docs-private */
        this.ngControl = inject(NgControl, { optional: true, self: true });
        /** The minimum selectable date. */
        this.minDate = input();
        /** The maximum selectable date. */
        this.maxDate = input();
        /** provided value of selected range */
        this.defaultRangeValue = input();
        /** Preset of selectable ranges */
        this.availableTimeRangeTypes = input(this.timeRangeService.providedDefaultTimeRangeTypes);
        /** Customizable trigger output */
        this.titleTemplate = input();
        /** Customizable option output */
        this.optionTemplate = input();
        /** Whether to show popover with arrow */
        this.arrow = input(true, { transform: booleanAttribute });
        /**
         * Whether to show range in popover if not provided
         * @see availableTimeRangeTypes
         */
        this.showRangeAsDefault = input(true);
        /** Whether component should fallback to default value if null provided */
        this.nonNullable = input(true, { transform: booleanAttribute });
        /** Emit value update if provided value via formControl wasn't valid */
        this.valueCorrected = output();
        /**
         * Used to calculate time range.
         * @docs-private */
        this.normalizedDefaultRangeValue = computed(() => ({
            ...this.timeRangeService.getDefaultRangeValue(),
            ...this.defaultRangeValue()
        }));
        /** @docs-private */
        this.popoverSize = PopUpSizes.Medium;
        /** @docs-private */
        this.popupPlacement = PopUpPlacements.BottomLeft;
        /** @docs-private */
        this.localeConfiguration = signal(inject(KBQ_TIME_RANGE_LOCALE_CONFIGURATION));
        /** @docs-private */
        this.onChange = (_value) => { };
        /** @docs-private */
        this.onTouch = () => { };
        this.handleAvailableTypesChange = (types) => {
            if (types.includes(this.rangeEditorControl.value.type) || this.rangeEditorControl.value.type === 'range') {
                return;
            }
            const timeRangeDefaultValue = this.timeRangeService.getTimeRangeDefaultValue(this.normalizedDefaultRangeValue(), types.length ? types : ['range']);
            this.titleValue.set(timeRangeDefaultValue);
            this.rangeEditorControl.setValue(timeRangeDefaultValue);
            this.onChange(timeRangeDefaultValue);
        };
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
        const defaultValue = this.timeRangeService.getTimeRangeDefaultValue(this.normalizedDefaultRangeValue(), this.availableTimeRangeTypes());
        this.titleValue = signal(this.nonNullable() ? defaultValue : null);
        this.rangeEditorControl = new FormControl(defaultValue, { nonNullable: true });
        this.localeService?.changes.pipe(takeUntilDestroyed()).subscribe(() => {
            this.localeConfiguration.set(this.localeService?.getParams('timeRange') ?? ruRULocaleData.timeRange);
        });
        toObservable(this.availableTimeRangeTypes)
            .pipe(takeUntilDestroyed())
            .subscribe(this.handleAvailableTypesChange);
    }
    ngOnInit() {
        // call again on init, so input signals values will be correct
        this.writeValue(this.ngControl?.value ?? null);
    }
    /** Implemented as part of ControlValueAccessor */
    writeValue(value) {
        const nonNullable = this.nonNullable();
        const availableTimeRangeTypes = this.availableTimeRangeTypes();
        const corrected = this.timeRangeService.checkAndCorrectTimeRangeValue(value, availableTimeRangeTypes, this.normalizedDefaultRangeValue());
        if ((value && value.type && !('startDateTime' in value && availableTimeRangeTypes.includes(value.type))) ||
            (nonNullable && value === null)) {
            this.valueCorrected.emit(corrected);
        }
        this.titleValue.set(nonNullable || value !== null ? corrected : null);
        this.rangeEditorControl.setValue(corrected);
    }
    /** @docs-private */
    onApply(popover) {
        this.titleValue.set(this.rangeEditorControl.value);
        this.onChange(this.rangeEditorControl.value);
        popover.hide();
    }
    /** @docs-private */
    onCancel(popover) {
        popover.hide();
    }
    onVisibleChange(isVisible) {
        const titleValue = this.titleValue();
        if (!isVisible && titleValue) {
            this.rangeEditorControl.setValue(titleValue);
        }
    }
    /** Implemented as part of ControlValueAccessor */
    registerOnChange(fn) {
        this.onChange = fn;
    }
    /** Implemented as part of ControlValueAccessor */
    registerOnTouched(fn) {
        this.onTouch = fn;
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRange, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: KbqTimeRange, isStandalone: true, selector: "kbq-time-range", inputs: { minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, defaultRangeValue: { classPropertyName: "defaultRangeValue", publicName: "defaultRangeValue", isSignal: true, isRequired: false, transformFunction: null }, availableTimeRangeTypes: { classPropertyName: "availableTimeRangeTypes", publicName: "availableTimeRangeTypes", isSignal: true, isRequired: false, transformFunction: null }, titleTemplate: { classPropertyName: "titleTemplate", publicName: "titleTemplate", isSignal: true, isRequired: false, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, arrow: { classPropertyName: "arrow", publicName: "arrow", isSignal: true, isRequired: false, transformFunction: null }, showRangeAsDefault: { classPropertyName: "showRangeAsDefault", publicName: "showRangeAsDefault", isSignal: true, isRequired: false, transformFunction: null }, nonNullable: { classPropertyName: "nonNullable", publicName: "nonNullable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueCorrected: "valueCorrected" }, host: { classAttribute: "kbq-time-range" }, providers: [KbqTimeRangeService], ngImport: i0, template: `
        @let localeConfig = localeConfiguration();
        <kbq-time-range-title
            #popover="kbqPopover"
            class="kbq-time-range__trigger"
            kbqPopover
            kbqPopoverClass="kbq-time-range__popover"
            [kbqPopoverSize]="popoverSize"
            [kbqPopoverContent]="timeRangePopoverContent"
            [kbqPopoverFooter]="timeRangePopoverFooter"
            [kbqPopoverPlacement]="popupPlacement"
            [kbqPopoverArrow]="arrow()"
            [titleTemplate]="titleTemplate()"
            [timeRange]="titleValue()"
            [localeConfiguration]="localeConfig"
            (kbqPopoverVisibleChange)="onVisibleChange($event)"
        />

        <ng-template #timeRangePopoverContent>
            <kbq-time-range-editor
                [maxDate]="maxDate()"
                [minDate]="minDate()"
                [formControl]="rangeEditorControl"
                [localeConfiguration]="localeConfig"
                [showRangeAsDefault]="showRangeAsDefault()"
                [rangeValue]="normalizedDefaultRangeValue()"
                [availableTimeRangeTypes]="availableTimeRangeTypes()"
                [optionTemplate]="optionTemplate()"
            />
        </ng-template>

        <ng-template #timeRangePopoverFooter>
            <div class="kbq-time-range__buttons" role="group">
                <button
                    kbq-button
                    [color]="'contrast'"
                    [disabled]="rangeEditorControl.invalid"
                    (click)="onApply(popover)"
                >
                    {{ localeConfig.editor.apply }}
                </button>

                <button kbq-button (click)="onCancel(popover)">{{ localeConfig.editor.cancel }}</button>
            </div>
        </ng-template>
    `, isInline: true, styles: [".kbq-time-range .kbq-time-range__trigger{display:block}.kbq-time-range__popover .kbq-time-range__buttons{display:flex;flex-direction:row;gap:var(--kbq-size-l)}.kbq-time-range__editor{display:block}.kbq-time-range__editor .kbq-time-range-editor__container{width:100%}.kbq-time-range__editor .kbq-time-range-editor__predefined{column-count:2}.kbq-time-range__editor .kbq-time-range-editor__predefined .kbq-time-range-editor__predefined-option{display:block;margin-bottom:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range{display:flex;flex-direction:column;gap:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__predefined{column-count:2}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__predefined .kbq-time-range-editor__predefined-option{display:block}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time{display:flex;flex-direction:row;justify-content:space-between;gap:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time .kbq-time-range-editor__date-time-prefix{align-self:center;width:57px}.kbq-time-range-title-as-form-field{white-space:nowrap;text-overflow:ellipsis;min-height:calc(var(--kbq-form-field-size-height) - 2 * var(--kbq-size-border-width))}.kbq-time-range-title-as-form-field .kbq-time-range-title__placeholder{color:var(--kbq-foreground-contrast-tertiary)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: KbqPopoverModule }, { kind: "directive", type: i2$2.KbqPopoverTrigger, selector: "[kbqPopover]", inputs: ["kbqPopoverPreventClose", "defaultPaddings", "kbqPopoverVisible", "kbqPopoverPlacement", "kbqPopoverPlacementPriority", "hasBackdrop", "kbqPopoverHeader", "kbqPopoverContent", "kbqPopoverFooter", "kbqPopoverDisabled", "kbqTrigger", "kbqPopoverSize", "kbqPopoverClass", "kbqPopoverContext", "hasCloseButton", "closeOnScroll", "backdropClass", "kbqPopoverArrow", "kbqPopoverOffset", "kbqLeaveDelay"], outputs: ["kbqPopoverPlacementChange", "kbqPopoverVisibleChange"], exportAs: ["kbqPopover"] }, { kind: "ngmodule", type: KbqButtonModule }, { kind: "component", type: i3$1.KbqButton, selector: "[kbq-button]", inputs: ["kbqStyle", "disabled", "tabIndex"] }, { kind: "directive", type: i3$1.KbqButtonCssStyler, selector: "[kbq-button]" }, { kind: "component", type: KbqTimeRangeEditor, selector: "kbq-time-range-editor", inputs: ["maxDate", "minDate", "availableTimeRangeTypes", "rangeValue", "showRangeAsDefault", "localeConfiguration", "optionTemplate"] }, { kind: "component", type: KbqTimeRangeTitle, selector: "kbq-time-range-title", inputs: ["timeRange", "localeConfiguration", "titleTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRange, decorators: [{
            type: Component,
            args: [{ standalone: true, selector: 'kbq-time-range', template: `
        @let localeConfig = localeConfiguration();
        <kbq-time-range-title
            #popover="kbqPopover"
            class="kbq-time-range__trigger"
            kbqPopover
            kbqPopoverClass="kbq-time-range__popover"
            [kbqPopoverSize]="popoverSize"
            [kbqPopoverContent]="timeRangePopoverContent"
            [kbqPopoverFooter]="timeRangePopoverFooter"
            [kbqPopoverPlacement]="popupPlacement"
            [kbqPopoverArrow]="arrow()"
            [titleTemplate]="titleTemplate()"
            [timeRange]="titleValue()"
            [localeConfiguration]="localeConfig"
            (kbqPopoverVisibleChange)="onVisibleChange($event)"
        />

        <ng-template #timeRangePopoverContent>
            <kbq-time-range-editor
                [maxDate]="maxDate()"
                [minDate]="minDate()"
                [formControl]="rangeEditorControl"
                [localeConfiguration]="localeConfig"
                [showRangeAsDefault]="showRangeAsDefault()"
                [rangeValue]="normalizedDefaultRangeValue()"
                [availableTimeRangeTypes]="availableTimeRangeTypes()"
                [optionTemplate]="optionTemplate()"
            />
        </ng-template>

        <ng-template #timeRangePopoverFooter>
            <div class="kbq-time-range__buttons" role="group">
                <button
                    kbq-button
                    [color]="'contrast'"
                    [disabled]="rangeEditorControl.invalid"
                    (click)="onApply(popover)"
                >
                    {{ localeConfig.editor.apply }}
                </button>

                <button kbq-button (click)="onCancel(popover)">{{ localeConfig.editor.cancel }}</button>
            </div>
        </ng-template>
    `, imports: [
                        ReactiveFormsModule,
                        KbqPopoverModule,
                        KbqButtonModule,
                        KbqTimeRangeEditor,
                        KbqTimeRangeTitle
                    ], host: {
                        class: 'kbq-time-range'
                    }, providers: [KbqTimeRangeService], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [".kbq-time-range .kbq-time-range__trigger{display:block}.kbq-time-range__popover .kbq-time-range__buttons{display:flex;flex-direction:row;gap:var(--kbq-size-l)}.kbq-time-range__editor{display:block}.kbq-time-range__editor .kbq-time-range-editor__container{width:100%}.kbq-time-range__editor .kbq-time-range-editor__predefined{column-count:2}.kbq-time-range__editor .kbq-time-range-editor__predefined .kbq-time-range-editor__predefined-option{display:block;margin-bottom:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range{display:flex;flex-direction:column;gap:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__predefined{column-count:2}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__predefined .kbq-time-range-editor__predefined-option{display:block}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time{display:flex;flex-direction:row;justify-content:space-between;gap:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time .kbq-time-range-editor__date-time-prefix{align-self:center;width:57px}.kbq-time-range-title-as-form-field{white-space:nowrap;text-overflow:ellipsis;min-height:calc(var(--kbq-form-field-size-height) - 2 * var(--kbq-size-border-width))}.kbq-time-range-title-as-form-field .kbq-time-range-title__placeholder{color:var(--kbq-foreground-contrast-tertiary)}\n"] }]
        }], ctorParameters: () => [] });

/** Directive for easy using styles of time-range placeholder publicly. */
class KbqTimeRangeTitlePlaceholder {
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeTitlePlaceholder, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqTimeRangeTitlePlaceholder, isStandalone: true, selector: "[kbqTimeRangeTitlePlaceholder]", host: { classAttribute: "kbq-time-range-title__placeholder" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeTitlePlaceholder, decorators: [{
            type: Directive,
            args: [{
                    standalone: true,
                    selector: '[kbqTimeRangeTitlePlaceholder]',
                    host: {
                        class: 'kbq-time-range-title__placeholder'
                    }
                }]
        }] });
/** Component simulates `KbqFormFieldControl` allowing to provide custom content inside `KbqFormField` */
class KbqTimeRangeTitleAsControl {
    constructor() {
        this.timeRange = inject(KbqTimeRange);
        /** @docs-private */
        this.controlType = 'select';
        /** @docs-private */
        this.stateChanges = new Subject();
        /** @docs-private */
        this.ngControl = this.timeRange.ngControl;
    }
    /** @docs-private */
    onContainerClick(_event) { }
    /** @docs-private */
    focus(_options) { }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeTitleAsControl, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: KbqTimeRangeTitleAsControl, isStandalone: true, selector: "kbq-time-range-title-as-control", host: { properties: { "attr.tabindex": "0" }, classAttribute: "kbq-time-range-title-as-form-field" }, providers: [
            {
                provide: KbqFormFieldControl,
                useExisting: KbqTimeRangeTitleAsControl
            }
        ], ngImport: i0, template: `
        <ng-content />
    `, isInline: true, styles: [":host{display:flex;align-items:center}:host:focus-visible{outline:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeTitleAsControl, decorators: [{
            type: Component,
            args: [{ standalone: true, selector: 'kbq-time-range-title-as-control', template: `
        <ng-content />
    `, providers: [
                        {
                            provide: KbqFormFieldControl,
                            useExisting: KbqTimeRangeTitleAsControl
                        }
                    ], host: {
                        '[attr.tabindex]': '0',
                        class: 'kbq-time-range-title-as-form-field'
                    }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:flex;align-items:center}:host:focus-visible{outline:none}\n"] }]
        }] });

const COMPONENTS = [
    KbqTimeRange,
    KbqTimeRangeTitle,
    KbqTimeRangeEditor,
    KbqTimeRangeTitlePlaceholder,
    KbqTimeRangeTitleAsControl
];
class KbqTimeRangeModule {
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeModule, imports: [KbqTimeRange,
            KbqTimeRangeTitle,
            KbqTimeRangeEditor,
            KbqTimeRangeTitlePlaceholder,
            KbqTimeRangeTitleAsControl], exports: [KbqTimeRange,
            KbqTimeRangeTitle,
            KbqTimeRangeEditor,
            KbqTimeRangeTitlePlaceholder,
            KbqTimeRangeTitleAsControl] }); }
    /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeModule, imports: [KbqTimeRange,
            KbqTimeRangeTitle,
            KbqTimeRangeEditor] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTimeRangeModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: COMPONENTS,
                    exports: COMPONENTS
                }]
        }] });

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

export { KBQ_CUSTOM_TIME_RANGE_TYPES, KBQ_DEFAULT_TIME_RANGE_TYPES, KBQ_TIME_RANGE_LOCALE_CONFIGURATION, KbqTimeRange, KbqTimeRangeEditor, KbqTimeRangeModule, KbqTimeRangeTitle, KbqTimeRangeTitleAsControl, KbqTimeRangeTitlePlaceholder, createMissingDateImplError, defaultTimeRangeTypes, kbqTimeRangeLocaleConfigurationProvider, rangeValidator };
//# sourceMappingURL=koobiq-components-time-range.mjs.map
