@taiga-ui/kit
Version:
Taiga UI Angular main components kit
156 lines (151 loc) • 20.4 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, computed, linkedSignal, untracked, input, model, output, ChangeDetectionStrategy, Component } from '@angular/core';
import { TUI_FALSE_HANDLER } from '@taiga-ui/cdk/constants';
import { TuiDay, TuiMonthRange, TuiMonth, TUI_FIRST_DAY, TUI_LAST_DAY, TuiYear } from '@taiga-ui/cdk/date-time';
import { TuiHovered } from '@taiga-ui/cdk/directives/hovered';
import { tuiNullableSame } from '@taiga-ui/cdk/utils/miscellaneous';
import { TuiCalendarYear } from '@taiga-ui/core/components/calendar';
import { TuiLink } from '@taiga-ui/core/components/link';
import { TuiScrollbar } from '@taiga-ui/core/components/scrollbar';
import { TuiSpinButton } from '@taiga-ui/core/components/spin-button';
import { tuiAsAuxiliary } from '@taiga-ui/core/tokens';
import { TUI_CALENDAR_MONTHS } from '@taiga-ui/kit/tokens';
import { tuiCreateOptions } from '@taiga-ui/cdk/utils/di';
const TUI_CALENDAR_MONTH_DEFAULT_OPTIONS = {
rangeMode: false,
};
const [TUI_CALENDAR_MONTH_OPTIONS, tuiCalendarMonthOptionsProvider] = tuiCreateOptions(TUI_CALENDAR_MONTH_DEFAULT_OPTIONS);
const TODAY = TuiDay.currentLocal();
class TuiCalendarMonth {
constructor() {
this.hoveredItem = null;
this.isYearPickerShown = false;
this.months = inject(TUI_CALENDAR_MONTHS);
this.isRangePicking = computed((x = this.value()) => (!this.options.rangeMode && x instanceof TuiMonthRange && x.isSingleMonth) || // TODO(v5): remove this condition
(this.options.rangeMode && x instanceof TuiMonth));
this.handler = computed(() => this.calculateDisabledItemHandlerWithMinMax(this.disabledItemHandler(), this.value(), this.isRangePicking(), this.min(), this.max(), this.minLength(), this.maxLength()));
this.activeYear = linkedSignal(() => {
const year = this.year();
if (year) {
return year;
}
const value = untracked(this.value);
if (value instanceof TuiMonth) {
return value;
}
return value instanceof TuiMonthRange ? value.from : TODAY;
});
this.value = input(null);
this.minLength = input(null);
this.maxLength = input(null);
this.disabledItemHandler = input(TUI_FALSE_HANDLER);
this.min = input(TUI_FIRST_DAY, {
transform: (x) => x ?? TUI_FIRST_DAY,
});
this.max = input(TUI_LAST_DAY, {
transform: (x) => x ?? TUI_LAST_DAY,
});
this.year = model();
this.monthClick = output();
this.hoveredItemChange = output();
this.options = inject(TUI_CALENDAR_MONTH_OPTIONS);
}
onNextYear() {
this.updateActiveYear(this.activeYear().append({ year: 1 }));
}
onPreviousYear() {
this.updateActiveYear(this.activeYear().append({ year: -1 }));
}
getItemRange(item) {
const value = this.value();
const { hoveredItem } = this;
if (!value) {
return null;
}
if (!this.options.rangeMode && value instanceof TuiMonth) {
return value?.monthSame(item) ? 'active' : null;
}
const selectedRange = value instanceof TuiMonth ? new TuiMonthRange(value, value) : value;
const months = item.month + item.year * 12;
const hovered = hoveredItem ? hoveredItem.month + hoveredItem.year * 12 : null;
const from = selectedRange.from.month + selectedRange.from.year * 12;
const to = selectedRange.to.month + selectedRange.to.year * 12;
const picking = this.isRangePicking() ? hovered : null;
const min = Math.min(from, to, picking ?? from);
const max = Math.max(from, to, picking ?? from);
if (min === max && min === months) {
return 'active';
}
if (min === months) {
return 'start';
}
if (max === months) {
return 'end';
}
return min < months && months < max ? 'middle' : null;
}
getTuiMonth(monthNumber, yearNumber) {
return new TuiMonth(yearNumber, monthNumber);
}
isItemToday(item) {
return TODAY.monthSame(item);
}
onPickerYearClick(year) {
this.isYearPickerShown = false;
if (this.activeYear().year !== year) {
this.updateActiveYear(new TuiYear(year));
}
}
onItemClick(month) {
if (!this.handler()(month)) {
this.monthClick.emit(month);
}
}
onYearClick() {
this.isYearPickerShown = true;
}
onItemHovered(hovered, item) {
this.updateHoveredItem(hovered ? item : null);
}
// eslint-disable-next-line @typescript-eslint/max-params,max-params
calculateDisabledItemHandlerWithMinMax(disabledItemHandler, value, isRangePicking, min, max, minLength, maxLength) {
return (item) => {
const selectedMonth = value instanceof TuiMonthRange ? value.from : value;
const delta = isRangePicking && selectedMonth
? Math.abs(item.year * 12 +
item.month -
selectedMonth.year * 12 -
selectedMonth.month)
: 0;
const tooLong = delta && maxLength && delta > maxLength;
const tooShort = delta && minLength && delta < minLength;
return (tooLong ||
tooShort ||
item.monthBefore(min) ||
item.monthAfter(max) ||
disabledItemHandler(item));
};
}
updateHoveredItem(month) {
if (tuiNullableSame(this.hoveredItem, month, (a, b) => a.monthSame(b))) {
return;
}
this.hoveredItem = month;
this.hoveredItemChange.emit(month);
}
updateActiveYear(year) {
this.activeYear.set(year);
this.year.set(year);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiCalendarMonth, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: TuiCalendarMonth, isStandalone: true, selector: "tui-calendar-month", inputs: { value: { classPropertyName: "value", publicName: "value", 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 }, disabledItemHandler: { classPropertyName: "disabledItemHandler", publicName: "disabledItemHandler", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, year: { classPropertyName: "year", publicName: "year", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { year: "yearChange", monthClick: "monthClick", hoveredItemChange: "hoveredItemChange" }, host: { properties: { "class._picking": "isRangePicking()" } }, providers: [tuiAsAuxiliary(TuiCalendarMonth)], ngImport: i0, template: "@if (isYearPickerShown) {\n <tui-scrollbar class=\"t-scrollbar\">\n <tui-calendar-year\n [initialItem]=\"activeYear().year\"\n [max]=\"max().year\"\n [min]=\"min().year\"\n [rangeMode]=\"options.rangeMode\"\n [value]=\"value()\"\n (yearClick)=\"onPickerYearClick($event)\"\n />\n </tui-scrollbar>\n} @else {\n <tui-spin-button\n class=\"t-spin\"\n [focusable]=\"false\"\n [leftDisabled]=\"activeYear().yearSameOrBefore(min())\"\n [rightDisabled]=\"activeYear().yearSameOrAfter(max())\"\n (leftClick)=\"onPreviousYear()\"\n (rightClick)=\"onNextYear()\"\n >\n <button\n automation-id=\"tui-calendar-month__active-year\"\n tabIndex=\"-1\"\n tuiLink\n type=\"button\"\n (click)=\"onYearClick()\"\n >\n {{ activeYear().formattedYear }}\n </button>\n </tui-spin-button>\n @for (_ of '-'.repeat(3); track $index) {\n @let row = $index;\n <div class=\"t-row\">\n @for (_ of '-'.repeat(4); track $index) {\n @let item = getTuiMonth(row * 4 + $index, activeYear().year);\n <div\n class=\"t-cell\"\n [attr.data-range]=\"getItemRange(item)\"\n [class.t-cell_disabled]=\"handler()(item)\"\n [class.t-cell_today]=\"isItemToday(item)\"\n (click)=\"onItemClick(item)\"\n (tuiHoveredChange)=\"onItemHovered($event, item)\"\n >\n {{ months()[row * 4 + $index] }}\n </div>\n }\n </div>\n }\n}\n", styles: [".t-row{display:flex;justify-content:flex-start;font:var(--tui-typography-body-m)}.t-row:first-child{justify-content:flex-end}.t-row:last-child{justify-content:flex-start}.t-cell{position:relative;display:flex;align-items:center;justify-content:center;line-height:2rem;isolation:isolate;cursor:pointer;overflow:hidden;border:.125rem solid transparent;box-sizing:border-box;-webkit-mask-image:linear-gradient(transparent calc(50% - 1rem),#000 calc(50% - 1rem),#000 calc(50% + 1rem),transparent calc(50% + 1rem));mask-image:linear-gradient(transparent calc(50% - 1rem),#000 calc(50% - 1rem),#000 calc(50% + 1rem),transparent calc(50% + 1rem))}.t-cell:first-child{border-inline-start-color:transparent!important}.t-cell:last-child{border-inline-end-color:transparent!important}.t-cell:before,.t-cell:after{position:absolute;inset-block-start:0;inset-inline-start:0;inset-block-end:0;inset-inline-end:0;content:\"\";z-index:-1;border-radius:var(--tui-radius-m)}.t-cell:after{-webkit-mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 12 32\"><path d=\"M0.2856 0L0.6763 0C2.9265 0 4.9876 1.259 6.0147 3.2611L10.2442 11.5048C11.5301 14.0113 11.5683 16.9754 10.3472 19.5141L5.9766 28.6007C4.9772 30.6786 2.8754 32 0.5696 32H0.285645V0Z\"></path></svg>'),linear-gradient(#000,#000);mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 12 32\"><path d=\"M0.2856 0L0.6763 0C2.9265 0 4.9876 1.259 6.0147 3.2611L10.2442 11.5048C11.5301 14.0113 11.5683 16.9754 10.3472 19.5141L5.9766 28.6007C4.9772 30.6786 2.8754 32 0.5696 32H0.285645V0Z\"></path></svg>'),linear-gradient(#000,#000);-webkit-mask-position:right,left;mask-position:right,left;-webkit-mask-size:.75rem 100%,calc(100% - .7rem) 100%;mask-size:.75rem 100%,calc(100% - .7rem) 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.t-cell[data-range]:before{background:var(--tui-background-neutral-1)}:host._picking .t-cell[data-range]:before{background:var(--tui-background-neutral-1-hover)}.t-cell[data-range=middle]{border-color:var(--tui-background-neutral-1)}:host._picking .t-cell[data-range=middle]{border-color:var(--tui-background-neutral-1-hover)}.t-cell[data-range=middle]:not(:first-child):before{border-top-left-radius:0;border-bottom-left-radius:0}.t-cell[data-range=middle]:not(:last-child):before{border-top-right-radius:0;border-bottom-right-radius:0}.t-cell[data-range=start]{border-inline-end-color:var(--tui-background-neutral-1);color:var(--tui-text-primary-on-accent-1)}:host._picking .t-cell[data-range=start]{border-inline-end-color:var(--tui-background-neutral-1-hover)}.t-cell[data-range=start]:not(:last-child):before{inset-inline-end:-1rem}.t-cell[data-range=start]:after{background:var(--tui-background-accent-1)}.t-cell[data-range=end]{border-inline-start-color:var(--tui-background-neutral-1);color:var(--tui-text-primary-on-accent-1)}:host._picking .t-cell[data-range=end]{border-inline-start-color:var(--tui-background-neutral-1-hover)}.t-cell[data-range=end]:not(:first-child):before{inset-inline-start:-1rem}.t-cell[data-range=end]:after{background:var(--tui-background-accent-1);transform:scaleX(-1)}.t-cell[data-range=active]{color:var(--tui-text-primary-on-accent-1)}.t-cell[data-range=active]:after{background:var(--tui-background-accent-1);-webkit-mask-image:none;mask-image:none}.t-cell_disabled{opacity:var(--tui-disabled-opacity);pointer-events:none}.t-cell_today{text-decoration:underline;text-underline-offset:.25rem}@media(hover:hover)and (pointer:fine){.t-cell:hover:not([data-range=start]):not([data-range=end]):before{background:var(--tui-background-neutral-1-hover)}.t-cell[data-range=start]:hover:after,.t-cell[data-range=end]:hover:after,.t-cell[data-range=active]:hover:after{background:var(--tui-background-accent-1-hover)}}:host{display:block;block-size:12rem;inline-size:16rem;padding:1.125rem;box-sizing:content-box}.t-spin{margin-block-end:1rem}.t-cell{inline-size:4rem;border-block-start-width:.75rem;border-block-end-width:.75rem}.t-scrollbar{block-size:inherit;inline-size:inherit}\n"], dependencies: [{ kind: "component", type: TuiCalendarYear, selector: "tui-calendar-year", inputs: ["rangeMode", "disabledItemHandler", "value", "min", "max", "initialItem"], outputs: ["yearClick"] }, { kind: "directive", type: TuiHovered, selector: "[tuiHoveredChange]", outputs: ["tuiHoveredChange"] }, { kind: "directive", type: TuiLink, selector: "a[tuiLink], button[tuiLink]" }, { kind: "component", type: TuiScrollbar, selector: "tui-scrollbar" }, { kind: "component", type: TuiSpinButton, selector: "tui-spin-button", inputs: ["focusable", "disabled", "leftDisabled", "rightDisabled"], outputs: ["leftClick", "rightClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiCalendarMonth, decorators: [{
type: Component,
args: [{ selector: 'tui-calendar-month', imports: [TuiCalendarYear, TuiHovered, TuiLink, TuiScrollbar, TuiSpinButton], changeDetection: ChangeDetectionStrategy.OnPush, providers: [tuiAsAuxiliary(TuiCalendarMonth)], host: { '[class._picking]': 'isRangePicking()' }, template: "@if (isYearPickerShown) {\n <tui-scrollbar class=\"t-scrollbar\">\n <tui-calendar-year\n [initialItem]=\"activeYear().year\"\n [max]=\"max().year\"\n [min]=\"min().year\"\n [rangeMode]=\"options.rangeMode\"\n [value]=\"value()\"\n (yearClick)=\"onPickerYearClick($event)\"\n />\n </tui-scrollbar>\n} @else {\n <tui-spin-button\n class=\"t-spin\"\n [focusable]=\"false\"\n [leftDisabled]=\"activeYear().yearSameOrBefore(min())\"\n [rightDisabled]=\"activeYear().yearSameOrAfter(max())\"\n (leftClick)=\"onPreviousYear()\"\n (rightClick)=\"onNextYear()\"\n >\n <button\n automation-id=\"tui-calendar-month__active-year\"\n tabIndex=\"-1\"\n tuiLink\n type=\"button\"\n (click)=\"onYearClick()\"\n >\n {{ activeYear().formattedYear }}\n </button>\n </tui-spin-button>\n @for (_ of '-'.repeat(3); track $index) {\n @let row = $index;\n <div class=\"t-row\">\n @for (_ of '-'.repeat(4); track $index) {\n @let item = getTuiMonth(row * 4 + $index, activeYear().year);\n <div\n class=\"t-cell\"\n [attr.data-range]=\"getItemRange(item)\"\n [class.t-cell_disabled]=\"handler()(item)\"\n [class.t-cell_today]=\"isItemToday(item)\"\n (click)=\"onItemClick(item)\"\n (tuiHoveredChange)=\"onItemHovered($event, item)\"\n >\n {{ months()[row * 4 + $index] }}\n </div>\n }\n </div>\n }\n}\n", styles: [".t-row{display:flex;justify-content:flex-start;font:var(--tui-typography-body-m)}.t-row:first-child{justify-content:flex-end}.t-row:last-child{justify-content:flex-start}.t-cell{position:relative;display:flex;align-items:center;justify-content:center;line-height:2rem;isolation:isolate;cursor:pointer;overflow:hidden;border:.125rem solid transparent;box-sizing:border-box;-webkit-mask-image:linear-gradient(transparent calc(50% - 1rem),#000 calc(50% - 1rem),#000 calc(50% + 1rem),transparent calc(50% + 1rem));mask-image:linear-gradient(transparent calc(50% - 1rem),#000 calc(50% - 1rem),#000 calc(50% + 1rem),transparent calc(50% + 1rem))}.t-cell:first-child{border-inline-start-color:transparent!important}.t-cell:last-child{border-inline-end-color:transparent!important}.t-cell:before,.t-cell:after{position:absolute;inset-block-start:0;inset-inline-start:0;inset-block-end:0;inset-inline-end:0;content:\"\";z-index:-1;border-radius:var(--tui-radius-m)}.t-cell:after{-webkit-mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 12 32\"><path d=\"M0.2856 0L0.6763 0C2.9265 0 4.9876 1.259 6.0147 3.2611L10.2442 11.5048C11.5301 14.0113 11.5683 16.9754 10.3472 19.5141L5.9766 28.6007C4.9772 30.6786 2.8754 32 0.5696 32H0.285645V0Z\"></path></svg>'),linear-gradient(#000,#000);mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 12 32\"><path d=\"M0.2856 0L0.6763 0C2.9265 0 4.9876 1.259 6.0147 3.2611L10.2442 11.5048C11.5301 14.0113 11.5683 16.9754 10.3472 19.5141L5.9766 28.6007C4.9772 30.6786 2.8754 32 0.5696 32H0.285645V0Z\"></path></svg>'),linear-gradient(#000,#000);-webkit-mask-position:right,left;mask-position:right,left;-webkit-mask-size:.75rem 100%,calc(100% - .7rem) 100%;mask-size:.75rem 100%,calc(100% - .7rem) 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.t-cell[data-range]:before{background:var(--tui-background-neutral-1)}:host._picking .t-cell[data-range]:before{background:var(--tui-background-neutral-1-hover)}.t-cell[data-range=middle]{border-color:var(--tui-background-neutral-1)}:host._picking .t-cell[data-range=middle]{border-color:var(--tui-background-neutral-1-hover)}.t-cell[data-range=middle]:not(:first-child):before{border-top-left-radius:0;border-bottom-left-radius:0}.t-cell[data-range=middle]:not(:last-child):before{border-top-right-radius:0;border-bottom-right-radius:0}.t-cell[data-range=start]{border-inline-end-color:var(--tui-background-neutral-1);color:var(--tui-text-primary-on-accent-1)}:host._picking .t-cell[data-range=start]{border-inline-end-color:var(--tui-background-neutral-1-hover)}.t-cell[data-range=start]:not(:last-child):before{inset-inline-end:-1rem}.t-cell[data-range=start]:after{background:var(--tui-background-accent-1)}.t-cell[data-range=end]{border-inline-start-color:var(--tui-background-neutral-1);color:var(--tui-text-primary-on-accent-1)}:host._picking .t-cell[data-range=end]{border-inline-start-color:var(--tui-background-neutral-1-hover)}.t-cell[data-range=end]:not(:first-child):before{inset-inline-start:-1rem}.t-cell[data-range=end]:after{background:var(--tui-background-accent-1);transform:scaleX(-1)}.t-cell[data-range=active]{color:var(--tui-text-primary-on-accent-1)}.t-cell[data-range=active]:after{background:var(--tui-background-accent-1);-webkit-mask-image:none;mask-image:none}.t-cell_disabled{opacity:var(--tui-disabled-opacity);pointer-events:none}.t-cell_today{text-decoration:underline;text-underline-offset:.25rem}@media(hover:hover)and (pointer:fine){.t-cell:hover:not([data-range=start]):not([data-range=end]):before{background:var(--tui-background-neutral-1-hover)}.t-cell[data-range=start]:hover:after,.t-cell[data-range=end]:hover:after,.t-cell[data-range=active]:hover:after{background:var(--tui-background-accent-1-hover)}}:host{display:block;block-size:12rem;inline-size:16rem;padding:1.125rem;box-sizing:content-box}.t-spin{margin-block-end:1rem}.t-cell{inline-size:4rem;border-block-start-width:.75rem;border-block-end-width:.75rem}.t-scrollbar{block-size:inherit;inline-size:inherit}\n"] }]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { TUI_CALENDAR_MONTH_DEFAULT_OPTIONS, TUI_CALENDAR_MONTH_OPTIONS, TuiCalendarMonth, tuiCalendarMonthOptionsProvider };
//# sourceMappingURL=taiga-ui-kit-components-calendar-month.mjs.map