@taiga-ui/kit
Version:
Taiga UI Angular main components kit
258 lines (251 loc) • 18.9 kB
JavaScript
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