@taiga-ui/kit
Version:
Taiga UI Angular main components kit
148 lines (142 loc) • 10.5 kB
JavaScript
import * as i0 from '@angular/core';
import { contentChildren, forwardRef, ElementRef, inject, input, model, ChangeDetectionStrategy, Component, computed } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { RouterLinkActive } from '@angular/router';
import { tuiDirectiveBinding } from '@taiga-ui/cdk/utils/di';
import { tuiInjectElement, tuiIsElement } from '@taiga-ui/cdk/utils/dom';
import * as i1 from '@taiga-ui/core/components/cell';
import { TuiCell } from '@taiga-ui/core/components/cell';
import * as i2 from '@taiga-ui/core/directives/appearance';
import { tuiAppearance, TuiWithAppearance } from '@taiga-ui/core/directives/appearance';
import { TUI_COMMON_ICONS } from '@taiga-ui/core/tokens';
import { TuiAvatar } from '@taiga-ui/kit/components/avatar';
import { EMPTY, filter } from 'rxjs';
import { WaResizeObserverService } from '@ng-web-apis/resize-observer';
import { tuiMoveFocus } from '@taiga-ui/cdk/utils/focus';
class TuiStepperComponent {
constructor() {
this.el = tuiInjectElement();
this.steps = contentChildren(forwardRef(() => TuiStep), { read: ElementRef });
this.$ = inject(WaResizeObserverService, { self: true })
.pipe(takeUntilDestroyed())
.subscribe(() => this.scrollIntoView(this.activeItemIndex()));
this.orientation = input('horizontal');
this.activeItemIndex = model(0);
}
ngOnChanges() {
this.scrollIntoView(this.activeItemIndex());
}
indexOf(step) {
const index = this.steps().findIndex(({ nativeElement }) => nativeElement === step);
return index < 0 ? Number.NaN : index;
}
isActive(index) {
return index === this.activeItemIndex();
}
activate(index) {
if (this.activeItemIndex() === index) {
return;
}
this.activeItemIndex.set(index);
this.scrollIntoView(index);
}
onHorizontal(event, step) {
if (this.orientation() !== 'horizontal' || !event.target) {
return;
}
event.preventDefault();
this.moveFocus(event.target, step);
}
onVertical(event, step) {
if (this.orientation() !== 'vertical' || !event.target) {
return;
}
event.preventDefault();
this.moveFocus(event.target, step);
}
moveFocus(current, step) {
if (!tuiIsElement(current)) {
return;
}
const stepElements = this.steps().map(({ nativeElement }) => nativeElement);
const index = stepElements.findIndex((element) => element === current);
tuiMoveFocus(index, stepElements, step);
}
scrollIntoView(index) {
const step = this.steps()[index]?.nativeElement;
if (!step) {
return;
}
const { clientHeight, clientWidth, offsetTop, offsetLeft } = this.el;
const { offsetHeight, offsetWidth, offsetTop: stepOffsetTop, offsetLeft: stepOffsetLeft, } = step;
const top = stepOffsetTop - offsetTop - clientHeight / 2 + offsetHeight / 2;
const left = stepOffsetLeft - offsetLeft - clientWidth / 2 + offsetWidth / 2;
this.el.scrollTo?.({ left: Math.max(0, left), top: Math.max(0, top) });
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.21", type: TuiStepperComponent, isStandalone: true, selector: "tui-stepper", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, activeItemIndex: { classPropertyName: "activeItemIndex", publicName: "activeItemIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeItemIndex: "activeItemIndexChange" }, host: { listeners: { "keydown.arrowDown": "onVertical($event, 1)", "keydown.arrowLeft": "onHorizontal($event, -1)", "keydown.arrowRight": "onHorizontal($event, 1)", "keydown.arrowUp": "onVertical($event, -1)" }, properties: { "attr.data-orientation": "orientation()" } }, providers: [WaResizeObserverService], queries: [{ propertyName: "steps", predicate: i0.forwardRef(() => TuiStep), read: ElementRef, isSignal: true }], usesOnChanges: true, ngImport: i0, template: `
<ng-content />
`, isInline: true, styles: [":host{scrollbar-width:none;-ms-overflow-style:none;display:flex;scroll-behavior:var(--tui-scroll-behavior);overflow:auto;counter-reset:steps;font:var(--tui-typography-body-m)}:host::-webkit-scrollbar,:host::-webkit-scrollbar-thumb{display:none}:host[data-orientation=vertical]{flex-direction:column}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiStepperComponent, decorators: [{
type: Component,
args: [{ selector: 'tui-stepper', template: `
<ng-content />
`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [WaResizeObserverService], host: {
'[attr.data-orientation]': 'orientation()',
'(keydown.arrowDown)': 'onVertical($event, 1)',
'(keydown.arrowLeft)': 'onHorizontal($event, -1)',
'(keydown.arrowRight)': 'onHorizontal($event, 1)',
'(keydown.arrowUp)': 'onVertical($event, -1)',
}, styles: [":host{scrollbar-width:none;-ms-overflow-style:none;display:flex;scroll-behavior:var(--tui-scroll-behavior);overflow:auto;counter-reset:steps;font:var(--tui-typography-body-m)}:host::-webkit-scrollbar,:host::-webkit-scrollbar-thumb{display:none}:host[data-orientation=vertical]{flex-direction:column}\n"] }]
}] });
class TuiStep {
constructor() {
this.el = tuiInjectElement();
this.icons = inject(TUI_COMMON_ICONS);
this.appearance = tuiAppearance(computed(() => (this.isActive() ? 'none' : 'action')));
this.size = tuiDirectiveBinding(TuiCell, 'size', 'm');
this.stepper = inject(TuiStepperComponent);
this.$ = (inject(RouterLinkActive, { optional: true })?.isActiveChange.asObservable() ?? EMPTY)
.pipe(filter(Boolean), takeUntilDestroyed())
.subscribe(() => this.activate());
this.stepState = input('normal');
this.icon = input('');
this.isActive = computed(() => this.stepper.activeItemIndex() === this.index);
this.avatarAppearance = computed(() => {
if (this.isActive()) {
return 'primary';
}
return this.stepState() === 'error' ? 'negative' : 'secondary';
});
this.avatarContent = computed(() => this.isActive() || (this.stepState() === 'normal' && !this.icon())
? `${this.index + 1}`
: this.avatarIcon());
this.avatarIcon = computed(() => this.icon() ||
(this.stepState() === 'error' ? this.icons.error : this.icons.check));
}
get index() {
return this.stepper.indexOf(this.el);
}
activate() {
this.stepper.activate(this.index);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiStep, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: TuiStep, isStandalone: true, selector: "button[tuiStep], a[tuiStep]:not([routerLink]), a[tuiStep][routerLink][routerLinkActive]", inputs: { stepState: { classPropertyName: "stepState", publicName: "stepState", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, listeners: { "click": "activate()" }, properties: { "class._active": "isActive()", "class._vertical": "stepper.orientation() === \"vertical\"", "tabIndex": "isActive() ? 0 : -1" } }, hostDirectives: [{ directive: i1.TuiCell }, { directive: i2.TuiWithAppearance }], ngImport: i0, template: "<div\n [appearance]=\"avatarAppearance()\"\n [tuiAvatar]=\"avatarContent()\"\n></div>\n<ng-content />\n", styles: [":host{min-inline-size:fit-content}:host:hover{background:unset!important}:host._active._active:not(:disabled){cursor:unset}:host:not(._vertical):first-of-type{padding-inline-start:0}:host:not(._vertical):last-of-type{padding-inline-end:0}:host._vertical{padding-inline:0;margin-block-end:.5rem}[tuiAvatar][data-size]:before{transition:none}[tuiAvatar][data-size]._initials:before{font-weight:400}\n"], dependencies: [{ kind: "directive", type: TuiAvatar, selector: "[tuiAvatar]", inputs: ["size", "round", "badge"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiStep, decorators: [{
type: Component,
args: [{ selector: 'button[tuiStep], a[tuiStep]:not([routerLink]), a[tuiStep][routerLink][routerLinkActive]', imports: [TuiAvatar], changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [TuiCell, TuiWithAppearance], host: {
type: 'button',
'[class._active]': 'isActive()',
'[class._vertical]': 'stepper.orientation() === "vertical"',
'[tabIndex]': 'isActive() ? 0 : -1',
'(click)': 'activate()',
}, template: "<div\n [appearance]=\"avatarAppearance()\"\n [tuiAvatar]=\"avatarContent()\"\n></div>\n<ng-content />\n", styles: [":host{min-inline-size:fit-content}:host:hover{background:unset!important}:host._active._active:not(:disabled){cursor:unset}:host:not(._vertical):first-of-type{padding-inline-start:0}:host:not(._vertical):last-of-type{padding-inline-end:0}:host._vertical{padding-inline:0;margin-block-end:.5rem}[tuiAvatar][data-size]:before{transition:none}[tuiAvatar][data-size]._initials:before{font-weight:400}\n"] }]
}] });
const TuiStepper = [TuiStepperComponent, TuiStep];
/**
* Generated bundle index. Do not edit.
*/
export { TuiStep, TuiStepper, TuiStepperComponent };
//# sourceMappingURL=taiga-ui-kit-components-stepper.mjs.map