UNPKG

@taiga-ui/kit

Version:

Taiga UI Angular main components kit

233 lines (226 loc) 15.2 kB
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