UNPKG

@taiga-ui/kit

Version:

Taiga UI Angular main components kit

258 lines (251 loc) 18.9 kB
import { TuiDayRange, TUI_FIRST_DAY, TUI_LAST_DAY, TuiDay, TuiMonth } from '@taiga-ui/cdk/date-time'; import * as i0 from '@angular/core'; import { signal, inject, input, model, linkedSignal, untracked, ChangeDetectionStrategy, Component } from '@angular/core'; import { WA_IS_MOBILE } from '@ng-web-apis/platform'; import { TUI_FALSE_HANDLER } from '@taiga-ui/cdk/constants'; import { TuiMapperPipe } from '@taiga-ui/cdk/pipes/mapper'; import { tuiIsString, tuiNullableSame } from '@taiga-ui/cdk/utils/miscellaneous'; import { TuiCalendar, tuiCalendarSheetOptionsProvider } from '@taiga-ui/core/components/calendar'; import * as i1 from '@taiga-ui/core/components/data-list'; import { TuiDataList } from '@taiga-ui/core/components/data-list'; import { TuiIcon } from '@taiga-ui/core/components/icon'; import { TUI_TEXTFIELD_OPTIONS } from '@taiga-ui/core/components/textfield'; import { TUI_COMMON_ICONS, tuiAsAuxiliary } from '@taiga-ui/core/tokens'; import { TUI_OTHER_DATE_TEXT, TUI_DAY_RANGE_PERIODS } from '@taiga-ui/kit/tokens'; const calculateDisabledItemHandler = (disabledItemHandler, value, minLength) => (item) => { if (!value || value instanceof TuiDayRange || !minLength) { return disabledItemHandler(item); } const negativeMinLength = Object.fromEntries(Object.entries(minLength).map(([key, value]) => [key, -value])); const disabledBefore = value.append(negativeMinLength).append({ day: 1 }); const disabledAfter = value.append(minLength).append({ day: -1 }); const inDisabledRange = disabledBefore.dayBefore(item) && disabledAfter.dayAfter(item); return inDisabledRange || disabledItemHandler(item); }; const TUI_DAY_CAPS_MAPPER = (current, value, maxLength, backwards) => { if ( // TODO(v5): replace with `if (!(value instanceof TuiDay) || !maxLength)` (backward compatibility) (value instanceof TuiDayRange && !value.isSingleDay) || !value || !maxLength) { return backwards ? current || TUI_FIRST_DAY : current || TUI_LAST_DAY; } const negativeMaxLength = Object.fromEntries(Object.entries(maxLength).map(([key, value]) => [key, -value])); // TODO(v5): `value instanceof TuiDay` always `true` const from = value instanceof TuiDay ? value : value.from; const dateShift = from .append(backwards ? negativeMaxLength : maxLength) .append({ day: backwards ? 1 : -1 }); if (backwards) { return dateShift.dayBefore(current || TUI_FIRST_DAY) ? current || TUI_FIRST_DAY : dateShift; } if (!current) { return dateShift; } return dateShift.dayAfter(current) ? current : dateShift; }; class TuiCalendarRange { constructor() { /** * @deprecated use `item` */ this.selectedPeriod = null; this.previousValue = null; this.hoveredItem = null; this.month = signal(TuiMonth.currentLocal()); this.otherDateText = inject(TUI_OTHER_DATE_TEXT); this.icons = inject(TUI_COMMON_ICONS); this.capsMapper = TUI_DAY_CAPS_MAPPER; this.mobile = inject(WA_IS_MOBILE); this.options = inject(TUI_TEXTFIELD_OPTIONS); this.min = input(TUI_FIRST_DAY); this.max = input(TUI_LAST_DAY); this.minLength = input(null); this.maxLength = input(null); this.items = input([]); this.listSize = input(this.options.size()); this.defaultViewedMonth = input(TuiMonth.currentLocal()); this.markerHandler = input(null); this.disabledItemHandler = input(TUI_FALSE_HANDLER); this.value = model(null); this.item = model(null); this.currentValue = linkedSignal({ source: this.value, computation: (value, current) => { if (value !== current?.value) { untracked(() => this.initDefaultViewedMonth(value)); } return value; }, }); this.monthOffset = (value, month) => value.append({ month }); this.mapper = (items, min, max, minLength, otherDateText) => [ ...items.filter((item) => (minLength === null || item.range.from .append(minLength) .append({ day: -1 }) .daySameOrBefore(item.range.to)) && (min === null || item.range.to.daySameOrAfter(min)) && (max === null || item.range.from.daySameOrBefore(max))), otherDateText || '', ]; this.disabledMapper = (disabledItemHandler, value, minLength) => calculateDisabledItemHandler(disabledItemHandler, value, minLength); } /** * @deprecated use `item` */ get selectedActivePeriod() { return this.selectedPeriod; } /** * @deprecated use `item` */ set selectedActivePeriod(period) { this.selectedPeriod = period; } ngOnChanges({ defaultViewedMonth }) { if (this.currentValue()) { return; } if (defaultViewedMonth) { this.month.set(this.defaultViewedMonth()); } else { this.initDefaultViewedMonth(); } } ngOnInit() { this.initDefaultViewedMonth(); } onEsc(event) { if (event.key !== 'Escape' || !(this.currentValue() instanceof TuiDay)) { return; } event.stopPropagation(); this.currentValue.set(this.previousValue); } isItemActive(item) { const { activePeriod } = this; return ((tuiIsString(item) && activePeriod === null) || activePeriod === item || activePeriod?.toString() === item.toString()); } onItemSelect(item) { if (!tuiIsString(item)) { this.selectedActivePeriod = item; this.item.set(item); this.value.set(item.range.dayLimit(this.min(), this.max())); } else if (this.activePeriod !== null) { this.selectedActivePeriod = null; this.item.set(null); this.value.set(null); } this.initDefaultViewedMonth(); } onDayClick(day) { const value = this.currentValue(); this.previousValue = value; this.selectedActivePeriod = null; if (value instanceof TuiDay) { const range = TuiDayRange.sort(value, day); this.currentValue.set(range); this.item.set(this.findItemByDayRange(range)); this.value.set(range); } else { this.currentValue.set(day); } } get activePeriod() { const value = this.currentValue(); return (this.item() ?? this.selectedActivePeriod ?? (this.items().find((item) => tuiNullableSame(value instanceof TuiDay ? new TuiDayRange(value, value) : value, item.range, (a, b) => a.from.daySame(b.from.dayLimit(this.min(), this.max())) && a.to.daySame(b.to.dayLimit(this.min(), this.max())))) || null)); } initDefaultViewedMonth(value = this.currentValue()) { const min = this.min(); const max = this.max(); if (value instanceof TuiDay) { this.month.set(value); } else if (value) { this.month.set(this.items().length ? value.to : value.from); } else if (max && this.month().monthSameOrAfter(max)) { this.month.set(this.items().length ? max : max.append({ month: -1 })); } else if (min && this.month().monthSameOrBefore(min)) { this.month.set(min); } } findItemByDayRange(dayRange) { return this.items().find((item) => dayRange.daySame(item.range)) ?? null; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiCalendarRange, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: TuiCalendarRange, isStandalone: true, selector: "tui-calendar-range", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, listSize: { classPropertyName: "listSize", publicName: "listSize", isSignal: true, isRequired: false, transformFunction: null }, defaultViewedMonth: { classPropertyName: "defaultViewedMonth", publicName: "defaultViewedMonth", isSignal: true, isRequired: false, transformFunction: null }, markerHandler: { classPropertyName: "markerHandler", publicName: "markerHandler", isSignal: true, isRequired: false, transformFunction: null }, disabledItemHandler: { classPropertyName: "disabledItemHandler", publicName: "disabledItemHandler", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", item: "itemChange" }, host: { listeners: { "document:keydown.capture": "onEsc($event)" }, properties: { "class._mobile": "mobile" } }, providers: [ tuiAsAuxiliary(TuiCalendarRange), tuiCalendarSheetOptionsProvider({ rangeMode: true }), ], usesOnChanges: true, ngImport: i0, template: "<tui-calendar\n automation-id=\"tui-calendar-range__calendar\"\n [class.t-calendar]=\"!mobile\"\n [disabledItemHandler]=\"disabledItemHandler() | tuiMapper: disabledMapper : currentValue() : minLength()\"\n [markerHandler]=\"markerHandler()\"\n [max]=\"max() | tuiMapper: capsMapper : currentValue() : maxLength() : false\"\n [maxViewedMonth]=\"items().length || mobile ? null : (month() | tuiMapper: monthOffset : -1)\"\n [min]=\"min() | tuiMapper: capsMapper : currentValue() : maxLength() : true\"\n [month]=\"month()\"\n [showAdjacent]=\"!!items().length || mobile\"\n [value]=\"currentValue()\"\n [(hoveredItem)]=\"hoveredItem\"\n (dayClick)=\"onDayClick($event)\"\n (monthChange)=\"month.set($event)\"\n/>\n@if (!items().length && !mobile) {\n <tui-calendar\n [disabledItemHandler]=\"disabledItemHandler() | tuiMapper: disabledMapper : currentValue() : minLength()\"\n [markerHandler]=\"markerHandler()\"\n [max]=\"max() | tuiMapper: capsMapper : currentValue() : maxLength() : false\"\n [min]=\"min() | tuiMapper: capsMapper : currentValue() : maxLength() : true\"\n [minViewedMonth]=\"month() | tuiMapper: monthOffset : 1\"\n [month]=\"month() | tuiMapper: monthOffset : 1\"\n [showAdjacent]=\"false\"\n [value]=\"currentValue()\"\n [(hoveredItem)]=\"hoveredItem\"\n (dayClick)=\"onDayClick($event)\"\n (monthChange)=\"month.set($event.append({month: -1}))\"\n />\n} @else {\n @if (!mobile) {\n <tui-data-list\n automation-id=\"tui-calendar-range__menu\"\n role=\"menu\"\n [size]=\"listSize()\"\n [style.flex]=\"1\"\n >\n @for (item of items() | tuiMapper: mapper : min() : max() : minLength() : otherDateText(); track item) {\n <button\n automation-id=\"tui-calendar-range__menu__item\"\n role=\"menuitemradio\"\n tuiOption\n type=\"button\"\n [attr.aria-checked]=\"isItemActive(item)\"\n (click)=\"onItemSelect(item)\"\n (pointerdown.prevent.zoneless)=\"(0)\"\n >\n {{ item }}\n @if (isItemActive(item)) {\n <tui-icon\n automation-id=\"tui-calendar-range__checkmark\"\n class=\"t-check\"\n [icon]=\"icons.check\"\n />\n }\n </button>\n }\n </tui-data-list>\n }\n}\n", styles: [":host:not(._mobile){display:flex;min-inline-size:30rem}.t-calendar{border-inline-end:1px solid var(--tui-border-normal)}.t-check{font-size:1rem;margin-inline-start:auto}\n"], dependencies: [{ kind: "component", type: TuiCalendar, selector: "tui-calendar", inputs: ["disabledItemHandler", "min", "max", "minViewedMonth", "maxViewedMonth", "showAdjacent", "markerHandler", "initialView", "month", "hoveredItem", "value"], outputs: ["monthChange", "hoveredItemChange", "valueChange", "dayClick"] }, { kind: "component", type: i1.TuiDataListComponent, selector: "tui-data-list", inputs: ["emptyContent", "size"] }, { kind: "directive", type: i1.TuiOption, selector: "button[tuiOption], a[tuiOption], label[tuiOption]", inputs: ["disabled"] }, { kind: "component", type: TuiIcon, selector: "tui-icon:not([tuiBadge])", inputs: ["background"] }, { kind: "pipe", type: TuiMapperPipe, name: "tuiMapper" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiCalendarRange, decorators: [{ type: Component, args: [{ selector: 'tui-calendar-range', imports: [TuiCalendar, TuiDataList, TuiIcon, TuiMapperPipe], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ tuiAsAuxiliary(TuiCalendarRange), tuiCalendarSheetOptionsProvider({ rangeMode: true }), ], host: { '[class._mobile]': 'mobile', '(document:keydown.capture)': 'onEsc($event)', }, template: "<tui-calendar\n automation-id=\"tui-calendar-range__calendar\"\n [class.t-calendar]=\"!mobile\"\n [disabledItemHandler]=\"disabledItemHandler() | tuiMapper: disabledMapper : currentValue() : minLength()\"\n [markerHandler]=\"markerHandler()\"\n [max]=\"max() | tuiMapper: capsMapper : currentValue() : maxLength() : false\"\n [maxViewedMonth]=\"items().length || mobile ? null : (month() | tuiMapper: monthOffset : -1)\"\n [min]=\"min() | tuiMapper: capsMapper : currentValue() : maxLength() : true\"\n [month]=\"month()\"\n [showAdjacent]=\"!!items().length || mobile\"\n [value]=\"currentValue()\"\n [(hoveredItem)]=\"hoveredItem\"\n (dayClick)=\"onDayClick($event)\"\n (monthChange)=\"month.set($event)\"\n/>\n@if (!items().length && !mobile) {\n <tui-calendar\n [disabledItemHandler]=\"disabledItemHandler() | tuiMapper: disabledMapper : currentValue() : minLength()\"\n [markerHandler]=\"markerHandler()\"\n [max]=\"max() | tuiMapper: capsMapper : currentValue() : maxLength() : false\"\n [min]=\"min() | tuiMapper: capsMapper : currentValue() : maxLength() : true\"\n [minViewedMonth]=\"month() | tuiMapper: monthOffset : 1\"\n [month]=\"month() | tuiMapper: monthOffset : 1\"\n [showAdjacent]=\"false\"\n [value]=\"currentValue()\"\n [(hoveredItem)]=\"hoveredItem\"\n (dayClick)=\"onDayClick($event)\"\n (monthChange)=\"month.set($event.append({month: -1}))\"\n />\n} @else {\n @if (!mobile) {\n <tui-data-list\n automation-id=\"tui-calendar-range__menu\"\n role=\"menu\"\n [size]=\"listSize()\"\n [style.flex]=\"1\"\n >\n @for (item of items() | tuiMapper: mapper : min() : max() : minLength() : otherDateText(); track item) {\n <button\n automation-id=\"tui-calendar-range__menu__item\"\n role=\"menuitemradio\"\n tuiOption\n type=\"button\"\n [attr.aria-checked]=\"isItemActive(item)\"\n (click)=\"onItemSelect(item)\"\n (pointerdown.prevent.zoneless)=\"(0)\"\n >\n {{ item }}\n @if (isItemActive(item)) {\n <tui-icon\n automation-id=\"tui-calendar-range__checkmark\"\n class=\"t-check\"\n [icon]=\"icons.check\"\n />\n }\n </button>\n }\n </tui-data-list>\n }\n}\n", styles: [":host:not(._mobile){display:flex;min-inline-size:30rem}.t-calendar{border-inline-end:1px solid var(--tui-border-normal)}.t-check{font-size:1rem;margin-inline-start:auto}\n"] }] }] }); class TuiDayRangePeriod { constructor(range, name, content) { this.range = range; this.name = name; this.content = content; } toString() { return this.name; } } function getDefaultPeriodTitles() { try { return inject(TUI_DAY_RANGE_PERIODS)(); } catch { return [ 'For all the time', 'Today', 'Yesterday', 'Current week', 'Current month', 'Previous month', ]; } } function tuiCreateDefaultDayRangePeriods(periodTitles = getDefaultPeriodTitles()) { const today = TuiDay.currentLocal(); const yesterday = today.append({ day: -1 }); const startOfWeek = today.append({ day: -today.dayOfWeek() }); const endOfWeek = startOfWeek.append({ day: 6 }); const startOfMonth = today.append({ day: 1 - today.day }); const endOfMonth = startOfMonth.append({ month: 1, day: -1 }); const startOfLastMonth = startOfMonth.append({ month: -1 }); return [ new TuiDayRangePeriod(new TuiDayRange(TUI_FIRST_DAY, today), periodTitles[0]), new TuiDayRangePeriod(new TuiDayRange(today, today), periodTitles[1]), new TuiDayRangePeriod(new TuiDayRange(yesterday, yesterday), periodTitles[2]), new TuiDayRangePeriod(new TuiDayRange(startOfWeek, endOfWeek), periodTitles[3]), new TuiDayRangePeriod(new TuiDayRange(startOfMonth, endOfMonth), periodTitles[4]), new TuiDayRangePeriod(new TuiDayRange(startOfLastMonth, startOfMonth.append({ day: -1 })), periodTitles[5]), ]; } /** * Generated bundle index. Do not edit. */ export { TUI_DAY_CAPS_MAPPER, TuiCalendarRange, TuiDayRangePeriod, calculateDisabledItemHandler, tuiCreateDefaultDayRangePeriods }; //# sourceMappingURL=taiga-ui-kit-components-calendar-range.mjs.map