@taiga-ui/kit
Version:
Taiga UI Angular main components kit
233 lines (226 loc) • 15.2 kB
JavaScript
import { TuiCalendar } from '@taiga-ui/core/components/calendar';
import { TuiLabel } from '@taiga-ui/core/components/label';
import * as i1$1 from '@taiga-ui/core/components/textfield';
import { tuiAsTextfieldAccessor, TuiTextfieldContent, TuiWithNativePicker, TuiTextfieldComponent, TuiTextfieldOptionsDirective } from '@taiga-ui/core/components/textfield';
import * as i2 from '@taiga-ui/core/portals/dropdown';
import { TuiDropdownAuto, TuiDropdownContent } from '@taiga-ui/core/portals/dropdown';
import * as i0 from '@angular/core';
import { InjectionToken, inject, effect, computed, input, untracked, Directive, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
import { TUI_VERSION } from '@taiga-ui/cdk/constants';
import { TuiTime, MILLISECONDS_IN_DAY, DATE_FILLER_LENGTH, TuiDay } from '@taiga-ui/cdk/date-time';
import { TuiNativeTimePicker } from '@taiga-ui/kit/components/input-time';
import * as i1 from '@maskito/angular';
import { MaskitoDirective } from '@maskito/angular';
import { maskitoDateTimeOptionsGenerator, maskitoSelectionChangeHandler } from '@maskito/kit';
import { TUI_IDENTITY_VALUE_TRANSFORMER, tuiAsControl, tuiValueTransformerFrom } from '@taiga-ui/cdk/classes';
import { tuiProvideOptions, tuiDirectiveBinding } from '@taiga-ui/cdk/utils/di';
import { tuiSum, tuiClamp } from '@taiga-ui/cdk/utils/math';
import { tuiSetSignal } from '@taiga-ui/cdk/utils/miscellaneous';
import { tuiAsOptionContent } from '@taiga-ui/core/components/data-list';
import * as i4 from '@taiga-ui/core/components/input';
import { TuiWithInput } from '@taiga-ui/core/components/input';
import * as i3 from '@taiga-ui/core/directives/items-handlers';
import { TuiItemsHandlersDirective, TuiItemsHandlersValidator } from '@taiga-ui/core/directives/items-handlers';
import { TUI_INPUT_DATE_OPTIONS, TUI_INPUT_DATE_DEFAULT_OPTIONS, TuiInputDateBase, tuiWithDateFiller } from '@taiga-ui/kit/components/input-date';
import { TuiSelectOption } from '@taiga-ui/kit/components/select';
import { TUI_TIME_TEXTS } from '@taiga-ui/kit/tokens';
import { tuiMaskito } from '@taiga-ui/kit/utils';
import { noop } from 'rxjs';
const TUI_INPUT_DATE_TIME_DEFAULT_OPTIONS = {
valueTransformer: TUI_IDENTITY_VALUE_TRANSFORMER,
timeMode: 'HH:MM',
dateTimeSeparator: ', ',
};
const TUI_INPUT_DATE_TIME_OPTIONS = new InjectionToken(ngDevMode ? 'TUI_INPUT_DATE_TIME_OPTIONS' : '', {
factory: () => ({
...inject(TUI_INPUT_DATE_OPTIONS),
...TUI_INPUT_DATE_TIME_DEFAULT_OPTIONS,
}),
});
const tuiInputDateTimeOptionsProvider = (options) => tuiProvideOptions(TUI_INPUT_DATE_TIME_OPTIONS, options, {
...TUI_INPUT_DATE_DEFAULT_OPTIONS,
...TUI_INPUT_DATE_TIME_DEFAULT_OPTIONS,
});
const MIN_TIME = new TuiTime(0, 0);
const MAX_TIME = TuiTime.fromAbsoluteMilliseconds(MILLISECONDS_IN_DAY - 1);
class TuiInputDateTimeDirective extends TuiInputDateBase {
constructor() {
super(...arguments);
this.timeFillers = inject(TUI_TIME_TEXTS);
this.options = inject(TUI_INPUT_DATE_TIME_OPTIONS);
this.filler = tuiWithDateFiller((date) => `${date}${this.options.dateTimeSeparator}${this.timeFillers()?.[this.timeMode()] ?? ''}`);
this.valueEffect = effect(noop);
this.identity = tuiDirectiveBinding(TuiItemsHandlersDirective, 'identityMatcher', (a, b) => tuiSum(...a.map(Number)) === tuiSum(...b.map(Number)), {});
this.disabledItemHandler = tuiDirectiveBinding(TuiItemsHandlersValidator, 'disabledItemHandler', computed(() => (value) => Boolean(value && this.handlers.disabledItemHandler()(value))));
this.mask = tuiMaskito(computed(() => this.computeMask({
dateMode: this.format().mode,
timeMode: this.timeMode(),
min: this.toNativeDate([this.min(), this.minTime()]),
max: this.toNativeDate([this.max(), this.maxTime()]),
dateSeparator: this.format().separator,
dateTimeSeparator: this.options.dateTimeSeparator,
})));
this.min = computed((min = this.minInput()) => Array.isArray(min) ? min[0] : (min ?? this.options.min));
this.max = computed((max = this.maxInput()) => Array.isArray(max) ? max[0] : (max ?? this.options.max));
this.minTime = computed((min = this.minInput()) => Array.isArray(min) ? min[1] : MIN_TIME);
this.maxTime = computed((max = this.maxInput()) => Array.isArray(max) ? max[1] : MAX_TIME);
this.timeMode = input(this.options.timeMode);
this.minInput = input(this.options.min, { alias: 'min' });
this.maxInput = input(this.options.max, { alias: 'max' });
}
setValue(value) {
this.onChange(value);
this.input.value.set(this.stringify(value));
}
setDate(newDate) {
const [date, time] = this.clampTime([newDate, this.value()?.[1] ?? null]);
this.setValue([date, time]);
this.open.set(false);
setTimeout((caretIndex = DATE_FILLER_LENGTH + this.options.dateTimeSeparator.length) => this.el.setSelectionRange(caretIndex, caretIndex));
}
writeValue(value) {
const reset = this.control.pristine && this.control.untouched && !value;
const changed = untracked(() => value !== this.value());
if (changed || reset) {
super.writeValue(value);
untracked(() => this.input.value.set(this.stringify(this.value())));
}
}
processCalendar(calendar) {
super.processCalendar(calendar);
tuiSetSignal(calendar.disabledItemHandler, (day) => this.handlers.disabledItemHandler()([day, null]));
}
onValueChange(value) {
this.input.value.set(value);
this.control?.control?.updateValueAndValidity({ emitEvent: false });
const [date = '', time = ''] = value.split(this.options.dateTimeSeparator);
const parsedDate = date.length >= DATE_FILLER_LENGTH
? TuiDay.normalizeParse(date, this.format().mode)
: null;
const parsedTime = time.length === this.timeMode().length ? TuiTime.fromString(time) : null;
if (!parsedDate || (time && !parsedTime)) {
return this.onChange(null);
}
const [prevDate, prevTime = null] = this.value() ?? [];
if (!prevDate?.daySame(parsedDate) || Number(parsedTime) !== Number(prevTime)) {
this.onChange([parsedDate, parsedTime]);
}
}
stringify(value) {
const [date, time] = value ?? [];
const dateString = date?.toString(this.format().mode, this.format().separator) ?? '';
const timeString = time?.toString(this.timeMode());
return timeString
? `${dateString}${this.options.dateTimeSeparator}${timeString}`
: dateString;
}
onBlur(valueWithAffixes) {
const [date = '', timeValue = ''] = valueWithAffixes.split(this.options.dateTimeSeparator);
if (timeValue && !this.value()) {
const time = TuiTime.fromString(timeValue);
const newValue = [
TuiDay.normalizeParse(date, this.format().mode),
time,
];
this.control?.control?.updateValueAndValidity({ emitEvent: false });
this.onChange(newValue);
this.input.value.set(this.stringify(newValue));
}
}
clampTime([date, time]) {
const min = date.daySame(this.min())
? this.minTime().toAbsoluteMilliseconds()
: -Infinity;
const max = date.daySame(this.max())
? this.maxTime().toAbsoluteMilliseconds()
: Infinity;
return [
date,
time &&
TuiTime.fromAbsoluteMilliseconds(tuiClamp(time.toAbsoluteMilliseconds(), min, max)),
];
}
computeMask(params) {
const options = maskitoDateTimeOptionsGenerator(params);
const { timeMode, dateMode, dateTimeSeparator } = params;
const inputModeSwitchPlugin = maskitoSelectionChangeHandler((element) => {
element.inputMode =
element.selectionStart >=
dateMode.length + dateTimeSeparator.length + timeMode.indexOf(' AA')
? 'text'
: 'numeric';
});
return {
...options,
plugins: options.plugins.concat(timeMode.includes('AA') ? inputModeSwitchPlugin : []),
};
}
toNativeDate([{ year, month, day }, { hours, minutes, seconds, ms }]) {
return new Date(year, month, day, hours, minutes, seconds, ms);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiInputDateTimeDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.21", type: TuiInputDateTimeDirective, isStandalone: true, selector: "input[tuiInputDateTime]", inputs: { timeMode: { classPropertyName: "timeMode", publicName: "timeMode", isSignal: true, isRequired: false, transformFunction: null }, minInput: { classPropertyName: "minInput", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, maxInput: { classPropertyName: "maxInput", publicName: "max", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "blur": "onBlur($event.target.value)" } }, providers: [
tuiAsOptionContent(TuiSelectOption),
tuiAsControl(TuiInputDateTimeDirective),
tuiAsTextfieldAccessor(TuiInputDateTimeDirective),
tuiValueTransformerFrom(TUI_INPUT_DATE_TIME_OPTIONS),
], usesInheritance: true, hostDirectives: [{ directive: i1.MaskitoDirective }, { directive: i2.TuiDropdownAuto }, { directive: i3.TuiItemsHandlersValidator }, { directive: i4.TuiWithInput }], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiInputDateTimeDirective, decorators: [{
type: Directive,
args: [{
selector: 'input[tuiInputDateTime]',
providers: [
tuiAsOptionContent(TuiSelectOption),
tuiAsControl(TuiInputDateTimeDirective),
tuiAsTextfieldAccessor(TuiInputDateTimeDirective),
tuiValueTransformerFrom(TUI_INPUT_DATE_TIME_OPTIONS),
],
hostDirectives: [
MaskitoDirective,
TuiDropdownAuto,
TuiItemsHandlersValidator,
TuiWithInput,
],
host: { '(blur)': 'onBlur($event.target.value)' },
}]
}] });
class TuiInputDateTimeComponent extends TuiNativeTimePicker {
constructor() {
super(...arguments);
this.host = inject(TuiInputDateTimeDirective);
this.step = computed(() => this.getStep(this.host.timeMode()));
this.value = computed(() => this.toISOString(this.host.value()));
this.min = computed(() => this.toISOString([this.host.min(), this.host.minTime()]));
this.max = computed(() => this.toISOString([this.host.max(), this.host.maxTime()]));
}
onInput(value) {
if (!value) {
return this.host.setValue(null);
}
const date = new Date(value);
const day = TuiDay.fromLocalNativeDate(date);
const time = TuiTime.fromLocalNativeDate(date);
this.host.setValue([day, time]);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiInputDateTimeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: TuiInputDateTimeComponent, isStandalone: true, selector: "input[tuiInputDateTime][type=\"datetime-local\"]", host: { attributes: { "data-tui-version": "5.7.0", "ngSkipHydration": "true" } }, usesInheritance: true, hostDirectives: [{ directive: i1$1.TuiWithNativePicker }], ngImport: i0, template: "@if (host.native) {\n <input\n *tuiTextfieldContent\n type=\"datetime-local\"\n [attr.list]=\"list\"\n [max]=\"max()\"\n [min]=\"min()\"\n [step]=\"step()\"\n [value]=\"value()\"\n (click.stop.zoneless)=\"(0)\"\n (input)=\"onInput($any($event.target).value)\"\n (pointerdown.stop.zoneless)=\"(0)\"\n />\n}\n", styles: ["tui-textfield input[tuiInputDateTime]:where(*[data-tui-version=\"5.7.0\"])~.t-content input[type=datetime-local]{position:absolute;inset-block-start:0;inset-inline-start:auto;inset-inline-end:0;inset-block-end:0;inline-size:2.5rem;padding:0;opacity:0;pointer-events:auto}tui-textfield input[tuiInputDateTime]:where(*[data-tui-version=\"5.7.0\"])~.t-content input[type=datetime-local]::-webkit-calendar-picker-indicator{position:absolute;inset-block-start:0;inset-inline-start:0;inline-size:100%;block-size:100%}\n"], dependencies: [{ kind: "directive", type: TuiTextfieldContent, selector: "ng-template[tuiTextfieldContent]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiInputDateTimeComponent, decorators: [{
type: Component,
args: [{ selector: 'input[tuiInputDateTime][type="datetime-local"]', imports: [TuiTextfieldContent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [TuiWithNativePicker], host: { 'data-tui-version': TUI_VERSION, ngSkipHydration: 'true' }, template: "@if (host.native) {\n <input\n *tuiTextfieldContent\n type=\"datetime-local\"\n [attr.list]=\"list\"\n [max]=\"max()\"\n [min]=\"min()\"\n [step]=\"step()\"\n [value]=\"value()\"\n (click.stop.zoneless)=\"(0)\"\n (input)=\"onInput($any($event.target).value)\"\n (pointerdown.stop.zoneless)=\"(0)\"\n />\n}\n", styles: ["tui-textfield input[tuiInputDateTime]:where(*[data-tui-version=\"5.7.0\"])~.t-content input[type=datetime-local]{position:absolute;inset-block-start:0;inset-inline-start:auto;inset-inline-end:0;inset-block-end:0;inline-size:2.5rem;padding:0;opacity:0;pointer-events:auto}tui-textfield input[tuiInputDateTime]:where(*[data-tui-version=\"5.7.0\"])~.t-content input[type=datetime-local]::-webkit-calendar-picker-indicator{position:absolute;inset-block-start:0;inset-inline-start:0;inline-size:100%;block-size:100%}\n"] }]
}] });
const TuiInputDateTime = [
TuiInputDateTimeDirective,
TuiInputDateTimeComponent,
TuiCalendar,
TuiLabel,
TuiTextfieldComponent,
TuiTextfieldOptionsDirective,
TuiDropdownContent,
];
/**
* Generated bundle index. Do not edit.
*/
export { TUI_INPUT_DATE_TIME_DEFAULT_OPTIONS, TUI_INPUT_DATE_TIME_OPTIONS, TuiInputDateTime, TuiInputDateTimeComponent, TuiInputDateTimeDirective, tuiInputDateTimeOptionsProvider };
//# sourceMappingURL=taiga-ui-kit-components-input-date-time.mjs.map