@almoamendev/ngx-md3 0.7.5 → 0.8.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/almoamendev-ngx-md3.mjs +1443 -1135
- package/fesm2022/almoamendev-ngx-md3.mjs.map +1 -1
- package/package.json +1 -1
- package/types/almoamendev-ngx-md3.d.ts +185 -90
|
@@ -8,12 +8,12 @@ import * as i1 from '@angular/router';
|
|
|
8
8
|
import { Router, NavigationEnd, RouterLinkActive } from '@angular/router';
|
|
9
9
|
import { CdkPortalOutlet, ComponentPortal } from '@angular/cdk/portal';
|
|
10
10
|
import { CdkDialogContainer, Dialog as Dialog$1 } from '@angular/cdk/dialog';
|
|
11
|
-
import { Overlay,
|
|
11
|
+
import { Overlay, OverlayConfig, OverlayContainer } from '@angular/cdk/overlay';
|
|
12
12
|
import { hasModifierKey } from '@angular/cdk/keycodes';
|
|
13
13
|
import * as i2 from '@angular/cdk/scrolling';
|
|
14
14
|
import { CdkScrollable } from '@angular/cdk/scrolling';
|
|
15
15
|
import { Directionality } from '@angular/cdk/bidi';
|
|
16
|
-
import { FormControlName } from '@angular/forms';
|
|
16
|
+
import { FormControlName, NgControl } from '@angular/forms';
|
|
17
17
|
|
|
18
18
|
class TypeDisplay {
|
|
19
19
|
el;
|
|
@@ -4353,7 +4353,6 @@ class Switch {
|
|
|
4353
4353
|
inputDisabledState = signal(false, /* @ts-ignore */
|
|
4354
4354
|
...(ngDevMode ? [{ debugName: "inputDisabledState" }] : /* istanbul ignore next */ []));
|
|
4355
4355
|
isDisabled = computed(() => {
|
|
4356
|
-
console.log('Switch disabled');
|
|
4357
4356
|
return this.inputDisabledState();
|
|
4358
4357
|
}, /* @ts-ignore */
|
|
4359
4358
|
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
@@ -6019,7 +6018,7 @@ class TextField {
|
|
|
6019
6018
|
provide: MD3_BUTTON_CONTEXT,
|
|
6020
6019
|
useExisting: TextField,
|
|
6021
6020
|
},
|
|
6022
|
-
], queries: [{ propertyName: "input", first: true, predicate: InputElement, descendants: true, isSignal: true }, { propertyName: "iconElements", predicate: IconElement, descendants: true, isSignal: true }, { propertyName: "iconButtons", predicate: IconButton, descendants: true, isSignal: true }, { propertyName: "controlName", first: true, predicate: FormControlName, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputContainer", first: true, predicate: ["inputContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<label #inputContainer class=\"md3-text-field-container\" [ngClass]=\"{\n 'md3-text-field-filled': fieldType() == 'filled',\n 'md3-text-field-outlined': fieldType() == 'outlined',\n}\">\n <ng-content></ng-content>\n <fieldset aria-hidden=\"true\" class=\"md3-text-field-outline\">\n @if (label() && fieldType() == 'outlined') {\n <legend class=\"md3-label-gap\">{{ label() }}</legend>\n }\n </fieldset>\n @if (label()) {\n <label class=\"md3-text-field-label\">{{ label() }}</label>\n }\n <ng-content select=\"[md3-icon-element=leading]\"></ng-content>\n <ng-content select=\"[md3-icon-button], [md3-icon-element=trailing]\"></ng-content>\n @if (fieldType() != 'outlined') {\n <div class=\"md3-text-field-state\"></div>\n }\n</label>\n<div class=\"md3-supporting-text-container\" [class.md3-has-error]=\"inputError()\">\n <ng-content select=\"[md3-supporting-text]\"></ng-content>\n @if (inputCounter()) {\n <div class=\"md3-text-input-counter\">{{ valueLength() + (maxLength() ? \"/\" + maxLength() : \"\") }}</div>\n }\n</div>\n", styles: [":host{--background-color: rgb(var(--md-scheme-surface-container-highest));--foreground-color: rgb(var(--md-scheme-on-surface));--label-color: rgb(var(--md-scheme-on-surface-variant));--caret-color: rgb(var(--md-scheme-primary));--outline-color: rgb(var(--md-scheme-on-surface-variant));font-size:1rem;width:100%}:host .md3-text-field-container{display:block;position:relative;border-radius:var(--md-border-radius-xsmall) var(--md-border-radius-xsmall) 0 0;overflow:hidden}:host .md3-text-field-container ::ng-deep [md3-icon-element=leading]{position:absolute;font-size:1.5em!important;height:1em!important;width:1em!important;top:.666667em;inset-inline-start:.5em;pointer-events:none;color:var(--label-color)}:host .md3-text-field-container ::ng-deep [md3-icon-element=trailing]{position:absolute;font-size:1.5em!important;height:1em!important;width:1em!important;top:.666667em;inset-inline-end:.5em;pointer-events:none;color:var(--label-color)}:host .md3-text-field-container ::ng-deep [md3-icon-button]{position:absolute;font-size:1em!important;top:.5em;inset-inline-end:.5em}:host .md3-text-field-container .md3-text-field-outline{position:absolute;inset:0;pointer-events:none;padding:0 .625em;margin:.0625em 0 0;border:none;border-bottom:.0625em solid var(--outline-color);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing),border-width none}:host .md3-text-field-container .md3-text-field-outline .md3-label-gap{padding:0;max-width:0em;font-size:.75em;font-weight:400;line-height:1.333332em;letter-spacing:.041667em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;visibility:hidden;transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing);interpolate-size:allow-keywords}:host .md3-text-field-container .md3-text-field-label{position:absolute;top:1em;inset-inline-start:1em;inset-inline-end:1em;padding:0;font-size:1em;font-weight:400;line-height:1.5em;letter-spacing:.03125em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none;color:var(--label-color);transform-origin:top left;transform:scale(1);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-text-field-container .md3-text-field-label:dir(rtl){transform-origin:top right}:host .md3-text-field-container .md3-text-field-state{position:absolute;inset:0;pointer-events:none;border-radius:inherit;background-color:rgba(var(--md-scheme-on-surface));opacity:0;transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-text-field-container ::ng-deep .md3-input-element{display:block;width:100%;border:none;outline:none;padding:1.5em 1em .5em;font-size:1em;font-weight:400;line-height:1.5em;letter-spacing:.03125em;resize:none;background-color:var(--background-color);color:var(--foreground-color);caret-color:var(--caret-color)}:host .md3-text-field-container ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-label{top:.4375em;transform:scale(.75)}:host .md3-text-field-container ::ng-deep .md3-input-element:hover~.md3-text-field-state{opacity:.08}:host .md3-text-field-container ::ng-deep .md3-input-element:hover~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-on-surface))}:host .md3-text-field-container ::ng-deep .md3-input-element:focus~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-primary));border-bottom-width:.1875em}:host .md3-text-field-container ::ng-deep .md3-input-element:focus~.md3-text-field-label{color:var(--caret-color);top:.4375em;transform:scale(.75)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled{--background-color: rgba(var(--md-scheme-surface-container), .4);--foreground-color: rgba(var(--md-scheme-on-surface), .38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-state{display:none}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-outline{border-bottom:.0625em solid rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-label{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~[md3-icon-element]{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]{caret-color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~.md3-text-field-label{color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-element=trailing]{color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-filled{--background-color: rgb(var(--md-scheme-error));--foreground-color: rgb(var(--md-scheme-on-error));--state-color: var(--md-scheme-on-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-tonal{--background-color: rgb(var(--md-scheme-error-container));--foreground-color: rgb(var(--md-scheme-on-error-container));--state-color: var(--md-scheme-on-error-container)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-outlined{--background-color: transparent;--foreground-color: rgb(var(--md-scheme-error));--state-color: var(--md-scheme-error);border-color:var(--md-scheme-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-standard{--background-color: transparent;--foreground-color: rgb(var(--md-scheme-error));--state-color: var(--md-scheme-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~.md3-text-field-label{color:rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~[md3-icon-element=trailing]{color:rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container.md3-has-leading-icon ::ng-deep .md3-input-element{padding-inline-start:3.25em}:host .md3-text-field-container.md3-has-leading-icon .md3-text-field-label{inset-inline-start:3.25em}:host .md3-text-field-container.md3-has-trailing-icon ::ng-deep .md3-input-element{padding-inline-end:3.25em}:host .md3-text-field-container.md3-has-trailing-icon .md3-text-field-label{inset-inline-end:3.25em}:host .md3-text-field-container.md3-text-field-outlined{--background-color: transparent;border-radius:var(--md-border-radius-xsmall);padding-top:.5em}:host .md3-text-field-container.md3-text-field-outlined .md3-text-field-outline{border-radius:inherit;border:.0625em solid var(--outline-color)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep [md3-icon-element=leading],:host .md3-text-field-container.md3-text-field-outlined ::ng-deep [md3-icon-element=trailing],:host .md3-text-field-container.md3-text-field-outlined ::ng-deep [md3-icon-button]{top:1em}:host .md3-text-field-container.md3-text-field-outlined .md3-text-field-label{top:1.5em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element{padding-block:1em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:focus~.md3-text-field-outline{padding:0 .5em;border-width:.1875em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:focus~.md3-text-field-outline .md3-label-gap,:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-outline .md3-label-gap{padding:0 .375em;max-width:fit-content}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:focus~.md3-text-field-label,:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-label{top:0;inset-inline:1em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled{--foreground-color: rgba(var(--md-scheme-on-surface), .38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~.md3-text-field-outline{border:.0625em solid rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~.md3-text-field-label{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~[md3-icon-element]{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-supporting-text-container{display:flex;flex-direction:row;align-items:flex-start;justify-content:space-between;gap:1.333332em;padding:0 1.333332em;font-size:.75em;font-weight:400;line-height:1.333332em;letter-spacing:.033332em;color:var(--label-color)}:host .md3-supporting-text-container.md3-has-error{color:rgb(var(--md-scheme-error))}:host .md3-supporting-text-container .md3-text-input-counter{margin-inline-start:auto}:host .md3-supporting-text-container>::ng-deep *{margin-top:.333332em}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
6021
|
+
], queries: [{ propertyName: "input", first: true, predicate: InputElement, descendants: true, isSignal: true }, { propertyName: "iconElements", predicate: IconElement, descendants: true, isSignal: true }, { propertyName: "iconButtons", predicate: IconButton, descendants: true, isSignal: true }, { propertyName: "controlName", first: true, predicate: FormControlName, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputContainer", first: true, predicate: ["inputContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<label #inputContainer class=\"md3-text-field-container\" [ngClass]=\"{\n 'md3-text-field-filled': fieldType() == 'filled',\n 'md3-text-field-outlined': fieldType() == 'outlined',\n}\">\n <ng-content></ng-content>\n <fieldset aria-hidden=\"true\" class=\"md3-text-field-outline\">\n @if (label() && fieldType() == 'outlined') {\n <legend class=\"md3-label-gap\">{{ label() }}</legend>\n }\n </fieldset>\n @if (label()) {\n <span class=\"md3-text-field-label\">{{ label() }}</span>\n }\n <ng-content select=\"[md3-icon-element=leading]\"></ng-content>\n <ng-content select=\"[md3-icon-button], [md3-icon-element=trailing]\"></ng-content>\n @if (fieldType() != 'outlined') {\n <div class=\"md3-text-field-state\"></div>\n }\n</label>\n<div class=\"md3-supporting-text-container\" [class.md3-has-error]=\"inputError()\">\n <ng-content select=\"[md3-supporting-text]\"></ng-content>\n @if (inputCounter()) {\n <div class=\"md3-text-input-counter\">{{ valueLength() + (maxLength() ? \"/\" + maxLength() : \"\") }}</div>\n }\n</div>\n", styles: [":host{--background-color: rgb(var(--md-scheme-surface-container-highest));--foreground-color: rgb(var(--md-scheme-on-surface));--label-color: rgb(var(--md-scheme-on-surface-variant));--caret-color: rgb(var(--md-scheme-primary));--outline-color: rgb(var(--md-scheme-on-surface-variant));font-size:1rem;width:100%}:host .md3-text-field-container{display:block;position:relative;border-radius:var(--md-border-radius-xsmall) var(--md-border-radius-xsmall) 0 0;overflow:hidden}:host .md3-text-field-container>::ng-deep [md3-icon-element=leading]{position:absolute;font-size:1.5em!important;height:1em!important;width:1em!important;top:.666667em;inset-inline-start:.5em;pointer-events:none;color:var(--label-color)}:host .md3-text-field-container>::ng-deep [md3-icon-element=trailing]{position:absolute;font-size:1.5em!important;height:1em!important;width:1em!important;top:.666667em;inset-inline-end:.5em;pointer-events:none;color:var(--label-color)}:host .md3-text-field-container>::ng-deep [md3-icon-button]{position:absolute;font-size:1em!important;top:.5em;inset-inline-end:.5em}:host .md3-text-field-container .md3-text-field-outline{position:absolute;inset:0;pointer-events:none;padding:0 .625em;margin:.0625em 0 0;border:none;border-bottom:.0625em solid var(--outline-color);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing),border-width none}:host .md3-text-field-container .md3-text-field-outline .md3-label-gap{padding:0;max-width:0em;font-size:.75em;font-weight:400;line-height:1.333332em;letter-spacing:.041667em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;visibility:hidden;transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing);interpolate-size:allow-keywords}:host .md3-text-field-container .md3-text-field-label{position:absolute;top:1em;inset-inline-start:1em;inset-inline-end:1em;padding:0;font-size:1em;font-weight:400;line-height:1.5em;letter-spacing:.03125em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none;color:var(--label-color);transform-origin:top left;transform:scale(1);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-text-field-container .md3-text-field-label:dir(rtl){transform-origin:top right}:host .md3-text-field-container .md3-text-field-state{position:absolute;inset:0;pointer-events:none;border-radius:inherit;background-color:rgba(var(--md-scheme-on-surface));opacity:0;transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-text-field-container ::ng-deep .md3-input-element{display:block;width:100%;border:none;outline:none;padding:1.5em 1em .5em;font-size:1em;font-weight:400;line-height:1.5em;letter-spacing:.03125em;resize:none;background-color:var(--background-color);color:var(--foreground-color);caret-color:var(--caret-color)}:host .md3-text-field-container ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-label{top:.4375em;transform:scale(.75)}:host .md3-text-field-container ::ng-deep .md3-input-element:hover~.md3-text-field-state{opacity:.08}:host .md3-text-field-container ::ng-deep .md3-input-element:hover~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-on-surface))}:host .md3-text-field-container ::ng-deep .md3-input-element:focus~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-primary));border-bottom-width:.1875em}:host .md3-text-field-container ::ng-deep .md3-input-element:focus:not(:read-only)~.md3-text-field-label{color:var(--caret-color);top:.4375em;transform:scale(.75)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled{--background-color: rgba(var(--md-scheme-surface-container), .4);--foreground-color: rgba(var(--md-scheme-on-surface), .38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-state{display:none}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-outline{border-bottom:.0625em solid rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-label{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~[md3-icon-element]{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]{caret-color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~.md3-text-field-label{color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-element=trailing]{color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-filled{--background-color: rgb(var(--md-scheme-error));--foreground-color: rgb(var(--md-scheme-on-error));--state-color: var(--md-scheme-on-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-tonal{--background-color: rgb(var(--md-scheme-error-container));--foreground-color: rgb(var(--md-scheme-on-error-container));--state-color: var(--md-scheme-on-error-container)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-outlined{--background-color: transparent;--foreground-color: rgb(var(--md-scheme-error));--state-color: var(--md-scheme-error);border-color:var(--md-scheme-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-standard{--background-color: transparent;--foreground-color: rgb(var(--md-scheme-error));--state-color: var(--md-scheme-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~.md3-text-field-label{color:rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~[md3-icon-element=trailing]{color:rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container.md3-has-leading-icon ::ng-deep .md3-input-element{padding-inline-start:3.25em}:host .md3-text-field-container.md3-has-leading-icon .md3-text-field-label{inset-inline-start:3.25em}:host .md3-text-field-container.md3-has-trailing-icon ::ng-deep .md3-input-element{padding-inline-end:3.25em}:host .md3-text-field-container.md3-has-trailing-icon .md3-text-field-label{inset-inline-end:3.25em}:host .md3-text-field-container.md3-text-field-outlined{--background-color: transparent;border-radius:var(--md-border-radius-xsmall);padding-top:.5em}:host .md3-text-field-container.md3-text-field-outlined .md3-text-field-outline{border-radius:inherit;border:.0625em solid var(--outline-color)}:host .md3-text-field-container.md3-text-field-outlined>::ng-deep [md3-icon-element=leading],:host .md3-text-field-container.md3-text-field-outlined>::ng-deep [md3-icon-element=trailing],:host .md3-text-field-container.md3-text-field-outlined>::ng-deep [md3-icon-button]{top:1em}:host .md3-text-field-container.md3-text-field-outlined .md3-text-field-label{top:1.5em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element{padding-block:1em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:focus~.md3-text-field-outline{padding:0 .5em;border-width:.1875em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:read-only):focus~.md3-text-field-outline .md3-label-gap,:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-outline .md3-label-gap{padding:0 .375em;max-width:fit-content}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:read-only):focus~.md3-text-field-label,:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-label{top:0;inset-inline:1em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled{--foreground-color: rgba(var(--md-scheme-on-surface), .38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~.md3-text-field-outline{border:.0625em solid rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~.md3-text-field-label{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~[md3-icon-element]{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-supporting-text-container{display:flex;flex-direction:row;align-items:flex-start;justify-content:space-between;gap:1.333332em;padding:0 1.333332em;font-size:.75em;font-weight:400;line-height:1.333332em;letter-spacing:.033332em;color:var(--label-color)}:host .md3-supporting-text-container.md3-has-error{color:rgb(var(--md-scheme-error))}:host .md3-supporting-text-container .md3-text-input-counter{margin-inline-start:auto}:host .md3-supporting-text-container>::ng-deep *{margin-top:.333332em}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
6023
6022
|
}
|
|
6024
6023
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: TextField, decorators: [{
|
|
6025
6024
|
type: Component,
|
|
@@ -6030,7 +6029,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
6030
6029
|
provide: MD3_BUTTON_CONTEXT,
|
|
6031
6030
|
useExisting: TextField,
|
|
6032
6031
|
},
|
|
6033
|
-
], template: "<label #inputContainer class=\"md3-text-field-container\" [ngClass]=\"{\n 'md3-text-field-filled': fieldType() == 'filled',\n 'md3-text-field-outlined': fieldType() == 'outlined',\n}\">\n <ng-content></ng-content>\n <fieldset aria-hidden=\"true\" class=\"md3-text-field-outline\">\n @if (label() && fieldType() == 'outlined') {\n <legend class=\"md3-label-gap\">{{ label() }}</legend>\n }\n </fieldset>\n @if (label()) {\n <label class=\"md3-text-field-label\">{{ label() }}</label>\n }\n <ng-content select=\"[md3-icon-element=leading]\"></ng-content>\n <ng-content select=\"[md3-icon-button], [md3-icon-element=trailing]\"></ng-content>\n @if (fieldType() != 'outlined') {\n <div class=\"md3-text-field-state\"></div>\n }\n</label>\n<div class=\"md3-supporting-text-container\" [class.md3-has-error]=\"inputError()\">\n <ng-content select=\"[md3-supporting-text]\"></ng-content>\n @if (inputCounter()) {\n <div class=\"md3-text-input-counter\">{{ valueLength() + (maxLength() ? \"/\" + maxLength() : \"\") }}</div>\n }\n</div>\n", styles: [":host{--background-color: rgb(var(--md-scheme-surface-container-highest));--foreground-color: rgb(var(--md-scheme-on-surface));--label-color: rgb(var(--md-scheme-on-surface-variant));--caret-color: rgb(var(--md-scheme-primary));--outline-color: rgb(var(--md-scheme-on-surface-variant));font-size:1rem;width:100%}:host .md3-text-field-container{display:block;position:relative;border-radius:var(--md-border-radius-xsmall) var(--md-border-radius-xsmall) 0 0;overflow:hidden}:host .md3-text-field-container ::ng-deep [md3-icon-element=leading]{position:absolute;font-size:1.5em!important;height:1em!important;width:1em!important;top:.666667em;inset-inline-start:.5em;pointer-events:none;color:var(--label-color)}:host .md3-text-field-container ::ng-deep [md3-icon-element=trailing]{position:absolute;font-size:1.5em!important;height:1em!important;width:1em!important;top:.666667em;inset-inline-end:.5em;pointer-events:none;color:var(--label-color)}:host .md3-text-field-container ::ng-deep [md3-icon-button]{position:absolute;font-size:1em!important;top:.5em;inset-inline-end:.5em}:host .md3-text-field-container .md3-text-field-outline{position:absolute;inset:0;pointer-events:none;padding:0 .625em;margin:.0625em 0 0;border:none;border-bottom:.0625em solid var(--outline-color);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing),border-width none}:host .md3-text-field-container .md3-text-field-outline .md3-label-gap{padding:0;max-width:0em;font-size:.75em;font-weight:400;line-height:1.333332em;letter-spacing:.041667em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;visibility:hidden;transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing);interpolate-size:allow-keywords}:host .md3-text-field-container .md3-text-field-label{position:absolute;top:1em;inset-inline-start:1em;inset-inline-end:1em;padding:0;font-size:1em;font-weight:400;line-height:1.5em;letter-spacing:.03125em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none;color:var(--label-color);transform-origin:top left;transform:scale(1);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-text-field-container .md3-text-field-label:dir(rtl){transform-origin:top right}:host .md3-text-field-container .md3-text-field-state{position:absolute;inset:0;pointer-events:none;border-radius:inherit;background-color:rgba(var(--md-scheme-on-surface));opacity:0;transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-text-field-container ::ng-deep .md3-input-element{display:block;width:100%;border:none;outline:none;padding:1.5em 1em .5em;font-size:1em;font-weight:400;line-height:1.5em;letter-spacing:.03125em;resize:none;background-color:var(--background-color);color:var(--foreground-color);caret-color:var(--caret-color)}:host .md3-text-field-container ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-label{top:.4375em;transform:scale(.75)}:host .md3-text-field-container ::ng-deep .md3-input-element:hover~.md3-text-field-state{opacity:.08}:host .md3-text-field-container ::ng-deep .md3-input-element:hover~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-on-surface))}:host .md3-text-field-container ::ng-deep .md3-input-element:focus~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-primary));border-bottom-width:.1875em}:host .md3-text-field-container ::ng-deep .md3-input-element:focus~.md3-text-field-label{color:var(--caret-color);top:.4375em;transform:scale(.75)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled{--background-color: rgba(var(--md-scheme-surface-container), .4);--foreground-color: rgba(var(--md-scheme-on-surface), .38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-state{display:none}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-outline{border-bottom:.0625em solid rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-label{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~[md3-icon-element]{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]{caret-color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~.md3-text-field-label{color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-element=trailing]{color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-filled{--background-color: rgb(var(--md-scheme-error));--foreground-color: rgb(var(--md-scheme-on-error));--state-color: var(--md-scheme-on-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-tonal{--background-color: rgb(var(--md-scheme-error-container));--foreground-color: rgb(var(--md-scheme-on-error-container));--state-color: var(--md-scheme-on-error-container)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-outlined{--background-color: transparent;--foreground-color: rgb(var(--md-scheme-error));--state-color: var(--md-scheme-error);border-color:var(--md-scheme-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-standard{--background-color: transparent;--foreground-color: rgb(var(--md-scheme-error));--state-color: var(--md-scheme-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~.md3-text-field-label{color:rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~[md3-icon-element=trailing]{color:rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container.md3-has-leading-icon ::ng-deep .md3-input-element{padding-inline-start:3.25em}:host .md3-text-field-container.md3-has-leading-icon .md3-text-field-label{inset-inline-start:3.25em}:host .md3-text-field-container.md3-has-trailing-icon ::ng-deep .md3-input-element{padding-inline-end:3.25em}:host .md3-text-field-container.md3-has-trailing-icon .md3-text-field-label{inset-inline-end:3.25em}:host .md3-text-field-container.md3-text-field-outlined{--background-color: transparent;border-radius:var(--md-border-radius-xsmall);padding-top:.5em}:host .md3-text-field-container.md3-text-field-outlined .md3-text-field-outline{border-radius:inherit;border:.0625em solid var(--outline-color)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep [md3-icon-element=leading],:host .md3-text-field-container.md3-text-field-outlined ::ng-deep [md3-icon-element=trailing],:host .md3-text-field-container.md3-text-field-outlined ::ng-deep [md3-icon-button]{top:1em}:host .md3-text-field-container.md3-text-field-outlined .md3-text-field-label{top:1.5em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element{padding-block:1em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:focus~.md3-text-field-outline{padding:0 .5em;border-width:.1875em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:focus~.md3-text-field-outline .md3-label-gap,:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-outline .md3-label-gap{padding:0 .375em;max-width:fit-content}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:focus~.md3-text-field-label,:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-label{top:0;inset-inline:1em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled{--foreground-color: rgba(var(--md-scheme-on-surface), .38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~.md3-text-field-outline{border:.0625em solid rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~.md3-text-field-label{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~[md3-icon-element]{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-supporting-text-container{display:flex;flex-direction:row;align-items:flex-start;justify-content:space-between;gap:1.333332em;padding:0 1.333332em;font-size:.75em;font-weight:400;line-height:1.333332em;letter-spacing:.033332em;color:var(--label-color)}:host .md3-supporting-text-container.md3-has-error{color:rgb(var(--md-scheme-error))}:host .md3-supporting-text-container .md3-text-input-counter{margin-inline-start:auto}:host .md3-supporting-text-container>::ng-deep *{margin-top:.333332em}\n"] }]
|
|
6032
|
+
], template: "<label #inputContainer class=\"md3-text-field-container\" [ngClass]=\"{\n 'md3-text-field-filled': fieldType() == 'filled',\n 'md3-text-field-outlined': fieldType() == 'outlined',\n}\">\n <ng-content></ng-content>\n <fieldset aria-hidden=\"true\" class=\"md3-text-field-outline\">\n @if (label() && fieldType() == 'outlined') {\n <legend class=\"md3-label-gap\">{{ label() }}</legend>\n }\n </fieldset>\n @if (label()) {\n <span class=\"md3-text-field-label\">{{ label() }}</span>\n }\n <ng-content select=\"[md3-icon-element=leading]\"></ng-content>\n <ng-content select=\"[md3-icon-button], [md3-icon-element=trailing]\"></ng-content>\n @if (fieldType() != 'outlined') {\n <div class=\"md3-text-field-state\"></div>\n }\n</label>\n<div class=\"md3-supporting-text-container\" [class.md3-has-error]=\"inputError()\">\n <ng-content select=\"[md3-supporting-text]\"></ng-content>\n @if (inputCounter()) {\n <div class=\"md3-text-input-counter\">{{ valueLength() + (maxLength() ? \"/\" + maxLength() : \"\") }}</div>\n }\n</div>\n", styles: [":host{--background-color: rgb(var(--md-scheme-surface-container-highest));--foreground-color: rgb(var(--md-scheme-on-surface));--label-color: rgb(var(--md-scheme-on-surface-variant));--caret-color: rgb(var(--md-scheme-primary));--outline-color: rgb(var(--md-scheme-on-surface-variant));font-size:1rem;width:100%}:host .md3-text-field-container{display:block;position:relative;border-radius:var(--md-border-radius-xsmall) var(--md-border-radius-xsmall) 0 0;overflow:hidden}:host .md3-text-field-container>::ng-deep [md3-icon-element=leading]{position:absolute;font-size:1.5em!important;height:1em!important;width:1em!important;top:.666667em;inset-inline-start:.5em;pointer-events:none;color:var(--label-color)}:host .md3-text-field-container>::ng-deep [md3-icon-element=trailing]{position:absolute;font-size:1.5em!important;height:1em!important;width:1em!important;top:.666667em;inset-inline-end:.5em;pointer-events:none;color:var(--label-color)}:host .md3-text-field-container>::ng-deep [md3-icon-button]{position:absolute;font-size:1em!important;top:.5em;inset-inline-end:.5em}:host .md3-text-field-container .md3-text-field-outline{position:absolute;inset:0;pointer-events:none;padding:0 .625em;margin:.0625em 0 0;border:none;border-bottom:.0625em solid var(--outline-color);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing),border-width none}:host .md3-text-field-container .md3-text-field-outline .md3-label-gap{padding:0;max-width:0em;font-size:.75em;font-weight:400;line-height:1.333332em;letter-spacing:.041667em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;visibility:hidden;transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing);interpolate-size:allow-keywords}:host .md3-text-field-container .md3-text-field-label{position:absolute;top:1em;inset-inline-start:1em;inset-inline-end:1em;padding:0;font-size:1em;font-weight:400;line-height:1.5em;letter-spacing:.03125em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none;color:var(--label-color);transform-origin:top left;transform:scale(1);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-text-field-container .md3-text-field-label:dir(rtl){transform-origin:top right}:host .md3-text-field-container .md3-text-field-state{position:absolute;inset:0;pointer-events:none;border-radius:inherit;background-color:rgba(var(--md-scheme-on-surface));opacity:0;transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-text-field-container ::ng-deep .md3-input-element{display:block;width:100%;border:none;outline:none;padding:1.5em 1em .5em;font-size:1em;font-weight:400;line-height:1.5em;letter-spacing:.03125em;resize:none;background-color:var(--background-color);color:var(--foreground-color);caret-color:var(--caret-color)}:host .md3-text-field-container ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-label{top:.4375em;transform:scale(.75)}:host .md3-text-field-container ::ng-deep .md3-input-element:hover~.md3-text-field-state{opacity:.08}:host .md3-text-field-container ::ng-deep .md3-input-element:hover~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-on-surface))}:host .md3-text-field-container ::ng-deep .md3-input-element:focus~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-primary));border-bottom-width:.1875em}:host .md3-text-field-container ::ng-deep .md3-input-element:focus:not(:read-only)~.md3-text-field-label{color:var(--caret-color);top:.4375em;transform:scale(.75)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled{--background-color: rgba(var(--md-scheme-surface-container), .4);--foreground-color: rgba(var(--md-scheme-on-surface), .38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-state{display:none}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-outline{border-bottom:.0625em solid rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~.md3-text-field-label{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element:disabled~[md3-icon-element]{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]{caret-color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~.md3-text-field-label{color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-element=trailing]{color:rgb(var(--md-scheme-error))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-filled{--background-color: rgb(var(--md-scheme-error));--foreground-color: rgb(var(--md-scheme-on-error));--state-color: var(--md-scheme-on-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-tonal{--background-color: rgb(var(--md-scheme-error-container));--foreground-color: rgb(var(--md-scheme-on-error-container));--state-color: var(--md-scheme-on-error-container)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-outlined{--background-color: transparent;--foreground-color: rgb(var(--md-scheme-error));--state-color: var(--md-scheme-error);border-color:var(--md-scheme-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]~[md3-icon-button].md3-standard{--background-color: transparent;--foreground-color: rgb(var(--md-scheme-error));--state-color: var(--md-scheme-error)}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~.md3-text-field-outline{--outline-color: rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~.md3-text-field-label{color:rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container ::ng-deep .md3-input-element[aria-invalid=true]:hover~[md3-icon-element=trailing]{color:rgb(var(--md-scheme-on-error-container))}:host .md3-text-field-container.md3-has-leading-icon ::ng-deep .md3-input-element{padding-inline-start:3.25em}:host .md3-text-field-container.md3-has-leading-icon .md3-text-field-label{inset-inline-start:3.25em}:host .md3-text-field-container.md3-has-trailing-icon ::ng-deep .md3-input-element{padding-inline-end:3.25em}:host .md3-text-field-container.md3-has-trailing-icon .md3-text-field-label{inset-inline-end:3.25em}:host .md3-text-field-container.md3-text-field-outlined{--background-color: transparent;border-radius:var(--md-border-radius-xsmall);padding-top:.5em}:host .md3-text-field-container.md3-text-field-outlined .md3-text-field-outline{border-radius:inherit;border:.0625em solid var(--outline-color)}:host .md3-text-field-container.md3-text-field-outlined>::ng-deep [md3-icon-element=leading],:host .md3-text-field-container.md3-text-field-outlined>::ng-deep [md3-icon-element=trailing],:host .md3-text-field-container.md3-text-field-outlined>::ng-deep [md3-icon-button]{top:1em}:host .md3-text-field-container.md3-text-field-outlined .md3-text-field-label{top:1.5em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element{padding-block:1em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:focus~.md3-text-field-outline{padding:0 .5em;border-width:.1875em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:read-only):focus~.md3-text-field-outline .md3-label-gap,:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-outline .md3-label-gap{padding:0 .375em;max-width:fit-content}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:read-only):focus~.md3-text-field-label,:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:not(:placeholder-shown)~.md3-text-field-label{top:0;inset-inline:1em}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled{--foreground-color: rgba(var(--md-scheme-on-surface), .38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~.md3-text-field-outline{border:.0625em solid rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~.md3-text-field-label{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-text-field-container.md3-text-field-outlined ::ng-deep .md3-input-element:disabled~[md3-icon-element]{color:rgba(var(--md-scheme-on-surface),.38)}:host .md3-supporting-text-container{display:flex;flex-direction:row;align-items:flex-start;justify-content:space-between;gap:1.333332em;padding:0 1.333332em;font-size:.75em;font-weight:400;line-height:1.333332em;letter-spacing:.033332em;color:var(--label-color)}:host .md3-supporting-text-container.md3-has-error{color:rgb(var(--md-scheme-error))}:host .md3-supporting-text-container .md3-text-input-counter{margin-inline-start:auto}:host .md3-supporting-text-container>::ng-deep *{margin-top:.333332em}\n"] }]
|
|
6034
6033
|
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], fieldType: [{ type: i0.Input, args: [{ isSignal: true, alias: "field-type", required: false }] }], inputCounter: [{ type: i0.Input, args: [{ isSignal: true, alias: "input-counter", required: false }] }], control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: false }] }], inputContainer: [{ type: i0.ViewChild, args: ['inputContainer', { isSignal: true }] }], input: [{ type: i0.ContentChild, args: [i0.forwardRef(() => InputElement), { isSignal: true }] }], iconElements: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => IconElement), { ...{ descendants: true }, isSignal: true }] }], iconButtons: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => IconButton), { ...{ descendants: true }, isSignal: true }] }], controlName: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FormControlName), { isSignal: true }] }] } });
|
|
6035
6034
|
|
|
6036
6035
|
class SupportingText {
|
|
@@ -6047,1207 +6046,1363 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
6047
6046
|
}]
|
|
6048
6047
|
}] });
|
|
6049
6048
|
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6049
|
+
class MenuGroup {
|
|
6050
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6051
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type: MenuGroup, isStandalone: true, selector: "md3-menu-group", host: { attributes: { "role": "group" } }, ngImport: i0, template: "<ng-content></ng-content>\n", styles: [":host{display:flex;flex-direction:column;gap:.125em;padding:.25em;background-color:var(--background-color);color:var(--foreground-color);border-radius:var(--menu-group-radius);box-shadow:var(--menu-group-shadow)}:host:first-child{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius)}:host:last-child{border-end-start-radius:var(--border-radius);border-end-end-radius:var(--border-radius)}:host ::ng-deep md3-divider{margin:.125em .5em}:host ::ng-deep [md3-menu-item]:first-child .md3-menu-item-container{--border-top-start-r: var(--md-border-radius-medium);--border-top-end-r: var(--md-border-radius-medium);border-start-start-radius:var(--border-top-start-r);border-start-end-radius:var(--border-top-end-r)}:host ::ng-deep [md3-menu-item]:last-child .md3-menu-item-container{--border-bottom-start-r: var(--md-border-radius-medium);--border-bottom-end-r: var(--md-border-radius-medium);border-end-start-radius:var(--border-bottom-start-r);border-end-end-radius:var(--border-bottom-end-r)}.md3-menu-group-label{padding:.5rem var(--menu-item-inline-padding, .75rem) .25rem;color:rgb(var(--md-scheme-on-surface-variant));font-size:.75rem;font-weight:500;line-height:1rem;letter-spacing:.03125rem}\n"] });
|
|
6052
|
+
}
|
|
6053
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuGroup, decorators: [{
|
|
6054
|
+
type: Component,
|
|
6055
|
+
args: [{ selector: 'md3-menu-group', imports: [], host: {
|
|
6056
|
+
'role': 'group',
|
|
6057
|
+
}, template: "<ng-content></ng-content>\n", styles: [":host{display:flex;flex-direction:column;gap:.125em;padding:.25em;background-color:var(--background-color);color:var(--foreground-color);border-radius:var(--menu-group-radius);box-shadow:var(--menu-group-shadow)}:host:first-child{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius)}:host:last-child{border-end-start-radius:var(--border-radius);border-end-end-radius:var(--border-radius)}:host ::ng-deep md3-divider{margin:.125em .5em}:host ::ng-deep [md3-menu-item]:first-child .md3-menu-item-container{--border-top-start-r: var(--md-border-radius-medium);--border-top-end-r: var(--md-border-radius-medium);border-start-start-radius:var(--border-top-start-r);border-start-end-radius:var(--border-top-end-r)}:host ::ng-deep [md3-menu-item]:last-child .md3-menu-item-container{--border-bottom-start-r: var(--md-border-radius-medium);--border-bottom-end-r: var(--md-border-radius-medium);border-end-start-radius:var(--border-bottom-start-r);border-end-end-radius:var(--border-bottom-end-r)}.md3-menu-group-label{padding:.5rem var(--menu-item-inline-padding, .75rem) .25rem;color:rgb(var(--md-scheme-on-surface-variant));font-size:.75rem;font-weight:500;line-height:1rem;letter-spacing:.03125rem}\n"] }]
|
|
6058
|
+
}] });
|
|
6059
|
+
|
|
6060
|
+
class MenuItem {
|
|
6061
|
+
el;
|
|
6062
|
+
label = input('', { ...(ngDevMode ? { debugName: "label" } : /* istanbul ignore next */ {}), alias: 'label' });
|
|
6063
|
+
supportingText = input(null, { ...(ngDevMode ? { debugName: "supportingText" } : /* istanbul ignore next */ {}), alias: 'supporting-text' });
|
|
6064
|
+
trailingText = input(null, { ...(ngDevMode ? { debugName: "trailingText" } : /* istanbul ignore next */ {}), alias: 'trailing-text' });
|
|
6065
|
+
selected = model(null, { ...(ngDevMode ? { debugName: "selected" } : /* istanbul ignore next */ {}), alias: 'selected' });
|
|
6066
|
+
iconElements = contentChildren(IconElement, /* @ts-ignore */
|
|
6067
|
+
...(ngDevMode ? [{ debugName: "iconElements" }] : /* istanbul ignore next */ []));
|
|
6068
|
+
get leading() {
|
|
6069
|
+
return this.iconElements().find((icon) => icon.iconType() === 'leading');
|
|
6063
6070
|
}
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
* once the dialog it replaces has had its head start. The animation runs on
|
|
6067
|
-
* the next frame so the surface has a real from/to state.
|
|
6068
|
-
*/
|
|
6069
|
-
startEnterAnimation() {
|
|
6070
|
-
requestAnimationFrame(() => {
|
|
6071
|
-
this.isActive.set(true);
|
|
6072
|
-
});
|
|
6071
|
+
get trailing() {
|
|
6072
|
+
return this.iconElements().find((icon) => icon.iconType() === 'trailing');
|
|
6073
6073
|
}
|
|
6074
|
-
|
|
6075
|
-
this.
|
|
6074
|
+
get showLeadingIcon() {
|
|
6075
|
+
return (!!this.leading && !this.selected()) || this.selected() == true;
|
|
6076
6076
|
}
|
|
6077
|
-
|
|
6078
|
-
this.
|
|
6077
|
+
onHostClick() {
|
|
6078
|
+
const selected = this.selected();
|
|
6079
|
+
if (selected === null) {
|
|
6080
|
+
return;
|
|
6081
|
+
}
|
|
6082
|
+
this.selected.set(!selected);
|
|
6079
6083
|
}
|
|
6080
|
-
|
|
6081
|
-
|
|
6084
|
+
constructor(el) {
|
|
6085
|
+
this.el = el;
|
|
6086
|
+
}
|
|
6087
|
+
get element() {
|
|
6088
|
+
return this.el.nativeElement;
|
|
6089
|
+
}
|
|
6090
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuItem, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
6091
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: MenuItem, isStandalone: true, selector: "button[md3-menu-item], a[md3-menu-item]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, supportingText: { classPropertyName: "supportingText", publicName: "supporting-text", isSignal: true, isRequired: false, transformFunction: null }, trailingText: { classPropertyName: "trailingText", publicName: "trailing-text", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange" }, host: { listeners: { "click": "onHostClick()" } }, queries: [{ propertyName: "iconElements", predicate: IconElement, isSignal: true }], ngImport: i0, template: "@if (selected() !== null) {\n <input type=\"checkbox\" md3-input-element [checked]=\"selected()\">\n}\n\n<div class=\"md3-menu-item-container\" md3-state-component>\n <div class=\"md3-menu-item-leading\" [class.has-icon]=\"showLeadingIcon\">\n <ng-content select=\"[md3-icon-element=leading]\"></ng-content>\n @if (!leading) {\n <md3-icon>check</md3-icon>\n }\n </div>\n\n <div class=\"md3-menu-item-content\">\n <md3-type-label size=\"large\">{{ label() }}</md3-type-label>\n @if (supportingText()?.length) {\n <md3-type-body size=\"small\">{{ supportingText() }}</md3-type-body>\n }\n </div>\n\n <div class=\"md3-menu-item-trailing\">\n <ng-content select=\"md3-badge\"></ng-content>\n @if (trailingText()?.length) {\n <md3-type-title size=\"small\">{{ trailingText() }}</md3-type-title>\n }\n <ng-content select=\"[md3-icon-element=trailing]\"></ng-content>\n </div>\n</div>", styles: [":host{--state-color: var(--menu-item-state-color);--border-radius: var(--menu-item-border-radius);--outline-color: var(--menu-item-outline-color);--outline-width: var(--menu-item-outline-width);--outline-offset: var(--menu-item-outline-offset);position:relative;display:block;padding:0;border:0;background:transparent;color:var(--menu-item-label-color);font:inherit;text-align:start;text-decoration:none;cursor:pointer;outline:none;appearance:none;-webkit-user-select:none;user-select:none;z-index:0}:host:focus{z-index:1}:host:focus:not(:hover) .md3-menu-item-container:after{opacity:1}:host:active{z-index:2}:host:active .md3-menu-item-container:after{opacity:0}:host .md3-menu-item-container{display:flex;align-items:center;min-height:3em;padding:0 .75em;border-radius:var(--border-radius);transition:background-color var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing),color var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-menu-item-container .md3-menu-item-leading{display:inline-flex;align-items:center;justify-content:center;font-size:inherit;opacity:0;transform:scale(1.2);width:0;height:1.25em;color:var(--menu-item-supporting-color);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-menu-item-container .md3-menu-item-leading ::ng-deep [md3-icon-element]{font-size:1.25em!important;height:1em!important;width:1em!important;line-height:1em!important}:host .md3-menu-item-container .md3-menu-item-leading.has-icon{margin-inline-end:.5em;opacity:1;transform:scale(1);height:1.25em;width:1.25em}:host .md3-menu-item-container .md3-menu-item-trailing{flex:0 1 content;display:inline-flex;gap:.5em;align-items:center;justify-content:center;font-size:inherit;margin-inline-start:.5em;color:var(--menu-item-supporting-color)}:host .md3-menu-item-container .md3-menu-item-trailing:empty{margin:0}:host .md3-menu-item-container .md3-menu-item-trailing ::ng-deep md3-badge{background-color:var(--menu-item-badge-background);color:var(--menu-item-badge-foreground)}:host .md3-menu-item-container .md3-menu-item-trailing .md3-text-title.md3-text-small{margin:0;padding:0;white-space:nowrap;letter-spacing:.007143em}:host .md3-menu-item-container .md3-menu-item-trailing ::ng-deep [md3-icon-element]{font-size:1.25em!important;height:1em!important;width:1em!important;line-height:1em!important}:host .md3-menu-item-container .md3-menu-item-content{flex:1 1 auto}:host .md3-menu-item-container .md3-menu-item-content .md3-text-label.md3-text-large{display:block;margin:0;padding:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:.007143em;color:var(--menu-item-label-color)}:host .md3-menu-item-container .md3-menu-item-content .md3-text-body.md3-text-small{display:block;margin:0;padding:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:.0333334em;color:var(--menu-item-supporting-color)}:host [md3-input-element]{position:absolute;height:0;width:0;opacity:0;pointer-events:none}:host [md3-input-element]+.md3-menu-item-container .md3-menu-item-leading{opacity:0;transform:scale(1.2);width:0}:host [md3-input-element]:checked+.md3-menu-item-container{--menu-item-label-color: var(--menu-item-selected-foreground);--menu-item-supporting-color: var(--menu-item-selected-foreground);--border-radius: var(--md-border-radius-medium);background-color:var(--menu-item-selected-background)}:host [md3-input-element]:checked+.md3-menu-item-container .md3-menu-item-leading{opacity:1;transform:scale(1);width:1.25em}:host:disabled{cursor:default}:host:disabled .md3-menu-item-container{--menu-item-label-color: var(--menu-item-label-color);--menu-item-supporting-color: var(--menu-item-label-color);--menu-item-selected-background: transparent;--menu-item-selected-foreground: var(--menu-item-label-color);pointer-events:none;opacity:.38}:host:disabled .md3-menu-item-container.md3-state-layer,:host:disabled .md3-menu-item-container:after{display:none}\n"], dependencies: [{ kind: "directive", type: InputElement, selector: "[md3-input-element]" }, { kind: "directive", type: StateComponent, selector: "[md3-state-component]" }, { kind: "component", type: MaterialIcon, selector: "md3-icon", inputs: ["icon-version", "filled", "icon-style", "icon-size", "bi-directional"] }, { kind: "directive", type: TypeLabel, selector: "md3-type-label, [md3-type-label]", inputs: ["size", "color", "emphasized"] }, { kind: "directive", type: TypeBody, selector: "md3-type-body, [md3-type-body]", inputs: ["size", "color", "emphasized"] }, { kind: "directive", type: TypeTitle, selector: "md3-type-title, [md3-type-title]", inputs: ["size", "color", "emphasized"] }] });
|
|
6082
6092
|
}
|
|
6083
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type:
|
|
6093
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuItem, decorators: [{
|
|
6084
6094
|
type: Component,
|
|
6085
|
-
args: [{ selector: 'md3-
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6095
|
+
args: [{ selector: 'button[md3-menu-item], a[md3-menu-item]', imports: [
|
|
6096
|
+
InputElement,
|
|
6097
|
+
StateComponent,
|
|
6098
|
+
MaterialIcon,
|
|
6099
|
+
TypeLabel,
|
|
6100
|
+
TypeBody,
|
|
6101
|
+
TypeTitle,
|
|
6102
|
+
], host: {
|
|
6103
|
+
'(click)': 'onHostClick()',
|
|
6104
|
+
}, template: "@if (selected() !== null) {\n <input type=\"checkbox\" md3-input-element [checked]=\"selected()\">\n}\n\n<div class=\"md3-menu-item-container\" md3-state-component>\n <div class=\"md3-menu-item-leading\" [class.has-icon]=\"showLeadingIcon\">\n <ng-content select=\"[md3-icon-element=leading]\"></ng-content>\n @if (!leading) {\n <md3-icon>check</md3-icon>\n }\n </div>\n\n <div class=\"md3-menu-item-content\">\n <md3-type-label size=\"large\">{{ label() }}</md3-type-label>\n @if (supportingText()?.length) {\n <md3-type-body size=\"small\">{{ supportingText() }}</md3-type-body>\n }\n </div>\n\n <div class=\"md3-menu-item-trailing\">\n <ng-content select=\"md3-badge\"></ng-content>\n @if (trailingText()?.length) {\n <md3-type-title size=\"small\">{{ trailingText() }}</md3-type-title>\n }\n <ng-content select=\"[md3-icon-element=trailing]\"></ng-content>\n </div>\n</div>", styles: [":host{--state-color: var(--menu-item-state-color);--border-radius: var(--menu-item-border-radius);--outline-color: var(--menu-item-outline-color);--outline-width: var(--menu-item-outline-width);--outline-offset: var(--menu-item-outline-offset);position:relative;display:block;padding:0;border:0;background:transparent;color:var(--menu-item-label-color);font:inherit;text-align:start;text-decoration:none;cursor:pointer;outline:none;appearance:none;-webkit-user-select:none;user-select:none;z-index:0}:host:focus{z-index:1}:host:focus:not(:hover) .md3-menu-item-container:after{opacity:1}:host:active{z-index:2}:host:active .md3-menu-item-container:after{opacity:0}:host .md3-menu-item-container{display:flex;align-items:center;min-height:3em;padding:0 .75em;border-radius:var(--border-radius);transition:background-color var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing),color var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-menu-item-container .md3-menu-item-leading{display:inline-flex;align-items:center;justify-content:center;font-size:inherit;opacity:0;transform:scale(1.2);width:0;height:1.25em;color:var(--menu-item-supporting-color);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-menu-item-container .md3-menu-item-leading ::ng-deep [md3-icon-element]{font-size:1.25em!important;height:1em!important;width:1em!important;line-height:1em!important}:host .md3-menu-item-container .md3-menu-item-leading.has-icon{margin-inline-end:.5em;opacity:1;transform:scale(1);height:1.25em;width:1.25em}:host .md3-menu-item-container .md3-menu-item-trailing{flex:0 1 content;display:inline-flex;gap:.5em;align-items:center;justify-content:center;font-size:inherit;margin-inline-start:.5em;color:var(--menu-item-supporting-color)}:host .md3-menu-item-container .md3-menu-item-trailing:empty{margin:0}:host .md3-menu-item-container .md3-menu-item-trailing ::ng-deep md3-badge{background-color:var(--menu-item-badge-background);color:var(--menu-item-badge-foreground)}:host .md3-menu-item-container .md3-menu-item-trailing .md3-text-title.md3-text-small{margin:0;padding:0;white-space:nowrap;letter-spacing:.007143em}:host .md3-menu-item-container .md3-menu-item-trailing ::ng-deep [md3-icon-element]{font-size:1.25em!important;height:1em!important;width:1em!important;line-height:1em!important}:host .md3-menu-item-container .md3-menu-item-content{flex:1 1 auto}:host .md3-menu-item-container .md3-menu-item-content .md3-text-label.md3-text-large{display:block;margin:0;padding:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:.007143em;color:var(--menu-item-label-color)}:host .md3-menu-item-container .md3-menu-item-content .md3-text-body.md3-text-small{display:block;margin:0;padding:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:.0333334em;color:var(--menu-item-supporting-color)}:host [md3-input-element]{position:absolute;height:0;width:0;opacity:0;pointer-events:none}:host [md3-input-element]+.md3-menu-item-container .md3-menu-item-leading{opacity:0;transform:scale(1.2);width:0}:host [md3-input-element]:checked+.md3-menu-item-container{--menu-item-label-color: var(--menu-item-selected-foreground);--menu-item-supporting-color: var(--menu-item-selected-foreground);--border-radius: var(--md-border-radius-medium);background-color:var(--menu-item-selected-background)}:host [md3-input-element]:checked+.md3-menu-item-container .md3-menu-item-leading{opacity:1;transform:scale(1);width:1.25em}:host:disabled{cursor:default}:host:disabled .md3-menu-item-container{--menu-item-label-color: var(--menu-item-label-color);--menu-item-supporting-color: var(--menu-item-label-color);--menu-item-selected-background: transparent;--menu-item-selected-foreground: var(--menu-item-label-color);pointer-events:none;opacity:.38}:host:disabled .md3-menu-item-container.md3-state-layer,:host:disabled .md3-menu-item-container:after{display:none}\n"] }]
|
|
6105
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], supportingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "supporting-text", required: false }] }], trailingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailing-text", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }, { type: i0.Output, args: ["selectedChange"] }], iconElements: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => IconElement), { isSignal: true }] }] } });
|
|
6089
6106
|
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
...(ngDevMode ? [{ debugName: "surface" }] : /* istanbul ignore next */ []));
|
|
6102
|
-
mainPane = viewChild('mainPane', /* @ts-ignore */
|
|
6103
|
-
...(ngDevMode ? [{ debugName: "mainPane" }] : /* istanbul ignore next */ []));
|
|
6104
|
-
startOutlet = viewChild('startOutlet', { ...(ngDevMode ? { debugName: "startOutlet" } : /* istanbul ignore next */ {}), read: CdkPortalOutlet });
|
|
6105
|
-
endOutlet = viewChild('endOutlet', { ...(ngDevMode ? { debugName: "endOutlet" } : /* istanbul ignore next */ {}), read: CdkPortalOutlet });
|
|
6106
|
-
sheets = inject(SheetsService);
|
|
6107
|
-
/** True while the shell holds the side sheet outlets, which happens without a layout only. */
|
|
6108
|
-
ownsSideSheetOutlets = false;
|
|
6109
|
-
isActive = signal(false, /* @ts-ignore */
|
|
6110
|
-
...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
|
|
6111
|
-
config = inject(DIALOG_CONFIG, { optional: true }) ?? {};
|
|
6112
|
-
get surfaceElement() {
|
|
6113
|
-
return this.surface()?.nativeElement ?? null;
|
|
6114
|
-
}
|
|
6115
|
-
ngAfterViewInit() {
|
|
6116
|
-
// The content is attached by now, so the layout it brings has already taken the
|
|
6117
|
-
// outlets. Its panes sit under the bar regions, which is where a side sheet belongs.
|
|
6118
|
-
const layout = this.findContentLayout();
|
|
6119
|
-
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
6120
|
-
this.checkContentLayout(layout);
|
|
6121
|
-
}
|
|
6122
|
-
if (layout) {
|
|
6107
|
+
class SelectOptions {
|
|
6108
|
+
options = input.required(/* @ts-ignore */
|
|
6109
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
6110
|
+
multiple = input(false, /* @ts-ignore */
|
|
6111
|
+
...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
6112
|
+
/** Emits the values selected by the user. The field owns the selection state. */
|
|
6113
|
+
selectionChange = output();
|
|
6114
|
+
optionClick(index) {
|
|
6115
|
+
const options = this.options();
|
|
6116
|
+
const option = options.at(index);
|
|
6117
|
+
if (!option) {
|
|
6123
6118
|
return;
|
|
6124
6119
|
}
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
const startOutlet = this.startOutlet();
|
|
6128
|
-
const endOutlet = this.endOutlet();
|
|
6129
|
-
if (startOutlet) {
|
|
6130
|
-
this.sheets.registerSideSheetOutlet('start', startOutlet);
|
|
6131
|
-
}
|
|
6132
|
-
if (endOutlet) {
|
|
6133
|
-
this.sheets.registerSideSheetOutlet('end', endOutlet);
|
|
6120
|
+
if (this.multiple()) {
|
|
6121
|
+
option.selected = !(option.selected ?? false);
|
|
6134
6122
|
}
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
const startOutlet = this.startOutlet();
|
|
6140
|
-
const endOutlet = this.endOutlet();
|
|
6141
|
-
if (startOutlet) {
|
|
6142
|
-
this.sheets.unregisterSideSheetOutlet('start', startOutlet);
|
|
6143
|
-
}
|
|
6144
|
-
if (endOutlet) {
|
|
6145
|
-
this.sheets.unregisterSideSheetOutlet('end', endOutlet);
|
|
6146
|
-
}
|
|
6147
|
-
this.ownsSideSheetOutlets = false;
|
|
6123
|
+
else {
|
|
6124
|
+
options.forEach((item, i) => {
|
|
6125
|
+
item.selected = i == index;
|
|
6126
|
+
});
|
|
6148
6127
|
}
|
|
6149
|
-
|
|
6128
|
+
this.selectionChange.emit(options.filter((item) => item.selected).map((item) => item.value));
|
|
6150
6129
|
}
|
|
6130
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SelectOptions, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6131
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: SelectOptions, isStandalone: true, selector: "md3-select-options", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, ngImport: i0, template: "<md3-menu-group class=\"md3-scrollable\">\n @for (item of options(); track `${$index}-${item.value}`) {\n <button\n md3-menu-item\n [selected]=\"item.selected ?? false\"\n [label]=\"item.label\"\n [supporting-text]=\"item.supportingText ?? null\"\n [trailing-text]=\"item.trailingText ?? null\"\n (click)=\"optionClick($index)\"\n >\n </button>\n }\n</md3-menu-group>", styles: [":host{max-height:inherit}:host md3-menu-group.md3-scrollable{padding:.5em .375em;max-height:inherit;overflow-y:auto}\n"], dependencies: [{ kind: "component", type: MenuGroup, selector: "md3-menu-group" }, { kind: "component", type: MenuItem, selector: "button[md3-menu-item], a[md3-menu-item]", inputs: ["label", "supporting-text", "trailing-text", "selected"], outputs: ["selectedChange"] }] });
|
|
6132
|
+
}
|
|
6133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SelectOptions, decorators: [{
|
|
6134
|
+
type: Component,
|
|
6135
|
+
args: [{ selector: 'md3-select-options', imports: [
|
|
6136
|
+
MenuGroup,
|
|
6137
|
+
MenuItem,
|
|
6138
|
+
], template: "<md3-menu-group class=\"md3-scrollable\">\n @for (item of options(); track `${$index}-${item.value}`) {\n <button\n md3-menu-item\n [selected]=\"item.selected ?? false\"\n [label]=\"item.label\"\n [supporting-text]=\"item.supportingText ?? null\"\n [trailing-text]=\"item.trailingText ?? null\"\n (click)=\"optionClick($index)\"\n >\n </button>\n }\n</md3-menu-group>", styles: [":host{max-height:inherit}:host md3-menu-group.md3-scrollable{padding:.5em .375em;max-height:inherit;overflow-y:auto}\n"] }]
|
|
6139
|
+
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
6140
|
+
|
|
6141
|
+
const MENU_DATA = new InjectionToken('MD3_MENU_DATA');
|
|
6142
|
+
const MENU_CONFIG = new InjectionToken('MD3_MENU_CONFIG');
|
|
6143
|
+
const MENU_COMPONENT = new InjectionToken('MD3_MENU_COMPONENT');
|
|
6144
|
+
const MENU_EXIT_ANIMATION_FALLBACK_MS = 300;
|
|
6145
|
+
class MenuRef {
|
|
6146
|
+
overlayRef;
|
|
6147
|
+
previouslyFocusedElement;
|
|
6148
|
+
closed = new Subject();
|
|
6149
|
+
isClosed = false;
|
|
6150
|
+
menuInstance;
|
|
6151
6151
|
/**
|
|
6152
|
-
*
|
|
6153
|
-
*
|
|
6154
|
-
* The root is either the layout itself, or the component that holds it — a dialog is
|
|
6155
|
-
* normally opened with a component whose own template starts with `md3-layout`.
|
|
6152
|
+
* Filled by MenuService after the user component is attached. Keeping the
|
|
6153
|
+
* instance here lets callers imperatively update inputs when that is useful.
|
|
6156
6154
|
*/
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
}
|
|
6162
|
-
if (content.tagName === 'MD3-LAYOUT') {
|
|
6163
|
-
return content;
|
|
6164
|
-
}
|
|
6165
|
-
const root = content.firstElementChild;
|
|
6166
|
-
return root?.tagName === 'MD3-LAYOUT' ? root : null;
|
|
6155
|
+
componentInstance;
|
|
6156
|
+
constructor(overlayRef, previouslyFocusedElement) {
|
|
6157
|
+
this.overlayRef = overlayRef;
|
|
6158
|
+
this.previouslyFocusedElement = previouslyFocusedElement;
|
|
6167
6159
|
}
|
|
6168
|
-
|
|
6169
|
-
if (
|
|
6160
|
+
close(result) {
|
|
6161
|
+
if (this.isClosed) {
|
|
6170
6162
|
return;
|
|
6171
6163
|
}
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
this.
|
|
6164
|
+
this.isClosed = true;
|
|
6165
|
+
this.startCloseAnimation().then(() => {
|
|
6166
|
+
// Disposing the overlay removes the wrapper, the backdrop, and the
|
|
6167
|
+
// dynamically attached content component in one operation.
|
|
6168
|
+
this.overlayRef.dispose();
|
|
6169
|
+
// this.previouslyFocusedElement?.focus();
|
|
6170
|
+
this.closed.next(result);
|
|
6171
|
+
this.closed.complete();
|
|
6179
6172
|
});
|
|
6180
6173
|
}
|
|
6181
|
-
|
|
6182
|
-
this.
|
|
6174
|
+
startCloseAnimation() {
|
|
6175
|
+
let panel = this.overlayRef.overlayElement;
|
|
6176
|
+
let animatedElement = panel.querySelector('.md3-menu-container') ?? panel;
|
|
6177
|
+
panel.classList.add('md3-menu-closing');
|
|
6178
|
+
this.menuInstance?.showMenu(false);
|
|
6179
|
+
return new Promise((resolve) => {
|
|
6180
|
+
let isResolved = false;
|
|
6181
|
+
let timeoutId = setTimeout(done, MENU_EXIT_ANIMATION_FALLBACK_MS);
|
|
6182
|
+
function done() {
|
|
6183
|
+
if (isResolved) {
|
|
6184
|
+
return;
|
|
6185
|
+
}
|
|
6186
|
+
isResolved = true;
|
|
6187
|
+
clearTimeout(timeoutId);
|
|
6188
|
+
animatedElement.removeEventListener('transitionend', onTransitionEnd);
|
|
6189
|
+
resolve();
|
|
6190
|
+
}
|
|
6191
|
+
function onTransitionEnd(event) {
|
|
6192
|
+
if (event.target === animatedElement) {
|
|
6193
|
+
done();
|
|
6194
|
+
}
|
|
6195
|
+
}
|
|
6196
|
+
animatedElement.addEventListener('transitionend', onTransitionEnd);
|
|
6197
|
+
});
|
|
6183
6198
|
}
|
|
6184
|
-
|
|
6185
|
-
this.
|
|
6199
|
+
afterClosed() {
|
|
6200
|
+
return this.closed.asObservable();
|
|
6186
6201
|
}
|
|
6187
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: FullScreenDialog, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
6188
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: FullScreenDialog, isStandalone: true, selector: "md3-fullscreen-dialog", viewQueries: [{ propertyName: "surface", first: true, predicate: ["surface"], descendants: true, isSignal: true }, { propertyName: "mainPane", first: true, predicate: ["mainPane"], descendants: true, isSignal: true }, { propertyName: "startOutlet", first: true, predicate: ["startOutlet"], descendants: true, read: CdkPortalOutlet, isSignal: true }, { propertyName: "endOutlet", first: true, predicate: ["endOutlet"], descendants: true, read: CdkPortalOutlet, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- The role and aria attributes live on the host element, applied by the CDK dialog container. -->\n<div\n #surface\n class=\"md3-fullscreen-dialog-container\"\n [class.md3-active]=\"isActive()\"\n [class.md-scheme-dark]=\"config.scheme == 'dark'\"\n [class.md-scheme-light]=\"config.scheme == 'light'\"\n [attr.dir]=\"config.direction ?? null\">\n <div class=\"md3-panes-container md3-scrollable\">\n <!--\n The CDK attaches the dialog content to the first portal outlet of\n this template, so the main pane has to come first. The panes are\n placed by grid area, which makes the DOM order irrelevant visually.\n -->\n <div class=\"md3-pane md3-pane-main\" #mainPane>\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n <div class=\"md3-pane md3-pane-start\">\n <ng-template #startOutlet cdkPortalOutlet></ng-template>\n </div>\n <div class=\"md3-pane md3-pane-end\">\n <ng-template #endOutlet cdkPortalOutlet></ng-template>\n </div>\n </div>\n</div>\n", styles: ["::ng-deep .cdk-overlay-container{position:fixed;z-index:1000;inset:0;pointer-events:none;font-size:1rem}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper{position:absolute;display:flex;inset:0;pointer-events:none;overflow:hidden}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper:has(>.md3-fullscreen-dialog-panel){padding:0}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel{width:100%;height:100%;max-width:none;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel.md3-dialog-closing,::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel.md3-dialog-hidden{pointer-events:none}:host{display:block;height:100%;width:100%;outline:0}:host .md3-fullscreen-dialog-container{display:grid;grid-template-rows:minmax(0,1fr);height:100%;min-height:0;overflow:hidden;color:rgb(var(--md-scheme-on-surface));background-color:rgb(var(--md-scheme-surface));transition:all var(--md-motion-expressive-default-spatial-duration) var(--md-motion-expressive-default-spatial-easing);opacity:0;transform:translateY(1.5em)}:host .md3-fullscreen-dialog-container.md3-active{opacity:1;transform:none}:host .md3-panes-container{display:grid;grid-template-areas:\"start main end\";grid-template-columns:auto minmax(0,1fr) auto;grid-template-rows:minmax(0,1fr);min-width:0;min-height:0;overflow:hidden}:host .md3-panes-container .md3-pane{justify-self:stretch;align-self:stretch;min-width:0;min-height:0;height:100%;overflow:hidden}:host .md3-panes-container .md3-pane.md3-pane-start{grid-area:start}:host .md3-panes-container .md3-pane.md3-pane-main{position:relative;grid-area:main;z-index:1;display:grid;grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr)}:host .md3-panes-container .md3-pane.md3-pane-main>::ng-deep *{min-width:0;min-height:0;height:100%;max-height:100dvh;max-width:100dvw}:host .md3-panes-container .md3-pane.md3-pane-end{grid-area:end}\n"], dependencies: [{ kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }] });
|
|
6189
6202
|
}
|
|
6190
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: FullScreenDialog, decorators: [{
|
|
6191
|
-
type: Component,
|
|
6192
|
-
args: [{ selector: 'md3-fullscreen-dialog', imports: [
|
|
6193
|
-
CdkPortalOutlet,
|
|
6194
|
-
], template: "<!-- The role and aria attributes live on the host element, applied by the CDK dialog container. -->\n<div\n #surface\n class=\"md3-fullscreen-dialog-container\"\n [class.md3-active]=\"isActive()\"\n [class.md-scheme-dark]=\"config.scheme == 'dark'\"\n [class.md-scheme-light]=\"config.scheme == 'light'\"\n [attr.dir]=\"config.direction ?? null\">\n <div class=\"md3-panes-container md3-scrollable\">\n <!--\n The CDK attaches the dialog content to the first portal outlet of\n this template, so the main pane has to come first. The panes are\n placed by grid area, which makes the DOM order irrelevant visually.\n -->\n <div class=\"md3-pane md3-pane-main\" #mainPane>\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n <div class=\"md3-pane md3-pane-start\">\n <ng-template #startOutlet cdkPortalOutlet></ng-template>\n </div>\n <div class=\"md3-pane md3-pane-end\">\n <ng-template #endOutlet cdkPortalOutlet></ng-template>\n </div>\n </div>\n</div>\n", styles: ["::ng-deep .cdk-overlay-container{position:fixed;z-index:1000;inset:0;pointer-events:none;font-size:1rem}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper{position:absolute;display:flex;inset:0;pointer-events:none;overflow:hidden}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper:has(>.md3-fullscreen-dialog-panel){padding:0}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel{width:100%;height:100%;max-width:none;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel.md3-dialog-closing,::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel.md3-dialog-hidden{pointer-events:none}:host{display:block;height:100%;width:100%;outline:0}:host .md3-fullscreen-dialog-container{display:grid;grid-template-rows:minmax(0,1fr);height:100%;min-height:0;overflow:hidden;color:rgb(var(--md-scheme-on-surface));background-color:rgb(var(--md-scheme-surface));transition:all var(--md-motion-expressive-default-spatial-duration) var(--md-motion-expressive-default-spatial-easing);opacity:0;transform:translateY(1.5em)}:host .md3-fullscreen-dialog-container.md3-active{opacity:1;transform:none}:host .md3-panes-container{display:grid;grid-template-areas:\"start main end\";grid-template-columns:auto minmax(0,1fr) auto;grid-template-rows:minmax(0,1fr);min-width:0;min-height:0;overflow:hidden}:host .md3-panes-container .md3-pane{justify-self:stretch;align-self:stretch;min-width:0;min-height:0;height:100%;overflow:hidden}:host .md3-panes-container .md3-pane.md3-pane-start{grid-area:start}:host .md3-panes-container .md3-pane.md3-pane-main{position:relative;grid-area:main;z-index:1;display:grid;grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr)}:host .md3-panes-container .md3-pane.md3-pane-main>::ng-deep *{min-width:0;min-height:0;height:100%;max-height:100dvh;max-width:100dvw}:host .md3-panes-container .md3-pane.md3-pane-end{grid-area:end}\n"] }]
|
|
6195
|
-
}], propDecorators: { surface: [{ type: i0.ViewChild, args: ['surface', { isSignal: true }] }], mainPane: [{ type: i0.ViewChild, args: ['mainPane', { isSignal: true }] }], startOutlet: [{ type: i0.ViewChild, args: ['startOutlet', { ...{ read: CdkPortalOutlet }, isSignal: true }] }], endOutlet: [{ type: i0.ViewChild, args: ['endOutlet', { ...{ read: CdkPortalOutlet }, isSignal: true }] }] } });
|
|
6196
6203
|
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
*/
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
/** Open dialogs, from the first one opened to the one currently on top. */
|
|
6215
|
-
refs = [];
|
|
6216
|
-
/**
|
|
6217
|
-
* Elements the page was made of that the CDK hid from assistive technology,
|
|
6218
|
-
* kept here while the dialogs are hidden and the page is given back.
|
|
6219
|
-
*/
|
|
6220
|
-
pageAriaHidden = new Map();
|
|
6221
|
-
/**
|
|
6222
|
-
* Page scrolling is blocked here instead of per overlay, so stacked dialogs
|
|
6223
|
-
* cannot unblock the page while another dialog is still open.
|
|
6224
|
-
*/
|
|
6225
|
-
scrollBlock = this.overlay.scrollStrategies.block();
|
|
6226
|
-
/** Element that was focused before the first dialog of the stack opened. */
|
|
6227
|
-
rootTrigger = null;
|
|
6228
|
-
pageStateQueued = false;
|
|
6229
|
-
get openDialogs() {
|
|
6230
|
-
return this.refs;
|
|
6231
|
-
}
|
|
6232
|
-
/** Open dialogs that are currently on screen, from the bottom one up. */
|
|
6233
|
-
get visibleDialogs() {
|
|
6234
|
-
return this.refs.filter((ref) => !ref.isHidden);
|
|
6235
|
-
}
|
|
6236
|
-
/** The full screen dialog that is open, if there is one. */
|
|
6237
|
-
get fullScreenDialog() {
|
|
6238
|
-
return this.refs.find((ref) => ref.isFullScreen && !ref.isClosing);
|
|
6204
|
+
class Menu {
|
|
6205
|
+
el;
|
|
6206
|
+
portalOutlet = viewChild(CdkPortalOutlet, /* @ts-ignore */
|
|
6207
|
+
...(ngDevMode ? [{ debugName: "portalOutlet" }] : /* istanbul ignore next */ []));
|
|
6208
|
+
config = inject(MENU_CONFIG, { optional: true }) ?? {};
|
|
6209
|
+
menuColors = signal('standard', /* @ts-ignore */
|
|
6210
|
+
...(ngDevMode ? [{ debugName: "menuColors" }] : /* istanbul ignore next */ []));
|
|
6211
|
+
isVisible = signal(false, /* @ts-ignore */
|
|
6212
|
+
...(ngDevMode ? [{ debugName: "isVisible" }] : /* istanbul ignore next */ []));
|
|
6213
|
+
scheme = signal('inherit', /* @ts-ignore */
|
|
6214
|
+
...(ngDevMode ? [{ debugName: "scheme" }] : /* istanbul ignore next */ []));
|
|
6215
|
+
direction = signal(null, /* @ts-ignore */
|
|
6216
|
+
...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
|
|
6217
|
+
isActive = signal(true, /* @ts-ignore */
|
|
6218
|
+
...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
|
|
6219
|
+
get element() {
|
|
6220
|
+
return this.el.nativeElement;
|
|
6239
6221
|
}
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
const previousRef = this.topRegularRef();
|
|
6249
|
-
if (previousRef) {
|
|
6250
|
-
this.dismissPrevious(previousRef, dialogConfig.previousDialog);
|
|
6251
|
-
}
|
|
6252
|
-
let dialogRef;
|
|
6253
|
-
const cdkRef = this.cdkDialog.open(component, {
|
|
6254
|
-
// The MD3 shell replaces the default CDK container, so the overlay,
|
|
6255
|
-
// focus trap and focus restoration come from the CDK while the shell
|
|
6256
|
-
// only renders the surface.
|
|
6257
|
-
container: {
|
|
6258
|
-
type: Dialog,
|
|
6259
|
-
providers: () => [
|
|
6260
|
-
{ provide: DIALOG_CONFIG, useValue: dialogConfig },
|
|
6261
|
-
],
|
|
6262
|
-
},
|
|
6263
|
-
// These tokens make the dialog controllable from the dynamic
|
|
6264
|
-
// component without coupling that component to the service.
|
|
6265
|
-
providers: (cdkDialogRef) => {
|
|
6266
|
-
dialogRef = new DialogRef(cdkDialogRef, dialogConfig.disableCloseEvents);
|
|
6267
|
-
return [
|
|
6268
|
-
{ provide: DialogRef, useValue: dialogRef },
|
|
6269
|
-
{ provide: DIALOG_DATA, useValue: dialogConfig.data },
|
|
6270
|
-
{ provide: DIALOG_CONFIG, useValue: dialogConfig },
|
|
6271
|
-
{ provide: DIALOG_COMPONENT, useValue: component },
|
|
6272
|
-
];
|
|
6273
|
-
},
|
|
6274
|
-
data: dialogConfig.data,
|
|
6275
|
-
role: dialogConfig.role,
|
|
6276
|
-
ariaModal: true,
|
|
6277
|
-
ariaLabel: dialogConfig.ariaLabel || null,
|
|
6278
|
-
ariaLabelledBy: dialogConfig.ariaLabelledBy || null,
|
|
6279
|
-
ariaDescribedBy: dialogConfig.ariaDescribedBy || null,
|
|
6280
|
-
direction: dialogConfig.direction ?? undefined,
|
|
6281
|
-
viewContainerRef: dialogConfig.viewContainerRef,
|
|
6282
|
-
injector: dialogConfig.injector,
|
|
6283
|
-
hasBackdrop: true,
|
|
6284
|
-
backdropClass: ['md3-dialog-scrim', OPENING_CLASS],
|
|
6285
|
-
panelClass: [PANEL_CLASS, OPENING_CLASS],
|
|
6286
|
-
positionStrategy: this.overlay.position()
|
|
6287
|
-
.global()
|
|
6288
|
-
.centerHorizontally()
|
|
6289
|
-
.centerVertically(),
|
|
6290
|
-
// Scrolling is blocked by the service for the whole stack.
|
|
6291
|
-
scrollStrategy: this.overlay.scrollStrategies.noop(),
|
|
6292
|
-
// Focus goes back to whatever opened the stack, even when the dialog
|
|
6293
|
-
// that was open underneath has been closed in the meantime.
|
|
6294
|
-
restoreFocus: this.rootTrigger ?? true,
|
|
6295
|
-
// Scrim and Escape handling lives in DialogRef so the dialog can
|
|
6296
|
-
// play its exit animation before the overlay is disposed.
|
|
6297
|
-
disableClose: true,
|
|
6222
|
+
constructor(el) {
|
|
6223
|
+
this.el = el;
|
|
6224
|
+
effect((onCleanup) => {
|
|
6225
|
+
const color = 'md3-' + this.menuColors();
|
|
6226
|
+
this.element.classList.add(color);
|
|
6227
|
+
onCleanup(() => {
|
|
6228
|
+
this.element.classList.remove(color);
|
|
6229
|
+
});
|
|
6298
6230
|
});
|
|
6299
|
-
this.
|
|
6300
|
-
|
|
6231
|
+
this.menuColors.set(this.config.menuColors ?? 'standard');
|
|
6232
|
+
this.scheme.set(this.config.scheme ?? 'inherit');
|
|
6233
|
+
this.direction.set(this.config.direction ?? null);
|
|
6301
6234
|
}
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
* outlets belong to it: side sheets open inside the dialog, not behind it.
|
|
6306
|
-
* `previousDialog` decides what happens to the dialogs it replaces, the
|
|
6307
|
-
* same way it does for a regular dialog.
|
|
6308
|
-
*/
|
|
6309
|
-
openFullScreen(component, config = {}) {
|
|
6310
|
-
const dialogConfig = this.mergeConfig(config);
|
|
6311
|
-
if (this.refs.length === 0) {
|
|
6312
|
-
this.rootTrigger = this.getFocusedElement();
|
|
6313
|
-
}
|
|
6314
|
-
// A full screen dialog is a context of its own: the dialog it replaces
|
|
6315
|
-
// and anything stacked on that dialog goes with it.
|
|
6316
|
-
const previousRef = this.topRef();
|
|
6317
|
-
if (previousRef) {
|
|
6318
|
-
// Everything open belongs to the context being replaced, including
|
|
6319
|
-
// a full screen dialog that is already up.
|
|
6320
|
-
this.dismissPreviousContext(dialogConfig.previousDialog);
|
|
6321
|
-
}
|
|
6322
|
-
let dialogRef;
|
|
6323
|
-
const cdkRef = this.cdkDialog.open(component, {
|
|
6324
|
-
container: {
|
|
6325
|
-
type: FullScreenDialog,
|
|
6326
|
-
providers: () => [
|
|
6327
|
-
{ provide: DIALOG_CONFIG, useValue: dialogConfig },
|
|
6328
|
-
],
|
|
6329
|
-
},
|
|
6330
|
-
providers: (cdkDialogRef) => {
|
|
6331
|
-
dialogRef = new DialogRef(cdkDialogRef, dialogConfig.disableCloseEvents, true);
|
|
6332
|
-
return [
|
|
6333
|
-
{ provide: DialogRef, useValue: dialogRef },
|
|
6334
|
-
{ provide: DIALOG_DATA, useValue: dialogConfig.data },
|
|
6335
|
-
{ provide: DIALOG_CONFIG, useValue: dialogConfig },
|
|
6336
|
-
{ provide: DIALOG_COMPONENT, useValue: component },
|
|
6337
|
-
];
|
|
6338
|
-
},
|
|
6339
|
-
data: dialogConfig.data,
|
|
6340
|
-
role: dialogConfig.role,
|
|
6341
|
-
ariaModal: true,
|
|
6342
|
-
ariaLabel: dialogConfig.ariaLabel || null,
|
|
6343
|
-
ariaLabelledBy: dialogConfig.ariaLabelledBy || null,
|
|
6344
|
-
ariaDescribedBy: dialogConfig.ariaDescribedBy || null,
|
|
6345
|
-
direction: dialogConfig.direction ?? undefined,
|
|
6346
|
-
viewContainerRef: dialogConfig.viewContainerRef,
|
|
6347
|
-
injector: dialogConfig.injector,
|
|
6348
|
-
// The dialog covers the page on its own, so there is nothing left
|
|
6349
|
-
// for a scrim to dim.
|
|
6350
|
-
hasBackdrop: false,
|
|
6351
|
-
panelClass: [FULL_SCREEN_PANEL_CLASS, OPENING_CLASS],
|
|
6352
|
-
// The CDK writes the size on the panel and the global strategy then
|
|
6353
|
-
// drops its centering margins, which is how the panel ends up
|
|
6354
|
-
// covering the whole wrapper.
|
|
6355
|
-
width: '100%',
|
|
6356
|
-
height: '100%',
|
|
6357
|
-
positionStrategy: this.overlay.position().global(),
|
|
6358
|
-
scrollStrategy: this.overlay.scrollStrategies.noop(),
|
|
6359
|
-
restoreFocus: this.rootTrigger ?? true,
|
|
6360
|
-
disableClose: true,
|
|
6235
|
+
ngAfterContentInit() {
|
|
6236
|
+
requestAnimationFrame(() => {
|
|
6237
|
+
this.showMenu(true);
|
|
6361
6238
|
});
|
|
6362
|
-
this.registerDialog(dialogRef, cdkRef, dialogConfig, previousRef);
|
|
6363
|
-
return dialogRef;
|
|
6364
|
-
}
|
|
6365
|
-
/** Wires a freshly created dialog into the stack and starts its animation. */
|
|
6366
|
-
registerDialog(dialogRef, cdkRef, dialogConfig, previousRef) {
|
|
6367
|
-
dialogRef.dialogInstance = cdkRef.containerInstance;
|
|
6368
|
-
dialogRef.componentInstance = cdkRef.componentInstance ?? undefined;
|
|
6369
|
-
if (cdkRef.componentRef) {
|
|
6370
|
-
this.bindDataToInputs(cdkRef.componentRef, dialogConfig);
|
|
6371
|
-
}
|
|
6372
|
-
this.refs.push(dialogRef);
|
|
6373
|
-
this.syncPageState();
|
|
6374
|
-
if (previousRef) {
|
|
6375
|
-
setTimeout(() => this.startReplacingAnimation(dialogRef, previousRef), DIALOG_HANDOVER_DELAY_MS);
|
|
6376
|
-
}
|
|
6377
|
-
else {
|
|
6378
|
-
this.startOpenAnimation(dialogRef);
|
|
6379
|
-
}
|
|
6380
|
-
// Restoring starts with the exit animation, so the dialog underneath is
|
|
6381
|
-
// already coming back while this one is fading out.
|
|
6382
|
-
dialogRef.beforeClosed().subscribe(() => this.restorePreviousDialog(dialogRef));
|
|
6383
|
-
dialogRef.afterClosed().subscribe(() => this.removeRef(dialogRef));
|
|
6384
|
-
// Hiding and showing can also come straight from the reference, so the
|
|
6385
|
-
// page state is driven by what the dialogs report rather than by the
|
|
6386
|
-
// calls that went through this service.
|
|
6387
|
-
dialogRef.hiddenChanged().subscribe(() => this.syncPageState());
|
|
6388
6239
|
}
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
* the closing animation. They stay alive with their content and state, the
|
|
6392
|
-
* page underneath becomes usable, and showAll() puts them back. The promise
|
|
6393
|
-
* resolves once they are all out of sight.
|
|
6394
|
-
*/
|
|
6395
|
-
hideAll() {
|
|
6396
|
-
const visible = this.refs.filter((ref) => !ref.isHidden && !ref.isClosing);
|
|
6397
|
-
return Promise.all(visible.map((ref) => ref.hide())).then(() => undefined);
|
|
6240
|
+
showMenu(value) {
|
|
6241
|
+
this.isVisible.set(value);
|
|
6398
6242
|
}
|
|
6399
6243
|
/**
|
|
6400
|
-
*
|
|
6401
|
-
*
|
|
6402
|
-
* screen dialog it sits in. Dialogs hidden behind another dialog stay
|
|
6403
|
-
* hidden, since that is where they belong once the stack is back.
|
|
6244
|
+
* The service creates this wrapper first, then calls this method to mount
|
|
6245
|
+
* the user supplied component into the dialog container.
|
|
6404
6246
|
*/
|
|
6405
|
-
|
|
6406
|
-
const
|
|
6407
|
-
|
|
6408
|
-
return;
|
|
6409
|
-
}
|
|
6410
|
-
const fullScreenRef = this.fullScreenDialog;
|
|
6411
|
-
// The full screen dialog is the context the top one sits in, so it
|
|
6412
|
-
// comes back first and the dialog on top ends up on top, with the focus.
|
|
6413
|
-
if (fullScreenRef && fullScreenRef !== topRef && fullScreenRef.isHidden) {
|
|
6414
|
-
fullScreenRef.show();
|
|
6415
|
-
}
|
|
6416
|
-
if (topRef.isHidden) {
|
|
6417
|
-
topRef.show();
|
|
6418
|
-
}
|
|
6247
|
+
attachContent(component, injector) {
|
|
6248
|
+
const portal = new ComponentPortal(component, null, injector);
|
|
6249
|
+
return this.portalOutlet().attachComponentPortal(portal);
|
|
6419
6250
|
}
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6251
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Menu, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
6252
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: Menu, isStandalone: true, selector: "md3-menu", host: { attributes: { "role": "menu" }, properties: { "class.md3-visible": "isVisible()", "class.md3-inactive": "!isActive()", "class.md-scheme-dark": "scheme() == \"dark\"", "class.md-scheme-light": "scheme() == \"light\"", "dir": "direction()" }, classAttribute: "md3-menu-container" }, viewQueries: [{ propertyName: "portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template cdkPortalOutlet></ng-template>", styles: ["::ng-deep .cdk-overlay-container{position:fixed;z-index:1000;inset:0;pointer-events:none;font-size:1rem}::ng-deep .cdk-overlay-container .md3-menu-scrim{position:absolute;inset:0;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-overlay-connected-position-bounding-box{pointer-events:none}::ng-deep .cdk-overlay-container .md3-menu-panel{pointer-events:auto}::ng-deep .cdk-overlay-container .md3-menu-panel.md3-select-menu>.md3-menu-container{--menu-min-width: 100%;--menu-max-width: 100%}::ng-deep .cdk-overlay-container .md3-menu-panel.md3-menu-closing{pointer-events:none}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper{position:absolute;display:flex;inset:0;pointer-events:none;padding:3.5rem 0;overflow:hidden}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-menu-panel{position:absolute;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-menu-panel.md3-menu-closing{pointer-events:none}:host{--background-color: rgb(var(--md-scheme-surface-container-low));--foreground-color: rgb(var(--md-scheme-on-surface));--border-radius: var(--md-border-radius-large);--menu-min-width: 7em;--menu-max-width: 17.5em;--menu-group-radius: var(--md-border-radius-small);--menu-group-shadow: var(--md-shadow-3dp);--menu-group-label-color: rgb(var(--md-scheme-on-surface-variant));--menu-item-label-color: rgb(var(--md-scheme-on-surface));--menu-item-supporting-color: rgb(var(--md-scheme-on-surface-variant));--menu-item-selected-background: rgb(var(--md-scheme-tertiary-container));--menu-item-selected-foreground: rgb(var(--md-scheme-on-tertiary-container));--menu-item-state-color: var(--md-scheme-on-surface);--menu-item-border-radius: var(--md-border-radius-xsmall);--menu-item-outline-color: rgb(var(--md-scheme-secondary));--menu-item-outline-width: .1875em;--menu-item-outline-offset: -.1875em;--menu-item-badge-background: rgb(var(--md-scheme-primary-container));--menu-item-badge-foreground: rgb(var(--md-scheme-on-primary-container));position:relative;display:block;font-size:1rem;min-width:var(--menu-min-width);max-width:min(var(--menu-max-width),100vw - 2rem);max-height:min(32rem,100vh - 2rem);outline:none;transition:all var(--md-motion-expressive-default-spatial-duration) var(--md-motion-expressive-default-spatial-easing);opacity:0;transform:scaleY(.8)}:host.md3-visible{opacity:1;transform:scaleY(1)}:host.md3-vibrant{--background-color: rgb(var(--md-scheme-tertiary-container));--foreground-color: rgb(var(--md-scheme-on-tertiary-container));--menu-group-label-color: rgb(var(--md-scheme-on-tertiary-container));--menu-item-label-color: rgb(var(--md-scheme-on-tertiary-container));--menu-item-supporting-color: rgb(var(--md-scheme-on-tertiary-container));--menu-item-selected-background: rgb(var(--md-scheme-tertiary));--menu-item-selected-foreground: rgb(var(--md-scheme-on-tertiary));--menu-item-state-color: var(--md-scheme-on-tertiary-container)}:host.md3-inactive{--border-radius: var(--md-border-radius-small)}:host ::ng-deep md3-menu-group{margin-top:.125em}:host ::ng-deep md3-menu-group:first-child{margin-top:0}\n"], dependencies: [{ kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }] });
|
|
6253
|
+
}
|
|
6254
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Menu, decorators: [{
|
|
6255
|
+
type: Component,
|
|
6256
|
+
args: [{ selector: 'md3-menu', imports: [
|
|
6257
|
+
CdkPortalOutlet,
|
|
6258
|
+
], host: {
|
|
6259
|
+
'class': 'md3-menu-container',
|
|
6260
|
+
'role': 'menu',
|
|
6261
|
+
'[class.md3-visible]': 'isVisible()',
|
|
6262
|
+
'[class.md3-inactive]': '!isActive()',
|
|
6263
|
+
'[class.md-scheme-dark]': 'scheme() == "dark"',
|
|
6264
|
+
'[class.md-scheme-light]': 'scheme() == "light"',
|
|
6265
|
+
'[dir]': 'direction()',
|
|
6266
|
+
}, template: "<ng-template cdkPortalOutlet></ng-template>", styles: ["::ng-deep .cdk-overlay-container{position:fixed;z-index:1000;inset:0;pointer-events:none;font-size:1rem}::ng-deep .cdk-overlay-container .md3-menu-scrim{position:absolute;inset:0;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-overlay-connected-position-bounding-box{pointer-events:none}::ng-deep .cdk-overlay-container .md3-menu-panel{pointer-events:auto}::ng-deep .cdk-overlay-container .md3-menu-panel.md3-select-menu>.md3-menu-container{--menu-min-width: 100%;--menu-max-width: 100%}::ng-deep .cdk-overlay-container .md3-menu-panel.md3-menu-closing{pointer-events:none}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper{position:absolute;display:flex;inset:0;pointer-events:none;padding:3.5rem 0;overflow:hidden}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-menu-panel{position:absolute;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-menu-panel.md3-menu-closing{pointer-events:none}:host{--background-color: rgb(var(--md-scheme-surface-container-low));--foreground-color: rgb(var(--md-scheme-on-surface));--border-radius: var(--md-border-radius-large);--menu-min-width: 7em;--menu-max-width: 17.5em;--menu-group-radius: var(--md-border-radius-small);--menu-group-shadow: var(--md-shadow-3dp);--menu-group-label-color: rgb(var(--md-scheme-on-surface-variant));--menu-item-label-color: rgb(var(--md-scheme-on-surface));--menu-item-supporting-color: rgb(var(--md-scheme-on-surface-variant));--menu-item-selected-background: rgb(var(--md-scheme-tertiary-container));--menu-item-selected-foreground: rgb(var(--md-scheme-on-tertiary-container));--menu-item-state-color: var(--md-scheme-on-surface);--menu-item-border-radius: var(--md-border-radius-xsmall);--menu-item-outline-color: rgb(var(--md-scheme-secondary));--menu-item-outline-width: .1875em;--menu-item-outline-offset: -.1875em;--menu-item-badge-background: rgb(var(--md-scheme-primary-container));--menu-item-badge-foreground: rgb(var(--md-scheme-on-primary-container));position:relative;display:block;font-size:1rem;min-width:var(--menu-min-width);max-width:min(var(--menu-max-width),100vw - 2rem);max-height:min(32rem,100vh - 2rem);outline:none;transition:all var(--md-motion-expressive-default-spatial-duration) var(--md-motion-expressive-default-spatial-easing);opacity:0;transform:scaleY(.8)}:host.md3-visible{opacity:1;transform:scaleY(1)}:host.md3-vibrant{--background-color: rgb(var(--md-scheme-tertiary-container));--foreground-color: rgb(var(--md-scheme-on-tertiary-container));--menu-group-label-color: rgb(var(--md-scheme-on-tertiary-container));--menu-item-label-color: rgb(var(--md-scheme-on-tertiary-container));--menu-item-supporting-color: rgb(var(--md-scheme-on-tertiary-container));--menu-item-selected-background: rgb(var(--md-scheme-tertiary));--menu-item-selected-foreground: rgb(var(--md-scheme-on-tertiary));--menu-item-state-color: var(--md-scheme-on-tertiary-container)}:host.md3-inactive{--border-radius: var(--md-border-radius-small)}:host ::ng-deep md3-menu-group{margin-top:.125em}:host ::ng-deep md3-menu-group:first-child{margin-top:0}\n"] }]
|
|
6267
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { portalOutlet: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkPortalOutlet), { isSignal: true }] }] } });
|
|
6268
|
+
|
|
6269
|
+
class MenuService {
|
|
6270
|
+
overlay = inject(Overlay);
|
|
6271
|
+
injector = inject(Injector);
|
|
6272
|
+
document = inject(DOCUMENT);
|
|
6273
|
+
open(component, config = {}) {
|
|
6274
|
+
const menuConfig = this.mergeConfig(config);
|
|
6275
|
+
const previouslyFocusedElement = this.getFocusedElement();
|
|
6276
|
+
const triggerElement = this.resolveTriggerElement(menuConfig.origin, previouslyFocusedElement);
|
|
6277
|
+
const menuOverlay = this.createOverlay(menuConfig, previouslyFocusedElement);
|
|
6278
|
+
const overlayRef = menuOverlay.overlayRef;
|
|
6279
|
+
const menuRef = new MenuRef(overlayRef, previouslyFocusedElement);
|
|
6280
|
+
const injector = this.createInjector(component, menuConfig, menuRef);
|
|
6281
|
+
// The overlay hosts the MD3 menu shell. The shell is responsible for
|
|
6282
|
+
// the surface markup and receives the dynamic content through a portal.
|
|
6283
|
+
const menuPortal = new ComponentPortal(Menu, menuConfig.viewContainerRef ?? null, injector);
|
|
6284
|
+
const menuComponentRef = overlayRef.attach(menuPortal);
|
|
6285
|
+
const contentComponentRef = menuComponentRef.instance.attachContent(component, injector);
|
|
6286
|
+
this.bindDataToInputs(contentComponentRef, menuConfig);
|
|
6287
|
+
this.flipPositionIfPushBreaksAnchor(menuOverlay, menuConfig);
|
|
6288
|
+
menuRef.componentInstance = contentComponentRef.instance;
|
|
6289
|
+
menuRef.menuInstance = menuComponentRef.instance;
|
|
6290
|
+
this.bindTriggerActiveState(triggerElement, overlayRef, menuRef);
|
|
6291
|
+
this.startOpenAnimation(overlayRef);
|
|
6292
|
+
this.connectCloseEvents(overlayRef, menuRef, menuOverlay.origin);
|
|
6293
|
+
return menuRef;
|
|
6425
6294
|
}
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
const
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6295
|
+
openSubMenu(component, config = {}) {
|
|
6296
|
+
const xPosition = this.getSubMenuXPosition(config.xPosition);
|
|
6297
|
+
const yPosition = config.yPosition ?? 'below';
|
|
6298
|
+
const offsetX = config.offsetX ?? 0;
|
|
6299
|
+
const offsetY = config.offsetY ?? 0;
|
|
6300
|
+
const subMenuConfig = {
|
|
6301
|
+
...config,
|
|
6302
|
+
isSubMenu: true,
|
|
6303
|
+
xPosition,
|
|
6304
|
+
yPosition,
|
|
6305
|
+
overlapTrigger: config.overlapTrigger ?? true,
|
|
6306
|
+
offsetX,
|
|
6307
|
+
offsetY,
|
|
6308
|
+
scheme: config.scheme ?? 'inherit',
|
|
6309
|
+
direction: config.direction ?? null,
|
|
6310
|
+
};
|
|
6311
|
+
return this.open(component, subMenuConfig);
|
|
6432
6312
|
}
|
|
6433
6313
|
mergeConfig(config) {
|
|
6314
|
+
const viewportMargin = this.getViewportMargin(config.viewportMargin);
|
|
6434
6315
|
return {
|
|
6435
6316
|
data: config.data,
|
|
6436
6317
|
bindDataToInputs: config.bindDataToInputs ?? false,
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6318
|
+
isSubMenu: config.isSubMenu ?? false,
|
|
6319
|
+
menuColors: config.menuColors ?? 'standard',
|
|
6320
|
+
origin: config.origin,
|
|
6321
|
+
xPosition: config.xPosition ?? 'start',
|
|
6322
|
+
yPosition: config.yPosition ?? 'below',
|
|
6323
|
+
overlapTrigger: config.overlapTrigger ?? false,
|
|
6324
|
+
offsetX: config.offsetX ?? 0,
|
|
6325
|
+
offsetY: config.offsetY ?? 4,
|
|
6326
|
+
viewportMargin,
|
|
6327
|
+
positions: config.positions,
|
|
6328
|
+
scrollStrategy: config.scrollStrategy ?? 'reposition',
|
|
6443
6329
|
scheme: config.scheme ?? 'inherit',
|
|
6444
6330
|
direction: config.direction ?? null,
|
|
6445
6331
|
viewContainerRef: config.viewContainerRef,
|
|
6446
6332
|
injector: config.injector ?? this.injector,
|
|
6447
6333
|
};
|
|
6448
6334
|
}
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
* the dialog taking over is ready for it, so the page behind never
|
|
6452
|
-
* brightens between the two dialogs.
|
|
6453
|
-
*/
|
|
6454
|
-
dismissPrevious(previousRef, behavior) {
|
|
6455
|
-
previousRef.overlayRef.backdropElement?.classList.add(SCRIM_KEPT_CLASS);
|
|
6456
|
-
return behavior === 'hide' ? previousRef.hide() : this.closeRegularDialogs();
|
|
6457
|
-
}
|
|
6458
|
-
/**
|
|
6459
|
-
* The same choice for a full screen dialog, applied to everything that is
|
|
6460
|
-
* on screen: what it takes over from is a whole context, a full screen
|
|
6461
|
-
* dialog of its own included. `hide` keeps that context alive, and it comes
|
|
6462
|
-
* back as it was once this dialog closes.
|
|
6463
|
-
*/
|
|
6464
|
-
dismissPreviousContext(behavior) {
|
|
6465
|
-
return behavior === 'hide' ? this.hideAll() : this.closeAll();
|
|
6335
|
+
isSelectInput(origin) {
|
|
6336
|
+
return origin?.tagName.toLowerCase() == 'input' && origin?.classList.contains('md3-select-input');
|
|
6466
6337
|
}
|
|
6467
|
-
|
|
6468
|
-
const
|
|
6469
|
-
const
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6338
|
+
createOverlay(config, fallbackOrigin) {
|
|
6339
|
+
const origin = this.resolveOrigin(config.origin, fallbackOrigin);
|
|
6340
|
+
const positionStrategy = this.overlay.position()
|
|
6341
|
+
.flexibleConnectedTo(origin)
|
|
6342
|
+
.withFlexibleDimensions(false)
|
|
6343
|
+
.withGrowAfterOpen(true)
|
|
6344
|
+
.withPush(true)
|
|
6345
|
+
.withViewportMargin(config.viewportMargin)
|
|
6346
|
+
.withPositions(config.positions ?? this.getInitialConnectedPositions(config))
|
|
6347
|
+
.withTransformOriginOn('.md3-menu-container');
|
|
6348
|
+
const isSelectInput = this.isSelectInput(origin);
|
|
6349
|
+
const originRect = this.getOriginClientRect(origin);
|
|
6350
|
+
const minWidth = !isSelectInput ? undefined : originRect.width;
|
|
6351
|
+
const overlayConfig = new OverlayConfig({
|
|
6352
|
+
hasBackdrop: !isSelectInput,
|
|
6353
|
+
backdropClass: ['md3-menu-scrim', 'md3-menu-opening'],
|
|
6354
|
+
panelClass: ['md3-menu-panel', 'md3-menu-opening', ...(isSelectInput ? ['md3-select-menu'] : [])],
|
|
6355
|
+
positionStrategy,
|
|
6356
|
+
scrollStrategy: this.getScrollStrategy(config.scrollStrategy),
|
|
6357
|
+
minWidth: minWidth,
|
|
6480
6358
|
});
|
|
6481
|
-
|
|
6359
|
+
return {
|
|
6360
|
+
overlayRef: this.overlay.create(overlayConfig),
|
|
6361
|
+
positionStrategy: config.positions ? undefined : positionStrategy,
|
|
6362
|
+
origin,
|
|
6363
|
+
};
|
|
6482
6364
|
}
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
if (dialogRef.isClosing) {
|
|
6365
|
+
bindTriggerActiveState(triggerElement, overlayRef, menuRef) {
|
|
6366
|
+
if (!triggerElement) {
|
|
6486
6367
|
return;
|
|
6487
6368
|
}
|
|
6488
|
-
const
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
panel.classList.remove(OPENING_CLASS);
|
|
6493
|
-
backdrop?.classList.remove(OPENING_CLASS);
|
|
6494
|
-
this.endScrimHandover(previousRef, dialogRef);
|
|
6495
|
-
dialogRef.dialogInstance?.startEnterAnimation();
|
|
6369
|
+
const removeActiveClass = () => triggerElement.classList.remove('md3-menu-active');
|
|
6370
|
+
triggerElement.classList.add('md3-menu-active');
|
|
6371
|
+
menuRef.afterClosed().pipe(take(1)).subscribe(removeActiveClass);
|
|
6372
|
+
overlayRef.detachments().pipe(take(1)).subscribe(removeActiveClass);
|
|
6496
6373
|
}
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
if (
|
|
6374
|
+
resolveOrigin(origin, fallbackOrigin) {
|
|
6375
|
+
const resolvedOrigin = origin ?? fallbackOrigin;
|
|
6376
|
+
if (resolvedOrigin) {
|
|
6377
|
+
if (this.isMouseEvent(resolvedOrigin)) {
|
|
6378
|
+
if (resolvedOrigin.currentTarget instanceof HTMLElement) {
|
|
6379
|
+
return resolvedOrigin.currentTarget;
|
|
6380
|
+
}
|
|
6381
|
+
return {
|
|
6382
|
+
x: resolvedOrigin.clientX,
|
|
6383
|
+
y: resolvedOrigin.clientY,
|
|
6384
|
+
};
|
|
6385
|
+
}
|
|
6386
|
+
if (this.isElementRef(resolvedOrigin)) {
|
|
6387
|
+
return resolvedOrigin.nativeElement;
|
|
6388
|
+
}
|
|
6389
|
+
return resolvedOrigin;
|
|
6390
|
+
}
|
|
6391
|
+
const viewport = this.document.defaultView;
|
|
6392
|
+
return {
|
|
6393
|
+
x: (viewport?.innerWidth ?? 0) / 2,
|
|
6394
|
+
y: (viewport?.innerHeight ?? 0) / 2,
|
|
6395
|
+
};
|
|
6396
|
+
}
|
|
6397
|
+
resolveTriggerElement(origin, fallbackOrigin) {
|
|
6398
|
+
const resolvedOrigin = origin ?? fallbackOrigin;
|
|
6399
|
+
if (!resolvedOrigin) {
|
|
6400
|
+
return null;
|
|
6401
|
+
}
|
|
6402
|
+
if (this.isMouseEvent(resolvedOrigin)) {
|
|
6403
|
+
return resolvedOrigin.currentTarget instanceof HTMLElement
|
|
6404
|
+
? resolvedOrigin.currentTarget
|
|
6405
|
+
: null;
|
|
6406
|
+
}
|
|
6407
|
+
if (this.isElementRef(resolvedOrigin)) {
|
|
6408
|
+
return resolvedOrigin.nativeElement;
|
|
6409
|
+
}
|
|
6410
|
+
return resolvedOrigin instanceof HTMLElement ? resolvedOrigin : null;
|
|
6411
|
+
}
|
|
6412
|
+
flipPositionIfPushBreaksAnchor(menuOverlay, config) {
|
|
6413
|
+
if (!menuOverlay.positionStrategy) {
|
|
6414
|
+
return;
|
|
6415
|
+
}
|
|
6416
|
+
menuOverlay.overlayRef.updatePosition();
|
|
6417
|
+
const fallbackPosition = this.getFallbackPositionAfterPush(config, this.getOriginClientRect(menuOverlay.origin), menuOverlay.overlayRef.overlayElement.getBoundingClientRect());
|
|
6418
|
+
if (!fallbackPosition) {
|
|
6500
6419
|
return;
|
|
6501
6420
|
}
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6421
|
+
menuOverlay.positionStrategy.withPositions([fallbackPosition]);
|
|
6422
|
+
menuOverlay.overlayRef.updatePosition();
|
|
6423
|
+
}
|
|
6424
|
+
getInitialConnectedPositions(config) {
|
|
6425
|
+
return [this.getPreferredConnectedPosition(config)];
|
|
6426
|
+
}
|
|
6427
|
+
getPreferredConnectedPosition(config) {
|
|
6428
|
+
if (config.isSubMenu) {
|
|
6429
|
+
return this.createSubMenuConnectedPosition(this.getSubMenuXPosition(config.xPosition), this.getSubMenuVerticalAlignment(config.yPosition), config.offsetX, config.offsetY);
|
|
6430
|
+
}
|
|
6431
|
+
return this.createConnectedPosition(config.xPosition, config.yPosition, config);
|
|
6432
|
+
}
|
|
6433
|
+
getFallbackPositionAfterPush(config, originRect, overlayRect) {
|
|
6434
|
+
const xPosition = this.shouldFlipXPosition(config, originRect, overlayRect)
|
|
6435
|
+
? this.getFallbackXPosition(config.xPosition)
|
|
6436
|
+
: config.xPosition;
|
|
6437
|
+
const yPosition = this.shouldFlipYPosition(config, originRect, overlayRect)
|
|
6438
|
+
? this.getFallbackYPosition(config.yPosition)
|
|
6439
|
+
: config.yPosition;
|
|
6440
|
+
if (xPosition === config.xPosition && yPosition === config.yPosition) {
|
|
6441
|
+
return null;
|
|
6442
|
+
}
|
|
6443
|
+
return this.getPreferredConnectedPosition({
|
|
6444
|
+
...config,
|
|
6445
|
+
xPosition,
|
|
6446
|
+
yPosition,
|
|
6447
|
+
});
|
|
6448
|
+
}
|
|
6449
|
+
shouldFlipXPosition(config, originRect, overlayRect) {
|
|
6450
|
+
const tolerance = config.viewportMargin;
|
|
6451
|
+
switch (config.xPosition) {
|
|
6452
|
+
case 'before':
|
|
6453
|
+
return overlayRect.right > originRect.left + tolerance;
|
|
6454
|
+
case 'after':
|
|
6455
|
+
return overlayRect.left < originRect.right - tolerance;
|
|
6456
|
+
case 'start':
|
|
6457
|
+
return originRect.left < overlayRect.left - tolerance
|
|
6458
|
+
|| originRect.left > overlayRect.right + tolerance;
|
|
6459
|
+
case 'end':
|
|
6460
|
+
return originRect.right < overlayRect.left - tolerance
|
|
6461
|
+
|| originRect.right > overlayRect.right + tolerance;
|
|
6462
|
+
case 'center':
|
|
6463
|
+
default:
|
|
6464
|
+
return false;
|
|
6465
|
+
}
|
|
6466
|
+
}
|
|
6467
|
+
shouldFlipYPosition(config, originRect, overlayRect) {
|
|
6468
|
+
const tolerance = config.viewportMargin;
|
|
6469
|
+
if (config.isSubMenu) {
|
|
6470
|
+
const anchorY = config.yPosition === 'above' ? originRect.bottom : originRect.top;
|
|
6471
|
+
return anchorY < overlayRect.top - tolerance
|
|
6472
|
+
|| anchorY > overlayRect.bottom + tolerance;
|
|
6473
|
+
}
|
|
6474
|
+
if (config.overlapTrigger) {
|
|
6475
|
+
const anchorY = config.yPosition === 'above' ? originRect.bottom : originRect.top;
|
|
6476
|
+
return anchorY < overlayRect.top - tolerance
|
|
6477
|
+
|| anchorY > overlayRect.bottom + tolerance;
|
|
6478
|
+
}
|
|
6479
|
+
switch (config.yPosition) {
|
|
6480
|
+
case 'above':
|
|
6481
|
+
return overlayRect.bottom > originRect.top + tolerance;
|
|
6482
|
+
case 'below':
|
|
6483
|
+
return overlayRect.top < originRect.bottom - tolerance;
|
|
6484
|
+
case 'center':
|
|
6485
|
+
default:
|
|
6486
|
+
return false;
|
|
6487
|
+
}
|
|
6488
|
+
}
|
|
6489
|
+
createConnectedPosition(xPosition, yPosition, config) {
|
|
6490
|
+
const horizontal = this.getHorizontalPosition(xPosition);
|
|
6491
|
+
const vertical = this.getVerticalPosition(yPosition, config.overlapTrigger);
|
|
6492
|
+
return {
|
|
6493
|
+
...horizontal,
|
|
6494
|
+
...vertical,
|
|
6495
|
+
offsetX: config.offsetX,
|
|
6496
|
+
offsetY: this.getOffsetY(yPosition, config),
|
|
6497
|
+
panelClass: [
|
|
6498
|
+
'md3-menu-position-' + xPosition,
|
|
6499
|
+
'md3-menu-position-' + yPosition,
|
|
6500
|
+
],
|
|
6501
|
+
};
|
|
6502
|
+
}
|
|
6503
|
+
createSubMenuConnectedPosition(xPosition, yAlignment, offsetX, offsetY) {
|
|
6504
|
+
const horizontal = this.getHorizontalPosition(xPosition);
|
|
6505
|
+
const yPosition = yAlignment === 'top' ? 'below' : 'above';
|
|
6506
|
+
return {
|
|
6507
|
+
...horizontal,
|
|
6508
|
+
originY: yAlignment,
|
|
6509
|
+
overlayY: yAlignment,
|
|
6510
|
+
offsetX: this.getSubMenuOffsetX(xPosition, offsetX),
|
|
6511
|
+
offsetY: this.getSubMenuOffsetY(yAlignment, offsetY),
|
|
6512
|
+
panelClass: [
|
|
6513
|
+
'md3-menu-position-' + xPosition,
|
|
6514
|
+
'md3-menu-position-' + yPosition,
|
|
6515
|
+
'md3-menu-position-submenu',
|
|
6516
|
+
],
|
|
6517
|
+
};
|
|
6518
|
+
}
|
|
6519
|
+
getHorizontalPosition(position) {
|
|
6520
|
+
switch (position) {
|
|
6521
|
+
case 'end':
|
|
6522
|
+
return {
|
|
6523
|
+
originX: 'end',
|
|
6524
|
+
overlayX: 'end',
|
|
6525
|
+
};
|
|
6526
|
+
case 'before':
|
|
6527
|
+
return {
|
|
6528
|
+
originX: 'start',
|
|
6529
|
+
overlayX: 'end',
|
|
6530
|
+
};
|
|
6531
|
+
case 'after':
|
|
6532
|
+
return {
|
|
6533
|
+
originX: 'end',
|
|
6534
|
+
overlayX: 'start',
|
|
6535
|
+
};
|
|
6536
|
+
case 'center':
|
|
6537
|
+
return {
|
|
6538
|
+
originX: 'center',
|
|
6539
|
+
overlayX: 'center',
|
|
6540
|
+
};
|
|
6541
|
+
case 'start':
|
|
6542
|
+
default:
|
|
6543
|
+
return {
|
|
6544
|
+
originX: 'start',
|
|
6545
|
+
overlayX: 'start',
|
|
6546
|
+
};
|
|
6547
|
+
}
|
|
6505
6548
|
}
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6549
|
+
getVerticalPosition(position, overlapTrigger) {
|
|
6550
|
+
switch (position) {
|
|
6551
|
+
case 'above':
|
|
6552
|
+
return {
|
|
6553
|
+
originY: overlapTrigger ? 'bottom' : 'top',
|
|
6554
|
+
overlayY: 'bottom',
|
|
6555
|
+
};
|
|
6556
|
+
case 'center':
|
|
6557
|
+
return {
|
|
6558
|
+
originY: 'center',
|
|
6559
|
+
overlayY: 'center',
|
|
6560
|
+
};
|
|
6561
|
+
case 'below':
|
|
6562
|
+
default:
|
|
6563
|
+
return {
|
|
6564
|
+
originY: overlapTrigger ? 'top' : 'bottom',
|
|
6565
|
+
overlayY: 'top',
|
|
6566
|
+
};
|
|
6517
6567
|
}
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6568
|
+
}
|
|
6569
|
+
getFallbackXPosition(position) {
|
|
6570
|
+
switch (position) {
|
|
6571
|
+
case 'start':
|
|
6572
|
+
return 'end';
|
|
6573
|
+
case 'end':
|
|
6574
|
+
return 'start';
|
|
6575
|
+
case 'before':
|
|
6576
|
+
return 'after';
|
|
6577
|
+
case 'after':
|
|
6578
|
+
return 'before';
|
|
6579
|
+
case 'center':
|
|
6580
|
+
default:
|
|
6581
|
+
return 'center';
|
|
6524
6582
|
}
|
|
6525
|
-
from?.classList.add(SCRIM_INSTANT_CLASS);
|
|
6526
|
-
from?.classList.remove(SCRIM_KEPT_CLASS);
|
|
6527
|
-
to?.classList.add(SCRIM_INSTANT_CLASS);
|
|
6528
6583
|
}
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
const from = fromRef.overlayRef.backdropElement;
|
|
6532
|
-
const to = toRef.overlayRef.backdropElement;
|
|
6533
|
-
requestAnimationFrame(() => {
|
|
6534
|
-
from?.classList.remove(SCRIM_INSTANT_CLASS);
|
|
6535
|
-
to?.classList.remove(SCRIM_INSTANT_CLASS);
|
|
6536
|
-
});
|
|
6584
|
+
getSubMenuXPosition(position) {
|
|
6585
|
+
return position === 'before' ? 'before' : 'after';
|
|
6537
6586
|
}
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6587
|
+
getFallbackYPosition(position) {
|
|
6588
|
+
switch (position) {
|
|
6589
|
+
case 'above':
|
|
6590
|
+
return 'below';
|
|
6591
|
+
case 'below':
|
|
6592
|
+
return 'above';
|
|
6593
|
+
case 'center':
|
|
6594
|
+
default:
|
|
6595
|
+
return 'center';
|
|
6541
6596
|
}
|
|
6542
|
-
// setInput runs Angular's normal input pipeline, so input setters,
|
|
6543
|
-
// transforms, signal inputs, and change detection are handled for us.
|
|
6544
|
-
Object.entries(config.data).forEach(([inputName, inputValue]) => {
|
|
6545
|
-
componentRef.setInput(inputName, inputValue);
|
|
6546
|
-
});
|
|
6547
6597
|
}
|
|
6548
|
-
|
|
6549
|
-
return
|
|
6598
|
+
getSubMenuVerticalAlignment(position) {
|
|
6599
|
+
return position === 'above' ? 'bottom' : 'top';
|
|
6550
6600
|
}
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
if (!this.refs[index].isClosing) {
|
|
6555
|
-
return this.refs[index];
|
|
6556
|
-
}
|
|
6601
|
+
getOriginClientRect(origin) {
|
|
6602
|
+
if ('getBoundingClientRect' in origin) {
|
|
6603
|
+
return origin.getBoundingClientRect();
|
|
6557
6604
|
}
|
|
6558
|
-
return
|
|
6605
|
+
return {
|
|
6606
|
+
x: origin.x,
|
|
6607
|
+
y: origin.y,
|
|
6608
|
+
top: origin.y,
|
|
6609
|
+
right: origin.x,
|
|
6610
|
+
bottom: origin.y,
|
|
6611
|
+
left: origin.x,
|
|
6612
|
+
width: 0,
|
|
6613
|
+
height: 0,
|
|
6614
|
+
};
|
|
6559
6615
|
}
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
*/
|
|
6564
|
-
topRegularRef() {
|
|
6565
|
-
const ref = this.topRef();
|
|
6566
|
-
return ref?.isFullScreen ? undefined : ref;
|
|
6616
|
+
getViewportMargin(configuredMargin) {
|
|
6617
|
+
const minimumMargin = this.getHalfEmInPixels();
|
|
6618
|
+
return Math.max(configuredMargin ?? minimumMargin, minimumMargin);
|
|
6567
6619
|
}
|
|
6568
|
-
|
|
6569
|
-
const
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
for (let previousIndex = index - 1; previousIndex >= 0; previousIndex--) {
|
|
6574
|
-
const previousRef = this.refs[previousIndex];
|
|
6575
|
-
if (previousRef.isClosing) {
|
|
6576
|
-
continue;
|
|
6577
|
-
}
|
|
6578
|
-
// The closing dialog gets the same head start it was given when it
|
|
6579
|
-
// took the screen, and keeps the scrim until then. Nothing to keep
|
|
6580
|
-
// when the dialog underneath has no scrim of its own.
|
|
6581
|
-
if (previousRef.overlayRef.backdropElement) {
|
|
6582
|
-
ref.overlayRef.backdropElement?.classList.add(SCRIM_KEPT_CLASS);
|
|
6583
|
-
}
|
|
6584
|
-
setTimeout(() => {
|
|
6585
|
-
this.showHostFullScreenDialog(previousRef);
|
|
6586
|
-
this.startRestoringAnimation(ref, previousRef);
|
|
6587
|
-
}, DIALOG_HANDOVER_DELAY_MS);
|
|
6588
|
-
return;
|
|
6589
|
-
}
|
|
6620
|
+
getHalfEmInPixels() {
|
|
6621
|
+
const viewport = this.document.defaultView;
|
|
6622
|
+
const fontSize = viewport?.getComputedStyle(this.document.documentElement).fontSize;
|
|
6623
|
+
const pixels = fontSize ? Number.parseFloat(fontSize) * 0.5 : 8;
|
|
6624
|
+
return Number.isFinite(pixels) ? pixels : 8;
|
|
6590
6625
|
}
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
* `previousDialog: 'hide'`, so the context has to be on screen again before
|
|
6595
|
-
* the dialog that sits on top of it, exactly as showAll() puts them back.
|
|
6596
|
-
*/
|
|
6597
|
-
showHostFullScreenDialog(ref) {
|
|
6598
|
-
if (ref.isFullScreen) {
|
|
6599
|
-
return;
|
|
6600
|
-
}
|
|
6601
|
-
const hostRef = this.fullScreenDialog;
|
|
6602
|
-
if (hostRef?.isHidden && this.refs.indexOf(hostRef) < this.refs.indexOf(ref)) {
|
|
6603
|
-
hostRef.show();
|
|
6626
|
+
getOffsetY(position, config) {
|
|
6627
|
+
if (config.overlapTrigger || position === 'center') {
|
|
6628
|
+
return 0;
|
|
6604
6629
|
}
|
|
6630
|
+
return position === 'above'
|
|
6631
|
+
? config.offsetY * -1
|
|
6632
|
+
: config.offsetY;
|
|
6605
6633
|
}
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
if (index === -1) {
|
|
6609
|
-
return;
|
|
6610
|
-
}
|
|
6611
|
-
this.refs.splice(index, 1);
|
|
6612
|
-
if (this.refs.length === 0) {
|
|
6613
|
-
this.rootTrigger = null;
|
|
6614
|
-
}
|
|
6615
|
-
this.syncPageState();
|
|
6634
|
+
getSubMenuOffsetX(position, offsetX) {
|
|
6635
|
+
return position === 'before' ? offsetX * -1 : offsetX;
|
|
6616
6636
|
}
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
* page scrolling, the page being hidden from assistive technology, and
|
|
6620
|
-
* where focus sits. Applied in a task of its own, so a dialog handing the
|
|
6621
|
-
* screen over to another one does not give the page back and take it again
|
|
6622
|
-
* within the same frame.
|
|
6623
|
-
*/
|
|
6624
|
-
syncPageState() {
|
|
6625
|
-
if (this.pageStateQueued) {
|
|
6626
|
-
return;
|
|
6627
|
-
}
|
|
6628
|
-
this.pageStateQueued = true;
|
|
6629
|
-
setTimeout(() => {
|
|
6630
|
-
this.pageStateQueued = false;
|
|
6631
|
-
this.applyPageState();
|
|
6632
|
-
});
|
|
6637
|
+
getSubMenuOffsetY(alignment, offsetY) {
|
|
6638
|
+
return alignment === 'bottom' ? offsetY * -1 : offsetY;
|
|
6633
6639
|
}
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
this.pageAriaHidden.clear();
|
|
6646
|
-
return;
|
|
6647
|
-
}
|
|
6648
|
-
if (hasVisibleDialog) {
|
|
6649
|
-
this.hidePageFromAssistiveTechnology();
|
|
6650
|
-
return;
|
|
6640
|
+
getScrollStrategy(scrollStrategy) {
|
|
6641
|
+
switch (scrollStrategy) {
|
|
6642
|
+
case 'block':
|
|
6643
|
+
return this.overlay.scrollStrategies.block();
|
|
6644
|
+
case 'close':
|
|
6645
|
+
return this.overlay.scrollStrategies.close();
|
|
6646
|
+
case 'noop':
|
|
6647
|
+
return this.overlay.scrollStrategies.noop();
|
|
6648
|
+
case 'reposition':
|
|
6649
|
+
default:
|
|
6650
|
+
return this.overlay.scrollStrategies.reposition();
|
|
6651
6651
|
}
|
|
6652
|
-
this.exposePageToAssistiveTechnology();
|
|
6653
|
-
this.releaseFocus();
|
|
6654
6652
|
}
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6653
|
+
isMouseEvent(origin) {
|
|
6654
|
+
return typeof MouseEvent !== 'undefined' && origin instanceof MouseEvent;
|
|
6655
|
+
}
|
|
6656
|
+
isElementRef(origin) {
|
|
6657
|
+
return typeof origin === 'object'
|
|
6658
|
+
&& origin !== null
|
|
6659
|
+
&& 'nativeElement' in origin
|
|
6660
|
+
&& origin.nativeElement instanceof HTMLElement;
|
|
6661
|
+
}
|
|
6662
|
+
startOpenAnimation(overlayRef) {
|
|
6663
|
+
const panel = overlayRef.overlayElement;
|
|
6664
|
+
const backdrop = overlayRef.backdropElement;
|
|
6665
|
+
// The overlay is inserted already rendered. Keep an initial class for
|
|
6666
|
+
// one frame, force style calculation, then remove it so CSS transitions
|
|
6667
|
+
// have a real from/to state.
|
|
6668
|
+
requestAnimationFrame(() => {
|
|
6669
|
+
setTimeout(() => {
|
|
6670
|
+
panel.getBoundingClientRect();
|
|
6671
|
+
panel.classList.remove('md3-menu-opening');
|
|
6672
|
+
backdrop?.classList.remove('md3-menu-opening');
|
|
6673
|
+
}, 100);
|
|
6674
|
+
});
|
|
6675
|
+
}
|
|
6676
|
+
createInjector(component, config, menuRef) {
|
|
6677
|
+
return Injector.create({
|
|
6678
|
+
parent: config.injector,
|
|
6679
|
+
providers: [
|
|
6680
|
+
// These tokens make the menu controllable from the dynamic
|
|
6681
|
+
// component without coupling that component to the service.
|
|
6682
|
+
{ provide: MenuRef, useValue: menuRef },
|
|
6683
|
+
{ provide: MENU_DATA, useValue: config.data },
|
|
6684
|
+
{ provide: MENU_CONFIG, useValue: config },
|
|
6685
|
+
{ provide: MENU_COMPONENT, useValue: component },
|
|
6686
|
+
],
|
|
6672
6687
|
});
|
|
6673
6688
|
}
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6689
|
+
bindDataToInputs(componentRef, config) {
|
|
6690
|
+
if (!config.bindDataToInputs || !this.canBindDataToInputs(config.data)) {
|
|
6691
|
+
return;
|
|
6692
|
+
}
|
|
6693
|
+
// setInput runs Angular's normal input pipeline, so input setters,
|
|
6694
|
+
// transforms, signal inputs, and change detection are handled for us.
|
|
6695
|
+
Object.entries(config.data).forEach(([inputName, inputValue]) => {
|
|
6696
|
+
componentRef.setInput(inputName, inputValue);
|
|
6678
6697
|
});
|
|
6679
|
-
this.pageAriaHidden.clear();
|
|
6680
6698
|
}
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6699
|
+
connectCloseEvents(overlayRef, menuRef, origin) {
|
|
6700
|
+
overlayRef.backdropClick().pipe(take(1)).subscribe(() => menuRef.close());
|
|
6701
|
+
overlayRef.keydownEvents().pipe(filter((event) => event.key === 'Escape'), take(1)).subscribe(() => menuRef.close());
|
|
6702
|
+
if (this.isSelectInput(origin)) {
|
|
6703
|
+
const originRect = this.getOriginClientRect(origin);
|
|
6704
|
+
overlayRef.outsidePointerEvents().pipe(filter((event) => {
|
|
6705
|
+
const clickedInsideOrigin = event.clientX >= originRect.left &&
|
|
6706
|
+
event.clientX <= originRect.right &&
|
|
6707
|
+
event.clientY >= originRect.top &&
|
|
6708
|
+
event.clientY <= originRect.bottom;
|
|
6709
|
+
return !clickedInsideOrigin;
|
|
6710
|
+
})).subscribe(() => menuRef.close());
|
|
6690
6711
|
}
|
|
6691
6712
|
}
|
|
6692
6713
|
getFocusedElement() {
|
|
6693
6714
|
const activeElement = this.document.activeElement;
|
|
6694
6715
|
return activeElement instanceof HTMLElement ? activeElement : null;
|
|
6695
6716
|
}
|
|
6696
|
-
|
|
6697
|
-
|
|
6717
|
+
canBindDataToInputs(data) {
|
|
6718
|
+
return typeof data === 'object' && data !== null && !Array.isArray(data);
|
|
6719
|
+
}
|
|
6720
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
6721
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuService, providedIn: 'root' });
|
|
6698
6722
|
}
|
|
6699
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type:
|
|
6723
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuService, decorators: [{
|
|
6700
6724
|
type: Injectable,
|
|
6701
6725
|
args: [{
|
|
6702
6726
|
providedIn: 'root',
|
|
6703
6727
|
}]
|
|
6704
6728
|
}] });
|
|
6705
6729
|
|
|
6706
|
-
class
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
}
|
|
6710
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogHeader, decorators: [{
|
|
6711
|
-
type: Component,
|
|
6712
|
-
args: [{ selector: 'md3-dialog-header', imports: [
|
|
6713
|
-
TypeHeadline
|
|
6714
|
-
], template: "<ng-content select=\"[md3-icon-element]\"></ng-content>\n<div class=\"md3-dialog-title\">\n <md3-type-headline size=\"small\">\n <ng-content></ng-content>\n </md3-type-headline>\n</div>", styles: [":host{display:block;margin:1.5em 1.5em 1em;text-align:center}:host .md3-dialog-title{text-align:start;color:rgb(var(--md-scheme-on-surface))}:host ::ng-deep [md3-icon-element]{color:rgb(var(--md-scheme-secondary))}:host ::ng-deep [md3-icon-element]+.md3-dialog-title{margin-top:1em;text-align:center}\n"] }]
|
|
6715
|
-
}] });
|
|
6716
|
-
|
|
6717
|
-
class DialogBody {
|
|
6718
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogBody, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6719
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type: DialogBody, isStandalone: true, selector: "md3-dialog-body", host: { classAttribute: "md3-scrollable" }, ngImport: i0, template: "<ng-content></ng-content>", styles: [":host{display:block;margin:1em 1.5em 1.5em;color:rgb(var(--md-scheme-on-surface-variant))}:host .md3-text-body.md3-text-medium{letter-spacing:.017857em}\n"] });
|
|
6720
|
-
}
|
|
6721
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogBody, decorators: [{
|
|
6722
|
-
type: Component,
|
|
6723
|
-
args: [{ selector: 'md3-dialog-body', imports: [], host: {
|
|
6724
|
-
'class': 'md3-scrollable',
|
|
6725
|
-
}, template: "<ng-content></ng-content>", styles: [":host{display:block;margin:1em 1.5em 1.5em;color:rgb(var(--md-scheme-on-surface-variant))}:host .md3-text-body.md3-text-medium{letter-spacing:.017857em}\n"] }]
|
|
6726
|
-
}] });
|
|
6727
|
-
|
|
6728
|
-
class DialogActions {
|
|
6729
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogActions, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6730
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type: DialogActions, isStandalone: true, selector: "md3-dialog-actions", ngImport: i0, template: "<div class=\"md3-actions\">\n <ng-content></ng-content>\n</div>", styles: [":host{display:block;margin:1.5em}:host .md3-actions{display:flex;gap:1em;flex-direction:row-reverse}\n"] });
|
|
6731
|
-
}
|
|
6732
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogActions, decorators: [{
|
|
6733
|
-
type: Component,
|
|
6734
|
-
args: [{ selector: 'md3-dialog-actions', imports: [], template: "<div class=\"md3-actions\">\n <ng-content></ng-content>\n</div>", styles: [":host{display:block;margin:1.5em}:host .md3-actions{display:flex;gap:1em;flex-direction:row-reverse}\n"] }]
|
|
6735
|
-
}] });
|
|
6736
|
-
|
|
6737
|
-
const MENU_DATA = new InjectionToken('MD3_MENU_DATA');
|
|
6738
|
-
const MENU_CONFIG = new InjectionToken('MD3_MENU_CONFIG');
|
|
6739
|
-
const MENU_COMPONENT = new InjectionToken('MD3_MENU_COMPONENT');
|
|
6740
|
-
const MENU_EXIT_ANIMATION_FALLBACK_MS = 300;
|
|
6741
|
-
class MenuRef {
|
|
6742
|
-
overlayRef;
|
|
6743
|
-
previouslyFocusedElement;
|
|
6744
|
-
closed = new Subject();
|
|
6745
|
-
isClosed = false;
|
|
6746
|
-
menuInstance;
|
|
6730
|
+
class SelectField {
|
|
6731
|
+
menuService;
|
|
6732
|
+
viewContainerRef;
|
|
6747
6733
|
/**
|
|
6748
|
-
*
|
|
6749
|
-
*
|
|
6734
|
+
* Form directive placed on the host element: [formControl], formControlName or [(ngModel)].
|
|
6735
|
+
* The accessor is registered from the constructor instead of through an NG_VALUE_ACCESSOR
|
|
6736
|
+
* provider, which keeps the directive injectable here and gives access to the control
|
|
6737
|
+
* itself for the error state forwarded to md3-text-field.
|
|
6750
6738
|
*/
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
}
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
6739
|
+
ngControl = inject(NgControl, { self: true, optional: true });
|
|
6740
|
+
options = input.required(/* @ts-ignore */
|
|
6741
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
6742
|
+
multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
6743
|
+
label = input(null, { ...(ngDevMode ? { debugName: "label" } : /* istanbul ignore next */ {}), alias: 'label' });
|
|
6744
|
+
/**
|
|
6745
|
+
* Formats the text shown in the field. The default joins the labels of the selected
|
|
6746
|
+
* options with a comma, so the field shows as many labels as its width allows.
|
|
6747
|
+
* The formatter is not called for an empty selection: the field stays empty, which keeps
|
|
6748
|
+
* the floating label in its place.
|
|
6749
|
+
*/
|
|
6750
|
+
displayWith = input(null, { ...(ngDevMode ? { debugName: "displayWith" } : /* istanbul ignore next */ {}), alias: 'display-with' });
|
|
6751
|
+
/**
|
|
6752
|
+
* Disables the field outside of a form. With reactive forms prefer control.disable().
|
|
6753
|
+
*/
|
|
6754
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
6755
|
+
menuColors = input('standard', { ...(ngDevMode ? { debugName: "menuColors" } : /* istanbul ignore next */ {}), alias: 'menu-colors' });
|
|
6756
|
+
fieldType = input('filled', { ...(ngDevMode ? { debugName: "fieldType" } : /* istanbul ignore next */ {}), alias: 'field-type' });
|
|
6757
|
+
/**
|
|
6758
|
+
* Control passed explicitly, mirroring md3-text-field. Takes precedence over a form
|
|
6759
|
+
* directive on the host element.
|
|
6760
|
+
*/
|
|
6761
|
+
control = input(undefined, { ...(ngDevMode ? { debugName: "control" } : /* istanbul ignore next */ {}), alias: 'control' });
|
|
6762
|
+
iconElements = contentChildren(IconElement, { ...(ngDevMode ? { debugName: "iconElements" } : /* istanbul ignore next */ {}), descendants: true });
|
|
6763
|
+
hasLeadingIcon = computed(() => this.iconElements().some(i => i.iconType() === 'leading') ?? false, /* @ts-ignore */
|
|
6764
|
+
...(ngDevMode ? [{ debugName: "hasLeadingIcon" }] : /* istanbul ignore next */ []));
|
|
6765
|
+
hasArrowIcon = computed(() => this.iconElements().some(i => i.iconType() === 'arrow') ?? false, /* @ts-ignore */
|
|
6766
|
+
...(ngDevMode ? [{ debugName: "hasArrowIcon" }] : /* istanbul ignore next */ []));
|
|
6767
|
+
isMenuOpen = signal(false, /* @ts-ignore */
|
|
6768
|
+
...(ngDevMode ? [{ debugName: "isMenuOpen" }] : /* istanbul ignore next */ []));
|
|
6769
|
+
menuRef = null;
|
|
6770
|
+
inputElement = viewChild(InputElement, { ...(ngDevMode ? { debugName: "inputElement" } : /* istanbul ignore next */ {}), read: ElementRef });
|
|
6771
|
+
/** Control resolved from the host form directive, captured when the accessor is wired up. */
|
|
6772
|
+
hostControl = signal(undefined, /* @ts-ignore */
|
|
6773
|
+
...(ngDevMode ? [{ debugName: "hostControl" }] : /* istanbul ignore next */ []));
|
|
6774
|
+
/** Disabled state pushed by the control, either through setDisabledState or control.disabled. */
|
|
6775
|
+
controlDisabled = signal(false, /* @ts-ignore */
|
|
6776
|
+
...(ngDevMode ? [{ debugName: "controlDisabled" }] : /* istanbul ignore next */ []));
|
|
6777
|
+
/**
|
|
6778
|
+
* Set as soon as a control writes a value. From then on the control owns the selection and
|
|
6779
|
+
* SelectOption.selected no longer seeds it.
|
|
6780
|
+
*/
|
|
6781
|
+
controlOwnsValue = false;
|
|
6782
|
+
onChange = () => { };
|
|
6783
|
+
onTouched = () => { };
|
|
6784
|
+
/** Selection is kept by value so it survives options arriving or being replaced later. */
|
|
6785
|
+
selectedValues = signal([], /* @ts-ignore */
|
|
6786
|
+
...(ngDevMode ? [{ debugName: "selectedValues" }] : /* istanbul ignore next */ []));
|
|
6787
|
+
formControl = computed(() => this.control() ?? this.hostControl(), /* @ts-ignore */
|
|
6788
|
+
...(ngDevMode ? [{ debugName: "formControl" }] : /* istanbul ignore next */ []));
|
|
6789
|
+
isDisabled = computed(() => this.disabled() || this.controlDisabled(), /* @ts-ignore */
|
|
6790
|
+
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
6791
|
+
selectedOptions = computed(() => {
|
|
6792
|
+
const values = this.selectedValues();
|
|
6793
|
+
return this.options().filter((option) => values.includes(option.value));
|
|
6794
|
+
}, /* @ts-ignore */
|
|
6795
|
+
...(ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ []));
|
|
6796
|
+
selectedText = computed(() => {
|
|
6797
|
+
const selected = this.selectedOptions();
|
|
6798
|
+
if (selected.length == 0) {
|
|
6799
|
+
return null;
|
|
6759
6800
|
}
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
function done() {
|
|
6779
|
-
if (isResolved) {
|
|
6801
|
+
const format = this.displayWith();
|
|
6802
|
+
if (format) {
|
|
6803
|
+
return format(selected);
|
|
6804
|
+
}
|
|
6805
|
+
return selected.map((option) => option.label).join(', ');
|
|
6806
|
+
}, /* @ts-ignore */
|
|
6807
|
+
...(ngDevMode ? [{ debugName: "selectedText" }] : /* istanbul ignore next */ []));
|
|
6808
|
+
constructor(menuService, viewContainerRef) {
|
|
6809
|
+
this.menuService = menuService;
|
|
6810
|
+
this.viewContainerRef = viewContainerRef;
|
|
6811
|
+
if (this.ngControl) {
|
|
6812
|
+
this.ngControl.valueAccessor = this;
|
|
6813
|
+
}
|
|
6814
|
+
// Seeds the selection from SelectOption.selected while no control owns the value.
|
|
6815
|
+
effect(() => {
|
|
6816
|
+
const options = this.options();
|
|
6817
|
+
untracked(() => {
|
|
6818
|
+
if (this.controlOwnsValue) {
|
|
6780
6819
|
return;
|
|
6781
6820
|
}
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
resolve();
|
|
6786
|
-
}
|
|
6787
|
-
function onTransitionEnd(event) {
|
|
6788
|
-
if (event.target === animatedElement) {
|
|
6789
|
-
done();
|
|
6821
|
+
let selected = options.filter((option) => option.selected);
|
|
6822
|
+
if (!this.multiple() && selected.length > 1) {
|
|
6823
|
+
selected = [selected[0]];
|
|
6790
6824
|
}
|
|
6825
|
+
this.setSelectedValues(selected.map((option) => option.value));
|
|
6826
|
+
});
|
|
6827
|
+
});
|
|
6828
|
+
// Mirrors the selection back onto SelectOption.selected so the menu renders it.
|
|
6829
|
+
effect(() => {
|
|
6830
|
+
const values = this.selectedValues();
|
|
6831
|
+
for (const option of this.options()) {
|
|
6832
|
+
option.selected = values.includes(option.value);
|
|
6791
6833
|
}
|
|
6792
|
-
|
|
6834
|
+
});
|
|
6835
|
+
// [control] is bound manually; [formControl]/formControlName go through the accessor API.
|
|
6836
|
+
effect((onCleanup) => {
|
|
6837
|
+
const control = this.control();
|
|
6838
|
+
if (!control) {
|
|
6839
|
+
return;
|
|
6840
|
+
}
|
|
6841
|
+
this.syncFromControl(control);
|
|
6842
|
+
const controlEvents = control.events.subscribe(() => this.syncFromControl(control));
|
|
6843
|
+
onCleanup(() => controlEvents.unsubscribe());
|
|
6844
|
+
});
|
|
6845
|
+
effect(() => {
|
|
6846
|
+
const isOpen = this.isMenuOpen();
|
|
6847
|
+
untracked(() => {
|
|
6848
|
+
if (isOpen) {
|
|
6849
|
+
this.openSelectOptions();
|
|
6850
|
+
return;
|
|
6851
|
+
}
|
|
6852
|
+
this.menuRef?.close();
|
|
6853
|
+
this.menuRef = null;
|
|
6854
|
+
});
|
|
6793
6855
|
});
|
|
6794
6856
|
}
|
|
6795
|
-
|
|
6796
|
-
|
|
6857
|
+
// ControlValueAccessor
|
|
6858
|
+
writeValue(value) {
|
|
6859
|
+
this.captureHostControl();
|
|
6860
|
+
this.controlOwnsValue = true;
|
|
6861
|
+
this.setSelectedValues(this.normalizeValues(value));
|
|
6862
|
+
}
|
|
6863
|
+
registerOnChange(fn) {
|
|
6864
|
+
this.captureHostControl();
|
|
6865
|
+
this.onChange = fn;
|
|
6866
|
+
}
|
|
6867
|
+
registerOnTouched(fn) {
|
|
6868
|
+
this.onTouched = fn;
|
|
6869
|
+
}
|
|
6870
|
+
setDisabledState(isDisabled) {
|
|
6871
|
+
this.controlDisabled.set(isDisabled);
|
|
6872
|
+
}
|
|
6873
|
+
// Menu
|
|
6874
|
+
openMenu() {
|
|
6875
|
+
if (this.isDisabled()) {
|
|
6876
|
+
return;
|
|
6877
|
+
}
|
|
6878
|
+
this.isMenuOpen.set(true);
|
|
6879
|
+
}
|
|
6880
|
+
closeMenu() {
|
|
6881
|
+
this.isMenuOpen.set(false);
|
|
6882
|
+
}
|
|
6883
|
+
toggleMenu() {
|
|
6884
|
+
if (this.isDisabled()) {
|
|
6885
|
+
return;
|
|
6886
|
+
}
|
|
6887
|
+
this.isMenuOpen.update(current => !current);
|
|
6888
|
+
}
|
|
6889
|
+
openSelectOptions() {
|
|
6890
|
+
this.menuRef = this.menuService.open(SelectOptions, {
|
|
6891
|
+
data: {
|
|
6892
|
+
options: this.options(),
|
|
6893
|
+
multiple: this.multiple(),
|
|
6894
|
+
},
|
|
6895
|
+
bindDataToInputs: true,
|
|
6896
|
+
menuColors: this.menuColors(),
|
|
6897
|
+
origin: this.inputElement(),
|
|
6898
|
+
xPosition: 'start',
|
|
6899
|
+
yPosition: 'below',
|
|
6900
|
+
overlapTrigger: false,
|
|
6901
|
+
// scrollStrategy: 'close',
|
|
6902
|
+
viewContainerRef: this.viewContainerRef,
|
|
6903
|
+
});
|
|
6904
|
+
this.menuRef.componentInstance?.selectionChange.subscribe((values) => this.selectValues(values));
|
|
6905
|
+
this.menuRef.afterClosed().subscribe(() => {
|
|
6906
|
+
this.isMenuOpen.set(false);
|
|
6907
|
+
this.markAsTouched();
|
|
6908
|
+
});
|
|
6909
|
+
}
|
|
6910
|
+
// Selection
|
|
6911
|
+
selectValues(values) {
|
|
6912
|
+
this.setSelectedValues(this.normalizeValues(values));
|
|
6913
|
+
this.commitValue();
|
|
6914
|
+
}
|
|
6915
|
+
setSelectedValues(values) {
|
|
6916
|
+
const current = untracked(this.selectedValues);
|
|
6917
|
+
if (current.length === values.length && current.every((value, index) => value === values[index])) {
|
|
6918
|
+
return;
|
|
6919
|
+
}
|
|
6920
|
+
this.selectedValues.set(values);
|
|
6921
|
+
}
|
|
6922
|
+
commitValue() {
|
|
6923
|
+
const value = this.currentValue();
|
|
6924
|
+
// No-op unless a form directive registered an accessor callback.
|
|
6925
|
+
this.onChange(value);
|
|
6926
|
+
const control = this.control();
|
|
6927
|
+
if (control && !this.valuesAreEqual(control.value, value)) {
|
|
6928
|
+
control.markAsDirty();
|
|
6929
|
+
control.setValue(value);
|
|
6930
|
+
}
|
|
6931
|
+
}
|
|
6932
|
+
currentValue() {
|
|
6933
|
+
const values = untracked(this.selectedValues);
|
|
6934
|
+
if (this.multiple()) {
|
|
6935
|
+
return [...values];
|
|
6936
|
+
}
|
|
6937
|
+
return values.length > 0 ? values[0] : null;
|
|
6938
|
+
}
|
|
6939
|
+
markAsTouched() {
|
|
6940
|
+
this.onTouched();
|
|
6941
|
+
const control = this.control();
|
|
6942
|
+
if (control && !control.touched) {
|
|
6943
|
+
control.markAsTouched();
|
|
6944
|
+
}
|
|
6945
|
+
}
|
|
6946
|
+
syncFromControl(control) {
|
|
6947
|
+
this.controlOwnsValue = true;
|
|
6948
|
+
this.setSelectedValues(this.normalizeValues(control.value));
|
|
6949
|
+
this.controlDisabled.set(control.disabled);
|
|
6950
|
+
}
|
|
6951
|
+
captureHostControl() {
|
|
6952
|
+
const control = this.ngControl?.control ?? undefined;
|
|
6953
|
+
if (control && untracked(this.hostControl) !== control) {
|
|
6954
|
+
this.hostControl.set(control);
|
|
6955
|
+
}
|
|
6956
|
+
}
|
|
6957
|
+
/**
|
|
6958
|
+
* Accepts whatever a control holds and reduces it to the option values this field can show:
|
|
6959
|
+
* a single value for single selection, a de-duplicated list for multiple selection.
|
|
6960
|
+
*/
|
|
6961
|
+
normalizeValues(value) {
|
|
6962
|
+
const values = (Array.isArray(value) ? value : [value])
|
|
6963
|
+
.filter((item) => typeof item === 'string' || typeof item === 'number');
|
|
6964
|
+
const unique = [...new Set(values)];
|
|
6965
|
+
return this.multiple() ? unique : unique.slice(0, 1);
|
|
6966
|
+
}
|
|
6967
|
+
valuesAreEqual(current, next) {
|
|
6968
|
+
if (Array.isArray(current) && Array.isArray(next)) {
|
|
6969
|
+
return current.length === next.length && current.every((value, index) => value === next[index]);
|
|
6970
|
+
}
|
|
6971
|
+
return current === next;
|
|
6797
6972
|
}
|
|
6973
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SelectField, deps: [{ token: MenuService }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
6974
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: SelectField, isStandalone: true, selector: "md3-select-field", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "display-with", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, menuColors: { classPropertyName: "menuColors", publicName: "menu-colors", isSignal: true, isRequired: false, transformFunction: null }, fieldType: { classPropertyName: "fieldType", publicName: "field-type", isSignal: true, isRequired: false, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "iconElements", predicate: IconElement, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputElement", first: true, predicate: InputElement, descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<md3-text-field [label]=\"label()\" [field-type]=\"fieldType()\" [control]=\"formControl()\">\n <!-- <md3-icon md3-icon-element=\"leading\">search</md3-icon> -->\n @if (hasLeadingIcon()) {\n <div md3-icon-element=\"leading\">\n <ng-content select=\"[md3-icon-element=leading]\"></ng-content>\n </div>\n }\n\n <input md3-input-element type=\"text\" [readonly]=\"true\" [disabled]=\"isDisabled()\" (click)=\"openMenu()\" class=\"md3-select-input\" [class.md3-menu-active]=\"isMenuOpen()\" [value]=\"selectedText()\">\n\n <button md3-icon-button button-type=\"standard\" [disabled]=\"isDisabled()\" (click)=\"toggleMenu()\" class=\"md3-select-arrow\">\n @if (hasArrowIcon()) {\n <ng-content select=\"[md3-icon-element=arrow]\"></ng-content>\n } @else {\n <md3-icon md3-icon-element>arrow_drop_down</md3-icon>\n }\n </button>\n\n <ng-content select=\"[md3-supporting-text]\" ngProjectAs=\"[md3-supporting-text]\"></ng-content>\n</md3-text-field>\n", styles: [".md3-select-input{text-overflow:ellipsis}.md3-select-input:read-only{cursor:default;-webkit-user-select:none;user-select:none}.md3-select-input~.md3-select-arrow{transition:transform var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}.md3-select-input.md3-menu-active:dir(ltr)~.md3-select-arrow{transform:rotate(180deg)}.md3-select-input.md3-menu-active:dir(rtl)~.md3-select-arrow{transform:rotate(-180deg)}\n"], dependencies: [{ kind: "component", type: TextField, selector: "md3-text-field", inputs: ["label", "field-type", "input-counter", "control"] }, { kind: "directive", type: IconElement, selector: "[md3-icon-element]", inputs: ["md3-icon-element"] }, { kind: "component", type: IconButton, selector: "button[md3-icon-button], a[md3-icon-button]", inputs: ["button-size", "button-type", "button-width", "button-squared", "selected"], outputs: ["selectedChange"] }, { kind: "directive", type: InputElement, selector: "[md3-input-element]" }, { kind: "component", type: MaterialIcon, selector: "md3-icon", inputs: ["icon-version", "filled", "icon-style", "icon-size", "bi-directional"] }] });
|
|
6798
6975
|
}
|
|
6976
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SelectField, decorators: [{
|
|
6977
|
+
type: Component,
|
|
6978
|
+
args: [{ selector: 'md3-select-field', imports: [
|
|
6979
|
+
TextField,
|
|
6980
|
+
IconElement,
|
|
6981
|
+
IconButton,
|
|
6982
|
+
InputElement,
|
|
6983
|
+
MaterialIcon,
|
|
6984
|
+
], template: "<md3-text-field [label]=\"label()\" [field-type]=\"fieldType()\" [control]=\"formControl()\">\n <!-- <md3-icon md3-icon-element=\"leading\">search</md3-icon> -->\n @if (hasLeadingIcon()) {\n <div md3-icon-element=\"leading\">\n <ng-content select=\"[md3-icon-element=leading]\"></ng-content>\n </div>\n }\n\n <input md3-input-element type=\"text\" [readonly]=\"true\" [disabled]=\"isDisabled()\" (click)=\"openMenu()\" class=\"md3-select-input\" [class.md3-menu-active]=\"isMenuOpen()\" [value]=\"selectedText()\">\n\n <button md3-icon-button button-type=\"standard\" [disabled]=\"isDisabled()\" (click)=\"toggleMenu()\" class=\"md3-select-arrow\">\n @if (hasArrowIcon()) {\n <ng-content select=\"[md3-icon-element=arrow]\"></ng-content>\n } @else {\n <md3-icon md3-icon-element>arrow_drop_down</md3-icon>\n }\n </button>\n\n <ng-content select=\"[md3-supporting-text]\" ngProjectAs=\"[md3-supporting-text]\"></ng-content>\n</md3-text-field>\n", styles: [".md3-select-input{text-overflow:ellipsis}.md3-select-input:read-only{cursor:default;-webkit-user-select:none;user-select:none}.md3-select-input~.md3-select-arrow{transition:transform var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}.md3-select-input.md3-menu-active:dir(ltr)~.md3-select-arrow{transform:rotate(180deg)}.md3-select-input.md3-menu-active:dir(rtl)~.md3-select-arrow{transform:rotate(-180deg)}\n"] }]
|
|
6985
|
+
}], ctorParameters: () => [{ type: MenuService }, { type: i0.ViewContainerRef }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], displayWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "display-with", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], menuColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "menu-colors", required: false }] }], fieldType: [{ type: i0.Input, args: [{ isSignal: true, alias: "field-type", required: false }] }], control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: false }] }], iconElements: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => IconElement), { ...{ descendants: true }, isSignal: true }] }], inputElement: [{ type: i0.ViewChild, args: [i0.forwardRef(() => InputElement), { ...{ read: ElementRef }, isSignal: true }] }] } });
|
|
6799
6986
|
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
scheme = signal('inherit', /* @ts-ignore */
|
|
6810
|
-
...(ngDevMode ? [{ debugName: "scheme" }] : /* istanbul ignore next */ []));
|
|
6811
|
-
direction = signal(null, /* @ts-ignore */
|
|
6812
|
-
...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
|
|
6813
|
-
isActive = signal(true, /* @ts-ignore */
|
|
6987
|
+
/**
|
|
6988
|
+
* Material 3 dialog shell. It extends the CDK dialog container, so focus
|
|
6989
|
+
* trapping, focus restoration and the ARIA attributes are handled by the CDK
|
|
6990
|
+
* while this component only owns the MD3 surface and its animation.
|
|
6991
|
+
*/
|
|
6992
|
+
class Dialog extends CdkDialogContainer {
|
|
6993
|
+
surface = viewChild('surface', /* @ts-ignore */
|
|
6994
|
+
...(ngDevMode ? [{ debugName: "surface" }] : /* istanbul ignore next */ []));
|
|
6995
|
+
isActive = signal(false, /* @ts-ignore */
|
|
6814
6996
|
...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
constructor(el) {
|
|
6819
|
-
this.el = el;
|
|
6820
|
-
effect((onCleanup) => {
|
|
6821
|
-
const color = 'md3-' + this.menuColors();
|
|
6822
|
-
this.element.classList.add(color);
|
|
6823
|
-
onCleanup(() => {
|
|
6824
|
-
this.element.classList.remove(color);
|
|
6825
|
-
});
|
|
6826
|
-
});
|
|
6827
|
-
this.menuColors.set(this.config.menuColors ?? 'standard');
|
|
6828
|
-
this.scheme.set(this.config.scheme ?? 'inherit');
|
|
6829
|
-
this.direction.set(this.config.direction ?? null);
|
|
6997
|
+
config = inject(DIALOG_CONFIG, { optional: true }) ?? {};
|
|
6998
|
+
get surfaceElement() {
|
|
6999
|
+
return this.surface()?.nativeElement ?? null;
|
|
6830
7000
|
}
|
|
6831
|
-
|
|
7001
|
+
/**
|
|
7002
|
+
* Started by DialogService, either right after the dialog is created or
|
|
7003
|
+
* once the dialog it replaces has had its head start. The animation runs on
|
|
7004
|
+
* the next frame so the surface has a real from/to state.
|
|
7005
|
+
*/
|
|
7006
|
+
startEnterAnimation() {
|
|
6832
7007
|
requestAnimationFrame(() => {
|
|
6833
|
-
this.
|
|
7008
|
+
this.isActive.set(true);
|
|
6834
7009
|
});
|
|
6835
7010
|
}
|
|
6836
|
-
|
|
6837
|
-
this.
|
|
7011
|
+
setActive(value) {
|
|
7012
|
+
this.isActive.set(value);
|
|
6838
7013
|
}
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
* the user supplied component into the dialog container.
|
|
6842
|
-
*/
|
|
6843
|
-
attachContent(component, injector) {
|
|
6844
|
-
const portal = new ComponentPortal(component, null, injector);
|
|
6845
|
-
return this.portalOutlet().attachComponentPortal(portal);
|
|
7014
|
+
recaptureFocus() {
|
|
7015
|
+
this._recaptureFocus();
|
|
6846
7016
|
}
|
|
6847
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type:
|
|
6848
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type:
|
|
7017
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Dialog, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
7018
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: Dialog, isStandalone: true, selector: "md3-dialog", viewQueries: [{ propertyName: "surface", first: true, predicate: ["surface"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- The role and aria attributes live on the host element, applied by the CDK dialog container. -->\n<div\n #surface\n class=\"md3-dialog-container\"\n [class.md3-active]=\"isActive()\"\n [class.md-scheme-dark]=\"config.scheme == 'dark'\"\n [class.md-scheme-light]=\"config.scheme == 'light'\"\n [attr.dir]=\"config.direction ?? null\">\n <ng-template cdkPortalOutlet></ng-template>\n</div>\n", styles: ["::ng-deep .cdk-overlay-container{position:fixed;z-index:1000;inset:0;pointer-events:none;font-size:1rem}::ng-deep .cdk-overlay-container .md3-dialog-scrim{position:absolute;inset:0;pointer-events:auto;background-color:rgb(var(--md-scheme-scrim));transition:all var(--md-motion-expressive-slow-spatial-duration) var(--md-motion-expressive-slow-spatial-easing);opacity:.32}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-opening{opacity:0}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-closing{opacity:0}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-hidden{opacity:0;pointer-events:none}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-scrim-kept{opacity:.32;transition:none}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-scrim-instant{transition:none}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper{position:absolute;display:flex;inset:0;pointer-events:none;padding:3.5rem 1.5rem;overflow:hidden}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-dialog-panel{position:absolute;pointer-events:auto;max-width:35em}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-dialog-panel.md3-dialog-closing,::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-dialog-panel.md3-dialog-hidden{pointer-events:none}:host{display:block;max-width:100%;min-width:17.5em;outline:0}:host .md3-dialog-container{display:block;width:100%;max-height:inherit;overflow:auto;color:rgb(var(--md-scheme-on-surface));background-color:rgb(var(--md-scheme-surface-container-high));border-radius:var(--md-border-radius-xlarge);box-shadow:var(--md-shadow-6dp);transform-origin:center;transition:all var(--md-motion-expressive-default-spatial-duration) var(--md-motion-expressive-default-spatial-easing);opacity:0;transform:scaleY(.8);margin-top:-8rem}:host .md3-dialog-container.md3-active{opacity:1;transform:scaleY(1);margin-top:0}\n"], dependencies: [{ kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }] });
|
|
6849
7019
|
}
|
|
6850
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type:
|
|
7020
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Dialog, decorators: [{
|
|
6851
7021
|
type: Component,
|
|
6852
|
-
args: [{ selector: 'md3-
|
|
7022
|
+
args: [{ selector: 'md3-dialog', imports: [
|
|
6853
7023
|
CdkPortalOutlet,
|
|
6854
|
-
], host: {
|
|
6855
|
-
|
|
6856
|
-
'role': 'menu',
|
|
6857
|
-
'[class.md3-visible]': 'isVisible()',
|
|
6858
|
-
'[class.md3-inactive]': '!isActive()',
|
|
6859
|
-
'[class.md-scheme-dark]': 'scheme() == "dark"',
|
|
6860
|
-
'[class.md-scheme-light]': 'scheme() == "light"',
|
|
6861
|
-
'[dir]': 'direction()',
|
|
6862
|
-
}, template: "<ng-template cdkPortalOutlet></ng-template>", styles: ["::ng-deep .cdk-overlay-container{position:fixed;z-index:1000;inset:0;pointer-events:none;font-size:1rem}::ng-deep .cdk-overlay-container .md3-menu-scrim{position:absolute;inset:0;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-overlay-connected-position-bounding-box{pointer-events:none}::ng-deep .cdk-overlay-container .md3-menu-panel{pointer-events:auto}::ng-deep .cdk-overlay-container .md3-menu-panel.md3-menu-closing{pointer-events:none}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper{position:absolute;display:flex;inset:0;pointer-events:none;padding:3.5rem 0;overflow:hidden}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-menu-panel{position:absolute;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-menu-panel.md3-menu-closing{pointer-events:none}:host{--background-color: rgb(var(--md-scheme-surface-container-low));--foreground-color: rgb(var(--md-scheme-on-surface));--border-radius: var(--md-border-radius-large);--menu-min-width: 7em;--menu-max-width: 17.5em;--menu-group-radius: var(--md-border-radius-small);--menu-group-shadow: var(--md-shadow-3dp);--menu-group-label-color: rgb(var(--md-scheme-on-surface-variant));--menu-item-label-color: rgb(var(--md-scheme-on-surface));--menu-item-supporting-color: rgb(var(--md-scheme-on-surface-variant));--menu-item-selected-background: rgb(var(--md-scheme-tertiary-container));--menu-item-selected-foreground: rgb(var(--md-scheme-on-tertiary-container));--menu-item-state-color: var(--md-scheme-on-surface);--menu-item-border-radius: var(--md-border-radius-xsmall);--menu-item-outline-color: rgb(var(--md-scheme-secondary));--menu-item-outline-width: .1875em;--menu-item-outline-offset: -.1875em;--menu-item-badge-background: rgb(var(--md-scheme-primary-container));--menu-item-badge-foreground: rgb(var(--md-scheme-on-primary-container));position:relative;display:block;font-size:1rem;min-width:var(--menu-min-width);max-width:min(var(--menu-max-width),100vw - 2rem);max-height:min(32rem,100vh - 2rem);outline:none;transition:all var(--md-motion-expressive-default-spatial-duration) var(--md-motion-expressive-default-spatial-easing);opacity:0;transform:scaleY(.8)}:host.md3-visible{opacity:1;transform:scaleY(1)}:host.md3-vibrant{--background-color: rgb(var(--md-scheme-tertiary-container));--foreground-color: rgb(var(--md-scheme-on-tertiary-container));--menu-group-label-color: rgb(var(--md-scheme-on-tertiary-container));--menu-item-label-color: rgb(var(--md-scheme-on-tertiary-container));--menu-item-supporting-color: rgb(var(--md-scheme-on-tertiary-container));--menu-item-selected-background: rgb(var(--md-scheme-tertiary));--menu-item-selected-foreground: rgb(var(--md-scheme-on-tertiary));--menu-item-state-color: var(--md-scheme-on-tertiary-container)}:host.md3-inactive{--border-radius: var(--md-border-radius-small)}:host ::ng-deep md3-menu-group{margin-top:.125em}:host ::ng-deep md3-menu-group:first-child{margin-top:0}\n"] }]
|
|
6863
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { portalOutlet: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkPortalOutlet), { isSignal: true }] }] } });
|
|
7024
|
+
], template: "<!-- The role and aria attributes live on the host element, applied by the CDK dialog container. -->\n<div\n #surface\n class=\"md3-dialog-container\"\n [class.md3-active]=\"isActive()\"\n [class.md-scheme-dark]=\"config.scheme == 'dark'\"\n [class.md-scheme-light]=\"config.scheme == 'light'\"\n [attr.dir]=\"config.direction ?? null\">\n <ng-template cdkPortalOutlet></ng-template>\n</div>\n", styles: ["::ng-deep .cdk-overlay-container{position:fixed;z-index:1000;inset:0;pointer-events:none;font-size:1rem}::ng-deep .cdk-overlay-container .md3-dialog-scrim{position:absolute;inset:0;pointer-events:auto;background-color:rgb(var(--md-scheme-scrim));transition:all var(--md-motion-expressive-slow-spatial-duration) var(--md-motion-expressive-slow-spatial-easing);opacity:.32}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-opening{opacity:0}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-closing{opacity:0}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-hidden{opacity:0;pointer-events:none}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-scrim-kept{opacity:.32;transition:none}::ng-deep .cdk-overlay-container .md3-dialog-scrim.md3-dialog-scrim-instant{transition:none}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper{position:absolute;display:flex;inset:0;pointer-events:none;padding:3.5rem 1.5rem;overflow:hidden}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-dialog-panel{position:absolute;pointer-events:auto;max-width:35em}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-dialog-panel.md3-dialog-closing,::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-dialog-panel.md3-dialog-hidden{pointer-events:none}:host{display:block;max-width:100%;min-width:17.5em;outline:0}:host .md3-dialog-container{display:block;width:100%;max-height:inherit;overflow:auto;color:rgb(var(--md-scheme-on-surface));background-color:rgb(var(--md-scheme-surface-container-high));border-radius:var(--md-border-radius-xlarge);box-shadow:var(--md-shadow-6dp);transform-origin:center;transition:all var(--md-motion-expressive-default-spatial-duration) var(--md-motion-expressive-default-spatial-easing);opacity:0;transform:scaleY(.8);margin-top:-8rem}:host .md3-dialog-container.md3-active{opacity:1;transform:scaleY(1);margin-top:0}\n"] }]
|
|
7025
|
+
}], propDecorators: { surface: [{ type: i0.ViewChild, args: ['surface', { isSignal: true }] }] } });
|
|
6864
7026
|
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
this.
|
|
6889
|
-
return menuRef;
|
|
6890
|
-
}
|
|
6891
|
-
openSubMenu(component, config = {}) {
|
|
6892
|
-
const xPosition = this.getSubMenuXPosition(config.xPosition);
|
|
6893
|
-
const yPosition = config.yPosition ?? 'below';
|
|
6894
|
-
const offsetX = config.offsetX ?? 0;
|
|
6895
|
-
const offsetY = config.offsetY ?? 0;
|
|
6896
|
-
const subMenuConfig = {
|
|
6897
|
-
...config,
|
|
6898
|
-
isSubMenu: true,
|
|
6899
|
-
xPosition,
|
|
6900
|
-
yPosition,
|
|
6901
|
-
overlapTrigger: config.overlapTrigger ?? true,
|
|
6902
|
-
offsetX,
|
|
6903
|
-
offsetY,
|
|
6904
|
-
scheme: config.scheme ?? 'inherit',
|
|
6905
|
-
direction: config.direction ?? null,
|
|
6906
|
-
};
|
|
6907
|
-
return this.open(component, subMenuConfig);
|
|
6908
|
-
}
|
|
6909
|
-
mergeConfig(config) {
|
|
6910
|
-
const viewportMargin = this.getViewportMargin(config.viewportMargin);
|
|
6911
|
-
return {
|
|
6912
|
-
data: config.data,
|
|
6913
|
-
bindDataToInputs: config.bindDataToInputs ?? false,
|
|
6914
|
-
isSubMenu: config.isSubMenu ?? false,
|
|
6915
|
-
menuColors: config.menuColors ?? 'standard',
|
|
6916
|
-
xPosition: config.xPosition ?? 'start',
|
|
6917
|
-
yPosition: config.yPosition ?? 'below',
|
|
6918
|
-
overlapTrigger: config.overlapTrigger ?? false,
|
|
6919
|
-
offsetX: config.offsetX ?? 0,
|
|
6920
|
-
offsetY: config.offsetY ?? 4,
|
|
6921
|
-
viewportMargin,
|
|
6922
|
-
positions: config.positions,
|
|
6923
|
-
scrollStrategy: config.scrollStrategy ?? 'reposition',
|
|
6924
|
-
scheme: config.scheme ?? 'inherit',
|
|
6925
|
-
direction: config.direction ?? null,
|
|
6926
|
-
viewContainerRef: config.viewContainerRef,
|
|
6927
|
-
injector: config.injector ?? this.injector,
|
|
6928
|
-
};
|
|
6929
|
-
}
|
|
6930
|
-
createOverlay(config, fallbackOrigin) {
|
|
6931
|
-
const origin = this.resolveOrigin(config.origin, fallbackOrigin);
|
|
6932
|
-
const positionStrategy = this.overlay.position()
|
|
6933
|
-
.flexibleConnectedTo(origin)
|
|
6934
|
-
.withFlexibleDimensions(false)
|
|
6935
|
-
.withGrowAfterOpen(true)
|
|
6936
|
-
.withPush(true)
|
|
6937
|
-
.withViewportMargin(config.viewportMargin)
|
|
6938
|
-
.withPositions(config.positions ?? this.getInitialConnectedPositions(config))
|
|
6939
|
-
.withTransformOriginOn('.md3-menu-container');
|
|
6940
|
-
const overlayConfig = new OverlayConfig({
|
|
6941
|
-
hasBackdrop: true,
|
|
6942
|
-
backdropClass: ['md3-menu-scrim', 'md3-menu-opening'],
|
|
6943
|
-
panelClass: ['md3-menu-panel', 'md3-menu-opening'],
|
|
6944
|
-
positionStrategy,
|
|
6945
|
-
scrollStrategy: this.getScrollStrategy(config.scrollStrategy),
|
|
6946
|
-
});
|
|
6947
|
-
return {
|
|
6948
|
-
overlayRef: this.overlay.create(overlayConfig),
|
|
6949
|
-
positionStrategy: config.positions ? undefined : positionStrategy,
|
|
6950
|
-
origin,
|
|
6951
|
-
};
|
|
7027
|
+
/**
|
|
7028
|
+
* Material 3 full screen dialog shell. It covers the viewport and holds the content.
|
|
7029
|
+
*
|
|
7030
|
+
* The content is an `md3-layout`. The layout places the regions — the bar rows for an app bar
|
|
7031
|
+
* or a toolbar, the rail columns, and the panes where side sheets open — so the dialog itself
|
|
7032
|
+
* places nothing but the content. A content root that is not a layout gets a warning in
|
|
7033
|
+
* development mode, and the shell falls back to panes of its own, so a side sheet never opens
|
|
7034
|
+
* behind the dialog where nobody can see it.
|
|
7035
|
+
*/
|
|
7036
|
+
class FullScreenDialog extends CdkDialogContainer {
|
|
7037
|
+
surface = viewChild('surface', /* @ts-ignore */
|
|
7038
|
+
...(ngDevMode ? [{ debugName: "surface" }] : /* istanbul ignore next */ []));
|
|
7039
|
+
mainPane = viewChild('mainPane', /* @ts-ignore */
|
|
7040
|
+
...(ngDevMode ? [{ debugName: "mainPane" }] : /* istanbul ignore next */ []));
|
|
7041
|
+
startOutlet = viewChild('startOutlet', { ...(ngDevMode ? { debugName: "startOutlet" } : /* istanbul ignore next */ {}), read: CdkPortalOutlet });
|
|
7042
|
+
endOutlet = viewChild('endOutlet', { ...(ngDevMode ? { debugName: "endOutlet" } : /* istanbul ignore next */ {}), read: CdkPortalOutlet });
|
|
7043
|
+
sheets = inject(SheetsService);
|
|
7044
|
+
/** True while the shell holds the side sheet outlets, which happens without a layout only. */
|
|
7045
|
+
ownsSideSheetOutlets = false;
|
|
7046
|
+
isActive = signal(false, /* @ts-ignore */
|
|
7047
|
+
...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
|
|
7048
|
+
config = inject(DIALOG_CONFIG, { optional: true }) ?? {};
|
|
7049
|
+
get surfaceElement() {
|
|
7050
|
+
return this.surface()?.nativeElement ?? null;
|
|
6952
7051
|
}
|
|
6953
|
-
|
|
6954
|
-
|
|
7052
|
+
ngAfterViewInit() {
|
|
7053
|
+
// The content is attached by now, so the layout it brings has already taken the
|
|
7054
|
+
// outlets. Its panes sit under the bar regions, which is where a side sheet belongs.
|
|
7055
|
+
const layout = this.findContentLayout();
|
|
7056
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
7057
|
+
this.checkContentLayout(layout);
|
|
7058
|
+
}
|
|
7059
|
+
if (layout) {
|
|
6955
7060
|
return;
|
|
6956
7061
|
}
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
7062
|
+
// No layout, so the shell keeps the dialog self-sufficient. Without this the next side
|
|
7063
|
+
// sheet would open in the outlet underneath — the page scaffold, behind the dialog.
|
|
7064
|
+
const startOutlet = this.startOutlet();
|
|
7065
|
+
const endOutlet = this.endOutlet();
|
|
7066
|
+
if (startOutlet) {
|
|
7067
|
+
this.sheets.registerSideSheetOutlet('start', startOutlet);
|
|
7068
|
+
}
|
|
7069
|
+
if (endOutlet) {
|
|
7070
|
+
this.sheets.registerSideSheetOutlet('end', endOutlet);
|
|
7071
|
+
}
|
|
7072
|
+
this.ownsSideSheetOutlets = !!startOutlet || !!endOutlet;
|
|
6961
7073
|
}
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
}
|
|
6969
|
-
return {
|
|
6970
|
-
x: resolvedOrigin.clientX,
|
|
6971
|
-
y: resolvedOrigin.clientY,
|
|
6972
|
-
};
|
|
7074
|
+
ngOnDestroy() {
|
|
7075
|
+
if (this.ownsSideSheetOutlets) {
|
|
7076
|
+
const startOutlet = this.startOutlet();
|
|
7077
|
+
const endOutlet = this.endOutlet();
|
|
7078
|
+
if (startOutlet) {
|
|
7079
|
+
this.sheets.unregisterSideSheetOutlet('start', startOutlet);
|
|
6973
7080
|
}
|
|
6974
|
-
if (
|
|
6975
|
-
|
|
7081
|
+
if (endOutlet) {
|
|
7082
|
+
this.sheets.unregisterSideSheetOutlet('end', endOutlet);
|
|
6976
7083
|
}
|
|
6977
|
-
|
|
7084
|
+
this.ownsSideSheetOutlets = false;
|
|
6978
7085
|
}
|
|
6979
|
-
|
|
6980
|
-
return {
|
|
6981
|
-
x: (viewport?.innerWidth ?? 0) / 2,
|
|
6982
|
-
y: (viewport?.innerHeight ?? 0) / 2,
|
|
6983
|
-
};
|
|
7086
|
+
super.ngOnDestroy();
|
|
6984
7087
|
}
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
7088
|
+
/**
|
|
7089
|
+
* The layout at the root of the content, if the content brought one.
|
|
7090
|
+
*
|
|
7091
|
+
* The root is either the layout itself, or the component that holds it — a dialog is
|
|
7092
|
+
* normally opened with a component whose own template starts with `md3-layout`.
|
|
7093
|
+
*/
|
|
7094
|
+
findContentLayout() {
|
|
7095
|
+
const content = this.mainPane()?.nativeElement.firstElementChild;
|
|
7096
|
+
if (!content) {
|
|
6988
7097
|
return null;
|
|
6989
7098
|
}
|
|
6990
|
-
if (
|
|
6991
|
-
return
|
|
6992
|
-
? resolvedOrigin.currentTarget
|
|
6993
|
-
: null;
|
|
7099
|
+
if (content.tagName === 'MD3-LAYOUT') {
|
|
7100
|
+
return content;
|
|
6994
7101
|
}
|
|
6995
|
-
|
|
6996
|
-
|
|
7102
|
+
const root = content.firstElementChild;
|
|
7103
|
+
return root?.tagName === 'MD3-LAYOUT' ? root : null;
|
|
7104
|
+
}
|
|
7105
|
+
checkContentLayout(layout) {
|
|
7106
|
+
if (layout) {
|
|
7107
|
+
return;
|
|
6997
7108
|
}
|
|
6998
|
-
|
|
7109
|
+
console.warn('[md3-fullscreen-dialog] the content of a full screen dialog should start with '
|
|
7110
|
+
+ 'md3-layout. Without it the dialog has no bar and no rail region, so an app bar or '
|
|
7111
|
+
+ 'a toolbar has nowhere to go, and the content does not scroll on its own.');
|
|
7112
|
+
}
|
|
7113
|
+
startEnterAnimation() {
|
|
7114
|
+
requestAnimationFrame(() => {
|
|
7115
|
+
this.isActive.set(true);
|
|
7116
|
+
});
|
|
7117
|
+
}
|
|
7118
|
+
setActive(value) {
|
|
7119
|
+
this.isActive.set(value);
|
|
7120
|
+
}
|
|
7121
|
+
recaptureFocus() {
|
|
7122
|
+
this._recaptureFocus();
|
|
7123
|
+
}
|
|
7124
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: FullScreenDialog, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
7125
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: FullScreenDialog, isStandalone: true, selector: "md3-fullscreen-dialog", viewQueries: [{ propertyName: "surface", first: true, predicate: ["surface"], descendants: true, isSignal: true }, { propertyName: "mainPane", first: true, predicate: ["mainPane"], descendants: true, isSignal: true }, { propertyName: "startOutlet", first: true, predicate: ["startOutlet"], descendants: true, read: CdkPortalOutlet, isSignal: true }, { propertyName: "endOutlet", first: true, predicate: ["endOutlet"], descendants: true, read: CdkPortalOutlet, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- The role and aria attributes live on the host element, applied by the CDK dialog container. -->\n<div\n #surface\n class=\"md3-fullscreen-dialog-container\"\n [class.md3-active]=\"isActive()\"\n [class.md-scheme-dark]=\"config.scheme == 'dark'\"\n [class.md-scheme-light]=\"config.scheme == 'light'\"\n [attr.dir]=\"config.direction ?? null\">\n <div class=\"md3-panes-container md3-scrollable\">\n <!--\n The CDK attaches the dialog content to the first portal outlet of\n this template, so the main pane has to come first. The panes are\n placed by grid area, which makes the DOM order irrelevant visually.\n -->\n <div class=\"md3-pane md3-pane-main\" #mainPane>\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n <div class=\"md3-pane md3-pane-start\">\n <ng-template #startOutlet cdkPortalOutlet></ng-template>\n </div>\n <div class=\"md3-pane md3-pane-end\">\n <ng-template #endOutlet cdkPortalOutlet></ng-template>\n </div>\n </div>\n</div>\n", styles: ["::ng-deep .cdk-overlay-container{position:fixed;z-index:1000;inset:0;pointer-events:none;font-size:1rem}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper{position:absolute;display:flex;inset:0;pointer-events:none;overflow:hidden}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper:has(>.md3-fullscreen-dialog-panel){padding:0}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel{width:100%;height:100%;max-width:none;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel.md3-dialog-closing,::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel.md3-dialog-hidden{pointer-events:none}:host{display:block;height:100%;width:100%;outline:0}:host .md3-fullscreen-dialog-container{display:grid;grid-template-rows:minmax(0,1fr);height:100%;min-height:0;overflow:hidden;color:rgb(var(--md-scheme-on-surface));background-color:rgb(var(--md-scheme-surface));transition:all var(--md-motion-expressive-default-spatial-duration) var(--md-motion-expressive-default-spatial-easing);opacity:0;transform:translateY(1.5em)}:host .md3-fullscreen-dialog-container.md3-active{opacity:1;transform:none}:host .md3-panes-container{display:grid;grid-template-areas:\"start main end\";grid-template-columns:auto minmax(0,1fr) auto;grid-template-rows:minmax(0,1fr);min-width:0;min-height:0;overflow:hidden}:host .md3-panes-container .md3-pane{justify-self:stretch;align-self:stretch;min-width:0;min-height:0;height:100%;overflow:hidden}:host .md3-panes-container .md3-pane.md3-pane-start{grid-area:start}:host .md3-panes-container .md3-pane.md3-pane-main{position:relative;grid-area:main;z-index:1;display:grid;grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr)}:host .md3-panes-container .md3-pane.md3-pane-main>::ng-deep *{min-width:0;min-height:0;height:100%;max-height:100dvh;max-width:100dvw}:host .md3-panes-container .md3-pane.md3-pane-end{grid-area:end}\n"], dependencies: [{ kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }] });
|
|
7126
|
+
}
|
|
7127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: FullScreenDialog, decorators: [{
|
|
7128
|
+
type: Component,
|
|
7129
|
+
args: [{ selector: 'md3-fullscreen-dialog', imports: [
|
|
7130
|
+
CdkPortalOutlet,
|
|
7131
|
+
], template: "<!-- The role and aria attributes live on the host element, applied by the CDK dialog container. -->\n<div\n #surface\n class=\"md3-fullscreen-dialog-container\"\n [class.md3-active]=\"isActive()\"\n [class.md-scheme-dark]=\"config.scheme == 'dark'\"\n [class.md-scheme-light]=\"config.scheme == 'light'\"\n [attr.dir]=\"config.direction ?? null\">\n <div class=\"md3-panes-container md3-scrollable\">\n <!--\n The CDK attaches the dialog content to the first portal outlet of\n this template, so the main pane has to come first. The panes are\n placed by grid area, which makes the DOM order irrelevant visually.\n -->\n <div class=\"md3-pane md3-pane-main\" #mainPane>\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n <div class=\"md3-pane md3-pane-start\">\n <ng-template #startOutlet cdkPortalOutlet></ng-template>\n </div>\n <div class=\"md3-pane md3-pane-end\">\n <ng-template #endOutlet cdkPortalOutlet></ng-template>\n </div>\n </div>\n</div>\n", styles: ["::ng-deep .cdk-overlay-container{position:fixed;z-index:1000;inset:0;pointer-events:none;font-size:1rem}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper{position:absolute;display:flex;inset:0;pointer-events:none;overflow:hidden}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper:has(>.md3-fullscreen-dialog-panel){padding:0}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel{width:100%;height:100%;max-width:none;pointer-events:auto}::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel.md3-dialog-closing,::ng-deep .cdk-overlay-container .cdk-global-overlay-wrapper .md3-fullscreen-dialog-panel.md3-dialog-hidden{pointer-events:none}:host{display:block;height:100%;width:100%;outline:0}:host .md3-fullscreen-dialog-container{display:grid;grid-template-rows:minmax(0,1fr);height:100%;min-height:0;overflow:hidden;color:rgb(var(--md-scheme-on-surface));background-color:rgb(var(--md-scheme-surface));transition:all var(--md-motion-expressive-default-spatial-duration) var(--md-motion-expressive-default-spatial-easing);opacity:0;transform:translateY(1.5em)}:host .md3-fullscreen-dialog-container.md3-active{opacity:1;transform:none}:host .md3-panes-container{display:grid;grid-template-areas:\"start main end\";grid-template-columns:auto minmax(0,1fr) auto;grid-template-rows:minmax(0,1fr);min-width:0;min-height:0;overflow:hidden}:host .md3-panes-container .md3-pane{justify-self:stretch;align-self:stretch;min-width:0;min-height:0;height:100%;overflow:hidden}:host .md3-panes-container .md3-pane.md3-pane-start{grid-area:start}:host .md3-panes-container .md3-pane.md3-pane-main{position:relative;grid-area:main;z-index:1;display:grid;grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr)}:host .md3-panes-container .md3-pane.md3-pane-main>::ng-deep *{min-width:0;min-height:0;height:100%;max-height:100dvh;max-width:100dvw}:host .md3-panes-container .md3-pane.md3-pane-end{grid-area:end}\n"] }]
|
|
7132
|
+
}], propDecorators: { surface: [{ type: i0.ViewChild, args: ['surface', { isSignal: true }] }], mainPane: [{ type: i0.ViewChild, args: ['mainPane', { isSignal: true }] }], startOutlet: [{ type: i0.ViewChild, args: ['startOutlet', { ...{ read: CdkPortalOutlet }, isSignal: true }] }], endOutlet: [{ type: i0.ViewChild, args: ['endOutlet', { ...{ read: CdkPortalOutlet }, isSignal: true }] }] } });
|
|
7133
|
+
|
|
7134
|
+
const PANEL_CLASS = 'md3-dialog-panel';
|
|
7135
|
+
const FULL_SCREEN_PANEL_CLASS = 'md3-fullscreen-dialog-panel';
|
|
7136
|
+
const OPENING_CLASS = 'md3-dialog-opening';
|
|
7137
|
+
const SCRIM_KEPT_CLASS = 'md3-dialog-scrim-kept';
|
|
7138
|
+
const SCRIM_INSTANT_CLASS = 'md3-dialog-scrim-instant';
|
|
7139
|
+
/**
|
|
7140
|
+
* Head start given to a dialog that leaves the screen before the dialog taking
|
|
7141
|
+
* its place animates in. Long enough to read as one dialog replacing another,
|
|
7142
|
+
* short enough to still feel like a single gesture.
|
|
7143
|
+
*/
|
|
7144
|
+
const DIALOG_HANDOVER_DELAY_MS = 160;
|
|
7145
|
+
class DialogService {
|
|
7146
|
+
cdkDialog = inject(Dialog$1);
|
|
7147
|
+
overlay = inject(Overlay);
|
|
7148
|
+
overlayContainer = inject(OverlayContainer);
|
|
7149
|
+
injector = inject(Injector);
|
|
7150
|
+
document = inject(DOCUMENT);
|
|
7151
|
+
/** Open dialogs, from the first one opened to the one currently on top. */
|
|
7152
|
+
refs = [];
|
|
7153
|
+
/**
|
|
7154
|
+
* Elements the page was made of that the CDK hid from assistive technology,
|
|
7155
|
+
* kept here while the dialogs are hidden and the page is given back.
|
|
7156
|
+
*/
|
|
7157
|
+
pageAriaHidden = new Map();
|
|
7158
|
+
/**
|
|
7159
|
+
* Page scrolling is blocked here instead of per overlay, so stacked dialogs
|
|
7160
|
+
* cannot unblock the page while another dialog is still open.
|
|
7161
|
+
*/
|
|
7162
|
+
scrollBlock = this.overlay.scrollStrategies.block();
|
|
7163
|
+
/** Element that was focused before the first dialog of the stack opened. */
|
|
7164
|
+
rootTrigger = null;
|
|
7165
|
+
pageStateQueued = false;
|
|
7166
|
+
get openDialogs() {
|
|
7167
|
+
return this.refs;
|
|
6999
7168
|
}
|
|
7000
|
-
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
}
|
|
7004
|
-
menuOverlay.overlayRef.updatePosition();
|
|
7005
|
-
const fallbackPosition = this.getFallbackPositionAfterPush(config, this.getOriginClientRect(menuOverlay.origin), menuOverlay.overlayRef.overlayElement.getBoundingClientRect());
|
|
7006
|
-
if (!fallbackPosition) {
|
|
7007
|
-
return;
|
|
7008
|
-
}
|
|
7009
|
-
menuOverlay.positionStrategy.withPositions([fallbackPosition]);
|
|
7010
|
-
menuOverlay.overlayRef.updatePosition();
|
|
7169
|
+
/** Open dialogs that are currently on screen, from the bottom one up. */
|
|
7170
|
+
get visibleDialogs() {
|
|
7171
|
+
return this.refs.filter((ref) => !ref.isHidden);
|
|
7011
7172
|
}
|
|
7012
|
-
|
|
7013
|
-
|
|
7173
|
+
/** The full screen dialog that is open, if there is one. */
|
|
7174
|
+
get fullScreenDialog() {
|
|
7175
|
+
return this.refs.find((ref) => ref.isFullScreen && !ref.isClosing);
|
|
7014
7176
|
}
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7177
|
+
open(component, config = {}) {
|
|
7178
|
+
const dialogConfig = this.mergeConfig(config);
|
|
7179
|
+
if (this.refs.length === 0) {
|
|
7180
|
+
this.rootTrigger = this.getFocusedElement();
|
|
7018
7181
|
}
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
const
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
const yPosition = this.shouldFlipYPosition(config, originRect, overlayRect)
|
|
7026
|
-
? this.getFallbackYPosition(config.yPosition)
|
|
7027
|
-
: config.yPosition;
|
|
7028
|
-
if (xPosition === config.xPosition && yPosition === config.yPosition) {
|
|
7029
|
-
return null;
|
|
7182
|
+
// The dialog that is on screen starts leaving first, so the two dialogs
|
|
7183
|
+
// never animate on top of each other. A full screen dialog is not part
|
|
7184
|
+
// of this: regular dialogs open on top of it and leave it alone.
|
|
7185
|
+
const previousRef = this.topRegularRef();
|
|
7186
|
+
if (previousRef) {
|
|
7187
|
+
this.dismissPrevious(previousRef, dialogConfig.previousDialog);
|
|
7030
7188
|
}
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
7034
|
-
|
|
7189
|
+
let dialogRef;
|
|
7190
|
+
const cdkRef = this.cdkDialog.open(component, {
|
|
7191
|
+
// The MD3 shell replaces the default CDK container, so the overlay,
|
|
7192
|
+
// focus trap and focus restoration come from the CDK while the shell
|
|
7193
|
+
// only renders the surface.
|
|
7194
|
+
container: {
|
|
7195
|
+
type: Dialog,
|
|
7196
|
+
providers: () => [
|
|
7197
|
+
{ provide: DIALOG_CONFIG, useValue: dialogConfig },
|
|
7198
|
+
],
|
|
7199
|
+
},
|
|
7200
|
+
// These tokens make the dialog controllable from the dynamic
|
|
7201
|
+
// component without coupling that component to the service.
|
|
7202
|
+
providers: (cdkDialogRef) => {
|
|
7203
|
+
dialogRef = new DialogRef(cdkDialogRef, dialogConfig.disableCloseEvents);
|
|
7204
|
+
return [
|
|
7205
|
+
{ provide: DialogRef, useValue: dialogRef },
|
|
7206
|
+
{ provide: DIALOG_DATA, useValue: dialogConfig.data },
|
|
7207
|
+
{ provide: DIALOG_CONFIG, useValue: dialogConfig },
|
|
7208
|
+
{ provide: DIALOG_COMPONENT, useValue: component },
|
|
7209
|
+
];
|
|
7210
|
+
},
|
|
7211
|
+
data: dialogConfig.data,
|
|
7212
|
+
role: dialogConfig.role,
|
|
7213
|
+
ariaModal: true,
|
|
7214
|
+
ariaLabel: dialogConfig.ariaLabel || null,
|
|
7215
|
+
ariaLabelledBy: dialogConfig.ariaLabelledBy || null,
|
|
7216
|
+
ariaDescribedBy: dialogConfig.ariaDescribedBy || null,
|
|
7217
|
+
direction: dialogConfig.direction ?? undefined,
|
|
7218
|
+
viewContainerRef: dialogConfig.viewContainerRef,
|
|
7219
|
+
injector: dialogConfig.injector,
|
|
7220
|
+
hasBackdrop: true,
|
|
7221
|
+
backdropClass: ['md3-dialog-scrim', OPENING_CLASS],
|
|
7222
|
+
panelClass: [PANEL_CLASS, OPENING_CLASS],
|
|
7223
|
+
positionStrategy: this.overlay.position()
|
|
7224
|
+
.global()
|
|
7225
|
+
.centerHorizontally()
|
|
7226
|
+
.centerVertically(),
|
|
7227
|
+
// Scrolling is blocked by the service for the whole stack.
|
|
7228
|
+
scrollStrategy: this.overlay.scrollStrategies.noop(),
|
|
7229
|
+
// Focus goes back to whatever opened the stack, even when the dialog
|
|
7230
|
+
// that was open underneath has been closed in the meantime.
|
|
7231
|
+
restoreFocus: this.rootTrigger ?? true,
|
|
7232
|
+
// Scrim and Escape handling lives in DialogRef so the dialog can
|
|
7233
|
+
// play its exit animation before the overlay is disposed.
|
|
7234
|
+
disableClose: true,
|
|
7035
7235
|
});
|
|
7236
|
+
this.registerDialog(dialogRef, cdkRef, dialogConfig, previousRef);
|
|
7237
|
+
return dialogRef;
|
|
7036
7238
|
}
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
return originRect.right < overlayRect.left - tolerance
|
|
7049
|
-
|| originRect.right > overlayRect.right + tolerance;
|
|
7050
|
-
case 'center':
|
|
7051
|
-
default:
|
|
7052
|
-
return false;
|
|
7053
|
-
}
|
|
7054
|
-
}
|
|
7055
|
-
shouldFlipYPosition(config, originRect, overlayRect) {
|
|
7056
|
-
const tolerance = config.viewportMargin;
|
|
7057
|
-
if (config.isSubMenu) {
|
|
7058
|
-
const anchorY = config.yPosition === 'above' ? originRect.bottom : originRect.top;
|
|
7059
|
-
return anchorY < overlayRect.top - tolerance
|
|
7060
|
-
|| anchorY > overlayRect.bottom + tolerance;
|
|
7061
|
-
}
|
|
7062
|
-
if (config.overlapTrigger) {
|
|
7063
|
-
const anchorY = config.yPosition === 'above' ? originRect.bottom : originRect.top;
|
|
7064
|
-
return anchorY < overlayRect.top - tolerance
|
|
7065
|
-
|| anchorY > overlayRect.bottom + tolerance;
|
|
7066
|
-
}
|
|
7067
|
-
switch (config.yPosition) {
|
|
7068
|
-
case 'above':
|
|
7069
|
-
return overlayRect.bottom > originRect.top + tolerance;
|
|
7070
|
-
case 'below':
|
|
7071
|
-
return overlayRect.top < originRect.bottom - tolerance;
|
|
7072
|
-
case 'center':
|
|
7073
|
-
default:
|
|
7074
|
-
return false;
|
|
7239
|
+
/**
|
|
7240
|
+
* Opens a dialog that covers the whole screen. Only one can be open at a
|
|
7241
|
+
* time, so it replaces whatever is open, and while it is up the side sheet
|
|
7242
|
+
* outlets belong to it: side sheets open inside the dialog, not behind it.
|
|
7243
|
+
* `previousDialog` decides what happens to the dialogs it replaces, the
|
|
7244
|
+
* same way it does for a regular dialog.
|
|
7245
|
+
*/
|
|
7246
|
+
openFullScreen(component, config = {}) {
|
|
7247
|
+
const dialogConfig = this.mergeConfig(config);
|
|
7248
|
+
if (this.refs.length === 0) {
|
|
7249
|
+
this.rootTrigger = this.getFocusedElement();
|
|
7075
7250
|
}
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
const
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
offsetX: config.offsetX,
|
|
7084
|
-
offsetY: this.getOffsetY(yPosition, config),
|
|
7085
|
-
panelClass: [
|
|
7086
|
-
'md3-menu-position-' + xPosition,
|
|
7087
|
-
'md3-menu-position-' + yPosition,
|
|
7088
|
-
],
|
|
7089
|
-
};
|
|
7090
|
-
}
|
|
7091
|
-
createSubMenuConnectedPosition(xPosition, yAlignment, offsetX, offsetY) {
|
|
7092
|
-
const horizontal = this.getHorizontalPosition(xPosition);
|
|
7093
|
-
const yPosition = yAlignment === 'top' ? 'below' : 'above';
|
|
7094
|
-
return {
|
|
7095
|
-
...horizontal,
|
|
7096
|
-
originY: yAlignment,
|
|
7097
|
-
overlayY: yAlignment,
|
|
7098
|
-
offsetX: this.getSubMenuOffsetX(xPosition, offsetX),
|
|
7099
|
-
offsetY: this.getSubMenuOffsetY(yAlignment, offsetY),
|
|
7100
|
-
panelClass: [
|
|
7101
|
-
'md3-menu-position-' + xPosition,
|
|
7102
|
-
'md3-menu-position-' + yPosition,
|
|
7103
|
-
'md3-menu-position-submenu',
|
|
7104
|
-
],
|
|
7105
|
-
};
|
|
7106
|
-
}
|
|
7107
|
-
getHorizontalPosition(position) {
|
|
7108
|
-
switch (position) {
|
|
7109
|
-
case 'end':
|
|
7110
|
-
return {
|
|
7111
|
-
originX: 'end',
|
|
7112
|
-
overlayX: 'end',
|
|
7113
|
-
};
|
|
7114
|
-
case 'before':
|
|
7115
|
-
return {
|
|
7116
|
-
originX: 'start',
|
|
7117
|
-
overlayX: 'end',
|
|
7118
|
-
};
|
|
7119
|
-
case 'after':
|
|
7120
|
-
return {
|
|
7121
|
-
originX: 'end',
|
|
7122
|
-
overlayX: 'start',
|
|
7123
|
-
};
|
|
7124
|
-
case 'center':
|
|
7125
|
-
return {
|
|
7126
|
-
originX: 'center',
|
|
7127
|
-
overlayX: 'center',
|
|
7128
|
-
};
|
|
7129
|
-
case 'start':
|
|
7130
|
-
default:
|
|
7131
|
-
return {
|
|
7132
|
-
originX: 'start',
|
|
7133
|
-
overlayX: 'start',
|
|
7134
|
-
};
|
|
7251
|
+
// A full screen dialog is a context of its own: the dialog it replaces
|
|
7252
|
+
// and anything stacked on that dialog goes with it.
|
|
7253
|
+
const previousRef = this.topRef();
|
|
7254
|
+
if (previousRef) {
|
|
7255
|
+
// Everything open belongs to the context being replaced, including
|
|
7256
|
+
// a full screen dialog that is already up.
|
|
7257
|
+
this.dismissPreviousContext(dialogConfig.previousDialog);
|
|
7135
7258
|
}
|
|
7259
|
+
let dialogRef;
|
|
7260
|
+
const cdkRef = this.cdkDialog.open(component, {
|
|
7261
|
+
container: {
|
|
7262
|
+
type: FullScreenDialog,
|
|
7263
|
+
providers: () => [
|
|
7264
|
+
{ provide: DIALOG_CONFIG, useValue: dialogConfig },
|
|
7265
|
+
],
|
|
7266
|
+
},
|
|
7267
|
+
providers: (cdkDialogRef) => {
|
|
7268
|
+
dialogRef = new DialogRef(cdkDialogRef, dialogConfig.disableCloseEvents, true);
|
|
7269
|
+
return [
|
|
7270
|
+
{ provide: DialogRef, useValue: dialogRef },
|
|
7271
|
+
{ provide: DIALOG_DATA, useValue: dialogConfig.data },
|
|
7272
|
+
{ provide: DIALOG_CONFIG, useValue: dialogConfig },
|
|
7273
|
+
{ provide: DIALOG_COMPONENT, useValue: component },
|
|
7274
|
+
];
|
|
7275
|
+
},
|
|
7276
|
+
data: dialogConfig.data,
|
|
7277
|
+
role: dialogConfig.role,
|
|
7278
|
+
ariaModal: true,
|
|
7279
|
+
ariaLabel: dialogConfig.ariaLabel || null,
|
|
7280
|
+
ariaLabelledBy: dialogConfig.ariaLabelledBy || null,
|
|
7281
|
+
ariaDescribedBy: dialogConfig.ariaDescribedBy || null,
|
|
7282
|
+
direction: dialogConfig.direction ?? undefined,
|
|
7283
|
+
viewContainerRef: dialogConfig.viewContainerRef,
|
|
7284
|
+
injector: dialogConfig.injector,
|
|
7285
|
+
// The dialog covers the page on its own, so there is nothing left
|
|
7286
|
+
// for a scrim to dim.
|
|
7287
|
+
hasBackdrop: false,
|
|
7288
|
+
panelClass: [FULL_SCREEN_PANEL_CLASS, OPENING_CLASS],
|
|
7289
|
+
// The CDK writes the size on the panel and the global strategy then
|
|
7290
|
+
// drops its centering margins, which is how the panel ends up
|
|
7291
|
+
// covering the whole wrapper.
|
|
7292
|
+
width: '100%',
|
|
7293
|
+
height: '100%',
|
|
7294
|
+
positionStrategy: this.overlay.position().global(),
|
|
7295
|
+
scrollStrategy: this.overlay.scrollStrategies.noop(),
|
|
7296
|
+
restoreFocus: this.rootTrigger ?? true,
|
|
7297
|
+
disableClose: true,
|
|
7298
|
+
});
|
|
7299
|
+
this.registerDialog(dialogRef, cdkRef, dialogConfig, previousRef);
|
|
7300
|
+
return dialogRef;
|
|
7136
7301
|
}
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
};
|
|
7144
|
-
case 'center':
|
|
7145
|
-
return {
|
|
7146
|
-
originY: 'center',
|
|
7147
|
-
overlayY: 'center',
|
|
7148
|
-
};
|
|
7149
|
-
case 'below':
|
|
7150
|
-
default:
|
|
7151
|
-
return {
|
|
7152
|
-
originY: overlapTrigger ? 'top' : 'bottom',
|
|
7153
|
-
overlayY: 'top',
|
|
7154
|
-
};
|
|
7302
|
+
/** Wires a freshly created dialog into the stack and starts its animation. */
|
|
7303
|
+
registerDialog(dialogRef, cdkRef, dialogConfig, previousRef) {
|
|
7304
|
+
dialogRef.dialogInstance = cdkRef.containerInstance;
|
|
7305
|
+
dialogRef.componentInstance = cdkRef.componentInstance ?? undefined;
|
|
7306
|
+
if (cdkRef.componentRef) {
|
|
7307
|
+
this.bindDataToInputs(cdkRef.componentRef, dialogConfig);
|
|
7155
7308
|
}
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
return 'end';
|
|
7161
|
-
case 'end':
|
|
7162
|
-
return 'start';
|
|
7163
|
-
case 'before':
|
|
7164
|
-
return 'after';
|
|
7165
|
-
case 'after':
|
|
7166
|
-
return 'before';
|
|
7167
|
-
case 'center':
|
|
7168
|
-
default:
|
|
7169
|
-
return 'center';
|
|
7309
|
+
this.refs.push(dialogRef);
|
|
7310
|
+
this.syncPageState();
|
|
7311
|
+
if (previousRef) {
|
|
7312
|
+
setTimeout(() => this.startReplacingAnimation(dialogRef, previousRef), DIALOG_HANDOVER_DELAY_MS);
|
|
7170
7313
|
}
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
return position === 'before' ? 'before' : 'after';
|
|
7174
|
-
}
|
|
7175
|
-
getFallbackYPosition(position) {
|
|
7176
|
-
switch (position) {
|
|
7177
|
-
case 'above':
|
|
7178
|
-
return 'below';
|
|
7179
|
-
case 'below':
|
|
7180
|
-
return 'above';
|
|
7181
|
-
case 'center':
|
|
7182
|
-
default:
|
|
7183
|
-
return 'center';
|
|
7314
|
+
else {
|
|
7315
|
+
this.startOpenAnimation(dialogRef);
|
|
7184
7316
|
}
|
|
7317
|
+
// Restoring starts with the exit animation, so the dialog underneath is
|
|
7318
|
+
// already coming back while this one is fading out.
|
|
7319
|
+
dialogRef.beforeClosed().subscribe(() => this.restorePreviousDialog(dialogRef));
|
|
7320
|
+
dialogRef.afterClosed().subscribe(() => this.removeRef(dialogRef));
|
|
7321
|
+
// Hiding and showing can also come straight from the reference, so the
|
|
7322
|
+
// page state is driven by what the dialogs report rather than by the
|
|
7323
|
+
// calls that went through this service.
|
|
7324
|
+
dialogRef.hiddenChanged().subscribe(() => this.syncPageState());
|
|
7185
7325
|
}
|
|
7186
|
-
|
|
7187
|
-
|
|
7326
|
+
/**
|
|
7327
|
+
* Hides every dialog that is on screen, the full screen one included, with
|
|
7328
|
+
* the closing animation. They stay alive with their content and state, the
|
|
7329
|
+
* page underneath becomes usable, and showAll() puts them back. The promise
|
|
7330
|
+
* resolves once they are all out of sight.
|
|
7331
|
+
*/
|
|
7332
|
+
hideAll() {
|
|
7333
|
+
const visible = this.refs.filter((ref) => !ref.isHidden && !ref.isClosing);
|
|
7334
|
+
return Promise.all(visible.map((ref) => ref.hide())).then(() => undefined);
|
|
7188
7335
|
}
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7336
|
+
/**
|
|
7337
|
+
* Brings the dialogs back on screen, whether they were hidden one by one or
|
|
7338
|
+
* all at once: the dialog that was on top returns, along with the full
|
|
7339
|
+
* screen dialog it sits in. Dialogs hidden behind another dialog stay
|
|
7340
|
+
* hidden, since that is where they belong once the stack is back.
|
|
7341
|
+
*/
|
|
7342
|
+
showAll() {
|
|
7343
|
+
const topRef = this.topRef();
|
|
7344
|
+
if (!topRef) {
|
|
7345
|
+
return;
|
|
7192
7346
|
}
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
height: 0,
|
|
7202
|
-
};
|
|
7203
|
-
}
|
|
7204
|
-
getViewportMargin(configuredMargin) {
|
|
7205
|
-
const minimumMargin = this.getHalfEmInPixels();
|
|
7206
|
-
return Math.max(configuredMargin ?? minimumMargin, minimumMargin);
|
|
7207
|
-
}
|
|
7208
|
-
getHalfEmInPixels() {
|
|
7209
|
-
const viewport = this.document.defaultView;
|
|
7210
|
-
const fontSize = viewport?.getComputedStyle(this.document.documentElement).fontSize;
|
|
7211
|
-
const pixels = fontSize ? Number.parseFloat(fontSize) * 0.5 : 8;
|
|
7212
|
-
return Number.isFinite(pixels) ? pixels : 8;
|
|
7213
|
-
}
|
|
7214
|
-
getOffsetY(position, config) {
|
|
7215
|
-
if (config.overlapTrigger || position === 'center') {
|
|
7216
|
-
return 0;
|
|
7347
|
+
const fullScreenRef = this.fullScreenDialog;
|
|
7348
|
+
// The full screen dialog is the context the top one sits in, so it
|
|
7349
|
+
// comes back first and the dialog on top ends up on top, with the focus.
|
|
7350
|
+
if (fullScreenRef && fullScreenRef !== topRef && fullScreenRef.isHidden) {
|
|
7351
|
+
fullScreenRef.show();
|
|
7352
|
+
}
|
|
7353
|
+
if (topRef.isHidden) {
|
|
7354
|
+
topRef.show();
|
|
7217
7355
|
}
|
|
7218
|
-
return position === 'above'
|
|
7219
|
-
? config.offsetY * -1
|
|
7220
|
-
: config.offsetY;
|
|
7221
7356
|
}
|
|
7222
|
-
|
|
7223
|
-
|
|
7357
|
+
/** Closes every open dialog, including the hidden and the full screen ones. */
|
|
7358
|
+
closeAll() {
|
|
7359
|
+
// Closed from the bottom up so a closing dialog never brings back a
|
|
7360
|
+
// hidden dialog that is about to close as well.
|
|
7361
|
+
return Promise.all([...this.refs].map((ref) => ref.close())).then(() => undefined);
|
|
7224
7362
|
}
|
|
7225
|
-
|
|
7226
|
-
|
|
7363
|
+
/** Closes the regular dialogs and leaves a full screen dialog alone. */
|
|
7364
|
+
closeRegularDialogs() {
|
|
7365
|
+
const closing = this.refs
|
|
7366
|
+
.filter((ref) => !ref.isFullScreen)
|
|
7367
|
+
.map((ref) => ref.close());
|
|
7368
|
+
return Promise.all(closing).then(() => undefined);
|
|
7227
7369
|
}
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7370
|
+
mergeConfig(config) {
|
|
7371
|
+
return {
|
|
7372
|
+
data: config.data,
|
|
7373
|
+
bindDataToInputs: config.bindDataToInputs ?? false,
|
|
7374
|
+
disableCloseEvents: config.disableCloseEvents ?? false,
|
|
7375
|
+
previousDialog: config.previousDialog ?? 'close',
|
|
7376
|
+
role: config.role ?? 'dialog',
|
|
7377
|
+
ariaLabel: config.ariaLabel ?? '',
|
|
7378
|
+
ariaLabelledBy: config.ariaLabelledBy ?? '',
|
|
7379
|
+
ariaDescribedBy: config.ariaDescribedBy ?? '',
|
|
7380
|
+
scheme: config.scheme ?? 'inherit',
|
|
7381
|
+
direction: config.direction ?? null,
|
|
7382
|
+
viewContainerRef: config.viewContainerRef,
|
|
7383
|
+
injector: config.injector ?? this.injector,
|
|
7384
|
+
};
|
|
7240
7385
|
}
|
|
7241
|
-
|
|
7242
|
-
|
|
7386
|
+
/**
|
|
7387
|
+
* Hides or closes the dialog that is on screen. Its scrim stays up until
|
|
7388
|
+
* the dialog taking over is ready for it, so the page behind never
|
|
7389
|
+
* brightens between the two dialogs.
|
|
7390
|
+
*/
|
|
7391
|
+
dismissPrevious(previousRef, behavior) {
|
|
7392
|
+
previousRef.overlayRef.backdropElement?.classList.add(SCRIM_KEPT_CLASS);
|
|
7393
|
+
return behavior === 'hide' ? previousRef.hide() : this.closeRegularDialogs();
|
|
7243
7394
|
}
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7395
|
+
/**
|
|
7396
|
+
* The same choice for a full screen dialog, applied to everything that is
|
|
7397
|
+
* on screen: what it takes over from is a whole context, a full screen
|
|
7398
|
+
* dialog of its own included. `hide` keeps that context alive, and it comes
|
|
7399
|
+
* back as it was once this dialog closes.
|
|
7400
|
+
*/
|
|
7401
|
+
dismissPreviousContext(behavior) {
|
|
7402
|
+
return behavior === 'hide' ? this.hideAll() : this.closeAll();
|
|
7249
7403
|
}
|
|
7250
|
-
startOpenAnimation(
|
|
7404
|
+
startOpenAnimation(dialogRef) {
|
|
7405
|
+
const overlayRef = dialogRef.overlayRef;
|
|
7251
7406
|
const panel = overlayRef.overlayElement;
|
|
7252
7407
|
const backdrop = overlayRef.backdropElement;
|
|
7253
7408
|
// The overlay is inserted already rendered. Keep an initial class for
|
|
@@ -7256,22 +7411,65 @@ class MenuService {
|
|
|
7256
7411
|
requestAnimationFrame(() => {
|
|
7257
7412
|
setTimeout(() => {
|
|
7258
7413
|
panel.getBoundingClientRect();
|
|
7259
|
-
panel.classList.remove(
|
|
7260
|
-
backdrop?.classList.remove(
|
|
7414
|
+
panel.classList.remove(OPENING_CLASS);
|
|
7415
|
+
backdrop?.classList.remove(OPENING_CLASS);
|
|
7261
7416
|
}, 100);
|
|
7262
7417
|
});
|
|
7418
|
+
dialogRef.dialogInstance?.startEnterAnimation();
|
|
7419
|
+
}
|
|
7420
|
+
/** Opening animation for a dialog that took the place of another one. */
|
|
7421
|
+
startReplacingAnimation(dialogRef, previousRef) {
|
|
7422
|
+
if (dialogRef.isClosing) {
|
|
7423
|
+
return;
|
|
7424
|
+
}
|
|
7425
|
+
const panel = dialogRef.overlayRef.overlayElement;
|
|
7426
|
+
const backdrop = dialogRef.overlayRef.backdropElement;
|
|
7427
|
+
this.beginScrimHandover(previousRef, dialogRef);
|
|
7428
|
+
panel.getBoundingClientRect();
|
|
7429
|
+
panel.classList.remove(OPENING_CLASS);
|
|
7430
|
+
backdrop?.classList.remove(OPENING_CLASS);
|
|
7431
|
+
this.endScrimHandover(previousRef, dialogRef);
|
|
7432
|
+
dialogRef.dialogInstance?.startEnterAnimation();
|
|
7433
|
+
}
|
|
7434
|
+
/** Opening animation for a dialog coming back from behind a closing one. */
|
|
7435
|
+
startRestoringAnimation(closingRef, previousRef) {
|
|
7436
|
+
if (previousRef.isClosing) {
|
|
7437
|
+
return;
|
|
7438
|
+
}
|
|
7439
|
+
this.beginScrimHandover(closingRef, previousRef);
|
|
7440
|
+
previousRef.show();
|
|
7441
|
+
this.endScrimHandover(closingRef, previousRef);
|
|
7442
|
+
}
|
|
7443
|
+
/**
|
|
7444
|
+
* Moves both scrims to their new value in a single frame, without a
|
|
7445
|
+
* transition on either side, so the dim behind the dialogs never changes.
|
|
7446
|
+
*/
|
|
7447
|
+
beginScrimHandover(fromRef, toRef) {
|
|
7448
|
+
const from = fromRef.overlayRef.backdropElement;
|
|
7449
|
+
const to = toRef.overlayRef.backdropElement;
|
|
7450
|
+
// Nothing to hand the scrim over to, e.g. a full screen dialog: the
|
|
7451
|
+
// outgoing scrim fades out on its own instead.
|
|
7452
|
+
if (!to) {
|
|
7453
|
+
return;
|
|
7454
|
+
}
|
|
7455
|
+
// Nothing to hand over either: the dialog leaving carries no scrim, so
|
|
7456
|
+
// the one coming in fades its own in rather than switching it on in a
|
|
7457
|
+
// single frame. This is a full screen dialog closing over a dialog that
|
|
7458
|
+
// was hidden underneath it.
|
|
7459
|
+
if (!from) {
|
|
7460
|
+
return;
|
|
7461
|
+
}
|
|
7462
|
+
from?.classList.add(SCRIM_INSTANT_CLASS);
|
|
7463
|
+
from?.classList.remove(SCRIM_KEPT_CLASS);
|
|
7464
|
+
to?.classList.add(SCRIM_INSTANT_CLASS);
|
|
7263
7465
|
}
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
{ provide: MENU_DATA, useValue: config.data },
|
|
7272
|
-
{ provide: MENU_CONFIG, useValue: config },
|
|
7273
|
-
{ provide: MENU_COMPONENT, useValue: component },
|
|
7274
|
-
],
|
|
7466
|
+
/** Gives the scrims their transitions back once the handover is painted. */
|
|
7467
|
+
endScrimHandover(fromRef, toRef) {
|
|
7468
|
+
const from = fromRef.overlayRef.backdropElement;
|
|
7469
|
+
const to = toRef.overlayRef.backdropElement;
|
|
7470
|
+
requestAnimationFrame(() => {
|
|
7471
|
+
from?.classList.remove(SCRIM_INSTANT_CLASS);
|
|
7472
|
+
to?.classList.remove(SCRIM_INSTANT_CLASS);
|
|
7275
7473
|
});
|
|
7276
7474
|
}
|
|
7277
7475
|
bindDataToInputs(componentRef, config) {
|
|
@@ -7284,84 +7482,194 @@ class MenuService {
|
|
|
7284
7482
|
componentRef.setInput(inputName, inputValue);
|
|
7285
7483
|
});
|
|
7286
7484
|
}
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7485
|
+
canBindDataToInputs(data) {
|
|
7486
|
+
return typeof data === 'object' && data !== null && !Array.isArray(data);
|
|
7487
|
+
}
|
|
7488
|
+
/** Last dialog of the stack that is not closing yet. */
|
|
7489
|
+
topRef() {
|
|
7490
|
+
for (let index = this.refs.length - 1; index >= 0; index--) {
|
|
7491
|
+
if (!this.refs[index].isClosing) {
|
|
7492
|
+
return this.refs[index];
|
|
7493
|
+
}
|
|
7494
|
+
}
|
|
7495
|
+
return undefined;
|
|
7496
|
+
}
|
|
7497
|
+
/**
|
|
7498
|
+
* Same, without the full screen dialog: it hosts the dialogs opened on top
|
|
7499
|
+
* of it, so it is never the one that gets hidden or closed to make room.
|
|
7500
|
+
*/
|
|
7501
|
+
topRegularRef() {
|
|
7502
|
+
const ref = this.topRef();
|
|
7503
|
+
return ref?.isFullScreen ? undefined : ref;
|
|
7504
|
+
}
|
|
7505
|
+
restorePreviousDialog(ref) {
|
|
7506
|
+
const index = this.refs.indexOf(ref);
|
|
7507
|
+
if (index < 1) {
|
|
7508
|
+
return;
|
|
7509
|
+
}
|
|
7510
|
+
for (let previousIndex = index - 1; previousIndex >= 0; previousIndex--) {
|
|
7511
|
+
const previousRef = this.refs[previousIndex];
|
|
7512
|
+
if (previousRef.isClosing) {
|
|
7513
|
+
continue;
|
|
7514
|
+
}
|
|
7515
|
+
// The closing dialog gets the same head start it was given when it
|
|
7516
|
+
// took the screen, and keeps the scrim until then. Nothing to keep
|
|
7517
|
+
// when the dialog underneath has no scrim of its own.
|
|
7518
|
+
if (previousRef.overlayRef.backdropElement) {
|
|
7519
|
+
ref.overlayRef.backdropElement?.classList.add(SCRIM_KEPT_CLASS);
|
|
7520
|
+
}
|
|
7521
|
+
setTimeout(() => {
|
|
7522
|
+
this.showHostFullScreenDialog(previousRef);
|
|
7523
|
+
this.startRestoringAnimation(ref, previousRef);
|
|
7524
|
+
}, DIALOG_HANDOVER_DELAY_MS);
|
|
7525
|
+
return;
|
|
7526
|
+
}
|
|
7527
|
+
}
|
|
7528
|
+
/**
|
|
7529
|
+
* Brings back the full screen dialog a restored dialog sits in. The two are
|
|
7530
|
+
* hidden together when a full screen dialog takes over with
|
|
7531
|
+
* `previousDialog: 'hide'`, so the context has to be on screen again before
|
|
7532
|
+
* the dialog that sits on top of it, exactly as showAll() puts them back.
|
|
7533
|
+
*/
|
|
7534
|
+
showHostFullScreenDialog(ref) {
|
|
7535
|
+
if (ref.isFullScreen) {
|
|
7536
|
+
return;
|
|
7537
|
+
}
|
|
7538
|
+
const hostRef = this.fullScreenDialog;
|
|
7539
|
+
if (hostRef?.isHidden && this.refs.indexOf(hostRef) < this.refs.indexOf(ref)) {
|
|
7540
|
+
hostRef.show();
|
|
7541
|
+
}
|
|
7542
|
+
}
|
|
7543
|
+
removeRef(ref) {
|
|
7544
|
+
const index = this.refs.indexOf(ref);
|
|
7545
|
+
if (index === -1) {
|
|
7546
|
+
return;
|
|
7547
|
+
}
|
|
7548
|
+
this.refs.splice(index, 1);
|
|
7549
|
+
if (this.refs.length === 0) {
|
|
7550
|
+
this.rootTrigger = null;
|
|
7551
|
+
}
|
|
7552
|
+
this.syncPageState();
|
|
7553
|
+
}
|
|
7554
|
+
/**
|
|
7555
|
+
* State that belongs to the dialogs as a whole rather than to one of them:
|
|
7556
|
+
* page scrolling, the page being hidden from assistive technology, and
|
|
7557
|
+
* where focus sits. Applied in a task of its own, so a dialog handing the
|
|
7558
|
+
* screen over to another one does not give the page back and take it again
|
|
7559
|
+
* within the same frame.
|
|
7560
|
+
*/
|
|
7561
|
+
syncPageState() {
|
|
7562
|
+
if (this.pageStateQueued) {
|
|
7563
|
+
return;
|
|
7564
|
+
}
|
|
7565
|
+
this.pageStateQueued = true;
|
|
7566
|
+
setTimeout(() => {
|
|
7567
|
+
this.pageStateQueued = false;
|
|
7568
|
+
this.applyPageState();
|
|
7569
|
+
});
|
|
7570
|
+
}
|
|
7571
|
+
applyPageState() {
|
|
7572
|
+
const hasVisibleDialog = this.refs.some((ref) => !ref.isHidden);
|
|
7573
|
+
if (hasVisibleDialog) {
|
|
7574
|
+
this.scrollBlock.enable();
|
|
7575
|
+
}
|
|
7576
|
+
else {
|
|
7577
|
+
this.scrollBlock.disable();
|
|
7578
|
+
}
|
|
7579
|
+
if (this.refs.length === 0) {
|
|
7580
|
+
// Nothing is open anymore: the CDK gives the page back to assistive
|
|
7581
|
+
// technology on its own, so there is nothing left to restore here.
|
|
7582
|
+
this.pageAriaHidden.clear();
|
|
7583
|
+
return;
|
|
7584
|
+
}
|
|
7585
|
+
if (hasVisibleDialog) {
|
|
7586
|
+
this.hidePageFromAssistiveTechnology();
|
|
7587
|
+
return;
|
|
7588
|
+
}
|
|
7589
|
+
this.exposePageToAssistiveTechnology();
|
|
7590
|
+
this.releaseFocus();
|
|
7591
|
+
}
|
|
7592
|
+
/**
|
|
7593
|
+
* Gives the page back to assistive technology while every dialog is hidden.
|
|
7594
|
+
* The CDK hides it for as long as a dialog is open, which would otherwise
|
|
7595
|
+
* leave nothing to read at all once the dialogs are out of sight.
|
|
7596
|
+
*/
|
|
7597
|
+
exposePageToAssistiveTechnology() {
|
|
7598
|
+
if (this.pageAriaHidden.size > 0) {
|
|
7599
|
+
return;
|
|
7600
|
+
}
|
|
7601
|
+
const container = this.overlayContainer.getContainerElement();
|
|
7602
|
+
Array.from(container.parentElement?.children ?? []).forEach((sibling) => {
|
|
7603
|
+
const value = sibling.getAttribute('aria-hidden');
|
|
7604
|
+
if (sibling === container || value === null) {
|
|
7605
|
+
return;
|
|
7606
|
+
}
|
|
7607
|
+
this.pageAriaHidden.set(sibling, value);
|
|
7608
|
+
sibling.removeAttribute('aria-hidden');
|
|
7609
|
+
});
|
|
7610
|
+
}
|
|
7611
|
+
/** Hides the page again as soon as a dialog is back on screen. */
|
|
7612
|
+
hidePageFromAssistiveTechnology() {
|
|
7613
|
+
this.pageAriaHidden.forEach((value, element) => {
|
|
7614
|
+
element.setAttribute('aria-hidden', value);
|
|
7615
|
+
});
|
|
7616
|
+
this.pageAriaHidden.clear();
|
|
7617
|
+
}
|
|
7618
|
+
/**
|
|
7619
|
+
* Focus follows the dialogs off the screen: it goes back to whatever opened
|
|
7620
|
+
* the stack, so the page stays usable with the keyboard while the dialogs
|
|
7621
|
+
* wait behind it. Focus that already moved somewhere else is left alone.
|
|
7622
|
+
*/
|
|
7623
|
+
releaseFocus() {
|
|
7624
|
+
const activeElement = this.document.activeElement;
|
|
7625
|
+
if (this.rootTrigger && (!activeElement || activeElement === this.document.body)) {
|
|
7626
|
+
this.rootTrigger.focus();
|
|
7627
|
+
}
|
|
7290
7628
|
}
|
|
7291
7629
|
getFocusedElement() {
|
|
7292
7630
|
const activeElement = this.document.activeElement;
|
|
7293
7631
|
return activeElement instanceof HTMLElement ? activeElement : null;
|
|
7294
7632
|
}
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
}
|
|
7298
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7299
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuService, providedIn: 'root' });
|
|
7633
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7634
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogService, providedIn: 'root' });
|
|
7300
7635
|
}
|
|
7301
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type:
|
|
7636
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogService, decorators: [{
|
|
7302
7637
|
type: Injectable,
|
|
7303
7638
|
args: [{
|
|
7304
7639
|
providedIn: 'root',
|
|
7305
7640
|
}]
|
|
7306
7641
|
}] });
|
|
7307
7642
|
|
|
7308
|
-
class
|
|
7309
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type:
|
|
7310
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type:
|
|
7643
|
+
class DialogHeader {
|
|
7644
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7645
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type: DialogHeader, isStandalone: true, selector: "md3-dialog-header", ngImport: i0, template: "<ng-content select=\"[md3-icon-element]\"></ng-content>\n<div class=\"md3-dialog-title\">\n <md3-type-headline size=\"small\">\n <ng-content></ng-content>\n </md3-type-headline>\n</div>", styles: [":host{display:block;margin:1.5em 1.5em 1em;text-align:center}:host .md3-dialog-title{text-align:start;color:rgb(var(--md-scheme-on-surface))}:host ::ng-deep [md3-icon-element]{color:rgb(var(--md-scheme-secondary))}:host ::ng-deep [md3-icon-element]+.md3-dialog-title{margin-top:1em;text-align:center}\n"], dependencies: [{ kind: "directive", type: TypeHeadline, selector: "md3-type-headline, [md3-type-headline]", inputs: ["size", "color", "emphasized"] }] });
|
|
7311
7646
|
}
|
|
7312
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type:
|
|
7647
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogHeader, decorators: [{
|
|
7313
7648
|
type: Component,
|
|
7314
|
-
args: [{ selector: 'md3-
|
|
7315
|
-
|
|
7316
|
-
|
|
7649
|
+
args: [{ selector: 'md3-dialog-header', imports: [
|
|
7650
|
+
TypeHeadline
|
|
7651
|
+
], template: "<ng-content select=\"[md3-icon-element]\"></ng-content>\n<div class=\"md3-dialog-title\">\n <md3-type-headline size=\"small\">\n <ng-content></ng-content>\n </md3-type-headline>\n</div>", styles: [":host{display:block;margin:1.5em 1.5em 1em;text-align:center}:host .md3-dialog-title{text-align:start;color:rgb(var(--md-scheme-on-surface))}:host ::ng-deep [md3-icon-element]{color:rgb(var(--md-scheme-secondary))}:host ::ng-deep [md3-icon-element]+.md3-dialog-title{margin-top:1em;text-align:center}\n"] }]
|
|
7317
7652
|
}] });
|
|
7318
7653
|
|
|
7319
|
-
class
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
supportingText = input(null, { ...(ngDevMode ? { debugName: "supportingText" } : /* istanbul ignore next */ {}), alias: 'supporting-text' });
|
|
7323
|
-
trailingText = input(null, { ...(ngDevMode ? { debugName: "trailingText" } : /* istanbul ignore next */ {}), alias: 'trailing-text' });
|
|
7324
|
-
selected = model(null, { ...(ngDevMode ? { debugName: "selected" } : /* istanbul ignore next */ {}), alias: 'selected' });
|
|
7325
|
-
iconElements = contentChildren(IconElement, /* @ts-ignore */
|
|
7326
|
-
...(ngDevMode ? [{ debugName: "iconElements" }] : /* istanbul ignore next */ []));
|
|
7327
|
-
get leading() {
|
|
7328
|
-
return this.iconElements().find((icon) => icon.iconType() === 'leading');
|
|
7329
|
-
}
|
|
7330
|
-
get trailing() {
|
|
7331
|
-
return this.iconElements().find((icon) => icon.iconType() === 'trailing');
|
|
7332
|
-
}
|
|
7333
|
-
get showLeadingIcon() {
|
|
7334
|
-
return (!!this.leading && !this.selected()) || this.selected() == true;
|
|
7335
|
-
}
|
|
7336
|
-
onHostClick() {
|
|
7337
|
-
const selected = this.selected();
|
|
7338
|
-
if (selected === null) {
|
|
7339
|
-
return;
|
|
7340
|
-
}
|
|
7341
|
-
this.selected.set(!selected);
|
|
7342
|
-
}
|
|
7343
|
-
constructor(el) {
|
|
7344
|
-
this.el = el;
|
|
7345
|
-
}
|
|
7346
|
-
get element() {
|
|
7347
|
-
return this.el.nativeElement;
|
|
7348
|
-
}
|
|
7349
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuItem, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
7350
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: MenuItem, isStandalone: true, selector: "button[md3-menu-item], a[md3-menu-item]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, supportingText: { classPropertyName: "supportingText", publicName: "supporting-text", isSignal: true, isRequired: false, transformFunction: null }, trailingText: { classPropertyName: "trailingText", publicName: "trailing-text", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange" }, host: { listeners: { "click": "onHostClick()" } }, queries: [{ propertyName: "iconElements", predicate: IconElement, isSignal: true }], ngImport: i0, template: "@if (selected() !== null) {\n <input type=\"checkbox\" md3-input-element [checked]=\"selected()\">\n}\n\n<div class=\"md3-menu-item-container\" md3-state-component>\n <div class=\"md3-menu-item-leading\" [class.has-icon]=\"showLeadingIcon\">\n <ng-content select=\"[md3-icon-element=leading]\"></ng-content>\n @if (!leading) {\n <md3-icon>check</md3-icon>\n }\n </div>\n\n <div class=\"md3-menu-item-content\">\n <md3-type-label size=\"large\">{{ label() }}</md3-type-label>\n @if (supportingText()?.length) {\n <md3-type-body size=\"small\">{{ supportingText() }}</md3-type-body>\n }\n </div>\n\n <div class=\"md3-menu-item-trailing\">\n <ng-content select=\"md3-badge\"></ng-content>\n @if (trailingText()?.length) {\n <md3-type-title size=\"small\">{{ trailingText() }}</md3-type-title>\n }\n <ng-content select=\"[md3-icon-element=trailing]\"></ng-content>\n </div>\n</div>", styles: [":host{--state-color: var(--menu-item-state-color);--border-radius: var(--menu-item-border-radius);--outline-color: var(--menu-item-outline-color);--outline-width: var(--menu-item-outline-width);--outline-offset: var(--menu-item-outline-offset);position:relative;display:block;padding:0;border:0;background:transparent;color:var(--menu-item-label-color);font:inherit;text-align:start;text-decoration:none;cursor:pointer;outline:none;appearance:none;-webkit-user-select:none;user-select:none;z-index:0}:host:focus{z-index:1}:host:focus:not(:hover) .md3-menu-item-container:after{opacity:1}:host:active{z-index:2}:host:active .md3-menu-item-container:after{opacity:0}:host .md3-menu-item-container{display:flex;align-items:center;min-height:3em;padding:0 .75em;border-radius:var(--border-radius);transition:background-color var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing),color var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-menu-item-container .md3-menu-item-leading{display:inline-flex;align-items:center;justify-content:center;font-size:inherit;opacity:0;transform:scale(1.2);width:0;height:1.25em;color:var(--menu-item-supporting-color);transition:all var(--md-motion-standard-fast-spatial-duration) var(--md-motion-standard-fast-spatial-easing)}:host .md3-menu-item-container .md3-menu-item-leading ::ng-deep [md3-icon-element]{font-size:1.25em!important;height:1em!important;width:1em!important;line-height:1em!important}:host .md3-menu-item-container .md3-menu-item-leading.has-icon{margin-inline-end:.5em;opacity:1;transform:scale(1);height:1.25em;width:1.25em}:host .md3-menu-item-container .md3-menu-item-trailing{flex:0 1 content;display:inline-flex;gap:.5em;align-items:center;justify-content:center;font-size:inherit;margin-inline-start:.5em;color:var(--menu-item-supporting-color)}:host .md3-menu-item-container .md3-menu-item-trailing:empty{margin:0}:host .md3-menu-item-container .md3-menu-item-trailing ::ng-deep md3-badge{background-color:var(--menu-item-badge-background);color:var(--menu-item-badge-foreground)}:host .md3-menu-item-container .md3-menu-item-trailing .md3-text-title.md3-text-small{margin:0;padding:0;white-space:nowrap;letter-spacing:.007143em}:host .md3-menu-item-container .md3-menu-item-trailing ::ng-deep [md3-icon-element]{font-size:1.25em!important;height:1em!important;width:1em!important;line-height:1em!important}:host .md3-menu-item-container .md3-menu-item-content{flex:1 1 auto}:host .md3-menu-item-container .md3-menu-item-content .md3-text-label.md3-text-large{display:block;margin:0;padding:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:.007143em;color:var(--menu-item-label-color)}:host .md3-menu-item-container .md3-menu-item-content .md3-text-body.md3-text-small{display:block;margin:0;padding:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:.0333334em;color:var(--menu-item-supporting-color)}:host [md3-input-element]{position:absolute;height:0;width:0;opacity:0;pointer-events:none}:host [md3-input-element]+.md3-menu-item-container .md3-menu-item-leading{opacity:0;transform:scale(1.2);width:0}:host [md3-input-element]:checked+.md3-menu-item-container{--menu-item-label-color: var(--menu-item-selected-foreground);--menu-item-supporting-color: var(--menu-item-selected-foreground);--border-radius: var(--md-border-radius-medium);background-color:var(--menu-item-selected-background)}:host [md3-input-element]:checked+.md3-menu-item-container .md3-menu-item-leading{opacity:1;transform:scale(1);width:1.25em}:host:disabled{cursor:default}:host:disabled .md3-menu-item-container{--menu-item-label-color: var(--menu-item-label-color);--menu-item-supporting-color: var(--menu-item-label-color);--menu-item-selected-background: transparent;--menu-item-selected-foreground: var(--menu-item-label-color);pointer-events:none;opacity:.38}:host:disabled .md3-menu-item-container.md3-state-layer,:host:disabled .md3-menu-item-container:after{display:none}\n"], dependencies: [{ kind: "directive", type: InputElement, selector: "[md3-input-element]" }, { kind: "directive", type: StateComponent, selector: "[md3-state-component]" }, { kind: "component", type: MaterialIcon, selector: "md3-icon", inputs: ["icon-version", "filled", "icon-style", "icon-size", "bi-directional"] }, { kind: "directive", type: TypeLabel, selector: "md3-type-label, [md3-type-label]", inputs: ["size", "color", "emphasized"] }, { kind: "directive", type: TypeBody, selector: "md3-type-body, [md3-type-body]", inputs: ["size", "color", "emphasized"] }, { kind: "directive", type: TypeTitle, selector: "md3-type-title, [md3-type-title]", inputs: ["size", "color", "emphasized"] }] });
|
|
7654
|
+
class DialogBody {
|
|
7655
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogBody, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7656
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type: DialogBody, isStandalone: true, selector: "md3-dialog-body", host: { classAttribute: "md3-scrollable" }, ngImport: i0, template: "<ng-content></ng-content>", styles: [":host{display:block;margin:1em 1.5em 1.5em;color:rgb(var(--md-scheme-on-surface-variant))}:host .md3-text-body.md3-text-medium{letter-spacing:.017857em}\n"] });
|
|
7351
7657
|
}
|
|
7352
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type:
|
|
7658
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogBody, decorators: [{
|
|
7353
7659
|
type: Component,
|
|
7354
|
-
args: [{ selector: '
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7660
|
+
args: [{ selector: 'md3-dialog-body', imports: [], host: {
|
|
7661
|
+
'class': 'md3-scrollable',
|
|
7662
|
+
}, template: "<ng-content></ng-content>", styles: [":host{display:block;margin:1em 1.5em 1.5em;color:rgb(var(--md-scheme-on-surface-variant))}:host .md3-text-body.md3-text-medium{letter-spacing:.017857em}\n"] }]
|
|
7663
|
+
}] });
|
|
7664
|
+
|
|
7665
|
+
class DialogActions {
|
|
7666
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogActions, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7667
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type: DialogActions, isStandalone: true, selector: "md3-dialog-actions", ngImport: i0, template: "<div class=\"md3-actions\">\n <ng-content></ng-content>\n</div>", styles: [":host{display:block;margin:1.5em}:host .md3-actions{display:flex;gap:1em;flex-direction:row-reverse}\n"] });
|
|
7668
|
+
}
|
|
7669
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DialogActions, decorators: [{
|
|
7670
|
+
type: Component,
|
|
7671
|
+
args: [{ selector: 'md3-dialog-actions', imports: [], template: "<div class=\"md3-actions\">\n <ng-content></ng-content>\n</div>", styles: [":host{display:block;margin:1.5em}:host .md3-actions{display:flex;gap:1em;flex-direction:row-reverse}\n"] }]
|
|
7672
|
+
}] });
|
|
7365
7673
|
|
|
7366
7674
|
class SideSheetHeader {
|
|
7367
7675
|
title = input('', { ...(ngDevMode ? { debugName: "title" } : /* istanbul ignore next */ {}), alias: 'title' });
|
|
@@ -7764,5 +8072,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
7764
8072
|
* Generated bundle index. Do not edit.
|
|
7765
8073
|
*/
|
|
7766
8074
|
|
|
7767
|
-
export { AppBar, AppBarLogo, Avatar, BOTTOM_SHEET_COMPONENT, BOTTOM_SHEET_CONFIG, BOTTOM_SHEET_DATA, Badge, BottomSheetRef, BottomSheetService, Button, ButtonGroup, CAROUSEL_STRATEGIES, Card, Carousel, CarouselItem, Checkbox, ChipAvatar, Chips, CircularProgressIndicator, DIALOG_COMPONENT, DIALOG_CONFIG, DIALOG_DATA, Dialog, DialogActions, DialogBody, DialogHeader, DialogRef, DialogService, Divider, FloatingActionButton, FullScreenDialog, Grid, GridItem, IconButton, IconElement, InputElement, Layout, LayoutService, LinearProgressIndicator, List, ListItem, ListItemPrimaryAction, ListLeading, ListSlot, LoadingIndicator, MENU_COMPONENT, MENU_CONFIG, MENU_DATA, MaterialIcon, Menu, MenuGroup, MenuItem, MenuRef, MenuService, ModalBottomSheetRef, NavigationBar, NavigationGroup, NavigationItem, NavigationRail, RadioButton, SIDE_SHEET_COMPONENT, SIDE_SHEET_CONFIG, SIDE_SHEET_DATA, SNACKBAR_ACTION_LABEL, SNACKBAR_CONFIG, SNACKBAR_MESSAGE, Scaffold, ScaffoldBar, ScaffoldPane, ScaffoldRail, SheetsService, SideSheetActions, SideSheetBody, SideSheetHeader, SideSheetRef, Slider, Snackbar, SnackbarRef, SnackbarService, SplitButton, StandardBottomSheetRef, StateComponent, SupportingText, Switch, TextField, Toolbar, ToolbarItem, TypeBody, TypeDisplay, TypeHeadline, TypeLabel, TypeTitle, ViewportService, buildGeometry, clampIndex, indexForScrollOffset, multiBrowseStrategy, parseCarouselAspectRatio, resolveItemGeometry, resolveState, scrollOffsetForIndex, sizeBandFor };
|
|
8075
|
+
export { AppBar, AppBarLogo, Avatar, BOTTOM_SHEET_COMPONENT, BOTTOM_SHEET_CONFIG, BOTTOM_SHEET_DATA, Badge, BottomSheetRef, BottomSheetService, Button, ButtonGroup, CAROUSEL_STRATEGIES, Card, Carousel, CarouselItem, Checkbox, ChipAvatar, Chips, CircularProgressIndicator, DIALOG_COMPONENT, DIALOG_CONFIG, DIALOG_DATA, Dialog, DialogActions, DialogBody, DialogHeader, DialogRef, DialogService, Divider, FloatingActionButton, FullScreenDialog, Grid, GridItem, IconButton, IconElement, InputElement, Layout, LayoutService, LinearProgressIndicator, List, ListItem, ListItemPrimaryAction, ListLeading, ListSlot, LoadingIndicator, MENU_COMPONENT, MENU_CONFIG, MENU_DATA, MaterialIcon, Menu, MenuGroup, MenuItem, MenuRef, MenuService, ModalBottomSheetRef, NavigationBar, NavigationGroup, NavigationItem, NavigationRail, RadioButton, SIDE_SHEET_COMPONENT, SIDE_SHEET_CONFIG, SIDE_SHEET_DATA, SNACKBAR_ACTION_LABEL, SNACKBAR_CONFIG, SNACKBAR_MESSAGE, Scaffold, ScaffoldBar, ScaffoldPane, ScaffoldRail, SelectField, SheetsService, SideSheetActions, SideSheetBody, SideSheetHeader, SideSheetRef, Slider, Snackbar, SnackbarRef, SnackbarService, SplitButton, StandardBottomSheetRef, StateComponent, SupportingText, Switch, TextField, Toolbar, ToolbarItem, TypeBody, TypeDisplay, TypeHeadline, TypeLabel, TypeTitle, ViewportService, buildGeometry, clampIndex, indexForScrollOffset, multiBrowseStrategy, parseCarouselAspectRatio, resolveItemGeometry, resolveState, scrollOffsetForIndex, sizeBandFor };
|
|
7768
8076
|
//# sourceMappingURL=almoamendev-ngx-md3.mjs.map
|