@yuuvis/client-framework 3.14.1 → 3.16.0
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/fesm2022/yuuvis-client-framework-actions.mjs +19 -19
- package/fesm2022/yuuvis-client-framework-app-bar.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-badges.mjs +16 -13
- package/fesm2022/yuuvis-client-framework-badges.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-breadcrumb.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-clipboard.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-datepicker.mjs +31 -31
- package/fesm2022/yuuvis-client-framework-forms.mjs +70 -68
- package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-icons.mjs +9 -9
- package/fesm2022/yuuvis-client-framework-metadata-form-defaults.mjs +7 -7
- package/fesm2022/yuuvis-client-framework-metadata-form.mjs +18 -18
- package/fesm2022/yuuvis-client-framework-object-details.mjs +28 -28
- package/fesm2022/yuuvis-client-framework-object-flavor.mjs +18 -18
- package/fesm2022/yuuvis-client-framework-object-form.mjs +35 -35
- package/fesm2022/yuuvis-client-framework-object-form.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-preview.mjs +9 -9
- package/fesm2022/yuuvis-client-framework-object-relationship.mjs +38 -38
- package/fesm2022/yuuvis-client-framework-object-relationship.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-summary.mjs +13 -13
- package/fesm2022/yuuvis-client-framework-object-versions.mjs +8 -8
- package/fesm2022/yuuvis-client-framework-object-versions.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-pagination.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-query-list.mjs +7 -7
- package/fesm2022/yuuvis-client-framework-renderer.mjs +99 -53
- package/fesm2022/yuuvis-client-framework-renderer.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-sequence-list.mjs +16 -8
- package/fesm2022/yuuvis-client-framework-sequence-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-simple-search.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-smart-search.mjs +13 -13
- package/fesm2022/yuuvis-client-framework-sort.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-tile-list.mjs +77 -35
- package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-token-search.mjs +7 -7
- package/fesm2022/yuuvis-client-framework-tree.mjs +9 -9
- package/fesm2022/yuuvis-client-framework-upload-progress.mjs +10 -10
- package/fesm2022/yuuvis-client-framework.mjs +108 -36
- package/fesm2022/yuuvis-client-framework.mjs.map +1 -1
- package/lib/assets/i18n/de.json +4 -3
- package/lib/assets/i18n/en.json +4 -3
- package/package.json +10 -10
- package/types/yuuvis-client-framework-forms.d.ts +3 -1
- package/types/yuuvis-client-framework-renderer.d.ts +18 -2
- package/types/yuuvis-client-framework-sequence-list.d.ts +9 -1
- package/types/yuuvis-client-framework-tile-list.d.ts +1 -0
- package/types/yuuvis-client-framework.d.ts +12 -2
|
@@ -468,10 +468,10 @@ class TokenSearchComponent {
|
|
|
468
468
|
return base(['contains', 'like', 'eq']);
|
|
469
469
|
}
|
|
470
470
|
}
|
|
471
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
472
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
471
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TokenSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
472
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TokenSearchComponent, isStandalone: true, selector: "yuv-token-search", inputs: { types: { classPropertyName: "types", publicName: "types", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { queryChange: "queryChange" }, viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"search-bar\" (click)=\"onBarClick($event)\">\n <!-- Committed tokens -->\n @for (token of tokens(); track token.uid; let i = $index) {\n <button\n class=\"token\"\n [class.token--type]=\"token.kind === 'type'\"\n [class.token--field]=\"token.kind === 'field'\"\n [class.token--operator]=\"token.kind === 'operator'\"\n [class.token--value]=\"token.kind === 'value'\"\n [class.token--combinator]=\"token.kind === 'combinator'\"\n (click)=\"onTokenClick(i)\"\n [attr.aria-label]=\"token.label\"\n >\n @if (token.kind === 'type') {\n <mat-icon class=\"token__icon\">category</mat-icon>\n }\n @if (token.kind === 'field') {\n <mat-icon class=\"token__icon\">tune</mat-icon>\n }\n <span class=\"token__label\">{{ token.label }}</span>\n @if (token.kind !== 'combinator') {\n <span\n class=\"token__remove\"\n (click)=\"$event.stopPropagation(); removeTokenGroup(i)\"\n matTooltip=\"Remove\"\n >\n <mat-icon>close</mat-icon>\n </span>\n }\n </button>\n }\n\n <!-- Pending type pill -->\n @if (pendingTypeId()) {\n <span class=\"token token--type token--pending\">\n <mat-icon class=\"token__icon\">category</mat-icon>\n <span class=\"token__label\">{{ pendingTypeLabel() }}</span>\n </span>\n }\n\n <!-- Pending field pill -->\n @if (pendingField(); as field) {\n <span class=\"token token--field token--pending\">\n <mat-icon class=\"token__icon\">tune</mat-icon>\n <span class=\"token__label\">{{ field.label }}</span>\n </span>\n }\n\n <!-- Pending operator pill -->\n @if (pendingOperator(); as op) {\n <span class=\"token token--operator token--pending\">\n <span class=\"token__label\">{{ op.label }}</span>\n </span>\n }\n\n <!-- Single input -->\n <input\n #searchInput\n [formControl]=\"searchCtrl\"\n [matAutocomplete]=\"auto\"\n [placeholder]=\"placeholderText()\"\n (keydown)=\"onKeydown($event)\"\n />\n</div>\n\n<!-- Autocomplete panel -->\n<mat-autocomplete #auto [displayWith]=\"displayFn\" (optionSelected)=\"onSuggestionSelected($event)\">\n @for (s of suggestions(); track s.id) {\n <mat-option [value]=\"s\">\n <div class=\"suggestion\">\n <mat-icon class=\"suggestion__icon\">\n @switch (s.kind) {\n @case ('type') { category }\n @case ('field') { tune }\n @case ('date-preset') { calendar_today }\n @default { manage_search }\n }\n </mat-icon>\n <span class=\"suggestion__label\">{{ s.label }}</span>\n @if (s.fieldType) {\n <span class=\"suggestion__type\">{{ s.fieldType }}</span>\n }\n </div>\n </mat-option>\n }\n</mat-autocomplete>\n", styles: [":host{display:block}.search-bar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ymt-spacing-3xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-s);border:1px solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-l);background:var(--ymt-surface);min-height:44px;cursor:text;transition:border-color .15s}.search-bar:focus-within{border-color:var(--ymt-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--ymt-primary) 15%,transparent)}.search-bar input{flex:1 1 120px;min-width:120px;border:none;outline:none;background:transparent;font:inherit;font-size:.9em;padding:var(--ymt-spacing-2xs) 0}.search-bar input::placeholder{color:var(--ymt-text-color-subtle);opacity:.7}.token{display:inline-flex;align-items:center;gap:var(--ymt-spacing-4xs);height:28px;padding:0 var(--ymt-spacing-xs);border-radius:var(--ymt-corner-s);border:1px solid var(--ymt-outline-variant);background:var(--ymt-surface-container);font:inherit;font-size:.82em;cursor:pointer;white-space:nowrap;outline:none;transition:border-color .15s,background .15s}.token:hover{border-color:var(--ymt-outline)}.token:focus-visible{border-color:var(--ymt-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--ymt-primary) 25%,transparent)}.token--type{background:var(--ymt-primary-container);color:var(--ymt-on-primary-container);font-weight:500}.token--field{background:color-mix(in srgb,var(--ymt-primary) 10%,transparent);color:var(--ymt-primary);font-weight:500}.token--operator{background:var(--ymt-surface-container-high);color:var(--ymt-text-color-subtle);font-style:italic}.token--value{max-width:160px;overflow:hidden;text-overflow:ellipsis}.token--combinator{background:var(--ymt-surface-container-high);font-weight:600;font-size:.75em;letter-spacing:.04em;color:var(--ymt-text-color-subtle);border-color:transparent}.token--pending{opacity:.7;border-style:dashed;cursor:default}.token__icon{font-size:var(--ymt-sizing-xs);width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs);opacity:.8}.token__label{line-height:1}.token__remove{display:inline-flex;align-items:center;margin-left:var(--ymt-spacing-4xs);opacity:0;transition:opacity .1s,color .1s}.token__remove mat-icon{font-size:14px;width:14px;height:14px}.token:hover .token__remove{opacity:.6}.token__remove:hover{opacity:1;color:var(--ymt-error)}.suggestion{display:flex;align-items:center;gap:var(--ymt-spacing-xs)}.suggestion__icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);opacity:.6}.suggestion__label{flex:1}.suggestion__type{font-size:.75em;opacity:.5;font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
473
473
|
}
|
|
474
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
474
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TokenSearchComponent, decorators: [{
|
|
475
475
|
type: Component,
|
|
476
476
|
args: [{ selector: 'yuv-token-search', imports: [
|
|
477
477
|
ReactiveFormsModule,
|
|
@@ -483,11 +483,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
483
483
|
|
|
484
484
|
const cmp = [TokenSearchComponent];
|
|
485
485
|
class YuvTokenSearchModule {
|
|
486
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
487
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.
|
|
488
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.
|
|
486
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: YuvTokenSearchModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
487
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.20", ngImport: i0, type: YuvTokenSearchModule, imports: [TokenSearchComponent], exports: [TokenSearchComponent] }); }
|
|
488
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: YuvTokenSearchModule, imports: [cmp] }); }
|
|
489
489
|
}
|
|
490
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
490
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: YuvTokenSearchModule, decorators: [{
|
|
491
491
|
type: NgModule,
|
|
492
492
|
args: [{
|
|
493
493
|
imports: cmp,
|
|
@@ -92,10 +92,10 @@ class TreeService {
|
|
|
92
92
|
this._resolveChildren(nodeIDs, n.children);
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
96
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
95
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
96
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeService }); }
|
|
97
97
|
}
|
|
98
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
98
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeService, decorators: [{
|
|
99
99
|
type: Injectable
|
|
100
100
|
}] });
|
|
101
101
|
|
|
@@ -138,10 +138,10 @@ class TreeNodeComponent {
|
|
|
138
138
|
ngOnDestroy() {
|
|
139
139
|
this._subs.forEach((s) => s.unsubscribe());
|
|
140
140
|
}
|
|
141
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
142
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
141
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
142
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TreeNodeComponent, isStandalone: true, selector: "yuv-tree-node", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null }, toggleIcon: { classPropertyName: "toggleIcon", publicName: "toggleIcon", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "treeitem" }, properties: { "class.focused": "focused", "attr.aria-selected": "selected", "attr.aria-expanded": "expanded" } }, ngImport: i0, template: "@if (node().children?.length) {\n <!-- toggle children button-->\n <!-- TODO: title should be i18n -->\n <button class=\"toggle\" (click)=\"toggleExpanded()\">\n <yuv-icon [svg]=\"toggleIcon()\"></yuv-icon>\n </button>\n}\n<div class=\"node-label\" [attr.node-id]=\"node().id\" [ngClass]=\"{ selectable: node().selectable }\" (click)=\"select($event)\">\n @if (node().icon) {\n <yuv-icon class=\"node-icon\" [svg]=\"node().icon!\"></yuv-icon>\n }\n <div class=\"label\">{{ node().label }}</div>\n</div>\n\n@if (node().expanded) {\n <div class=\"children\">\n @for (childNode of node().children; track $index) {\n <yuv-tree-node tabindex=\"0\" [toggleIcon]=\"toggleIcon()\" [node]=\"childNode\"></yuv-tree-node>\n }\n </div>\n}\n", styles: [":host-context(:focus).focused>.node-label{background-color:var(--ymt-focus-background);outline:1px solid var(--ymt-text-color-subtle);outline-offset:-3px}:host-context([selectable])[aria-selected=true]>.node-label{background-color:var(--ymt-selection-background)}:host-context([selectable])[aria-selected=true]>.node-label:hover{background-color:var(--ymt-selection-background)}:host{display:grid;grid-template-rows:auto auto;grid-template-columns:var(--toggle-icon-size) 1fr;grid-template-areas:\"toggle label\" \"child child\";align-items:center}:host .node-label{grid-area:label;display:flex;flex-flow:row nowrap;align-items:center}:host .node-label.selectable{cursor:pointer}:host .node-label:hover{background-color:var(--ymt-hover-background)}:host .node-label .label{padding:var(--node-padding);text-align:start;color:var(--ymt-text-color);background-color:transparent;-webkit-user-select:none;user-select:none;flex:1}:host .node-label .node-icon{color:var(--ymt-text-color-subtle)}:host .children{grid-area:child;padding-inline-start:var(--node-indent)}:host[aria-expanded=true] button.toggle{rotate:90deg}:host button.toggle{grid-area:toggle;border:0;padding:2px;border-radius:50%;justify-self:center;align-self:center}\n"], dependencies: [{ kind: "component", type: TreeNodeComponent, selector: "yuv-tree-node", inputs: ["node", "toggleIcon"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: YuvIconComponent, selector: "yuv-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: MatTooltipModule }] }); }
|
|
143
143
|
}
|
|
144
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
144
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeNodeComponent, decorators: [{
|
|
145
145
|
type: Component,
|
|
146
146
|
args: [{ selector: 'yuv-tree-node', standalone: true, imports: [CommonModule, YuvIconComponent, MatTooltipModule], host: {
|
|
147
147
|
role: 'treeitem',
|
|
@@ -274,10 +274,10 @@ class TreeComponent {
|
|
|
274
274
|
ngOnDestroy() {
|
|
275
275
|
this._observer.disconnect();
|
|
276
276
|
}
|
|
277
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
278
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
277
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
278
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TreeComponent, isStandalone: true, selector: "yuv-tree", inputs: { tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: true, transformFunction: null }, multiselect: { classPropertyName: "multiselect", publicName: "multiselect", isSignal: true, isRequired: false, transformFunction: null }, selectedNodes: { classPropertyName: "selectedNodes", publicName: "selectedNodes", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { attributes: { "role": "tree" }, listeners: { "keydown": "onKeydown($event)" }, properties: { "class.selectable": "selectable", "attr.tabindex": "tabindex" }, classAttribute: "yuv-tree" }, providers: [TreeService], ngImport: i0, template: "@for (node of tree().nodes; track node.id) {\n <yuv-tree-node tabindex=\"0\" [node]=\"node\"></yuv-tree-node>\n}\n", styles: [":host{--toggle-icon-size: 18px;--node-padding: var(--ymt-spacing-xs);--node-indent: var(--toggle-icon-size)}\n"], dependencies: [{ kind: "component", type: TreeNodeComponent, selector: "yuv-tree-node", inputs: ["node", "toggleIcon"] }] }); }
|
|
279
279
|
}
|
|
280
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
280
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeComponent, decorators: [{
|
|
281
281
|
type: Component,
|
|
282
282
|
args: [{ selector: 'yuv-tree', standalone: true, imports: [TreeNodeComponent], providers: [TreeService], host: {
|
|
283
283
|
class: 'yuv-tree',
|
|
@@ -38,10 +38,10 @@ class UploadProgressOverlayComponent {
|
|
|
38
38
|
return this.translate.instant('yuv.upload-progress-overlay.error.default');
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
42
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
41
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UploadProgressOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
42
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: UploadProgressOverlayComponent, isStandalone: true, selector: "yuv-upload-progress-overlay", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, ngImport: i0, template: "<ul>\n @for (item of _items(); track item.id) {\n @let progress = item.progress | async;\n <li [ngClass]=\"{ err: !!item.err, done: !!item.result }\" [style.--progress]=\"progress + '%'\">\n <button mat-icon-button class=\"remove\" (click)=\"remove(item.id)\">\n <mat-icon [ngClass]=\"{ err: !!item.err }\">close</mat-icon>\n </button>\n\n @if (!item.result) {\n <div class=\"name\">{{ item.filename }}\n @if(item.err) {\n <span class=\"error\">{{item.err.message}}</span>\n }\n </div>\n <div class=\"progress\">\n @if (progress && progress < 100) {\n <div class=\"percentage\">{{ progress }}</div>\n }\n @else if(item.err) {\n <mat-icon class=\"error\">warning</mat-icon>\n }\n @else {\n <mat-progress-spinner mode=\"indeterminate\" class=\"ymt-progress-spinner--tiny\"></mat-progress-spinner>\n }\n </div>\n } @else {\n <div class=\"result-items\">\n @for (res of item.result; track $index) {\n <div class=\"result-item\">\n <div class=\"name\" (click)=\"itemClick.emit(res)\">\n {{ res.label }}\n </div>\n </div>\n }\n </div>\n <mat-icon class=\"done\">check</mat-icon>\n }\n </li>\n }\n</ul>\n", styles: [":host ul{list-style:none;padding:0;margin:var(--ymt-spacing-xs) 0}:host li{--hover-background: transparent;display:grid;grid-template-columns:1fr auto auto;grid-template-rows:auto;cursor:default;grid-template-areas:\"result progress action\";align-items:center;padding:var(--ymt-spacing-2xs) var(--ymt-spacing-2xs) var(--ymt-spacing-2xs) var(--ymt-spacing-xs);gap:.5em;margin-block-end:1px;background:linear-gradient(90deg,rgb(from var(--ymt-primary) r g b/.1) 0%,rgb(from var(--ymt-primary) r g b/.3) var(--progress),var(--hover-background) var(--progress));transition:background-color .3s ease-in-out}:host li.done{background:var(--hover-background)}:host li:hover{--hover-background: var(--ymt-hover-background)}:host li .name{grid-area:result;max-width:35ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host li .name .error{color:var(--ymt-text-color-subtle);display:block;font-style:italic;max-width:35ch}:host li .progress{grid-area:progress}:host li .percentage{font-family:monospace;padding:var(--ymt-spacing-2xs) var(--ymt-spacing-m);font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);align-self:center}:host li .percentage:after{content:\"%\"}:host li mat-icon.done{--icon-size: 18px;fill:var(--ymt-primary)}:host li .remove{grid-area:action}:host li .remove mat-icon{color:var(--ymt-text-color-subtle)}:host .result-items{grid-area:result}:host .result-items .result-item{cursor:pointer}:host mat-icon{--icon-size: 18px;border-radius:4px}:host mat-icon.done{background-color:var(--ymt-primary);color:var(--ymt-on-primary)}:host mat-icon.error{color:var(--ymt-danger)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.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"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] }); }
|
|
43
43
|
}
|
|
44
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
44
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UploadProgressOverlayComponent, decorators: [{
|
|
45
45
|
type: Component,
|
|
46
46
|
args: [{ selector: 'yuv-upload-progress-overlay', standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatProgressSpinner], template: "<ul>\n @for (item of _items(); track item.id) {\n @let progress = item.progress | async;\n <li [ngClass]=\"{ err: !!item.err, done: !!item.result }\" [style.--progress]=\"progress + '%'\">\n <button mat-icon-button class=\"remove\" (click)=\"remove(item.id)\">\n <mat-icon [ngClass]=\"{ err: !!item.err }\">close</mat-icon>\n </button>\n\n @if (!item.result) {\n <div class=\"name\">{{ item.filename }}\n @if(item.err) {\n <span class=\"error\">{{item.err.message}}</span>\n }\n </div>\n <div class=\"progress\">\n @if (progress && progress < 100) {\n <div class=\"percentage\">{{ progress }}</div>\n }\n @else if(item.err) {\n <mat-icon class=\"error\">warning</mat-icon>\n }\n @else {\n <mat-progress-spinner mode=\"indeterminate\" class=\"ymt-progress-spinner--tiny\"></mat-progress-spinner>\n }\n </div>\n } @else {\n <div class=\"result-items\">\n @for (res of item.result; track $index) {\n <div class=\"result-item\">\n <div class=\"name\" (click)=\"itemClick.emit(res)\">\n {{ res.label }}\n </div>\n </div>\n }\n </div>\n <mat-icon class=\"done\">check</mat-icon>\n }\n </li>\n }\n</ul>\n", styles: [":host ul{list-style:none;padding:0;margin:var(--ymt-spacing-xs) 0}:host li{--hover-background: transparent;display:grid;grid-template-columns:1fr auto auto;grid-template-rows:auto;cursor:default;grid-template-areas:\"result progress action\";align-items:center;padding:var(--ymt-spacing-2xs) var(--ymt-spacing-2xs) var(--ymt-spacing-2xs) var(--ymt-spacing-xs);gap:.5em;margin-block-end:1px;background:linear-gradient(90deg,rgb(from var(--ymt-primary) r g b/.1) 0%,rgb(from var(--ymt-primary) r g b/.3) var(--progress),var(--hover-background) var(--progress));transition:background-color .3s ease-in-out}:host li.done{background:var(--hover-background)}:host li:hover{--hover-background: var(--ymt-hover-background)}:host li .name{grid-area:result;max-width:35ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host li .name .error{color:var(--ymt-text-color-subtle);display:block;font-style:italic;max-width:35ch}:host li .progress{grid-area:progress}:host li .percentage{font-family:monospace;padding:var(--ymt-spacing-2xs) var(--ymt-spacing-m);font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);align-self:center}:host li .percentage:after{content:\"%\"}:host li mat-icon.done{--icon-size: 18px;fill:var(--ymt-primary)}:host li .remove{grid-area:action}:host li .remove mat-icon{color:var(--ymt-text-color-subtle)}:host .result-items{grid-area:result}:host .result-items .result-item{cursor:pointer}:host mat-icon{--icon-size: 18px;border-radius:4px}:host mat-icon.done{background-color:var(--ymt-primary);color:var(--ymt-on-primary)}:host mat-icon.error{color:var(--ymt-danger)}\n"] }]
|
|
47
47
|
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }] } });
|
|
@@ -93,10 +93,10 @@ class UploadProgressComponent {
|
|
|
93
93
|
close() {
|
|
94
94
|
this.filteredItems().forEach((item) => this.#uploadService.cancelItem(item.id));
|
|
95
95
|
}
|
|
96
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
97
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
96
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UploadProgressComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
97
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: UploadProgressComponent, isStandalone: true, selector: "yuv-upload-progress", inputs: { scopes: { classPropertyName: "scopes", publicName: "scopes", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { resultItemClick: "resultItemClick" }, host: { properties: { "class.expanded": "expanded" } }, ngImport: i0, template: "@let items = filteredItems();\n@if (items.length) {\n @let completed = completedUp$ | async;\n\n <div class=\"upload-progress\">\n <header>\n <h4>\n @if (!completed) {\n {{ 'yuv.upload-progress.header.uploading' | translate: { count: items.length } }}\n } @else {\n {{ 'yuv.upload-progress.header.uploaded' | translate: { count: items.length } }}\n }\n </h4>\n <button mat-icon-button (click)=\"expanded = !expanded\">\n <mat-icon class=\"toggle\">keyboard_arrow_down</mat-icon>\n </button>\n <button mat-icon-button (click)=\"close()\">\n <mat-icon class=\"toggle\">clear</mat-icon>\n </button>\n </header>\n @if (expanded) {\n <yuv-upload-progress-overlay [items]=\"items\" (itemClick)=\"resultItemClick.emit($event)\" />\n }\n </div>\n}\n", styles: [":host{--upload-progress-background-header: var(--ymt-surface-panel);--upload-progress-background-main: var(--ymt-surface-panel);--upload-progress-border-color: var(--ymt-surface-panel);--upload-progress-outline: 4px solid rgb(from var(--ymt-outline-variant) r g b / .9);--upload-progress-border-radius: var(--ymt-spacing-2xs);position:absolute;inset-block-end:var(--ymt-spacing-m);inset-inline-end:var(--ymt-spacing-m);z-index:1000}:host .upload-progress{display:flex;flex-flow:column;background-color:var(--upload-progress-background-main);border:1px solid var(--upload-progress-border-color);border-radius:var(--upload-progress-border-radius);outline:var(--upload-progress-outline);min-width:250px;max-height:30vh;overflow:hidden;animation:appear .3s ease-in-out}:host .toggle{rotate:180deg}:host.expanded .toggle{rotate:0deg}:host header{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);background-color:var(--upload-progress-background-header);padding:var(--ymt-spacing-2xs)}:host header h4{margin:0;padding:0 var(--ymt-spacing-xs);flex:1}:host yuv-upload-progress-overlay{overflow-y:auto}@keyframes appear{0%{opacity:0;transform:translateY(var(--ymt-spacing-m))}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: UploadProgressOverlayComponent, selector: "yuv-upload-progress-overlay", inputs: ["items"], outputs: ["itemClick"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
98
98
|
}
|
|
99
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
99
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UploadProgressComponent, decorators: [{
|
|
100
100
|
type: Component,
|
|
101
101
|
args: [{ selector: 'yuv-upload-progress', standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, TranslatePipe, UploadProgressOverlayComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
102
102
|
'[class.expanded]': 'expanded'
|
|
@@ -107,11 +107,11 @@ const cmp = [
|
|
|
107
107
|
UploadProgressComponent
|
|
108
108
|
];
|
|
109
109
|
class YuvUploadProgressModule {
|
|
110
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
111
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.
|
|
112
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.
|
|
110
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: YuvUploadProgressModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
111
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.20", ngImport: i0, type: YuvUploadProgressModule, imports: [UploadProgressComponent], exports: [UploadProgressComponent] }); }
|
|
112
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: YuvUploadProgressModule, imports: [cmp] }); }
|
|
113
113
|
}
|
|
114
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
114
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: YuvUploadProgressModule, decorators: [{
|
|
115
115
|
type: NgModule,
|
|
116
116
|
args: [{
|
|
117
117
|
imports: [cmp],
|
|
@@ -102,13 +102,21 @@ const defaultHaloFocusOffset = 3;
|
|
|
102
102
|
* **Style Properties:**
|
|
103
103
|
* - `position: 'fixed'` - Keeps halo in viewport regardless of scroll position
|
|
104
104
|
* - `pointerEvents: 'none'` - Allows click-through; halo doesn't block interactions
|
|
105
|
-
* - `zIndex: '9999'` -
|
|
105
|
+
* - `zIndex: '9999'` - Stacking fallback for browsers without the Popover API. The halo normally
|
|
106
|
+
* joins the browser's top layer instead (see {@link HaloFocusService}), where z-index does not
|
|
107
|
+
* apply, because Angular CDK renders overlays there as well.
|
|
106
108
|
* - `border` - Primary border using CSS variable `--ymt-primary` (2px solid)
|
|
107
109
|
* - `boxShadow` - Soft shadow with 20% opacity for subtle depth effect
|
|
108
110
|
* - `borderRadius` - Default 8px rounded corners for modern appearance
|
|
109
111
|
* - `opacity: '0'` - Initially hidden; visibility controlled by service
|
|
110
112
|
* - `transform: 'translateZ(0)'` - Creates GPU layer for smoother animations
|
|
111
113
|
*
|
|
114
|
+
* **Popover user-agent resets:**
|
|
115
|
+
* Once the halo carries `popover="manual"` the UA stylesheet applies
|
|
116
|
+
* `inset: 0; margin: auto; padding: 0.25em; overflow: auto; background-color: Canvas` to it. Those
|
|
117
|
+
* defaults would re-center the halo and paint it as an opaque filled box over the content, so they
|
|
118
|
+
* are neutralised here. This mirrors the resets the CDK applies to its own `.cdk-overlay-popover`.
|
|
119
|
+
*
|
|
112
120
|
* **CSS Variable Dependencies:**
|
|
113
121
|
* - `--ymt-primary` - Primary theme color for border and shadow
|
|
114
122
|
*
|
|
@@ -119,6 +127,12 @@ const defaultHaloFocusOffset = 3;
|
|
|
119
127
|
*/
|
|
120
128
|
const haloFocusStyles = {
|
|
121
129
|
position: 'fixed',
|
|
130
|
+
// Popover UA resets - `left`/`top`/`width`/`height` are set per update by HaloUtilityService.
|
|
131
|
+
inset: 'auto',
|
|
132
|
+
margin: '0',
|
|
133
|
+
padding: '0',
|
|
134
|
+
background: 'none',
|
|
135
|
+
overflow: 'visible',
|
|
122
136
|
pointerEvents: 'none',
|
|
123
137
|
zIndex: '9999',
|
|
124
138
|
border: '2px solid var(--ymt-primary)',
|
|
@@ -305,6 +319,7 @@ var ChannelMessage;
|
|
|
305
319
|
* - Automatic visibility detection (handles clipping, hidden elements, etc.)
|
|
306
320
|
* - Responsive to dynamic DOM changes via ResizeObserver and MutationObserver
|
|
307
321
|
* - Smart exclusion for Angular Material form fields (prevents redundant styling)
|
|
322
|
+
* - Renders in the browser's top layer, so it stays visible inside CDK overlays
|
|
308
323
|
*
|
|
309
324
|
* **Usage:**
|
|
310
325
|
* 1. Add `provideHaloFocus()` to your providers array in app.config.ts
|
|
@@ -359,6 +374,13 @@ class HaloFocusService {
|
|
|
359
374
|
#haloElement = null;
|
|
360
375
|
#currentElement = null;
|
|
361
376
|
#lastInteractionWasKeyboard = false;
|
|
377
|
+
/** Whether the browser supports the Popover API, i.e. whether the halo can join the top layer. */
|
|
378
|
+
#supportsPopover = false;
|
|
379
|
+
/**
|
|
380
|
+
* Tracked manually instead of via `matches(':popover-open')`, because `matches()` throws on
|
|
381
|
+
* pseudo-classes the environment does not know (jsdom).
|
|
382
|
+
*/
|
|
383
|
+
#popoverOpen = false;
|
|
362
384
|
#rafId = null; //Request Animation Frame ID
|
|
363
385
|
#resizeObserver;
|
|
364
386
|
#mutationObserver;
|
|
@@ -369,7 +391,8 @@ class HaloFocusService {
|
|
|
369
391
|
*
|
|
370
392
|
* This method performs the following initialization steps:
|
|
371
393
|
* 1. Applies optional configuration for halo appearance (inner and outer colors)
|
|
372
|
-
* 2. Creates and appends the halo DIV element to the document body
|
|
394
|
+
* 2. Creates and appends the halo DIV element to the document body, as a `popover` so it can
|
|
395
|
+
* join the browser's top layer, and marks the body with `yuv-halo-focus`
|
|
373
396
|
* 3. Attaches global event listeners for focus, blur, keyboard, mouse, scroll, and resize events
|
|
374
397
|
* 4. Sets up ResizeObserver and MutationObserver for tracking dynamic DOM changes
|
|
375
398
|
*
|
|
@@ -403,7 +426,17 @@ class HaloFocusService {
|
|
|
403
426
|
this.#haloElement.id = 'focus-halo';
|
|
404
427
|
this.#haloElement.setAttribute('aria-hidden', 'true');
|
|
405
428
|
Object.assign(this.#haloElement.style, this.#utility.getHaloFocusStyles(this.#config));
|
|
429
|
+
// Angular CDK renders overlays (dialogs, menus, selects, autocompletes) in the browser's top
|
|
430
|
+
// layer via popover="manual". Nothing in the normal DOM can paint above the top layer, no
|
|
431
|
+
// matter its z-index, so the halo has to join it to stay visible inside an overlay.
|
|
432
|
+
this.#supportsPopover = 'showPopover' in document.body;
|
|
433
|
+
if (this.#supportsPopover) {
|
|
434
|
+
this.#haloElement.setAttribute('popover', 'manual');
|
|
435
|
+
}
|
|
406
436
|
document.body.appendChild(this.#haloElement);
|
|
437
|
+
// Lets @yuuvis/material suppress its global :focus-visible ring, so keyboard focus is not
|
|
438
|
+
// indicated twice by two differently coloured rings.
|
|
439
|
+
document.body.classList.add('yuv-halo-focus');
|
|
407
440
|
}
|
|
408
441
|
#initListeners() {
|
|
409
442
|
document.addEventListener('focus', this.#onFocus, true);
|
|
@@ -428,18 +461,56 @@ class HaloFocusService {
|
|
|
428
461
|
}
|
|
429
462
|
}
|
|
430
463
|
// #endregion
|
|
464
|
+
//#region Top layer
|
|
465
|
+
/**
|
|
466
|
+
* Re-enters the browser's top layer so the halo becomes its topmost entry.
|
|
467
|
+
*
|
|
468
|
+
* Top layer order is "last shown wins", so an overlay opened after the halo would paint over it.
|
|
469
|
+
* Re-showing the popover moves the halo back to the front. Called once per focus change rather
|
|
470
|
+
* than per render frame: an overlay that appears above the halo also moves focus into itself, so
|
|
471
|
+
* a focus change is the only moment the order can turn stale.
|
|
472
|
+
*/
|
|
473
|
+
#raiseToTopLayer() {
|
|
474
|
+
if (!this.#supportsPopover || !this.#haloElement)
|
|
475
|
+
return;
|
|
476
|
+
this.#leaveTopLayer();
|
|
477
|
+
try {
|
|
478
|
+
this.#haloElement.showPopover();
|
|
479
|
+
this.#popoverOpen = true;
|
|
480
|
+
}
|
|
481
|
+
catch {
|
|
482
|
+
// Element not connected, or popover already open in a browser we misdetected.
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
/** Leaves the top layer again, so a hidden halo does not linger in it. */
|
|
486
|
+
#leaveTopLayer() {
|
|
487
|
+
if (!this.#supportsPopover || !this.#haloElement || !this.#popoverOpen)
|
|
488
|
+
return;
|
|
489
|
+
try {
|
|
490
|
+
this.#haloElement.hidePopover();
|
|
491
|
+
}
|
|
492
|
+
catch {
|
|
493
|
+
// Already hidden.
|
|
494
|
+
}
|
|
495
|
+
this.#popoverOpen = false;
|
|
496
|
+
}
|
|
497
|
+
#hideHalo() {
|
|
498
|
+
if (this.#haloElement) {
|
|
499
|
+
this.#haloElement.style.opacity = '0';
|
|
500
|
+
}
|
|
501
|
+
this.#leaveTopLayer();
|
|
502
|
+
}
|
|
503
|
+
//#endregion
|
|
431
504
|
//#region Rendering
|
|
432
505
|
#updateHaloRect = () => {
|
|
433
506
|
if (!this.#currentElement || !this.#haloElement || !document.contains(this.#currentElement)) {
|
|
434
|
-
|
|
435
|
-
this.#haloElement.style.opacity = '0';
|
|
436
|
-
}
|
|
507
|
+
this.#hideHalo();
|
|
437
508
|
this.#currentElement = null;
|
|
438
509
|
return;
|
|
439
510
|
}
|
|
440
511
|
// Check if element is actually visible
|
|
441
512
|
if (!this.#utility.isElementVisible(this.#currentElement)) {
|
|
442
|
-
this.#
|
|
513
|
+
this.#hideHalo();
|
|
443
514
|
return;
|
|
444
515
|
}
|
|
445
516
|
this.#utility.setHaloElementSize(this.#currentElement, this.#haloElement);
|
|
@@ -453,6 +524,9 @@ class HaloFocusService {
|
|
|
453
524
|
};
|
|
454
525
|
#startTracking(target) {
|
|
455
526
|
this.#currentElement = target;
|
|
527
|
+
// Raise before the update is scheduled; the halo is still at opacity 0 until #updateHaloRect
|
|
528
|
+
// has repositioned it, so it cannot flash at its previous position.
|
|
529
|
+
this.#raiseToTopLayer();
|
|
456
530
|
this.#scheduleUpdate();
|
|
457
531
|
// Track size changes on target element
|
|
458
532
|
if (this.#resizeObserver) {
|
|
@@ -498,7 +572,7 @@ class HaloFocusService {
|
|
|
498
572
|
#onMouseDown = () => {
|
|
499
573
|
this.#lastInteractionWasKeyboard = false;
|
|
500
574
|
if (this.#haloElement) {
|
|
501
|
-
this.#
|
|
575
|
+
this.#hideHalo();
|
|
502
576
|
this.#currentElement = null;
|
|
503
577
|
this.#stopTracking();
|
|
504
578
|
}
|
|
@@ -513,9 +587,7 @@ class HaloFocusService {
|
|
|
513
587
|
this.#utility.shouldSkipElementInMatFormField(target) ||
|
|
514
588
|
container?.hasAttribute('halo-container-skip') ||
|
|
515
589
|
!this.#utility.matchesFocusVisible(target, this.#lastInteractionWasKeyboard)) {
|
|
516
|
-
|
|
517
|
-
this.#haloElement.style.opacity = '0';
|
|
518
|
-
}
|
|
590
|
+
this.#hideHalo();
|
|
519
591
|
this.#currentElement = null;
|
|
520
592
|
return;
|
|
521
593
|
}
|
|
@@ -524,15 +596,15 @@ class HaloFocusService {
|
|
|
524
596
|
};
|
|
525
597
|
#onBlur = (focusEvent) => {
|
|
526
598
|
if (focusEvent.target === this.#currentElement && this.#haloElement) {
|
|
527
|
-
this.#
|
|
599
|
+
this.#hideHalo();
|
|
528
600
|
this.#currentElement = null;
|
|
529
601
|
this.#stopTracking();
|
|
530
602
|
}
|
|
531
603
|
};
|
|
532
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
533
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
604
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HaloFocusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
605
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HaloFocusService, providedIn: 'root' }); }
|
|
534
606
|
}
|
|
535
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
607
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HaloFocusService, decorators: [{
|
|
536
608
|
type: Injectable,
|
|
537
609
|
args: [{
|
|
538
610
|
providedIn: 'root'
|
|
@@ -961,10 +1033,10 @@ class HaloUtilityService {
|
|
|
961
1033
|
haloElement.style.height = `${height}px`;
|
|
962
1034
|
haloElement.style.borderRadius = cs.borderRadius || '8px';
|
|
963
1035
|
}
|
|
964
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
965
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1036
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HaloUtilityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1037
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HaloUtilityService }); }
|
|
966
1038
|
}
|
|
967
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1039
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HaloUtilityService, decorators: [{
|
|
968
1040
|
type: Injectable
|
|
969
1041
|
}] });
|
|
970
1042
|
|
|
@@ -1074,10 +1146,10 @@ class PwaUpdateService {
|
|
|
1074
1146
|
.catch(() => false)
|
|
1075
1147
|
.finally(() => document.location.reload());
|
|
1076
1148
|
}
|
|
1077
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1078
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1149
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PwaUpdateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1150
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PwaUpdateService, providedIn: 'root' }); }
|
|
1079
1151
|
}
|
|
1080
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1152
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PwaUpdateService, decorators: [{
|
|
1081
1153
|
type: Injectable,
|
|
1082
1154
|
args: [{ providedIn: 'root' }]
|
|
1083
1155
|
}] });
|
|
@@ -1119,10 +1191,10 @@ class SessionExpiryDialogComponent {
|
|
|
1119
1191
|
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
1120
1192
|
return Math.max(0, Math.ceil((this.#data.expiresAt - Date.now()) / 1000));
|
|
1121
1193
|
}
|
|
1122
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1123
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
1194
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SessionExpiryDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1195
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.20", type: SessionExpiryDialogComponent, isStandalone: true, selector: "yuv-session-expiry-dialog", ngImport: i0, template: "<yuv-dialog [headertitle]=\"'yuv.session.expires.title' | translate\">\n <main>{{ 'yuv.session.expires.message' | translate: { seconds: remainingSeconds() } }}</main>\n <footer>\n <button ymtButton=\"primary\" type=\"button\" (click)=\"extend()\">\n {{ 'yuv.session.extend.action' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: ["main{padding:var(--ymt-spacing-m)}\n"], dependencies: [{ 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 }); }
|
|
1124
1196
|
}
|
|
1125
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1197
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SessionExpiryDialogComponent, decorators: [{
|
|
1126
1198
|
type: Component,
|
|
1127
1199
|
args: [{ selector: 'yuv-session-expiry-dialog', imports: [DialogComponent, YmtButtonDirective, TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<yuv-dialog [headertitle]=\"'yuv.session.expires.title' | translate\">\n <main>{{ 'yuv.session.expires.message' | translate: { seconds: remainingSeconds() } }}</main>\n <footer>\n <button ymtButton=\"primary\" type=\"button\" (click)=\"extend()\">\n {{ 'yuv.session.extend.action' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: ["main{padding:var(--ymt-spacing-m)}\n"] }]
|
|
1128
1200
|
}], ctorParameters: () => [] });
|
|
@@ -1452,10 +1524,10 @@ class SessionService {
|
|
|
1452
1524
|
this.#activityWindowEnd$?.unsubscribe();
|
|
1453
1525
|
this.#logoutTimer$?.unsubscribe();
|
|
1454
1526
|
}
|
|
1455
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1456
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1527
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SessionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1528
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SessionService, providedIn: 'root' }); }
|
|
1457
1529
|
}
|
|
1458
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1530
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SessionService, decorators: [{
|
|
1459
1531
|
type: Injectable,
|
|
1460
1532
|
args: [{ providedIn: 'root' }]
|
|
1461
1533
|
}] });
|
|
@@ -1509,10 +1581,10 @@ class SnackBarService {
|
|
|
1509
1581
|
panelClass: ['yuv-snack-bar', 'level-' + options.level]
|
|
1510
1582
|
});
|
|
1511
1583
|
}
|
|
1512
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1513
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1584
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SnackBarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1585
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SnackBarService, providedIn: 'root' }); }
|
|
1514
1586
|
}
|
|
1515
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1587
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SnackBarService, decorators: [{
|
|
1516
1588
|
type: Injectable,
|
|
1517
1589
|
args: [{
|
|
1518
1590
|
providedIn: 'root'
|
|
@@ -1538,8 +1610,8 @@ class SnackBarComponent {
|
|
|
1538
1610
|
this.#snackBarRef.dismiss();
|
|
1539
1611
|
}
|
|
1540
1612
|
}
|
|
1541
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1542
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1613
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SnackBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1614
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SnackBarComponent, isStandalone: true, selector: "yuv-snack-bar-component", host: { properties: { "class.info": "level() === 'info'", "class.success": "level() === 'success'", "class.warning": "level() === 'warning'", "class.danger": "level() === 'danger'" } }, ngImport: i0, template: `
|
|
1543
1615
|
@let a = action();
|
|
1544
1616
|
<span
|
|
1545
1617
|
matSnackBarLabel
|
|
@@ -1558,7 +1630,7 @@ class SnackBarComponent {
|
|
|
1558
1630
|
}
|
|
1559
1631
|
`, isInline: true, styles: [":host{display:flex}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatSnackBarLabel, selector: "[matSnackBarLabel]" }, { kind: "directive", type: MatSnackBarActions, selector: "[matSnackBarActions]" }, { kind: "directive", type: MatSnackBarAction, selector: "[matSnackBarAction]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1560
1632
|
}
|
|
1561
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1633
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SnackBarComponent, decorators: [{
|
|
1562
1634
|
type: Component,
|
|
1563
1635
|
args: [{ selector: 'yuv-snack-bar-component', template: `
|
|
1564
1636
|
@let a = action();
|
|
@@ -1758,11 +1830,11 @@ function provideSession(sessionDuration) {
|
|
|
1758
1830
|
}
|
|
1759
1831
|
|
|
1760
1832
|
class YuuvisClientFrameworkModule {
|
|
1761
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1762
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.
|
|
1763
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.
|
|
1833
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: YuuvisClientFrameworkModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1834
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.20", ngImport: i0, type: YuuvisClientFrameworkModule, imports: [CommonModule] }); }
|
|
1835
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: YuuvisClientFrameworkModule, imports: [CommonModule] }); }
|
|
1764
1836
|
}
|
|
1765
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1837
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: YuuvisClientFrameworkModule, decorators: [{
|
|
1766
1838
|
type: NgModule,
|
|
1767
1839
|
args: [{
|
|
1768
1840
|
imports: [CommonModule],
|