UNPKG

@taiga-ui/kit

Version:

Taiga UI Angular main components kit

156 lines (151 loc) 20.4 kB
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