@yuuvis/client-framework 3.0.0-beta.21.0 → 3.0.0-beta.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/autocomplete/README.md +1 -1
- package/common/README.md +1 -1
- package/fesm2022/yuuvis-client-framework-autocomplete.mjs +5 -236
- package/fesm2022/yuuvis-client-framework-autocomplete.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-common.mjs +3 -1793
- package/fesm2022/yuuvis-client-framework-common.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-list.mjs +3 -667
- package/fesm2022/yuuvis-client-framework-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-master-details.mjs +3 -136
- package/fesm2022/yuuvis-client-framework-master-details.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-overflow-hidden.mjs +3 -62
- package/fesm2022/yuuvis-client-framework-overflow-hidden.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-overflow-menu.mjs +3 -129
- package/fesm2022/yuuvis-client-framework-overflow-menu.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-popout.mjs +3 -239
- package/fesm2022/yuuvis-client-framework-popout.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-split-view.mjs +3 -318
- package/fesm2022/yuuvis-client-framework-split-view.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-widget-grid.mjs +3 -942
- package/fesm2022/yuuvis-client-framework-widget-grid.mjs.map +1 -1
- package/lib/assets/i18n/de.json +1 -55
- package/lib/assets/i18n/en.json +1 -55
- package/list/README.md +1 -1
- package/master-details/README.md +1 -1
- package/overflow-hidden/README.md +1 -1
- package/overflow-menu/README.md +1 -1
- package/package.json +6 -5
- package/popout/README.md +1 -1
- package/split-view/README.md +1 -1
- package/types/yuuvis-client-framework-autocomplete.d.ts +1 -89
- package/types/yuuvis-client-framework-common.d.ts +1 -536
- package/types/yuuvis-client-framework-list.d.ts +1 -380
- package/types/yuuvis-client-framework-master-details.d.ts +1 -69
- package/types/yuuvis-client-framework-overflow-hidden.d.ts +1 -28
- package/types/yuuvis-client-framework-overflow-menu.d.ts +1 -52
- package/types/yuuvis-client-framework-popout.d.ts +1 -106
- package/types/yuuvis-client-framework-split-view.d.ts +1 -197
- package/types/yuuvis-client-framework-widget-grid.d.ts +1 -299
- package/widget-grid/README.md +1 -46
|
@@ -1,1801 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import { input, ChangeDetectionStrategy, Component, inject, computed, DestroyRef, viewChild, signal, afterNextRender, ElementRef, Input, Directive, output, EnvironmentInjector, ViewContainerRef, effect, NgZone, DOCUMENT, contentChildren, Injectable, forwardRef, Renderer2, NgModule, InjectionToken, makeEnvironmentProviders, RendererFactory2 } from '@angular/core';
|
|
3
|
-
import { MatButtonModule } from '@angular/material/button';
|
|
4
|
-
import * as i1 from '@angular/material/dialog';
|
|
5
|
-
import { MatDialogActions, MatDialogTitle, MatDialogContent, MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
|
|
6
|
-
import { TranslatePipe, AppCacheService, RetentionService, LocaleDatePipe } from '@yuuvis/client-core';
|
|
7
|
-
import { YmtButtonDirective, YmtIconButtonDirective } from '@yuuvis/material';
|
|
8
|
-
import * as i1$1 from '@angular/material/icon';
|
|
9
|
-
import { MatIconModule } from '@angular/material/icon';
|
|
10
|
-
import { TranslatePipe as TranslatePipe$1, TranslateService } from '@ngx-translate/core';
|
|
11
|
-
import { MatProgressSpinner } from '@angular/material/progress-spinner';
|
|
12
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
13
|
-
import { Subject, fromEvent, merge, timer, of, forkJoin, map as map$1 } from 'rxjs';
|
|
14
|
-
import { debounceTime, tap, filter, switchMap, map, takeUntil } from 'rxjs/operators';
|
|
15
|
-
import { NG_VALUE_ACCESSOR, NgControl, FormControlDirective, FormControlName, NgModel } from '@angular/forms';
|
|
16
|
-
import { marker } from '@colsen1991/ngx-translate-extract-marker';
|
|
17
|
-
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
18
|
-
|
|
19
|
-
class DialogComponent {
|
|
20
|
-
constructor() {
|
|
21
|
-
this.headertitle = input(null, ...(ngDevMode ? [{ debugName: "headertitle" }] : /* istanbul ignore next */ []));
|
|
22
|
-
/**
|
|
23
|
-
* @deprecated use headertitle instead
|
|
24
|
-
*/
|
|
25
|
-
this.headertitel = input(null, ...(ngDevMode ? [{ debugName: "headertitel" }] : /* istanbul ignore next */ []));
|
|
26
|
-
}
|
|
27
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
28
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DialogComponent, isStandalone: true, selector: "yuv-dialog", inputs: { headertitle: { classPropertyName: "headertitle", publicName: "headertitle", isSignal: true, isRequired: false, transformFunction: null }, headertitel: { classPropertyName: "headertitel", publicName: "headertitel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
29
|
-
@let title = headertitle() ?? headertitel();
|
|
30
|
-
@if (title) {
|
|
31
|
-
<h2 mat-dialog-title>{{ title }}</h2>
|
|
32
|
-
}
|
|
33
|
-
<mat-dialog-content>
|
|
34
|
-
<ng-content select="main" />
|
|
35
|
-
</mat-dialog-content>
|
|
36
|
-
|
|
37
|
-
<mat-dialog-actions align="end" class="footer">
|
|
38
|
-
<ng-content select="footer" />
|
|
39
|
-
</mat-dialog-actions>
|
|
40
|
-
`, isInline: true, styles: [":host{--_dialog-area-background: var(--dialog-area-background, light-dark(var(--ymt-surface), var(--ymt-surface-container-low)));--_dialog-area-divider-color: var(--dialog-area-divider-color, var(--ymt-outline-variant));height:100%;display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:1fr;grid-template-areas:\"header\" \"content\" \"footer\"}:host h2{grid-area:header;background-color:var(--_dialog-area-background);border-block-end:1px solid var(--_dialog-area-divider-color)}:host .footer{background-color:var(--_dialog-area-background);border-block-start:1px solid var(--_dialog-area-divider-color);gap:calc(var(--ymt-font-body) / 2)}:host.not-separated{background-color:var(--ymt-surface-app)}:host.not-separated h2,:host.not-separated .footer{background-color:transparent;border:0}.mat-mdc-dialog-container{height:100%}mat-dialog-content:empty{display:contents}mat-dialog-content main{display:var(--ymt-dialog-content-display);grid-area:content;overflow:hidden}mat-dialog-actions{grid-area:footer}mat-dialog-actions:empty{display:contents}\n"], dependencies: [{ kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
41
|
-
}
|
|
42
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DialogComponent, decorators: [{
|
|
43
|
-
type: Component,
|
|
44
|
-
args: [{ selector: 'yuv-dialog', imports: [MatDialogActions, MatDialogTitle, MatDialogContent], template: `
|
|
45
|
-
@let title = headertitle() ?? headertitel();
|
|
46
|
-
@if (title) {
|
|
47
|
-
<h2 mat-dialog-title>{{ title }}</h2>
|
|
48
|
-
}
|
|
49
|
-
<mat-dialog-content>
|
|
50
|
-
<ng-content select="main" />
|
|
51
|
-
</mat-dialog-content>
|
|
52
|
-
|
|
53
|
-
<mat-dialog-actions align="end" class="footer">
|
|
54
|
-
<ng-content select="footer" />
|
|
55
|
-
</mat-dialog-actions>
|
|
56
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--_dialog-area-background: var(--dialog-area-background, light-dark(var(--ymt-surface), var(--ymt-surface-container-low)));--_dialog-area-divider-color: var(--dialog-area-divider-color, var(--ymt-outline-variant));height:100%;display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:1fr;grid-template-areas:\"header\" \"content\" \"footer\"}:host h2{grid-area:header;background-color:var(--_dialog-area-background);border-block-end:1px solid var(--_dialog-area-divider-color)}:host .footer{background-color:var(--_dialog-area-background);border-block-start:1px solid var(--_dialog-area-divider-color);gap:calc(var(--ymt-font-body) / 2)}:host.not-separated{background-color:var(--ymt-surface-app)}:host.not-separated h2,:host.not-separated .footer{background-color:transparent;border:0}.mat-mdc-dialog-container{height:100%}mat-dialog-content:empty{display:contents}mat-dialog-content main{display:var(--ymt-dialog-content-display);grid-area:content;overflow:hidden}mat-dialog-actions{grid-area:footer}mat-dialog-actions:empty{display:contents}\n"] }]
|
|
57
|
-
}], propDecorators: { headertitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headertitle", required: false }] }], headertitel: [{ type: i0.Input, args: [{ isSignal: true, alias: "headertitel", required: false }] }] } });
|
|
58
|
-
|
|
59
|
-
class ConfirmComponent {
|
|
60
|
-
constructor() {
|
|
61
|
-
this.dialogData = inject(MAT_DIALOG_DATA);
|
|
62
|
-
this.buttonType = computed(() => {
|
|
63
|
-
switch (this.dialogData.level) {
|
|
64
|
-
case 'warning':
|
|
65
|
-
return 'danger';
|
|
66
|
-
// case 'warning':
|
|
67
|
-
// return 'tertiary' as ButtonType;
|
|
68
|
-
// case 'info':
|
|
69
|
-
// return 'primary' as ButtonType;
|
|
70
|
-
// case 'success':
|
|
71
|
-
// return 'primary' as ButtonType;
|
|
72
|
-
default:
|
|
73
|
-
return 'primary';
|
|
74
|
-
}
|
|
75
|
-
}, ...(ngDevMode ? [{ debugName: "buttonType" }] : /* istanbul ignore next */ []));
|
|
76
|
-
}
|
|
77
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ConfirmComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
78
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ConfirmComponent, isStandalone: true, selector: "yuv-confirm", ngImport: i0, template: "<yuv-dialog [headertitle]=\"dialogData.title || ''\">\n <main>{{ dialogData.message }}</main>\n <footer>\n @if (!dialogData.hideCancelButton) {\n <button ymtButton=\"secondary\" mat-dialog-close type=\"button\">\n {{ dialogData.cancelLabel || ('yuv.confirm.cancel' | translate) }}\n </button>\n }\n <button [ymtButton]=\"buttonType()\" type=\"button\" [mat-dialog-close]=\"true\">\n {{ dialogData.confirmLabel || ('yuv.confirm.confirm' | translate) }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{padding:var(--ymt-spacing-m)}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitle", "headertitel"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
79
|
-
}
|
|
80
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ConfirmComponent, decorators: [{
|
|
81
|
-
type: Component,
|
|
82
|
-
args: [{ selector: 'yuv-confirm', imports: [MatButtonModule, TranslatePipe, MatDialogModule, DialogComponent, YmtButtonDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<yuv-dialog [headertitle]=\"dialogData.title || ''\">\n <main>{{ dialogData.message }}</main>\n <footer>\n @if (!dialogData.hideCancelButton) {\n <button ymtButton=\"secondary\" mat-dialog-close type=\"button\">\n {{ dialogData.cancelLabel || ('yuv.confirm.cancel' | translate) }}\n </button>\n }\n <button [ymtButton]=\"buttonType()\" type=\"button\" [mat-dialog-close]=\"true\">\n {{ dialogData.confirmLabel || ('yuv.confirm.confirm' | translate) }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{padding:var(--ymt-spacing-m)}\n"] }]
|
|
83
|
-
}] });
|
|
84
|
-
|
|
85
|
-
const DEFAULT_SCROLL_AMOUNT$1 = 150;
|
|
86
|
-
/**
|
|
87
|
-
* Wrapper component that adds left/right scroll buttons when its content overflows horizontally.
|
|
88
|
-
* Buttons appear only when there is overflow in the respective direction.
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* <yuv-scroll-buttons>
|
|
92
|
-
* <mat-chip-grid>...</mat-chip-grid>
|
|
93
|
-
* </yuv-scroll-buttons>
|
|
94
|
-
*/
|
|
95
|
-
class ScrollButtonsComponent {
|
|
96
|
-
#destroyRef;
|
|
97
|
-
#resizeObserver;
|
|
98
|
-
constructor() {
|
|
99
|
-
this.#destroyRef = inject(DestroyRef);
|
|
100
|
-
this.scrollContainer = viewChild.required('scrollContainer');
|
|
101
|
-
/** How many pixels to scroll per button click. */
|
|
102
|
-
this.scrollAmount = input(DEFAULT_SCROLL_AMOUNT$1, ...(ngDevMode ? [{ debugName: "scrollAmount" }] : /* istanbul ignore next */ []));
|
|
103
|
-
this.showLeftButton = signal(false, ...(ngDevMode ? [{ debugName: "showLeftButton" }] : /* istanbul ignore next */ []));
|
|
104
|
-
this.showRightButton = signal(false, ...(ngDevMode ? [{ debugName: "showRightButton" }] : /* istanbul ignore next */ []));
|
|
105
|
-
afterNextRender(() => {
|
|
106
|
-
const element = this.scrollContainer().nativeElement;
|
|
107
|
-
this.#resizeObserver = new ResizeObserver(() => this.#checkOverflow());
|
|
108
|
-
this.#resizeObserver.observe(element);
|
|
109
|
-
// Also observe mutations to detect when children (chips) are added/removed
|
|
110
|
-
const mutationObserver = new MutationObserver(() => this.#checkOverflow());
|
|
111
|
-
mutationObserver.observe(element, { childList: true, subtree: true });
|
|
112
|
-
this.#destroyRef.onDestroy(() => {
|
|
113
|
-
this.#resizeObserver?.disconnect();
|
|
114
|
-
mutationObserver.disconnect();
|
|
115
|
-
});
|
|
116
|
-
this.#checkOverflow();
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
onScroll() {
|
|
120
|
-
this.#checkOverflow();
|
|
121
|
-
}
|
|
122
|
-
scrollLeft() {
|
|
123
|
-
this.scrollContainer().nativeElement.scrollBy({ left: -this.scrollAmount(), behavior: 'smooth' });
|
|
124
|
-
}
|
|
125
|
-
scrollRight() {
|
|
126
|
-
this.scrollContainer().nativeElement.scrollBy({ left: this.scrollAmount(), behavior: 'smooth' });
|
|
127
|
-
}
|
|
128
|
-
#checkOverflow() {
|
|
129
|
-
const element = this.scrollContainer().nativeElement;
|
|
130
|
-
const threshold = 1; // account for sub-pixel rounding
|
|
131
|
-
this.showLeftButton.set(element.scrollLeft > threshold);
|
|
132
|
-
this.showRightButton.set(element.scrollLeft + element.clientWidth < element.scrollWidth - threshold);
|
|
133
|
-
}
|
|
134
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ScrollButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
135
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ScrollButtonsComponent, isStandalone: true, selector: "yuv-scroll-buttons", inputs: { scrollAmount: { classPropertyName: "scrollAmount", publicName: "scrollAmount", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (showLeftButton()) {\n <button\n class=\"scroll-btn scroll-btn--left\"\n (click)=\"scrollLeft()\"\n [attr.aria-label]=\"'yuv.object-form-element.scroll.button.left' | translate\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n}\n<div class=\"scroll-content\" #scrollContainer (scroll)=\"onScroll()\">\n <ng-content />\n</div>\n@if (showRightButton()) {\n <button\n class=\"scroll-btn scroll-btn--right\"\n (click)=\"scrollRight()\"\n [attr.aria-label]=\"'yuv.object-form-element.scroll.button.right' | translate\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n}\n", styles: [":host{display:flex;align-items:center;flex:1;min-width:0}.scroll-content{flex:1;overflow-x:auto;scrollbar-width:none;min-width:0}.scroll-content ::ng-deep mat-chip-grid .mdc-evolution-chip-set__chips{flex-wrap:nowrap}.scroll-content ::ng-deep mat-chip-grid mat-chip-row{flex-shrink:0;max-width:none}.scroll-content ::ng-deep mat-chip-grid mat-chip-row .mdc-evolution-chip__cell--primary{max-width:none}.scroll-content ::ng-deep mat-chip-grid mat-chip-row .mdc-evolution-chip__text-label,.scroll-content ::ng-deep mat-chip-grid mat-chip-row .mat-mdc-chip-action-label{white-space:nowrap}.scroll-btn{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;background:none;border:none;cursor:pointer;padding:0;color:var(--ymv-text-color-subtle);width:var(--ymv-sizing-m);height:var(--ymv-sizing-m);background-color:var(--ymv-surface-hover)}.scroll-btn:hover,.scroll-btn:focus-visible{color:var(--ymv-text-color)}.scroll-btn:focus-visible{outline:2px solid var(--ymv-primary-color);outline-offset:-2px}.scroll-btn mat-icon{font-size:20px;width:20px;height:20px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: TranslatePipe$1, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
136
|
-
}
|
|
137
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ScrollButtonsComponent, decorators: [{
|
|
138
|
-
type: Component,
|
|
139
|
-
args: [{ selector: 'yuv-scroll-buttons', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, TranslatePipe$1], template: "@if (showLeftButton()) {\n <button\n class=\"scroll-btn scroll-btn--left\"\n (click)=\"scrollLeft()\"\n [attr.aria-label]=\"'yuv.object-form-element.scroll.button.left' | translate\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n}\n<div class=\"scroll-content\" #scrollContainer (scroll)=\"onScroll()\">\n <ng-content />\n</div>\n@if (showRightButton()) {\n <button\n class=\"scroll-btn scroll-btn--right\"\n (click)=\"scrollRight()\"\n [attr.aria-label]=\"'yuv.object-form-element.scroll.button.right' | translate\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n}\n", styles: [":host{display:flex;align-items:center;flex:1;min-width:0}.scroll-content{flex:1;overflow-x:auto;scrollbar-width:none;min-width:0}.scroll-content ::ng-deep mat-chip-grid .mdc-evolution-chip-set__chips{flex-wrap:nowrap}.scroll-content ::ng-deep mat-chip-grid mat-chip-row{flex-shrink:0;max-width:none}.scroll-content ::ng-deep mat-chip-grid mat-chip-row .mdc-evolution-chip__cell--primary{max-width:none}.scroll-content ::ng-deep mat-chip-grid mat-chip-row .mdc-evolution-chip__text-label,.scroll-content ::ng-deep mat-chip-grid mat-chip-row .mat-mdc-chip-action-label{white-space:nowrap}.scroll-btn{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;background:none;border:none;cursor:pointer;padding:0;color:var(--ymv-text-color-subtle);width:var(--ymv-sizing-m);height:var(--ymv-sizing-m);background-color:var(--ymv-surface-hover)}.scroll-btn:hover,.scroll-btn:focus-visible{color:var(--ymv-text-color)}.scroll-btn:focus-visible{outline:2px solid var(--ymv-primary-color);outline-offset:-2px}.scroll-btn mat-icon{font-size:20px;width:20px;height:20px}\n"] }]
|
|
140
|
-
}], ctorParameters: () => [], propDecorators: { scrollContainer: [{ type: i0.ViewChild, args: ['scrollContainer', { isSignal: true }] }], scrollAmount: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollAmount", required: false }] }] } });
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Directive putting focus on a 'focusable' child element.
|
|
144
|
-
* By default the first focusable child will receive focus.
|
|
145
|
-
*/
|
|
146
|
-
class AutofocusChildDirective {
|
|
147
|
-
#elRef = inject(ElementRef);
|
|
148
|
-
#targetIndex = 0;
|
|
149
|
-
set yuvAutofocusChild(s) {
|
|
150
|
-
const i = parseInt(s);
|
|
151
|
-
this.#targetIndex = !isNaN(i) ? i : 0;
|
|
152
|
-
}
|
|
153
|
-
#getFirstFocusableChild() {
|
|
154
|
-
const focusableElements = [
|
|
155
|
-
...this.#elRef.nativeElement.querySelectorAll('a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])')
|
|
156
|
-
].filter((el) => !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden'));
|
|
157
|
-
return focusableElements[this.#targetIndex];
|
|
158
|
-
}
|
|
159
|
-
ngAfterViewInit() {
|
|
160
|
-
setTimeout(() => {
|
|
161
|
-
const focusEl = this.#getFirstFocusableChild();
|
|
162
|
-
if (focusEl)
|
|
163
|
-
focusEl.focus();
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AutofocusChildDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
167
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: AutofocusChildDirective, isStandalone: true, selector: "[yuvAutofocusChild]", inputs: { yuvAutofocusChild: "yuvAutofocusChild" }, ngImport: i0 }); }
|
|
168
|
-
}
|
|
169
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AutofocusChildDirective, decorators: [{
|
|
170
|
-
type: Directive,
|
|
171
|
-
args: [{
|
|
172
|
-
selector: '[yuvAutofocusChild]',
|
|
173
|
-
standalone: true
|
|
174
|
-
}]
|
|
175
|
-
}], propDecorators: { yuvAutofocusChild: [{
|
|
176
|
-
type: Input
|
|
177
|
-
}] } });
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Directive putting delayed focus on an element. If no
|
|
181
|
-
* delay is set, the focus will be set immediately.
|
|
182
|
-
*
|
|
183
|
-
* You have to ensure that the element is focusable when adding this directive to it.
|
|
184
|
-
*/
|
|
185
|
-
class AutofocusDelayedDirective {
|
|
186
|
-
constructor() {
|
|
187
|
-
this.#elRef = inject(ElementRef);
|
|
188
|
-
/**
|
|
189
|
-
* Sets the delay in milliseconds. If no delay is set, the focus will be set immediately.
|
|
190
|
-
*/
|
|
191
|
-
this.yuvAutofocusDelayed = input(0, ...(ngDevMode ? [{ debugName: "yuvAutofocusDelayed" }] : /* istanbul ignore next */ []));
|
|
192
|
-
this.#delay = computed(() => {
|
|
193
|
-
const d = this.yuvAutofocusDelayed();
|
|
194
|
-
return typeof d === 'string' ? parseInt(d) : d;
|
|
195
|
-
}, ...(ngDevMode ? [{ debugName: "#delay" }] : /* istanbul ignore next */ []));
|
|
196
|
-
}
|
|
197
|
-
#elRef;
|
|
198
|
-
#delay;
|
|
199
|
-
ngAfterViewInit() {
|
|
200
|
-
setTimeout(() => {
|
|
201
|
-
this.#elRef.nativeElement.focus();
|
|
202
|
-
}, this.#delay());
|
|
203
|
-
}
|
|
204
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AutofocusDelayedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
205
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: AutofocusDelayedDirective, isStandalone: true, selector: "[yuvAutofocusDelayed]", inputs: { yuvAutofocusDelayed: { classPropertyName: "yuvAutofocusDelayed", publicName: "yuvAutofocusDelayed", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
206
|
-
}
|
|
207
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AutofocusDelayedDirective, decorators: [{
|
|
208
|
-
type: Directive,
|
|
209
|
-
args: [{
|
|
210
|
-
selector: '[yuvAutofocusDelayed]',
|
|
211
|
-
standalone: true
|
|
212
|
-
}]
|
|
213
|
-
}], propDecorators: { yuvAutofocusDelayed: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuvAutofocusDelayed", required: false }] }] } });
|
|
214
|
-
|
|
215
|
-
class BusyOverlayComponent {
|
|
216
|
-
constructor() {
|
|
217
|
-
this.config = input(...(ngDevMode ? [undefined, { debugName: "config" }] : /* istanbul ignore next */ []));
|
|
218
|
-
this.error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
219
|
-
this.errorDismiss = output();
|
|
220
|
-
}
|
|
221
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BusyOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
222
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: BusyOverlayComponent, isStandalone: true, selector: "yuv-busy-overlay", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { errorDismiss: "errorDismiss" }, host: { properties: { "class.error": "!!error()", "class.blured": "!!config()?.blur", "style.--backdrop-background": "config()?.backdropColor || \"var(--ymt-surface-app)\"" } }, ngImport: i0, template: "<div class=\"backdrop\"></div>\n\n@let e = error();\n@if (e) {\n <div class=\"error\">\n <button ymtIconButton icon-button-size=\"small\" (click)=\"errorDismiss.emit()\">\n <mat-icon>close</mat-icon>\n </button>\n <p>{{ e }}</p>\n </div>\n} @else {\n <mat-progress-spinner class=\"ymt-progress-spinner--giant\" [mode]=\"'indeterminate'\"></mat-progress-spinner>\n}\n", styles: [":host{position:absolute;transition:opacity .2s;inset:0;display:grid;place-items:center;z-index:5}:host.blured{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}:host{--mat-progress-spinner-active-indicator-color: currentColor}:host .error,:host mat-progress-spinner{opacity:0;animation:fadeIn .2s ease-in forwards;animation-delay:.2s}:host .error{display:flex;flex-direction:column;background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);border:var(--ymt-danger);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-corner-xs);max-width:60ch;margin:var(--ymt-spacing-m);overflow-y:auto;align-items:end}:host .error p{margin:var(--ymt-spacing-m)}:host .backdrop{position:absolute;inset:0;background-color:rgb(from var(--backdrop-background) r g b/.5);animation:fadeIn .2s ease-in}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
|
|
223
|
-
}
|
|
224
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BusyOverlayComponent, decorators: [{
|
|
225
|
-
type: Component,
|
|
226
|
-
args: [{ selector: 'yuv-busy-overlay', imports: [YmtIconButtonDirective, MatIconModule, MatProgressSpinner], host: {
|
|
227
|
-
'[class.error]': '!!error()',
|
|
228
|
-
'[class.blured]': '!!config()?.blur',
|
|
229
|
-
'[style.--backdrop-background]': 'config()?.backdropColor || "var(--ymt-surface-app)"'
|
|
230
|
-
}, template: "<div class=\"backdrop\"></div>\n\n@let e = error();\n@if (e) {\n <div class=\"error\">\n <button ymtIconButton icon-button-size=\"small\" (click)=\"errorDismiss.emit()\">\n <mat-icon>close</mat-icon>\n </button>\n <p>{{ e }}</p>\n </div>\n} @else {\n <mat-progress-spinner class=\"ymt-progress-spinner--giant\" [mode]=\"'indeterminate'\"></mat-progress-spinner>\n}\n", styles: [":host{position:absolute;transition:opacity .2s;inset:0;display:grid;place-items:center;z-index:5}:host.blured{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}:host{--mat-progress-spinner-active-indicator-color: currentColor}:host .error,:host mat-progress-spinner{opacity:0;animation:fadeIn .2s ease-in forwards;animation-delay:.2s}:host .error{display:flex;flex-direction:column;background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);border:var(--ymt-danger);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-corner-xs);max-width:60ch;margin:var(--ymt-spacing-m);overflow-y:auto;align-items:end}:host .error p{margin:var(--ymt-spacing-m)}:host .backdrop{position:absolute;inset:0;background-color:rgb(from var(--backdrop-background) r g b/.5);animation:fadeIn .2s ease-in}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}\n"] }]
|
|
231
|
-
}], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorDismiss: [{ type: i0.Output, args: ["errorDismiss"] }] } });
|
|
1
|
+
export * from '@yuuvis/client-components/common';
|
|
232
2
|
|
|
233
3
|
/**
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
* prevent user interaction while component data is loading or some processing is done.
|
|
237
|
-
*
|
|
238
|
-
* It'll also prevent the overlaid element from being interacted with.
|
|
239
|
-
*
|
|
240
|
-
* ```html
|
|
241
|
-
* <div class="data-panel" [yuvBusyOverlay]="isLoadingData">...</div>
|
|
242
|
-
* ```
|
|
243
|
-
* Setting a `yuvBusyError` will replace the loading spinner by the provided error message.
|
|
244
|
-
* You need to keep the `yuvBusyOverlay` condition true to show the error.
|
|
245
|
-
* The error element rendered has a dismiss/close action that trigger the `yuvBusyErrorDismiss`
|
|
246
|
-
* output event, that you then can use to set the busy condition to false.
|
|
247
|
-
*
|
|
248
|
-
* ```html
|
|
249
|
-
* <div class="result-list"
|
|
250
|
-
* [yuvBusyOverlay]="waitingForServerResponse"
|
|
251
|
-
* (yuvBusyErrorDismiss)="waitingForServerResponse = false"
|
|
252
|
-
* [yuvBusyError]="errorMessage">
|
|
253
|
-
* ...
|
|
254
|
-
* </div>
|
|
255
|
-
* ```
|
|
256
|
-
*
|
|
257
|
-
* ```ts
|
|
258
|
-
* // in your component code
|
|
259
|
-
* this.waitingForServerResponse = true;
|
|
260
|
-
* fetchData().subscribe({
|
|
261
|
-
* next: (data) => {
|
|
262
|
-
* ...
|
|
263
|
-
* this.waitingForServerResponse = false;
|
|
264
|
-
* }
|
|
265
|
-
* error: (err) => {
|
|
266
|
-
* this.errorMessage = 'Failed to load data from server: ' + err.message;
|
|
267
|
-
* }
|
|
268
|
-
* });
|
|
269
|
-
* ```
|
|
270
|
-
*
|
|
4
|
+
* @deprecated Import from `@yuuvis/client-components/common` instead.
|
|
5
|
+
* This entry point is a backward-compatibility shim and will be removed in a future release.
|
|
271
6
|
*/
|
|
272
|
-
class BusyOverlayDirective {
|
|
273
|
-
constructor() {
|
|
274
|
-
this.#initialStylePosition = signal('initial', ...(ngDevMode ? [{ debugName: "#initialStylePosition" }] : /* istanbul ignore next */ []));
|
|
275
|
-
this.stylePosition = signal(this.#initialStylePosition(), ...(ngDevMode ? [{ debugName: "stylePosition" }] : /* istanbul ignore next */ []));
|
|
276
|
-
this.#elRef = inject(ElementRef);
|
|
277
|
-
this.#environmentInjector = inject(EnvironmentInjector);
|
|
278
|
-
this.#vcRef = inject(ViewContainerRef);
|
|
279
|
-
/**
|
|
280
|
-
* The Boolean expression to evaluate as the condition for showing the busy overlay
|
|
281
|
-
*/
|
|
282
|
-
this.yuvBusyOverlay = input(false, ...(ngDevMode ? [{ debugName: "yuvBusyOverlay" }] : /* istanbul ignore next */ []));
|
|
283
|
-
this.#yuvBusyOverlayEffect = effect(() => {
|
|
284
|
-
const busy = this.yuvBusyOverlay();
|
|
285
|
-
if (busy === true) {
|
|
286
|
-
this.#addBusyOverlay();
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
this.#removeBusyOverlay();
|
|
290
|
-
}
|
|
291
|
-
}, ...(ngDevMode ? [{ debugName: "#yuvBusyOverlayEffect" }] : /* istanbul ignore next */ []));
|
|
292
|
-
/**
|
|
293
|
-
* Configuration options for the busy overlay. These include
|
|
294
|
-
* e.g. backdrops background color and whether to blur the
|
|
295
|
-
* overlaid content.
|
|
296
|
-
*/
|
|
297
|
-
this.yuvBusyOverlayConfig = input(...(ngDevMode ? [undefined, { debugName: "yuvBusyOverlayConfig" }] : /* istanbul ignore next */ []));
|
|
298
|
-
/**
|
|
299
|
-
* Error message to display in the overlay. If set, the loading spinner is replaced by the error message.
|
|
300
|
-
*/
|
|
301
|
-
this.yuvBusyError = input(...(ngDevMode ? [undefined, { debugName: "yuvBusyError" }] : /* istanbul ignore next */ []));
|
|
302
|
-
this.#yuvBusyErrorEffect = effect(() => this.#busyOverlayComponentRef?.setInput('error', this.yuvBusyError()), ...(ngDevMode ? [{ debugName: "#yuvBusyErrorEffect" }] : /* istanbul ignore next */ []));
|
|
303
|
-
/**
|
|
304
|
-
* Event emitted when the error message's dismiss action is triggered.
|
|
305
|
-
*/
|
|
306
|
-
this.yuvBusyErrorDismiss = output();
|
|
307
|
-
this.#outputSubscriptions = [];
|
|
308
|
-
}
|
|
309
|
-
#initialStylePosition;
|
|
310
|
-
#elRef;
|
|
311
|
-
#environmentInjector;
|
|
312
|
-
#vcRef;
|
|
313
|
-
#yuvBusyOverlayEffect;
|
|
314
|
-
#yuvBusyErrorEffect;
|
|
315
|
-
#busyOverlayComponentRef;
|
|
316
|
-
#outputSubscriptions;
|
|
317
|
-
#attachOverlay() {
|
|
318
|
-
if (this.#busyOverlayComponentRef) {
|
|
319
|
-
// Already attached; just refresh inputs/outputs
|
|
320
|
-
this.#applyInputs();
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
// Create the component inside the directive’s host
|
|
324
|
-
this.#busyOverlayComponentRef = this.#vcRef.createComponent(BusyOverlayComponent, {
|
|
325
|
-
environmentInjector: this.#environmentInjector
|
|
326
|
-
});
|
|
327
|
-
const node = this.#busyOverlayComponentRef.location.nativeElement;
|
|
328
|
-
this.#elRef.nativeElement.appendChild(node);
|
|
329
|
-
this.#applyInputs();
|
|
330
|
-
this.#bindOutputs();
|
|
331
|
-
this.#busyOverlayComponentRef.changeDetectorRef?.detectChanges?.();
|
|
332
|
-
}
|
|
333
|
-
#detachOverlay() {
|
|
334
|
-
// Unsubscribe outputs first
|
|
335
|
-
this.#outputSubscriptions.forEach((sub) => sub.unsubscribe());
|
|
336
|
-
this.#outputSubscriptions = [];
|
|
337
|
-
// Destroy componentRef and clear container
|
|
338
|
-
if (this.#busyOverlayComponentRef) {
|
|
339
|
-
this.#busyOverlayComponentRef.destroy();
|
|
340
|
-
this.#busyOverlayComponentRef = undefined;
|
|
341
|
-
}
|
|
342
|
-
this.#vcRef.clear();
|
|
343
|
-
}
|
|
344
|
-
#applyInputs() {
|
|
345
|
-
if (!this.#busyOverlayComponentRef)
|
|
346
|
-
return;
|
|
347
|
-
this.#busyOverlayComponentRef.setInput('config', this.yuvBusyOverlayConfig());
|
|
348
|
-
this.#busyOverlayComponentRef.setInput('error', this.yuvBusyError());
|
|
349
|
-
}
|
|
350
|
-
#bindOutputs() {
|
|
351
|
-
if (!this.#busyOverlayComponentRef)
|
|
352
|
-
return;
|
|
353
|
-
// Clean up old subscriptions if re-binding
|
|
354
|
-
this.#outputSubscriptions.forEach((sub) => sub.unsubscribe());
|
|
355
|
-
this.#outputSubscriptions = [];
|
|
356
|
-
const errorDismissOutput = this.#busyOverlayComponentRef.instance.errorDismiss;
|
|
357
|
-
this.#outputSubscriptions.push(errorDismissOutput.subscribe(() => this.yuvBusyErrorDismiss.emit()));
|
|
358
|
-
}
|
|
359
|
-
#addBusyOverlay() {
|
|
360
|
-
this.stylePosition.set('relative');
|
|
361
|
-
this.#attachOverlay();
|
|
362
|
-
}
|
|
363
|
-
#removeBusyOverlay() {
|
|
364
|
-
if (!this.#busyOverlayComponentRef)
|
|
365
|
-
return;
|
|
366
|
-
const el = this.#busyOverlayComponentRef.location.nativeElement;
|
|
367
|
-
if (el) {
|
|
368
|
-
el.style.opacity = '0';
|
|
369
|
-
setTimeout(() => {
|
|
370
|
-
this.#detachOverlay();
|
|
371
|
-
this.stylePosition.set(this.#initialStylePosition());
|
|
372
|
-
}, 200);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
ngOnInit() {
|
|
376
|
-
const initialPosition = getComputedStyle(this.#elRef.nativeElement).position;
|
|
377
|
-
this.#initialStylePosition.set(initialPosition === 'static' || !initialPosition ? 'relative' : initialPosition);
|
|
378
|
-
}
|
|
379
|
-
ngOnDestroy() {
|
|
380
|
-
this.#detachOverlay();
|
|
381
|
-
}
|
|
382
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BusyOverlayDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
383
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: BusyOverlayDirective, isStandalone: true, selector: "[yuvBusyOverlay]", inputs: { yuvBusyOverlay: { classPropertyName: "yuvBusyOverlay", publicName: "yuvBusyOverlay", isSignal: true, isRequired: false, transformFunction: null }, yuvBusyOverlayConfig: { classPropertyName: "yuvBusyOverlayConfig", publicName: "yuvBusyOverlayConfig", isSignal: true, isRequired: false, transformFunction: null }, yuvBusyError: { classPropertyName: "yuvBusyError", publicName: "yuvBusyError", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { yuvBusyErrorDismiss: "yuvBusyErrorDismiss" }, host: { properties: { "attr.aria-busy": "yuvBusyOverlay() ? \"true\" : \"false\"", "style.position": "stylePosition()" } }, ngImport: i0 }); }
|
|
384
|
-
}
|
|
385
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BusyOverlayDirective, decorators: [{
|
|
386
|
-
type: Directive,
|
|
387
|
-
args: [{
|
|
388
|
-
selector: '[yuvBusyOverlay]',
|
|
389
|
-
standalone: true,
|
|
390
|
-
host: {
|
|
391
|
-
'[attr.aria-busy]': 'yuvBusyOverlay() ? "true" : "false"',
|
|
392
|
-
'[style.position]': 'stylePosition()'
|
|
393
|
-
}
|
|
394
|
-
}]
|
|
395
|
-
}], propDecorators: { yuvBusyOverlay: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuvBusyOverlay", required: false }] }], yuvBusyOverlayConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuvBusyOverlayConfig", required: false }] }], yuvBusyError: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuvBusyError", required: false }] }], yuvBusyErrorDismiss: [{ type: i0.Output, args: ["yuvBusyErrorDismiss"] }] } });
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Fixes the issue of 'click' event beeing triggered on 'doubleclick' by defining new outputs that
|
|
399
|
-
* distinguish between single and double click.
|
|
400
|
-
*/
|
|
401
|
-
class ClickDoubleDirective {
|
|
402
|
-
constructor() {
|
|
403
|
-
this.debounceTime = input(200, ...(ngDevMode ? [{ debugName: "debounceTime" }] : /* istanbul ignore next */ []));
|
|
404
|
-
this.doubleClick = output({ alias: 'click.double' });
|
|
405
|
-
this.singleClick = output({ alias: 'click.single' });
|
|
406
|
-
this.clicksSubject = new Subject();
|
|
407
|
-
this.clicksSubject.pipe(takeUntilDestroyed(), debounceTime(this.debounceTime())).subscribe({
|
|
408
|
-
next: (event) => {
|
|
409
|
-
event.type === 'click' ? this.singleClick.emit(event) : this.doubleClick.emit(event);
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
clickEvent(event) {
|
|
414
|
-
event.preventDefault();
|
|
415
|
-
event.stopPropagation();
|
|
416
|
-
this.clicksSubject.next(event);
|
|
417
|
-
}
|
|
418
|
-
doubleClickEvent(event) {
|
|
419
|
-
event.preventDefault();
|
|
420
|
-
event.stopPropagation();
|
|
421
|
-
this.clicksSubject.next(event);
|
|
422
|
-
}
|
|
423
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ClickDoubleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
424
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: ClickDoubleDirective, isStandalone: true, selector: "[click.single],[click.double]", inputs: { debounceTime: { classPropertyName: "debounceTime", publicName: "debounceTime", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { doubleClick: "click.double", singleClick: "click.single" }, host: { listeners: { "click": "clickEvent($event)", "dblclick": "doubleClickEvent($event)" } }, ngImport: i0 }); }
|
|
425
|
-
}
|
|
426
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ClickDoubleDirective, decorators: [{
|
|
427
|
-
type: Directive,
|
|
428
|
-
args: [{
|
|
429
|
-
selector: '[click.single],[click.double]',
|
|
430
|
-
host: {
|
|
431
|
-
'(click)': 'clickEvent($event)',
|
|
432
|
-
'(dblclick)': 'doubleClickEvent($event)'
|
|
433
|
-
}
|
|
434
|
-
}]
|
|
435
|
-
}], ctorParameters: () => [], propDecorators: { debounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceTime", required: false }] }], doubleClick: [{ type: i0.Output, args: ["click.double"] }], singleClick: [{ type: i0.Output, args: ["click.single"] }] } });
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Directive to watch the size of an element inside the DOM. Usefull for example to provide
|
|
439
|
-
* a different layout (different components) depending on the available screen estate. You
|
|
440
|
-
* should first try to use CSS container queries but somtimes you need a different set of
|
|
441
|
-
* components to be loaded for a certain component size.
|
|
442
|
-
*
|
|
443
|
-
* Let's say you have components designed for bigger screens. You do not want to load them
|
|
444
|
-
* if there is not enough space for them. So you rather load components that are designed to
|
|
445
|
-
* take less space by providing the best user experience on smaller devices.
|
|
446
|
-
*
|
|
447
|
-
* ```html
|
|
448
|
-
* <div yuvContainerSize (containerHeight)="onContainerResize($event)" (containerWidth)="onContainerResize($event)"></div>
|
|
449
|
-
* ```
|
|
450
|
-
*
|
|
451
|
-
*/
|
|
452
|
-
class ContainerSizeDirective {
|
|
453
|
-
constructor() {
|
|
454
|
-
this.elRef = inject(ElementRef);
|
|
455
|
-
this.ngZone = inject(NgZone);
|
|
456
|
-
this.containerHeight = output();
|
|
457
|
-
this.containerWidth = output();
|
|
458
|
-
this._resizeObserver = new ResizeObserver((entries) => {
|
|
459
|
-
const size = entries[0].borderBoxSize[0];
|
|
460
|
-
if (!this._size || size.blockSize !== this._size.blockSize) {
|
|
461
|
-
this._emit(size.blockSize, true);
|
|
462
|
-
}
|
|
463
|
-
if (!this._size || size.inlineSize !== this._size.inlineSize) {
|
|
464
|
-
this._emit(size.inlineSize);
|
|
465
|
-
}
|
|
466
|
-
this._size = size;
|
|
467
|
-
});
|
|
468
|
-
this._resizeObserver.observe(this.elRef.nativeElement);
|
|
469
|
-
}
|
|
470
|
-
_emit(value, isHeight = false) {
|
|
471
|
-
// ResizeObserver callback is not covered by change detection
|
|
472
|
-
// so it has to be executed withing ngZone
|
|
473
|
-
this.ngZone.run(() => {
|
|
474
|
-
(isHeight ? this.containerHeight : this.containerWidth).emit(value);
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
ngOnDestroy() {
|
|
478
|
-
this._resizeObserver.unobserve(this.elRef.nativeElement);
|
|
479
|
-
}
|
|
480
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContainerSizeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
481
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: ContainerSizeDirective, isStandalone: true, selector: "[yuvContainerSize]", outputs: { containerHeight: "containerHeight", containerWidth: "containerWidth" }, ngImport: i0 }); }
|
|
482
|
-
}
|
|
483
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContainerSizeDirective, decorators: [{
|
|
484
|
-
type: Directive,
|
|
485
|
-
args: [{
|
|
486
|
-
selector: '[yuvContainerSize]',
|
|
487
|
-
standalone: true
|
|
488
|
-
}]
|
|
489
|
-
}], ctorParameters: () => [], propDecorators: { containerHeight: [{ type: i0.Output, args: ["containerHeight"] }], containerWidth: [{ type: i0.Output, args: ["containerWidth"] }] } });
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* Directive for adding drag scroll behaviour to a container element. Elements that overlow will then
|
|
493
|
-
* be 'scrollable' by dragging the list of children.
|
|
494
|
-
*
|
|
495
|
-
* @example
|
|
496
|
-
* <div yuvDragScroll>
|
|
497
|
-
* <div class="tile">#1</div>
|
|
498
|
-
* <div class="tile">#2</div>
|
|
499
|
-
* <div class="tile">#3</div>
|
|
500
|
-
* ...
|
|
501
|
-
* </div>
|
|
502
|
-
*/
|
|
503
|
-
class DragScrollDirective {
|
|
504
|
-
#document = inject(DOCUMENT);
|
|
505
|
-
#element = inject(ElementRef);
|
|
506
|
-
#dragging = false;
|
|
507
|
-
#applyDraggingStyles(el, remove) {
|
|
508
|
-
const draggingStyles = {
|
|
509
|
-
cursor: 'grabbing'
|
|
510
|
-
};
|
|
511
|
-
Object.keys(draggingStyles).forEach((property) => {
|
|
512
|
-
if (remove) {
|
|
513
|
-
el.style.removeProperty(property);
|
|
514
|
-
}
|
|
515
|
-
else {
|
|
516
|
-
el.style.setProperty(property, draggingStyles[property]);
|
|
517
|
-
}
|
|
518
|
-
});
|
|
519
|
-
}
|
|
520
|
-
ngAfterViewInit() {
|
|
521
|
-
const nativeElement = this.#element.nativeElement;
|
|
522
|
-
const mouseDown$ = fromEvent(nativeElement, 'mousedown');
|
|
523
|
-
const mouseMove$ = fromEvent(this.#document, 'mousemove');
|
|
524
|
-
const mouseUp$ = fromEvent(this.#document, 'mouseup').pipe(tap((e) => {
|
|
525
|
-
if (this.#dragging) {
|
|
526
|
-
e.preventDefault();
|
|
527
|
-
e.stopPropagation();
|
|
528
|
-
this.#dragging = false;
|
|
529
|
-
this.#applyDraggingStyles(nativeElement, true);
|
|
530
|
-
}
|
|
531
|
-
}));
|
|
532
|
-
const dragMove$ = mouseDown$.pipe(filter(() =>
|
|
533
|
-
// only calculate new scroll position if the container is actually overflowing
|
|
534
|
-
nativeElement.scrollHeight > nativeElement.clientHeight || nativeElement.scrollWidth > nativeElement.clientWidth), tap((startEvent) => {
|
|
535
|
-
this.#applyDraggingStyles(nativeElement);
|
|
536
|
-
startEvent.preventDefault();
|
|
537
|
-
startEvent.stopPropagation();
|
|
538
|
-
}), switchMap((startEvent) => {
|
|
539
|
-
this.#dragging = true;
|
|
540
|
-
const scrollPos = {
|
|
541
|
-
left: nativeElement.scrollLeft,
|
|
542
|
-
top: nativeElement.scrollTop
|
|
543
|
-
};
|
|
544
|
-
return mouseMove$.pipe(map((moveEvent) => {
|
|
545
|
-
moveEvent.preventDefault();
|
|
546
|
-
moveEvent.stopPropagation();
|
|
547
|
-
return {
|
|
548
|
-
startEvent,
|
|
549
|
-
moveEvent,
|
|
550
|
-
scrollPos
|
|
551
|
-
};
|
|
552
|
-
}), takeUntil(mouseUp$));
|
|
553
|
-
}), tap(({ startEvent, moveEvent, scrollPos }) => {
|
|
554
|
-
const diffX = moveEvent.clientX - startEvent.clientX;
|
|
555
|
-
const diffY = moveEvent.clientY - startEvent.clientY;
|
|
556
|
-
nativeElement.scrollLeft = scrollPos.left - diffX;
|
|
557
|
-
nativeElement.scrollTop = scrollPos.top - diffY;
|
|
558
|
-
}));
|
|
559
|
-
dragMove$.subscribe();
|
|
560
|
-
}
|
|
561
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DragScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
562
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: DragScrollDirective, isStandalone: true, selector: "[yuvDragScroll]", ngImport: i0 }); }
|
|
563
|
-
}
|
|
564
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DragScrollDirective, decorators: [{
|
|
565
|
-
type: Directive,
|
|
566
|
-
args: [{
|
|
567
|
-
selector: '[yuvDragScroll]'
|
|
568
|
-
}]
|
|
569
|
-
}] });
|
|
570
|
-
|
|
571
|
-
class DragSelectDirective {
|
|
572
|
-
constructor() {
|
|
573
|
-
this.#selectStartX = 0;
|
|
574
|
-
this.#selectStartY = 0;
|
|
575
|
-
this.#selection = [];
|
|
576
|
-
this.items = contentChildren(DragSelectItemDirective, ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
577
|
-
this.#selectables = computed(() => this.items().map((item) => item.el), ...(ngDevMode ? [{ debugName: "#selectables" }] : /* istanbul ignore next */ []));
|
|
578
|
-
this.yuvDragSelect = input(...(ngDevMode ? [undefined, { debugName: "yuvDragSelect" }] : /* istanbul ignore next */ []));
|
|
579
|
-
this.dragSelectChange = output();
|
|
580
|
-
this.dragSelect = output();
|
|
581
|
-
this.#onPointerUp = () => {
|
|
582
|
-
removeEventListener('pointermove', this.#resize);
|
|
583
|
-
removeEventListener('pointerup', this.#onPointerUp);
|
|
584
|
-
if (this.#selection.length)
|
|
585
|
-
this.dragSelect.emit(this.#selection);
|
|
586
|
-
if (this.#selector)
|
|
587
|
-
this.#selector.remove();
|
|
588
|
-
};
|
|
589
|
-
this.#resize = (event) => {
|
|
590
|
-
if (!this.#selector)
|
|
591
|
-
return;
|
|
592
|
-
const diffX = event.pageX - this.#selectStartX;
|
|
593
|
-
const diffY = event.pageY - this.#selectStartY;
|
|
594
|
-
this.#selector.style.left = diffX < 0 ? this.#selectStartX + diffX + 'px' : this.#selectStartX + 'px';
|
|
595
|
-
this.#selector.style.top = diffY < 0 ? this.#selectStartY + diffY + 'px' : this.#selectStartY + 'px';
|
|
596
|
-
this.#selector.style.height = Math.abs(diffY) + 'px';
|
|
597
|
-
this.#selector.style.width = Math.abs(diffX) + 'px';
|
|
598
|
-
this.#selector.style.border = `1px solid ${this.yuvDragSelect()?.selectorColor || 'var(--ymt-primary'}`;
|
|
599
|
-
this.#checkSelected();
|
|
600
|
-
};
|
|
601
|
-
this.#checkSelected = () => {
|
|
602
|
-
if (!this.#selector)
|
|
603
|
-
return;
|
|
604
|
-
const select = this.#selector.getBoundingClientRect();
|
|
605
|
-
const { x, y, height, width } = select;
|
|
606
|
-
if (!height || !width)
|
|
607
|
-
return;
|
|
608
|
-
const currSelectionLength = this.#selection.length;
|
|
609
|
-
this.#selectables().forEach((selectable, idx) => {
|
|
610
|
-
const r1 = { x: x + window.scrollX, y: y + window.scrollY, height, width };
|
|
611
|
-
const r2 = selectable.getBoundingClientRect();
|
|
612
|
-
this.#selection = this.#selection.filter((s) => s !== idx);
|
|
613
|
-
if (this.#checkRectIntersection(r1, r2)) {
|
|
614
|
-
this.#selection.push(idx);
|
|
615
|
-
}
|
|
616
|
-
});
|
|
617
|
-
if (currSelectionLength !== this.#selection.length) {
|
|
618
|
-
this.dragSelectChange.emit(this.#selection);
|
|
619
|
-
}
|
|
620
|
-
};
|
|
621
|
-
this.#checkRectIntersection = (r1, r2) => {
|
|
622
|
-
return !(r1.x + r1.width < r2.x || r2.x + r2.width < r1.x || r1.y + r1.height < r2.y || r2.y + r2.height < r1.y);
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
#selector;
|
|
626
|
-
#selectStartX;
|
|
627
|
-
#selectStartY;
|
|
628
|
-
#selection;
|
|
629
|
-
onPointerDown(event) {
|
|
630
|
-
if (this.yuvDragSelect()?.disabled || event.target.tagName === 'BUTTON')
|
|
631
|
-
return;
|
|
632
|
-
event.preventDefault();
|
|
633
|
-
this.#selectStartX = event.pageX;
|
|
634
|
-
this.#selectStartY = event.pageY;
|
|
635
|
-
const div = document.createElement('div');
|
|
636
|
-
div.style.position = 'absolute';
|
|
637
|
-
div.style.width = '0';
|
|
638
|
-
div.style.height = '0';
|
|
639
|
-
div.style.left = this.#selectStartX + 'px';
|
|
640
|
-
div.style.top = this.#selectStartY + 'px';
|
|
641
|
-
div.classList.add('drag-select');
|
|
642
|
-
this.#selector = div;
|
|
643
|
-
document.body.append(this.#selector);
|
|
644
|
-
this.#selection = [];
|
|
645
|
-
addEventListener('pointermove', this.#resize);
|
|
646
|
-
addEventListener('pointerup', this.#onPointerUp);
|
|
647
|
-
}
|
|
648
|
-
#selectables;
|
|
649
|
-
#onPointerUp;
|
|
650
|
-
#resize;
|
|
651
|
-
#checkSelected;
|
|
652
|
-
#checkRectIntersection;
|
|
653
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DragSelectDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
654
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.9", type: DragSelectDirective, isStandalone: true, selector: "[yuvDragSelect]", inputs: { yuvDragSelect: { classPropertyName: "yuvDragSelect", publicName: "yuvDragSelect", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragSelectChange: "dragSelectChange", dragSelect: "dragSelect" }, host: { listeners: { "pointerdown": "onPointerDown($event)" } }, queries: [{ propertyName: "items", predicate: DragSelectItemDirective, isSignal: true }], ngImport: i0 }); }
|
|
655
|
-
}
|
|
656
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DragSelectDirective, decorators: [{
|
|
657
|
-
type: Directive,
|
|
658
|
-
args: [{
|
|
659
|
-
selector: '[yuvDragSelect]',
|
|
660
|
-
host: {
|
|
661
|
-
'(pointerdown)': 'onPointerDown($event)'
|
|
662
|
-
}
|
|
663
|
-
}]
|
|
664
|
-
}], propDecorators: { items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DragSelectItemDirective), { isSignal: true }] }], yuvDragSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuvDragSelect", required: false }] }], dragSelectChange: [{ type: i0.Output, args: ["dragSelectChange"] }], dragSelect: [{ type: i0.Output, args: ["dragSelect"] }] } });
|
|
665
|
-
class DragSelectItemDirective {
|
|
666
|
-
constructor() {
|
|
667
|
-
this.#elRef = inject(ElementRef);
|
|
668
|
-
this.el = this.#elRef.nativeElement;
|
|
669
|
-
}
|
|
670
|
-
#elRef;
|
|
671
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DragSelectItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
672
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: DragSelectItemDirective, isStandalone: true, selector: "[yuvDragSelectItem]", ngImport: i0 }); }
|
|
673
|
-
}
|
|
674
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DragSelectItemDirective, decorators: [{
|
|
675
|
-
type: Directive,
|
|
676
|
-
args: [{
|
|
677
|
-
selector: '[yuvDragSelectItem]',
|
|
678
|
-
standalone: true
|
|
679
|
-
}]
|
|
680
|
-
}] });
|
|
681
|
-
|
|
682
|
-
class FileDropService {
|
|
683
|
-
constructor() {
|
|
684
|
-
this.activeDropZone = signal(null, ...(ngDevMode ? [{ debugName: "activeDropZone" }] : /* istanbul ignore next */ []));
|
|
685
|
-
}
|
|
686
|
-
fileOver(id, active) {
|
|
687
|
-
this.activeDropZone.set(active ? id : null);
|
|
688
|
-
}
|
|
689
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FileDropService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
690
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FileDropService, providedIn: 'root' }); }
|
|
691
|
-
}
|
|
692
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FileDropService, decorators: [{
|
|
693
|
-
type: Injectable,
|
|
694
|
-
args: [{
|
|
695
|
-
providedIn: 'root'
|
|
696
|
-
}]
|
|
697
|
-
}] });
|
|
698
|
-
|
|
699
|
-
class FileDropZoneDirective {
|
|
700
|
-
constructor() {
|
|
701
|
-
this.#elRef = inject(ElementRef);
|
|
702
|
-
this.#fileDropService = inject(FileDropService);
|
|
703
|
-
// ID to track the element
|
|
704
|
-
this.#id = crypto.randomUUID();
|
|
705
|
-
this.active = computed(() => {
|
|
706
|
-
const fileOver = this.#fileDropService.activeDropZone() === this.#id;
|
|
707
|
-
this.fileDropOver.emit(fileOver);
|
|
708
|
-
return fileOver;
|
|
709
|
-
}, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
710
|
-
this.#activeEffect = effect(() => {
|
|
711
|
-
this.#toggleCover(this.active());
|
|
712
|
-
}, ...(ngDevMode ? [{ debugName: "#activeEffect" }] : /* istanbul ignore next */ []));
|
|
713
|
-
this.#defaultDragOverCoverStyles = {
|
|
714
|
-
// outline: '2px dashed var(--ymt-primary)',
|
|
715
|
-
display: 'flex',
|
|
716
|
-
transition: 'background-color .3s ease-in-out',
|
|
717
|
-
'z-index': '500',
|
|
718
|
-
'align-items': 'center',
|
|
719
|
-
'justify-content': 'center',
|
|
720
|
-
'outline-offset': '-2px',
|
|
721
|
-
'background-color': 'rgb(from var(--ymt-primary) r g b / .5)'
|
|
722
|
-
};
|
|
723
|
-
this.#defaultDragOverCoverLabelStyles = {
|
|
724
|
-
outline: '1px solid var(--ymt-primary)',
|
|
725
|
-
padding: 'var(--ymt-spacing-m, 16px)',
|
|
726
|
-
'background-color': 'rgb(from var(--ymt-primary) r g b / 0.9)',
|
|
727
|
-
color: 'var(--ymt-on-primary)'
|
|
728
|
-
};
|
|
729
|
-
this.yuvFileDropZone = input(...(ngDevMode ? [undefined, { debugName: "yuvFileDropZone" }] : /* istanbul ignore next */ []));
|
|
730
|
-
this.fileDropDisabled = input(false, ...(ngDevMode ? [{ debugName: "fileDropDisabled" }] : /* istanbul ignore next */ []));
|
|
731
|
-
this.fileDrop = output();
|
|
732
|
-
this.fileDropOver = output();
|
|
733
|
-
}
|
|
734
|
-
#elRef;
|
|
735
|
-
#fileDropService;
|
|
736
|
-
#coverElement;
|
|
737
|
-
// ID to track the element
|
|
738
|
-
#id;
|
|
739
|
-
#activeEffect;
|
|
740
|
-
#defaultDragOverCoverStyles;
|
|
741
|
-
#defaultDragOverCoverLabelStyles;
|
|
742
|
-
onDrop(event) {
|
|
743
|
-
if (this.fileDropDisabled())
|
|
744
|
-
return;
|
|
745
|
-
event.preventDefault();
|
|
746
|
-
event.stopPropagation();
|
|
747
|
-
this.#fileDropService.fileOver(this.#id, false);
|
|
748
|
-
const dataTransfer = event.dataTransfer;
|
|
749
|
-
if (dataTransfer) {
|
|
750
|
-
if (dataTransfer?.items) {
|
|
751
|
-
const files = [];
|
|
752
|
-
for (let i = 0; i < dataTransfer.items.length; i++) {
|
|
753
|
-
// If dropped items aren't files, reject them
|
|
754
|
-
if (dataTransfer.items[i].kind === 'file') {
|
|
755
|
-
const file = dataTransfer.items[i].getAsFile();
|
|
756
|
-
if (file)
|
|
757
|
-
files.push(file);
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
dataTransfer.items.clear();
|
|
761
|
-
this.fileDrop.emit(files);
|
|
762
|
-
}
|
|
763
|
-
else {
|
|
764
|
-
const files = dataTransfer.files;
|
|
765
|
-
dataTransfer.clearData();
|
|
766
|
-
this.fileDrop.emit(Array.from(files));
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
onDragOver(event) {
|
|
771
|
-
if (this.fileDropDisabled())
|
|
772
|
-
return;
|
|
773
|
-
event.stopPropagation();
|
|
774
|
-
event.preventDefault();
|
|
775
|
-
this.#fileDropService.fileOver(this.#id, true);
|
|
776
|
-
}
|
|
777
|
-
onDragLeave(event) {
|
|
778
|
-
if (this.fileDropDisabled())
|
|
779
|
-
return;
|
|
780
|
-
if (event.target.getAttribute('id') === this.#coverElement?.getAttribute('id')) {
|
|
781
|
-
this.#fileDropService.fileOver(this.#id, false);
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
onBodyDragOver(event) {
|
|
785
|
-
event.preventDefault();
|
|
786
|
-
event.stopPropagation();
|
|
787
|
-
}
|
|
788
|
-
onBodyDrop(event) {
|
|
789
|
-
event.preventDefault();
|
|
790
|
-
}
|
|
791
|
-
#toggleCover(active) {
|
|
792
|
-
const el = this.#elRef.nativeElement;
|
|
793
|
-
if (this.#coverElement) {
|
|
794
|
-
el.style.position = 'initial';
|
|
795
|
-
this.#coverElement.remove();
|
|
796
|
-
this.#coverElement = undefined;
|
|
797
|
-
}
|
|
798
|
-
if (active) {
|
|
799
|
-
el.style.position = 'relative';
|
|
800
|
-
this.#coverElement = this.#createCoverElement();
|
|
801
|
-
el.append(this.#coverElement);
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
#createCoverElement() {
|
|
805
|
-
const coverElement = document.createElement('div');
|
|
806
|
-
coverElement.classList.add('yuv-file-drop-zone-cover');
|
|
807
|
-
coverElement.setAttribute('id', this.#id);
|
|
808
|
-
coverElement.style.position = 'absolute';
|
|
809
|
-
coverElement.style.inset = '0';
|
|
810
|
-
const styles = this.yuvFileDropZone()?.coverStyles || this.#defaultDragOverCoverStyles;
|
|
811
|
-
Object.keys(styles).forEach((k) => {
|
|
812
|
-
coverElement.style[k] = styles[k];
|
|
813
|
-
});
|
|
814
|
-
const label = this.yuvFileDropZone()?.label;
|
|
815
|
-
if (label) {
|
|
816
|
-
const coverLabelElement = document.createElement('div');
|
|
817
|
-
coverElement.classList.add('yuv-file-drop-zone-label');
|
|
818
|
-
coverLabelElement.innerText = label;
|
|
819
|
-
const labelStyles = this.yuvFileDropZone()?.coverLabelStyles || this.#defaultDragOverCoverLabelStyles;
|
|
820
|
-
Object.keys(labelStyles).forEach((k) => {
|
|
821
|
-
coverLabelElement.style[k] = labelStyles[k];
|
|
822
|
-
});
|
|
823
|
-
coverLabelElement.style.pointerEvents = 'none';
|
|
824
|
-
coverElement.append(coverLabelElement);
|
|
825
|
-
}
|
|
826
|
-
return coverElement;
|
|
827
|
-
}
|
|
828
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FileDropZoneDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
829
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: FileDropZoneDirective, isStandalone: true, selector: "[yuvFileDropZone]", inputs: { yuvFileDropZone: { classPropertyName: "yuvFileDropZone", publicName: "yuvFileDropZone", isSignal: true, isRequired: false, transformFunction: null }, fileDropDisabled: { classPropertyName: "fileDropDisabled", publicName: "fileDropDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileDrop: "fileDrop", fileDropOver: "fileDropOver" }, host: { listeners: { "drop": "onDrop($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "body:dragover": "onBodyDragOver($event)", "body:drop": "onBodyDrop($event)" } }, ngImport: i0 }); }
|
|
830
|
-
}
|
|
831
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FileDropZoneDirective, decorators: [{
|
|
832
|
-
type: Directive,
|
|
833
|
-
args: [{
|
|
834
|
-
selector: '[yuvFileDropZone]',
|
|
835
|
-
host: {
|
|
836
|
-
'(drop)': 'onDrop($event)',
|
|
837
|
-
'(dragover)': 'onDragOver($event)',
|
|
838
|
-
'(dragleave)': 'onDragLeave($event)',
|
|
839
|
-
'(body:dragover)': 'onBodyDragOver($event)',
|
|
840
|
-
'(body:drop)': 'onBodyDrop($event)'
|
|
841
|
-
}
|
|
842
|
-
}]
|
|
843
|
-
}], propDecorators: { yuvFileDropZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuvFileDropZone", required: false }] }], fileDropDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileDropDisabled", required: false }] }], fileDrop: [{ type: i0.Output, args: ["fileDrop"] }], fileDropOver: [{ type: i0.Output, args: ["fileDropOver"] }] } });
|
|
844
|
-
|
|
845
|
-
/**
|
|
846
|
-
* Directive keeping track of the focus beeing within a component. Once the component or
|
|
847
|
-
* any of its child components gain focus, a class of `focusWithin` will be set on the
|
|
848
|
-
* host component in order to allow styling it while beeing focused. Furthermore you can
|
|
849
|
-
* register callbacks once the component gets or looses focus.
|
|
850
|
-
*
|
|
851
|
-
* @example
|
|
852
|
-
* // just set the css class
|
|
853
|
-
* <some-component yuvFocusWithin></some-component>
|
|
854
|
-
* // set the css class and listen to focus changes
|
|
855
|
-
* <some-component (yuvFocusWithin)="onFocusEnter()" (yuvFocusWithinBlur)="onFocusLeave()"></some-component>
|
|
856
|
-
*/
|
|
857
|
-
class FocusWithinDirective {
|
|
858
|
-
onFocusIn(evt) {
|
|
859
|
-
const hadFocusWithin = this.hasFocusWithin;
|
|
860
|
-
this.hasFocusWithin = this.matchesFocusWithin();
|
|
861
|
-
if (!hadFocusWithin && this.hasFocusWithin) {
|
|
862
|
-
this.yuvFocusWithin.emit();
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
onFocusOut(evt) {
|
|
866
|
-
const hadFocusWithin = this.hasFocusWithin;
|
|
867
|
-
this.hasFocusWithin = this.matchesFocusWithin();
|
|
868
|
-
if (hadFocusWithin && !this.hasFocusWithin) {
|
|
869
|
-
this.yuvFocusWithinBlur.emit();
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
/**
|
|
873
|
-
* @ignore
|
|
874
|
-
*/
|
|
875
|
-
constructor(elRef) {
|
|
876
|
-
this.elRef = elRef;
|
|
877
|
-
this.eventCount = 0;
|
|
878
|
-
this.hasFocusWithin = false;
|
|
879
|
-
/**
|
|
880
|
-
* Emitted once the component or any of its child components gains focus.
|
|
881
|
-
*/
|
|
882
|
-
this.yuvFocusWithin = output();
|
|
883
|
-
/**
|
|
884
|
-
* Emitted once the component (incl. any of its child components) looses focus.
|
|
885
|
-
*/
|
|
886
|
-
this.yuvFocusWithinBlur = output();
|
|
887
|
-
}
|
|
888
|
-
// Determine if the given node matches the given selector.
|
|
889
|
-
// @see: https://www.bennadel.com/blog/3476-checking-to-see-if-an-element-has-a-css-pseudo-class-in-javascript.htm
|
|
890
|
-
matchesFocusWithin() {
|
|
891
|
-
const node = this.elRef.nativeElement;
|
|
892
|
-
const nativeMatches = node.matches || node.msMatchesSelector;
|
|
893
|
-
try {
|
|
894
|
-
return nativeMatches.call(node, ':focus-within');
|
|
895
|
-
}
|
|
896
|
-
catch (error) {
|
|
897
|
-
return false;
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FocusWithinDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
901
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: FocusWithinDirective, isStandalone: true, selector: "[yuvFocusWithin]", outputs: { yuvFocusWithin: "yuvFocusWithin", yuvFocusWithinBlur: "yuvFocusWithinBlur" }, host: { listeners: { "focusin": "onFocusIn($event)", "focusout": "onFocusOut($event)" }, properties: { "class.focusWithin": "hasFocusWithin" } }, ngImport: i0 }); }
|
|
902
|
-
}
|
|
903
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FocusWithinDirective, decorators: [{
|
|
904
|
-
type: Directive,
|
|
905
|
-
args: [{
|
|
906
|
-
selector: '[yuvFocusWithin]',
|
|
907
|
-
host: {
|
|
908
|
-
'[class.focusWithin]': 'hasFocusWithin',
|
|
909
|
-
'(focusin)': 'onFocusIn($event)',
|
|
910
|
-
'(focusout)': 'onFocusOut($event)'
|
|
911
|
-
}
|
|
912
|
-
}]
|
|
913
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { yuvFocusWithin: [{ type: i0.Output, args: ["yuvFocusWithin"] }], yuvFocusWithinBlur: [{ type: i0.Output, args: ["yuvFocusWithinBlur"] }] } });
|
|
914
|
-
|
|
915
|
-
/**
|
|
916
|
-
* Directive for applying light dismiss actions. Adding this directive will trigger
|
|
917
|
-
* the given function when the user clicks outside the component or hits escape.
|
|
918
|
-
*
|
|
919
|
-
* ```ts
|
|
920
|
-
* <div class="notifications" (yuvLightDismiss)="close()">
|
|
921
|
-
* ...
|
|
922
|
-
* </div>
|
|
923
|
-
* ```
|
|
924
|
-
*/
|
|
925
|
-
class LightDismissDirective {
|
|
926
|
-
constructor() {
|
|
927
|
-
this.elRef = inject(ElementRef);
|
|
928
|
-
this.yuvLightDismiss = output();
|
|
929
|
-
}
|
|
930
|
-
onKeydownHandler(event) {
|
|
931
|
-
if (!event.defaultPrevented) {
|
|
932
|
-
this.yuvLightDismiss.emit();
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
onMousedown(event) {
|
|
936
|
-
if (!this.elRef.nativeElement.contains(event.target)) {
|
|
937
|
-
this.yuvLightDismiss.emit();
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LightDismissDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
941
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: LightDismissDirective, isStandalone: true, selector: "[yuvLightDismiss]", outputs: { yuvLightDismiss: "yuvLightDismiss" }, host: { listeners: { "document:keydown.escape": "onKeydownHandler($event)", "document:mousedown": "onMousedown($event)" } }, ngImport: i0 }); }
|
|
942
|
-
}
|
|
943
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LightDismissDirective, decorators: [{
|
|
944
|
-
type: Directive,
|
|
945
|
-
args: [{
|
|
946
|
-
selector: '[yuvLightDismiss]',
|
|
947
|
-
host: {
|
|
948
|
-
'(document:keydown.escape)': 'onKeydownHandler($event)',
|
|
949
|
-
'(document:mousedown)': 'onMousedown($event)'
|
|
950
|
-
}
|
|
951
|
-
}]
|
|
952
|
-
}], propDecorators: { yuvLightDismiss: [{ type: i0.Output, args: ["yuvLightDismiss"] }] } });
|
|
953
|
-
|
|
954
|
-
class LongPressDirective {
|
|
955
|
-
constructor() {
|
|
956
|
-
this.elRef = inject(ElementRef);
|
|
957
|
-
this.threshold = 500;
|
|
958
|
-
this.yuvLongPress = input({
|
|
959
|
-
enabled: false
|
|
960
|
-
}, ...(ngDevMode ? [{ debugName: "yuvLongPress" }] : /* istanbul ignore next */ []));
|
|
961
|
-
this.longpress = output();
|
|
962
|
-
const mousedown = fromEvent(this.elRef.nativeElement, 'mousedown').pipe(takeUntilDestroyed(), filter((event) => event.button == 0), // Only allow left button (Primary button)
|
|
963
|
-
map(() => true) // turn on threshold counter
|
|
964
|
-
);
|
|
965
|
-
const touchstart = fromEvent(this.elRef.nativeElement, 'touchstart').pipe(takeUntilDestroyed(), map(() => true));
|
|
966
|
-
const touchEnd = fromEvent(this.elRef.nativeElement, 'touchend').pipe(takeUntilDestroyed(), map(() => false));
|
|
967
|
-
const mouseup = fromEvent(window, 'mouseup').pipe(takeUntilDestroyed(), filter((event) => event.button == 0), // Only allow left button (Primary button)
|
|
968
|
-
map(() => false) // reset threshold counter
|
|
969
|
-
);
|
|
970
|
-
merge(mousedown, mouseup, touchstart, touchEnd)
|
|
971
|
-
.pipe(takeUntilDestroyed(), switchMap((state) => (state ? timer(this.threshold, 100) : of(null))), filter((value) => !!value))
|
|
972
|
-
.subscribe(() => this.longpress.emit());
|
|
973
|
-
}
|
|
974
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LongPressDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
975
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: LongPressDirective, isStandalone: true, selector: "[yuvLongPress]", inputs: { yuvLongPress: { classPropertyName: "yuvLongPress", publicName: "yuvLongPress", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { longpress: "longpress" }, ngImport: i0 }); }
|
|
976
|
-
}
|
|
977
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LongPressDirective, decorators: [{
|
|
978
|
-
type: Directive,
|
|
979
|
-
args: [{
|
|
980
|
-
selector: '[yuvLongPress]',
|
|
981
|
-
standalone: true
|
|
982
|
-
}]
|
|
983
|
-
}], ctorParameters: () => [], propDecorators: { yuvLongPress: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuvLongPress", required: false }] }], longpress: [{ type: i0.Output, args: ["longpress"] }] } });
|
|
984
|
-
|
|
985
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
986
|
-
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
987
|
-
// @see: https://netbasal.com/forwarding-form-controls-to-custom-control-components-in-angular-701e8406cc55
|
|
988
|
-
class NoopValueAccessorDirective {
|
|
989
|
-
writeValue(obj) { }
|
|
990
|
-
registerOnChange(fn) { }
|
|
991
|
-
registerOnTouched(fn) { }
|
|
992
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NoopValueAccessorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
993
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: NoopValueAccessorDirective, isStandalone: true, providers: [
|
|
994
|
-
{
|
|
995
|
-
provide: NG_VALUE_ACCESSOR,
|
|
996
|
-
multi: true,
|
|
997
|
-
useExisting: forwardRef(() => NoopValueAccessorDirective)
|
|
998
|
-
}
|
|
999
|
-
], ngImport: i0 }); }
|
|
1000
|
-
}
|
|
1001
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NoopValueAccessorDirective, decorators: [{
|
|
1002
|
-
type: Directive,
|
|
1003
|
-
args: [{
|
|
1004
|
-
standalone: true,
|
|
1005
|
-
providers: [
|
|
1006
|
-
{
|
|
1007
|
-
provide: NG_VALUE_ACCESSOR,
|
|
1008
|
-
multi: true,
|
|
1009
|
-
useExisting: forwardRef(() => NoopValueAccessorDirective)
|
|
1010
|
-
}
|
|
1011
|
-
]
|
|
1012
|
-
}]
|
|
1013
|
-
}] });
|
|
1014
|
-
function injectNgControl(cva) {
|
|
1015
|
-
const ngControl = inject(NgControl, { self: true, optional: true });
|
|
1016
|
-
if (!ngControl)
|
|
1017
|
-
return null;
|
|
1018
|
-
if (ngControl instanceof FormControlDirective || ngControl instanceof FormControlName || ngControl instanceof NgModel) {
|
|
1019
|
-
if (cva)
|
|
1020
|
-
ngControl.valueAccessor = cva;
|
|
1021
|
-
return ngControl;
|
|
1022
|
-
}
|
|
1023
|
-
throw new Error('...');
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
const DEFAULT_SCROLL_AMOUNT = 150;
|
|
1027
|
-
const THRESHOLD = 1;
|
|
1028
|
-
/**
|
|
1029
|
-
* Directive that adds left/right scroll buttons around the host element when its content overflows horizontally.
|
|
1030
|
-
* The directive restructures the DOM by wrapping the host inside a scroll container with navigation buttons.
|
|
1031
|
-
*
|
|
1032
|
-
* @example
|
|
1033
|
-
* <mat-chip-grid yuvScrollButtons>...</mat-chip-grid>
|
|
1034
|
-
*
|
|
1035
|
-
* @example
|
|
1036
|
-
* <div yuvScrollButtons [yuvScrollButtonsAmount]="200">...</div>
|
|
1037
|
-
*/
|
|
1038
|
-
class ScrollButtonsDirective {
|
|
1039
|
-
#renderer;
|
|
1040
|
-
#elRef;
|
|
1041
|
-
#destroyRef;
|
|
1042
|
-
#leftBtn;
|
|
1043
|
-
#rightBtn;
|
|
1044
|
-
#scrollContent;
|
|
1045
|
-
constructor() {
|
|
1046
|
-
this.#renderer = inject(Renderer2);
|
|
1047
|
-
this.#elRef = inject(ElementRef);
|
|
1048
|
-
this.translate = inject(TranslateService);
|
|
1049
|
-
this.#destroyRef = inject(DestroyRef);
|
|
1050
|
-
/** How many pixels to scroll per button click. */
|
|
1051
|
-
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
1052
|
-
this.yuvScrollButtonsAmount = input(DEFAULT_SCROLL_AMOUNT, ...(ngDevMode ? [{ debugName: "yuvScrollButtonsAmount" }] : /* istanbul ignore next */ []));
|
|
1053
|
-
afterNextRender(() => this.#init());
|
|
1054
|
-
}
|
|
1055
|
-
#init() {
|
|
1056
|
-
const host = this.#elRef.nativeElement;
|
|
1057
|
-
const parent = host.parentNode;
|
|
1058
|
-
const renderer = this.#renderer;
|
|
1059
|
-
// Create wrapper
|
|
1060
|
-
const wrapper = renderer.createElement('div');
|
|
1061
|
-
this.#applyStyles(wrapper, {
|
|
1062
|
-
display: 'flex',
|
|
1063
|
-
'align-items': 'center',
|
|
1064
|
-
flex: '1',
|
|
1065
|
-
'min-width': '0'
|
|
1066
|
-
});
|
|
1067
|
-
// Create scroll content container
|
|
1068
|
-
this.#scrollContent = renderer.createElement('div');
|
|
1069
|
-
this.#applyStyles(this.#scrollContent, {
|
|
1070
|
-
flex: '1',
|
|
1071
|
-
'overflow-x': 'auto',
|
|
1072
|
-
'scrollbar-width': 'none',
|
|
1073
|
-
'min-width': '0'
|
|
1074
|
-
});
|
|
1075
|
-
// Create buttons
|
|
1076
|
-
this.#leftBtn = this.#createButton('chevron_left');
|
|
1077
|
-
this.#rightBtn = this.#createButton('chevron_right');
|
|
1078
|
-
// Restructure DOM: replace host with wrapper, move host into scroll content
|
|
1079
|
-
renderer.insertBefore(parent, wrapper, host);
|
|
1080
|
-
renderer.appendChild(this.#scrollContent, host);
|
|
1081
|
-
renderer.appendChild(wrapper, this.#leftBtn);
|
|
1082
|
-
renderer.appendChild(wrapper, this.#scrollContent);
|
|
1083
|
-
renderer.appendChild(wrapper, this.#rightBtn);
|
|
1084
|
-
// Apply chip-specific overrides
|
|
1085
|
-
this.#applyChipOverrides(host);
|
|
1086
|
-
// Hide buttons initially
|
|
1087
|
-
this.#setButtonVisible(this.#leftBtn, false);
|
|
1088
|
-
this.#setButtonVisible(this.#rightBtn, false);
|
|
1089
|
-
// Set up listeners
|
|
1090
|
-
this.#scrollContent.addEventListener('scroll', () => this.#checkOverflow(), { passive: true });
|
|
1091
|
-
const resizeObserver = new ResizeObserver(() => this.#checkOverflow());
|
|
1092
|
-
resizeObserver.observe(this.#scrollContent);
|
|
1093
|
-
const mutationObserver = new MutationObserver(() => this.#checkOverflow());
|
|
1094
|
-
mutationObserver.observe(this.#scrollContent, { childList: true, subtree: true });
|
|
1095
|
-
this.#leftBtn.addEventListener('click', () => {
|
|
1096
|
-
this.#scrollContent.scrollBy({ left: -this.yuvScrollButtonsAmount(), behavior: 'smooth' });
|
|
1097
|
-
});
|
|
1098
|
-
this.#rightBtn.addEventListener('click', () => {
|
|
1099
|
-
this.#scrollContent.scrollBy({ left: this.yuvScrollButtonsAmount(), behavior: 'smooth' });
|
|
1100
|
-
});
|
|
1101
|
-
this.#destroyRef.onDestroy(() => {
|
|
1102
|
-
resizeObserver.disconnect();
|
|
1103
|
-
mutationObserver.disconnect();
|
|
1104
|
-
});
|
|
1105
|
-
this.#checkOverflow();
|
|
1106
|
-
}
|
|
1107
|
-
#createButton(icon) {
|
|
1108
|
-
const btn = this.#renderer.createElement('button');
|
|
1109
|
-
btn.setAttribute('aria-label', icon === 'chevron_left'
|
|
1110
|
-
? this.translate.instant('yuv.object-form-element.scroll.button.left')
|
|
1111
|
-
: this.translate.instant('yuv.object-form-element.scroll.button.right'));
|
|
1112
|
-
this.#applyStyles(btn, {
|
|
1113
|
-
'flex-shrink': '0',
|
|
1114
|
-
display: 'inline-flex',
|
|
1115
|
-
'align-items': 'center',
|
|
1116
|
-
'justify-content': 'center',
|
|
1117
|
-
background: 'none',
|
|
1118
|
-
border: 'none',
|
|
1119
|
-
cursor: 'pointer',
|
|
1120
|
-
padding: '0',
|
|
1121
|
-
color: 'var(--ymt-text-color-subtle)',
|
|
1122
|
-
width: 'var(--ymt-sizing-m)',
|
|
1123
|
-
height: 'var(--ymt-sizing-m)',
|
|
1124
|
-
backgroundColor: 'var(--ymt-surface-hover)'
|
|
1125
|
-
});
|
|
1126
|
-
const iconEl = this.#renderer.createElement('span');
|
|
1127
|
-
iconEl.classList.add('material-symbols-sharp');
|
|
1128
|
-
this.#applyStyles(iconEl, {
|
|
1129
|
-
'font-size': '1.25rem', //calc(var(--ymt-sizing-s) * 0.8)
|
|
1130
|
-
width: 'var(--ymt-sizing-s)',
|
|
1131
|
-
height: 'var(--ymt-sizing-s)'
|
|
1132
|
-
});
|
|
1133
|
-
iconEl.textContent = icon;
|
|
1134
|
-
this.#renderer.appendChild(btn, iconEl);
|
|
1135
|
-
const highlight = () => {
|
|
1136
|
-
btn.style.color = 'var(--ymt-text-color)';
|
|
1137
|
-
};
|
|
1138
|
-
const reset = () => {
|
|
1139
|
-
btn.style.color = 'var(--ymt-text-color-subtle)';
|
|
1140
|
-
};
|
|
1141
|
-
btn.addEventListener('mouseenter', highlight);
|
|
1142
|
-
btn.addEventListener('mouseleave', reset);
|
|
1143
|
-
btn.addEventListener('focusin', highlight);
|
|
1144
|
-
btn.addEventListener('focusout', reset);
|
|
1145
|
-
// Focus-visible outline via CSS class
|
|
1146
|
-
btn.addEventListener('focus', () => {
|
|
1147
|
-
if (btn.matches(':focus-visible')) {
|
|
1148
|
-
btn.style.outline = '2px solid var(--ymt-primary-color)';
|
|
1149
|
-
btn.style.outlineOffset = '-2px';
|
|
1150
|
-
}
|
|
1151
|
-
});
|
|
1152
|
-
btn.addEventListener('blur', () => {
|
|
1153
|
-
btn.style.outline = '';
|
|
1154
|
-
btn.style.outlineOffset = '';
|
|
1155
|
-
});
|
|
1156
|
-
return btn;
|
|
1157
|
-
}
|
|
1158
|
-
#applyChipOverrides(host) {
|
|
1159
|
-
const chipSet = host.querySelector('.mdc-evolution-chip-set__chips');
|
|
1160
|
-
if (chipSet) {
|
|
1161
|
-
chipSet.style.flexWrap = 'nowrap';
|
|
1162
|
-
}
|
|
1163
|
-
// Use MutationObserver to apply overrides to chip rows as they appear
|
|
1164
|
-
const applyRowOverrides = () => {
|
|
1165
|
-
host.querySelectorAll('mat-chip-row, .mat-mdc-chip-row').forEach((row) => {
|
|
1166
|
-
const rowElement = row;
|
|
1167
|
-
rowElement.style.flexShrink = '0';
|
|
1168
|
-
rowElement.style.maxWidth = 'none';
|
|
1169
|
-
const primaryCell = rowElement.querySelector('.mdc-evolution-chip__cell--primary');
|
|
1170
|
-
if (primaryCell) {
|
|
1171
|
-
primaryCell.style.maxWidth = 'none';
|
|
1172
|
-
}
|
|
1173
|
-
rowElement
|
|
1174
|
-
.querySelectorAll('.mdc-evolution-chip__text-label, .mat-mdc-chip-action-label')
|
|
1175
|
-
.forEach((label) => {
|
|
1176
|
-
label.style.whiteSpace = 'nowrap';
|
|
1177
|
-
});
|
|
1178
|
-
});
|
|
1179
|
-
};
|
|
1180
|
-
applyRowOverrides();
|
|
1181
|
-
const observer = new MutationObserver(() => applyRowOverrides());
|
|
1182
|
-
observer.observe(host, { childList: true, subtree: true });
|
|
1183
|
-
this.#destroyRef.onDestroy(() => observer.disconnect());
|
|
1184
|
-
}
|
|
1185
|
-
#setButtonVisible(btn, visible) {
|
|
1186
|
-
btn.style.display = visible ? 'inline-flex' : 'none';
|
|
1187
|
-
}
|
|
1188
|
-
#checkOverflow() {
|
|
1189
|
-
const scrollElement = this.#scrollContent;
|
|
1190
|
-
this.#setButtonVisible(this.#leftBtn, scrollElement.scrollLeft > THRESHOLD);
|
|
1191
|
-
this.#setButtonVisible(this.#rightBtn, scrollElement.scrollLeft + scrollElement.clientWidth < scrollElement.scrollWidth - THRESHOLD);
|
|
1192
|
-
}
|
|
1193
|
-
#applyStyles(element, styles) {
|
|
1194
|
-
Object.entries(styles).forEach(([prop, value]) => {
|
|
1195
|
-
this.#renderer.setStyle(element, prop, value);
|
|
1196
|
-
});
|
|
1197
|
-
}
|
|
1198
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ScrollButtonsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1199
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: ScrollButtonsDirective, isStandalone: true, selector: "[yuvScrollButtons]", inputs: { yuvScrollButtonsAmount: { classPropertyName: "yuvScrollButtonsAmount", publicName: "yuvScrollButtonsAmount", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
1200
|
-
}
|
|
1201
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ScrollButtonsDirective, decorators: [{
|
|
1202
|
-
type: Directive,
|
|
1203
|
-
args: [{
|
|
1204
|
-
selector: '[yuvScrollButtons]'
|
|
1205
|
-
}]
|
|
1206
|
-
}], ctorParameters: () => [], propDecorators: { yuvScrollButtonsAmount: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuvScrollButtonsAmount", required: false }] }] } });
|
|
1207
|
-
|
|
1208
|
-
const directives = [
|
|
1209
|
-
BusyOverlayDirective,
|
|
1210
|
-
FocusWithinDirective,
|
|
1211
|
-
FileDropZoneDirective,
|
|
1212
|
-
ClickDoubleDirective,
|
|
1213
|
-
LightDismissDirective,
|
|
1214
|
-
ContainerSizeDirective,
|
|
1215
|
-
LongPressDirective,
|
|
1216
|
-
DragSelectDirective,
|
|
1217
|
-
DragScrollDirective,
|
|
1218
|
-
NoopValueAccessorDirective,
|
|
1219
|
-
AutofocusChildDirective,
|
|
1220
|
-
AutofocusDelayedDirective,
|
|
1221
|
-
ScrollButtonsDirective
|
|
1222
|
-
];
|
|
1223
|
-
const components = [ConfirmComponent, ScrollButtonsComponent];
|
|
1224
|
-
class YuvCommonModule {
|
|
1225
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: YuvCommonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1226
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: YuvCommonModule, imports: [BusyOverlayDirective,
|
|
1227
|
-
FocusWithinDirective,
|
|
1228
|
-
FileDropZoneDirective,
|
|
1229
|
-
ClickDoubleDirective,
|
|
1230
|
-
LightDismissDirective,
|
|
1231
|
-
ContainerSizeDirective,
|
|
1232
|
-
LongPressDirective,
|
|
1233
|
-
DragSelectDirective,
|
|
1234
|
-
DragScrollDirective,
|
|
1235
|
-
NoopValueAccessorDirective,
|
|
1236
|
-
AutofocusChildDirective,
|
|
1237
|
-
AutofocusDelayedDirective,
|
|
1238
|
-
ScrollButtonsDirective, ConfirmComponent, ScrollButtonsComponent], exports: [BusyOverlayDirective,
|
|
1239
|
-
FocusWithinDirective,
|
|
1240
|
-
FileDropZoneDirective,
|
|
1241
|
-
ClickDoubleDirective,
|
|
1242
|
-
LightDismissDirective,
|
|
1243
|
-
ContainerSizeDirective,
|
|
1244
|
-
LongPressDirective,
|
|
1245
|
-
DragSelectDirective,
|
|
1246
|
-
DragScrollDirective,
|
|
1247
|
-
NoopValueAccessorDirective,
|
|
1248
|
-
AutofocusChildDirective,
|
|
1249
|
-
AutofocusDelayedDirective,
|
|
1250
|
-
ScrollButtonsDirective, ConfirmComponent, ScrollButtonsComponent] }); }
|
|
1251
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: YuvCommonModule, imports: [components] }); }
|
|
1252
|
-
}
|
|
1253
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: YuvCommonModule, decorators: [{
|
|
1254
|
-
type: NgModule,
|
|
1255
|
-
args: [{
|
|
1256
|
-
imports: [...directives, ...components],
|
|
1257
|
-
exports: [...directives, ...components]
|
|
1258
|
-
}]
|
|
1259
|
-
}] });
|
|
1260
|
-
|
|
1261
|
-
function getFocusableChildren(element) {
|
|
1262
|
-
return [...Array.from(element.querySelectorAll('a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])'))].filter((el) => !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden'));
|
|
1263
|
-
}
|
|
1264
|
-
function getFirstFocusableChild(element) {
|
|
1265
|
-
return getFocusableChildren(element)[0];
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
/**
|
|
1269
|
-
* Service to store and retrieve layout settings. Those
|
|
1270
|
-
* settings are stored on the users device because in
|
|
1271
|
-
* general layout settings like panel widths are highly
|
|
1272
|
-
* dependent on the current device.
|
|
1273
|
-
*/
|
|
1274
|
-
class LayoutSettingsService {
|
|
1275
|
-
constructor() {
|
|
1276
|
-
this.#STORAGE_PREFIX = 'yuv.layout:';
|
|
1277
|
-
/**
|
|
1278
|
-
* @deprecated Theme storage is now handled by `ThemeService`.
|
|
1279
|
-
*/
|
|
1280
|
-
this.#MODE_STORAGE_KEY = 'app.layout.mode';
|
|
1281
|
-
this.DEFAULT_SPLIT_VIEW_GUTTER_SIZE = 16;
|
|
1282
|
-
/**
|
|
1283
|
-
* @deprecated Use `ThemeService.mode` instead.
|
|
1284
|
-
*/
|
|
1285
|
-
this.themeMode = signal('system', ...(ngDevMode ? [{ debugName: "themeMode" }] : /* istanbul ignore next */ []));
|
|
1286
|
-
/**
|
|
1287
|
-
* @deprecated Use `ThemeService.mode` instead.
|
|
1288
|
-
*/
|
|
1289
|
-
this.mode = this.themeMode.asReadonly();
|
|
1290
|
-
}
|
|
1291
|
-
#STORAGE_PREFIX;
|
|
1292
|
-
/**
|
|
1293
|
-
* @deprecated Theme storage is now handled by `ThemeService`.
|
|
1294
|
-
*/
|
|
1295
|
-
#MODE_STORAGE_KEY;
|
|
1296
|
-
/**
|
|
1297
|
-
* @deprecated Theme initialization is now handled by `ThemeService` internally.
|
|
1298
|
-
*/
|
|
1299
|
-
init() {
|
|
1300
|
-
// set configured mode
|
|
1301
|
-
const modeSettings = this.getSettings(this.#MODE_STORAGE_KEY);
|
|
1302
|
-
this.applyLayoutMode(modeSettings?.mode || undefined);
|
|
1303
|
-
}
|
|
1304
|
-
/**
|
|
1305
|
-
* @deprecated Use `ThemeService.toggleTheme()` instead.
|
|
1306
|
-
*/
|
|
1307
|
-
setMode(mode) {
|
|
1308
|
-
this.saveSettings(this.#MODE_STORAGE_KEY, { mode });
|
|
1309
|
-
}
|
|
1310
|
-
saveSettings(key, settings) {
|
|
1311
|
-
if (typeof settings === 'object') {
|
|
1312
|
-
localStorage.setItem(this.#getKey(key), JSON.stringify(settings));
|
|
1313
|
-
return true;
|
|
1314
|
-
}
|
|
1315
|
-
else
|
|
1316
|
-
return false;
|
|
1317
|
-
}
|
|
1318
|
-
getSettings(key) {
|
|
1319
|
-
try {
|
|
1320
|
-
const v = localStorage.getItem(this.#getKey(key));
|
|
1321
|
-
return v ? JSON.parse(v) : undefined;
|
|
1322
|
-
}
|
|
1323
|
-
catch (e) {
|
|
1324
|
-
console.error('Error while parsing layout settings', e);
|
|
1325
|
-
return undefined;
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
#getKey(key) {
|
|
1329
|
-
return `${this.#STORAGE_PREFIX}${key}`;
|
|
1330
|
-
}
|
|
1331
|
-
/**
|
|
1332
|
-
* Clears all layout settings.
|
|
1333
|
-
*/
|
|
1334
|
-
clearSettings() {
|
|
1335
|
-
Object.keys(localStorage).forEach((key) => {
|
|
1336
|
-
if (key.startsWith(this.#STORAGE_PREFIX)) {
|
|
1337
|
-
localStorage.removeItem(key);
|
|
1338
|
-
}
|
|
1339
|
-
});
|
|
1340
|
-
}
|
|
1341
|
-
/**
|
|
1342
|
-
* @deprecated Use `ThemeService.toggleTheme()` instead.
|
|
1343
|
-
*/
|
|
1344
|
-
applyLayoutMode(mode) {
|
|
1345
|
-
const body = document.getElementsByTagName('body')[0];
|
|
1346
|
-
body.style.colorScheme = mode === 'dark' || mode === 'light' ? mode : 'inherit';
|
|
1347
|
-
this.themeMode.set(mode || 'system');
|
|
1348
|
-
}
|
|
1349
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1350
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutSettingsService, providedIn: 'root' }); }
|
|
1351
|
-
}
|
|
1352
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutSettingsService, decorators: [{
|
|
1353
|
-
type: Injectable,
|
|
1354
|
-
args: [{
|
|
1355
|
-
providedIn: 'root'
|
|
1356
|
-
}]
|
|
1357
|
-
}] });
|
|
1358
|
-
|
|
1359
|
-
/**
|
|
1360
|
-
* Providing an error message when a translation string for an object wasn't found
|
|
1361
|
-
*/
|
|
1362
|
-
class FormTranslateService {
|
|
1363
|
-
constructor() {
|
|
1364
|
-
this.translate = inject(TranslateService);
|
|
1365
|
-
}
|
|
1366
|
-
/**
|
|
1367
|
-
* Set the error label if a translation for this string wasn't provided
|
|
1368
|
-
* @param error - error message about a missed translation key
|
|
1369
|
-
* @param params
|
|
1370
|
-
*/
|
|
1371
|
-
getErrorLabel(error, params) {
|
|
1372
|
-
switch (error) {
|
|
1373
|
-
case 'daterange':
|
|
1374
|
-
return this.translate.instant('yuv.object-form-element.error.daterange.invalid', params);
|
|
1375
|
-
case 'daterangeorder':
|
|
1376
|
-
return this.translate.instant('yuv.object-form-element.error.daterangeorder.invalid', params);
|
|
1377
|
-
case 'numberrange':
|
|
1378
|
-
return this.translate.instant('yuv.object-form-element.error.numberrange.invalid', params);
|
|
1379
|
-
case 'numberrangeorder':
|
|
1380
|
-
return this.translate.instant('yuv.object-form-element.error.numberrangeorder.invalid', params);
|
|
1381
|
-
case 'number':
|
|
1382
|
-
return this.translate.instant('yuv.object-form-element.error.number', params);
|
|
1383
|
-
case 'precision':
|
|
1384
|
-
return this.translate.instant('yuv.object-form-element.error.number.precision', params);
|
|
1385
|
-
case 'scale':
|
|
1386
|
-
return this.translate.instant('yuv.object-form-element.error.number.scale', params);
|
|
1387
|
-
case 'regex':
|
|
1388
|
-
return this.translate.instant('yuv.object-form-element.error.string.regex.nomatch', params);
|
|
1389
|
-
case 'pattern':
|
|
1390
|
-
return this.translate.instant('yuv.object-form-element.error.string.regex.nomatch', params);
|
|
1391
|
-
case 'classificationemail':
|
|
1392
|
-
return this.translate.instant('yuv.object-form-element.error.string.classification.email', params);
|
|
1393
|
-
case 'classificationphone':
|
|
1394
|
-
return this.translate.instant('yuv.object-form-element.error.string.classification.phone', params);
|
|
1395
|
-
case 'classificationurl':
|
|
1396
|
-
return this.translate.instant('yuv.object-form-element.error.string.classification.url', params);
|
|
1397
|
-
case 'onlyWhitespaces':
|
|
1398
|
-
return this.translate.instant('yuv.object-form-element.error.string.whitespaces', params);
|
|
1399
|
-
case 'datecontrol':
|
|
1400
|
-
return this.translate.instant('yuv.object-form-element.error.date.invalid', params);
|
|
1401
|
-
case 'required':
|
|
1402
|
-
return this.translate.instant('yuv.object-form-element.error.required', params);
|
|
1403
|
-
case 'maxlength':
|
|
1404
|
-
return this.translate.instant('yuv.object-form-element.error.maxlength', params);
|
|
1405
|
-
case 'minlength':
|
|
1406
|
-
return this.translate.instant('yuv.object-form-element.error.minlength', params);
|
|
1407
|
-
case 'minmax':
|
|
1408
|
-
return this.translate.instant('yuv.object-form-element.error.minmax', params);
|
|
1409
|
-
case 'minvalue':
|
|
1410
|
-
return this.translate.instant('yuv.object-form-element.error.minvalue', params);
|
|
1411
|
-
case 'maxvalue':
|
|
1412
|
-
return this.translate.instant('yuv.object-form-element.error.maxvalue', params);
|
|
1413
|
-
default:
|
|
1414
|
-
return this.translate.instant(error, params);
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FormTranslateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1418
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FormTranslateService, providedIn: 'root' }); }
|
|
1419
|
-
}
|
|
1420
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FormTranslateService, decorators: [{
|
|
1421
|
-
type: Injectable,
|
|
1422
|
-
args: [{
|
|
1423
|
-
providedIn: 'root'
|
|
1424
|
-
}]
|
|
1425
|
-
}] });
|
|
1426
|
-
|
|
1427
|
-
var ThemeStorageKeys;
|
|
1428
|
-
(function (ThemeStorageKeys) {
|
|
1429
|
-
ThemeStorageKeys["THEME_MODE"] = "yuv.theme:app.theme.mode";
|
|
1430
|
-
ThemeStorageKeys["CUSTOM_THEME"] = "yuv.theme:app.theme.custom";
|
|
1431
|
-
})(ThemeStorageKeys || (ThemeStorageKeys = {}));
|
|
1432
|
-
const DEFAULT_THEME_KEY = 'yuv-default';
|
|
1433
|
-
const DEFAULT_THEME = {
|
|
1434
|
-
key: DEFAULT_THEME_KEY,
|
|
1435
|
-
label: 'yuv.theme.default.label',
|
|
1436
|
-
description: 'yuv.theme.default.description',
|
|
1437
|
-
hasLightTheme: true,
|
|
1438
|
-
hasDarkTheme: true
|
|
1439
|
-
};
|
|
1440
|
-
const HIGH_CONTRAST_THEME_KEY = 'yuv-high-contrast';
|
|
1441
|
-
const HIGH_CONTRAST_THEME = {
|
|
1442
|
-
key: HIGH_CONTRAST_THEME_KEY,
|
|
1443
|
-
label: 'yuv.theme.highContrast.label',
|
|
1444
|
-
description: 'yuv.theme.highContrast.description',
|
|
1445
|
-
hasLightTheme: true,
|
|
1446
|
-
hasDarkTheme: true
|
|
1447
|
-
};
|
|
1448
|
-
|
|
1449
|
-
const YUV_CUSTOM_THEME = new InjectionToken('CUSTOM_THEME', { factory: () => [HIGH_CONTRAST_THEME] });
|
|
1450
|
-
const provideYuvCustomTheme = (customTheme) => makeEnvironmentProviders([{ provide: YUV_CUSTOM_THEME, useValue: [HIGH_CONTRAST_THEME, ...customTheme] }]);
|
|
1451
|
-
|
|
1452
|
-
class ThemeService {
|
|
1453
|
-
#rendererFactory;
|
|
1454
|
-
#customThemesToken;
|
|
1455
|
-
#document;
|
|
1456
|
-
#storage;
|
|
1457
|
-
#MODE_STORAGE_KEY;
|
|
1458
|
-
#CUSTOM_THEME_STORAGE_KEY;
|
|
1459
|
-
#renderer;
|
|
1460
|
-
#mode;
|
|
1461
|
-
#currentTheme;
|
|
1462
|
-
#disableMode;
|
|
1463
|
-
// Effect to apply classes and save to localStorage
|
|
1464
|
-
#setThemeModeEffect;
|
|
1465
|
-
constructor() {
|
|
1466
|
-
this.#rendererFactory = inject(RendererFactory2);
|
|
1467
|
-
this.#customThemesToken = inject(YUV_CUSTOM_THEME, { optional: true });
|
|
1468
|
-
this.#document = inject(DOCUMENT);
|
|
1469
|
-
this.#storage = inject(AppCacheService);
|
|
1470
|
-
this.#MODE_STORAGE_KEY = ThemeStorageKeys.THEME_MODE;
|
|
1471
|
-
this.#CUSTOM_THEME_STORAGE_KEY = ThemeStorageKeys.CUSTOM_THEME;
|
|
1472
|
-
this.#renderer = this.#rendererFactory.createRenderer(null, null);
|
|
1473
|
-
this.#mode = signal('light', ...(ngDevMode ? [{ debugName: "#mode" }] : /* istanbul ignore next */ []));
|
|
1474
|
-
this.mode = this.#mode.asReadonly();
|
|
1475
|
-
this.customTheme = signal(DEFAULT_THEME, ...(ngDevMode ? [{ debugName: "customTheme" }] : /* istanbul ignore next */ []));
|
|
1476
|
-
this.customThemes = computed(() => {
|
|
1477
|
-
const customThemesToken = this.#customThemesToken || [];
|
|
1478
|
-
return customThemesToken.map((theme) => {
|
|
1479
|
-
const { key, label, description, hasLightTheme, hasDarkTheme } = theme;
|
|
1480
|
-
return {
|
|
1481
|
-
key,
|
|
1482
|
-
label,
|
|
1483
|
-
description,
|
|
1484
|
-
hasLightTheme: hasLightTheme ?? true,
|
|
1485
|
-
hasDarkTheme: hasDarkTheme ?? false
|
|
1486
|
-
};
|
|
1487
|
-
});
|
|
1488
|
-
}, ...(ngDevMode ? [{ debugName: "customThemes" }] : /* istanbul ignore next */ []));
|
|
1489
|
-
this.#currentTheme = signal(DEFAULT_THEME_KEY, ...(ngDevMode ? [{ debugName: "#currentTheme" }] : /* istanbul ignore next */ []));
|
|
1490
|
-
this.currentTheme = this.#currentTheme.asReadonly();
|
|
1491
|
-
this.#disableMode = signal(false, ...(ngDevMode ? [{ debugName: "#disableMode" }] : /* istanbul ignore next */ []));
|
|
1492
|
-
this.disableMode = this.#disableMode.asReadonly();
|
|
1493
|
-
// Effect to apply classes and save to localStorage
|
|
1494
|
-
this.#setThemeModeEffect = effect(() => {
|
|
1495
|
-
const currentTheme = this.#mode();
|
|
1496
|
-
const body = this.#document.getElementsByTagName('body')[0];
|
|
1497
|
-
this.setMode(currentTheme);
|
|
1498
|
-
// Theme class
|
|
1499
|
-
if (currentTheme === 'dark') {
|
|
1500
|
-
this.#renderer.setAttribute(body, 'style', 'color-scheme: dark');
|
|
1501
|
-
}
|
|
1502
|
-
else if (currentTheme === 'light') {
|
|
1503
|
-
this.#renderer.setAttribute(body, 'style', 'color-scheme: light');
|
|
1504
|
-
}
|
|
1505
|
-
else {
|
|
1506
|
-
this.#renderer.removeAttribute(body, 'style');
|
|
1507
|
-
}
|
|
1508
|
-
}, ...(ngDevMode ? [{ debugName: "#setThemeModeEffect" }] : /* istanbul ignore next */ []));
|
|
1509
|
-
this.#initializeModes();
|
|
1510
|
-
}
|
|
1511
|
-
#saveSettings(key, settings) {
|
|
1512
|
-
if (typeof settings === 'object') {
|
|
1513
|
-
this.#storage.setItem(key, JSON.stringify(settings)).subscribe();
|
|
1514
|
-
return true;
|
|
1515
|
-
}
|
|
1516
|
-
else
|
|
1517
|
-
return false;
|
|
1518
|
-
}
|
|
1519
|
-
#deleteSettings(key) {
|
|
1520
|
-
this.#storage.removeItem(key).subscribe();
|
|
1521
|
-
return true;
|
|
1522
|
-
}
|
|
1523
|
-
#checkPrefersContrast() {
|
|
1524
|
-
const prefersHighContrast = window.matchMedia('(prefers-contrast: more)').matches;
|
|
1525
|
-
}
|
|
1526
|
-
#initializeModes() {
|
|
1527
|
-
// Theme initialization
|
|
1528
|
-
forkJoin([this.#storage.getItem(this.#MODE_STORAGE_KEY), this.#storage.getItem(this.#CUSTOM_THEME_STORAGE_KEY)])
|
|
1529
|
-
.pipe(map$1(([savedTheme, savedCustomTheme]) => {
|
|
1530
|
-
if (savedTheme) {
|
|
1531
|
-
try {
|
|
1532
|
-
this.#mode.set(JSON.parse(savedTheme).mode);
|
|
1533
|
-
}
|
|
1534
|
-
catch (error) {
|
|
1535
|
-
this.#mode.set(this.#mode());
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1538
|
-
else {
|
|
1539
|
-
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
1540
|
-
this.#mode.set(prefersDark ? 'dark' : 'light');
|
|
1541
|
-
}
|
|
1542
|
-
// Contrast initialization
|
|
1543
|
-
this.#checkPrefersContrast();
|
|
1544
|
-
// Custom Theme initialization
|
|
1545
|
-
if (savedCustomTheme) {
|
|
1546
|
-
try {
|
|
1547
|
-
const customThemeKey = JSON.parse(savedCustomTheme).customTheme;
|
|
1548
|
-
this.setCustomTheme(customThemeKey);
|
|
1549
|
-
}
|
|
1550
|
-
catch (error) {
|
|
1551
|
-
// ignore
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
}))
|
|
1555
|
-
.subscribe();
|
|
1556
|
-
}
|
|
1557
|
-
setMode(mode) {
|
|
1558
|
-
this.#saveSettings(this.#MODE_STORAGE_KEY, { mode });
|
|
1559
|
-
}
|
|
1560
|
-
setCustomTheme(key) {
|
|
1561
|
-
// Reset contrast to system on custom theme change
|
|
1562
|
-
const previousTheme = this.customTheme();
|
|
1563
|
-
const body = this.#document.getElementsByTagName('body')[0];
|
|
1564
|
-
previousTheme && previousTheme.key && this.#renderer.removeClass(body, previousTheme.key);
|
|
1565
|
-
const selectedTheme = this.customThemes().find((theme) => theme.key === key);
|
|
1566
|
-
if (selectedTheme) {
|
|
1567
|
-
this.customTheme.set(selectedTheme);
|
|
1568
|
-
this.#currentTheme.set(selectedTheme.key);
|
|
1569
|
-
selectedTheme.key && this.#renderer.addClass(body, selectedTheme.key);
|
|
1570
|
-
// Check if custom theme has light or dark mode
|
|
1571
|
-
if ((selectedTheme.hasDarkTheme && selectedTheme.hasLightTheme) || (!selectedTheme.hasDarkTheme && !selectedTheme.hasLightTheme)) {
|
|
1572
|
-
// If both, do nothing further with this (enable group)
|
|
1573
|
-
this.#disableMode.set(false);
|
|
1574
|
-
}
|
|
1575
|
-
else {
|
|
1576
|
-
// Else disable mode button group and set the corresponding mode active
|
|
1577
|
-
if (selectedTheme.hasDarkTheme) {
|
|
1578
|
-
this.#mode.set('dark');
|
|
1579
|
-
}
|
|
1580
|
-
else if (selectedTheme.hasLightTheme) {
|
|
1581
|
-
this.#mode.set('light');
|
|
1582
|
-
}
|
|
1583
|
-
this.#disableMode.set(true);
|
|
1584
|
-
}
|
|
1585
|
-
this.#saveSettings(this.#CUSTOM_THEME_STORAGE_KEY, { customTheme: key });
|
|
1586
|
-
}
|
|
1587
|
-
else {
|
|
1588
|
-
if (key === DEFAULT_THEME_KEY) {
|
|
1589
|
-
this.#disableMode.set(false);
|
|
1590
|
-
this.#renderer.removeClass(body, HIGH_CONTRAST_THEME_KEY);
|
|
1591
|
-
this.#deleteSettings(this.#CUSTOM_THEME_STORAGE_KEY);
|
|
1592
|
-
}
|
|
1593
|
-
// Default theme or no theme found
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
toggleTheme(theme) {
|
|
1597
|
-
this.#mode.set(theme);
|
|
1598
|
-
}
|
|
1599
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1600
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ThemeService, providedIn: 'root' }); }
|
|
1601
|
-
}
|
|
1602
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ThemeService, decorators: [{
|
|
1603
|
-
type: Injectable,
|
|
1604
|
-
args: [{
|
|
1605
|
-
providedIn: 'root'
|
|
1606
|
-
}]
|
|
1607
|
-
}], ctorParameters: () => [] });
|
|
1608
|
-
|
|
1609
|
-
marker('yuv.theme.default.label');
|
|
1610
|
-
marker('yuv.theme.default.description');
|
|
1611
|
-
marker('yuv.theme.highContrast.label');
|
|
1612
|
-
marker('yuv.theme.highContrast.description');
|
|
1613
|
-
|
|
1614
|
-
// eslint-disable-next-line @angular-eslint/component-class-suffix
|
|
1615
|
-
class AbstractMatFormField {
|
|
1616
|
-
constructor() {
|
|
1617
|
-
this.stateChanges = new Subject();
|
|
1618
|
-
this.elRef = inject(ElementRef);
|
|
1619
|
-
this.#value = signal(null, ...(ngDevMode ? [{ debugName: "#value" }] : /* istanbul ignore next */ []));
|
|
1620
|
-
this.#id = signal('', ...(ngDevMode ? [{ debugName: "#id" }] : /* istanbul ignore next */ []));
|
|
1621
|
-
this.#placeholder = signal('', ...(ngDevMode ? [{ debugName: "#placeholder" }] : /* istanbul ignore next */ []));
|
|
1622
|
-
this.ngControl = null;
|
|
1623
|
-
this.#focused = signal(false, ...(ngDevMode ? [{ debugName: "#focused" }] : /* istanbul ignore next */ []));
|
|
1624
|
-
this.#empty = signal(false, ...(ngDevMode ? [{ debugName: "#empty" }] : /* istanbul ignore next */ []));
|
|
1625
|
-
this.#required = signal(false, ...(ngDevMode ? [{ debugName: "#required" }] : /* istanbul ignore next */ []));
|
|
1626
|
-
this.#disabled = signal(false, ...(ngDevMode ? [{ debugName: "#disabled" }] : /* istanbul ignore next */ []));
|
|
1627
|
-
this.focusHandled = signal(false, ...(ngDevMode ? [{ debugName: "focusHandled" }] : /* istanbul ignore next */ []));
|
|
1628
|
-
this.#errorState = signal(false, ...(ngDevMode ? [{ debugName: "#errorState" }] : /* istanbul ignore next */ []));
|
|
1629
|
-
}
|
|
1630
|
-
onFocusIn() {
|
|
1631
|
-
this.focused = true;
|
|
1632
|
-
}
|
|
1633
|
-
onFocusout() {
|
|
1634
|
-
this.focused = false;
|
|
1635
|
-
}
|
|
1636
|
-
#value;
|
|
1637
|
-
set value(v) {
|
|
1638
|
-
this.#value.set(v);
|
|
1639
|
-
this.empty = !v;
|
|
1640
|
-
this.stateChanges.next();
|
|
1641
|
-
}
|
|
1642
|
-
get value() {
|
|
1643
|
-
return this.#value();
|
|
1644
|
-
}
|
|
1645
|
-
#id;
|
|
1646
|
-
set id(v) {
|
|
1647
|
-
this.#id.set(v);
|
|
1648
|
-
this.stateChanges.next();
|
|
1649
|
-
}
|
|
1650
|
-
get id() {
|
|
1651
|
-
return this.#id();
|
|
1652
|
-
}
|
|
1653
|
-
#placeholder;
|
|
1654
|
-
set placeholder(v) {
|
|
1655
|
-
this.#placeholder.set(v);
|
|
1656
|
-
this.stateChanges.next();
|
|
1657
|
-
}
|
|
1658
|
-
get placeholder() {
|
|
1659
|
-
return this.#placeholder();
|
|
1660
|
-
}
|
|
1661
|
-
#focused;
|
|
1662
|
-
set focused(f) {
|
|
1663
|
-
this.#focused.set(f);
|
|
1664
|
-
this.stateChanges.next();
|
|
1665
|
-
}
|
|
1666
|
-
get focused() {
|
|
1667
|
-
return this.#focused();
|
|
1668
|
-
}
|
|
1669
|
-
// #shouldLabelFloat = signal<boolean>(false);
|
|
1670
|
-
// set shouldLabelFloat(f: boolean) {
|
|
1671
|
-
// this.#shouldLabelFloat.set(f);
|
|
1672
|
-
// this.stateChanges.next();
|
|
1673
|
-
// }
|
|
1674
|
-
get shouldLabelFloat() {
|
|
1675
|
-
return this.focused || !this.empty || !!this.ngControl?.invalid;
|
|
1676
|
-
}
|
|
1677
|
-
#empty;
|
|
1678
|
-
set empty(f) {
|
|
1679
|
-
this.#empty.set(f);
|
|
1680
|
-
this.stateChanges.next();
|
|
1681
|
-
}
|
|
1682
|
-
get empty() {
|
|
1683
|
-
return this.#empty();
|
|
1684
|
-
}
|
|
1685
|
-
#required;
|
|
1686
|
-
set required(f) {
|
|
1687
|
-
this.#required.set(coerceBooleanProperty(f));
|
|
1688
|
-
this.stateChanges.next();
|
|
1689
|
-
}
|
|
1690
|
-
get required() {
|
|
1691
|
-
return this.#required();
|
|
1692
|
-
}
|
|
1693
|
-
#disabled;
|
|
1694
|
-
set disabled(f) {
|
|
1695
|
-
this.#disabled.set(coerceBooleanProperty(f));
|
|
1696
|
-
this.stateChanges.next();
|
|
1697
|
-
}
|
|
1698
|
-
get disabled() {
|
|
1699
|
-
return this.#disabled();
|
|
1700
|
-
}
|
|
1701
|
-
#errorState;
|
|
1702
|
-
set errorState(f) {
|
|
1703
|
-
this.#errorState.set(coerceBooleanProperty(f));
|
|
1704
|
-
this.stateChanges.next();
|
|
1705
|
-
}
|
|
1706
|
-
get errorState() {
|
|
1707
|
-
return this.#errorState();
|
|
1708
|
-
}
|
|
1709
|
-
setDescribedByIds(ids) {
|
|
1710
|
-
// this.describedBy = ids.join(' ');
|
|
1711
|
-
}
|
|
1712
|
-
onContainerClick(event) {
|
|
1713
|
-
if (this.focusHandled())
|
|
1714
|
-
return;
|
|
1715
|
-
const fe = getFocusableChildren(this.elRef.nativeElement);
|
|
1716
|
-
if (fe[0] && !fe.includes(event.target)) {
|
|
1717
|
-
fe[0].focus();
|
|
1718
|
-
}
|
|
1719
|
-
}
|
|
1720
|
-
onNgOnDestroy() {
|
|
1721
|
-
this.stateChanges.complete();
|
|
1722
|
-
}
|
|
1723
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AbstractMatFormField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1724
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: AbstractMatFormField, isStandalone: true, selector: "ng-component", inputs: { placeholder: "placeholder", required: "required", disabled: "disabled" }, host: { listeners: { "focusin": "onFocusIn()", "focusout": "onFocusout()" } }, ngImport: i0, template: '', isInline: true }); }
|
|
1725
|
-
}
|
|
1726
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AbstractMatFormField, decorators: [{
|
|
1727
|
-
type: Component,
|
|
1728
|
-
args: [{
|
|
1729
|
-
template: '',
|
|
1730
|
-
host: {
|
|
1731
|
-
'(focusin)': 'onFocusIn()',
|
|
1732
|
-
'(focusout)': 'onFocusout()'
|
|
1733
|
-
}
|
|
1734
|
-
}]
|
|
1735
|
-
}], propDecorators: { placeholder: [{
|
|
1736
|
-
type: Input
|
|
1737
|
-
}], required: [{
|
|
1738
|
-
type: Input
|
|
1739
|
-
}], disabled: [{
|
|
1740
|
-
type: Input
|
|
1741
|
-
}] } });
|
|
1742
|
-
|
|
1743
|
-
var DialogSize;
|
|
1744
|
-
(function (DialogSize) {
|
|
1745
|
-
DialogSize["SMALL"] = "small";
|
|
1746
|
-
DialogSize["MEDIUM"] = "medium";
|
|
1747
|
-
DialogSize["LARGE"] = "large";
|
|
1748
|
-
DialogSize["EXTRA_LARGE"] = "extra-large";
|
|
1749
|
-
DialogSize["FULL_SCREEN"] = "full-screen";
|
|
1750
|
-
})(DialogSize || (DialogSize = {}));
|
|
1751
|
-
|
|
1752
|
-
class RetentionBadgeComponent {
|
|
1753
|
-
constructor() {
|
|
1754
|
-
this.#retention = inject(RetentionService);
|
|
1755
|
-
this.dmsObject = input.required(...(ngDevMode ? [{ debugName: "dmsObject" }] : /* istanbul ignore next */ []));
|
|
1756
|
-
this.retentionData = computed(() => {
|
|
1757
|
-
return this.#retention.getRetentionState(this.dmsObject());
|
|
1758
|
-
}, ...(ngDevMode ? [{ debugName: "retentionData" }] : /* istanbul ignore next */ []));
|
|
1759
|
-
}
|
|
1760
|
-
#retention;
|
|
1761
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RetentionBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1762
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: RetentionBadgeComponent, isStandalone: true, selector: "yuv-retention-badge", inputs: { dmsObject: { classPropertyName: "dmsObject", publicName: "dmsObject", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let rd = retentionData();\n@if (rd.underRetention) {\n <div class=\"badge\">\n <span class=\"badge__icon\">\n <mat-icon class=\"ymt-icon--size-s\">lock_clock</mat-icon>\n </span>\n <span class=\"badge__label\">\n <span class=\"badge__label-truncated\">\n {{\n 'yuv.retention-badge.retain'\n | translate\n : {\n from: rd.start | localeDate: 'shortDate',\n until: rd.end | localeDate: 'shortDate'\n }\n }}\n </span>\n </span>\n </div>\n}\n", styles: [":host{display:contents}:host .badge{font:var(--ymt-font-body-subtle);color:var(--badge-retention-color, var(--ymt-on-surface));display:inline-flex;overflow:hidden;padding:var(--ymt-spacing-2xs) var(--ymt-spacing-s) var(--ymt-spacing-2xs) var(--ymt-spacing-xs);background-color:var(--badge-retention-background, var(--ymt-primary-container));border-radius:var(--ymt-corner-full);gap:var(--ymt-spacing-s)}:host .badge__icon{flex-shrink:0;color:var(--badge-retention-icon-color, var(--ymt-on-primary-container));display:flex;align-items:center;justify-content:center}:host .badge__label{color:var(--badge-retention-color, var(--ymt-on-surface));align-self:stretch;display:flex;align-items:center;justify-content:center;border-top-right-radius:var(--ymt-corner-full);border-bottom-right-radius:var(--ymt-corner-full);overflow:hidden}:host .badge__label-truncated{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;display:block}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: LocaleDatePipe, name: "localeDate" }] }); }
|
|
1763
|
-
}
|
|
1764
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RetentionBadgeComponent, decorators: [{
|
|
1765
|
-
type: Component,
|
|
1766
|
-
args: [{ selector: 'yuv-retention-badge', standalone: true, imports: [TranslatePipe, LocaleDatePipe, MatIconModule], template: "@let rd = retentionData();\n@if (rd.underRetention) {\n <div class=\"badge\">\n <span class=\"badge__icon\">\n <mat-icon class=\"ymt-icon--size-s\">lock_clock</mat-icon>\n </span>\n <span class=\"badge__label\">\n <span class=\"badge__label-truncated\">\n {{\n 'yuv.retention-badge.retain'\n | translate\n : {\n from: rd.start | localeDate: 'shortDate',\n until: rd.end | localeDate: 'shortDate'\n }\n }}\n </span>\n </span>\n </div>\n}\n", styles: [":host{display:contents}:host .badge{font:var(--ymt-font-body-subtle);color:var(--badge-retention-color, var(--ymt-on-surface));display:inline-flex;overflow:hidden;padding:var(--ymt-spacing-2xs) var(--ymt-spacing-s) var(--ymt-spacing-2xs) var(--ymt-spacing-xs);background-color:var(--badge-retention-background, var(--ymt-primary-container));border-radius:var(--ymt-corner-full);gap:var(--ymt-spacing-s)}:host .badge__icon{flex-shrink:0;color:var(--badge-retention-icon-color, var(--ymt-on-primary-container));display:flex;align-items:center;justify-content:center}:host .badge__label{color:var(--badge-retention-color, var(--ymt-on-surface));align-self:stretch;display:flex;align-items:center;justify-content:center;border-top-right-radius:var(--ymt-corner-full);border-bottom-right-radius:var(--ymt-corner-full);overflow:hidden}:host .badge__label-truncated{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;display:block}\n"] }]
|
|
1767
|
-
}], propDecorators: { dmsObject: [{ type: i0.Input, args: [{ isSignal: true, alias: "dmsObject", required: true }] }] } });
|
|
1768
|
-
|
|
1769
|
-
class ConfirmService {
|
|
1770
|
-
#dialog = inject(MatDialog);
|
|
1771
|
-
confirm(data) {
|
|
1772
|
-
return this.#dialog
|
|
1773
|
-
.open(ConfirmComponent, { data })
|
|
1774
|
-
.afterClosed()
|
|
1775
|
-
.pipe(map((result) => !!result));
|
|
1776
|
-
}
|
|
1777
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ConfirmService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1778
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ConfirmService, providedIn: 'root' }); }
|
|
1779
|
-
}
|
|
1780
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ConfirmService, decorators: [{
|
|
1781
|
-
type: Injectable,
|
|
1782
|
-
args: [{
|
|
1783
|
-
providedIn: 'root'
|
|
1784
|
-
}]
|
|
1785
|
-
}] });
|
|
1786
|
-
|
|
1787
|
-
class HaloFocusComponent {
|
|
1788
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: HaloFocusComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1789
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: HaloFocusComponent, isStandalone: true, selector: "yuv-halo-focus", ngImport: i0, template: "<p>halo-focus works!</p>\n", styles: [""] }); }
|
|
1790
|
-
}
|
|
1791
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: HaloFocusComponent, decorators: [{
|
|
1792
|
-
type: Component,
|
|
1793
|
-
args: [{ selector: 'yuv-halo-focus', imports: [], template: "<p>halo-focus works!</p>\n" }]
|
|
1794
|
-
}] });
|
|
1795
7
|
|
|
1796
8
|
/**
|
|
1797
9
|
* Generated bundle index. Do not edit.
|
|
1798
10
|
*/
|
|
1799
|
-
|
|
1800
|
-
export { AbstractMatFormField, AutofocusChildDirective, AutofocusDelayedDirective, BusyOverlayComponent, BusyOverlayDirective, ClickDoubleDirective, ConfirmComponent, ConfirmService, ContainerSizeDirective, DEFAULT_THEME, DEFAULT_THEME_KEY, DialogComponent, DialogSize, DragScrollDirective, DragSelectDirective, DragSelectItemDirective, FileDropZoneDirective, FocusWithinDirective, FormTranslateService, HIGH_CONTRAST_THEME, HIGH_CONTRAST_THEME_KEY, HaloFocusComponent, LayoutSettingsService, LightDismissDirective, LongPressDirective, NoopValueAccessorDirective, RetentionBadgeComponent, ScrollButtonsComponent, ScrollButtonsDirective, ThemeService, ThemeStorageKeys, YUV_CUSTOM_THEME, YuvCommonModule, getFirstFocusableChild, getFocusableChildren, injectNgControl, provideYuvCustomTheme };
|
|
1801
11
|
//# sourceMappingURL=yuuvis-client-framework-common.mjs.map
|