UNPKG

@taiga-ui/cdk

Version:

Base library for creating Angular components and applications using Taiga UI principles regarding of actual visual appearance

204 lines (197 loc) 8.37 kB
import * as i0 from '@angular/core'; import { inject, signal, ChangeDetectorRef, computed, untracked, Directive, Input, INJECTOR, ViewContainerRef, ViewChild, Injectable } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { NgControl, NgModel } from '@angular/forms'; import { EMPTY_FUNCTION } from '@taiga-ui/cdk/constants'; import { TUI_FALLBACK_VALUE } from '@taiga-ui/cdk/tokens'; import { tuiProvide } from '@taiga-ui/cdk/utils'; import { identity, Subject, delay, startWith, map, filter, distinctUntilChanged, switchMap, merge, EMPTY } from 'rxjs'; class TuiValueTransformer { } function tuiValueTransformerFrom(token) { return { provide: TuiValueTransformer, useFactory: () => inject(token).valueTransformer, }; } class TuiNonNullableValueTransformer extends TuiValueTransformer { fromControlValue(value) { this.prevValue = value; return value; } toControlValue(value) { this.prevValue = value ?? this.prevValue; return this.prevValue; } } const TUI_IDENTITY_VALUE_TRANSFORMER = { fromControlValue: identity, toControlValue: identity, }; const FLAGS = { self: true, optional: true }; /** * Basic ControlValueAccessor class to build form components upon */ class TuiControl { constructor() { this.fallback = inject(TUI_FALLBACK_VALUE, FLAGS); this.refresh$ = new Subject(); this.pseudoInvalid = signal(null); this.internal = signal(this.fallback); this.control = inject(NgControl, { self: true }); this.cdr = inject(ChangeDetectorRef); this.transformer = inject(TuiValueTransformer, FLAGS) ?? TUI_IDENTITY_VALUE_TRANSFORMER; this.value = computed(() => this.internal() ?? this.fallback); this.readOnly = signal(false); this.touched = signal(false); this.status = signal(undefined); this.disabled = computed(() => this.status() === 'DISABLED'); this.interactive = computed(() => !this.disabled() && !this.readOnly()); this.invalid = computed(() => this.pseudoInvalid() !== null ? !!this.pseudoInvalid() && this.interactive() : this.interactive() && this.touched() && this.status() === 'INVALID'); this.mode = computed(() => // eslint-disable-next-line no-nested-ternary this.readOnly() ? 'readonly' : this.invalid() ? 'invalid' : 'valid'); this.onTouched = EMPTY_FUNCTION; this.onChange = EMPTY_FUNCTION; this.control.valueAccessor = this; this.refresh$ .pipe(delay(0), startWith(null), map(() => this.control.control), filter(Boolean), distinctUntilChanged(), switchMap((c) => merge(c.valueChanges, c.statusChanges, c.events || EMPTY).pipe(startWith(null))), takeUntilDestroyed()) .subscribe(() => this.update()); } set readOnlySetter(readOnly) { this.readOnly.set(readOnly); } set invalidSetter(invalid) { this.pseudoInvalid.set(invalid); } registerOnChange(onChange) { this.refresh$.next(); this.onChange = (value) => { const internal = untracked(() => this.internal()); if (value === internal) { return; } onChange(this.transformer.toControlValue(value)); this.internal.set(value); this.update(); }; } registerOnTouched(onTouched) { this.onTouched = () => { onTouched(); this.update(); }; } setDisabledState() { this.update(); } writeValue(value) { // TODO: https://github.com/angular/angular/issues/14988 const safe = this.control instanceof NgModel ? this.control.model : value; this.internal.set(this.transformer.fromControlValue(safe)); this.update(); } update() { this.status.set(this.control.control?.status); this.touched.set(!!this.control.control?.touched); this.cdr.markForCheck(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiControl, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: TuiControl, inputs: { readOnlySetter: ["readOnly", "readOnlySetter"], invalidSetter: ["invalid", "invalidSetter"] }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiControl, decorators: [{ type: Directive }], ctorParameters: function () { return []; }, propDecorators: { readOnlySetter: [{ type: Input, args: ['readOnly'] }], invalidSetter: [{ type: Input, args: ['invalid'] }] } }); function tuiAsControl(control) { return tuiProvide(TuiControl, control); } /// <reference types="@taiga-ui/tsconfig/ng-dev-mode" /> /// <reference types="@taiga-ui/tsconfig/ng-dev-mode" /> /** * Abstract class for host element for dynamically created portals. */ class TuiPortals { constructor() { this.injector = inject(INJECTOR); this.nothing = inject(TuiPortalService).attach(this); } addComponentChild(component) { const injector = component.createInjector(this.injector); const ref = this.vcr.createComponent(component.component, { injector }); ref.changeDetectorRef.detectChanges(); return ref; } addTemplateChild(templateRef, context) { return this.vcr.createEmbeddedView(templateRef, context); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiPortals, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: TuiPortals, viewQueries: [{ propertyName: "vcr", first: true, predicate: ["viewContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiPortals, decorators: [{ type: Directive }], propDecorators: { vcr: [{ type: ViewChild, args: ['viewContainer', { read: ViewContainerRef }] }] } }); /** * Abstract service for displaying portals */ class TuiPortalService { attach(host) { this.host = host; } add(component) { return this.safeHost.addComponentChild(component); } remove({ hostView }) { this.removeTemplate(hostView); } addTemplate(templateRef, context) { return this.safeHost.addTemplateChild(templateRef, context); } removeTemplate(viewRef) { if (!viewRef.destroyed) { viewRef.destroy(); } } get safeHost() { if (!this.host) { throw new TuiNoHostException(); } return this.host; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiPortalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiPortalService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiPortalService, decorators: [{ type: Injectable }] }); function tuiAsPortal(portal) { return tuiProvide(TuiPortalService, portal); } class TuiNoHostException extends Error { constructor() { super(ngDevMode ? 'Portals cannot be used without TuiPortalHostComponent; perhaps you forgot to wrap your application with tui-root.' : ''); } } class TuiValidationError { constructor(message, context = {}) { this.message = message; this.context = context; } } /** * Generated bundle index. Do not edit. */ export { TUI_IDENTITY_VALUE_TRANSFORMER, TuiControl, TuiNoHostException, TuiNonNullableValueTransformer, TuiPortalService, TuiPortals, TuiValidationError, TuiValueTransformer, tuiAsControl, tuiAsPortal, tuiValueTransformerFrom }; //# sourceMappingURL=taiga-ui-cdk-classes.mjs.map